renamed all (#3207)

This commit is contained in:
Eduard van Valkenburg
2026-01-14 06:54:07 +01:00
committed by GitHub
Unverified
parent 1ae0b09e42
commit d8cf8361bd
125 changed files with 1024 additions and 1027 deletions
@@ -9,8 +9,8 @@ from azure.identity import AzureCliCredential
from pydantic import Field
from agent_framework import (
AgentRunResponse,
AgentRunResponseUpdate,
AgentResponse,
AgentResponseUpdate,
AgentThread,
ChatAgent,
ChatClientProtocol,
@@ -403,7 +403,7 @@ async def test_azure_assistants_agent_basic_run():
response = await agent.run("Hello! Please respond with 'Hello World' exactly.")
# Validate response
assert isinstance(response, AgentRunResponse)
assert isinstance(response, AgentResponse)
assert response.text is not None
assert len(response.text) > 0
assert "Hello World" in response.text
@@ -420,7 +420,7 @@ async def test_azure_assistants_agent_basic_run_streaming():
full_message: str = ""
async for chunk in agent.run_stream("Please respond with exactly: 'This is a streaming response test.'"):
assert chunk is not None
assert isinstance(chunk, AgentRunResponseUpdate)
assert isinstance(chunk, AgentResponseUpdate)
if chunk.text:
full_message += chunk.text
@@ -444,14 +444,14 @@ async def test_azure_assistants_agent_thread_persistence():
first_response = await agent.run(
"Remember this number: 42. What number did I just tell you to remember?", thread=thread
)
assert isinstance(first_response, AgentRunResponse)
assert isinstance(first_response, AgentResponse)
assert "42" in first_response.text
# Second message - test conversation memory
second_response = await agent.run(
"What number did I tell you to remember in my previous message?", thread=thread
)
assert isinstance(second_response, AgentRunResponse)
assert isinstance(second_response, AgentResponse)
assert "42" in second_response.text
# Verify thread has been populated with conversation ID
@@ -475,7 +475,7 @@ async def test_azure_assistants_agent_existing_thread_id():
response1 = await agent.run("What's the weather in Paris?", thread=thread)
# Validate first response
assert isinstance(response1, AgentRunResponse)
assert isinstance(response1, AgentResponse)
assert response1.text is not None
assert any(word in response1.text.lower() for word in ["weather", "paris"])
@@ -497,7 +497,7 @@ async def test_azure_assistants_agent_existing_thread_id():
response2 = await agent.run("What was the last city I asked about?", thread=thread)
# Validate that the agent remembers the previous conversation
assert isinstance(response2, AgentRunResponse)
assert isinstance(response2, AgentResponse)
assert response2.text is not None
# Should reference Paris from the previous conversation
assert "paris" in response2.text.lower()
@@ -517,7 +517,7 @@ async def test_azure_assistants_agent_code_interpreter():
response = await agent.run("Write Python code to calculate the factorial of 5 and show the result.")
# Validate response
assert isinstance(response, AgentRunResponse)
assert isinstance(response, AgentResponse)
assert response.text is not None
# Factorial of 5 is 120
assert "120" in response.text or "factorial" in response.text.lower()
@@ -536,7 +536,7 @@ async def test_azure_assistants_client_agent_level_tool_persistence():
# First run - agent-level tool should be available
first_response = await agent.run("What's the weather like in Chicago?")
assert isinstance(first_response, AgentRunResponse)
assert isinstance(first_response, AgentResponse)
assert first_response.text is not None
# Should use the agent-level weather tool
assert any(term in first_response.text.lower() for term in ["chicago", "sunny", "72"])
@@ -544,7 +544,7 @@ async def test_azure_assistants_client_agent_level_tool_persistence():
# Second run - agent-level tool should still be available (persistence test)
second_response = await agent.run("What's the weather in Miami?")
assert isinstance(second_response, AgentRunResponse)
assert isinstance(second_response, AgentResponse)
assert second_response.text is not None
# Should use the agent-level weather tool again
assert any(term in second_response.text.lower() for term in ["miami", "sunny", "72"])
@@ -17,8 +17,8 @@ from openai.types.chat.chat_completion_chunk import ChoiceDelta as ChunkChoiceDe
from openai.types.chat.chat_completion_message import ChatCompletionMessage
from agent_framework import (
AgentRunResponse,
AgentRunResponseUpdate,
AgentResponse,
AgentResponseUpdate,
BaseChatClient,
ChatAgent,
ChatClientProtocol,
@@ -731,7 +731,7 @@ async def test_azure_openai_chat_client_agent_basic_run():
# Test basic run
response = await agent.run("Please respond with exactly: 'This is a response test.'")
assert isinstance(response, AgentRunResponse)
assert isinstance(response, AgentResponse)
assert response.text is not None
assert len(response.text) > 0
assert "response test" in response.text.lower()
@@ -747,7 +747,7 @@ async def test_azure_openai_chat_client_agent_basic_run_streaming():
# Test streaming run
full_text = ""
async for chunk in agent.run_stream("Please respond with exactly: 'This is a streaming response test.'"):
assert isinstance(chunk, AgentRunResponseUpdate)
assert isinstance(chunk, AgentResponseUpdate)
if chunk.text:
full_text += chunk.text
@@ -769,13 +769,13 @@ async def test_azure_openai_chat_client_agent_thread_persistence():
# First interaction
response1 = await agent.run("My name is Alice. Remember this.", thread=thread)
assert isinstance(response1, AgentRunResponse)
assert isinstance(response1, AgentResponse)
assert response1.text is not None
# Second interaction - test memory
response2 = await agent.run("What is my name?", thread=thread)
assert isinstance(response2, AgentRunResponse)
assert isinstance(response2, AgentResponse)
assert response2.text is not None
assert "alice" in response2.text.lower()
@@ -795,7 +795,7 @@ async def test_azure_openai_chat_client_agent_existing_thread():
thread = first_agent.get_new_thread()
first_response = await first_agent.run("My name is Alice. Remember this.", thread=thread)
assert isinstance(first_response, AgentRunResponse)
assert isinstance(first_response, AgentResponse)
assert first_response.text is not None
# Preserve the thread for reuse
@@ -810,7 +810,7 @@ async def test_azure_openai_chat_client_agent_existing_thread():
# Reuse the preserved thread
second_response = await second_agent.run("What is my name?", thread=preserved_thread)
assert isinstance(second_response, AgentRunResponse)
assert isinstance(second_response, AgentResponse)
assert second_response.text is not None
assert "alice" in second_response.text.lower()
@@ -828,7 +828,7 @@ async def test_azure_chat_client_agent_level_tool_persistence():
# First run - agent-level tool should be available
first_response = await agent.run("What's the weather like in Chicago?")
assert isinstance(first_response, AgentRunResponse)
assert isinstance(first_response, AgentResponse)
assert first_response.text is not None
# Should use the agent-level weather tool
assert any(term in first_response.text.lower() for term in ["chicago", "sunny", "72"])
@@ -836,7 +836,7 @@ async def test_azure_chat_client_agent_level_tool_persistence():
# Second run - agent-level tool should still be available (persistence test)
second_response = await agent.run("What's the weather in Miami?")
assert isinstance(second_response, AgentRunResponse)
assert isinstance(second_response, AgentResponse)
assert second_response.text is not None
# Should use the agent-level weather tool again
assert any(term in second_response.text.lower() for term in ["miami", "sunny", "72"])
@@ -10,7 +10,7 @@ from pydantic import BaseModel
from pytest import param
from agent_framework import (
AgentRunResponse,
AgentResponse,
ChatAgent,
ChatClientProtocol,
ChatMessage,
@@ -432,7 +432,7 @@ async def test_integration_client_agent_existing_thread():
thread = first_agent.get_new_thread()
first_response = await first_agent.run("My hobby is photography. Remember this.", thread=thread, store=True)
assert isinstance(first_response, AgentRunResponse)
assert isinstance(first_response, AgentResponse)
assert first_response.text is not None
# Preserve the thread for reuse
@@ -447,6 +447,6 @@ async def test_integration_client_agent_existing_thread():
# Reuse the preserved thread
second_response = await second_agent.run("What is my hobby?", thread=preserved_thread)
assert isinstance(second_response, AgentRunResponse)
assert isinstance(second_response, AgentResponse)
assert second_response.text is not None
assert "photography" in second_response.text.lower()
+6 -6
View File
@@ -13,8 +13,8 @@ from pytest import fixture
from agent_framework import (
AgentProtocol,
AgentRunResponse,
AgentRunResponseUpdate,
AgentResponse,
AgentResponseUpdate,
AgentThread,
BaseChatClient,
ChatMessage,
@@ -231,9 +231,9 @@ class MockAgent(AgentProtocol):
*,
thread: AgentThread | None = None,
**kwargs: Any,
) -> AgentRunResponse:
) -> AgentResponse:
logger.debug(f"Running mock agent, with: {messages=}, {thread=}, {kwargs=}")
return AgentRunResponse(messages=[ChatMessage(role=Role.ASSISTANT, contents=[TextContent("Response")])])
return AgentResponse(messages=[ChatMessage(role=Role.ASSISTANT, contents=[TextContent("Response")])])
async def run_stream(
self,
@@ -241,9 +241,9 @@ class MockAgent(AgentProtocol):
*,
thread: AgentThread | None = None,
**kwargs: Any,
) -> AsyncIterable[AgentRunResponseUpdate]:
) -> AsyncIterable[AgentResponseUpdate]:
logger.debug(f"Running mock agent stream, with: {messages=}, {thread=}, {kwargs=}")
yield AgentRunResponseUpdate(contents=[TextContent("Response")])
yield AgentResponseUpdate(contents=[TextContent("Response")])
def get_new_thread(self) -> AgentThread:
return MockAgentThread()
@@ -10,8 +10,8 @@ from pytest import raises
from agent_framework import (
AgentProtocol,
AgentRunResponse,
AgentRunResponseUpdate,
AgentResponse,
AgentResponseUpdate,
AgentThread,
ChatAgent,
ChatClientProtocol,
@@ -45,7 +45,7 @@ async def test_agent_run(agent: AgentProtocol) -> None:
async def test_agent_run_streaming(agent: AgentProtocol) -> None:
async def collect_updates(updates: AsyncIterable[AgentRunResponseUpdate]) -> list[AgentRunResponseUpdate]:
async def collect_updates(updates: AsyncIterable[AgentResponseUpdate]) -> list[AgentResponseUpdate]:
return [u async for u in updates]
updates = await collect_updates(agent.run_stream(messages="test"))
@@ -87,7 +87,7 @@ async def test_chat_client_agent_run(chat_client: ChatClientProtocol) -> None:
async def test_chat_client_agent_run_streaming(chat_client: ChatClientProtocol) -> None:
agent = ChatAgent(chat_client=chat_client)
result = await AgentRunResponse.from_agent_response_generator(agent.run_stream("Hello"))
result = await AgentResponse.from_agent_response_generator(agent.run_stream("Hello"))
assert result.text == "test streaming response another update"
@@ -329,7 +329,7 @@ async def test_chat_agent_run_stream_context_providers(chat_client: ChatClientPr
agent = ChatAgent(chat_client=chat_client, context_provider=mock_provider)
# Collect all stream updates
updates: list[AgentRunResponseUpdate] = []
updates: list[AgentResponseUpdate] = []
async for update in agent.run_stream("Hello"):
updates.append(update)
@@ -440,9 +440,9 @@ async def test_chat_agent_as_tool_with_stream_callback(chat_client: ChatClientPr
agent = ChatAgent(chat_client=chat_client, name="StreamingAgent")
# Collect streaming updates
collected_updates: list[AgentRunResponseUpdate] = []
collected_updates: list[AgentResponseUpdate] = []
def stream_callback(update: AgentRunResponseUpdate) -> None:
def stream_callback(update: AgentResponseUpdate) -> None:
collected_updates.append(update)
tool = agent.as_tool(stream_callback=stream_callback)
@@ -474,9 +474,9 @@ async def test_chat_agent_as_tool_with_async_stream_callback(chat_client: ChatCl
agent = ChatAgent(chat_client=chat_client, name="AsyncStreamingAgent")
# Collect streaming updates using an async callback
collected_updates: list[AgentRunResponseUpdate] = []
collected_updates: list[AgentResponseUpdate] = []
async def async_stream_callback(update: AgentRunResponseUpdate) -> None:
async def async_stream_callback(update: AgentResponseUpdate) -> None:
collected_updates.append(update)
tool = agent.as_tool(stream_callback=async_stream_callback)
@@ -8,8 +8,8 @@ import pytest
from pydantic import BaseModel
from agent_framework import (
AgentRunResponse,
AgentRunResponseUpdate,
AgentResponse,
AgentResponseUpdate,
AgentThread,
ChatAgent,
HostedCodeInterpreterTool,
@@ -46,7 +46,7 @@ async def test_openai_responses_client_agent_basic_run_streaming():
# Test streaming run
full_text = ""
async for chunk in agent.run_stream("Please respond with exactly: 'This is a streaming response test.'"):
assert isinstance(chunk, AgentRunResponseUpdate)
assert isinstance(chunk, AgentResponseUpdate)
if chunk.text:
full_text += chunk.text
@@ -68,13 +68,13 @@ async def test_openai_responses_client_agent_thread_persistence():
# First interaction
first_response = await agent.run("My favorite programming language is Python. Remember this.", thread=thread)
assert isinstance(first_response, AgentRunResponse)
assert isinstance(first_response, AgentResponse)
assert first_response.text is not None
# Second interaction - test memory
second_response = await agent.run("What is my favorite programming language?", thread=thread)
assert isinstance(second_response, AgentRunResponse)
assert isinstance(second_response, AgentResponse)
assert second_response.text is not None
@@ -100,7 +100,7 @@ async def test_openai_responses_client_agent_thread_storage_with_store_true():
)
# Validate response
assert isinstance(response, AgentRunResponse)
assert isinstance(response, AgentResponse)
assert response.text is not None
assert len(response.text) > 0
@@ -125,7 +125,7 @@ async def test_openai_responses_client_agent_existing_thread():
thread = first_agent.get_new_thread()
first_response = await first_agent.run("My hobby is photography. Remember this.", thread=thread)
assert isinstance(first_response, AgentRunResponse)
assert isinstance(first_response, AgentResponse)
assert first_response.text is not None
# Preserve the thread for reuse
@@ -140,7 +140,7 @@ async def test_openai_responses_client_agent_existing_thread():
# Reuse the preserved thread
second_response = await second_agent.run("What is my hobby?", thread=preserved_thread)
assert isinstance(second_response, AgentRunResponse)
assert isinstance(second_response, AgentResponse)
assert second_response.text is not None
assert "photography" in second_response.text.lower()
@@ -157,7 +157,7 @@ async def test_openai_responses_client_agent_hosted_code_interpreter_tool():
# Test code interpreter functionality
response = await agent.run("Calculate the sum of numbers from 1 to 10 using Python code.")
assert isinstance(response, AgentRunResponse)
assert isinstance(response, AgentResponse)
assert response.text is not None
assert len(response.text) > 0
# Should contain calculation result (sum of 1-10 = 55) or code execution content
@@ -179,7 +179,7 @@ async def test_openai_responses_client_agent_image_generation_tool():
# Test image generation functionality
response = await agent.run("Generate an image of a cute red panda sitting on a tree branch in a forest.")
assert isinstance(response, AgentRunResponse)
assert isinstance(response, AgentResponse)
assert response.messages
# Verify we got image content - look for ImageGenerationToolResultContent
@@ -209,7 +209,7 @@ async def test_openai_responses_client_agent_level_tool_persistence():
# First run - agent-level tool should be available
first_response = await agent.run("What's the weather like in Chicago?")
assert isinstance(first_response, AgentRunResponse)
assert isinstance(first_response, AgentResponse)
assert first_response.text is not None
# Should use the agent-level weather tool
assert any(term in first_response.text.lower() for term in ["chicago", "sunny", "72"])
@@ -217,7 +217,7 @@ async def test_openai_responses_client_agent_level_tool_persistence():
# Second run - agent-level tool should still be available (persistence test)
second_response = await agent.run("What's the weather in Miami?")
assert isinstance(second_response, AgentRunResponse)
assert isinstance(second_response, AgentResponse)
assert second_response.text is not None
# Should use the agent-level weather tool again
assert any(term in second_response.text.lower() for term in ["miami", "sunny", "72"])
@@ -249,7 +249,7 @@ async def test_openai_responses_client_run_level_tool_isolation():
tools=[get_weather_with_counter], # Run-level tool
)
assert isinstance(first_response, AgentRunResponse)
assert isinstance(first_response, AgentResponse)
assert first_response.text is not None
# Should use the run-level weather tool (call count should be 1)
assert call_count == 1
@@ -258,7 +258,7 @@ async def test_openai_responses_client_run_level_tool_isolation():
# Second run - run-level tool should NOT persist (key isolation test)
second_response = await agent.run("What's the weather like in Miami?")
assert isinstance(second_response, AgentRunResponse)
assert isinstance(second_response, AgentResponse)
assert second_response.text is not None
# Should NOT use the weather tool since it was only run-level in previous call
# Call count should still be 1 (no additional calls)
@@ -286,7 +286,7 @@ async def test_openai_responses_client_agent_chat_options_agent_level() -> None:
"Provide a brief, helpful response.",
)
assert isinstance(response, AgentRunResponse)
assert isinstance(response, AgentResponse)
assert response.text is not None
assert len(response.text) > 0
@@ -312,7 +312,7 @@ async def test_openai_responses_client_agent_hosted_mcp_tool() -> None:
options={"max_tokens": 5000},
)
assert isinstance(response, AgentRunResponse)
assert isinstance(response, AgentResponse)
assert response.text
# Should contain Azure-related content since it's asking about Azure CLI
assert any(term in response.text.lower() for term in ["azure", "storage", "account", "cli"])
@@ -338,7 +338,7 @@ async def test_openai_responses_client_agent_local_mcp_tool() -> None:
options={"max_tokens": 200},
)
assert isinstance(response, AgentRunResponse)
assert isinstance(response, AgentResponse)
assert response.text is not None
assert len(response.text) > 0
# Should contain Azure-related content since it's asking about Azure CLI
@@ -375,7 +375,7 @@ async def test_openai_responses_client_agent_with_response_format_pydantic() ->
)
# Validate response
assert isinstance(response, AgentRunResponse)
assert isinstance(response, AgentResponse)
assert response.value is not None
assert isinstance(response.value, ReleaseBrief)
@@ -422,7 +422,7 @@ async def test_openai_responses_client_agent_with_runtime_json_schema() -> None:
)
# Validate response
assert isinstance(response, AgentRunResponse)
assert isinstance(response, AgentResponse)
assert response.text is not None
# Parse JSON and validate structure
@@ -9,8 +9,8 @@ from pydantic import BaseModel, Field
from agent_framework import (
AgentProtocol,
AgentRunResponse,
AgentRunResponseUpdate,
AgentResponse,
AgentResponseUpdate,
ChatMessage,
ChatResponse,
ChatResponseUpdate,
@@ -172,9 +172,9 @@ class TestAgentMiddlewarePipeline:
messages = [ChatMessage(role=Role.USER, text="test")]
context = AgentRunContext(agent=mock_agent, messages=messages)
expected_response = AgentRunResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="response")])
expected_response = AgentResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="response")])
async def final_handler(ctx: AgentRunContext) -> AgentRunResponse:
async def final_handler(ctx: AgentRunContext) -> AgentResponse:
return expected_response
result = await pipeline.execute(mock_agent, messages, context, final_handler)
@@ -200,9 +200,9 @@ class TestAgentMiddlewarePipeline:
messages = [ChatMessage(role=Role.USER, text="test")]
context = AgentRunContext(agent=mock_agent, messages=messages)
expected_response = AgentRunResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="response")])
expected_response = AgentResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="response")])
async def final_handler(ctx: AgentRunContext) -> AgentRunResponse:
async def final_handler(ctx: AgentRunContext) -> AgentResponse:
execution_order.append("handler")
return expected_response
@@ -216,11 +216,11 @@ class TestAgentMiddlewarePipeline:
messages = [ChatMessage(role=Role.USER, text="test")]
context = AgentRunContext(agent=mock_agent, messages=messages)
async def final_handler(ctx: AgentRunContext) -> AsyncIterable[AgentRunResponseUpdate]:
yield AgentRunResponseUpdate(contents=[TextContent(text="chunk1")])
yield AgentRunResponseUpdate(contents=[TextContent(text="chunk2")])
async def final_handler(ctx: AgentRunContext) -> AsyncIterable[AgentResponseUpdate]:
yield AgentResponseUpdate(contents=[TextContent(text="chunk1")])
yield AgentResponseUpdate(contents=[TextContent(text="chunk2")])
updates: list[AgentRunResponseUpdate] = []
updates: list[AgentResponseUpdate] = []
async for update in pipeline.execute_stream(mock_agent, messages, context, final_handler):
updates.append(update)
@@ -248,13 +248,13 @@ class TestAgentMiddlewarePipeline:
messages = [ChatMessage(role=Role.USER, text="test")]
context = AgentRunContext(agent=mock_agent, messages=messages)
async def final_handler(ctx: AgentRunContext) -> AsyncIterable[AgentRunResponseUpdate]:
async def final_handler(ctx: AgentRunContext) -> AsyncIterable[AgentResponseUpdate]:
execution_order.append("handler_start")
yield AgentRunResponseUpdate(contents=[TextContent(text="chunk1")])
yield AgentRunResponseUpdate(contents=[TextContent(text="chunk2")])
yield AgentResponseUpdate(contents=[TextContent(text="chunk1")])
yield AgentResponseUpdate(contents=[TextContent(text="chunk2")])
execution_order.append("handler_end")
updates: list[AgentRunResponseUpdate] = []
updates: list[AgentResponseUpdate] = []
async for update in pipeline.execute_stream(mock_agent, messages, context, final_handler):
updates.append(update)
@@ -271,10 +271,10 @@ class TestAgentMiddlewarePipeline:
context = AgentRunContext(agent=mock_agent, messages=messages)
execution_order: list[str] = []
async def final_handler(ctx: AgentRunContext) -> AgentRunResponse:
async def final_handler(ctx: AgentRunContext) -> AgentResponse:
# Handler should not be executed when terminated before next()
execution_order.append("handler")
return AgentRunResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="response")])
return AgentResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="response")])
response = await pipeline.execute(mock_agent, messages, context, final_handler)
assert response is not None
@@ -291,9 +291,9 @@ class TestAgentMiddlewarePipeline:
context = AgentRunContext(agent=mock_agent, messages=messages)
execution_order: list[str] = []
async def final_handler(ctx: AgentRunContext) -> AgentRunResponse:
async def final_handler(ctx: AgentRunContext) -> AgentResponse:
execution_order.append("handler")
return AgentRunResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="response")])
return AgentResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="response")])
response = await pipeline.execute(mock_agent, messages, context, final_handler)
assert response is not None
@@ -310,14 +310,14 @@ class TestAgentMiddlewarePipeline:
context = AgentRunContext(agent=mock_agent, messages=messages)
execution_order: list[str] = []
async def final_handler(ctx: AgentRunContext) -> AsyncIterable[AgentRunResponseUpdate]:
async def final_handler(ctx: AgentRunContext) -> AsyncIterable[AgentResponseUpdate]:
# Handler should not be executed when terminated before next()
execution_order.append("handler_start")
yield AgentRunResponseUpdate(contents=[TextContent(text="chunk1")])
yield AgentRunResponseUpdate(contents=[TextContent(text="chunk2")])
yield AgentResponseUpdate(contents=[TextContent(text="chunk1")])
yield AgentResponseUpdate(contents=[TextContent(text="chunk2")])
execution_order.append("handler_end")
updates: list[AgentRunResponseUpdate] = []
updates: list[AgentResponseUpdate] = []
async for update in pipeline.execute_stream(mock_agent, messages, context, final_handler):
updates.append(update)
@@ -334,13 +334,13 @@ class TestAgentMiddlewarePipeline:
context = AgentRunContext(agent=mock_agent, messages=messages)
execution_order: list[str] = []
async def final_handler(ctx: AgentRunContext) -> AsyncIterable[AgentRunResponseUpdate]:
async def final_handler(ctx: AgentRunContext) -> AsyncIterable[AgentResponseUpdate]:
execution_order.append("handler_start")
yield AgentRunResponseUpdate(contents=[TextContent(text="chunk1")])
yield AgentRunResponseUpdate(contents=[TextContent(text="chunk2")])
yield AgentResponseUpdate(contents=[TextContent(text="chunk1")])
yield AgentResponseUpdate(contents=[TextContent(text="chunk2")])
execution_order.append("handler_end")
updates: list[AgentRunResponseUpdate] = []
updates: list[AgentResponseUpdate] = []
async for update in pipeline.execute_stream(mock_agent, messages, context, final_handler):
updates.append(update)
@@ -370,9 +370,9 @@ class TestAgentMiddlewarePipeline:
thread = AgentThread()
context = AgentRunContext(agent=mock_agent, messages=messages, thread=thread)
expected_response = AgentRunResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="response")])
expected_response = AgentResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="response")])
async def final_handler(ctx: AgentRunContext) -> AgentRunResponse:
async def final_handler(ctx: AgentRunContext) -> AgentResponse:
return expected_response
result = await pipeline.execute(mock_agent, messages, context, final_handler)
@@ -396,9 +396,9 @@ class TestAgentMiddlewarePipeline:
messages = [ChatMessage(role=Role.USER, text="test")]
context = AgentRunContext(agent=mock_agent, messages=messages, thread=None)
expected_response = AgentRunResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="response")])
expected_response = AgentResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="response")])
async def final_handler(ctx: AgentRunContext) -> AgentRunResponse:
async def final_handler(ctx: AgentRunContext) -> AgentResponse:
return expected_response
result = await pipeline.execute(mock_agent, messages, context, final_handler)
@@ -767,9 +767,9 @@ class TestClassBasedMiddleware:
messages = [ChatMessage(role=Role.USER, text="test")]
context = AgentRunContext(agent=mock_agent, messages=messages)
async def final_handler(ctx: AgentRunContext) -> AgentRunResponse:
async def final_handler(ctx: AgentRunContext) -> AgentResponse:
metadata_updates.append("handler")
return AgentRunResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="response")])
return AgentResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="response")])
result = await pipeline.execute(mock_agent, messages, context, final_handler)
@@ -830,9 +830,9 @@ class TestFunctionBasedMiddleware:
messages = [ChatMessage(role=Role.USER, text="test")]
context = AgentRunContext(agent=mock_agent, messages=messages)
async def final_handler(ctx: AgentRunContext) -> AgentRunResponse:
async def final_handler(ctx: AgentRunContext) -> AgentResponse:
execution_order.append("handler")
return AgentRunResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="response")])
return AgentResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="response")])
result = await pipeline.execute(mock_agent, messages, context, final_handler)
@@ -893,9 +893,9 @@ class TestMixedMiddleware:
messages = [ChatMessage(role=Role.USER, text="test")]
context = AgentRunContext(agent=mock_agent, messages=messages)
async def final_handler(ctx: AgentRunContext) -> AgentRunResponse:
async def final_handler(ctx: AgentRunContext) -> AgentResponse:
execution_order.append("handler")
return AgentRunResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="response")])
return AgentResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="response")])
result = await pipeline.execute(mock_agent, messages, context, final_handler)
@@ -1004,9 +1004,9 @@ class TestMultipleMiddlewareOrdering:
messages = [ChatMessage(role=Role.USER, text="test")]
context = AgentRunContext(agent=mock_agent, messages=messages)
async def final_handler(ctx: AgentRunContext) -> AgentRunResponse:
async def final_handler(ctx: AgentRunContext) -> AgentResponse:
execution_order.append("handler")
return AgentRunResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="response")])
return AgentResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="response")])
result = await pipeline.execute(mock_agent, messages, context, final_handler)
@@ -1142,10 +1142,10 @@ class TestContextContentValidation:
messages = [ChatMessage(role=Role.USER, text="test")]
context = AgentRunContext(agent=mock_agent, messages=messages)
async def final_handler(ctx: AgentRunContext) -> AgentRunResponse:
async def final_handler(ctx: AgentRunContext) -> AgentResponse:
# Verify metadata was set by middleware
assert ctx.metadata.get("validated") is True
return AgentRunResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="response")])
return AgentResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="response")])
result = await pipeline.execute(mock_agent, messages, context, final_handler)
assert result is not None
@@ -1253,20 +1253,20 @@ class TestStreamingScenarios:
# Test non-streaming
context = AgentRunContext(agent=mock_agent, messages=messages)
async def final_handler(ctx: AgentRunContext) -> AgentRunResponse:
async def final_handler(ctx: AgentRunContext) -> AgentResponse:
streaming_flags.append(ctx.is_streaming)
return AgentRunResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="response")])
return AgentResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="response")])
await pipeline.execute(mock_agent, messages, context, final_handler)
# Test streaming
context_stream = AgentRunContext(agent=mock_agent, messages=messages)
async def final_stream_handler(ctx: AgentRunContext) -> AsyncIterable[AgentRunResponseUpdate]:
async def final_stream_handler(ctx: AgentRunContext) -> AsyncIterable[AgentResponseUpdate]:
streaming_flags.append(ctx.is_streaming)
yield AgentRunResponseUpdate(contents=[TextContent(text="chunk")])
yield AgentResponseUpdate(contents=[TextContent(text="chunk")])
updates: list[AgentRunResponseUpdate] = []
updates: list[AgentResponseUpdate] = []
async for update in pipeline.execute_stream(mock_agent, messages, context_stream, final_stream_handler):
updates.append(update)
@@ -1290,11 +1290,11 @@ class TestStreamingScenarios:
messages = [ChatMessage(role=Role.USER, text="test")]
context = AgentRunContext(agent=mock_agent, messages=messages)
async def final_stream_handler(ctx: AgentRunContext) -> AsyncIterable[AgentRunResponseUpdate]:
async def final_stream_handler(ctx: AgentRunContext) -> AsyncIterable[AgentResponseUpdate]:
chunks_processed.append("stream_start")
yield AgentRunResponseUpdate(contents=[TextContent(text="chunk1")])
yield AgentResponseUpdate(contents=[TextContent(text="chunk1")])
chunks_processed.append("chunk1_yielded")
yield AgentRunResponseUpdate(contents=[TextContent(text="chunk2")])
yield AgentResponseUpdate(contents=[TextContent(text="chunk2")])
chunks_processed.append("chunk2_yielded")
chunks_processed.append("stream_end")
@@ -1452,16 +1452,16 @@ class TestMiddlewareExecutionControl:
handler_called = False
async def final_handler(ctx: AgentRunContext) -> AgentRunResponse:
async def final_handler(ctx: AgentRunContext) -> AgentResponse:
nonlocal handler_called
handler_called = True
return AgentRunResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="should not execute")])
return AgentResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="should not execute")])
result = await pipeline.execute(mock_agent, messages, context, final_handler)
# Verify no execution happened - should return empty AgentRunResponse
# Verify no execution happened - should return empty AgentResponse
assert result is not None
assert isinstance(result, AgentRunResponse)
assert isinstance(result, AgentResponse)
assert result.messages == [] # Empty response
assert not handler_called
assert context.result is None
@@ -1483,13 +1483,13 @@ class TestMiddlewareExecutionControl:
handler_called = False
async def final_handler(ctx: AgentRunContext) -> AsyncIterable[AgentRunResponseUpdate]:
async def final_handler(ctx: AgentRunContext) -> AsyncIterable[AgentResponseUpdate]:
nonlocal handler_called
handler_called = True
yield AgentRunResponseUpdate(contents=[TextContent(text="should not execute")])
yield AgentResponseUpdate(contents=[TextContent(text="should not execute")])
# When middleware doesn't call next(), streaming should yield no updates
updates: list[AgentRunResponseUpdate] = []
updates: list[AgentResponseUpdate] = []
async for update in pipeline.execute_stream(mock_agent, messages, context, final_handler):
updates.append(update)
@@ -1556,17 +1556,17 @@ class TestMiddlewareExecutionControl:
handler_called = False
async def final_handler(ctx: AgentRunContext) -> AgentRunResponse:
async def final_handler(ctx: AgentRunContext) -> AgentResponse:
nonlocal handler_called
handler_called = True
return AgentRunResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="should not execute")])
return AgentResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="should not execute")])
result = await pipeline.execute(mock_agent, messages, context, final_handler)
# Verify only first middleware was called and empty response returned
assert execution_order == ["first"]
assert result is not None
assert isinstance(result, AgentRunResponse)
assert isinstance(result, AgentResponse)
assert result.messages == [] # Empty response
assert not handler_called
@@ -9,8 +9,8 @@ from pydantic import BaseModel, Field
from agent_framework import (
AgentProtocol,
AgentRunResponse,
AgentRunResponseUpdate,
AgentResponse,
AgentResponseUpdate,
ChatAgent,
ChatMessage,
Role,
@@ -40,7 +40,7 @@ class TestResultOverrideMiddleware:
async def test_agent_middleware_response_override_non_streaming(self, mock_agent: AgentProtocol) -> None:
"""Test that agent middleware can override response for non-streaming execution."""
override_response = AgentRunResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="overridden response")])
override_response = AgentResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="overridden response")])
class ResponseOverrideMiddleware(AgentMiddleware):
async def process(
@@ -57,10 +57,10 @@ class TestResultOverrideMiddleware:
handler_called = False
async def final_handler(ctx: AgentRunContext) -> AgentRunResponse:
async def final_handler(ctx: AgentRunContext) -> AgentResponse:
nonlocal handler_called
handler_called = True
return AgentRunResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="original response")])
return AgentResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="original response")])
result = await pipeline.execute(mock_agent, messages, context, final_handler)
@@ -74,9 +74,9 @@ class TestResultOverrideMiddleware:
async def test_agent_middleware_response_override_streaming(self, mock_agent: AgentProtocol) -> None:
"""Test that agent middleware can override response for streaming execution."""
async def override_stream() -> AsyncIterable[AgentRunResponseUpdate]:
yield AgentRunResponseUpdate(contents=[TextContent(text="overridden")])
yield AgentRunResponseUpdate(contents=[TextContent(text=" stream")])
async def override_stream() -> AsyncIterable[AgentResponseUpdate]:
yield AgentResponseUpdate(contents=[TextContent(text="overridden")])
yield AgentResponseUpdate(contents=[TextContent(text=" stream")])
class StreamResponseOverrideMiddleware(AgentMiddleware):
async def process(
@@ -91,10 +91,10 @@ class TestResultOverrideMiddleware:
messages = [ChatMessage(role=Role.USER, text="test")]
context = AgentRunContext(agent=mock_agent, messages=messages)
async def final_handler(ctx: AgentRunContext) -> AsyncIterable[AgentRunResponseUpdate]:
yield AgentRunResponseUpdate(contents=[TextContent(text="original")])
async def final_handler(ctx: AgentRunContext) -> AsyncIterable[AgentResponseUpdate]:
yield AgentResponseUpdate(contents=[TextContent(text="original")])
updates: list[AgentRunResponseUpdate] = []
updates: list[AgentResponseUpdate] = []
async for update in pipeline.execute_stream(mock_agent, messages, context, final_handler):
updates.append(update)
@@ -148,7 +148,7 @@ class TestResultOverrideMiddleware:
await next(context)
# Then conditionally override based on content
if any("special" in msg.text for msg in context.messages if msg.text):
context.result = AgentRunResponse(
context.result = AgentResponse(
messages=[ChatMessage(role=Role.ASSISTANT, text="Special response from middleware!")]
)
@@ -174,10 +174,10 @@ class TestResultOverrideMiddleware:
"""Test streaming result override functionality with ChatAgent integration."""
mock_chat_client = MockChatClient()
async def custom_stream() -> AsyncIterable[AgentRunResponseUpdate]:
yield AgentRunResponseUpdate(contents=[TextContent(text="Custom")])
yield AgentRunResponseUpdate(contents=[TextContent(text=" streaming")])
yield AgentRunResponseUpdate(contents=[TextContent(text=" response!")])
async def custom_stream() -> AsyncIterable[AgentResponseUpdate]:
yield AgentResponseUpdate(contents=[TextContent(text="Custom")])
yield AgentResponseUpdate(contents=[TextContent(text=" streaming")])
yield AgentResponseUpdate(contents=[TextContent(text=" response!")])
class ChatAgentStreamOverrideMiddleware(AgentMiddleware):
async def process(
@@ -195,7 +195,7 @@ class TestResultOverrideMiddleware:
# Test streaming override case
override_messages = [ChatMessage(role=Role.USER, text="Give me a custom stream")]
override_updates: list[AgentRunResponseUpdate] = []
override_updates: list[AgentResponseUpdate] = []
async for update in agent.run_stream(override_messages):
override_updates.append(update)
@@ -206,7 +206,7 @@ class TestResultOverrideMiddleware:
# Test normal streaming case
normal_messages = [ChatMessage(role=Role.USER, text="Normal streaming request")]
normal_updates: list[AgentRunResponseUpdate] = []
normal_updates: list[AgentResponseUpdate] = []
async for update in agent.run_stream(normal_messages):
normal_updates.append(update)
@@ -231,19 +231,19 @@ class TestResultOverrideMiddleware:
handler_called = False
async def final_handler(ctx: AgentRunContext) -> AgentRunResponse:
async def final_handler(ctx: AgentRunContext) -> AgentResponse:
nonlocal handler_called
handler_called = True
return AgentRunResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="executed response")])
return AgentResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="executed response")])
# Test case where next() is NOT called
no_execute_messages = [ChatMessage(role=Role.USER, text="Don't run this")]
no_execute_context = AgentRunContext(agent=mock_agent, messages=no_execute_messages)
no_execute_result = await pipeline.execute(mock_agent, no_execute_messages, no_execute_context, final_handler)
# When middleware doesn't call next(), result should be empty AgentRunResponse
# When middleware doesn't call next(), result should be empty AgentResponse
assert no_execute_result is not None
assert isinstance(no_execute_result, AgentRunResponse)
assert isinstance(no_execute_result, AgentResponse)
assert no_execute_result.messages == [] # Empty response
assert not handler_called
assert no_execute_context.result is None
@@ -313,7 +313,7 @@ class TestResultObservability:
async def test_agent_middleware_response_observability(self, mock_agent: AgentProtocol) -> None:
"""Test that middleware can observe response after execution."""
observed_responses: list[AgentRunResponse] = []
observed_responses: list[AgentResponse] = []
class ObservabilityMiddleware(AgentMiddleware):
async def process(
@@ -327,7 +327,7 @@ class TestResultObservability:
# Context should now contain the response for observability
assert context.result is not None
assert isinstance(context.result, AgentRunResponse)
assert isinstance(context.result, AgentResponse)
observed_responses.append(context.result)
middleware = ObservabilityMiddleware()
@@ -335,8 +335,8 @@ class TestResultObservability:
messages = [ChatMessage(role=Role.USER, text="test")]
context = AgentRunContext(agent=mock_agent, messages=messages)
async def final_handler(ctx: AgentRunContext) -> AgentRunResponse:
return AgentRunResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="executed response")])
async def final_handler(ctx: AgentRunContext) -> AgentResponse:
return AgentResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="executed response")])
result = await pipeline.execute(mock_agent, messages, context, final_handler)
@@ -392,11 +392,11 @@ class TestResultObservability:
# Now observe and conditionally override
assert context.result is not None
assert isinstance(context.result, AgentRunResponse)
assert isinstance(context.result, AgentResponse)
if "modify" in context.result.messages[0].text:
# Override after observing
context.result = AgentRunResponse(
context.result = AgentResponse(
messages=[ChatMessage(role=Role.ASSISTANT, text="modified after execution")]
)
@@ -405,8 +405,8 @@ class TestResultObservability:
messages = [ChatMessage(role=Role.USER, text="test")]
context = AgentRunContext(agent=mock_agent, messages=messages)
async def final_handler(ctx: AgentRunContext) -> AgentRunResponse:
return AgentRunResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="response to modify")])
async def final_handler(ctx: AgentRunContext) -> AgentResponse:
return AgentResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="response to modify")])
result = await pipeline.execute(mock_agent, messages, context, final_handler)
@@ -6,7 +6,7 @@ from typing import Any
import pytest
from agent_framework import (
AgentRunResponseUpdate,
AgentResponseUpdate,
ChatAgent,
ChatContext,
ChatMessage,
@@ -372,7 +372,7 @@ class TestChatAgentStreamingMiddleware:
# Execute streaming
messages = [ChatMessage(role=Role.USER, text="test message")]
updates: list[AgentRunResponseUpdate] = []
updates: list[AgentResponseUpdate] = []
async for update in agent.run_stream(messages):
updates.append(update)
@@ -878,7 +878,7 @@ class TestMiddlewareDynamicRebuild:
agent = ChatAgent(chat_client=chat_client, middleware=[middleware1])
# First streaming execution
updates: list[AgentRunResponseUpdate] = []
updates: list[AgentResponseUpdate] = []
async for update in agent.run_stream("Test stream message 1"):
updates.append(update)
@@ -1085,7 +1085,7 @@ class TestRunLevelMiddleware:
run_middleware = StreamingTrackingMiddleware("run_stream")
# Execute streaming with run middleware
updates: list[AgentRunResponseUpdate] = []
updates: list[AgentResponseUpdate] = []
async for update in agent.run_stream("Test streaming", middleware=[run_middleware]):
updates.append(update)
@@ -1711,7 +1711,7 @@ class TestChatAgentChatMiddleware:
# Execute streaming
messages = [ChatMessage(role=Role.USER, text="test message")]
updates: list[AgentRunResponseUpdate] = []
updates: list[AgentResponseUpdate] = []
async for update in agent.run_stream(messages):
updates.append(update)
@@ -13,7 +13,7 @@ from opentelemetry.trace import StatusCode
from agent_framework import (
AGENT_FRAMEWORK_USER_AGENT,
AgentProtocol,
AgentRunResponse,
AgentResponse,
AgentThread,
BaseChatClient,
ChatMessage,
@@ -407,7 +407,7 @@ def mock_chat_agent():
self.default_options: dict[str, Any] = {"model_id": "TestModel"}
async def run(self, messages=None, *, thread=None, **kwargs):
return AgentRunResponse(
return AgentResponse(
messages=[ChatMessage(role=Role.ASSISTANT, text="Agent response")],
usage_details=UsageDetails(input_token_count=15, output_token_count=25),
response_id="test_response_id",
@@ -415,10 +415,10 @@ def mock_chat_agent():
)
async def run_stream(self, messages=None, *, thread=None, **kwargs):
from agent_framework import AgentRunResponseUpdate
from agent_framework import AgentResponseUpdate
yield AgentRunResponseUpdate(text="Hello", role=Role.ASSISTANT)
yield AgentRunResponseUpdate(text=" from agent", role=Role.ASSISTANT)
yield AgentResponseUpdate(text="Hello", role=Role.ASSISTANT)
yield AgentResponseUpdate(text=" from agent", role=Role.ASSISTANT)
return MockChatClientAgent
+43 -43
View File
@@ -10,8 +10,8 @@ from pydantic import BaseModel
from pytest import fixture, mark, raises
from agent_framework import (
AgentRunResponse,
AgentRunResponseUpdate,
AgentResponse,
AgentResponseUpdate,
BaseContent,
ChatMessage,
ChatOptions,
@@ -1026,90 +1026,90 @@ def text_content() -> TextContent:
@fixture
def agent_run_response(chat_message: ChatMessage) -> AgentRunResponse:
return AgentRunResponse(messages=chat_message)
def agent_response(chat_message: ChatMessage) -> AgentResponse:
return AgentResponse(messages=chat_message)
@fixture
def agent_run_response_update(text_content: TextContent) -> AgentRunResponseUpdate:
return AgentRunResponseUpdate(role=Role.ASSISTANT, contents=[text_content])
def agent_response_update(text_content: TextContent) -> AgentResponseUpdate:
return AgentResponseUpdate(role=Role.ASSISTANT, contents=[text_content])
# region AgentRunResponse
# region AgentResponse
def test_agent_run_response_init_single_message(chat_message: ChatMessage) -> None:
response = AgentRunResponse(messages=chat_message)
response = AgentResponse(messages=chat_message)
assert response.messages == [chat_message]
def test_agent_run_response_init_list_messages(chat_message: ChatMessage) -> None:
response = AgentRunResponse(messages=[chat_message, chat_message])
response = AgentResponse(messages=[chat_message, chat_message])
assert len(response.messages) == 2
assert response.messages[0] == chat_message
def test_agent_run_response_init_none_messages() -> None:
response = AgentRunResponse()
response = AgentResponse()
assert response.messages == []
def test_agent_run_response_text_property(chat_message: ChatMessage) -> None:
response = AgentRunResponse(messages=[chat_message, chat_message])
response = AgentResponse(messages=[chat_message, chat_message])
assert response.text == "HelloHello"
def test_agent_run_response_text_property_empty() -> None:
response = AgentRunResponse()
response = AgentResponse()
assert response.text == ""
def test_agent_run_response_from_updates(agent_run_response_update: AgentRunResponseUpdate) -> None:
updates = [agent_run_response_update, agent_run_response_update]
response = AgentRunResponse.from_agent_run_response_updates(updates)
def test_agent_run_response_from_updates(agent_response_update: AgentResponseUpdate) -> None:
updates = [agent_response_update, agent_response_update]
response = AgentResponse.from_agent_run_response_updates(updates)
assert len(response.messages) > 0
assert response.text == "Test contentTest content"
def test_agent_run_response_str_method(chat_message: ChatMessage) -> None:
response = AgentRunResponse(messages=chat_message)
response = AgentResponse(messages=chat_message)
assert str(response) == "Hello"
# region AgentRunResponseUpdate
# region AgentResponseUpdate
def test_agent_run_response_update_init_content_list(text_content: TextContent) -> None:
update = AgentRunResponseUpdate(contents=[text_content, text_content])
update = AgentResponseUpdate(contents=[text_content, text_content])
assert len(update.contents) == 2
assert update.contents[0] == text_content
def test_agent_run_response_update_init_none_content() -> None:
update = AgentRunResponseUpdate()
update = AgentResponseUpdate()
assert update.contents == []
def test_agent_run_response_update_text_property(text_content: TextContent) -> None:
update = AgentRunResponseUpdate(contents=[text_content, text_content])
update = AgentResponseUpdate(contents=[text_content, text_content])
assert update.text == "Test contentTest content"
def test_agent_run_response_update_text_property_empty() -> None:
update = AgentRunResponseUpdate()
update = AgentResponseUpdate()
assert update.text == ""
def test_agent_run_response_update_str_method(text_content: TextContent) -> None:
update = AgentRunResponseUpdate(contents=[text_content])
update = AgentResponseUpdate(contents=[text_content])
assert str(update) == "Test content"
def test_agent_run_response_update_created_at() -> None:
"""Test that AgentRunResponseUpdate properly handles created_at timestamps."""
"""Test that AgentResponseUpdate properly handles created_at timestamps."""
# Test with a properly formatted UTC timestamp
utc_timestamp = "2024-12-01T00:31:30.000000Z"
update = AgentRunResponseUpdate(
update = AgentResponseUpdate(
contents=[TextContent(text="test")],
role=Role.ASSISTANT,
created_at=utc_timestamp,
@@ -1120,7 +1120,7 @@ def test_agent_run_response_update_created_at() -> None:
# Verify that we can generate a proper UTC timestamp
now_utc = datetime.now(tz=timezone.utc)
formatted_utc = now_utc.strftime("%Y-%m-%dT%H:%M:%S.%fZ")
update_with_now = AgentRunResponseUpdate(
update_with_now = AgentResponseUpdate(
contents=[TextContent(text="test")],
role=Role.ASSISTANT,
created_at=formatted_utc,
@@ -1130,10 +1130,10 @@ def test_agent_run_response_update_created_at() -> None:
def test_agent_run_response_created_at() -> None:
"""Test that AgentRunResponse properly handles created_at timestamps."""
"""Test that AgentResponse properly handles created_at timestamps."""
# Test with a properly formatted UTC timestamp
utc_timestamp = "2024-12-01T00:31:30.000000Z"
response = AgentRunResponse(
response = AgentResponse(
messages=[ChatMessage(role=Role.ASSISTANT, text="Hello")],
created_at=utc_timestamp,
)
@@ -1143,7 +1143,7 @@ def test_agent_run_response_created_at() -> None:
# Verify that we can generate a proper UTC timestamp
now_utc = datetime.now(tz=timezone.utc)
formatted_utc = now_utc.strftime("%Y-%m-%dT%H:%M:%S.%fZ")
response_with_now = AgentRunResponse(
response_with_now = AgentResponse(
messages=[ChatMessage(role=Role.ASSISTANT, text="Hello")],
created_at=formatted_utc,
)
@@ -1285,20 +1285,20 @@ def test_chat_tool_mode_eq_with_string():
assert {"mode": "auto"} == {"mode": "auto"}
# region AgentRunResponse
# region AgentResponse
@fixture
def agent_run_response_async() -> AgentRunResponse:
return AgentRunResponse(messages=[ChatMessage(role="user", text="Hello")])
def agent_run_response_async() -> AgentResponse:
return AgentResponse(messages=[ChatMessage(role="user", text="Hello")])
async def test_agent_run_response_from_async_generator():
async def gen():
yield AgentRunResponseUpdate(contents=[TextContent("A")])
yield AgentRunResponseUpdate(contents=[TextContent("B")])
yield AgentResponseUpdate(contents=[TextContent("A")])
yield AgentResponseUpdate(contents=[TextContent("B")])
r = await AgentRunResponse.from_agent_response_generator(gen())
r = await AgentResponse.from_agent_response_generator(gen())
assert r.text == "AB"
@@ -1668,7 +1668,7 @@ def test_chat_response_update_all_content_types():
def test_agent_run_response_complex_serialization():
"""Test AgentRunResponse from_dict and to_dict with messages and usage_details."""
"""Test AgentResponse from_dict and to_dict with messages and usage_details."""
response_data = {
"messages": [
@@ -1683,7 +1683,7 @@ def test_agent_run_response_complex_serialization():
},
}
response = AgentRunResponse.from_dict(response_data)
response = AgentResponse.from_dict(response_data)
assert len(response.messages) == 2
assert isinstance(response.messages[0], ChatMessage)
assert isinstance(response.usage_details, UsageDetails)
@@ -1696,7 +1696,7 @@ def test_agent_run_response_complex_serialization():
def test_agent_run_response_update_all_content_types():
"""Test AgentRunResponseUpdate from_dict with all content types and role handling."""
"""Test AgentResponseUpdate from_dict with all content types and role handling."""
update_data = {
"contents": [
@@ -1725,7 +1725,7 @@ def test_agent_run_response_update_all_content_types():
"role": {"value": "assistant"}, # Test role as dict
}
update = AgentRunResponseUpdate.from_dict(update_data)
update = AgentResponseUpdate.from_dict(update_data)
assert len(update.contents) == 12 # unknown_type is logged and ignored
assert isinstance(update.role, Role)
assert update.role.value == "assistant"
@@ -1738,7 +1738,7 @@ def test_agent_run_response_update_all_content_types():
# Test role as string conversion
update_data_str_role = update_data.copy()
update_data_str_role["role"] = "user"
update_str = AgentRunResponseUpdate.from_dict(update_data_str_role)
update_str = AgentResponseUpdate.from_dict(update_data_str_role)
assert isinstance(update_str.role, Role)
assert update_str.role.value == "user"
@@ -1922,7 +1922,7 @@ def test_agent_run_response_update_all_content_types():
id="chat_response_update",
),
pytest.param(
AgentRunResponse,
AgentResponse,
{
"messages": [
{
@@ -1942,10 +1942,10 @@ def test_agent_run_response_update_all_content_types():
"total_token_count": 8,
},
},
id="agent_run_response",
id="agent_response",
),
pytest.param(
AgentRunResponseUpdate,
AgentResponseUpdate,
{
"contents": [
{"type": "text", "text": "Streaming"},
@@ -1956,7 +1956,7 @@ def test_agent_run_response_update_all_content_types():
"response_id": "run-123",
"author_name": "Agent",
},
id="agent_run_response_update",
id="agent_response_update",
),
],
)
@@ -11,8 +11,8 @@ from openai.types.beta.threads.runs import RunStep
from pydantic import Field
from agent_framework import (
AgentRunResponse,
AgentRunResponseUpdate,
AgentResponse,
AgentResponseUpdate,
AgentThread,
ChatAgent,
ChatClientProtocol,
@@ -1118,7 +1118,7 @@ async def test_openai_assistants_agent_basic_run():
response = await agent.run("Hello! Please respond with 'Hello World' exactly.")
# Validate response
assert isinstance(response, AgentRunResponse)
assert isinstance(response, AgentResponse)
assert response.text is not None
assert len(response.text) > 0
assert "Hello World" in response.text
@@ -1135,7 +1135,7 @@ async def test_openai_assistants_agent_basic_run_streaming():
full_message: str = ""
async for chunk in agent.run_stream("Please respond with exactly: 'This is a streaming response test.'"):
assert chunk is not None
assert isinstance(chunk, AgentRunResponseUpdate)
assert isinstance(chunk, AgentResponseUpdate)
if chunk.text:
full_message += chunk.text
@@ -1159,14 +1159,14 @@ async def test_openai_assistants_agent_thread_persistence():
first_response = await agent.run(
"Remember this number: 42. What number did I just tell you to remember?", thread=thread
)
assert isinstance(first_response, AgentRunResponse)
assert isinstance(first_response, AgentResponse)
assert "42" in first_response.text
# Second message - test conversation memory
second_response = await agent.run(
"What number did I tell you to remember in my previous message?", thread=thread
)
assert isinstance(second_response, AgentRunResponse)
assert isinstance(second_response, AgentResponse)
assert "42" in second_response.text
# Verify thread has been populated with conversation ID
@@ -1190,7 +1190,7 @@ async def test_openai_assistants_agent_existing_thread_id():
response1 = await agent.run("What's the weather in Paris?", thread=thread)
# Validate first response
assert isinstance(response1, AgentRunResponse)
assert isinstance(response1, AgentResponse)
assert response1.text is not None
assert any(word in response1.text.lower() for word in ["weather", "paris"])
@@ -1212,7 +1212,7 @@ async def test_openai_assistants_agent_existing_thread_id():
response2 = await agent.run("What was the last city I asked about?", thread=thread)
# Validate that the agent remembers the previous conversation
assert isinstance(response2, AgentRunResponse)
assert isinstance(response2, AgentResponse)
assert response2.text is not None
# Should reference Paris from the previous conversation
assert "paris" in response2.text.lower()
@@ -1232,7 +1232,7 @@ async def test_openai_assistants_agent_code_interpreter():
response = await agent.run("Write Python code to calculate the factorial of 5 and show the result.")
# Validate response
assert isinstance(response, AgentRunResponse)
assert isinstance(response, AgentResponse)
assert response.text is not None
# Factorial of 5 is 120
assert "120" in response.text or "factorial" in response.text.lower()
@@ -1251,7 +1251,7 @@ async def test_agent_level_tool_persistence():
# First run - agent-level tool should be available
first_response = await agent.run("What's the weather like in Chicago?")
assert isinstance(first_response, AgentRunResponse)
assert isinstance(first_response, AgentResponse)
assert first_response.text is not None
# Should use the agent-level weather tool
assert any(term in first_response.text.lower() for term in ["chicago", "sunny", "72"])
@@ -1259,7 +1259,7 @@ async def test_agent_level_tool_persistence():
# Second run - agent-level tool should still be available (persistence test)
second_response = await agent.run("What's the weather in Miami?")
assert isinstance(second_response, AgentRunResponse)
assert isinstance(second_response, AgentResponse)
assert second_response.text is not None
# Should use the agent-level weather tool again
assert any(term in second_response.text.lower() for term in ["miami", "sunny", "72"])
@@ -5,8 +5,8 @@ from typing import Any
from agent_framework import (
AgentExecutor,
AgentRunResponse,
AgentRunResponseUpdate,
AgentResponse,
AgentResponseUpdate,
AgentThread,
BaseAgent,
ChatMessage,
@@ -35,9 +35,9 @@ class _CountingAgent(BaseAgent):
*,
thread: AgentThread | None = None,
**kwargs: Any,
) -> AgentRunResponse:
) -> AgentResponse:
self.call_count += 1
return AgentRunResponse(
return AgentResponse(
messages=[ChatMessage(role=Role.ASSISTANT, text=f"Response #{self.call_count}: {self.name}")]
)
@@ -47,9 +47,9 @@ class _CountingAgent(BaseAgent):
*,
thread: AgentThread | None = None,
**kwargs: Any,
) -> AsyncIterable[AgentRunResponseUpdate]:
) -> AsyncIterable[AgentResponseUpdate]:
self.call_count += 1
yield AgentRunResponseUpdate(contents=[TextContent(text=f"Response #{self.call_count}: {self.name}")])
yield AgentResponseUpdate(contents=[TextContent(text=f"Response #{self.call_count}: {self.name}")])
async def test_agent_executor_checkpoint_stores_and_restores_state() -> None:
@@ -10,8 +10,8 @@ from typing_extensions import Never
from agent_framework import (
AgentExecutor,
AgentExecutorResponse,
AgentRunResponse,
AgentRunResponseUpdate,
AgentResponse,
AgentResponseUpdate,
AgentRunUpdateEvent,
AgentThread,
BaseAgent,
@@ -46,9 +46,9 @@ class _ToolCallingAgent(BaseAgent):
*,
thread: AgentThread | None = None,
**kwargs: Any,
) -> AgentRunResponse:
) -> AgentResponse:
"""Non-streaming run - not used in this test."""
return AgentRunResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="done")])
return AgentResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="done")])
async def run_stream(
self,
@@ -56,16 +56,16 @@ class _ToolCallingAgent(BaseAgent):
*,
thread: AgentThread | None = None,
**kwargs: Any,
) -> AsyncIterable[AgentRunResponseUpdate]:
) -> AsyncIterable[AgentResponseUpdate]:
"""Simulate streaming with tool calls and results."""
# First update: some text
yield AgentRunResponseUpdate(
yield AgentResponseUpdate(
contents=[TextContent(text="Let me search for that...")],
role=Role.ASSISTANT,
)
# Second update: tool call (no text!)
yield AgentRunResponseUpdate(
yield AgentResponseUpdate(
contents=[
FunctionCallContent(
call_id="call_123",
@@ -77,7 +77,7 @@ class _ToolCallingAgent(BaseAgent):
)
# Third update: tool result (no text!)
yield AgentRunResponseUpdate(
yield AgentResponseUpdate(
contents=[
FunctionResultContent(
call_id="call_123",
@@ -88,7 +88,7 @@ class _ToolCallingAgent(BaseAgent):
)
# Fourth update: final text response
yield AgentRunResponseUpdate(
yield AgentResponseUpdate(
contents=[TextContent(text="The weather is sunny, 72°F.")],
role=Role.ASSISTANT,
)
@@ -223,7 +223,7 @@ class MockChatClient:
@executor(id="test_executor")
async def test_executor(agent_executor_response: AgentExecutorResponse, ctx: WorkflowContext[Never, str]) -> None:
await ctx.yield_output(agent_executor_response.agent_run_response.text)
await ctx.yield_output(agent_executor_response.agent_response.text)
async def test_agent_executor_tool_call_with_approval() -> None:
@@ -2,26 +2,26 @@
"""Tests for AgentRunEvent and AgentRunUpdateEvent type annotations."""
from agent_framework import AgentRunResponse, AgentRunResponseUpdate, ChatMessage, Role
from agent_framework import AgentResponse, AgentResponseUpdate, ChatMessage, Role
from agent_framework._workflows._events import AgentRunEvent, AgentRunUpdateEvent
def test_agent_run_event_data_type() -> None:
"""Verify AgentRunEvent.data is typed as AgentRunResponse | None."""
response = AgentRunResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="Hello")])
"""Verify AgentRunEvent.data is typed as AgentResponse | None."""
response = AgentResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="Hello")])
event = AgentRunEvent(executor_id="test", data=response)
# This assignment should pass type checking without a cast
data: AgentRunResponse | None = event.data
data: AgentResponse | None = event.data
assert data is not None
assert data.text == "Hello"
def test_agent_run_update_event_data_type() -> None:
"""Verify AgentRunUpdateEvent.data is typed as AgentRunResponseUpdate | None."""
update = AgentRunResponseUpdate()
"""Verify AgentRunUpdateEvent.data is typed as AgentResponseUpdate | None."""
update = AgentResponseUpdate()
event = AgentRunUpdateEvent(executor_id="test", data=update)
# This assignment should pass type checking without a cast
data: AgentRunResponseUpdate | None = event.data
data: AgentResponseUpdate | None = event.data
assert data is not None
@@ -3,7 +3,7 @@
from collections.abc import AsyncIterable
from typing import Any
from agent_framework import AgentRunResponse, AgentRunResponseUpdate, AgentThread, ChatMessage
from agent_framework import AgentResponse, AgentResponseUpdate, AgentThread, ChatMessage
from agent_framework._workflows._agent_utils import resolve_agent_id
@@ -38,7 +38,7 @@ class MockAgent:
*,
thread: AgentThread | None = None,
**kwargs: Any,
) -> AgentRunResponse: ...
) -> AgentResponse: ...
def run_stream(
self,
@@ -46,7 +46,7 @@ class MockAgent:
*,
thread: AgentThread | None = None,
**kwargs: Any,
) -> AsyncIterable[AgentRunResponseUpdate]: ...
) -> AsyncIterable[AgentResponseUpdate]: ...
def get_new_thread(self, **kwargs: Any) -> AgentThread:
"""Creates a new conversation thread for the agent."""
@@ -8,7 +8,7 @@ from typing_extensions import Never
from agent_framework import (
AgentExecutorRequest,
AgentExecutorResponse,
AgentRunResponse,
AgentResponse,
ChatMessage,
ConcurrentBuilder,
Executor,
@@ -36,7 +36,7 @@ class _FakeAgentExec(Executor):
@handler
async def run(self, request: AgentExecutorRequest, ctx: WorkflowContext[AgentExecutorResponse]) -> None:
response = AgentRunResponse(messages=ChatMessage(Role.ASSISTANT, text=self._reply_text))
response = AgentResponse(messages=ChatMessage(Role.ASSISTANT, text=self._reply_text))
full_conversation = list(request.messages) + list(response.messages)
await ctx.send_message(AgentExecutorResponse(self.id, response, full_conversation=full_conversation))
@@ -142,7 +142,7 @@ async def test_concurrent_custom_aggregator_callback_is_used() -> None:
async def summarize(results: list[AgentExecutorResponse]) -> str:
texts: list[str] = []
for r in results:
msgs: list[ChatMessage] = r.agent_run_response.messages
msgs: list[ChatMessage] = r.agent_response.messages
texts.append(msgs[-1].text if msgs else "")
return " | ".join(sorted(texts))
@@ -173,7 +173,7 @@ async def test_concurrent_custom_aggregator_sync_callback_is_used() -> None:
def summarize_sync(results: list[AgentExecutorResponse], _ctx: WorkflowContext[Any]) -> str: # type: ignore[unused-argument]
texts: list[str] = []
for r in results:
msgs: list[ChatMessage] = r.agent_run_response.messages
msgs: list[ChatMessage] = r.agent_response.messages
texts.append(msgs[-1].text if msgs else "")
return " | ".join(sorted(texts))
@@ -217,7 +217,7 @@ async def test_concurrent_with_aggregator_executor_instance() -> None:
async def aggregate(self, results: list[AgentExecutorResponse], ctx: WorkflowContext[Never, str]) -> None:
texts: list[str] = []
for r in results:
msgs: list[ChatMessage] = r.agent_run_response.messages
msgs: list[ChatMessage] = r.agent_response.messages
texts.append(msgs[-1].text if msgs else "")
await ctx.yield_output(" & ".join(sorted(texts)))
@@ -251,7 +251,7 @@ async def test_concurrent_with_aggregator_executor_factory() -> None:
async def aggregate(self, results: list[AgentExecutorResponse], ctx: WorkflowContext[Never, str]) -> None:
texts: list[str] = []
for r in results:
msgs: list[ChatMessage] = r.agent_run_response.messages
msgs: list[ChatMessage] = r.agent_response.messages
texts.append(msgs[-1].text if msgs else "")
await ctx.yield_output(" | ".join(sorted(texts)))
@@ -292,7 +292,7 @@ async def test_concurrent_with_aggregator_executor_factory_with_default_id() ->
async def aggregate(self, results: list[AgentExecutorResponse], ctx: WorkflowContext[Never, str]) -> None:
texts: list[str] = []
for r in results:
msgs: list[ChatMessage] = r.agent_run_response.messages
msgs: list[ChatMessage] = r.agent_response.messages
texts.append(msgs[-1].text if msgs else "")
await ctx.yield_output(" | ".join(sorted(texts)))
@@ -9,8 +9,8 @@ from typing_extensions import Never
from agent_framework import (
AgentExecutor,
AgentExecutorResponse,
AgentRunResponse,
AgentRunResponseUpdate,
AgentResponse,
AgentResponseUpdate,
AgentThread,
BaseAgent,
ChatMessage,
@@ -39,8 +39,8 @@ class _SimpleAgent(BaseAgent):
*,
thread: AgentThread | None = None,
**kwargs: Any,
) -> AgentRunResponse:
return AgentRunResponse(messages=[ChatMessage(role=Role.ASSISTANT, text=self._reply_text)])
) -> AgentResponse:
return AgentResponse(messages=[ChatMessage(role=Role.ASSISTANT, text=self._reply_text)])
async def run_stream( # type: ignore[override]
self,
@@ -48,9 +48,9 @@ class _SimpleAgent(BaseAgent):
*,
thread: AgentThread | None = None,
**kwargs: Any,
) -> AsyncIterable[AgentRunResponseUpdate]:
) -> AsyncIterable[AgentResponseUpdate]:
# This agent does not support streaming; yield a single complete response
yield AgentRunResponseUpdate(contents=[TextContent(text=self._reply_text)])
yield AgentResponseUpdate(contents=[TextContent(text=self._reply_text)])
class _CaptureFullConversation(Executor):
@@ -108,7 +108,7 @@ class _CaptureAgent(BaseAgent):
*,
thread: AgentThread | None = None,
**kwargs: Any,
) -> AgentRunResponse:
) -> AgentResponse:
# Normalize and record messages for verification when running non-streaming
norm: list[ChatMessage] = []
if messages:
@@ -118,7 +118,7 @@ class _CaptureAgent(BaseAgent):
elif isinstance(m, str):
norm.append(ChatMessage(role=Role.USER, text=m))
self._last_messages = norm
return AgentRunResponse(messages=[ChatMessage(role=Role.ASSISTANT, text=self._reply_text)])
return AgentResponse(messages=[ChatMessage(role=Role.ASSISTANT, text=self._reply_text)])
async def run_stream( # type: ignore[override]
self,
@@ -126,7 +126,7 @@ class _CaptureAgent(BaseAgent):
*,
thread: AgentThread | None = None,
**kwargs: Any,
) -> AsyncIterable[AgentRunResponseUpdate]:
) -> AsyncIterable[AgentResponseUpdate]:
# Normalize and record messages for verification when running streaming
norm: list[ChatMessage] = []
if messages:
@@ -136,7 +136,7 @@ class _CaptureAgent(BaseAgent):
elif isinstance(m, str):
norm.append(ChatMessage(role=Role.USER, text=m))
self._last_messages = norm
yield AgentRunResponseUpdate(contents=[TextContent(text=self._reply_text)])
yield AgentResponseUpdate(contents=[TextContent(text=self._reply_text)])
async def test_sequential_adapter_uses_full_conversation() -> None:
@@ -8,8 +8,8 @@ import pytest
from agent_framework import (
AgentExecutorResponse,
AgentRequestInfoResponse,
AgentRunResponse,
AgentRunResponseUpdate,
AgentResponse,
AgentResponseUpdate,
AgentThread,
BaseAgent,
BaseGroupChatOrchestrator,
@@ -44,9 +44,9 @@ class StubAgent(BaseAgent):
*,
thread: AgentThread | None = None,
**kwargs: Any,
) -> AgentRunResponse:
) -> AgentResponse:
response = ChatMessage(role=Role.ASSISTANT, text=self._reply_text, author_name=self.name)
return AgentRunResponse(messages=[response])
return AgentResponse(messages=[response])
def run_stream( # type: ignore[override]
self,
@@ -54,9 +54,9 @@ class StubAgent(BaseAgent):
*,
thread: AgentThread | None = None,
**kwargs: Any,
) -> AsyncIterable[AgentRunResponseUpdate]:
async def _stream() -> AsyncIterable[AgentRunResponseUpdate]:
yield AgentRunResponseUpdate(
) -> AsyncIterable[AgentResponseUpdate]:
async def _stream() -> AsyncIterable[AgentResponseUpdate]:
yield AgentResponseUpdate(
contents=[TextContent(text=self._reply_text)], role=Role.ASSISTANT, author_name=self.name
)
@@ -88,12 +88,12 @@ class StubManagerAgent(ChatAgent):
*,
thread: AgentThread | None = None,
**kwargs: Any,
) -> AgentRunResponse:
) -> AgentResponse:
if self._call_count == 0:
self._call_count += 1
# First call: select the agent (using AgentOrchestrationOutput format)
payload = {"terminate": False, "reason": "Selecting agent", "next_speaker": "agent", "final_message": None}
return AgentRunResponse(
return AgentResponse(
messages=[
ChatMessage(
role=Role.ASSISTANT,
@@ -114,7 +114,7 @@ class StubManagerAgent(ChatAgent):
"next_speaker": None,
"final_message": "agent manager final",
}
return AgentRunResponse(
return AgentResponse(
messages=[
ChatMessage(
role=Role.ASSISTANT,
@@ -134,12 +134,12 @@ class StubManagerAgent(ChatAgent):
*,
thread: AgentThread | None = None,
**kwargs: Any,
) -> AsyncIterable[AgentRunResponseUpdate]:
) -> AsyncIterable[AgentResponseUpdate]:
if self._call_count == 0:
self._call_count += 1
async def _stream_initial() -> AsyncIterable[AgentRunResponseUpdate]:
yield AgentRunResponseUpdate(
async def _stream_initial() -> AsyncIterable[AgentResponseUpdate]:
yield AgentResponseUpdate(
contents=[
TextContent(
text=(
@@ -154,8 +154,8 @@ class StubManagerAgent(ChatAgent):
return _stream_initial()
async def _stream_final() -> AsyncIterable[AgentRunResponseUpdate]:
yield AgentRunResponseUpdate(
async def _stream_final() -> AsyncIterable[AgentResponseUpdate]:
yield AgentResponseUpdate(
contents=[
TextContent(
text=(
@@ -341,14 +341,14 @@ class TestGroupChatBuilder:
def __init__(self) -> None:
super().__init__(name="", description="test")
async def run(self, messages: Any = None, *, thread: Any = None, **kwargs: Any) -> AgentRunResponse:
return AgentRunResponse(messages=[])
async def run(self, messages: Any = None, *, thread: Any = None, **kwargs: Any) -> AgentResponse:
return AgentResponse(messages=[])
def run_stream(
self, messages: Any = None, *, thread: Any = None, **kwargs: Any
) -> AsyncIterable[AgentRunResponseUpdate]:
async def _stream() -> AsyncIterable[AgentRunResponseUpdate]:
yield AgentRunResponseUpdate(contents=[])
) -> AsyncIterable[AgentResponseUpdate]:
async def _stream() -> AsyncIterable[AgentResponseUpdate]:
yield AgentResponseUpdate(contents=[])
return _stream()
@@ -9,8 +9,8 @@ import pytest
from agent_framework import (
AgentProtocol,
AgentRunResponse,
AgentRunResponseUpdate,
AgentResponse,
AgentResponseUpdate,
AgentRunUpdateEvent,
AgentThread,
BaseAgent,
@@ -158,9 +158,9 @@ class StubAgent(BaseAgent):
*,
thread: AgentThread | None = None,
**kwargs: Any,
) -> AgentRunResponse:
) -> AgentResponse:
response = ChatMessage(role=Role.ASSISTANT, text=self._reply_text, author_name=self.name)
return AgentRunResponse(messages=[response])
return AgentResponse(messages=[response])
def run_stream( # type: ignore[override]
self,
@@ -168,9 +168,9 @@ class StubAgent(BaseAgent):
*,
thread: AgentThread | None = None,
**kwargs: Any,
) -> AsyncIterable[AgentRunResponseUpdate]:
async def _stream() -> AsyncIterable[AgentRunResponseUpdate]:
yield AgentRunResponseUpdate(
) -> AsyncIterable[AgentResponseUpdate]:
async def _stream() -> AsyncIterable[AgentResponseUpdate]:
yield AgentResponseUpdate(
contents=[TextContent(text=self._reply_text)], role=Role.ASSISTANT, author_name=self.name
)
@@ -424,8 +424,8 @@ class StubManagerAgent(BaseAgent):
*,
thread: Any = None,
**kwargs: Any,
) -> AgentRunResponse:
return AgentRunResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="ok")])
) -> AgentResponse:
return AgentResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="ok")])
def run_stream(
self,
@@ -433,9 +433,9 @@ class StubManagerAgent(BaseAgent):
*,
thread: Any = None,
**kwargs: Any,
) -> AsyncIterable[AgentRunResponseUpdate]:
async def _gen() -> AsyncIterable[AgentRunResponseUpdate]:
yield AgentRunResponseUpdate(message_deltas=[ChatMessage(role=Role.ASSISTANT, text="ok")])
) -> AsyncIterable[AgentResponseUpdate]:
async def _gen() -> AsyncIterable[AgentResponseUpdate]:
yield AgentResponseUpdate(message_deltas=[ChatMessage(role=Role.ASSISTANT, text="ok")])
return _gen()
@@ -538,14 +538,14 @@ class StubThreadAgent(BaseAgent):
super().__init__(name=name or "agentA")
async def run_stream(self, messages=None, *, thread=None, **kwargs): # type: ignore[override]
yield AgentRunResponseUpdate(
yield AgentResponseUpdate(
contents=[TextContent(text="thread-ok")],
author_name=self.name,
role=Role.ASSISTANT,
)
async def run(self, messages=None, *, thread=None, **kwargs): # type: ignore[override]
return AgentRunResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="thread-ok", author_name=self.name)])
return AgentResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="thread-ok", author_name=self.name)])
class StubAssistantsClient:
@@ -560,16 +560,14 @@ class StubAssistantsAgent(BaseAgent):
self.chat_client = StubAssistantsClient() # type name contains 'AssistantsClient'
async def run_stream(self, messages=None, *, thread=None, **kwargs): # type: ignore[override]
yield AgentRunResponseUpdate(
yield AgentResponseUpdate(
contents=[TextContent(text="assistants-ok")],
author_name=self.name,
role=Role.ASSISTANT,
)
async def run(self, messages=None, *, thread=None, **kwargs): # type: ignore[override]
return AgentRunResponse(
messages=[ChatMessage(role=Role.ASSISTANT, text="assistants-ok", author_name=self.name)]
)
return AgentResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="assistants-ok", author_name=self.name)])
async def _collect_agent_responses_setup(participant: AgentProtocol) -> list[ChatMessage]:
@@ -10,8 +10,8 @@ import pytest
from agent_framework import (
AgentProtocol,
AgentRunResponse,
AgentRunResponseUpdate,
AgentResponse,
AgentResponseUpdate,
AgentThread,
ChatMessage,
Role,
@@ -114,10 +114,10 @@ class TestAgentRequestInfoExecutor:
"""Test that request_info handler calls ctx.request_info."""
executor = AgentRequestInfoExecutor(id="test_executor")
agent_run_response = AgentRunResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="Agent response")])
agent_response = AgentResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="Agent response")])
agent_response = AgentExecutorResponse(
executor_id="test_agent",
agent_run_response=agent_run_response,
agent_response=agent_response,
)
ctx = MagicMock(spec=WorkflowContext)
@@ -132,10 +132,10 @@ class TestAgentRequestInfoExecutor:
"""Test response handler when user provides additional messages."""
executor = AgentRequestInfoExecutor(id="test_executor")
agent_run_response = AgentRunResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="Original")])
agent_response = AgentResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="Original")])
original_request = AgentExecutorResponse(
executor_id="test_agent",
agent_run_response=agent_run_response,
agent_response=agent_response,
)
response = AgentRequestInfoResponse.from_strings(["Additional input"])
@@ -158,10 +158,10 @@ class TestAgentRequestInfoExecutor:
"""Test response handler when user approves (no additional messages)."""
executor = AgentRequestInfoExecutor(id="test_executor")
agent_run_response = AgentRunResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="Original")])
agent_response = AgentResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="Original")])
original_request = AgentExecutorResponse(
executor_id="test_agent",
agent_run_response=agent_run_response,
agent_response=agent_response,
)
response = AgentRequestInfoResponse.approve()
@@ -205,9 +205,9 @@ class _TestAgent:
*,
thread: AgentThread | None = None,
**kwargs: Any,
) -> AgentRunResponse:
) -> AgentResponse:
"""Dummy run method."""
return AgentRunResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="Test response")])
return AgentResponse(messages=[ChatMessage(role=Role.ASSISTANT, text="Test response")])
def run_stream(
self,
@@ -215,11 +215,11 @@ class _TestAgent:
*,
thread: AgentThread | None = None,
**kwargs: Any,
) -> AsyncIterable[AgentRunResponseUpdate]:
) -> AsyncIterable[AgentResponseUpdate]:
"""Dummy run_stream method."""
async def generator():
yield AgentRunResponseUpdate(messages=[ChatMessage(role=Role.ASSISTANT, text="Test response stream")])
yield AgentResponseUpdate(messages=[ChatMessage(role=Role.ASSISTANT, text="Test response stream")])
return generator()
@@ -7,7 +7,7 @@ import pytest
from agent_framework import (
AgentExecutorResponse,
AgentRunResponse,
AgentResponse,
Executor,
WorkflowContext,
WorkflowEvent,
@@ -158,7 +158,7 @@ async def test_runner_emits_runner_completion_for_agent_response_without_targets
await ctx.send_message(
Message(
data=AgentExecutorResponse("agent", AgentRunResponse()),
data=AgentExecutorResponse("agent", AgentResponse()),
source_id="agent",
)
)
@@ -7,8 +7,8 @@ import pytest
from agent_framework import (
AgentExecutorResponse,
AgentRunResponse,
AgentRunResponseUpdate,
AgentResponse,
AgentResponseUpdate,
AgentThread,
BaseAgent,
ChatMessage,
@@ -35,8 +35,8 @@ class _EchoAgent(BaseAgent):
*,
thread: AgentThread | None = None,
**kwargs: Any,
) -> AgentRunResponse:
return AgentRunResponse(messages=[ChatMessage(role=Role.ASSISTANT, text=f"{self.name} reply")])
) -> AgentResponse:
return AgentResponse(messages=[ChatMessage(role=Role.ASSISTANT, text=f"{self.name} reply")])
async def run_stream( # type: ignore[override]
self,
@@ -44,9 +44,9 @@ class _EchoAgent(BaseAgent):
*,
thread: AgentThread | None = None,
**kwargs: Any,
) -> AsyncIterable[AgentRunResponseUpdate]:
) -> AsyncIterable[AgentResponseUpdate]:
# Minimal async generator with one assistant update
yield AgentRunResponseUpdate(contents=[TextContent(text=f"{self.name} reply")])
yield AgentResponseUpdate(contents=[TextContent(text=f"{self.name} reply")])
class _SummarizerExec(Executor):
@@ -11,9 +11,9 @@ import pytest
from agent_framework import (
AgentExecutor,
AgentResponse,
AgentResponseUpdate,
AgentRunEvent,
AgentRunResponse,
AgentRunResponseUpdate,
AgentRunUpdateEvent,
AgentThread,
BaseAgent,
@@ -831,9 +831,9 @@ class _StreamingTestAgent(BaseAgent):
*,
thread: AgentThread | None = None,
**kwargs: Any,
) -> AgentRunResponse:
) -> AgentResponse:
"""Non-streaming run - returns complete response."""
return AgentRunResponse(messages=[ChatMessage(role=Role.ASSISTANT, text=self._reply_text)])
return AgentResponse(messages=[ChatMessage(role=Role.ASSISTANT, text=self._reply_text)])
async def run_stream(
self,
@@ -841,11 +841,11 @@ class _StreamingTestAgent(BaseAgent):
*,
thread: AgentThread | None = None,
**kwargs: Any,
) -> AsyncIterable[AgentRunResponseUpdate]:
) -> AsyncIterable[AgentResponseUpdate]:
"""Streaming run - yields incremental updates."""
# Simulate streaming by yielding character by character
for char in self._reply_text:
yield AgentRunResponseUpdate(contents=[TextContent(text=char)])
yield AgentResponseUpdate(contents=[TextContent(text=char)])
async def test_agent_streaming_vs_non_streaming() -> None:
@@ -8,8 +8,8 @@ import pytest
from agent_framework import (
AgentProtocol,
AgentRunResponse,
AgentRunResponseUpdate,
AgentResponse,
AgentResponseUpdate,
AgentRunUpdateEvent,
AgentThread,
ChatMessage,
@@ -52,7 +52,7 @@ class SimpleExecutor(Executor):
response_message = ChatMessage(role=Role.ASSISTANT, contents=[TextContent(text=response_text)])
# Emit update event.
streaming_update = AgentRunResponseUpdate(
streaming_update = AgentResponseUpdate(
contents=[TextContent(text=response_text)], role=Role.ASSISTANT, message_id=str(uuid.uuid4())
)
await ctx.add_event(AgentRunUpdateEvent(executor_id=self.id, data=streaming_update))
@@ -74,7 +74,7 @@ class RequestingExecutor(Executor):
self, original_request: str, response: str, ctx: WorkflowContext[ChatMessage]
) -> None:
# Handle the response and emit completion response
update = AgentRunResponseUpdate(
update = AgentResponseUpdate(
contents=[TextContent(text="Request completed successfully")],
role=Role.ASSISTANT,
message_id=str(uuid.uuid4()),
@@ -100,7 +100,7 @@ class ConversationHistoryCapturingExecutor(Executor):
response_message = ChatMessage(role=Role.ASSISTANT, contents=[TextContent(text=response_text)])
streaming_update = AgentRunResponseUpdate(
streaming_update = AgentResponseUpdate(
contents=[TextContent(text=response_text)], role=Role.ASSISTANT, message_id=str(uuid.uuid4())
)
await ctx.add_event(AgentRunUpdateEvent(executor_id=self.id, data=streaming_update))
@@ -124,7 +124,7 @@ class TestWorkflowAgent:
result = await agent.run("Hello World")
# Verify we got responses from both executors
assert isinstance(result, AgentRunResponse)
assert isinstance(result, AgentResponse)
assert len(result.messages) >= 2, f"Expected at least 2 messages, got {len(result.messages)}"
# Find messages from each executor
@@ -162,7 +162,7 @@ class TestWorkflowAgent:
agent = WorkflowAgent(workflow=workflow, name="Streaming Test Agent")
# Execute workflow streaming to capture streaming events
updates: list[AgentRunResponseUpdate] = []
updates: list[AgentResponseUpdate] = []
async for update in agent.run_stream("Test input"):
updates.append(update)
@@ -191,13 +191,13 @@ class TestWorkflowAgent:
agent = WorkflowAgent(workflow=workflow, name="Request Test Agent")
# Execute workflow streaming to get request info event
updates: list[AgentRunResponseUpdate] = []
updates: list[AgentResponseUpdate] = []
async for update in agent.run_stream("Start request"):
updates.append(update)
# Should have received an approval request for the request info
assert len(updates) > 0
approval_update: AgentRunResponseUpdate | None = None
approval_update: AgentResponseUpdate | None = None
for update in updates:
if any(isinstance(content, FunctionApprovalRequestContent) for content in update.contents):
approval_update = update
@@ -248,7 +248,7 @@ class TestWorkflowAgent:
continuation_result = await agent.run(response_message)
# Should complete successfully
assert isinstance(continuation_result, AgentRunResponse)
assert isinstance(continuation_result, AgentResponse)
# Verify cleanup - pending requests should be cleared after function response handling
assert len(agent.pending_requests) == 0
@@ -293,7 +293,7 @@ class TestWorkflowAgent:
"""Test that ctx.yield_output() in a workflow executor surfaces as agent output when using .as_agent().
This validates the fix for issue #2813: WorkflowOutputEvent should be converted to
AgentRunResponseUpdate when the workflow is wrapped via .as_agent().
AgentResponseUpdate when the workflow is wrapped via .as_agent().
"""
@executor
@@ -314,12 +314,12 @@ class TestWorkflowAgent:
agent = workflow.as_agent("test-agent")
agent_result = await agent.run("hello")
assert isinstance(agent_result, AgentRunResponse)
assert isinstance(agent_result, AgentResponse)
assert len(agent_result.messages) == 1
assert agent_result.messages[0].text == "processed: hello"
async def test_workflow_as_agent_yield_output_surfaces_in_run_stream(self) -> None:
"""Test that ctx.yield_output() surfaces as AgentRunResponseUpdate when streaming."""
"""Test that ctx.yield_output() surfaces as AgentResponseUpdate when streaming."""
@executor
async def yielding_executor(messages: list[ChatMessage], ctx: WorkflowContext) -> None:
@@ -329,7 +329,7 @@ class TestWorkflowAgent:
workflow = WorkflowBuilder().set_start_executor(yielding_executor).build()
agent = workflow.as_agent("test-agent")
updates: list[AgentRunResponseUpdate] = []
updates: list[AgentResponseUpdate] = []
async for update in agent.run_stream("hello"):
updates.append(update)
@@ -353,7 +353,7 @@ class TestWorkflowAgent:
result = await agent.run("test")
assert isinstance(result, AgentRunResponse)
assert isinstance(result, AgentResponse)
assert len(result.messages) == 3
# Verify each content type is preserved
@@ -410,7 +410,7 @@ class TestWorkflowAgent:
workflow = WorkflowBuilder().set_start_executor(raw_yielding_executor).build()
agent = workflow.as_agent("raw-test-agent")
updates: list[AgentRunResponseUpdate] = []
updates: list[AgentResponseUpdate] = []
async for update in agent.run_stream("test"):
updates.append(update)
@@ -448,7 +448,7 @@ class TestWorkflowAgent:
agent = workflow.as_agent("list-msg-agent")
# Verify streaming returns the update with all 4 contents before coalescing
updates: list[AgentRunResponseUpdate] = []
updates: list[AgentResponseUpdate] = []
async for update in agent.run_stream("test"):
updates.append(update)
@@ -460,7 +460,7 @@ class TestWorkflowAgent:
# Verify run() coalesces text contents (expected behavior)
result = await agent.run("test")
assert isinstance(result, AgentRunResponse)
assert isinstance(result, AgentResponse)
assert len(result.messages) == 1
# TextContent items are coalesced into one
assert len(result.messages[0].contents) == 1
@@ -587,17 +587,17 @@ class TestWorkflowAgent:
def get_new_thread(self) -> AgentThread:
return AgentThread()
async def run(self, messages: Any, *, thread: AgentThread | None = None, **kwargs: Any) -> AgentRunResponse:
return AgentRunResponse(
async def run(self, messages: Any, *, thread: AgentThread | None = None, **kwargs: Any) -> AgentResponse:
return AgentResponse(
messages=[ChatMessage(role=Role.ASSISTANT, text=self._response_text)],
text=self._response_text,
)
async def run_stream(
self, messages: Any, *, thread: AgentThread | None = None, **kwargs: Any
) -> AsyncIterable[AgentRunResponseUpdate]:
) -> AsyncIterable[AgentResponseUpdate]:
for word in self._response_text.split():
yield AgentRunResponseUpdate(
yield AgentResponseUpdate(
contents=[TextContent(text=word + " ")],
role=Role.ASSISTANT,
author_name=self._name,
@@ -661,16 +661,16 @@ class TestWorkflowAgent:
def get_new_thread(self) -> AgentThread:
return AgentThread()
async def run(self, messages: Any, *, thread: AgentThread | None = None, **kwargs: Any) -> AgentRunResponse:
return AgentRunResponse(
async def run(self, messages: Any, *, thread: AgentThread | None = None, **kwargs: Any) -> AgentResponse:
return AgentResponse(
messages=[ChatMessage(role=Role.ASSISTANT, text=self._response_text)],
text=self._response_text,
)
async def run_stream(
self, messages: Any, *, thread: AgentThread | None = None, **kwargs: Any
) -> AsyncIterable[AgentRunResponseUpdate]:
yield AgentRunResponseUpdate(
) -> AsyncIterable[AgentResponseUpdate]:
yield AgentResponseUpdate(
contents=[TextContent(text=self._response_text)],
role=Role.ASSISTANT,
author_name=self._name,
@@ -717,7 +717,7 @@ class TestWorkflowAgentAuthorName:
agent = WorkflowAgent(workflow=workflow, name="Test Agent")
# Collect streaming updates
updates: list[AgentRunResponseUpdate] = []
updates: list[AgentResponseUpdate] = []
async for update in agent.run_stream("Hello"):
updates.append(update)
@@ -736,7 +736,7 @@ class TestWorkflowAgentAuthorName:
@handler
async def handle_message(self, message: list[ChatMessage], ctx: WorkflowContext[list[ChatMessage]]) -> None:
# Emit update with explicit author_name
update = AgentRunResponseUpdate(
update = AgentResponseUpdate(
contents=[TextContent(text="Response with author")],
role=Role.ASSISTANT,
author_name="custom_author_name", # Explicitly set
@@ -749,7 +749,7 @@ class TestWorkflowAgentAuthorName:
agent = WorkflowAgent(workflow=workflow, name="Test Agent")
# Collect streaming updates
updates: list[AgentRunResponseUpdate] = []
updates: list[AgentResponseUpdate] = []
async for update in agent.run_stream("Hello"):
updates.append(update)
@@ -767,7 +767,7 @@ class TestWorkflowAgentAuthorName:
agent = WorkflowAgent(workflow=workflow, name="Multi-Executor Agent")
# Collect streaming updates
updates: list[AgentRunResponseUpdate] = []
updates: list[AgentResponseUpdate] = []
async for update in agent.run_stream("Hello"):
updates.append(update)
@@ -788,7 +788,7 @@ class TestWorkflowAgentMergeUpdates:
# Create updates with different response_ids and message_ids in non-chronological order
updates = [
# Response B, Message 2 (latest in resp B)
AgentRunResponseUpdate(
AgentResponseUpdate(
contents=[TextContent(text="RespB-Msg2")],
role=Role.ASSISTANT,
response_id="resp-b",
@@ -796,7 +796,7 @@ class TestWorkflowAgentMergeUpdates:
created_at="2024-01-01T12:02:00Z",
),
# Response A, Message 1 (earliest overall)
AgentRunResponseUpdate(
AgentResponseUpdate(
contents=[TextContent(text="RespA-Msg1")],
role=Role.ASSISTANT,
response_id="resp-a",
@@ -804,7 +804,7 @@ class TestWorkflowAgentMergeUpdates:
created_at="2024-01-01T12:00:00Z",
),
# Response B, Message 1 (earlier in resp B)
AgentRunResponseUpdate(
AgentResponseUpdate(
contents=[TextContent(text="RespB-Msg1")],
role=Role.ASSISTANT,
response_id="resp-b",
@@ -812,7 +812,7 @@ class TestWorkflowAgentMergeUpdates:
created_at="2024-01-01T12:01:00Z",
),
# Response A, Message 2 (later in resp A)
AgentRunResponseUpdate(
AgentResponseUpdate(
contents=[TextContent(text="RespA-Msg2")],
role=Role.ASSISTANT,
response_id="resp-a",
@@ -820,7 +820,7 @@ class TestWorkflowAgentMergeUpdates:
created_at="2024-01-01T12:00:30Z",
),
# Global dangling update (no response_id) - should go at end
AgentRunResponseUpdate(
AgentResponseUpdate(
contents=[TextContent(text="Global-Dangling")],
role=Role.ASSISTANT,
response_id=None,
@@ -891,7 +891,7 @@ class TestWorkflowAgentMergeUpdates:
"""Test that merge_updates correctly aggregates usage details, timestamps, and additional properties."""
# Create updates with various metadata including usage details
updates = [
AgentRunResponseUpdate(
AgentResponseUpdate(
contents=[
TextContent(text="First"),
UsageContent(
@@ -904,7 +904,7 @@ class TestWorkflowAgentMergeUpdates:
created_at="2024-01-01T12:00:00Z",
additional_properties={"source": "executor1", "priority": "high"},
),
AgentRunResponseUpdate(
AgentResponseUpdate(
contents=[
TextContent(text="Second"),
UsageContent(
@@ -917,7 +917,7 @@ class TestWorkflowAgentMergeUpdates:
created_at="2024-01-01T12:01:00Z", # Later timestamp
additional_properties={"source": "executor2", "category": "analysis"},
),
AgentRunResponseUpdate(
AgentResponseUpdate(
contents=[
TextContent(text="Third"),
UsageContent(details=UsageDetails(input_token_count=5, output_token_count=3, total_token_count=8)),
@@ -7,8 +7,8 @@ import pytest
from agent_framework import (
AgentExecutor,
AgentRunResponse,
AgentRunResponseUpdate,
AgentResponse,
AgentResponseUpdate,
AgentThread,
BaseAgent,
ChatMessage,
@@ -29,11 +29,11 @@ class DummyAgent(BaseAgent):
norm.append(m)
elif isinstance(m, str):
norm.append(ChatMessage(role=Role.USER, text=m))
return AgentRunResponse(messages=norm)
return AgentResponse(messages=norm)
async def run_stream(self, messages=None, *, thread: AgentThread | None = None, **kwargs): # type: ignore[override]
# Minimal async generator
yield AgentRunResponseUpdate()
yield AgentResponseUpdate()
def test_builder_accepts_agents_directly():
@@ -6,8 +6,8 @@ from typing import Annotated, Any
import pytest
from agent_framework import (
AgentRunResponse,
AgentRunResponseUpdate,
AgentResponse,
AgentResponseUpdate,
AgentThread,
BaseAgent,
ChatMessage,
@@ -55,9 +55,9 @@ class _KwargsCapturingAgent(BaseAgent):
*,
thread: AgentThread | None = None,
**kwargs: Any,
) -> AgentRunResponse:
) -> AgentResponse:
self.captured_kwargs.append(dict(kwargs))
return AgentRunResponse(messages=[ChatMessage(role=Role.ASSISTANT, text=f"{self.name} response")])
return AgentResponse(messages=[ChatMessage(role=Role.ASSISTANT, text=f"{self.name} response")])
async def run_stream(
self,
@@ -65,9 +65,9 @@ class _KwargsCapturingAgent(BaseAgent):
*,
thread: AgentThread | None = None,
**kwargs: Any,
) -> AsyncIterable[AgentRunResponseUpdate]:
) -> AsyncIterable[AgentResponseUpdate]:
self.captured_kwargs.append(dict(kwargs))
yield AgentRunResponseUpdate(contents=[TextContent(text=f"{self.name} response")])
yield AgentResponseUpdate(contents=[TextContent(text=f"{self.name} response")])
# region Sequential Builder Tests