fix(agent): steer on non-string tool content only as anthropic blocks, coerce for chat-completions (#78598) - #78706
Open
webtecnica wants to merge 1 commit into
Open
fix(agent): steer on non-string tool content only as anthropic blocks, coerce for chat-completions (#78598)#78706webtecnica wants to merge 1 commit into
webtecnica wants to merge 1 commit into
Conversation
…, coerce for chat-completions (NousResearch#78598)
This was referenced Aug 5, 2026
Open
Open
Open
Open
Open
Open
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes
/steeron tool results with non-string content (e.g. multimodal block lists).apply_pending_steer_to_tool_results()inagent/agent_runtime_helpers.pyunconditionally converted non-string tool content into an Anthropic Messages API block list. For chat-completions providers (OpenRouter, Xiaomi, DeepSeek, DeepInfra — routed via/chat/completions),ChatCompletionToolMessage.contentmust be a plain string; the block list is rejected with HTTP 400 and the poisoned message stays in the history, causing a 400 loop on every subsequent call including fallbacks.Root Cause
The block-list shape is only valid for the Anthropic Messages API wire format. The function never consulted the active wire format (
agent.api_mode) before choosing the content shape.Change
agent/agent_runtime_helpers.py:apply_pending_steer_to_tool_results()now only builds the block-list shape whenagent.api_mode == "anthropic_messages"(previous behavior preserved for Anthropic)._coerce_tool_content_to_string()(JSON serialization withstr()fallback, matching the pattern already used elsewhere in the codebase).tests/run_agent/test_steer.py:test_multimodal_content_list_preservednow pinsapi_mode="anthropic_messages"(block-list behavior is Anthropic-only).test_chat_completions_coerces_non_string_content_to_plain_string— chat-completions mode + block-list content produces a plain string with the marker appended after the serialized content.test_string_content_shape_unchanged_in_anthropic_mode— string content stays a string with the marker in both wire formats.Verification
python3 -m pytest tests/run_agent/test_steer.py -q— 29 passed.python3 -m pytest tests/ -k "steer or tool_result" -q— 154 passed, 3 skipped, 0 failures.Closes
Closes #78598