diff --git a/src/openai/types/beta/beta_response_function_call_arguments_done_event.py b/src/openai/types/beta/beta_response_function_call_arguments_done_event.py index b9ded692bb..bdda249db7 100644 --- a/src/openai/types/beta/beta_response_function_call_arguments_done_event.py +++ b/src/openai/types/beta/beta_response_function_call_arguments_done_event.py @@ -24,9 +24,6 @@ class BetaResponseFunctionCallArgumentsDoneEvent(BaseModel): item_id: str """The ID of the item.""" - name: str - """The name of the function that was called.""" - output_index: int """The index of the output item.""" @@ -35,5 +32,13 @@ class BetaResponseFunctionCallArgumentsDoneEvent(BaseModel): type: Literal["response.function_call_arguments.done"] + name: Optional[str] = None + """The name of the function that was called. + + The live Responses API may omit this field on + `response.function_call_arguments.done` events; correlate via `item_id` when + absent. + """ + agent: Optional[Agent] = None """The agent that owns this multi-agent streaming event.""" diff --git a/src/openai/types/responses/response_function_call_arguments_done_event.py b/src/openai/types/responses/response_function_call_arguments_done_event.py index 543cd073a2..5810dac169 100644 --- a/src/openai/types/responses/response_function_call_arguments_done_event.py +++ b/src/openai/types/responses/response_function_call_arguments_done_event.py @@ -1,5 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +from typing import Optional from typing_extensions import Literal from ..._models import BaseModel @@ -16,9 +17,6 @@ class ResponseFunctionCallArgumentsDoneEvent(BaseModel): item_id: str """The ID of the item.""" - name: str - """The name of the function that was called.""" - output_index: int """The index of the output item.""" @@ -26,3 +24,11 @@ class ResponseFunctionCallArgumentsDoneEvent(BaseModel): """The sequence number of this event.""" type: Literal["response.function_call_arguments.done"] + + name: Optional[str] = None + """The name of the function that was called. + + The live Responses API may omit this field on + `response.function_call_arguments.done` events; correlate via `item_id` when + absent. + """ diff --git a/tests/test_response_function_call_arguments_done_event.py b/tests/test_response_function_call_arguments_done_event.py new file mode 100644 index 0000000000..8595a92eae --- /dev/null +++ b/tests/test_response_function_call_arguments_done_event.py @@ -0,0 +1,49 @@ +from __future__ import annotations + +import pydantic +import pytest + +from openai.types.beta.beta_response_function_call_arguments_done_event import ( + BetaResponseFunctionCallArgumentsDoneEvent, +) +from openai.types.responses.response_function_call_arguments_done_event import ( + ResponseFunctionCallArgumentsDoneEvent, +) +from openai.types.responses.response_stream_event import ResponseStreamEvent + + +PAYLOAD_WITHOUT_NAME = { + "type": "response.function_call_arguments.done", + "arguments": "{\"city\": \"Paris\"}", + "item_id": "fc_test_item", + "output_index": 2, + "sequence_number": 10, +} + + +def test_function_call_arguments_done_accepts_missing_name() -> None: + """Live Responses API may omit `name` on done events (issue #3472).""" + event = ResponseFunctionCallArgumentsDoneEvent.model_validate(PAYLOAD_WITHOUT_NAME) + assert event.type == "response.function_call_arguments.done" + assert event.item_id == "fc_test_item" + assert event.name is None + assert event.arguments == '{"city": "Paris"}' + + +def test_function_call_arguments_done_keeps_name_when_present() -> None: + event = ResponseFunctionCallArgumentsDoneEvent.model_validate( + {**PAYLOAD_WITHOUT_NAME, "name": "get_weather"} + ) + assert event.name == "get_weather" + + +def test_response_stream_event_union_accepts_done_without_name() -> None: + # Strict union validation previously failed with missing: name. + event = pydantic.TypeAdapter(ResponseStreamEvent).validate_python(PAYLOAD_WITHOUT_NAME) + assert isinstance(event, ResponseFunctionCallArgumentsDoneEvent) + assert event.name is None + + +def test_beta_function_call_arguments_done_accepts_missing_name() -> None: + event = BetaResponseFunctionCallArgumentsDoneEvent.model_validate(PAYLOAD_WITHOUT_NAME) + assert event.name is None