Python: Added AgentRunResponse and AgentRunResponseUpdate types (#157)

* Removed instructions property from Agent

* Added AgentRunResponse and AgentRunResponseUpdate types

* Added unit tests for agent response types

* Small fix

* Addressed PR feedback

* Small improvement

* Small fix
This commit is contained in:
Dmytro Struk
2025-07-11 08:13:06 -07:00
committed by GitHub
Unverified
parent 456e7d1b65
commit df84675c0f
6 changed files with 241 additions and 32 deletions
+14 -7
View File
@@ -7,7 +7,15 @@ from uuid import uuid4
from pydantic import BaseModel, Field
from pytest import fixture
from agent_framework import Agent, AgentThread, ChatMessage, ChatResponse, ChatResponseUpdate, ChatRole, TextContent
from agent_framework import (
Agent,
AgentRunResponse,
AgentRunResponseUpdate,
AgentThread,
ChatMessage,
ChatRole,
TextContent,
)
TThreadType = TypeVar("TThreadType", bound=AgentThread)
@@ -29,7 +37,6 @@ class MockAgent(BaseModel):
id: str = Field(default_factory=lambda: str(uuid4()))
name: str | None = None
description: str | None = None
instructions: str | None = None
async def run(
self,
@@ -37,8 +44,8 @@ class MockAgent(BaseModel):
*,
thread: AgentThread | None = None,
**kwargs: Any,
) -> ChatResponse:
return ChatResponse(messages=[ChatMessage(role=ChatRole.ASSISTANT, contents=[TextContent("Response")])])
) -> AgentRunResponse:
return AgentRunResponse(messages=[ChatMessage(role=ChatRole.ASSISTANT, contents=[TextContent("Response")])])
async def run_stream(
self,
@@ -46,8 +53,8 @@ class MockAgent(BaseModel):
*,
thread: AgentThread | None = None,
**kwargs: Any,
) -> AsyncIterable[ChatResponseUpdate]:
yield ChatResponseUpdate(contents=[TextContent("Response")])
) -> AsyncIterable[AgentRunResponseUpdate]:
yield AgentRunResponseUpdate(contents=[TextContent("Response")])
def get_new_thread(self) -> AgentThread:
return MockAgentThread()
@@ -107,7 +114,7 @@ async def test_agent_run(agent: Agent) -> None:
async def test_agent_run_stream(agent: Agent) -> None:
async def collect_updates(updates: AsyncIterable[ChatResponseUpdate]) -> list[ChatResponseUpdate]:
async def collect_updates(updates: AsyncIterable[AgentRunResponseUpdate]) -> list[AgentRunResponseUpdate]:
return [u async for u in updates]
updates = await collect_updates(agent.run_stream(messages="test"))
+96 -1
View File
@@ -3,9 +3,11 @@
from collections.abc import MutableSequence
from pydantic import BaseModel, ValidationError
from pytest import mark, raises
from pytest import fixture, mark, raises
from agent_framework import (
AgentRunResponse,
AgentRunResponseUpdate,
AIContent,
AIContents,
ChatMessage,
@@ -480,3 +482,96 @@ def test_generated_embeddings():
# Ensure the instance is of type GeneratedEmbeddings
assert isinstance(embeddings, GeneratedEmbeddings)
assert issubclass(GeneratedEmbeddings, MutableSequence)
# region Agent Response Fixtures
@fixture
def chat_message() -> ChatMessage:
return ChatMessage(role=ChatRole.USER, text="Hello")
@fixture
def text_content() -> TextContent:
return TextContent(text="Test content")
@fixture
def agent_run_response(chat_message: ChatMessage) -> AgentRunResponse:
return AgentRunResponse(messages=chat_message)
@fixture
def agent_run_response_update(text_content: TextContent) -> AgentRunResponseUpdate:
return AgentRunResponseUpdate(role=ChatRole.ASSISTANT, contents=[text_content])
# region AgentRunResponse
def test_agent_run_response_init_single_message(chat_message: ChatMessage) -> None:
response = AgentRunResponse(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])
assert len(response.messages) == 2
assert response.messages[0] == chat_message
def test_agent_run_response_init_none_messages() -> None:
response = AgentRunResponse()
assert response.messages == []
def test_agent_run_response_text_property(chat_message: ChatMessage) -> None:
response = AgentRunResponse(messages=[chat_message, chat_message])
assert response.text == "HelloHello"
def test_agent_run_response_text_property_empty() -> None:
response = AgentRunResponse()
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)
assert len(response.messages) > 0
assert response.text == "Test content\nTest content"
def test_agent_run_response_str_method(chat_message: ChatMessage) -> None:
response = AgentRunResponse(messages=chat_message)
assert str(response) == "Hello"
# region AgentRunResponseUpdate
def test_agent_run_response_update_init_content_list(text_content: TextContent) -> None:
update = AgentRunResponseUpdate(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()
assert update.contents == []
def test_agent_run_response_update_text_property(text_content: TextContent) -> None:
update = AgentRunResponseUpdate(contents=[text_content, text_content])
assert update.text == "Test contentTest content"
def test_agent_run_response_update_text_property_empty() -> None:
update = AgentRunResponseUpdate()
assert update.text == ""
def test_agent_run_response_update_str_method(text_content: TextContent) -> None:
update = AgentRunResponseUpdate(contents=[text_content])
assert str(update) == "Test content"