@@ -702,6 +702,9 @@ def get_author_for_event(llm_response):
702702 else :
703703 return invocation_context .agent .name
704704
705+ # Cache maps function call names to generated IDs so that partial and
706+ # final streaming events for the same call share a stable ID.
707+ function_call_id_cache : dict [str , str ] = {}
705708 try :
706709 while True :
707710 async with Aclosing (llm_connection .receive ()) as agen :
@@ -726,6 +729,7 @@ def get_author_for_event(llm_response):
726729 llm_request ,
727730 llm_response ,
728731 model_response_event ,
732+ function_call_id_cache ,
729733 )
730734 ) as agen :
731735 async for event in agen :
@@ -959,6 +963,7 @@ async def _postprocess_live(
959963 llm_request : LlmRequest ,
960964 llm_response : LlmResponse ,
961965 model_response_event : Event ,
966+ function_call_id_cache : Optional [dict [str , str ]] = None ,
962967 ) -> AsyncGenerator [Event , None ]:
963968 """Postprocess after calling the LLM asynchronously.
964969
@@ -967,6 +972,9 @@ async def _postprocess_live(
967972 llm_request: The original LLM request.
968973 llm_response: The LLM response from the LLM call.
969974 model_response_event: A mutable event for the LLM response.
975+ function_call_id_cache: Optional dict mapping function call names to
976+ previously generated IDs. Keeps IDs stable across partial and final
977+ streaming events.
970978
971979 Yields:
972980 A generator of events.
@@ -1028,7 +1036,8 @@ async def _postprocess_live(
10281036
10291037 # Builds the event.
10301038 model_response_event = self ._finalize_model_response_event (
1031- llm_request , llm_response , model_response_event
1039+ llm_request , llm_response , model_response_event ,
1040+ function_call_id_cache ,
10321041 )
10331042 yield model_response_event
10341043
0 commit comments