From 6bfa4341bf4fb6c0ce20a20b04c6789196e15d60 Mon Sep 17 00:00:00 2001 From: AAliKKhan Date: Thu, 23 Jul 2026 04:35:55 +0500 Subject: [PATCH 1/3] fix: resolve voice pipeline deadlock on TTS error, remove redundant input deep copy, fix unretrieved task exception --- src/agents/models/openai_responses.py | 1 - src/agents/voice/result.py | 6 +++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/agents/models/openai_responses.py b/src/agents/models/openai_responses.py index 55c78d0245..849b590571 100644 --- a/src/agents/models/openai_responses.py +++ b/src/agents/models/openai_responses.py @@ -733,7 +733,6 @@ def _build_response_create_kwargs( prompt: ResponsePromptParam | None = None, ) -> dict[str, Any]: list_input = ItemHelpers.input_to_new_input_list(input) - list_input = _to_dump_compatible(list_input) list_input = self._remove_openai_responses_api_incompatible_fields(list_input) if model_settings.parallel_tool_calls and tools: diff --git a/src/agents/voice/result.py b/src/agents/voice/result.py index 2f4b24433b..b6657b76a9 100644 --- a/src/agents/voice/result.py +++ b/src/agents/voice/result.py @@ -196,6 +196,7 @@ async def _stream_audio( # Signal completion for whole session because of error await local_queue.put(VoiceStreamEventLifecycle(event="session_ended")) + await local_queue.put(None) raise e async def _add_text(self, text: str): @@ -292,7 +293,10 @@ def _cleanup_tasks(self): self.text_generation_task.cancel() def _check_errors(self): - for task in self._tasks: + all_tasks = list(self._tasks) + if self.text_generation_task is not None: + all_tasks.append(self.text_generation_task) + for task in all_tasks: if task.done(): if task.exception(): self._stored_exception = task.exception() From 94aea19a4241ffa252be5a148f43b2f2568fddd9 Mon Sep 17 00:00:00 2001 From: AAliKKhan Date: Thu, 23 Jul 2026 04:54:53 +0500 Subject: [PATCH 2/3] Update result.py --- src/agents/voice/result.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/agents/voice/result.py b/src/agents/voice/result.py index b6657b76a9..8dd27ce1c6 100644 --- a/src/agents/voice/result.py +++ b/src/agents/voice/result.py @@ -194,9 +194,10 @@ async def _stream_audio( ) logger.error("Error streaming audio: %s", e) - # Signal completion for whole session because of error - await local_queue.put(VoiceStreamEventLifecycle(event="session_ended")) + await self._add_error(e) await local_queue.put(None) + if self.text_generation_task is not None and not self.text_generation_task.done(): + self.text_generation_task.cancel() raise e async def _add_text(self, text: str): @@ -297,7 +298,7 @@ def _check_errors(self): if self.text_generation_task is not None: all_tasks.append(self.text_generation_task) for task in all_tasks: - if task.done(): + if task.done() and not task.cancelled(): if task.exception(): self._stored_exception = task.exception() break From 036cf41bf60face398d3273cf7be273a47fdfa82 Mon Sep 17 00:00:00 2001 From: AAliKKhan Date: Thu, 23 Jul 2026 14:44:54 +0500 Subject: [PATCH 3/3] Revert openai_responses.py changes into separate PR --- src/agents/models/openai_responses.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/agents/models/openai_responses.py b/src/agents/models/openai_responses.py index 849b590571..55c78d0245 100644 --- a/src/agents/models/openai_responses.py +++ b/src/agents/models/openai_responses.py @@ -733,6 +733,7 @@ def _build_response_create_kwargs( prompt: ResponsePromptParam | None = None, ) -> dict[str, Any]: list_input = ItemHelpers.input_to_new_input_list(input) + list_input = _to_dump_compatible(list_input) list_input = self._remove_openai_responses_api_incompatible_fields(list_input) if model_settings.parallel_tool_calls and tools: