Skip to content

fix(anthropic): end requests on a user turn (Fixes #7861) - #7862

Open
ninglinLiu wants to merge 14 commits into
google:mainfrom
ninglinLiu:fix/7861-anthropic-trailing-assistant
Open

ninglinLiu wants to merge 14 commits into
google:mainfrom
ninglinLiu:fix/7861-anthropic-trailing-assistant

Conversation

@ninglinLiu

Copy link
Copy Markdown
Contributor

Related issue

Fixes #7861

Summary

AnthropicLlm.generate_content_async converted llm_request.contents without ensuring the Anthropic messages end on a user turn. A LoopAgent (or any re-run on the agent's last reply) can therefore send [user, assistant]. Claude treats a final assistant message as a prefill: Claude 4.6+ returns 400, and older models continue the previous reply instead of answering again.

Gemini / LiteLlm / Apigee already call BaseLlm._maybe_append_user_content. This change appends the same synthetic user text after empty-message filtering and after cache breakpoints, so a dropped turn cannot leave two user turns in a row and the synthetic turn is not part of the cached session prefix.

Verification

  • pytest tests/unittests/models/test_anthropic_llm.py -k 'appends_user_when_history_ends_on_assistant or keeps_single_user_when_already_trailing' -q passes

AI assistance

Assisted by an AI coding agent; the fix and tests were reviewed and verified locally before opening this PR.

Claude treats a trailing assistant message as a prefill. Claude 4.6+
rejects that; older models continue the previous reply. Append the same
synthetic user turn BaseLlm._maybe_append_user_content uses, after the
empty-message filter and after cache breakpoints so the synthetic turn
is not part of the cached session prefix.

Fixes google#7861
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.

AnthropicLlm sends a trailing assistant turn, which Claude 4.6+ rejects

2 participants