From 1fb6d6bd23241dbf0dda98748a3e6183dd2f877d Mon Sep 17 00:00:00 2001 From: Mark Backman Date: Thu, 6 Nov 2025 12:59:37 -0500 Subject: [PATCH] GoogleSTTService: Add more robust handling of 409 errors --- CHANGELOG.md | 7 +++++++ examples/foundational/07n-interruptible-google.py | 3 ++- src/pipecat/services/google/stt.py | 13 +++++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3aa59cf93..649424eec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -73,6 +73,13 @@ reason")`. level. Important: The STTMuteFilter should be placed _after_ the STT service itself. +- Improved `GoogleSTTService` error handling to properly catch gRPC `Aborted` + exceptions (corresponding to 409 errors) caused by stream inactivity. These + exceptions are now logged at DEBUG level instead of ERROR level, since they + indicate expected behavior when no audio is sent for 10+ seconds (e.g., during + long silences or when audio input is blocked). The service automatically + reconnects when this occurs. + - Bumped the `fastapi` dependency's upperbound to `<0.122.0`. - Updated the default model for `GoogleVertexLLMService` to `gemini-2.5-flash`. diff --git a/examples/foundational/07n-interruptible-google.py b/examples/foundational/07n-interruptible-google.py index 203099c59..879ed0d1a 100644 --- a/examples/foundational/07n-interruptible-google.py +++ b/examples/foundational/07n-interruptible-google.py @@ -61,8 +61,9 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): logger.info(f"Starting bot") stt = GoogleSTTService( - params=GoogleSTTService.InputParams(languages=Language.EN_US), + params=GoogleSTTService.InputParams(languages=Language.EN_US, model="chirp_3"), credentials=os.getenv("GOOGLE_TEST_CREDENTIALS"), + location="us", ) tts = GoogleTTSService( diff --git a/src/pipecat/services/google/stt.py b/src/pipecat/services/google/stt.py index fa538b02e..59d1dcd63 100644 --- a/src/pipecat/services/google/stt.py +++ b/src/pipecat/services/google/stt.py @@ -41,6 +41,7 @@ from pipecat.utils.time import time_now_iso8601 try: from google.api_core.client_options import ClientOptions + from google.api_core.exceptions import Aborted from google.auth import default from google.auth.exceptions import GoogleAuthError from google.cloud import speech_v2 @@ -886,6 +887,18 @@ class GoogleSTTService(STTService): result=result, ) ) + except Aborted as e: + # Handle stream abort due to inactivity (409 error). + # This occurs when no audio is sent to the stream for 10+ seconds, + # which can happen when InputAudioRawFrames are blocked (e.g., by STTMuteFilter). + # Google's STT service automatically closes the stream in this case. + # We log at DEBUG level (not ERROR) since this is recoverable, then re-raise + # to trigger automatic reconnection in _stream_audio. + logger.debug( + f"{self} Stream aborted due to inactivity (no audio input). " + f"Reconnecting automatically..." + ) + raise except Exception as e: logger.error(f"Error processing Google STT responses: {e}") # Re-raise the exception to let it propagate (e.g. in the case of a