You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[bug] Saying "stop" does nothing — only "stop voice" is a command, and the agent replies "Stopped" anyway #331
Coder Lead, 2026-08-06 23:51:37. The user said "Stop-stop." — meaning stop.
It was transcribed and sent as a chat message. The agent replied "Got it. Stopped." Nothing
stopped. The mic stayed live, and two phantom turns followed (see #(B), the companion ticket).
Cause: "stop" alone is not an exit phrase
packages/sdk/src/voice/convo.ts:147:
constEXIT_BY_LANG={en: ["exit voice","exit voice mode","stop voice","stop voice mode","leave voice","text mode","switch to text","back to text"],
…
}
Every English phrase that contains "stop" requires the word "voice" after it. Bare "stop", "stop stop", "stop listening" match nothing.
There is no vocabulary reason for this: phraseMatchesTranscript already allows a single-word
command when it is the whole utterance — the restriction exists so "don't forget to mute"
stays a message. "Stop-stop." was the whole utterance, so a listed "stop" would have fired
correctly and safely.
Stop-words are not the answer either: they are off unless configured (stripStopWord:394), and a
stop-word ends the turn — it submits the message. It does not stop the session.
The second half: the agent confirmed a stop it cannot perform
"Got it. Stopped."
Voice mode is client state. The agent has no visibility into it and no control over it — it
answered "stop" conversationally, as any assistant would. But the reply reads as confirmation, so
the user reasonably disengaged while the microphone was still open.
That is the same class as #254 and #259: an agent making a confident statement about a capability
it does not have, because nothing told it otherwise. Here the honest reply is "I can't control
the microphone — say 'stop voice' or tap the mode control", which requires the prompt to know
voice is active.
Fix
Add bare "stop", "stop stop", "stop listening" (and the equivalents in the other nine
languages already listed) to EXIT_BY_LANG.
Consider whether "stop" should mean exit voice or interrupt what is happening — they are
different. Mid-reply, a user saying "stop" most likely wants the TTS to shut up and the turn
abandoned, not to leave hands-free entirely. exit may be the wrong verb to bind it to.
Superseded in part by #333… correction: by #334. The owner has "stop stop" configured as a stop-word, so the real failure was not "stop is not in EXIT_BY_LANG" — it was that normalizeTranscript does not strip hyphens, and Whisper rendered the phrase as "Stop-stop.". See #334 for the measurement.
What remains valid here: bare "stop" still is not an exit phrase (only "stop voice"), and the agent still replies "Got it. Stopped." about client state it cannot see or control. Both worth fixing — but #334 is the one that explains the intermittency.
Voice half fixed in 3d7e28b; the prompt half is left open below.
"stop" and "stop stop" are now exit phrases in EXIT_BY_LANG, with equivalents in the other nine languages (停止 / やめて / 그만 / basta / arrête / aufhören / рuko …).
On whether the bare word is safe: yes, and by construction rather than luck. phraseMatchesTranscript requires a single-word phrase to BE the whole utterance — the rule added when "next agent" fired inside "the next agent in the chain is the builder" — so "don't stop now", "stop the deploy when the tests go green" and "did it stop?" all stay messages. Tests pin those.
"stop stop" is not redundant with it: it normalises to two words, which the single-word rule can never match, and it is what the reported "Stop-stop." becomes after #334. As a multi-word phrase it can also match inside a longer utterance; a doubled imperative is distinctive enough for that, in the way "next agent" was not.
"stop listening" deliberately stays a MUTE phrase — it says literally what mute does, exit is checked first and would have stolen it, and silencing the mic is the smaller, recoverable reading.
On the ticket's second bullet (interrupt vs exit): exit now cancels TTS immediately rather than after awaiting the hands-free teardown, so mid-reply "stop" silences the agent at once instead of talking over the answer to whether anything stopped.
Left open — the prompt half. "Teach the agent that voice is active so it stops confirming actions it cannot take" belongs in workers/api (#315's lib/prompt-claims.ts is the right machinery: "Got it. Stopped." is a claim that contradicts reality, same class as #254/#259). That was another agent's lane this run, so it is untouched. Suggest tracking it as its own ticket against prompt-claims rather than reopening this one.
Activity
serge-ivo commentedon Aug 6, 2026
Superseded in part by #333… correction: by #334. The owner has
"stop stop"configured as a stop-word, so the real failure was not "stop is not in EXIT_BY_LANG" — it was thatnormalizeTranscriptdoes not strip hyphens, and Whisper rendered the phrase as"Stop-stop.". See #334 for the measurement.What remains valid here: bare
"stop"still is not an exit phrase (only"stop voice"), and the agent still replies "Got it. Stopped." about client state it cannot see or control. Both worth fixing — but #334 is the one that explains the intermittency.fix(sdk): one normaliser for spoken text, so "Stop-stop." stops (#334, …
serge-ivo commentedon Aug 7, 2026
Voice half fixed in 3d7e28b; the prompt half is left open below.
"stop"and"stop stop"are now exit phrases inEXIT_BY_LANG, with equivalents in the other nine languages (停止 / やめて / 그만 / basta / arrête / aufhören / рuko …).On whether the bare word is safe: yes, and by construction rather than luck.
phraseMatchesTranscriptrequires a single-word phrase to BE the whole utterance — the rule added when"next agent"fired inside "the next agent in the chain is the builder" — so"don't stop now","stop the deploy when the tests go green"and"did it stop?"all stay messages. Tests pin those."stop stop"is not redundant with it: it normalises to two words, which the single-word rule can never match, and it is what the reported"Stop-stop."becomes after #334. As a multi-word phrase it can also match inside a longer utterance; a doubled imperative is distinctive enough for that, in the way "next agent" was not."stop listening"deliberately stays a MUTE phrase — it says literally what mute does, exit is checked first and would have stolen it, and silencing the mic is the smaller, recoverable reading.On the ticket's second bullet (interrupt vs exit): exit now cancels TTS immediately rather than after awaiting the hands-free teardown, so mid-reply "stop" silences the agent at once instead of talking over the answer to whether anything stopped.
Left open — the prompt half. "Teach the agent that voice is active so it stops confirming actions it cannot take" belongs in
workers/api(#315'slib/prompt-claims.tsis the right machinery: "Got it. Stopped." is a claim that contradicts reality, same class as #254/#259). That was another agent's lane this run, so it is untouched. Suggest tracking it as its own ticket against prompt-claims rather than reopening this one.fix(voice): a phrase you bound is yours, the agent cannot command its…