| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- """Tests for handling LiteLLM/Chat Completions placeholder IDs.
- When using non-Responses API models (LiteLLM, Chat Completions), the SDK emits
- `item.id = "__fake_id__"` for all output items. This causes collisions when
- using item.id as a map key. These tests verify the fix: skip placeholder IDs
- and use call_id for correlation instead.
- """
- from types import SimpleNamespace
- import pytest
- from agents.models.fake_id import FAKE_RESPONSES_ID
- pytest.importorskip("ag_ui")
- from ag_ui.core import ToolCallArgsEvent
- from openai.types.responses import ResponseFunctionToolCall
- from openai.types.responses.response_function_call_arguments_delta_event import (
- ResponseFunctionCallArgumentsDeltaEvent,
- )
- from openai.types.responses.response_output_item_added_event import ResponseOutputItemAddedEvent
- from agency_swarm.ui.core.agui_adapter import AguiAdapter
- def make_raw_event(data):
- return SimpleNamespace(type="raw_response_event", data=data)
- class TestAguiAdapterFakeIdHandling:
- """Tests for agui_adapter handling of __fake_id__ placeholder."""
- def test_multiple_tool_calls_with_fake_id_are_tracked_separately(self):
- """Multiple tool calls sharing __fake_id__ should each be tracked by call_id."""
- adapter = AguiAdapter()
- run_id = "fake-id-run"
- # First tool call with __fake_id__
- tool1 = ResponseFunctionToolCall(
- arguments="{}",
- call_id="call_first_tool",
- name="tool_one",
- type="function_call",
- id=FAKE_RESPONSES_ID, # Same placeholder ID
- status="in_progress",
- )
- # Second tool call with same __fake_id__
- tool2 = ResponseFunctionToolCall(
- arguments="{}",
- call_id="call_second_tool",
- name="tool_two",
- type="function_call",
- id=FAKE_RESPONSES_ID, # Same placeholder ID
- status="in_progress",
- )
- # Register first tool
- adapter.openai_to_agui_events(
- make_raw_event(
- ResponseOutputItemAddedEvent(
- item=tool1,
- output_index=0,
- sequence_number=1,
- type="response.output_item.added",
- )
- ),
- run_id=run_id,
- )
- # Register second tool
- adapter.openai_to_agui_events(
- make_raw_event(
- ResponseOutputItemAddedEvent(
- item=tool2,
- output_index=1,
- sequence_number=2,
- type="response.output_item.added",
- )
- ),
- run_id=run_id,
- )
- # Send delta for first tool - should map to call_first_tool
- # Using call_id directly since item_id is the placeholder
- delta1_event = adapter.openai_to_agui_events(
- make_raw_event(
- ResponseFunctionCallArgumentsDeltaEvent(
- item_id=FAKE_RESPONSES_ID,
- delta='{"arg1": "value1"}',
- output_index=0, # First tool's output_index
- sequence_number=3,
- type="response.function_call_arguments.delta",
- )
- ),
- run_id=run_id,
- )
- # Send delta for second tool - should map to call_second_tool
- delta2_event = adapter.openai_to_agui_events(
- make_raw_event(
- ResponseFunctionCallArgumentsDeltaEvent(
- item_id=FAKE_RESPONSES_ID,
- delta='{"arg2": "value2"}',
- output_index=1, # Second tool's output_index
- sequence_number=4,
- type="response.function_call_arguments.delta",
- )
- ),
- run_id=run_id,
- )
- # Both deltas should be properly mapped to different call_ids
- assert isinstance(delta1_event, ToolCallArgsEvent)
- assert isinstance(delta2_event, ToolCallArgsEvent)
- assert delta1_event.tool_call_id == "call_first_tool"
- assert delta2_event.tool_call_id == "call_second_tool"
- def test_tool_call_with_real_id_still_works(self):
- """Tool calls with real item IDs should continue to work."""
- adapter = AguiAdapter()
- run_id = "real-id-run"
- tool = ResponseFunctionToolCall(
- arguments="{}",
- call_id="call_real",
- name="real_tool",
- type="function_call",
- id="real_item_id", # Real ID, not placeholder
- status="in_progress",
- )
- adapter.openai_to_agui_events(
- make_raw_event(
- ResponseOutputItemAddedEvent(
- item=tool,
- output_index=0,
- sequence_number=1,
- type="response.output_item.added",
- )
- ),
- run_id=run_id,
- )
- delta_event = adapter.openai_to_agui_events(
- make_raw_event(
- ResponseFunctionCallArgumentsDeltaEvent(
- item_id="real_item_id",
- delta='{"key": "value"}',
- output_index=0,
- sequence_number=2,
- type="response.function_call_arguments.delta",
- )
- ),
- run_id=run_id,
- )
- assert isinstance(delta_event, ToolCallArgsEvent)
- assert delta_event.tool_call_id == "call_real"
|