Skip to content

Voice: a long reply is watched for 1.6 s before it starts (16 → 3 of 84 replies with a pause) - #129

Merged
jayleaton merged 1 commit into
mainfrom
feat/voice-start-observe
Oct 27, 2026
Merged

jayleaton merged 1 commit into
mainfrom
feat/voice-start-observe

Conversation

@jayleaton

Copy link
Copy Markdown
Owner

Summary

A reply whose text is still being written is watched for 1.6 s from its first piece before the start rule may release it. This applies to the /voice page, the companion (which uses the page), the mobile replyHold and voice_e2e's replay.

 holdNeed(item):
+  if (!textDone && now - firstPiece < OBSERVE_MS /* 1600 */) return Infinity   // still watching its rate
   return max(START_MS, rest * (1 - rate) + margin)

Why: in the first second, a long reply's speech often arrives at real time. It then slows once the chat model writes its next sentences beside it. A start trusted on that first second ran dry later in the reply.

Evidence

The rule was replayed on the recorded events of every reply.

Live on DGX-02, 2026-10-27/28:

  • 84 long replies from 7 batches: Mae and Scarlette, typed and spoken turns, ten prompts, a fresh session each.
  • 20 short spoken turns.
Before (9902b37 rule) After (this PR)
Long replies with a pause over 50 ms 16 / 84 3 / 84 (0.07–0.4 s, each 35 s or more into the reply)
Long reply start, mean from request 3.19 s 3.47 s (best start in hindsight: 2.7 s)
Short replies, start mean / max 0.93 / 1.80 s 0.93 / 1.80 s (unchanged)

The real page in headless Chrome (DGX-02 daemon at 9902b37, typed long prompts in a call; the old page and this page interleaved):

Gaps the page's scheduler measured Page's held start
Old page Scarlette story started after 0.3 s, then a 164 ms gap 0.3–3.0 s
This page none in 4 replies 1.9–2.5 s

Checks

  • zig fmt --check, zig build and zig build test on DGX-02: exit 0, 287/287 tests.
  • apps/mobile: lint, type-check and test (54) pass.
  • apps/companion: npm run check passes.
  • voice_e2e.page_start gives exactly the replay's start on 54 replies (0 s difference).

Merge Danger

Door: two-way. Client-side only, with no state or protocol change.

Blast Radius: voice

  • Long replies start about 0.3 s later on average.
  • Replies under about 1.6 s of writing are unaffected: their text completes before the window ends.

🤖 Generated with Claude Code

In the first second a long reply's speech often comes at real time and slows once the chat
model writes its next sentences beside it, so the start the measured rate allowed then still
paused in 16 of 84 long replies measured live on DGX-02. A reply whose text is still being
written now waits OBSERVE_MS (1.6 s) from its first piece before the rule may start it: 3 of
84 then pause (0.07 to 0.4 s, each 35 s or more in). The page, the mobile app and
voice_e2e's replay change together.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@jayleaton
jayleaton merged commit 87ea48b into main Oct 27, 2026
20 of 21 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant