chat : fix reasoning leak with force-opened bare <think> templates (#24674)
* chat : fix reasoning leak with force-opened bare <think> templates The reasoning start tag inferred from prior turns can carry trailing whitespace (e.g. <think>\n) while a force-open template prefills a bare <think>. Trim the tag used for the prefix split so the bare prefill is matched instead of being swallowed into content. * chat : fix Nemotron Nano v2 regression --------- Co-authored-by: Alde Rojas <hello@alde.dev>
This commit is contained in:
@@ -147,7 +147,8 @@ common_peg_arena autoparser::build_parser(const generation_params & inputs, cons
|
|||||||
} else {
|
} else {
|
||||||
parser = content.build_parser(ctx);
|
parser = content.build_parser(ctx);
|
||||||
}
|
}
|
||||||
return pure_content ? p.prefix(generation_prompt, reasoning.start) + parser : p.prefix(generation_prompt, reasoning.start) << parser;
|
const std::string reasoning_start = trim_whitespace(reasoning.start);
|
||||||
|
return pure_content ? p.prefix(generation_prompt, reasoning_start) + parser : p.prefix(generation_prompt, reasoning_start) << parser;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -124,16 +124,16 @@ static std::vector<std::function<void(const common_chat_template & tmpl, autopar
|
|||||||
analysis.tools.format.section_end = "";
|
analysis.tools.format.section_end = "";
|
||||||
analysis.tools.format.per_call_start = "<TOOLCALL>";
|
analysis.tools.format.per_call_start = "<TOOLCALL>";
|
||||||
analysis.tools.format.per_call_end = "</TOOLCALL>";
|
analysis.tools.format.per_call_end = "</TOOLCALL>";
|
||||||
|
analysis.tools.format.tools_array_wrapped = true;
|
||||||
analysis.content.mode = content_mode::PLAIN;
|
analysis.content.mode = content_mode::PLAIN;
|
||||||
analysis.content.start = "";
|
analysis.content.start = "";
|
||||||
analysis.content.end = "";
|
analysis.content.end = "";
|
||||||
analysis.reasoning.mode = reasoning_mode::TAG_BASED;
|
analysis.reasoning.mode = reasoning_mode::TAG_BASED;
|
||||||
analysis.reasoning.start = "<think>\n\n";
|
analysis.reasoning.start = "<think>\n";
|
||||||
analysis.reasoning.end = "</think>";
|
analysis.reasoning.end = "</think>";
|
||||||
analysis.assistant_start = "<SPECIAL_11>Assistant";
|
analysis.assistant_start = "<SPECIAL_11>Assistant";
|
||||||
analysis.user_start = "<SPECIAL_11>User";
|
analysis.user_start = "<SPECIAL_11>User";
|
||||||
analysis.preserved_tokens.clear();
|
analysis.preserved_tokens.clear();
|
||||||
analysis.preserved_tokens.push_back("<SPECIAL_12>");
|
|
||||||
analysis.preserved_tokens.push_back("<SPECIAL_11>");
|
analysis.preserved_tokens.push_back("<SPECIAL_11>");
|
||||||
analysis.preserved_tokens.push_back("</think>");
|
analysis.preserved_tokens.push_back("</think>");
|
||||||
analysis.preserved_tokens.push_back("<TOOLCALL>");
|
analysis.preserved_tokens.push_back("<TOOLCALL>");
|
||||||
|
|||||||
+9
-2
@@ -4706,9 +4706,16 @@ static void test_template_output_peg_parsers(bool detailed_debug) {
|
|||||||
// Format: <TOOLCALL>[{"name": "func", "arguments": {...}}]</TOOLCALL>
|
// Format: <TOOLCALL>[{"name": "func", "arguments": {...}}]</TOOLCALL>
|
||||||
{
|
{
|
||||||
auto tst = peg_tester("models/templates/NVIDIA-Nemotron-Nano-v2.jinja", detailed_debug);
|
auto tst = peg_tester("models/templates/NVIDIA-Nemotron-Nano-v2.jinja", detailed_debug);
|
||||||
tst.test("<TOOLCALL>[{\"name\": \"special_function\", \"arguments\": {\"arg1\": 1}}]</TOOLCALL>")
|
tst.test("I'm\nthinking\n</think>\n<TOOLCALL>[{\"name\": \"special_function\", \"arguments\": {\"arg1\": 1}}]</TOOLCALL>")
|
||||||
|
.reasoning_format(COMMON_REASONING_FORMAT_AUTO)
|
||||||
.tools({ special_function_tool })
|
.tools({ special_function_tool })
|
||||||
.expect(message_assist_call)
|
.expect(message_assist_call_thoughts)
|
||||||
|
.run();
|
||||||
|
|
||||||
|
tst.test("I'm\nthinking\n</think>\n\n<TOOLCALL>[{\"name\": \"special_function\", \"arguments\": {\"arg1\": 1}}]</TOOLCALL>\n")
|
||||||
|
.reasoning_format(COMMON_REASONING_FORMAT_AUTO)
|
||||||
|
.tools({ special_function_tool })
|
||||||
|
.expect(message_assist_call_thoughts)
|
||||||
.run();
|
.run();
|
||||||
|
|
||||||
// Continuation tests
|
// Continuation tests
|
||||||
|
|||||||
Reference in New Issue
Block a user