Fix pesky issue on optional trailing arguments in function calls for TAGGED format
This commit is contained in:
parent
2726bd7090
commit
8e87ba402f
|
|
@ -309,6 +309,12 @@ common_peg_parser universal_peg_generator::build_tool_parser(
|
|||
|
||||
if (!m.func_close.empty()) {
|
||||
func_parser = func_parser + p.space() + p.tool_close(p.literal(m.func_close));
|
||||
} else if (!m.per_call_end.empty()) {
|
||||
// When there's no func_close but there is a per_call_end marker, use peek() to ensure
|
||||
// we only emit tool_close when we can actually see the closing marker. This prevents
|
||||
// premature closing during partial parsing when we've seen e.g. "</" which could be
|
||||
// either "</tool_call>" (end) or "<arg_key>" prefix that failed to match.
|
||||
func_parser = func_parser + p.tool_close(p.peek(p.literal(m.per_call_end)));
|
||||
} else {
|
||||
func_parser = func_parser + p.tool_close(p.space()); // force this to process tool closing callbacks in mapper
|
||||
}
|
||||
|
|
|
|||
|
|
@ -338,6 +338,24 @@ static common_chat_tool magic_tool{
|
|||
})",
|
||||
};
|
||||
|
||||
static common_chat_tool magic_int_tool{
|
||||
/* .name = */ "magic_int",
|
||||
/* .description = */ "Magic tool that takes a hash",
|
||||
/* .parameters = */ R"({
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"ref": {
|
||||
"type": "integer"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": ["ref"]
|
||||
})",
|
||||
};
|
||||
|
||||
|
||||
static std::vector<common_chat_tool> tools{ special_function_tool, special_function_tool_with_optional_param,
|
||||
python_tool, html_tool, todo_list };
|
||||
|
||||
|
|
@ -2115,6 +2133,60 @@ static void test_template_output_peg_parsers(bool detailed_debug) {
|
|||
{ "magic", R"({"name": "fooBar", "ref": "5123123"})", {} },
|
||||
})
|
||||
.run();
|
||||
|
||||
// Test that numeric values are correctly interpreted as numbers when schema calls for number
|
||||
tst.test(
|
||||
"Let me call the special function\n"
|
||||
"</think>\n"
|
||||
"<tool_call>\n"
|
||||
"<function=special_function>\n"
|
||||
"<parameter=arg1>\n42555916\n</parameter>\n"
|
||||
"</function>\n"
|
||||
"</tool_call>")
|
||||
.enable_thinking(true)
|
||||
.reasoning_format(COMMON_REASONING_FORMAT_DEEPSEEK)
|
||||
.tools({ special_function_tool })
|
||||
.expect_reasoning("Let me call the special function")
|
||||
.expect_tool_calls({
|
||||
{ "special_function", R"({"arg1": 42555916})", {} },
|
||||
})
|
||||
.run();
|
||||
|
||||
tst.test(
|
||||
"Let me call the special function with opt\n"
|
||||
"</think>\n"
|
||||
"<tool_call>\n"
|
||||
"<function=special_function_with_opt>\n"
|
||||
"<parameter=arg1>\n42555916\n</parameter>\n"
|
||||
"</function>\n"
|
||||
"</tool_call>")
|
||||
.enable_thinking(true)
|
||||
.reasoning_format(COMMON_REASONING_FORMAT_DEEPSEEK)
|
||||
.tools({ special_function_tool_with_optional_param })
|
||||
.expect_reasoning("Let me call the special function with opt")
|
||||
.expect_tool_calls({
|
||||
{ "special_function_with_opt", R"({"arg1": 42555916})", {} },
|
||||
})
|
||||
.run();
|
||||
|
||||
tst.test(
|
||||
"Let me call the magic_int function\n"
|
||||
"</think>\n"
|
||||
"<tool_call>\n"
|
||||
"<function=magic_int>\n"
|
||||
"<parameter=ref>\n42555916\n</parameter>\n"
|
||||
"<parameter=name>\nbaz\n</parameter>\n"
|
||||
"</function>\n"
|
||||
"</tool_call>")
|
||||
.enable_thinking(true)
|
||||
.reasoning_format(COMMON_REASONING_FORMAT_DEEPSEEK)
|
||||
.tools({ magic_int_tool })
|
||||
.expect_reasoning("Let me call the magic_int function")
|
||||
.expect_tool_calls({
|
||||
{ "magic_int", R"({"ref": 42555916, "name": "baz"})", {} },
|
||||
})
|
||||
.run();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue