diff --git a/src/pipecat/services/aws/nova_sonic/llm.py b/src/pipecat/services/aws/nova_sonic/llm.py index f77d6aee5..4aeb5c848 100644 --- a/src/pipecat/services/aws/nova_sonic/llm.py +++ b/src/pipecat/services/aws/nova_sonic/llm.py @@ -645,11 +645,18 @@ class AWSNovaSonicLLMService(LLMService[AWSNovaSonicLLMAdapter]): error_msg="Nova Sonic does not support streamed async tool results.", ) continue - # kind == "final": deliver via the formal toolResult channel - # — same path as a synchronous tool result, just delayed. - if send_new_results: - await self._send_tool_result(async_payload.tool_call_id, async_payload.result) - self._completed_tool_calls.add(async_payload.tool_call_id) + if async_payload.kind == "final": + # Deliver via the formal toolResult channel — same path + # as a synchronous tool result, just delayed. + if send_new_results: + await self._send_tool_result( + async_payload.tool_call_id, async_payload.result + ) + self._completed_tool_calls.add(async_payload.tool_call_id) + continue + # Defensive: any async-tool message must not fall through + # to the regular tool-result block below, even if it + # carries a kind we don't recognize. continue # Look for newly-completed "regular" (as opposed to async-tool) results diff --git a/src/pipecat/services/openai/realtime/llm.py b/src/pipecat/services/openai/realtime/llm.py index d105a8a39..28b987437 100644 --- a/src/pipecat/services/openai/realtime/llm.py +++ b/src/pipecat/services/openai/realtime/llm.py @@ -1068,12 +1068,19 @@ class OpenAIRealtimeLLMService(LLMService[OpenAIRealtimeLLMAdapter]): error_msg="OpenAI Realtime does not support streamed async tool results.", ) continue - # kind == "final": deliver via the formal tool-result channel - # — same path as a synchronous tool result, just delayed. - if send_new_results: - sent_new_result = True - await self._send_tool_result(async_payload.tool_call_id, async_payload.result) - self._completed_tool_calls.add(async_payload.tool_call_id) + if async_payload.kind == "final": + # Deliver via the formal tool-result channel — same path + # as a synchronous tool result, just delayed. + if send_new_results: + sent_new_result = True + await self._send_tool_result( + async_payload.tool_call_id, async_payload.result + ) + self._completed_tool_calls.add(async_payload.tool_call_id) + continue + # Defensive: any async-tool message must not fall through + # to the regular tool-result block below, even if it + # carries a kind we don't recognize. continue # Look for newly-completed "regular" (as opposed to async-tool) results