fix(anthropic): strip trailing whitespace from final assistant message (#35072)

This commit is contained in:
Mohan Kumar S
2026-02-08 21:38:59 +05:30
committed by GitHub
parent a027f46403
commit 4276d31cb5
2 changed files with 31 additions and 0 deletions

View File

@@ -643,6 +643,17 @@ def _format_messages(
_lc_tool_calls_to_anthropic_tool_use_blocks(missing_tool_calls),
)
if role == "assistant" and _i == len(merged_messages) - 1:
if isinstance(content, str):
content = content.rstrip()
elif (
isinstance(content, list)
and content
and isinstance(content[-1], dict)
and content[-1].get("type") == "text"
):
content[-1]["text"] = content[-1]["text"].rstrip()
if not content and role == "assistant" and _i < len(merged_messages) - 1:
# anthropic.BadRequestError: Error code: 400: all messages must have
# non-empty content except for the optional final assistant message

View File

@@ -2319,3 +2319,23 @@ def test_extras_with_multiple_fields() -> None:
assert tool_def.get("defer_loading") is True
assert tool_def.get("cache_control") == {"type": "ephemeral"}
assert "input_examples" in tool_def
def test__format_messages_trailing_whitespace() -> None:
"""Test that trailing whitespace is trimmed from the final assistant message."""
human = HumanMessage("foo") # type: ignore[misc]
# Test string content
ai_string = AIMessage("thought ") # type: ignore[misc]
_, anthropic_messages = _format_messages([human, ai_string])
assert anthropic_messages[-1]["content"] == "thought"
# Test list content
ai_list = AIMessage([{"type": "text", "text": "thought "}]) # type: ignore[misc]
_, anthropic_messages = _format_messages([human, ai_list])
assert anthropic_messages[-1]["content"][0]["text"] == "thought" # type: ignore[index]
# Test that intermediate messages are NOT trimmed
ai_intermediate = AIMessage("thought ") # type: ignore[misc]
_, anthropic_messages = _format_messages([human, ai_intermediate, human])
assert anthropic_messages[1]["content"] == "thought "