Skip to content

Fix: drop trailing assistant message when rstrip leaves it empty - #8029

Closed
Mayuri (mayuriphad) wants to merge 2 commits into
microsoft:mainfrom
mayuriphad:fix/issue-7768-rstrip-empty-assistant-message
Closed

Mayuri (mayuriphad) wants to merge 2 commits into
microsoft:mainfrom
mayuriphad:fix/issue-7768-rstrip-empty-assistant-message

Conversation

@mayuriphad

Copy link
Copy Markdown

Fixes #7768

Root cause

_rstrip_last_assistant_message() is documented as removing the last assistant message when it is empty, but it only called .rstrip() on the content and left the (now possibly empty) message in the list. When the trailing AssistantMessage.content was whitespace-only, this produced an empty-string content block, which the Anthropic API rejects (text content blocks must be non-empty).

Fix

After stripping, if the content becomes an empty string, drop the message entirely — matching the function's documented behavior. Non-empty trailing assistant messages are still only whitespace-stripped, preserving the existing "prefill" behavior and pre-existing passing tests. Same fix applied to both the Anthropic and OpenAI clients, which share an identical copy of this helper.

Verification

Added regression tests in both test_anthropic_model_client.py and test_openai_model_client.py. Ran the full local suite: all pre-existing and new tests pass (unrelated failures due to missing OPENAI_API_KEY in this environment, confirmed unrelated via traceback inspection).

_rstrip_last_assistant_message() is documented as removing the last
assistant message when it is empty, but it only called .rstrip() on
the content and left the (now possibly empty) message in place. When
the last AssistantMessage content was whitespace-only, this produced
an empty-string content block, which the Anthropic API rejects (text
content blocks must be non-empty).

Now, after stripping, if the content becomes an empty string the
message is dropped from the returned list, matching the function's
documented behavior. Non-empty trailing assistant messages are still
only whitespace-stripped, preserving existing prefill behavior and
the pre-existing passing tests.

Same fix applied to both the Anthropic and OpenAI clients, which
share an identical copy of this helper.

Fixes #7768
Copilot AI lite review requested due to automatic review settings August 7, 2026 09:08

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a bug in autogen-ext where _rstrip_last_assistant_message() could leave a trailing AssistantMessage in the history with content == "" after .rstrip(). That empty assistant content can be rejected by Claude/Anthropic message validation, so the helper now removes the assistant message entirely when stripping results in an empty string.

Changes:

  • Update _rstrip_last_assistant_message() in both the Anthropic and OpenAI clients to (a) handle empty messages safely and (b) drop the trailing assistant message if rstrip() produces "".
  • Add regression tests covering whitespace-only trailing assistant messages for both clients.

Reviewed changes

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

File Description
python/packages/autogen-ext/src/autogen_ext/models/openai/_openai_client.py Drops trailing assistant message when rstrip() leaves empty content (and avoids messages[-1] on empty input).
python/packages/autogen-ext/src/autogen_ext/models/anthropic/_anthropic_client.py Same helper fix applied to Anthropic client implementation.
python/packages/autogen-ext/tests/models/test_openai_model_client.py Adds regression test ensuring whitespace-only trailing assistant message is removed.
python/packages/autogen-ext/tests/models/test_anthropic_model_client.py Adds regression test ensuring whitespace-only trailing assistant message is removed.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Correct — dropping a last assistant message that becomes empty after rstrip avoids the API rejection of empty text blocks, and guarding on a non-empty list fixes the prior index error. Two small notes: mutating messages then removing it changes the list identity returned, which is fine, but the same logic is now duplicated across the Anthropic and OpenAI clients — worth extracting the shared helper so the behavior cannot diverge; and confirm stripping affects only the trailing message, never an interleaved one.

@mayuriphad

Copy link
Copy Markdown
Author

@microsoft-github-policy-service agree

Addresses review feedback on #8029: the empty-trailing-assistant-message
handling was duplicated identically across the Anthropic and OpenAI
clients, risking divergence over time (the same codebase already has one
such duplicated helper, normalize_stop_reason, that diverged when only
one client was updated to import the shared version).

Moved the logic to autogen_ext.models._utils.rstrip_last_assistant_message
as a plain function, matching the existing _utils pattern used by
normalize_stop_reason and parse_r1_content, and updated both clients and
their tests to use it.

Also added a regression test confirming the strip only affects the
trailing message, not interleaved assistant messages earlier in the
sequence.
@mayuriphad

Copy link
Copy Markdown
Author

Addressed: extracted the shared rstrip_last_assistant_message helper (see autogen_ext/models/_utils/rstrip_last_assistant_message.py) and updated both the OpenAI and Anthropic clients to use it, so the logic can no longer diverge between the two. The docstring also spells out that only the trailing message is stripped/dropped — earlier assistant messages in the history are left untouched even if they are also AssistantMessages, including interleaved ones.

@mayuriphad

Copy link
Copy Markdown
Author

I have recreated this PR here: #8250

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

_rstrip_last_assistant_message only strips trailing whitespace from the content — it does not remove the assistant message.

4 participants