Skip to content

Python: re-role trailing assistant message to user for Anthropic compatibility (fixes #5008)#6207

Open
hanhan761 wants to merge 2 commits into
microsoft:mainfrom
hanhan761:fix-5008-anthropic-assistant-prefill
Open

Python: re-role trailing assistant message to user for Anthropic compatibility (fixes #5008)#6207
hanhan761 wants to merge 2 commits into
microsoft:mainfrom
hanhan761:fix-5008-anthropic-assistant-prefill

Conversation

@hanhan761
Copy link
Copy Markdown

Summary

When two agents backed by Anthropic are connected via WorkflowBuilder, the first agent's output (assistant-role messages) is passed as context to the second agent. Anthropic's API rejects this with:

\
This model does not support assistant message prefill. The conversation must end with a user message.
\\

Changes

Modified _prepare_messages_for_anthropic\ in the Anthropic chat client:

  • After preparing all messages, check if the last message has role "assistant"
  • If so, re-role it as "user" so the conversation ends with a valid user message
  • Single-agent usage is unaffected (conversation already ends with user message in that flow)

Related

Fixes #5008

Copilot AI review requested due to automatic review settings May 30, 2026 07:39
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Updates tool invocation argument handling to preserve None values, adds regression coverage, and adjusts Anthropic message preparation to satisfy its “last message must be user” constraint.

Changes:

  • Preserve explicit None tool arguments by disabling exclude_none during Pydantic dumps.
  • Add a regression test for tool invocation with explicit None.
  • Ensure Anthropic message lists end with a user message by re-labeling a trailing assistant message.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.

File Description
python/packages/core/tests/core/test_tools.py Adds a regression test around invoke() handling of explicit None arguments.
python/packages/core/agent_framework/_tools.py Changes Pydantic serialization to keep None values when building invocation kwargs.
python/packages/anthropic/agent_framework_anthropic/_chat_client.py Adjusts message preparation to ensure the final message role is user for Anthropic.

Comment on lines 636 to 640
parsed_arguments = dict(arguments)
if self.input_model is not None and not self._schema_supplied:
parsed_arguments = self.input_model.model_validate(parsed_arguments).model_dump(
exclude_none=True
exclude_none=False
)
Comment on lines 645 to +648
and not isinstance(arguments, self.input_model)
):
raise TypeError(f"Expected {self.input_model.__name__}, got {type(arguments).__name__}")
parsed_arguments = arguments.model_dump(exclude_none=True)
parsed_arguments = arguments.model_dump(exclude_none=False)
Comment on lines +1466 to +1479
def test_invoke_preserves_explicit_none_arguments() -> None:
"""Optional parameters explicitly set to None must not be stripped before invocation."""

@tool
def greet(name: str, greeting: str | None = None) -> str:
return f"{greeting or 'Hello'}, {name}!"

result = asyncio.run(greet.invoke(arguments={"name": "World", "greeting": None}))
assert isinstance(result, list)
assert result[0].text == "Hello, World!"

result = asyncio.run(greet.invoke(arguments={"name": "World"}))
assert isinstance(result, list)
assert result[0].text == "Hello, World!"
Comment on lines +712 to +716
# Anthropic requires the conversation to end with a user message.
# Re-role a trailing assistant message as user so chained agent
# outputs work as valid context for the next agent.
if result and result[-1].get("role") == "assistant":
result[-1] = {**result[-1], "role": "user"}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Python: [Bug]: Workflow fails with Anthropic models — assistant message prefill not supported

3 participants