@@ -1070,13 +1070,13 @@ static common_chat_params common_chat_params_init_qwen3(const common_chat_templa
10701070
10711071 data.prompt = apply (tmpl, inputs);
10721072 data.format = COMMON_CHAT_FORMAT_QWEN3;
1073- if (string_ends_with (data.prompt , " <think>\n " )) {
1074- if (!inputs.enable_thinking ) {
1075- data.prompt += " </think>" ;
1076- } else {
1077- data.thinking_forced_open = true ;
1078- }
1079- }
1073+ // if (string_ends_with(data.prompt, "<think>\n")) {
1074+ // if (!inputs.enable_thinking) {
1075+ // data.prompt += "</think>";
1076+ // } else {
1077+ // data.thinking_forced_open = true;
1078+ // }
1079+ // }
10801080
10811081 if (!inputs.tools .is_null ()) {
10821082 // (content)?(<tool_call>{"name": "foo", "arguments": {"a": 1}}</tool_call>)*
@@ -1090,7 +1090,7 @@ static common_chat_params common_chat_params_init_qwen3(const common_chat_templa
10901090 builder.resolve_refs (parameters);
10911091
10921092 std::vector<std::string> fragments;
1093- fragments.push_back (" \" <tool_call>\\ n<function=" + name + " >\\ n\" " );
1093+ fragments.push_back (" space \" <tool_call>\\ n<function=" + name + " >\\ n\" " );
10941094
10951095 const auto & properties = parameters.at (" properties" );
10961096 std::vector<std::string> required;
@@ -1120,15 +1120,18 @@ static common_chat_params common_chat_params_init_qwen3(const common_chat_templa
11201120 builder.add_rule (" root" ,
11211121 std::string (data.thinking_forced_open ? " ( \" </think>\" space )? " : " " ) +
11221122 (inputs.parallel_tool_calls ? " (" + tool_call + " )+" : tool_call));
1123- // Trigger on some common known "good bad" outputs (only from the start and with a json that's about a specific argument name to avoid false positives)
11241123 data.grammar_triggers .push_back ({
1125- COMMON_GRAMMAR_TRIGGER_TYPE_PATTERN_FULL,
1126- // If thinking_forced_open, then we capture the </think> tag in the grammar,
1127- // (important for required tool choice) and in the trigger's first capture (decides what is sent to the grammar)
1128- std::string (data.thinking_forced_open ? " [\\ s\\ S]*?(</think>\\ s*)" : " (?:<think>[\\ s\\ S]*?</think>\\ s*)?" ) + (
1129- " \\ s*(<tool_call>\\ n<function=)" // + string_join(tool_names, "|") + ")>\n)"
1130- ),
1124+ COMMON_GRAMMAR_TRIGGER_TYPE_WORD,
1125+ " <tool_call>"
11311126 });
1127+ // data.grammar_triggers.push_back({
1128+ // COMMON_GRAMMAR_TRIGGER_TYPE_PATTERN_FULL,
1129+ // // If thinking_forced_open, then we capture the </think> tag in the grammar,
1130+ // // (important for required tool choice) and in the trigger's first capture (decides what is sent to the grammar)
1131+ // std::string(data.thinking_forced_open ? "[\\s\\S]*?(</think>\\s*)" : "(?:<think>[\\s\\S]*?</think>\\s*)?") + (
1132+ // "\\s*(<tool_call>\\n<function=)" // + string_join(tool_names, "|") + ")>\n)"
1133+ // ),
1134+ // });
11321135 data.preserved_tokens = {
11331136 " <think>" ,
11341137 " </think>" ,
@@ -1148,12 +1151,11 @@ static void common_chat_parse_qwen3(common_chat_msg_parser & builder) {
11481151 return ;
11491152 }
11501153
1151- static const common_regex function_open (" <tool_call>\n <function=([a-zA-Z0-9_]+)>\n " );
1154+ static const common_regex function_open (" \\ s* <tool_call>\n <function=([a-zA-Z0-9_]+)>\n " );
11521155 static const common_regex function_close (" </function>\n </tool_call>" );
11531156 static const common_regex parameter_open (" <parameter=([a-zA-Z0-9_]+)>\n " );
11541157 static const common_regex parameter_close (" </parameter>\n " );
11551158
1156- const auto start_pos = builder.pos ();
11571159 while (auto block_open_match = builder.try_find_regex (function_open)) {
11581160 const auto function_name = builder.str (block_open_match->groups [1 ]);
11591161 json arguments = json::object ();
0 commit comments