Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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."""

Expand All @@ -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."""
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -16,13 +17,18 @@ 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."""

sequence_number: int
"""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.
"""
49 changes: 49 additions & 0 deletions tests/test_response_function_call_arguments_done_event.py
Original file line number Diff line number Diff line change
@@ -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)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Use Pydantic-v1-compatible validation in tests

In the pydantic-v1 CI session (noxfile.py installs pydantic<2 and runs the full pytest suite), this new test file fails before exercising the fix: under Pydantic v1 these models do not expose model_validate, and the later union test also calls pydantic.TypeAdapter, which is v2-only. Using the repository's compatibility helpers (or otherwise gating the v2-only union assertion) keeps the tests passing for the supported pydantic>=1.9.0,<3 range.

Useful? React with 👍 / 👎.

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