mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
renamed all (#3207)
This commit is contained in:
committed by
GitHub
Unverified
parent
1ae0b09e42
commit
d8cf8361bd
@@ -24,7 +24,7 @@ from ag_ui.core import (
|
||||
ToolCallStartEvent,
|
||||
)
|
||||
from agent_framework import (
|
||||
AgentRunResponseUpdate,
|
||||
AgentResponseUpdate,
|
||||
FunctionApprovalRequestContent,
|
||||
FunctionCallContent,
|
||||
FunctionResultContent,
|
||||
@@ -81,9 +81,9 @@ class AgentFrameworkEventBridge:
|
||||
self.should_stop_after_confirm: bool = False # Flag to stop run after confirm_changes
|
||||
self.suppressed_summary: str = "" # Store LLM summary to show after confirmation
|
||||
|
||||
async def from_agent_run_update(self, update: AgentRunResponseUpdate) -> list[BaseEvent]:
|
||||
async def from_agent_run_update(self, update: AgentResponseUpdate) -> list[BaseEvent]:
|
||||
"""
|
||||
Convert an AgentRunResponseUpdate to AG-UI events.
|
||||
Convert an AgentResponseUpdate to AG-UI events.
|
||||
|
||||
Args:
|
||||
update: The agent run update to convert.
|
||||
|
||||
@@ -646,11 +646,11 @@ class DefaultOrchestrator(Orchestrator):
|
||||
yield end_event
|
||||
|
||||
if response_format and all_updates:
|
||||
from agent_framework import AgentRunResponse
|
||||
from agent_framework import AgentResponse
|
||||
from pydantic import BaseModel
|
||||
|
||||
logger.info(f"Processing structured output, update count: {len(all_updates)}")
|
||||
final_response = AgentRunResponse.from_agent_run_response_updates(
|
||||
final_response = AgentResponse.from_agent_run_response_updates(
|
||||
all_updates, output_format_type=response_format
|
||||
)
|
||||
|
||||
|
||||
@@ -169,7 +169,7 @@ The package uses a clean, orchestrator-based architecture:
|
||||
- **AgentFrameworkAgent**: Lightweight wrapper that delegates to orchestrators
|
||||
- **Orchestrators**: Handle different execution flows (default, human-in-the-loop, etc.)
|
||||
- **Confirmation Strategies**: Domain-specific confirmation messages (extensible)
|
||||
- **AgentFrameworkEventBridge**: Converts AgentRunResponseUpdate to AG-UI events
|
||||
- **AgentFrameworkEventBridge**: Converts AgentResponseUpdate to AG-UI events
|
||||
- **Message Adapters**: Bidirectional conversion between AG-UI and Agent Framework message formats
|
||||
- **FastAPI Endpoint**: Streaming HTTP endpoint with Server-Sent Events (SSE)
|
||||
|
||||
@@ -198,10 +198,10 @@ def my_tool(param: str) -> str:
|
||||
|
||||
def my_custom_agent(chat_client: ChatClientProtocol) -> AgentFrameworkAgent:
|
||||
"""Create a custom agent with the specified chat client.
|
||||
|
||||
|
||||
Args:
|
||||
chat_client: The chat client to use for the agent
|
||||
|
||||
|
||||
Returns:
|
||||
A configured AgentFrameworkAgent instance
|
||||
"""
|
||||
@@ -211,7 +211,7 @@ def my_custom_agent(chat_client: ChatClientProtocol) -> AgentFrameworkAgent:
|
||||
chat_client=chat_client,
|
||||
tools=[my_tool],
|
||||
)
|
||||
|
||||
|
||||
return AgentFrameworkAgent(
|
||||
agent=agent,
|
||||
name="MyCustomAgent",
|
||||
@@ -302,13 +302,13 @@ from agent_framework.ag_ui import AgentFrameworkAgent, ConfirmationStrategy
|
||||
class CustomConfirmationStrategy(ConfirmationStrategy):
|
||||
def on_approval_accepted(self, steps: list[dict[str, Any]]) -> str:
|
||||
return "Your custom approval message!"
|
||||
|
||||
|
||||
def on_approval_rejected(self, steps: list[dict[str, Any]]) -> str:
|
||||
return "Your custom rejection message!"
|
||||
|
||||
|
||||
def on_state_confirmed(self) -> str:
|
||||
return "State changes confirmed!"
|
||||
|
||||
|
||||
def on_state_rejected(self) -> str:
|
||||
return "State changes rejected!"
|
||||
|
||||
@@ -349,7 +349,7 @@ class MyCustomOrchestrator(Orchestrator):
|
||||
def can_handle(self, context: ExecutionContext) -> bool:
|
||||
# Return True if this orchestrator should handle the request
|
||||
return context.input_data.get("custom_mode") == True
|
||||
|
||||
|
||||
async def run(self, context: ExecutionContext):
|
||||
# Custom execution logic
|
||||
yield RunStartedEvent(...)
|
||||
|
||||
@@ -12,7 +12,7 @@ from ag_ui.core import (
|
||||
ToolCallResultEvent,
|
||||
ToolCallStartEvent,
|
||||
)
|
||||
from agent_framework import AgentRunResponseUpdate, FunctionCallContent, FunctionResultContent, TextContent
|
||||
from agent_framework import AgentResponseUpdate, FunctionCallContent, FunctionResultContent, TextContent
|
||||
|
||||
from agent_framework_ag_ui._events import AgentFrameworkEventBridge
|
||||
|
||||
@@ -28,7 +28,7 @@ async def test_tool_call_flow():
|
||||
arguments={"location": "Seattle"},
|
||||
)
|
||||
|
||||
update1 = AgentRunResponseUpdate(contents=[tool_call])
|
||||
update1 = AgentResponseUpdate(contents=[tool_call])
|
||||
events1 = await bridge.from_agent_run_update(update1)
|
||||
|
||||
# Should have: ToolCallStartEvent, ToolCallArgsEvent
|
||||
@@ -49,7 +49,7 @@ async def test_tool_call_flow():
|
||||
result="Weather in Seattle: Rainy, 52°F",
|
||||
)
|
||||
|
||||
update2 = AgentRunResponseUpdate(contents=[tool_result])
|
||||
update2 = AgentResponseUpdate(contents=[tool_result])
|
||||
events2 = await bridge.from_agent_run_update(update2)
|
||||
|
||||
# Should have: ToolCallEndEvent, ToolCallResultEvent
|
||||
@@ -78,7 +78,7 @@ async def test_text_with_tool_call():
|
||||
arguments={"location": "San Francisco", "days": 3},
|
||||
)
|
||||
|
||||
update = AgentRunResponseUpdate(contents=[text_content, tool_call])
|
||||
update = AgentResponseUpdate(contents=[text_content, tool_call])
|
||||
events = await bridge.from_agent_run_update(update)
|
||||
|
||||
# Should have: TextMessageStart, TextMessageContent, ToolCallStart, ToolCallArgs
|
||||
@@ -107,7 +107,7 @@ async def test_multiple_tool_results():
|
||||
FunctionResultContent(call_id="tool-3", result="Result 3"),
|
||||
]
|
||||
|
||||
update = AgentRunResponseUpdate(contents=results)
|
||||
update = AgentResponseUpdate(contents=results)
|
||||
events = await bridge.from_agent_run_update(update)
|
||||
|
||||
# Should have 3 pairs of ToolCallEndEvent + ToolCallResultEvent = 6 events
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"""Tests for document writer predictive state flow with confirm_changes."""
|
||||
|
||||
from ag_ui.core import EventType, StateDeltaEvent, ToolCallArgsEvent, ToolCallEndEvent, ToolCallStartEvent
|
||||
from agent_framework import AgentRunResponseUpdate, FunctionCallContent, FunctionResultContent, TextContent
|
||||
from agent_framework import AgentResponseUpdate, FunctionCallContent, FunctionResultContent, TextContent
|
||||
|
||||
from agent_framework_ag_ui._events import AgentFrameworkEventBridge
|
||||
|
||||
@@ -26,7 +26,7 @@ async def test_streaming_document_with_state_deltas():
|
||||
name="write_document_local",
|
||||
arguments='{"document":"Once',
|
||||
)
|
||||
update1 = AgentRunResponseUpdate(contents=[tool_call_start])
|
||||
update1 = AgentResponseUpdate(contents=[tool_call_start])
|
||||
events1 = await bridge.from_agent_run_update(update1)
|
||||
|
||||
# Should have ToolCallStartEvent and ToolCallArgsEvent
|
||||
@@ -35,7 +35,7 @@ async def test_streaming_document_with_state_deltas():
|
||||
|
||||
# Second chunk - incomplete JSON, should try partial extraction
|
||||
tool_call_chunk2 = FunctionCallContent(call_id="call_123", name="write_document_local", arguments=" upon a time")
|
||||
update2 = AgentRunResponseUpdate(contents=[tool_call_chunk2])
|
||||
update2 = AgentResponseUpdate(contents=[tool_call_chunk2])
|
||||
events2 = await bridge.from_agent_run_update(update2)
|
||||
|
||||
# Should emit StateDeltaEvent with partial document
|
||||
@@ -76,7 +76,7 @@ async def test_confirm_changes_emission():
|
||||
result="Document written.",
|
||||
)
|
||||
|
||||
update = AgentRunResponseUpdate(contents=[tool_result])
|
||||
update = AgentResponseUpdate(contents=[tool_result])
|
||||
events = await bridge.from_agent_run_update(update)
|
||||
|
||||
# Should have: ToolCallEndEvent, ToolCallResultEvent, StateSnapshotEvent, confirm_changes sequence
|
||||
@@ -116,7 +116,7 @@ async def test_text_suppression_before_confirm():
|
||||
|
||||
# Text content that should be suppressed
|
||||
text = TextContent(text="I have written a story about pirates.")
|
||||
update = AgentRunResponseUpdate(contents=[text])
|
||||
update = AgentResponseUpdate(contents=[text])
|
||||
|
||||
events = await bridge.from_agent_run_update(update)
|
||||
|
||||
@@ -151,7 +151,7 @@ async def test_no_confirm_for_non_predictive_tools():
|
||||
result="Sunny, 72°F",
|
||||
)
|
||||
|
||||
update = AgentRunResponseUpdate(contents=[tool_result])
|
||||
update = AgentResponseUpdate(contents=[tool_result])
|
||||
events = await bridge.from_agent_run_update(update)
|
||||
|
||||
# Should NOT have confirm_changes
|
||||
@@ -180,7 +180,7 @@ async def test_state_delta_deduplication():
|
||||
name="write_document_local",
|
||||
arguments='{"document":"Same text"}',
|
||||
)
|
||||
update1 = AgentRunResponseUpdate(contents=[tool_call1])
|
||||
update1 = AgentResponseUpdate(contents=[tool_call1])
|
||||
events1 = await bridge.from_agent_run_update(update1)
|
||||
|
||||
# Count state deltas
|
||||
@@ -194,7 +194,7 @@ async def test_state_delta_deduplication():
|
||||
name="write_document_local",
|
||||
arguments='{"document":"Same text"}', # Identical content
|
||||
)
|
||||
update2 = AgentRunResponseUpdate(contents=[tool_call2])
|
||||
update2 = AgentResponseUpdate(contents=[tool_call2])
|
||||
events2 = await bridge.from_agent_run_update(update2)
|
||||
|
||||
# Should NOT emit state delta (same value)
|
||||
@@ -221,7 +221,7 @@ async def test_predict_state_config_multiple_fields():
|
||||
name="create_post",
|
||||
arguments='{"title":"My Post","body":"Post content"}',
|
||||
)
|
||||
update = AgentRunResponseUpdate(contents=[tool_call])
|
||||
update = AgentResponseUpdate(contents=[tool_call])
|
||||
events = await bridge.from_agent_run_update(update)
|
||||
|
||||
# Should emit StateDeltaEvent for both fields
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
import json
|
||||
|
||||
from agent_framework import (
|
||||
AgentRunResponseUpdate,
|
||||
AgentResponseUpdate,
|
||||
FunctionApprovalRequestContent,
|
||||
FunctionCallContent,
|
||||
FunctionResultContent,
|
||||
@@ -19,7 +19,7 @@ async def test_basic_text_message_conversion():
|
||||
|
||||
bridge = AgentFrameworkEventBridge(run_id="test_run", thread_id="test_thread")
|
||||
|
||||
update = AgentRunResponseUpdate(contents=[TextContent(text="Hello")])
|
||||
update = AgentResponseUpdate(contents=[TextContent(text="Hello")])
|
||||
events = await bridge.from_agent_run_update(update)
|
||||
|
||||
assert len(events) == 2
|
||||
@@ -35,8 +35,8 @@ async def test_text_message_streaming():
|
||||
|
||||
bridge = AgentFrameworkEventBridge(run_id="test_run", thread_id="test_thread")
|
||||
|
||||
update1 = AgentRunResponseUpdate(contents=[TextContent(text="Hello ")])
|
||||
update2 = AgentRunResponseUpdate(contents=[TextContent(text="world")])
|
||||
update1 = AgentResponseUpdate(contents=[TextContent(text="Hello ")])
|
||||
update2 = AgentResponseUpdate(contents=[TextContent(text="world")])
|
||||
|
||||
events1 = await bridge.from_agent_run_update(update1)
|
||||
events2 = await bridge.from_agent_run_update(update2)
|
||||
@@ -61,7 +61,7 @@ async def test_skip_text_content_for_structured_outputs():
|
||||
|
||||
bridge = AgentFrameworkEventBridge(run_id="test_run", thread_id="test_thread", skip_text_content=True)
|
||||
|
||||
update = AgentRunResponseUpdate(contents=[TextContent(text='{"result": "data"}')])
|
||||
update = AgentResponseUpdate(contents=[TextContent(text='{"result": "data"}')])
|
||||
events = await bridge.from_agent_run_update(update)
|
||||
|
||||
# No events should be emitted
|
||||
@@ -74,9 +74,9 @@ async def test_skip_text_content_for_empty_text():
|
||||
|
||||
bridge = AgentFrameworkEventBridge(run_id="test_run", thread_id="test_thread")
|
||||
|
||||
update1 = AgentRunResponseUpdate(contents=[TextContent(text="Hello ")])
|
||||
update2 = AgentRunResponseUpdate(contents=[TextContent(text="")]) # Empty chunk
|
||||
update3 = AgentRunResponseUpdate(contents=[TextContent(text="world")])
|
||||
update1 = AgentResponseUpdate(contents=[TextContent(text="Hello ")])
|
||||
update2 = AgentResponseUpdate(contents=[TextContent(text="")]) # Empty chunk
|
||||
update3 = AgentResponseUpdate(contents=[TextContent(text="world")])
|
||||
|
||||
events1 = await bridge.from_agent_run_update(update1)
|
||||
events2 = await bridge.from_agent_run_update(update2)
|
||||
@@ -105,7 +105,7 @@ async def test_tool_call_with_name():
|
||||
|
||||
bridge = AgentFrameworkEventBridge(run_id="test_run", thread_id="test_thread")
|
||||
|
||||
update = AgentRunResponseUpdate(contents=[FunctionCallContent(name="search_web", call_id="call_123")])
|
||||
update = AgentResponseUpdate(contents=[FunctionCallContent(name="search_web", call_id="call_123")])
|
||||
events = await bridge.from_agent_run_update(update)
|
||||
|
||||
assert len(events) == 1
|
||||
@@ -121,17 +121,15 @@ async def test_tool_call_streaming_args():
|
||||
bridge = AgentFrameworkEventBridge(run_id="test_run", thread_id="test_thread")
|
||||
|
||||
# First chunk: name only
|
||||
update1 = AgentRunResponseUpdate(contents=[FunctionCallContent(name="search_web", call_id="call_123")])
|
||||
update1 = AgentResponseUpdate(contents=[FunctionCallContent(name="search_web", call_id="call_123")])
|
||||
events1 = await bridge.from_agent_run_update(update1)
|
||||
|
||||
# Second chunk: arguments chunk 1 (name can be empty string for continuation)
|
||||
update2 = AgentRunResponseUpdate(
|
||||
contents=[FunctionCallContent(name="", call_id="call_123", arguments='{"query": "')]
|
||||
)
|
||||
update2 = AgentResponseUpdate(contents=[FunctionCallContent(name="", call_id="call_123", arguments='{"query": "')])
|
||||
events2 = await bridge.from_agent_run_update(update2)
|
||||
|
||||
# Third chunk: arguments chunk 2
|
||||
update3 = AgentRunResponseUpdate(contents=[FunctionCallContent(name="", call_id="call_123", arguments='AI"}')])
|
||||
update3 = AgentResponseUpdate(contents=[FunctionCallContent(name="", call_id="call_123", arguments='AI"}')])
|
||||
events3 = await bridge.from_agent_run_update(update3)
|
||||
|
||||
# First update: ToolCallStartEvent
|
||||
@@ -169,9 +167,9 @@ async def test_streaming_tool_call_no_duplicate_start_events():
|
||||
bridge = AgentFrameworkEventBridge(run_id="test_run", thread_id="test_thread")
|
||||
|
||||
# Simulate streaming tool call: first chunk has name, subsequent chunks have name=""
|
||||
update1 = AgentRunResponseUpdate(contents=[FunctionCallContent(name="get_weather", call_id="call_789")])
|
||||
update2 = AgentRunResponseUpdate(contents=[FunctionCallContent(name="", call_id="call_789", arguments='{"loc":')])
|
||||
update3 = AgentRunResponseUpdate(contents=[FunctionCallContent(name="", call_id="call_789", arguments='"SF"}')])
|
||||
update1 = AgentResponseUpdate(contents=[FunctionCallContent(name="get_weather", call_id="call_789")])
|
||||
update2 = AgentResponseUpdate(contents=[FunctionCallContent(name="", call_id="call_789", arguments='{"loc":')])
|
||||
update3 = AgentResponseUpdate(contents=[FunctionCallContent(name="", call_id="call_789", arguments='"SF"}')])
|
||||
|
||||
events1 = await bridge.from_agent_run_update(update1)
|
||||
events2 = await bridge.from_agent_run_update(update2)
|
||||
@@ -195,7 +193,7 @@ async def test_tool_result_with_dict():
|
||||
bridge = AgentFrameworkEventBridge(run_id="test_run", thread_id="test_thread")
|
||||
|
||||
result_data = {"status": "success", "count": 42}
|
||||
update = AgentRunResponseUpdate(contents=[FunctionResultContent(call_id="call_123", result=result_data)])
|
||||
update = AgentResponseUpdate(contents=[FunctionResultContent(call_id="call_123", result=result_data)])
|
||||
events = await bridge.from_agent_run_update(update)
|
||||
|
||||
# Should emit ToolCallEndEvent + ToolCallResultEvent
|
||||
@@ -216,7 +214,7 @@ async def test_tool_result_with_string():
|
||||
|
||||
bridge = AgentFrameworkEventBridge(run_id="test_run", thread_id="test_thread")
|
||||
|
||||
update = AgentRunResponseUpdate(contents=[FunctionResultContent(call_id="call_123", result="Search complete")])
|
||||
update = AgentResponseUpdate(contents=[FunctionResultContent(call_id="call_123", result="Search complete")])
|
||||
events = await bridge.from_agent_run_update(update)
|
||||
|
||||
assert len(events) == 2
|
||||
@@ -231,7 +229,7 @@ async def test_tool_result_with_none():
|
||||
|
||||
bridge = AgentFrameworkEventBridge(run_id="test_run", thread_id="test_thread")
|
||||
|
||||
update = AgentRunResponseUpdate(contents=[FunctionResultContent(call_id="call_123", result=None)])
|
||||
update = AgentResponseUpdate(contents=[FunctionResultContent(call_id="call_123", result=None)])
|
||||
events = await bridge.from_agent_run_update(update)
|
||||
|
||||
assert len(events) == 2
|
||||
@@ -247,7 +245,7 @@ async def test_multiple_tool_results_in_sequence():
|
||||
|
||||
bridge = AgentFrameworkEventBridge(run_id="test_run", thread_id="test_thread")
|
||||
|
||||
update = AgentRunResponseUpdate(
|
||||
update = AgentResponseUpdate(
|
||||
contents=[
|
||||
FunctionResultContent(call_id="call_1", result="Result 1"),
|
||||
FunctionResultContent(call_id="call_2", result="Result 2"),
|
||||
@@ -284,7 +282,7 @@ async def test_function_approval_request_basic():
|
||||
function_call=func_call,
|
||||
)
|
||||
|
||||
update = AgentRunResponseUpdate(contents=[approval])
|
||||
update = AgentResponseUpdate(contents=[approval])
|
||||
events = await bridge.from_agent_run_update(update)
|
||||
|
||||
# Should emit: ToolCallEndEvent + CustomEvent
|
||||
@@ -312,7 +310,7 @@ async def test_empty_predict_state_config():
|
||||
)
|
||||
|
||||
# Tool call with arguments
|
||||
update = AgentRunResponseUpdate(
|
||||
update = AgentResponseUpdate(
|
||||
contents=[
|
||||
FunctionCallContent(name="write_doc", call_id="call_1", arguments='{"content": "test"}'),
|
||||
FunctionResultContent(call_id="call_1", result="Done"),
|
||||
@@ -347,7 +345,7 @@ async def test_tool_not_in_predict_state_config():
|
||||
)
|
||||
|
||||
# Different tool name
|
||||
update = AgentRunResponseUpdate(
|
||||
update = AgentResponseUpdate(
|
||||
contents=[
|
||||
FunctionCallContent(name="search_web", call_id="call_1", arguments='{"query": "AI"}'),
|
||||
FunctionResultContent(call_id="call_1", result="Results"),
|
||||
@@ -376,7 +374,7 @@ async def test_state_management_tracking():
|
||||
)
|
||||
|
||||
# Streaming tool call
|
||||
update1 = AgentRunResponseUpdate(
|
||||
update1 = AgentResponseUpdate(
|
||||
contents=[
|
||||
FunctionCallContent(name="write_doc", call_id="call_1"),
|
||||
FunctionCallContent(name="", call_id="call_1", arguments='{"content": "Hello"}'),
|
||||
@@ -389,7 +387,7 @@ async def test_state_management_tracking():
|
||||
assert bridge.pending_state_updates["document"] == "Hello"
|
||||
|
||||
# Tool result should update current_state
|
||||
update2 = AgentRunResponseUpdate(contents=[FunctionResultContent(call_id="call_1", result="Done")])
|
||||
update2 = AgentResponseUpdate(contents=[FunctionResultContent(call_id="call_1", result="Done")])
|
||||
await bridge.from_agent_run_update(update2)
|
||||
|
||||
# current_state should be updated
|
||||
@@ -413,7 +411,7 @@ async def test_wildcard_tool_argument():
|
||||
)
|
||||
|
||||
# Complete tool call with dict arguments
|
||||
update = AgentRunResponseUpdate(
|
||||
update = AgentResponseUpdate(
|
||||
contents=[
|
||||
FunctionCallContent(
|
||||
name="create_recipe",
|
||||
@@ -503,7 +501,7 @@ async def test_state_snapshot_after_tool_result():
|
||||
)
|
||||
|
||||
# Tool call with streaming args
|
||||
update1 = AgentRunResponseUpdate(
|
||||
update1 = AgentResponseUpdate(
|
||||
contents=[
|
||||
FunctionCallContent(name="write_doc", call_id="call_1"),
|
||||
FunctionCallContent(name="", call_id="call_1", arguments='{"content": "Test"}'),
|
||||
@@ -512,7 +510,7 @@ async def test_state_snapshot_after_tool_result():
|
||||
await bridge.from_agent_run_update(update1)
|
||||
|
||||
# Tool result should trigger StateSnapshotEvent
|
||||
update2 = AgentRunResponseUpdate(contents=[FunctionResultContent(call_id="call_1", result="Done")])
|
||||
update2 = AgentResponseUpdate(contents=[FunctionResultContent(call_id="call_1", result="Done")])
|
||||
events = await bridge.from_agent_run_update(update2)
|
||||
|
||||
# Should have: ToolCallEnd, ToolCallResult, StateSnapshot, ToolCallStart (confirm_changes), ToolCallArgs, ToolCallEnd
|
||||
@@ -528,12 +526,12 @@ async def test_message_id_persistence_across_chunks():
|
||||
bridge = AgentFrameworkEventBridge(run_id="test_run", thread_id="test_thread")
|
||||
|
||||
# First chunk
|
||||
update1 = AgentRunResponseUpdate(contents=[TextContent(text="Hello ")])
|
||||
update1 = AgentResponseUpdate(contents=[TextContent(text="Hello ")])
|
||||
events1 = await bridge.from_agent_run_update(update1)
|
||||
message_id = events1[0].message_id
|
||||
|
||||
# Second chunk
|
||||
update2 = AgentRunResponseUpdate(contents=[TextContent(text="world")])
|
||||
update2 = AgentResponseUpdate(contents=[TextContent(text="world")])
|
||||
events2 = await bridge.from_agent_run_update(update2)
|
||||
|
||||
# Should use same message_id
|
||||
@@ -548,14 +546,14 @@ async def test_tool_call_id_tracking():
|
||||
bridge = AgentFrameworkEventBridge(run_id="test_run", thread_id="test_thread")
|
||||
|
||||
# First chunk with name
|
||||
update1 = AgentRunResponseUpdate(contents=[FunctionCallContent(name="search", call_id="call_1")])
|
||||
update1 = AgentResponseUpdate(contents=[FunctionCallContent(name="search", call_id="call_1")])
|
||||
await bridge.from_agent_run_update(update1)
|
||||
|
||||
assert bridge.current_tool_call_id == "call_1"
|
||||
assert bridge.current_tool_call_name == "search"
|
||||
|
||||
# Second chunk with args but no name
|
||||
update2 = AgentRunResponseUpdate(contents=[FunctionCallContent(name="", call_id="call_1", arguments='{"q":"AI"}')])
|
||||
update2 = AgentResponseUpdate(contents=[FunctionCallContent(name="", call_id="call_1", arguments='{"q":"AI"}')])
|
||||
events2 = await bridge.from_agent_run_update(update2)
|
||||
|
||||
# Should still track same tool call
|
||||
@@ -576,7 +574,7 @@ async def test_tool_name_reset_after_result():
|
||||
)
|
||||
|
||||
# Tool call
|
||||
update1 = AgentRunResponseUpdate(
|
||||
update1 = AgentResponseUpdate(
|
||||
contents=[
|
||||
FunctionCallContent(name="write_doc", call_id="call_1"),
|
||||
FunctionCallContent(name="", call_id="call_1", arguments='{"content": "Test"}'),
|
||||
@@ -587,7 +585,7 @@ async def test_tool_name_reset_after_result():
|
||||
assert bridge.current_tool_call_name == "write_doc"
|
||||
|
||||
# Tool result with predictive state (should trigger confirm_changes and reset)
|
||||
update2 = AgentRunResponseUpdate(contents=[FunctionResultContent(call_id="call_1", result="Done")])
|
||||
update2 = AgentResponseUpdate(contents=[FunctionResultContent(call_id="call_1", result="Done")])
|
||||
await bridge.from_agent_run_update(update2)
|
||||
|
||||
# Tool name should be reset
|
||||
@@ -613,7 +611,7 @@ async def test_function_approval_with_wildcard_argument():
|
||||
),
|
||||
)
|
||||
|
||||
update = AgentRunResponseUpdate(contents=[approval_content])
|
||||
update = AgentResponseUpdate(contents=[approval_content])
|
||||
events = await bridge.from_agent_run_update(update)
|
||||
|
||||
# Should emit StateSnapshotEvent with entire parsed args as value
|
||||
@@ -639,7 +637,7 @@ async def test_function_approval_missing_argument():
|
||||
function_call=FunctionCallContent(name="process", call_id="call_1", arguments='{"other_field": "value"}'),
|
||||
)
|
||||
|
||||
update = AgentRunResponseUpdate(contents=[approval_content])
|
||||
update = AgentResponseUpdate(contents=[approval_content])
|
||||
events = await bridge.from_agent_run_update(update)
|
||||
|
||||
# Should not emit StateSnapshotEvent since argument not found
|
||||
@@ -654,7 +652,7 @@ async def test_empty_predict_state_config_no_deltas():
|
||||
bridge = AgentFrameworkEventBridge(run_id="test_run", thread_id="test_thread", predict_state_config={})
|
||||
|
||||
# Tool call with arguments
|
||||
update = AgentRunResponseUpdate(
|
||||
update = AgentResponseUpdate(
|
||||
contents=[
|
||||
FunctionCallContent(name="search", call_id="call_1"),
|
||||
FunctionCallContent(name="", call_id="call_1", arguments='{"query": "test"}'),
|
||||
@@ -678,7 +676,7 @@ async def test_tool_with_no_matching_config():
|
||||
)
|
||||
|
||||
# Tool call for different tool
|
||||
update = AgentRunResponseUpdate(
|
||||
update = AgentResponseUpdate(
|
||||
contents=[
|
||||
FunctionCallContent(name="search_web", call_id="call_1"),
|
||||
FunctionCallContent(name="", call_id="call_1", arguments='{"query": "test"}'),
|
||||
@@ -698,7 +696,7 @@ async def test_tool_call_without_name_or_id():
|
||||
bridge = AgentFrameworkEventBridge(run_id="test_run", thread_id="test_thread")
|
||||
|
||||
# This should not crash but log an error
|
||||
update = AgentRunResponseUpdate(contents=[FunctionCallContent(name="", call_id="", arguments='{"arg": "val"}')])
|
||||
update = AgentResponseUpdate(contents=[FunctionCallContent(name="", call_id="", arguments='{"arg": "val"}')])
|
||||
events = await bridge.from_agent_run_update(update)
|
||||
|
||||
# Should emit ToolCallArgsEvent with generated ID
|
||||
@@ -717,7 +715,7 @@ async def test_state_delta_count_logging():
|
||||
|
||||
# Emit multiple state deltas with different content each time
|
||||
for i in range(15):
|
||||
update = AgentRunResponseUpdate(
|
||||
update = AgentResponseUpdate(
|
||||
contents=[
|
||||
FunctionCallContent(name="", call_id="call_1", arguments=f'{{"text": "Content variation {i}"}}'),
|
||||
]
|
||||
@@ -739,7 +737,7 @@ async def test_tool_result_with_empty_list():
|
||||
|
||||
bridge = AgentFrameworkEventBridge(run_id="test_run", thread_id="test_thread")
|
||||
|
||||
update = AgentRunResponseUpdate(contents=[FunctionResultContent(call_id="call_123", result=[])])
|
||||
update = AgentResponseUpdate(contents=[FunctionResultContent(call_id="call_123", result=[])])
|
||||
events = await bridge.from_agent_run_update(update)
|
||||
|
||||
assert len(events) == 2
|
||||
@@ -761,7 +759,7 @@ async def test_tool_result_with_single_text_content():
|
||||
|
||||
bridge = AgentFrameworkEventBridge(run_id="test_run", thread_id="test_thread")
|
||||
|
||||
update = AgentRunResponseUpdate(
|
||||
update = AgentResponseUpdate(
|
||||
contents=[FunctionResultContent(call_id="call_123", result=[MockTextContent("Hello from MCP tool!")])]
|
||||
)
|
||||
events = await bridge.from_agent_run_update(update)
|
||||
@@ -785,7 +783,7 @@ async def test_tool_result_with_multiple_text_contents():
|
||||
|
||||
bridge = AgentFrameworkEventBridge(run_id="test_run", thread_id="test_thread")
|
||||
|
||||
update = AgentRunResponseUpdate(
|
||||
update = AgentResponseUpdate(
|
||||
contents=[
|
||||
FunctionResultContent(
|
||||
call_id="call_123",
|
||||
@@ -813,7 +811,7 @@ async def test_tool_result_with_model_dump_objects():
|
||||
|
||||
bridge = AgentFrameworkEventBridge(run_id="test_run", thread_id="test_thread")
|
||||
|
||||
update = AgentRunResponseUpdate(
|
||||
update = AgentResponseUpdate(
|
||||
contents=[FunctionResultContent(call_id="call_123", result=[MockModel(value=1), MockModel(value=2)])]
|
||||
)
|
||||
events = await bridge.from_agent_run_update(update)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
"""Tests for human in the loop (function approval requests)."""
|
||||
|
||||
from agent_framework import AgentRunResponseUpdate, FunctionApprovalRequestContent, FunctionCallContent
|
||||
from agent_framework import AgentResponseUpdate, FunctionApprovalRequestContent, FunctionCallContent
|
||||
|
||||
from agent_framework_ag_ui._events import AgentFrameworkEventBridge
|
||||
|
||||
@@ -27,7 +27,7 @@ async def test_function_approval_request_emission():
|
||||
function_call=func_call,
|
||||
)
|
||||
|
||||
update = AgentRunResponseUpdate(contents=[approval_request])
|
||||
update = AgentResponseUpdate(contents=[approval_request])
|
||||
events = await bridge.from_agent_run_update(update)
|
||||
|
||||
# Should emit ToolCallEndEvent + CustomEvent for approval request
|
||||
@@ -66,7 +66,7 @@ async def test_function_approval_request_with_confirm_changes():
|
||||
function_call=func_call,
|
||||
)
|
||||
|
||||
update = AgentRunResponseUpdate(contents=[approval_request])
|
||||
update = AgentResponseUpdate(contents=[approval_request])
|
||||
events = await bridge.from_agent_run_update(update)
|
||||
|
||||
# Should emit: ToolCallEndEvent, CustomEvent, and confirm_changes (Start, Args, End) = 5 events
|
||||
@@ -129,7 +129,7 @@ async def test_multiple_approval_requests():
|
||||
function_call=func_call_2,
|
||||
)
|
||||
|
||||
update = AgentRunResponseUpdate(contents=[approval_1, approval_2])
|
||||
update = AgentResponseUpdate(contents=[approval_1, approval_2])
|
||||
events = await bridge.from_agent_run_update(update)
|
||||
|
||||
# Should emit ToolCallEndEvent + CustomEvent for each approval (4 events total)
|
||||
@@ -174,7 +174,7 @@ async def test_function_approval_request_sets_stop_flag():
|
||||
function_call=func_call,
|
||||
)
|
||||
|
||||
update = AgentRunResponseUpdate(contents=[approval_request])
|
||||
update = AgentResponseUpdate(contents=[approval_request])
|
||||
await bridge.from_agent_run_update(update)
|
||||
|
||||
assert bridge.should_stop_after_confirm is True
|
||||
|
||||
@@ -6,7 +6,7 @@ from collections.abc import AsyncGenerator
|
||||
from types import SimpleNamespace
|
||||
from typing import Any
|
||||
|
||||
from agent_framework import AgentRunResponseUpdate, FunctionInvocationConfiguration, TextContent, ai_function
|
||||
from agent_framework import AgentResponseUpdate, FunctionInvocationConfiguration, TextContent, ai_function
|
||||
|
||||
from agent_framework_ag_ui._agent import AgentConfig
|
||||
from agent_framework_ag_ui._orchestrators import DefaultOrchestrator, ExecutionContext
|
||||
@@ -36,9 +36,9 @@ class DummyAgent:
|
||||
thread: Any,
|
||||
tools: list[Any] | None = None,
|
||||
**kwargs: Any,
|
||||
) -> AsyncGenerator[AgentRunResponseUpdate, None]:
|
||||
) -> AsyncGenerator[AgentResponseUpdate, None]:
|
||||
self.seen_tools = tools
|
||||
yield AgentRunResponseUpdate(contents=[TextContent(text="ok")], role="assistant")
|
||||
yield AgentResponseUpdate(contents=[TextContent(text="ok")], role="assistant")
|
||||
|
||||
|
||||
class RecordingAgent:
|
||||
@@ -59,9 +59,9 @@ class RecordingAgent:
|
||||
thread: Any,
|
||||
tools: list[Any] | None = None,
|
||||
**kwargs: Any,
|
||||
) -> AsyncGenerator[AgentRunResponseUpdate, None]:
|
||||
) -> AsyncGenerator[AgentResponseUpdate, None]:
|
||||
self.seen_messages = messages
|
||||
yield AgentRunResponseUpdate(contents=[TextContent(text="ok")], role="assistant")
|
||||
yield AgentResponseUpdate(contents=[TextContent(text="ok")], role="assistant")
|
||||
|
||||
|
||||
async def test_default_orchestrator_merges_client_tools() -> None:
|
||||
|
||||
@@ -9,7 +9,7 @@ from types import SimpleNamespace
|
||||
from typing import Any
|
||||
|
||||
from agent_framework import (
|
||||
AgentRunResponseUpdate,
|
||||
AgentResponseUpdate,
|
||||
ChatMessage,
|
||||
TextContent,
|
||||
ai_function,
|
||||
@@ -55,7 +55,7 @@ async def test_human_in_the_loop_json_decode_error() -> None:
|
||||
|
||||
agent = StubAgent(
|
||||
default_options={"tools": [approval_tool], "response_format": None},
|
||||
updates=[AgentRunResponseUpdate(contents=[TextContent(text="response")], role="assistant")],
|
||||
updates=[AgentResponseUpdate(contents=[TextContent(text="response")], role="assistant")],
|
||||
)
|
||||
context = TestExecutionContext(
|
||||
input_data=input_data,
|
||||
@@ -451,7 +451,7 @@ async def test_structured_output_processing() -> None:
|
||||
agent = StubAgent(
|
||||
default_options=DEFAULT_OPTIONS,
|
||||
updates=[
|
||||
AgentRunResponseUpdate(
|
||||
AgentResponseUpdate(
|
||||
contents=[TextContent(text='{"ingredients": ["tomato"], "message": "Added tomato"}')],
|
||||
role="assistant",
|
||||
)
|
||||
@@ -691,7 +691,7 @@ async def test_confirm_changes_closes_active_message_before_finish() -> None:
|
||||
from agent_framework import FunctionCallContent, FunctionResultContent
|
||||
|
||||
updates = [
|
||||
AgentRunResponseUpdate(
|
||||
AgentResponseUpdate(
|
||||
contents=[
|
||||
FunctionCallContent(
|
||||
name="write_document_local",
|
||||
@@ -700,7 +700,7 @@ async def test_confirm_changes_closes_active_message_before_finish() -> None:
|
||||
)
|
||||
]
|
||||
),
|
||||
AgentRunResponseUpdate(contents=[FunctionResultContent(call_id="call_1", result="Done")]),
|
||||
AgentResponseUpdate(contents=[FunctionResultContent(call_id="call_1", result="Done")]),
|
||||
]
|
||||
|
||||
orchestrator = DefaultOrchestrator()
|
||||
@@ -792,9 +792,9 @@ async def test_agent_protocol_fallback_paths() -> None:
|
||||
thread: Any = None,
|
||||
tools: list[Any] | None = None,
|
||||
**kwargs: Any,
|
||||
) -> AsyncGenerator[AgentRunResponseUpdate, None]:
|
||||
) -> AsyncGenerator[AgentResponseUpdate, None]:
|
||||
self.messages_received = messages
|
||||
yield AgentRunResponseUpdate(contents=[TextContent(text="response")], role="assistant")
|
||||
yield AgentResponseUpdate(contents=[TextContent(text="response")], role="assistant")
|
||||
|
||||
from agent_framework import ChatMessage, TextContent
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@ from typing import Any, Generic
|
||||
|
||||
from agent_framework import (
|
||||
AgentProtocol,
|
||||
AgentRunResponse,
|
||||
AgentRunResponseUpdate,
|
||||
AgentResponse,
|
||||
AgentResponseUpdate,
|
||||
AgentThread,
|
||||
BaseChatClient,
|
||||
ChatMessage,
|
||||
@@ -81,7 +81,7 @@ class StubAgent(AgentProtocol):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
updates: list[AgentRunResponseUpdate] | None = None,
|
||||
updates: list[AgentResponseUpdate] | None = None,
|
||||
*,
|
||||
agent_id: str = "stub-agent",
|
||||
agent_name: str | None = "stub-agent",
|
||||
@@ -91,7 +91,7 @@ class StubAgent(AgentProtocol):
|
||||
self.id = agent_id
|
||||
self.name = agent_name
|
||||
self.description = "stub agent"
|
||||
self.updates = updates or [AgentRunResponseUpdate(contents=[TextContent(text="response")], role="assistant")]
|
||||
self.updates = updates or [AgentResponseUpdate(contents=[TextContent(text="response")], role="assistant")]
|
||||
self.default_options: dict[str, Any] = (
|
||||
default_options if isinstance(default_options, dict) else {"tools": None, "response_format": None}
|
||||
)
|
||||
@@ -105,8 +105,8 @@ class StubAgent(AgentProtocol):
|
||||
*,
|
||||
thread: AgentThread | None = None,
|
||||
**kwargs: Any,
|
||||
) -> AgentRunResponse:
|
||||
return AgentRunResponse(messages=[], response_id="stub-response")
|
||||
) -> AgentResponse:
|
||||
return AgentResponse(messages=[], response_id="stub-response")
|
||||
|
||||
def run_stream(
|
||||
self,
|
||||
@@ -114,8 +114,8 @@ class StubAgent(AgentProtocol):
|
||||
*,
|
||||
thread: AgentThread | None = None,
|
||||
**kwargs: Any,
|
||||
) -> AsyncIterable[AgentRunResponseUpdate]:
|
||||
async def _stream() -> AsyncIterator[AgentRunResponseUpdate]:
|
||||
) -> AsyncIterable[AgentResponseUpdate]:
|
||||
async def _stream() -> AsyncIterator[AgentResponseUpdate]:
|
||||
self.messages_received = [] if messages is None else list(messages) # type: ignore[arg-type]
|
||||
self.tools_received = kwargs.get("tools")
|
||||
for update in self.updates:
|
||||
|
||||
Reference in New Issue
Block a user