fix(responses): keep a dict tool call's thought signature on the streamed function_call done item

This commit is contained in:
mateo-berri 2026-10-29 12:23:59 -07:00
parent 0e68a20812
commit 765b129ab4
2 changed files with 29 additions and 1 deletions

View file

@ -93,7 +93,12 @@ def _tool_call_objects(tool_calls: object) -> tuple[object, ...]:
def _tool_call_provider_specific_fields(tool_call: object) -> Mapping[str, object]:
fields: Final[object] = getattr(tool_call, "provider_specific_fields", None)
mapping: Final = as_str_mapping(tool_call)
fields: Final[object] = (
mapping.get("provider_specific_fields")
if mapping is not None
else getattr(tool_call, "provider_specific_fields", None)
)
return {"provider_specific_fields": fields} if fields else {}

View file

@ -4746,6 +4746,29 @@ class TestEnsureOutputItemContentPartAdded:
assert done.item.name == "spawn_agent"
assert done.item.namespace == "collaboration"
def test_streaming_final_only_dict_tool_call_keeps_its_provider_specific_fields(self):
from unittest.mock import MagicMock
iterator = self._make_iterator()
iterator.tool_call_provider_fields = True
provider_specific_fields = {"thought_signature": "sig-" + "x" * 512}
message = MagicMock()
message.tool_calls = [
{
"id": "call_1",
"function": {"name": "get_weather", "arguments": '{"city":"Paris"}'},
"provider_specific_fields": provider_specific_fields,
}
]
complete_response = MagicMock()
complete_response.choices = [MagicMock(message=message)]
iterator._queue_final_tool_call_done_events(complete_response)
done = iterator._pending_tool_events[-1]
assert done.type == "response.output_item.done"
assert done.item.provider_specific_fields == provider_specific_fields
def test_streaming_top_level_function_collision_stays_unnamespaced(self):
iterator = self._make_iterator()
iterator.responses_api_request = {