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:
committed by
GitHub
Unverified
parent
a4c9e43afb
commit
0521f5bed8
@@ -18,7 +18,6 @@ from a2a.types import (
|
||||
FilePart,
|
||||
FileWithBytes,
|
||||
FileWithUri,
|
||||
Message,
|
||||
Task,
|
||||
TaskIdParams,
|
||||
TaskQueryParams,
|
||||
@@ -34,9 +33,9 @@ from agent_framework import (
|
||||
AgentResponseUpdate,
|
||||
AgentThread,
|
||||
BaseAgent,
|
||||
ChatMessage,
|
||||
Content,
|
||||
ContinuationToken,
|
||||
Message,
|
||||
ResponseStream,
|
||||
normalize_messages,
|
||||
prepend_agent_framework_to_user_agent,
|
||||
@@ -83,7 +82,7 @@ class A2AAgent(AgentTelemetryLayer, BaseAgent):
|
||||
"""Agent2Agent (A2A) protocol implementation.
|
||||
|
||||
Wraps an A2A Client to connect the Agent Framework with external A2A-compliant agents
|
||||
via HTTP/JSON-RPC. Converts framework ChatMessages to A2A Messages on send, and converts
|
||||
via HTTP/JSON-RPC. Converts framework Messages to A2A Messages on send, and converts
|
||||
A2A responses (Messages/Tasks) back to framework types. Inherits BaseAgent capabilities
|
||||
while managing the underlying A2A protocol communication.
|
||||
|
||||
@@ -209,7 +208,7 @@ class A2AAgent(AgentTelemetryLayer, BaseAgent):
|
||||
@overload
|
||||
def run(
|
||||
self,
|
||||
messages: str | ChatMessage | Sequence[str | ChatMessage] | None = None,
|
||||
messages: str | Message | Sequence[str | Message] | None = None,
|
||||
*,
|
||||
stream: Literal[False] = ...,
|
||||
thread: AgentThread | None = None,
|
||||
@@ -221,7 +220,7 @@ class A2AAgent(AgentTelemetryLayer, BaseAgent):
|
||||
@overload
|
||||
def run(
|
||||
self,
|
||||
messages: str | ChatMessage | Sequence[str | ChatMessage] | None = None,
|
||||
messages: str | Message | Sequence[str | Message] | None = None,
|
||||
*,
|
||||
stream: Literal[True],
|
||||
thread: AgentThread | None = None,
|
||||
@@ -232,7 +231,7 @@ class A2AAgent(AgentTelemetryLayer, BaseAgent):
|
||||
|
||||
def run(
|
||||
self,
|
||||
messages: str | ChatMessage | Sequence[str | ChatMessage] | None = None,
|
||||
messages: str | Message | Sequence[str | Message] | None = None,
|
||||
*,
|
||||
stream: bool = False,
|
||||
thread: AgentThread | None = None,
|
||||
@@ -268,7 +267,7 @@ class A2AAgent(AgentTelemetryLayer, BaseAgent):
|
||||
|
||||
response = ResponseStream(
|
||||
self._map_a2a_stream(a2a_stream, background=background),
|
||||
finalizer=lambda updates: AgentResponse.from_updates(list(updates)),
|
||||
finalizer=AgentResponse.from_updates,
|
||||
)
|
||||
if stream:
|
||||
return response
|
||||
@@ -291,7 +290,8 @@ class A2AAgent(AgentTelemetryLayer, BaseAgent):
|
||||
When True, they are yielded with a continuation token.
|
||||
"""
|
||||
async for item in a2a_stream:
|
||||
if isinstance(item, Message):
|
||||
if isinstance(item, A2AMessage):
|
||||
# Process A2A Message
|
||||
contents = self._parse_contents_from_a2a(item.parts)
|
||||
yield AgentResponseUpdate(
|
||||
contents=contents,
|
||||
@@ -377,10 +377,10 @@ class A2AAgent(AgentTelemetryLayer, BaseAgent):
|
||||
return AgentResponse.from_updates(updates)
|
||||
return AgentResponse(messages=[], response_id=task.id, raw_representation=task)
|
||||
|
||||
def _prepare_message_for_a2a(self, message: ChatMessage) -> A2AMessage:
|
||||
"""Prepare a ChatMessage for the A2A protocol.
|
||||
def _prepare_message_for_a2a(self, message: Message) -> A2AMessage:
|
||||
"""Prepare a Message for the A2A protocol.
|
||||
|
||||
Transforms Agent Framework ChatMessage objects into A2A protocol Messages by:
|
||||
Transforms Agent Framework Message objects into A2A protocol Messages by:
|
||||
- Converting all message contents to appropriate A2A Part types
|
||||
- Mapping text content to TextPart objects
|
||||
- Converting file references (URI/data/hosted_file) to FilePart objects
|
||||
@@ -389,7 +389,7 @@ class A2AAgent(AgentTelemetryLayer, BaseAgent):
|
||||
"""
|
||||
parts: list[A2APart] = []
|
||||
if not message.contents:
|
||||
raise ValueError("ChatMessage.contents is empty; cannot convert to A2AMessage.")
|
||||
raise ValueError("Message.contents is empty; cannot convert to A2AMessage.")
|
||||
|
||||
# Process ALL contents
|
||||
for content in message.contents:
|
||||
@@ -511,9 +511,9 @@ class A2AAgent(AgentTelemetryLayer, BaseAgent):
|
||||
raise ValueError(f"Unknown Part kind: {inner_part.kind}")
|
||||
return contents
|
||||
|
||||
def _parse_messages_from_task(self, task: Task) -> list[ChatMessage]:
|
||||
"""Parse A2A Task artifacts into ChatMessages with ASSISTANT role."""
|
||||
messages: list[ChatMessage] = []
|
||||
def _parse_messages_from_task(self, task: Task) -> list[Message]:
|
||||
"""Parse A2A Task artifacts into Messages with ASSISTANT role."""
|
||||
messages: list[Message] = []
|
||||
|
||||
if task.artifacts is not None:
|
||||
for artifact in task.artifacts:
|
||||
@@ -523,7 +523,7 @@ class A2AAgent(AgentTelemetryLayer, BaseAgent):
|
||||
history_item = task.history[-1]
|
||||
contents = self._parse_contents_from_a2a(history_item.parts)
|
||||
messages.append(
|
||||
ChatMessage(
|
||||
Message(
|
||||
role="assistant" if history_item.role == A2ARole.agent else "user",
|
||||
contents=contents,
|
||||
raw_representation=history_item,
|
||||
@@ -532,10 +532,10 @@ class A2AAgent(AgentTelemetryLayer, BaseAgent):
|
||||
|
||||
return messages
|
||||
|
||||
def _parse_message_from_artifact(self, artifact: Artifact) -> ChatMessage:
|
||||
"""Parse A2A Artifact into ChatMessage using part contents."""
|
||||
def _parse_message_from_artifact(self, artifact: Artifact) -> Message:
|
||||
"""Parse A2A Artifact into Message using part contents."""
|
||||
contents = self._parse_contents_from_a2a(artifact.parts)
|
||||
return ChatMessage(
|
||||
return Message(
|
||||
role="assistant",
|
||||
contents=contents,
|
||||
raw_representation=artifact,
|
||||
|
||||
Reference in New Issue
Block a user