Python: [BREAKING] Fix #3613 chat/agent message typing alignment#3920
Python: [BREAKING] Fix #3613 chat/agent message typing alignment#3920eavanvalkenburg wants to merge 10 commits intomicrosoft:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR aligns Python chat-client and agent message-input typing to resolve #3613: chat clients now accept Sequence[Message] only (removing chat-side normalization), while agents accept broader “run inputs” including Content (and nullable variants), with downstream implementations, tests, and samples updated accordingly.
Changes:
- Updated chat client contracts and middleware layers to take
messages: Sequence[Message]and removed implicit normalization. - Updated agent
run()contracts to acceptstr | Content | Message | Sequence[str | Content | Message] | None. - Updated downstream agent packages plus tests/samples to match the new typing.
Reviewed changes
Copilot reviewed 24 out of 24 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| python/packages/orchestrations/tests/test_magentic.py | Updates agent run() typing in orchestrations tests to include Content. |
| python/packages/orchestrations/tests/test_group_chat.py | Updates agent run() typing in group chat tests to include Content. |
| python/packages/github_copilot/agent_framework_github_copilot/_agent.py | Aligns GitHub Copilot agent run() overloads/impl typing with new agent message union. |
| python/packages/durabletask/agent_framework_durabletask/_shim.py | Updates DurableTask shim run() typing and switches to normalize_messages() for string conversion. |
| python/packages/core/tests/workflow/test_workflow_kwargs.py | Updates workflow test agents’ run() message typing to include Content. |
| python/packages/core/tests/workflow/test_workflow.py | Updates workflow test agent run() message typing to include Content. |
| python/packages/core/tests/workflow/test_full_conversation.py | Updates workflow test agent run() message typing to include Content. |
| python/packages/core/tests/workflow/test_agent_executor_tool_calls.py | Updates executor test agent run() message typing to include Content. |
| python/packages/core/tests/core/test_function_invocation_logic.py | Updates chat client calls to pass Sequence[Message] instead of str. |
| python/packages/core/tests/core/test_clients.py | Updates core client tests to pass Sequence[Message] consistently (streaming and non-streaming). |
| python/packages/core/tests/core/test_agents.py | Adds coverage for agent.run(Content.from_text(...)). |
| python/packages/core/agent_framework/observability.py | Aligns telemetry-layer chat contract to Sequence[Message] and agent contract to new union. |
| python/packages/core/agent_framework/_workflows/_message_utils.py | Extends workflow normalization helper to support Content inputs. |
| python/packages/core/agent_framework/_workflows/_agent.py | Updates workflow agent run() typing to support Content and mixed input sequences. |
| python/packages/core/agent_framework/_tools.py | Updates function-invocation layer to accept Sequence[Message] and removes message prepping. |
| python/packages/core/agent_framework/_middleware.py | Updates middleware-layer chat contract to Sequence[Message] and adjusts context creation. |
| python/packages/core/agent_framework/_clients.py | Updates core chat client protocol/base signatures and examples to require Sequence[Message]. |
| python/packages/core/agent_framework/_agents.py | Updates agent contracts to accept Content and mixed sequences for run(). |
| python/packages/copilotstudio/agent_framework_copilotstudio/_agent.py | Aligns Copilot Studio agent run() typing with new agent message union. |
| python/packages/claude/agent_framework_claude/_agent.py | Aligns Claude agent run() typing with new agent message union. |
| python/packages/ag-ui/tests/ag_ui/conftest.py | Updates AG-UI test stubs’ typing to include Content. |
| python/packages/ag-ui/getting_started/client_advanced.py | Updates sample usage to pass Sequence[Message] into get_response(). |
| python/packages/ag-ui/getting_started/client.py | Updates sample usage to pass Sequence[Message] into get_response(). |
| python/packages/a2a/agent_framework_a2a/_agent.py | Aligns A2A agent run() typing with new agent message union. |
Comments suppressed due to low confidence (1)
python/packages/ag-ui/tests/ag_ui/conftest.py:103
StreamingChatClientStub.get_responseis typed to acceptstr | Content | Message | Sequence[str | Content | Message], but it forwardsmessagesdirectly toBaseChatClient.get_response, which now requiresSequence[Message]and no longer normalizes inputs. This makes the stub’s signature misleading and will raise at runtime if tests (or future callers) pass astr/Content/MessageorSequence[str|Content]. Either narrow the stub’smessagesparameter toSequence[Message](matching the new contract) or normalize toSequence[Message]before callingsuper().get_response.
def get_response(
self,
messages: str | Content | Message | Sequence[str | Content | Message],
*,
stream: bool = False,
options: OptionsCoT | ChatOptions[Any] | None = None,
**kwargs: Any,
) -> Awaitable[ChatResponse[Any]] | ResponseStream[ChatResponseUpdate, ChatResponse[Any]]:
self.last_session = kwargs.get("session")
self.last_service_session_id = self.last_session.service_session_id if self.last_session else None
return cast(
Awaitable[ChatResponse[Any]] | ResponseStream[ChatResponseUpdate, ChatResponse[Any]],
super().get_response(
messages=messages,
stream=cast(Literal[True, False], stream),
options=options,
**kwargs,
),
)
python/packages/durabletask/agent_framework_durabletask/_shim.py
Outdated
Show resolved
Hide resolved
42aa185 to
8ba0f2f
Compare
14469dc to
838571a
Compare
| from agent_framework._logging import get_logger | ||
|
|
||
| logger = get_logger() | ||
| logger = logging.getLogger("agent_framework.ag_ui") |
There was a problem hiding this comment.
Why do we need to create the logger again?
|
|
||
| stream = client.get_response( | ||
| "Tell me a short joke", | ||
| [Message(role="user", text="Tell me a short joke")], |
There was a problem hiding this comment.
Any reason we remove the support for string? Seems like a very convenient way for people to get started.
There was a problem hiding this comment.
Were keeping it at the agent level, but since most people will use that it simplifies and speeds up being able to assume we have messages at the chat client level
python/packages/core/agent_framework/_workflows/_checkpoint_encoding.py
Outdated
Show resolved
Hide resolved
| AgentRunInputs = str | Content | Message | Sequence[str | Content | Message] | ||
| AgentRunInputsOrNone = AgentRunInputs | None |
There was a problem hiding this comment.
This really isn't saving much. I wonder if we should just make people do AgentRunInputs | None to make thing more obvious
Co-authored-by: Tao Chen <taochen@microsoft.com>
Summary
get_responsecontracts to accept onlySequence[Message]runruninputs tostr | Content | Message | Sequence[str | Content | Message] | NoneCloses #3613