Skip to content

companion-ws: accept voice:interrupt upstream messages from mobile (F007 barge-in) #358

@jpelaez-23blocks

Description

@jpelaez-23blocks

Context

Companion to #357. Mobile app v0.4.0 ships with full-duplex voice support including barge-in — if the user starts speaking while the agent is mid-response, the phone stops the TTS locally and sends an interrupt signal upstream so the backend halts any in-progress generation for the current turn.

Requested change

companion-ws should accept upstream messages of the form:

{ "type": "voice:interrupt" }

…and halt whatever's currently being generated for that turn, so the mobile doesn't keep receiving speech downstream chunks the user no longer wants to hear. The follow-up voice:transcript (the user's new utterance) will arrive shortly after and should be treated as a fresh turn.

Acceptance criteria

  • companion-ws parses incoming JSON with type === 'voice:interrupt'
  • In-progress response generation for the current turn is cancelled (best-effort — kill pending LLM stream, stop emitting speech downstream messages)
  • No new speech messages for that turn flow downstream after the interrupt arrives
  • Subsequent voice:transcript messages are processed as new turns (no leftover state from the cancelled one)
  • If no turn is in progress when voice:interrupt arrives, the message is a no-op (log + drop)

Why it matters

Without server-side interrupt handling, the agent keeps generating speech chunks after the user barges in. The phone silences them locally (we already stop the TTS playback), but the backend wastes tokens, the user's next utterance gets queued behind the obsolete response, and the conversation drifts out of sync.

Related

  • Mobile-side spec: backlog/F007-talk-to-agent-via-voice.md in 23blocks/ai-maestro-app
  • Companion: #357 (voice:transcript upstream)
  • Mobile sends both messages through hooks/useCompanionWS.ts (sendVoiceInterrupt + sendVoiceTranscript)

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions