From 2c65713c99cd32fd3b0d6885851372cd58ea69ab Mon Sep 17 00:00:00 2001 From: Paul Kompfner Date: Fri, 8 May 2026 15:45:05 -0400 Subject: [PATCH] refactor: explicit kind=='final' check in async-tool routing (Grok) Mirrors the same change applied to AWSNovaSonicLLMService and OpenAIRealtimeLLMService in #4441: replaces the implicit "final happens last" pattern in _process_completed_function_calls with an explicit `if async_payload.kind == "final":` block, plus a trailing defensive `continue` so async-tool messages with an unrecognized kind don't fall through to the regular tool-result handling block. --- src/pipecat/services/xai/realtime/llm.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/pipecat/services/xai/realtime/llm.py b/src/pipecat/services/xai/realtime/llm.py index 8b8e0d94a..7ac83d071 100644 --- a/src/pipecat/services/xai/realtime/llm.py +++ b/src/pipecat/services/xai/realtime/llm.py @@ -942,12 +942,19 @@ class GrokRealtimeLLMService(LLMService[GrokRealtimeLLMAdapter]): error_msg="Grok 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