From 91c631b21d6e5d09e9c6659efdf6baeef5a44ddb Mon Sep 17 00:00:00 2001 From: Frosty40 Date: Mon, 13 Jul 2026 02:45:10 -0500 Subject: [PATCH] chat : fix reasoning leak with force-opened bare templates (#24674) * chat : fix reasoning leak with force-opened bare templates The reasoning start tag inferred from prior turns can carry trailing whitespace (e.g. \n) while a force-open template prefills a bare . 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 --- common/chat-auto-parser-generator.cpp | 3 ++- common/chat-diff-analyzer.cpp | 4 ++-- tests/test-chat.cpp | 11 +++++++++-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/common/chat-auto-parser-generator.cpp b/common/chat-auto-parser-generator.cpp index 36aab7ecbe..ddf81fc4d5 100644 --- a/common/chat-auto-parser-generator.cpp +++ b/common/chat-auto-parser-generator.cpp @@ -147,7 +147,8 @@ common_peg_arena autoparser::build_parser(const generation_params & inputs, cons } else { 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; }); } diff --git a/common/chat-diff-analyzer.cpp b/common/chat-diff-analyzer.cpp index b166ee5a18..79598368ca 100644 --- a/common/chat-diff-analyzer.cpp +++ b/common/chat-diff-analyzer.cpp @@ -124,16 +124,16 @@ static std::vector"); analysis.preserved_tokens.push_back(""); analysis.preserved_tokens.push_back(""); analysis.preserved_tokens.push_back(""); diff --git a/tests/test-chat.cpp b/tests/test-chat.cpp index fc8df4fb5e..93685ec8ff 100644 --- a/tests/test-chat.cpp +++ b/tests/test-chat.cpp @@ -4706,9 +4706,16 @@ static void test_template_output_peg_parsers(bool detailed_debug) { // Format: [{"name": "func", "arguments": {...}}] { auto tst = peg_tester("models/templates/NVIDIA-Nemotron-Nano-v2.jinja", detailed_debug); - tst.test("[{\"name\": \"special_function\", \"arguments\": {\"arg1\": 1}}]") + tst.test("I'm\nthinking\n\n[{\"name\": \"special_function\", \"arguments\": {\"arg1\": 1}}]") + .reasoning_format(COMMON_REASONING_FORMAT_AUTO) .tools({ special_function_tool }) - .expect(message_assist_call) + .expect(message_assist_call_thoughts) + .run(); + + tst.test("I'm\nthinking\n\n\n[{\"name\": \"special_function\", \"arguments\": {\"arg1\": 1}}]\n") + .reasoning_format(COMMON_REASONING_FORMAT_AUTO) + .tools({ special_function_tool }) + .expect(message_assist_call_thoughts) .run(); // Continuation tests