# Copyright (c) Microsoft. All rights reserved. """Tests for backend tool rendering.""" from ag_ui.core import ( TextMessageContentEvent, TextMessageStartEvent, ToolCallArgsEvent, ToolCallEndEvent, ToolCallResultEvent, ToolCallStartEvent, ) from agent_framework import AgentRunResponseUpdate, FunctionCallContent, FunctionResultContent, TextContent from agent_framework_ag_ui._events import AgentFrameworkEventBridge async def test_tool_call_flow(): """Test complete tool call flow: call -> args -> end -> result.""" bridge = AgentFrameworkEventBridge(run_id="test-run", thread_id="test-thread") # Step 1: Tool call starts tool_call = FunctionCallContent( call_id="weather-123", name="get_weather", arguments={"location": "Seattle"}, ) update1 = AgentRunResponseUpdate(contents=[tool_call]) events1 = await bridge.from_agent_run_update(update1) # Should have: ToolCallStartEvent, ToolCallArgsEvent assert len(events1) == 2 assert isinstance(events1[0], ToolCallStartEvent) assert isinstance(events1[1], ToolCallArgsEvent) start_event = events1[0] assert start_event.tool_call_id == "weather-123" assert start_event.tool_call_name == "get_weather" args_event = events1[1] assert "Seattle" in args_event.delta # Step 2: Tool result comes back tool_result = FunctionResultContent( call_id="weather-123", result="Weather in Seattle: Rainy, 52°F", ) update2 = AgentRunResponseUpdate(contents=[tool_result]) events2 = await bridge.from_agent_run_update(update2) # Should have: ToolCallEndEvent, ToolCallResultEvent, MessagesSnapshotEvent assert len(events2) == 3 assert isinstance(events2[0], ToolCallEndEvent) assert isinstance(events2[1], ToolCallResultEvent) end_event = events2[0] assert end_event.tool_call_id == "weather-123" result_event = events2[1] assert result_event.tool_call_id == "weather-123" assert "Seattle" in result_event.content assert "Rainy" in result_event.content async def test_text_with_tool_call(): """Test agent response with both text and tool calls.""" bridge = AgentFrameworkEventBridge(run_id="test-run", thread_id="test-thread") # Agent says something then calls a tool text_content = TextContent(text="Let me check the weather for you.") tool_call = FunctionCallContent( call_id="weather-456", name="get_forecast", arguments={"location": "San Francisco", "days": 3}, ) update = AgentRunResponseUpdate(contents=[text_content, tool_call]) events = await bridge.from_agent_run_update(update) # Should have: TextMessageStart, TextMessageContent, ToolCallStart, ToolCallArgs assert len(events) == 4 assert isinstance(events[0], TextMessageStartEvent) assert isinstance(events[1], TextMessageContentEvent) assert isinstance(events[2], ToolCallStartEvent) assert isinstance(events[3], ToolCallArgsEvent) text_event = events[1] assert "check the weather" in text_event.delta tool_start = events[2] assert tool_start.tool_call_name == "get_forecast" async def test_multiple_tool_results(): """Test handling multiple tool results in sequence.""" bridge = AgentFrameworkEventBridge(run_id="test-run", thread_id="test-thread") # Multiple tool results results = [ FunctionResultContent(call_id="tool-1", result="Result 1"), FunctionResultContent(call_id="tool-2", result="Result 2"), FunctionResultContent(call_id="tool-3", result="Result 3"), ] update = AgentRunResponseUpdate(contents=results) events = await bridge.from_agent_run_update(update) # Should have 3 pairs of ToolCallEndEvent + ToolCallResultEvent = 6 events assert len(events) == 6 # Verify the pattern: End, Result, End, Result, End, Result for i in range(3): end_idx = i * 2 result_idx = i * 2 + 1 assert isinstance(events[end_idx], ToolCallEndEvent) assert isinstance(events[result_idx], ToolCallResultEvent) assert events[end_idx].tool_call_id == f"tool-{i + 1}" assert events[result_idx].tool_call_id == f"tool-{i + 1}" assert f"Result {i + 1}" in events[result_idx].content