From c4805ecd3dde4bd9fca24b34b6ad30fcb4c37455 Mon Sep 17 00:00:00 2001 From: James O'Leary Date: Thu, 19 Mar 2026 08:19:27 -0700 Subject: [PATCH 1/2] chat : handle tool calls with no required args in TAG_WITH_TAGGED format --- common/chat-auto-parser-generator.cpp | 4 +++- tests/test-chat.cpp | 21 +++++++++++++++++++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/common/chat-auto-parser-generator.cpp b/common/chat-auto-parser-generator.cpp index f19819494c8..d508c73a90d 100644 --- a/common/chat-auto-parser-generator.cpp +++ b/common/chat-auto-parser-generator.cpp @@ -384,7 +384,9 @@ common_peg_parser analyze_tools::build_tool_parser_tag_tagged(parser_build_conte func_parser = p.atomic(p.tool_open(function.name_prefix + p.tool_name(p.literal(name)) + function.name_suffix) + call_id_section) + p.space() + args_seq; matched_atomic = true; - } else if (!arguments.name_prefix.empty() && properties.size() > 0) { + } else if (!arguments.name_prefix.empty() && !required_parsers.empty()) { + // Only peek for an arg tag when there are required args that must follow. + // When all args are optional, the model may emit no arg tags at all (#20650). func_parser = p.atomic(p.tool_open(function.name_prefix + p.tool_name(p.literal(name)) + function.name_suffix) + call_id_section + p.space() + p.peek(p.literal(arguments.name_prefix))) + args_seq; matched_atomic = true; diff --git a/tests/test-chat.cpp b/tests/test-chat.cpp index 915b6f71dc5..a39de1d1cbd 100644 --- a/tests/test-chat.cpp +++ b/tests/test-chat.cpp @@ -1912,9 +1912,26 @@ static void test_template_output_peg_parsers(bool detailed_debug) { }) .expect_tool_calls({ { "special_function", R"({"arg1": 1})", {} }, - { "special_function_with_opt", R"({"arg1": 1, "arg2": 2})", {} }, - }) + { "special_function_with_opt", R"({"arg1": 1, "arg2": 2})", {} }, }) .run(); + + // #20650: tool with no required args, model emits name with no arg tags. + { + static common_chat_tool no_args_tool{ + "read_file_diff_md", "Reads a file diff", + R"({"type":"object","properties":{"review_id":{"type":"string"},"file_id":{"type":"string"}}})", + }; + tst.test( + "Let me read the diff content." + "" + "read_file_diff_md") + .enable_thinking(true) + .reasoning_format(COMMON_REASONING_FORMAT_DEEPSEEK) + .tools({ no_args_tool }) + .expect_reasoning("Let me read the diff content.") + .expect_tool_calls({{ "read_file_diff_md", "{}", {} }}) + .run(); + } } // Kimi-K2-Thinking tests - custom parser From 12e1dcc6f2c7ac73d31b115bdd1c8147f65424b8 Mon Sep 17 00:00:00 2001 From: "Piotr Wilkin (ilintar)" Date: Thu, 19 Mar 2026 17:52:52 +0100 Subject: [PATCH 2/2] Update tests/test-chat.cpp [no ci] Co-authored-by: Aldehir Rojas --- tests/test-chat.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test-chat.cpp b/tests/test-chat.cpp index a39de1d1cbd..d6bfdf45ad7 100644 --- a/tests/test-chat.cpp +++ b/tests/test-chat.cpp @@ -1912,7 +1912,8 @@ static void test_template_output_peg_parsers(bool detailed_debug) { }) .expect_tool_calls({ { "special_function", R"({"arg1": 1})", {} }, - { "special_function_with_opt", R"({"arg1": 1, "arg2": 2})", {} }, }) + { "special_function_with_opt", R"({"arg1": 1, "arg2": 2})", {} }, + }) .run(); // #20650: tool with no required args, model emits name with no arg tags.