Skip to content

fix: include closing brace in tool call arguments substring extraction - #531

Open
AshtonVaughan wants to merge 1 commit into
ROCm:mainfrom
AshtonVaughan:fix/tool-args-substr-off-by-one
Open

fix: include closing brace in tool call arguments substring extraction#531
AshtonVaughan wants to merge 1 commit into
ROCm:mainfrom
AshtonVaughan:fix/tool-args-substr-off-by-one

Conversation

@AshtonVaughan

Copy link
Copy Markdown

Bug

std::string::substr(pos, count) takes length as the second argument, not end position. The current extraction in 7 places drops the closing brace:

size_t brace_start = json_str.find("{", args_pos);
size_t brace_end = json_str.rfind("}");
if (brace_start != std::string::npos && brace_end != std::string::npos && brace_end > brace_start) {
    arguments = json_str.substr(brace_start, brace_end - brace_start);
}

For input "arguments": {"limit": 6} where brace_start=13 and brace_end=23, this returns 10 characters starting at index 13, which gives {"limit": 6 instead of {"limit": 6}. The closing brace at position 23 is excluded.

Fix

Add + 1 to the length argument so the closing brace is included.

Affected files

7 occurrences across 5 model parsers:

  • src/common/AutoModel/modeling_qwen2.cpp:136
  • src/common/AutoModel/modeling_qwen3.cpp:151
  • src/common/AutoModel/modeling_qwen3.cpp:296
  • src/common/AutoModel/modeling_qwen3.cpp:500
  • src/common/AutoModel/modeling_qwen3vl.cpp:248
  • src/common/AutoModel/modeling_qwen3_5vl.cpp:258
  • src/common/AutoModel/modeling_nanbeige.cpp:298

Verification

C++ standard says substr(pos, count) returns a substring of length up to count starting at position pos. Last character is at pos + count - 1, so the original code excludes the character at brace_end. After the fix, last character is at brace_end, which is the closing brace.

The streaming parsers (parse_stream_content) use nlohmann::json::parse and were not affected by this bug. Only the non-streaming substring path was missing the closing brace.

Possible related issue

This may explain part of #483 (tool call arguments serialization). When the closing brace is missing, downstream JSON parsers either fail or attempt error recovery, which could plausibly produce the int-as-string behaviour reported there. Recommend testing against #483's reproduction after this fix lands.

std::string::substr(pos, count) takes length as second arg, not end
position. The existing extraction:

    arguments = json_str.substr(brace_start, brace_end - brace_start);

returns the substring [brace_start, brace_end), excluding the closing
brace at position brace_end. The resulting JSON is malformed:

    {"limit": 6

instead of:

    {"limit": 6}

Adding +1 to the length includes the closing brace.

Affects 7 sites across 5 model parsers: qwen2, qwen3, qwen3vl,
qwen3_5vl, nanbeige.

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 aims to fix non-stream tool-call argument extraction by adjusting std::string::substr(pos, count) length calculations so the closing brace is included.

Changes:

  • Update 7 tool-call argument substring extractions to use brace_end - brace_start + 1.
  • Apply the same fix across Qwen2, Qwen3 (and variants), Qwen3VL, Qwen3.5VL, and Nanbeige non-stream parsers.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
src/common/AutoModel/modeling_qwen3vl.cpp Adjusts non-stream tool-call arguments substring length.
src/common/AutoModel/modeling_qwen3_5vl.cpp Adjusts non-stream tool-call arguments substring length.
src/common/AutoModel/modeling_qwen3.cpp Adjusts non-stream tool-call arguments substring length in 3 parsers.
src/common/AutoModel/modeling_qwen2.cpp Adjusts non-stream tool-call arguments substring length.
src/common/AutoModel/modeling_nanbeige.cpp Adjusts non-stream tool-call arguments substring length.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/common/AutoModel/modeling_qwen3.cpp
Comment thread src/common/AutoModel/modeling_qwen3.cpp
Comment thread src/common/AutoModel/modeling_qwen2.cpp
Comment thread src/common/AutoModel/modeling_nanbeige.cpp
Comment thread src/common/AutoModel/modeling_qwen3vl.cpp
Comment thread src/common/AutoModel/modeling_qwen3_5vl.cpp
Comment thread src/common/AutoModel/modeling_qwen3.cpp
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.

2 participants