Skip to content

Commit b03ebc2

Browse files
authored
Fix "Invalid tool call arguments passed" in a rare case.
In a rare case, the model may emit a raw string that begins with a valid JSON string. This commit adds unit tests to cover that scenario and fixes the regression introduced during the Kimi-K2 adaptation.
1 parent 1608420 commit b03ebc2

File tree

2 files changed

+26
-5
lines changed

2 files changed

+26
-5
lines changed

common/chat-parser-xml-toolcall.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -545,15 +545,12 @@ inline bool parse_xml_tool_calls(common_chat_msg_parser & builder, const struct
545545
}
546546
builder.move_to(json_end);
547547
auto [val_end_size, tc] = try_find_val_end();
548-
if (tc && value_json->healing_marker.marker.empty()) {
548+
if (tc && all_space(tc->prelude) && value_json->healing_marker.marker.empty()) {
549549
if (tc->groups[0].end - tc->groups[0].begin != val_end_size) {
550550
gen_partial_args([&](auto &, auto &needle) {arguments[key] = needle;});
551551
LOG_DBG("Possible terminated JSON arg_value: %s\n", value_json->json.dump().c_str());
552552
throw common_chat_msg_partial_exception("Partial literal: " + gbnf_format_literal(form.val_end) + (form.last_val_end ? gbnf_format_literal(*form.last_val_end) : ""));
553-
}
554-
if (all_space(tc->prelude)) {
555-
arguments[key] = value_json->json;
556-
}
553+
} else arguments[key] = value_json->json;
557554
} else builder.move_to(val_start);
558555
}
559556

tests/test-chat.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2562,6 +2562,30 @@ Hey there!<|im_end|>
25622562
/* .format = */ COMMON_CHAT_FORMAT_GLM_4_5,
25632563
/* .reasoning_format = */ COMMON_REASONING_FORMAT_DEEPSEEK
25642564
}); });
2565+
test_parser_with_streaming(
2566+
simple_assist_msg("", "", "complex_function", "{\"name\":\"John Doe\",\"age\":30,\"active\":true,\"score\":95.5}"),
2567+
"<tool_call>complex_function\n"
2568+
"<arg_key>name</arg_key>\n"
2569+
"<arg_value>John Doe</arg_value>\n"
2570+
"<arg_key>age</arg_key>\n"
2571+
"<arg_value>30</arg_value>\n"
2572+
"<arg_key>active</arg_key>\n"
2573+
"<arg_value>true</arg_value>\n"
2574+
"<arg_key>score</arg_key>\n"
2575+
"<arg_value>95.5</arg_value>\n"
2576+
"</tool_call>",
2577+
[&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_GLM_4_5}); });
2578+
test_parser_with_streaming(
2579+
simple_assist_msg("", "", "web_search", "{\"query\":\"\\\"From Zero\\\" Linkin Park album tracklist complete songs\",\"limit\":3,\"type\":\"text\"}"),
2580+
"<tool_call>web_search\n"
2581+
"<arg_key>query</arg_key>\n"
2582+
"<arg_value>\"From Zero\" Linkin Park album tracklist complete songs</arg_value>\n"
2583+
"<arg_key>limit</arg_key>\n"
2584+
"<arg_value>3</arg_value>\n"
2585+
"<arg_key>type</arg_key>\n"
2586+
"<arg_value>text</arg_value>\n"
2587+
"</tool_call>",
2588+
[&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_GLM_4_5}); });
25652589

25662590
// Test interleaved thinking
25672591
test_parser_with_streaming(simple_assist_msg("Hello, world!\n\nWhat's up?", "I'm\nthinkingThinking2", "special_function", "{\"arg1\": 1}"),

0 commit comments

Comments
 (0)