The instant the server starts, Hina texts first with a fixed opener, then hands off to the live agent.
4 minThree bubbles, sent one at a time with the normal human typing choreography (dots → "type" → send → beat → next). Modeled on the north-star anna cold-open.
dashed = hardcoded · everything after is the live model picking up the thread.
The exact bubbles live in one constant, DEMO_BUBBLES in agent/core/demo-opener.mjs. Drop the 'hey' line for exactly the two you asked for. I added it because the north-star opens with a standalone greeting before the question — it reads warmer — but it's a one-line edit either way.
npm start (+ npm run messages).+15109358199 back to fresh onboarding (keeps the chatGuid) so the demo is identical every run — the live agent behaves like a first conversation, not someone already onboarded.sendBubbles path + sending latch as a real reply, so it looks human and can't collide with an inbound turn or the proactive sweep.Two terminals, from agent/. DEMO=1 is already set in .env.
# terminal 1 — launch Messages with the helper injected
npm run messages
# terminal 2 — start the server (fires the cold-open on connect)
npm start
Watch the demo phone: hey → i heard you want to learn a language → which one? arrive within a couple seconds. Reply japanese and the live agent takes over. To re-run a clean demo, just restart the server — the reset makes it repeatable.
DEMO=1 means every npm start now cold-opens and wipes that learner's memory. Set DEMO=0 (or delete the line) to go back to normal operation.| Env / location | Default | What it does |
|---|---|---|
DEMO | 1 (in .env) | Master switch. 0/off disarms the cold-open entirely. |
DEMO_HANDLE | first ALLOW_FROM | Who to open on. Unset → +15109358199. |
DEMO_RESET | 1 | Reset the learner to fresh onboarding each run. 0 = demo against existing memory. |
DEMO_BUBBLES (code) | 3 bubbles | The scripted lines, in core/demo-opener.mjs. Edit to change the words. |
Model-generated, reply-only.
"hey, it's hina" came from the onboarding prompt in agent.mjs — it varies run to run and only fires after the learner texts in. Proactive can re-poke a quiet thread but won't script exact words or cold-open a fresh one.
Fixed, fires first, deterministic.
Same bubbles every run, on a clean slate, the second Messages connects. No model call for the opener — just the scripted lines, then the live agent owns everything after. Exactly what a live demo needs.
へえ 本当??) — that's the product, not a tutor.remember — never a five-question form.| File | Change | |
|---|---|---|
agent/core/demo-opener.mjs | new | The cold-open: scripted bubbles, fire-once latch, clean-slate reset, history seed. |
agent/core/memory.mjs | edit | Added resetLearner(handle) — fresh onboarding, keeps chatGuid. |
agent/config.mjs | edit | Added the demo config block (enabled / handle / reset). |
agent/server.mjs | edit | Wired startDemoOpener(...) into main() after the proactive sweep. |
agent/.env | edit | DEMO=1 to arm it. |
Smoke-tested: config parses, modules import, the opener registers its connect handler without sending. The real send needs Messages.app connected — that's the demo itself.