mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
Python: [BREAKING] Simplify API: ChatAgent -> Agent, ChatMessage -> Message (#3747)
* [BREAKING] Rename ChatAgent -> Agent, ChatMessage -> Message, ChatClientProtocol -> SupportsChatGetResponse Simplify the public API by removing redundant 'Chat' prefix from core types: - ChatAgent -> Agent - RawChatAgent -> RawAgent - ChatMessage -> Message - ChatClientProtocol -> SupportsChatGetResponse Also renamed internal WorkflowMessage (was Message in _runner_context) to avoid collision. No backward compatibility aliases - this is a clean breaking change. * [BREAKING] Rename Agent chat_client parameter to client * Fix rebase issues: WorkflowMessage references and broken markdown links * Fix formatting and lint issues from code quality checks * Fix import ordering in workflow sample files * fixed rebase * Fix test failures: use WorkflowMessage and A2AMessage after ChatMessage→Message rename - Replace Message(data=..., source_id=...) with WorkflowMessage(...) in workflow tests - Fix isinstance check in A2A agent to use A2AMessage instead of Message - Fix import in test_workflow_observability.py (Message→WorkflowMessage) * Fix lint, fmt, and sample errors after ChatMessage→Message rename - Auto-fix 70+ ruff lint issues across samples (ChatMessage→Message refs) - Fix HostedVectorStoreContent→Content.from_hosted_vector_store in file search sample - Fix _normalize_messages→normalize_messages in custom agent sample - Fix context.terminate→raise MiddlewareTermination in middleware samples - Fix with_update_hook→with_transform_hook in override middleware sample - Add TOptions_co import back to custom_chat_client sample - Add noqa for FastAPI File() default in chatkit sample - Fix B023 loop variable capture in weather agent sample * fix: update Agent constructor calls from chat_client to client in declaration-only tool tests * fix: add register_cleanup to devui lazy-loading proxy and type stub * fixed tests and updated new pieces * fix agui typevar * fix merge errors * fix merge conflicts * fiux merge * Remove unused links --------- Co-authored-by: Evan Mattson <evan.mattson@microsoft.com>
This commit is contained in:
co-authored by
Evan Mattson
parent
a4c9e43afb
commit
0521f5bed8
@@ -6,13 +6,13 @@ from unittest.mock import AsyncMock, MagicMock
|
||||
|
||||
import pytest
|
||||
from agent_framework import (
|
||||
ChatAgent,
|
||||
ChatMessage,
|
||||
Agent,
|
||||
ChatResponse,
|
||||
ChatResponseUpdate,
|
||||
Content,
|
||||
Context,
|
||||
ContextProvider,
|
||||
Message,
|
||||
ResponseStream,
|
||||
WorkflowEvent,
|
||||
resolve_agent_id,
|
||||
@@ -50,7 +50,7 @@ class MockChatClient(ChatMiddlewareLayer[Any], FunctionInvocationLayer[Any], Bas
|
||||
def _inner_get_response(
|
||||
self,
|
||||
*,
|
||||
messages: Sequence[ChatMessage],
|
||||
messages: Sequence[Message],
|
||||
stream: bool,
|
||||
options: Mapping[str, Any],
|
||||
**kwargs: Any,
|
||||
@@ -60,7 +60,7 @@ class MockChatClient(ChatMiddlewareLayer[Any], FunctionInvocationLayer[Any], Bas
|
||||
|
||||
async def _get() -> ChatResponse:
|
||||
contents = _build_reply_contents(self._name, self._handoff_to, self._next_call_id())
|
||||
reply = ChatMessage(
|
||||
reply = Message(
|
||||
role="assistant",
|
||||
contents=contents,
|
||||
)
|
||||
@@ -105,7 +105,7 @@ def _build_reply_contents(
|
||||
return contents
|
||||
|
||||
|
||||
class MockHandoffAgent(ChatAgent):
|
||||
class MockHandoffAgent(Agent):
|
||||
"""Mock agent that can hand off to another agent."""
|
||||
|
||||
def __init__(
|
||||
@@ -121,7 +121,7 @@ class MockHandoffAgent(ChatAgent):
|
||||
handoff_to: The name of the agent to hand off to, or None for no handoff.
|
||||
This is hardcoded for testing purposes so that the agent always attempts to hand off.
|
||||
"""
|
||||
super().__init__(chat_client=MockChatClient(name=name, handoff_to=handoff_to), name=name, id=name)
|
||||
super().__init__(client=MockChatClient(name=name, handoff_to=handoff_to), name=name, id=name)
|
||||
|
||||
|
||||
async def _drain(stream: AsyncIterable[WorkflowEvent]) -> list[WorkflowEvent]:
|
||||
@@ -196,7 +196,7 @@ async def test_autonomous_mode_yields_output_without_user_request():
|
||||
|
||||
final_conversation = outputs[-1].data
|
||||
assert isinstance(final_conversation, list)
|
||||
conversation_list = cast(list[ChatMessage], final_conversation)
|
||||
conversation_list = cast(list[Message], final_conversation)
|
||||
assert any(msg.role == "assistant" and (msg.text or "").startswith("specialist reply") for msg in conversation_list)
|
||||
|
||||
|
||||
@@ -237,7 +237,7 @@ async def test_handoff_async_termination_condition() -> None:
|
||||
"""Test that async termination conditions work correctly."""
|
||||
termination_call_count = 0
|
||||
|
||||
async def async_termination(conv: list[ChatMessage]) -> bool:
|
||||
async def async_termination(conv: list[Message]) -> bool:
|
||||
nonlocal termination_call_count
|
||||
termination_call_count += 1
|
||||
user_count = sum(1 for msg in conv if msg.role == "user")
|
||||
@@ -258,7 +258,7 @@ async def test_handoff_async_termination_condition() -> None:
|
||||
|
||||
events = await _drain(
|
||||
workflow.run(
|
||||
stream=True, responses={requests[-1].request_id: [ChatMessage(role="user", text="Second user message")]}
|
||||
stream=True, responses={requests[-1].request_id: [Message(role="user", text="Second user message")]}
|
||||
)
|
||||
)
|
||||
outputs = [ev for ev in events if ev.type == "output"]
|
||||
@@ -266,7 +266,7 @@ async def test_handoff_async_termination_condition() -> None:
|
||||
|
||||
final_conversation = outputs[0].data
|
||||
assert isinstance(final_conversation, list)
|
||||
final_conv_list = cast(list[ChatMessage], final_conversation)
|
||||
final_conv_list = cast(list[Message], final_conversation)
|
||||
user_messages = [msg for msg in final_conv_list if msg.role == "user"]
|
||||
assert len(user_messages) == 2
|
||||
assert termination_call_count > 0
|
||||
@@ -281,7 +281,7 @@ async def test_tool_choice_preserved_from_agent_config():
|
||||
if options:
|
||||
recorded_tool_choices.append(options.get("tool_choice"))
|
||||
return ChatResponse(
|
||||
messages=[ChatMessage(role="assistant", text="Response")],
|
||||
messages=[Message(role="assistant", text="Response")],
|
||||
response_id="test_response",
|
||||
)
|
||||
|
||||
@@ -289,8 +289,8 @@ async def test_tool_choice_preserved_from_agent_config():
|
||||
mock_client.get_response = AsyncMock(side_effect=mock_get_response)
|
||||
|
||||
# Create agent with specific tool_choice configuration via default_options
|
||||
agent = ChatAgent(
|
||||
chat_client=mock_client,
|
||||
agent = Agent(
|
||||
client=mock_client,
|
||||
name="test_agent",
|
||||
default_options={"tool_choice": {"mode": "required"}}, # type: ignore
|
||||
)
|
||||
@@ -313,7 +313,7 @@ async def test_context_provider_preserved_during_handoff():
|
||||
class TestContextProvider(ContextProvider):
|
||||
"""A test context provider that tracks its invocations."""
|
||||
|
||||
async def invoking(self, messages: Sequence[ChatMessage], **kwargs: Any) -> Context:
|
||||
async def invoking(self, messages: Sequence[Message], **kwargs: Any) -> Context:
|
||||
provider_calls.append("invoking")
|
||||
return Context(instructions="Test context from provider.")
|
||||
|
||||
@@ -324,8 +324,8 @@ async def test_context_provider_preserved_during_handoff():
|
||||
mock_client = MockChatClient(name="test_agent")
|
||||
|
||||
# Create agent with context provider using proper constructor
|
||||
agent = ChatAgent(
|
||||
chat_client=mock_client,
|
||||
agent = Agent(
|
||||
client=mock_client,
|
||||
name="test_agent",
|
||||
id="test_agent",
|
||||
context_provider=context_provider,
|
||||
|
||||
Reference in New Issue
Block a user