Skip to content

fix(voice): recover STT stream after unrecoverable errors#6418

Open
longcw wants to merge 2 commits into
mainfrom
longc/stt-reconnect
Open

fix(voice): recover STT stream after unrecoverable errors#6418
longcw wants to merge 2 commits into
mainfrom
longc/stt-reconnect

Conversation

@longcw

@longcw longcw commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Fixes #5665.

Unlike the LLM and TTS streams, which are recreated every turn, the STT stream is long-lived: it is created once per agent activity and iterated by a single pump task. When it exhausted its per-utterance retries it emitted an unrecoverable stt_error and the pump ended, so nothing recreated it — and because stt_error had none of the session-level tolerance that llm_error/tts_error have, the session closed immediately on the first unrecoverable STT error.

This makes the long-lived STT stream self-healing and gives it the same session-level tolerance:

  • _STTPipeline recreates the STT stream (with a short backoff) after an unrecoverable error, so the agent keeps hearing the user if the provider recovers.
  • AgentSession applies max_unrecoverable_errors to stt_error as the circuit breaker: each failed stream increments the count, and it resets on a user transcript (STT's success signal, mirroring how llm/tts reset on agent speaking).
  • The pump does not recreate the stream while the session is closing, so a teardown in progress can't spawn provider connections that are torn down at once.

Supersedes #5666, #5997, and #6001

Fixes #5665.

Unlike the LLM and TTS streams, which are recreated every turn, the STT stream is long-lived: it is created once per agent activity and iterated by a single pump task. When it exhausted its per-utterance retries it emitted an unrecoverable stt_error and the pump ended, so nothing recreated it — and because stt_error had none of the session-level tolerance that llm_error/tts_error have, the session closed immediately on the first unrecoverable STT error.

This makes the long-lived STT stream self-healing and gives it the same session-level tolerance:

- _STTPipeline recreates the STT stream (with a short backoff) after an unrecoverable error, so the agent keeps hearing the user if the provider recovers.
- AgentSession applies max_unrecoverable_errors to stt_error as the circuit breaker: each failed stream increments the count, and it resets on a user transcript (STT's success signal, mirroring how llm/tts reset on agent speaking).
- The pump does not recreate the stream while the session is closing, so a teardown in progress can't spawn provider connections that are torn down at once.

Supersedes #5666, #5997, and #6001, which added the session counter alone — without the reconnect the counter freezes at 1 (a dead stream emits no further errors) and the session stays open but deaf.
@longcw longcw requested a review from a team as a code owner July 14, 2026 10:54
devin-ai-integration[bot]

This comment was marked as resolved.

Narrow the pump's reconnect to APIError — the connection/API failures that RecognizeStream emits and the session counts — instead of any exception, and move stream creation into the retry scope so a connection failure during setup is retried too. Programming errors and malformed events now fail loud instead of looping forever.
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.

bug: STT errors close AgentSession immediately, lacking the tolerance counter that LLM and TTS errors have

1 participant