fix: parse <tool_call> XML from text content in main agent loop#3518
Open
janovaworkstation wants to merge 1 commit into
Open
fix: parse <tool_call> XML from text content in main agent loop#3518janovaworkstation wants to merge 1 commit into
janovaworkstation wants to merge 1 commit into
Conversation
Models served via providers that don't translate tool calls into structured OpenAI tool_calls (e.g. Nous Portal with Hermes-4-405B) return tool calls as <tool_call> XML tags in the text content. The RL training path (environments/agent_loop.py) already had a fallback parser for this, but the main agent loop in run_agent.py did not — causing tool calls to be silently treated as final text responses and never executed. Add the same fallback in two places: 1. Streaming path: after chunks are accumulated, parse <tool_call> tags from content when no structured tool_calls were streamed. 2. Main loop: before the tool_calls check, parse <tool_call> tags from content when assistant_message.tool_calls is empty. Both reuse the existing HermesToolCallParser from environments/tool_call_parsers/hermes_parser.py. Closes NousResearch#2936 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
4 tasks
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
<tool_call>XML parsing to the main agent loop inrun_agent.pytool_callsHermesToolCallParserfromenvironments/tool_call_parsers/hermes_parser.py— zero new dependencies, 46 lines addedProblem
Models served via providers that don't translate tool calls into structured OpenAI
tool_calls(e.g.inference-api.nousresearch.comwith Hermes-4-405B) emit<tool_call>XML tags in the text content. The main agent loop only checksassistant_message.tool_calls, finds it empty, treats the response as a final text answer, and returns to the prompt — tools are never executed.The RL training path (
environments/agent_loop.py:260-281) already had a fallback parser for this exact case, but the main agent loop did not.Fix
Add the same fallback in two places:
Streaming path (~line 3898): After streaming chunks are accumulated into a mock response, if no structured
tool_callswere received but the content contains<tool_call>tags, parse them withHermesToolCallParser.Main agent loop (~line 7157): Before the
if assistant_message.tool_calls:check, parse<tool_call>XML from text content whentool_callsis empty.Both paths reuse the battle-tested
HermesToolCallParseralready in the codebase — no new files or abstractions needed.Related
response_adapters.pymodule. This PR is a lighter approach that reuses existing infrastructure.Test plan
HermesToolCallParsercorrectly extracts tool calls from<tool_call>XMLtests/test_tool_call_parsers.py— 27 passed)🤖 Generated with Claude Code