Skip to content
Merged
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
20 changes: 10 additions & 10 deletions python/packages/a2a/agent_framework_a2a/_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
from a2a.types import Part as A2APart
from a2a.types import Role as A2ARole
from agent_framework import (
AgentRunResponse,
AgentRunResponseUpdate,
AgentResponse,
AgentResponseUpdate,
AgentThread,
BaseAgent,
ChatMessage,
Expand Down Expand Up @@ -193,11 +193,11 @@ async def run(
*,
thread: AgentThread | None = None,
**kwargs: Any,
) -> AgentRunResponse:
) -> AgentResponse:
"""Get a response from the agent.

This method returns the final result of the agent's execution
as a single AgentRunResponse object. The caller is blocked until
as a single AgentResponse object. The caller is blocked until
the final result is available.

Args:
Expand All @@ -212,19 +212,19 @@ async def run(
"""
# Collect all updates and use framework to consolidate updates into response
updates = [update async for update in self.run_stream(messages, thread=thread, **kwargs)]
return AgentRunResponse.from_agent_run_response_updates(updates)
return AgentResponse.from_agent_run_response_updates(updates)

async def run_stream(
self,
messages: str | ChatMessage | Sequence[str | ChatMessage] | None = None,
*,
thread: AgentThread | None = None,
**kwargs: Any,
) -> AsyncIterable[AgentRunResponseUpdate]:
) -> AsyncIterable[AgentResponseUpdate]:
"""Run the agent as a stream.

This method will return the intermediate steps and final results of the
agent's execution as a stream of AgentRunResponseUpdate objects to the caller.
agent's execution as a stream of AgentResponseUpdate objects to the caller.

Args:
messages: The message(s) to send to the agent.
Expand All @@ -245,7 +245,7 @@ async def run_stream(
if isinstance(item, Message):
# Process A2A Message
contents = self._parse_contents_from_a2a(item.parts)
yield AgentRunResponseUpdate(
yield AgentResponseUpdate(
contents=contents,
role=Role.ASSISTANT if item.role == A2ARole.agent else Role.USER,
response_id=str(getattr(item, "message_id", uuid.uuid4())),
Expand All @@ -260,7 +260,7 @@ async def run_stream(
for message in task_messages:
# Use the artifact's ID from raw_representation as message_id for unique identification
artifact_id = getattr(message.raw_representation, "artifact_id", None)
yield AgentRunResponseUpdate(
yield AgentResponseUpdate(
contents=message.contents,
role=message.role,
response_id=task.id,
Expand All @@ -269,7 +269,7 @@ async def run_stream(
)
else:
# Empty task
yield AgentRunResponseUpdate(
yield AgentResponseUpdate(
contents=[],
role=Role.ASSISTANT,
response_id=task.id,
Expand Down
16 changes: 8 additions & 8 deletions python/packages/a2a/tests/test_a2a_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
)
from a2a.types import Role as A2ARole
from agent_framework import (
AgentRunResponse,
AgentRunResponseUpdate,
AgentResponse,
AgentResponseUpdate,
ChatMessage,
DataContent,
ErrorContent,
Expand Down Expand Up @@ -131,7 +131,7 @@ async def test_run_with_message_response(a2a_agent: A2AAgent, mock_a2a_client: M

response = await a2a_agent.run("Hello agent")

assert isinstance(response, AgentRunResponse)
assert isinstance(response, AgentResponse)
assert len(response.messages) == 1
assert response.messages[0].role == Role.ASSISTANT
assert response.messages[0].text == "Hello from agent!"
Expand All @@ -146,7 +146,7 @@ async def test_run_with_task_response_single_artifact(a2a_agent: A2AAgent, mock_

response = await a2a_agent.run("Generate a report")

assert isinstance(response, AgentRunResponse)
assert isinstance(response, AgentResponse)
assert len(response.messages) == 1
assert response.messages[0].role == Role.ASSISTANT
assert response.messages[0].text == "Generated report content"
Expand All @@ -165,7 +165,7 @@ async def test_run_with_task_response_multiple_artifacts(a2a_agent: A2AAgent, mo

response = await a2a_agent.run("Generate multiple outputs")

assert isinstance(response, AgentRunResponse)
assert isinstance(response, AgentResponse)
assert len(response.messages) == 3

assert response.messages[0].text == "First artifact content"
Expand All @@ -185,7 +185,7 @@ async def test_run_with_task_response_no_artifacts(a2a_agent: A2AAgent, mock_a2a

response = await a2a_agent.run("Do something with no output")

assert isinstance(response, AgentRunResponse)
assert isinstance(response, AgentResponse)
assert response.response_id == "task-empty"


Expand Down Expand Up @@ -357,13 +357,13 @@ async def test_run_stream_with_message_response(a2a_agent: A2AAgent, mock_a2a_cl
mock_a2a_client.add_message_response("msg-stream-123", "Streaming response from agent!", "agent")

# Collect streaming updates
updates: list[AgentRunResponseUpdate] = []
updates: list[AgentResponseUpdate] = []
async for update in a2a_agent.run_stream("Hello agent"):
updates.append(update)

# Verify streaming response
assert len(updates) == 1
assert isinstance(updates[0], AgentRunResponseUpdate)
assert isinstance(updates[0], AgentResponseUpdate)
assert updates[0].role == Role.ASSISTANT
assert len(updates[0].contents) == 1

Expand Down
6 changes: 3 additions & 3 deletions python/packages/ag-ui/agent_framework_ag_ui/_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
ToolCallStartEvent,
)
from agent_framework import (
AgentRunResponseUpdate,
AgentResponseUpdate,
FunctionApprovalRequestContent,
FunctionCallContent,
FunctionResultContent,
Expand Down Expand Up @@ -81,9 +81,9 @@ def __init__(
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.
Expand Down
4 changes: 2 additions & 2 deletions python/packages/ag-ui/agent_framework_ag_ui/_orchestrators.py
Original file line number Diff line number Diff line change
Expand Up @@ -646,11 +646,11 @@ def _build_messages_snapshot(tool_message_id: str | None = None) -> MessagesSnap
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
)

Expand Down
16 changes: 8 additions & 8 deletions python/packages/ag-ui/agent_framework_ag_ui_examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down Expand Up @@ -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
"""
Expand All @@ -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",
Expand Down Expand Up @@ -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!"

Expand Down Expand Up @@ -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(...)
Expand Down
10 changes: 5 additions & 5 deletions python/packages/ag-ui/tests/test_backend_tool_rendering.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
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

Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
18 changes: 9 additions & 9 deletions python/packages/ag-ui/tests/test_document_writer_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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)
Expand All @@ -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
Expand Down
Loading
Loading