diff --git a/src/openai/lib/streaming/responses/__init__.py b/src/openai/lib/streaming/responses/__init__.py index ff073633bf..019dbaa7fd 100644 --- a/src/openai/lib/streaming/responses/__init__.py +++ b/src/openai/lib/streaming/responses/__init__.py @@ -2,6 +2,7 @@ ResponseTextDoneEvent as ResponseTextDoneEvent, ResponseTextDeltaEvent as ResponseTextDeltaEvent, ResponseFunctionCallArgumentsDeltaEvent as ResponseFunctionCallArgumentsDeltaEvent, + ResponseFunctionCallArgumentsDoneEvent as ResponseFunctionCallArgumentsDoneEvent, ) from ._responses import ( ResponseStream as ResponseStream, diff --git a/src/openai/lib/streaming/responses/_responses.py b/src/openai/lib/streaming/responses/_responses.py index 6975a9260d..d1596f4b71 100644 --- a/src/openai/lib/streaming/responses/_responses.py +++ b/src/openai/lib/streaming/responses/_responses.py @@ -12,13 +12,14 @@ ResponseCompletedEvent, ResponseTextDeltaEvent, ResponseFunctionCallArgumentsDeltaEvent, + ResponseFunctionCallArgumentsDoneEvent, ) from ...._types import Omit, omit from ...._utils import is_given, consume_sync_iterator, consume_async_iterator from ...._models import build, construct_type_unchecked from ...._streaming import Stream, AsyncStream from ....types.responses import ParsedResponse, ResponseStreamEvent as RawResponseStreamEvent -from ..._parsing._responses import TextFormatT, parse_text, parse_response +from ..._parsing._responses import TextFormatT, parse_text, parse_response, parse_function_tool_arguments from ....types.responses.tool_param import ToolParam from ....types.responses.parsed_response import ( ParsedContent, @@ -305,6 +306,30 @@ def handle_event(self, event: RawResponseStreamEvent) -> List[ResponseStreamEven ) ) + elif event.type == "response.function_call_arguments.done": + output = snapshot.output[event.output_index] + assert output.type == "function_call" + + # Parse arguments using input_tools + parsed_arguments = parse_function_tool_arguments( + input_tools=self._input_tools, + function_call=output + ) + output.parsed_arguments = parsed_arguments + + # Emit event with name from accumulated snapshot + events.append( + build( + ResponseFunctionCallArgumentsDoneEvent, + arguments=event.arguments, # Use event as source of truth + item_id=event.item_id, + name=output.name, # FROM SNAPSHOT, not raw event + output_index=event.output_index, + sequence_number=event.sequence_number, + type="response.function_call_arguments.done", + ) + ) + elif event.type == "response.completed": response = self._completed_response assert response is not None