@@ -443,10 +443,26 @@ static common_chat_data common_chat_init_deepseek_r1_tool_call(const common_chat
443443 fprintf (stderr, " [%s]\n " , __func__);
444444 common_chat_data data;
445445 data.grammar = " root ::= .*" ;
446+ // data.grammar = "root ::= .*";
447+ data.grammar = build_grammar ([&](const common_grammar_builder & builder) {
448+ std::vector<std::string> tool_rules;
449+ foreach_function (params.tools , [&](const json & tool) {
450+ const auto & function = tool[" function" ];
451+ std::string name = function[" name" ];
452+ auto parameters = function[" parameters" ];
453+ auto args_rule = builder.add_schema (name + " -args" , parameters);
454+ tool_rules.push_back (builder.add_rule (name + " -call" ,
455+ " \" <|tool▁call▁begin|>function<|tool▁sep|>" + name + " \\ n```json\\ n\" " + args_rule + " \" ```<|tool▁call▁end|>\" " ));
456+ });
457+ if (params.tool_choice != " required" ) {
458+ data.grammar_triggers .push_back ({" <|tool▁calls▁begin|>" , /* .at_start = */ false });
459+ }
460+ builder.add_rule (" root" , " \" <|tool▁calls▁begin|>\" (" + string_join (tool_rules, " | " ) + " )" + (params.parallel_tool_calls ? " *" : " " ) + " space" );
461+ }, grammar_options);
446462 data.prompt = tmpl.apply (params.messages , params.tools .empty () ? json () : params.tools , params.add_generation_prompt );
447463 data.parser = std::make_unique<monolithic_chat_parser>([params](const std::string & input) -> common_chat_msg {
448464 static std::regex trigger_regex (" <|tool▁calls▁begin|>" );
449- static std::regex function_regex (" <|tool▁call▁begin|>function<|tool▁sep|>([^< ]+)\n ```json\n " );
465+ static std::regex function_regex (" <|tool▁call▁begin|>function<|tool▁sep|>([^\n ]+)\n ```json\n " );
450466 static std::regex close_regex (" ```<|tool▁call▁end|>" );
451467 return parse_json_tool_calls (params.tools , input, trigger_regex, function_regex, close_regex, /* check_names= */ true );
452468 });
0 commit comments