return p.literal(reasoning_content) + p.space() + p.optional(p.tag("post", (p.marker() + p.space())) + p.rest());
});
auto parser_wrapped = build_tagged_peg_parser([&](common_peg_parser_builder &p) {
- return p.tag("pre", p.marker() + p.space()) + p.literal(reasoning_content) + p.space() + p.tag("post", (p.marker() + p.space())) + p.rest();
+ return p.tag("pre", p.marker() + p.space()) + p.literal(reasoning_content) + p.tag("post", (p.space() + p.marker() + p.space())) + p.rest();
});
// try the more aggressive parse first, if it fails, fall back to the delimiter one
auto result = parser_wrapped.parse_anywhere_and_extract(comparison->output_B);
if (result.result.success()) {
if (!result.tags["pre"].empty() && !result.tags["post"].empty()) {
mode = reasoning_mode::TAG_BASED;
- start = trim_leading_whitespace(result.tags["pre"]);
- end = trim_trailing_whitespace(result.tags["post"]);
+ start = result.tags["pre"];
+ end = result.tags["post"];
} else if (!result.tags["post"].empty()) {
mode = reasoning_mode::TAG_BASED;
- end = trim_trailing_whitespace(result.tags["post"]);
+ end = result.tags["post"];
}
}
}
// Qwen3.5 (basically same as Nemotron, but keeping separate tests just in case)
auto tst = peg_tester("models/templates/Qwen3.5-4B.jinja", detailed_debug);
- tst.test("I'm\nthinking</think>Hello, world!\nWhat's up?")
+ tst.test("I'm\nthinking\n</think>\n\nHello, world!\nWhat's up?")
.reasoning_format(COMMON_REASONING_FORMAT_AUTO)
.enable_thinking(true)
.expect(message_assist_thoughts)
.run();
- tst.test("I'm\nthinking\n</think>\nHello, world!\nWhat's up?")
+ tst.test("I'm\nthinking\n</think>\n\nHello, world!\nWhat's up?")
.enable_thinking(true)
.reasoning_format(COMMON_REASONING_FORMAT_NONE)
- .expect_content("<think>\nI'm\nthinking\n</think>\nHello, world!\nWhat's up?")
- .run();
-
- tst.test("I'm\nthinking\n</think>\nHello, world!\nWhat's up?")
- .enable_thinking(true)
- .reasoning_format(COMMON_REASONING_FORMAT_AUTO)
- .expect(message_assist_thoughts)
+ .expect_content("<think>\nI'm\nthinking\n</think>\n\nHello, world!\nWhat's up?")
.run();
tst.test(
.run();
tst.test(
- "I'm\nthinking\n</think>\n"
+ "I'm\nthinking\n</think>\n\n"
"<tool_call>\n"
"<function=special_function>\n"
"<parameter=arg1>\n1\n</parameter>\n"
tst.test(
"I need to output the invoice details in JSON\n"
- "</think>\n"
+ "</think>\n\n"
R"({"amount": 123.45, "date": "2025-12-03"})")
.reasoning_format(COMMON_REASONING_FORMAT_AUTO)
.enable_thinking(true)
"hello()\n"
"</parameter>\n"
"</function>\n"
- "</tool_call></think>\n"
+ "</tool_call>\n</think>\n\n"
"<tool_call>\n"
"<function=python>\n"
"<parameter=code>\n"
"hello()\n"
"</parameter>\n"
"</function>\n"
- "</tool_call></think>\n"
+ "</tool_call>\n</think>\n"
"<tool_call>\n"
"<function=python>\n"
"<parameter=code>\n"
.run();
// Tool call with reasoning (enable_thinking=true)
- tst.test("I'm\nthinking</think><tool_call>\n{\"name\": \"special_function\", \"arguments\": {\"arg1\": 1}}</tool_call>")
+ tst.test("I'm\nthinking\n</think>\n\n<tool_call>\n{\"name\": \"special_function\", \"arguments\": {\"arg1\": 1}}</tool_call>")
.enable_thinking(true)
.reasoning_format(COMMON_REASONING_FORMAT_AUTO)
.tools({ special_function_tool })
.run();
// Tool call with reasoning and content
- tst.test("I need to call a function</think>"
+ tst.test("I need to call a function\n</think>\n\n"
"Let me check the time.<tool_call>\n{\"name\": \"get_time\", \"arguments\": {\"city\": \"XYZCITY\"}}</tool_call>")
.enable_thinking(true)
.reasoning_format(COMMON_REASONING_FORMAT_AUTO)
// fake tool call marker in reasoning
tst.test(
- "Let me think about <tool_call>\n{\"name\": \"special_function\", \"arguments\": {\"arg1\": 2}}</tool_call> hmm</think>"
+ "Let me think about <tool_call>\n{\"name\": \"special_function\", \"arguments\": {\"arg1\": 2}}</tool_call> hmm\n</think>\n\n"
"<tool_call>\n{\"name\": \"special_function\", \"arguments\": {\"arg1\": 1}}</tool_call>")
.enable_thinking(true)
.reasoning_format(COMMON_REASONING_FORMAT_AUTO)
// Format: <minimax:tool_call><invoke name="func"><parameter name="key">value</parameter></invoke></minimax:tool_call>
{
auto tst = peg_tester("models/templates/MiniMax-M2.jinja", detailed_debug);
- tst.test("</think>Hello, world!\nWhat's up?").enable_thinking(true).reasoning_format(COMMON_REASONING_FORMAT_AUTO).expect(message_assist).run();
+ tst.test("\n</think>\n\nHello, world!\nWhat's up?").enable_thinking(true).reasoning_format(COMMON_REASONING_FORMAT_AUTO).expect(message_assist).run();
- tst.test("I'm\nthinking</think>Hello, world!\nWhat's up?").enable_thinking(true).reasoning_format(COMMON_REASONING_FORMAT_AUTO).expect(message_assist_thoughts).run();
+ tst.test("I'm\nthinking\n</think>\n\nHello, world!\nWhat's up?").enable_thinking(true).reasoning_format(COMMON_REASONING_FORMAT_AUTO).expect(message_assist_thoughts).run();
- tst.test("Let's call a tool:</think><minimax:tool_call>\n<invoke name=\"empty_args\">\n</invoke>\n</minimax:tool_call>").
+ tst.test("Let's call a tool:\n</think>\n\n<minimax:tool_call>\n<invoke name=\"empty_args\">\n</invoke>\n</minimax:tool_call>").
enable_thinking(true).
reasoning_format(COMMON_REASONING_FORMAT_AUTO).
tools({ empty_args_tool }).
run();
tst.test(
- "</think><minimax:tool_call>\n<invoke name=\"special_function\">\n<parameter "
+ "\n</think>\n\n<minimax:tool_call>\n<invoke name=\"special_function\">\n<parameter "
"name=\"arg1\">1</parameter>\n</invoke>\n</minimax:tool_call>")
.tools({ special_function_tool })
.expect(message_assist_call)
.enable_thinking(false)
.expect(message_assist)
.run();
- tst.test("I'm\nthinking</think>\n\nHello, world!\nWhat's up?")
+ tst.test("I'm\nthinking\n</think>\n\nHello, world!\nWhat's up?")
.enable_thinking(true)
.reasoning_format(COMMON_REASONING_FORMAT_DEEPSEEK)
.expect(message_assist_thoughts)
.tools({ special_function_tool })
.expect(message_assist_call_content)
.run();
- tst.test("I'm\nthinking</think>\n\n<tool_call>\n{\"name\": \"special_function\", \"arguments\": {\"arg1\": 1}}\n</tool_call>")
+ tst.test("I'm\nthinking\n</think>\n\n<tool_call>\n{\"name\": \"special_function\", \"arguments\": {\"arg1\": 1}}\n</tool_call>")
.enable_thinking(true)
.reasoning_format(COMMON_REASONING_FORMAT_DEEPSEEK)
.tools({ special_function_tool })
{
auto tst = peg_tester("models/templates/StepFun3.5-Flash.jinja", detailed_debug);
- tst.test("I was thinking</think>\nNow I'm not.").
+
+ tst.test("I was thinking\n</think>\nNow I'm not.").
enable_thinking(true).
reasoning_format(COMMON_REASONING_FORMAT_DEEPSEEK).
expect_reasoning("I was thinking").