static void test_reasoning() {
//common_log_set_verbosity_thold(LOG_DEFAULT_DEBUG);
{
- common_chat_msg_parser builder("<tnk>Cogito</tnk>Ergo sum", /* is_partial= */ false, {
- /* .format = */ COMMON_CHAT_FORMAT_CONTENT_ONLY,
- /* .reasoning_format = */ COMMON_REASONING_FORMAT_NONE,
- /* .reasoning_in_content = */ false,
- /* .thinking_forced_open = */ false,
- });
+ common_chat_parser_params params;
+ params.format = COMMON_CHAT_FORMAT_CONTENT_ONLY;
+ params.reasoning_format = COMMON_REASONING_FORMAT_NONE;
+ params.reasoning_in_content = false;
+ params.thinking_forced_open = false;
+ common_chat_msg_parser builder("<tnk>Cogito</tnk>Ergo sum", /* is_partial= */ false, params);
assert_equals(false, builder.try_parse_reasoning("<tnk>", "</tnk>"));
assert_equals("<tnk>Cogito</tnk>Ergo sum", builder.consume_rest());
}
{
- common_chat_msg_parser builder("<tnk>Cogito</tnk>Ergo sum", /* is_partial= */ false, {
- /* .format = */ COMMON_CHAT_FORMAT_CONTENT_ONLY,
- /* .reasoning_format = */ COMMON_REASONING_FORMAT_DEEPSEEK,
- /* .reasoning_in_content = */ false,
- /* .thinking_forced_open = */ false,
- });
+ common_chat_parser_params params;
+ params.format = COMMON_CHAT_FORMAT_CONTENT_ONLY;
+ params.reasoning_format = COMMON_REASONING_FORMAT_DEEPSEEK;
+ params.reasoning_in_content = false;
+ params.thinking_forced_open = false;
+ common_chat_msg_parser builder("<tnk>Cogito</tnk>Ergo sum", /* is_partial= */ false, params);
assert_equals(true, builder.try_parse_reasoning("<tnk>", "</tnk>"));
assert_equals(std::string("Cogito"), builder.result().reasoning_content);
assert_equals("Ergo sum", builder.consume_rest());
}
{
- common_chat_msg_parser builder("Cogito</tnk>Ergo sum", /* is_partial= */ false, {
- /* .format = */ COMMON_CHAT_FORMAT_CONTENT_ONLY,
- /* .reasoning_format = */ COMMON_REASONING_FORMAT_NONE,
- /* .reasoning_in_content = */ false,
- /* .thinking_forced_open = */ false,
- });
+ common_chat_parser_params params;
+ params.format = COMMON_CHAT_FORMAT_CONTENT_ONLY;
+ params.reasoning_format = COMMON_REASONING_FORMAT_NONE;
+ params.reasoning_in_content = false;
+ params.thinking_forced_open = false;
+ common_chat_msg_parser builder("Cogito</tnk>Ergo sum", /* is_partial= */ false, params);
assert_equals(false, builder.try_parse_reasoning("<tnk>", "</tnk>"));
assert_equals("Cogito</tnk>Ergo sum", builder.consume_rest());
}
{
- common_chat_msg_parser builder("Cogito</tnk>Ergo sum", /* is_partial= */ false, {
- /* .format = */ COMMON_CHAT_FORMAT_CONTENT_ONLY,
- /* .reasoning_format = */ COMMON_REASONING_FORMAT_DEEPSEEK,
- /* .reasoning_in_content = */ false,
- /* .thinking_forced_open = */ true,
- });
+ common_chat_parser_params params;
+ params.format = COMMON_CHAT_FORMAT_CONTENT_ONLY;
+ params.reasoning_format = COMMON_REASONING_FORMAT_DEEPSEEK;
+ params.reasoning_in_content = false;
+ params.thinking_forced_open = true;
+ common_chat_msg_parser builder("Cogito</tnk>Ergo sum", /* is_partial= */ false, params);
assert_equals(true, builder.try_parse_reasoning("<tnk>", "</tnk>"));
assert_equals(std::string("Cogito"), builder.result().reasoning_content);
assert_equals("Ergo sum", builder.consume_rest());
}
{
- common_chat_msg_parser builder("Cogito</tnk>Ergo sum", /* is_partial= */ false, {
- /* .format = */ COMMON_CHAT_FORMAT_CONTENT_ONLY,
- /* .reasoning_format = */ COMMON_REASONING_FORMAT_DEEPSEEK,
- /* .reasoning_in_content = */ true,
- /* .thinking_forced_open = */ true,
- });
+ common_chat_parser_params params;
+ params.format = COMMON_CHAT_FORMAT_CONTENT_ONLY;
+ params.reasoning_format = COMMON_REASONING_FORMAT_DEEPSEEK;
+ params.reasoning_in_content = true;
+ params.thinking_forced_open = true;
+ common_chat_msg_parser builder("Cogito</tnk>Ergo sum", /* is_partial= */ false, params);
assert_equals(true, builder.try_parse_reasoning("<tnk>", "</tnk>"));
assert_equals("<think>Cogito</think>", builder.result().content);
assert_equals("Ergo sum", builder.consume_rest());
}
{
const std::string variant("content_only_inline_think");
- common_chat_syntax syntax = {
- /* .format = */ COMMON_CHAT_FORMAT_CONTENT_ONLY,
- /* .reasoning_format = */ COMMON_REASONING_FORMAT_DEEPSEEK,
- /* .reasoning_in_content = */ false,
- /* .thinking_forced_open = */ false,
- /* .parse_tool_calls = */ false,
- };
+ common_chat_parser_params params;
+ params.format = COMMON_CHAT_FORMAT_CONTENT_ONLY;
+ params.reasoning_format = COMMON_REASONING_FORMAT_DEEPSEEK;
+ params.reasoning_in_content = false;
+ params.thinking_forced_open = false;
+ params.parse_tool_calls = false;
const std::string input = "<think>Pense</think>Bonjour";
- auto msg = common_chat_parse(input, false, syntax);
+ auto msg = common_chat_parse(input, false, params);
assert_equals(variant, std::string("Pense"), msg.reasoning_content);
assert_equals(variant, std::string("Bonjour"), msg.content);
}
{
const std::string variant("llama_3_inline_think");
- common_chat_syntax syntax = {
- /* .format = */ COMMON_CHAT_FORMAT_LLAMA_3_X,
- /* .reasoning_format = */ COMMON_REASONING_FORMAT_DEEPSEEK,
- /* .reasoning_in_content = */ false,
- /* .thinking_forced_open = */ false,
- /* .parse_tool_calls = */ false,
- };
+ common_chat_parser_params params;
+ params.format = COMMON_CHAT_FORMAT_LLAMA_3_X;
+ params.reasoning_format = COMMON_REASONING_FORMAT_DEEPSEEK;
+ params.reasoning_in_content = false;
+ params.thinking_forced_open = false;
+ params.parse_tool_calls = false;
const std::string input = "<think>Plan</think>Réponse";
- auto msg = common_chat_parse(input, false, syntax);
+ auto msg = common_chat_parse(input, false, params);
assert_equals(variant, std::string("Plan"), msg.reasoning_content);
assert_equals(variant, std::string("Réponse"), msg.content);
}
// Test DeepSeek V3.1 parsing - reasoning content followed by "</think>" and then regular content
{
- common_chat_syntax syntax = {
- /* .format = */ COMMON_CHAT_FORMAT_DEEPSEEK_V3_1,
- /* .reasoning_format = */ COMMON_REASONING_FORMAT_DEEPSEEK,
- /* .reasoning_in_content = */ false,
- /* .thinking_forced_open = */ true,
- /* .parse_tool_calls = */ true,
- };
+ common_chat_parser_params params;
+ params.format = COMMON_CHAT_FORMAT_DEEPSEEK_V3_1;
+ params.reasoning_format = COMMON_REASONING_FORMAT_DEEPSEEK;
+ params.reasoning_in_content = false;
+ params.thinking_forced_open = true;
+ params.parse_tool_calls = true;
const std::string variant("deepseek_v3_1_reasoning_format_deepseek");
- common_chat_msg_parser builder("REASONING</think>ok", /* is_partial= */ false, syntax);
+ common_chat_msg_parser builder("REASONING</think>ok", /* is_partial= */ false, params);
assert_equals(variant, true, builder.try_parse_reasoning("<think>", "</think>"));
assert_equals(variant, std::string("REASONING"), builder.result().reasoning_content);
assert_equals(variant, std::string("ok"), builder.consume_rest());
}
// Test DeepSeek V3.1 parsing - reasoning_format none - reasoning content followed by "</think>" and then regular content
{
- common_chat_syntax syntax = {
- /* .format = */ COMMON_CHAT_FORMAT_DEEPSEEK_V3_1,
- /* .reasoning_format = */ COMMON_REASONING_FORMAT_NONE,
- /* .reasoning_in_content = */ false,
- /* .thinking_forced_open = */ true,
- /* .parse_tool_calls = */ true,
- };
+ common_chat_parser_params params;
+ params.format = COMMON_CHAT_FORMAT_DEEPSEEK_V3_1;
+ params.reasoning_format = COMMON_REASONING_FORMAT_NONE;
+ params.reasoning_in_content = false;
+ params.thinking_forced_open = true;
+ params.parse_tool_calls = true;
const std::string variant("deepseek_v3_1_reasoning_format_none");
const std::string input = "REASONING</think>ok";
- auto msg = common_chat_parse(input, false, syntax);
+ auto msg = common_chat_parse(input, false, params);
assert_equals(variant, std::string("REASONING</think>ok"), msg.content);
assert_equals(variant, std::string(""), msg.reasoning_content);
}
//common_log_set_verbosity_thold(LOG_DEFAULT_DEBUG);
// variant: happy path for when it works as the model card says it should
const std::string variant("simple");
- common_chat_syntax syntax = {
- /* .format = */ COMMON_CHAT_FORMAT_DEEPSEEK_V3_1,
- /* .reasoning_format = */ COMMON_REASONING_FORMAT_DEEPSEEK,
- /* .reasoning_in_content = */ false,
- /* .thinking_forced_open = */ false,
- /* .parse_tool_calls = */ true,
- };
+ common_chat_parser_params params;
+ params.format = COMMON_CHAT_FORMAT_DEEPSEEK_V3_1;
+ params.reasoning_format = COMMON_REASONING_FORMAT_DEEPSEEK;
+ params.reasoning_in_content = false;
+ params.thinking_forced_open = false;
+ params.parse_tool_calls = true;
const std::string input = "<|tool▁calls▁begin|><|tool▁call▁begin|>get_time<|tool▁sep|>{\"city\": \"Tokyo\"}<|tool▁call▁end|><|tool▁calls▁end|>";
- auto msg = common_chat_parse(input, false, syntax);
+ auto msg = common_chat_parse(input, false, params);
assert_equals<std::size_t>(variant, 1, msg.tool_calls.size());
assert_equals(variant, std::string("get_time"), msg.tool_calls[0].name);
// JSON arguments are dumped without spaces
// variant: simple + thinking open
{
- common_chat_syntax syntax = {
- /* .format = */ COMMON_CHAT_FORMAT_DEEPSEEK_V3_1,
- /* .reasoning_format = */ COMMON_REASONING_FORMAT_DEEPSEEK,
- /* .reasoning_in_content = */ false,
- /* .thinking_forced_open = */ true,
- /* .parse_tool_calls = */ true,
- };
+ common_chat_parser_params params;
+ params.format = COMMON_CHAT_FORMAT_DEEPSEEK_V3_1;
+ params.reasoning_format = COMMON_REASONING_FORMAT_DEEPSEEK;
+ params.reasoning_in_content = false;
+ params.thinking_forced_open = true;
+ params.parse_tool_calls = true;
const std::string variant("simple_thinking");
const std::string in = "REASONING</think><|tool▁calls▁begin|><|tool▁call▁begin|>get_time<|tool▁sep|>{\"city\": \"Tokyo\"}<|tool▁call▁end|><|tool▁calls▁end|>";
- auto m = common_chat_parse(in, false, syntax);
+ auto m = common_chat_parse(in, false, params);
assert_equals<std::size_t>(variant, 1, m.tool_calls.size());
assert_equals(variant, std::string("get_time"), m.tool_calls[0].name);
assert_equals(variant, std::string("{\"city\":\"Tokyo\"}"), m.tool_calls[0].arguments);
}
// variant: simple + multiple tool calls
{
- common_chat_syntax syntax = {
- /* .format = */ COMMON_CHAT_FORMAT_DEEPSEEK_V3_1,
- /* .reasoning_format = */ COMMON_REASONING_FORMAT_DEEPSEEK,
- /* .reasoning_in_content = */ false,
- /* .thinking_forced_open = */ false,
- /* .parse_tool_calls = */ true,
- };
+ common_chat_parser_params params;
+ params.format = COMMON_CHAT_FORMAT_DEEPSEEK_V3_1;
+ params.reasoning_format = COMMON_REASONING_FORMAT_DEEPSEEK;
+ params.reasoning_in_content = false;
+ params.thinking_forced_open = false;
+ params.parse_tool_calls = true;
const std::string variant("simple_multiple_tool_calls");
const std::string in = "CONTENT<|tool▁calls▁begin|><|tool▁call▁begin|>get_time<|tool▁sep|>{\"city\": \"Paris\"}<|tool▁call▁end|><|tool▁call▁begin|>get_weather<|tool▁sep|>{\"city\": \"Paris\"}<|tool▁call▁end|><|tool▁calls▁end|>";
- auto m = common_chat_parse(in, false, syntax);
+ auto m = common_chat_parse(in, false, params);
assert_equals<std::size_t>(variant, 2, m.tool_calls.size());
assert_equals(variant, std::string("get_time"), m.tool_calls[0].name);
assert_equals(variant, std::string("{\"city\":\"Paris\"}"), m.tool_calls[0].arguments);
// variant: thinking forced open + tool call in reasoning content
{
- common_chat_syntax syntax = {
- /* .format = */ COMMON_CHAT_FORMAT_DEEPSEEK_V3_1,
- /* .reasoning_format = */ COMMON_REASONING_FORMAT_DEEPSEEK,
- /* .reasoning_in_content = */ false,
- /* .thinking_forced_open = */ true,
- /* .parse_tool_calls = */ true,
- };
+ common_chat_parser_params params;
+ params.format = COMMON_CHAT_FORMAT_DEEPSEEK_V3_1;
+ params.reasoning_format = COMMON_REASONING_FORMAT_DEEPSEEK;
+ params.reasoning_in_content = false;
+ params.thinking_forced_open = true;
+ params.parse_tool_calls = true;
const std::string variant("thinking_forced_open_tool_call_in_reasoning");
const std::string in = "REASONING<|tool▁calls▁begin|><|tool▁call▁begin|>get_time2<|tool▁sep|>{\"city\": \"Tokyo2\"}<|tool▁call▁end|><|tool▁calls▁end|>REASONING</think><|tool▁calls▁begin|><|tool▁call▁begin|>get_time<|tool▁sep|>{\"city\": \"Tokyo\"}<|tool▁call▁end|><|tool▁calls▁end|>";
- auto m = common_chat_parse(in, false, syntax);
+ auto m = common_chat_parse(in, false, params);
assert_equals<std::size_t>(variant, 1, m.tool_calls.size());
assert_equals(variant, std::string("get_time"), m.tool_calls[0].name);
assert_equals(variant, std::string("{\"city\":\"Tokyo\"}"), m.tool_calls[0].arguments);
// to make tool calls in reasoning content according to the model card, but it does sometimes, so
// add the reasoning content as regular content and parse the tool calls.
{
- common_chat_syntax syntax = {
- /* .format = */ COMMON_CHAT_FORMAT_DEEPSEEK_V3_1,
- /* .reasoning_format = */ COMMON_REASONING_FORMAT_DEEPSEEK,
- /* .reasoning_in_content = */ false,
- /* .thinking_forced_open = */ true,
- /* .parse_tool_calls = */ true,
- };
+ common_chat_parser_params params;
+ params.format = COMMON_CHAT_FORMAT_DEEPSEEK_V3_1;
+ params.reasoning_format = COMMON_REASONING_FORMAT_DEEPSEEK;
+ params.reasoning_in_content = false;
+ params.thinking_forced_open = true;
+ params.parse_tool_calls = true;
const std::string variant("thinking_forced_open_tool_call_in_reasoning_no_closing_think_not_partial");
const std::string in = "REASONING<|tool▁calls▁begin|><|tool▁call▁begin|>get_time<|tool▁sep|>{\"city\": \"Tokyo\"}<|tool▁call▁end|><|tool▁calls▁end|>";
- auto m = common_chat_parse(in, false, syntax);
+ auto m = common_chat_parse(in, false, params);
assert_equals(variant, std::string("REASONING"), m.content);
assert_equals(variant, std::string(""), m.reasoning_content);
assert_equals<std::size_t>(variant, 1, m.tool_calls.size());
// variant: thinking forced open + tool call in reasoning content + no closing think + partial
{
- common_chat_syntax syntax = {
- /* .format = */ COMMON_CHAT_FORMAT_DEEPSEEK_V3_1,
- /* .reasoning_format = */ COMMON_REASONING_FORMAT_DEEPSEEK,
- /* .reasoning_in_content = */ false,
- /* .thinking_forced_open = */ true,
- /* .parse_tool_calls = */ true,
- };
+ common_chat_parser_params params;
+ params.format = COMMON_CHAT_FORMAT_DEEPSEEK_V3_1;
+ params.reasoning_format = COMMON_REASONING_FORMAT_DEEPSEEK;
+ params.reasoning_in_content = false;
+ params.thinking_forced_open = true;
+ params.parse_tool_calls = true;
const std::string variant("thinking_forced_open_tool_call_in_reasoning_no_closing_think_partial");
const std::string in = "REASONING<|tool▁calls▁begin|><|tool▁call▁begin|>get_time<|tool▁sep|>{\"city\": \"Tokyo\"}<|tool▁call▁end|><|tool▁calls▁end|>";
- auto m = common_chat_parse(in, /* is_partial= */ true, syntax);
+ auto m = common_chat_parse(in, /* is_partial= */ true, params);
assert_equals(variant, std::string("REASONING<|tool▁calls▁begin|><|tool▁call▁begin|>get_time<|tool▁sep|>{\"city\": \"Tokyo\"}<|tool▁call▁end|><|tool▁calls▁end|>"), m.reasoning_content);
assert_equals(variant, std::string(""), m.content);
assert_equals<std::size_t>(variant, 0, m.tool_calls.size());
// variant: thinking not forced open + reasoning + regular content + no tool calls
{
- common_chat_syntax syntax = {
- /* .format = */ COMMON_CHAT_FORMAT_DEEPSEEK_V3_1,
- /* .reasoning_format = */ COMMON_REASONING_FORMAT_DEEPSEEK,
- /* .reasoning_in_content = */ false,
- /* .thinking_forced_open = */ true,
- /* .parse_tool_calls = */ true,
- };
+ common_chat_parser_params params;
+ params.format = COMMON_CHAT_FORMAT_DEEPSEEK_V3_1;
+ params.reasoning_format = COMMON_REASONING_FORMAT_DEEPSEEK;
+ params.reasoning_in_content = false;
+ params.thinking_forced_open = true;
+ params.parse_tool_calls = true;
const std::string variant("thinking_forced_open_reasoning_regular_content_no_tool_calls");
const std::string in = "REASONING</think>CONTENT";
- auto m = common_chat_parse(in, false, syntax);
+ auto m = common_chat_parse(in, false, params);
assert_equals<std::size_t>(variant, 0, m.tool_calls.size());
assert_equals(variant, std::string("CONTENT"), m.content);
assert_equals(variant, std::string("REASONING"), m.reasoning_content);
}
// variant: thinking not forced open + missing reasoning + no tool calls
{
- common_chat_syntax syntax = {
- /* .format = */ COMMON_CHAT_FORMAT_DEEPSEEK_V3_1,
- /* .reasoning_format = */ COMMON_REASONING_FORMAT_DEEPSEEK,
- /* .reasoning_in_content = */ false,
- /* .thinking_forced_open = */ false,
- /* .parse_tool_calls = */ true,
- };
+ common_chat_parser_params params;
+ params.format = COMMON_CHAT_FORMAT_DEEPSEEK_V3_1;
+ params.reasoning_format = COMMON_REASONING_FORMAT_DEEPSEEK;
+ params.reasoning_in_content = false;
+ params.thinking_forced_open = false;
+ params.parse_tool_calls = true;
const std::string variant("thinking_not_forced_open_missing_reasoning_no_tool_calls");
const std::string in = "CONTENT";
- auto m = common_chat_parse(in, false, syntax);
+ auto m = common_chat_parse(in, false, params);
assert_equals<std::size_t>(variant, 0, m.tool_calls.size());
assert_equals(variant, std::string("CONTENT"), m.content);
assert_equals(variant, std::string(""), m.reasoning_content);
}
if (expect_grammar_triggered) {
- common_chat_syntax syntax;
- syntax.format = data.params.format;
- syntax.reasoning_format = reasoning_format;
- const auto msg = common_chat_parse(data.delta, /* is_partial= */ false, syntax);
+ // TODO @ngxson : refactor common_chat_parse to avoid passing format/reasoning_format every time
+ common_chat_parser_params params;
+ params.format = data.params.format;
+ params.reasoning_format = reasoning_format;
+ const auto msg = common_chat_parse(data.delta, /* is_partial= */ false, params);
assert_msg_equals(test_message, msg, ignore_whitespace_differences);
}
}
common_chat_msg parse(const std::string & msg, bool is_partial) {
- return common_chat_peg_parse(arena_, msg, is_partial, /* syntax = */ {params_.format});
+ common_chat_parser_params parser_params;
+ parser_params.format = params_.format;
+ return common_chat_peg_parse(arena_, msg, is_partial, parser_params);
}
};
}
}
+// for compat; ref: https://github.com/ggml-org/llama.cpp/pull/18961
+struct test_parser_params {
+ common_chat_format format = COMMON_CHAT_FORMAT_CONTENT_ONLY;
+ common_reasoning_format reasoning_format = COMMON_REASONING_FORMAT_NONE;
+ bool reasoning_in_content = false;
+ bool thinking_forced_open = false;
+ bool parse_tool_calls = true;
+};
+
+static common_chat_msg test_chat_parse(const std::string & input, bool is_partial, const test_parser_params & syntax) {
+ common_chat_parser_params params;
+ params.format = syntax.format;
+ params.reasoning_format = syntax.reasoning_format;
+ params.reasoning_in_content = syntax.reasoning_in_content;
+ params.thinking_forced_open = syntax.thinking_forced_open;
+ params.parse_tool_calls = syntax.parse_tool_calls;
+ return common_chat_parse(input, is_partial, params);
+}
+
static void test_template_output_parsers() {
printf("[%s]\n", __func__);
}
assert_msg_equals(message_assist,
- common_chat_parse(
+ test_chat_parse(
"Hello, world!\nWhat's up?",
/* is_partial= */ false,
{COMMON_CHAT_FORMAT_COMMAND_R7B}));
assert_msg_equals(message_assist,
- common_chat_parse(
+ test_chat_parse(
"<|START_RESPONSE|>Hello, world!\nWhat's up?<|END_RESPONSE|>",
/* is_partial= */ false,
{COMMON_CHAT_FORMAT_COMMAND_R7B}));
assert_msg_equals(message_assist_thoughts,
- common_chat_parse(
+ test_chat_parse(
"<|START_THINKING|>I'm\nthinking<|END_THINKING|>"
"<|START_RESPONSE|>Hello, world!\nWhat's up?<|END_RESPONSE|>",
/* is_partial= */ false,
/* .reasoning_format = */ COMMON_REASONING_FORMAT_DEEPSEEK,
}));
assert_msg_equals(message_assist_thoughts_unparsed_deepseek,
- common_chat_parse(
+ test_chat_parse(
"<|START_THINKING|>I'm\nthinking<|END_THINKING|>"
"<|START_RESPONSE|>Hello, world!\nWhat's up?<|END_RESPONSE|>",
/* is_partial= */ false,
/* .thinking_forced_open = */ false,
}));
assert_msg_equals(message_assist_thoughts_unparsed_r7b,
- common_chat_parse(
+ test_chat_parse(
"<|START_THINKING|>I'm\nthinking<|END_THINKING|>"
"<|START_RESPONSE|>Hello, world!\nWhat's up?<|END_RESPONSE|>",
/* is_partial= */ false,
{COMMON_CHAT_FORMAT_COMMAND_R7B}));
assert_msg_equals(message_assist_thoughts,
- common_chat_parse(
+ test_chat_parse(
"<|START_THINKING|>I'm\nthinking<|END_THINKING|>"
"<|START_RESPONSE|>Hello, world!\nWhat's up?<|END_RESPONSE|>",
/* is_partial= */ false,
/* .reasoning_format = */ COMMON_REASONING_FORMAT_DEEPSEEK,
}));
assert_msg_equals(message_assist_thoughts_call_idx,
- common_chat_parse(
+ test_chat_parse(
"<|START_THINKING|>I'm\nthinking<|END_THINKING|>"
"<|START_ACTION|>[\n"
" {\"tool_call_id\": \"0\", \"tool_name\": \"special_function\", \"parameters\": {\"arg1\": 1}}\n"
/* .reasoning_format = */ COMMON_REASONING_FORMAT_DEEPSEEK,
}));
assert_msg_equals(message_assist_thoughts_no_content,
- common_chat_parse(
+ test_chat_parse(
"<|START_THINKING|>I'm\nthinking<|END_THINKING|>"
"<|START_ACTION|>[\n"
" {\"tool_call_id\": \"0\", \"tool_name\": \"special",
assert_equals(
simple_assist_msg("{ \"tool_call\" : { \"name\" : \"t"),
- common_chat_parse(
+ test_chat_parse(
"{ \"tool_call\" : { \"name\" : \"t",
/* is_partial= */ true,
{
}));
assert_equals(
message_assist_empty,
- common_chat_parse(
+ test_chat_parse(
"{ \"tool_call\" : { \"name\" : \"t",
/* is_partial= */ true,
{COMMON_CHAT_FORMAT_GENERIC}));
assert_equals(
simple_assist_msg("", "", "puppeteer_screenshot", "{\"name\":\"servethehome_homepage\","),
- common_chat_parse(
+ test_chat_parse(
R"({"tool_call": {"name": "puppeteer_screenshot", "arguments": {"name": "servethehome_homepage",)",
/* is_partial= */ true,
{COMMON_CHAT_FORMAT_GENERIC}));
assert_equals(
message_assist_call_empty_args,
- common_chat_parse(
+ test_chat_parse(
"{ \"tool_call\" : { \"name\" : \"special_function\"",
/* is_partial= */ true,
{COMMON_CHAT_FORMAT_GENERIC}));
assert_equals(
message_assist_call_cutoff_args,
- common_chat_parse(
+ test_chat_parse(
"{ \"tool_call\" : { \"name\" : \"special_function\", \"arguments\" : { \"arg",
/* is_partial= */ true,
{COMMON_CHAT_FORMAT_GENERIC}));
assert_msg_equals(message_assist,
- common_chat_parse(
+ test_chat_parse(
"{\n"
" \"response\": \"Hello, world!\\nWhat's up?\"\n"
"}",
{
assert_msg_equals(
simple_assist_msg("Réponse", "raisonnement"),
- common_chat_parse(
+ test_chat_parse(
message_assist_thoughts_unparsed_magistral.content,
/* is_partial= */ false,
{
// Test parsing
assert_msg_equals(
simple_assist_msg("", "", "python", ""),
- common_chat_parse(
+ test_chat_parse(
"```json\n"
"<function_call> { \"name\" : \"python\"",
/* is_partial= */ true,
{COMMON_CHAT_FORMAT_HERMES_2_PRO}));
assert_msg_equals(
simple_assist_msg("Let's call something\n"),
- common_chat_parse(
+ test_chat_parse(
"Let's call something\n"
"<tool_call>{\"name\"",
/* is_partial= */ true,
}));
assert_msg_equals(
simple_assist_msg("Let's call something\n"),
- common_chat_parse(
+ test_chat_parse(
"Let's call something\n"
"<tool_call>{\"name",
/* is_partial= */ true,
/* .reasoning_format = */ COMMON_REASONING_FORMAT_DEEPSEEK,
}));
assert_msg_equals(message_assist_call_thoughts,
- common_chat_parse(
+ test_chat_parse(
// QwQ-32B's template adds a trailing <think> if add_generation_prompt
"I'm\nthinking</think>\n"
"<tool_call>{\"name\": \"special_function\", \"arguments\": {\"arg1\": 1}}</tool_call>",
}));
assert_msg_equals(
message_assist_call,
- common_chat_parse(
+ test_chat_parse(
"<tool_call>\n"
"{\"name\": \"special_function\", \"arguments\": {\"arg1\": 1}}\n"
"</tool_call>",
/* is_partial= */ false,
{COMMON_CHAT_FORMAT_HERMES_2_PRO}));
assert_msg_equals(message_assist_call_content,
- common_chat_parse(
+ test_chat_parse(
"Hello, world!\nWhat's up?<tool_call>\n"
"{\"name\": \"special_function\", \"arguments\": {\"arg1\": 1}}\n"
"</tool_call>",
{COMMON_CHAT_FORMAT_HERMES_2_PRO}));
assert_msg_equals(
message_assist_call,
- common_chat_parse(
+ test_chat_parse(
"<function=special_function>{\"arg1\": 1}</function>",
/* is_partial= */ false,
{COMMON_CHAT_FORMAT_HERMES_2_PRO}));
assert_msg_equals(
message_assist_call,
- common_chat_parse(
+ test_chat_parse(
"<function name=\"special_function\">\n"
"{\"arg1\": 1}\n"
"</function>",
{COMMON_CHAT_FORMAT_HERMES_2_PRO}));
assert_msg_equals(
message_assist_call,
- common_chat_parse(
+ test_chat_parse(
"<tool>\n"
" {\"name\": \"special_function\", \"arguments\": {\"arg1\": 1}}\n"
"</tool>",
{COMMON_CHAT_FORMAT_HERMES_2_PRO}));
assert_msg_equals(
message_assist_call,
- common_chat_parse(
+ test_chat_parse(
"<tools>\n"
" {\"name\": \"special_function\", \"arguments\": {\"arg1\": 1}}\n"
"</tools>",
{COMMON_CHAT_FORMAT_HERMES_2_PRO}));
assert_msg_equals(
message_assist_call,
- common_chat_parse(
+ test_chat_parse(
"<response>\n"
" {\"name\": \"special_function\", \"arguments\": {\"arg1\": 1}}\n"
"</response>",
{COMMON_CHAT_FORMAT_HERMES_2_PRO}));
assert_msg_equals(
message_assist_call,
- common_chat_parse(
+ test_chat_parse(
"```xml\n"
"<response>\n"
" {\"name\": \"special_function\", \"arguments\": {\"arg1\": 1}}\n"
{COMMON_CHAT_FORMAT_HERMES_2_PRO}));
assert_msg_equals(
message_assist_call,
- common_chat_parse(
+ test_chat_parse(
"```xml\n"
" {\"name\": \"special_function\", \"arguments\": {\"arg1\": 1}}\n"
"```",
{COMMON_CHAT_FORMAT_HERMES_2_PRO}));
assert_msg_equals(
message_assist_call,
- common_chat_parse(
+ test_chat_parse(
"```\n"
" {\"name\": \"special_function\", \"arguments\": {\"arg1\": 1}}\n"
"```",
{COMMON_CHAT_FORMAT_HERMES_2_PRO}));
assert_msg_equals(
message_assist_call,
- common_chat_parse(
+ test_chat_parse(
"```\n"
"{\"name\": \"special_function\", \"arguments\": {\"arg1\": 1}}\n"
"```",
{COMMON_CHAT_FORMAT_HERMES_2_PRO}));
assert_msg_equals(
message_assist_call,
- common_chat_parse(
+ test_chat_parse(
"```json\n"
" {\"name\": \"special_function\", \"arguments\": {\"arg1\": 1}}\n"
"```",
{COMMON_CHAT_FORMAT_HERMES_2_PRO}));
assert_msg_equals(
message_assist_call,
- common_chat_parse(
+ test_chat_parse(
"```json\n"
"\n"
" <function_call> {\"name\": \"special_function\", \"arguments\": {\"arg1\": 1}} \n"
{COMMON_CHAT_FORMAT_HERMES_2_PRO}));
assert_msg_equals(
message_assist_call,
- common_chat_parse(
+ test_chat_parse(
"<json>\n"
" {\"name\": \"special_function\", \"arguments\": {\"arg1\": 1}}\n"
"</json>",
{COMMON_CHAT_FORMAT_HERMES_2_PRO}));
assert_msg_equals(
message_assist_call,
- common_chat_parse(
+ test_chat_parse(
"<xml>\n"
" {\n"
" \"name\": \"special_function\", \"arguments\": {\"arg1\": 1}\n"
{COMMON_CHAT_FORMAT_HERMES_2_PRO}));
assert_msg_equals(
message_assist_call,
- common_chat_parse(
+ test_chat_parse(
"<JSON>\n"
" {\"name\": \"special_function\", \"arguments\": {\"arg1\": 1}}\n"
"</JSON>",
{COMMON_CHAT_FORMAT_HERMES_2_PRO}));
assert_msg_equals(
message_assist_call,
- common_chat_parse(
+ test_chat_parse(
"{\"name\": \"special_function\", \"arguments\": {\"arg1\": 1}}",
/* is_partial= */ false,
{COMMON_CHAT_FORMAT_HERMES_2_PRO}));
assert_msg_equals(
message_assist_call,
- common_chat_parse(
+ test_chat_parse(
"{\n \"name\": \"special_function\", \"arguments\": {\"arg1\": 1}}",
/* is_partial= */ false,
{COMMON_CHAT_FORMAT_HERMES_2_PRO}));
assert_msg_equals(
message_assist_multiple_calls,
- common_chat_parse(
+ test_chat_parse(
"<tool_call>\n"
"{\"name\": \"special_function\", \"arguments\": {\"arg1\": 1}}\n"
"</tool_call>\n"
assert_msg_equals(
message_assist_multiple_calls,
- common_chat_parse(
+ test_chat_parse(
"<function=special_function>{\"arg1\": 1}</function>\n"
"<function=python>{\"code\":\"print('hello')\"}</function>",
/* is_partial= */ false,
"",
"special_function",
"{\"arg1\": 1}"),
- common_chat_parse(
+ test_chat_parse(
"This is not a tool call:\n"
"{\"name\": \"special_function\", \"arguments\": {\"arg1\": 1}}",
/* is_partial= */ false,
{COMMON_CHAT_FORMAT_HERMES_2_PRO}));
assert_msg_equals(message_assist,
- common_chat_parse(
+ test_chat_parse(
"Hello, world!\nWhat's up?",
/* is_partial= */ false,
{COMMON_CHAT_FORMAT_HERMES_2_PRO}));
assert_msg_equals(message_assist_thoughts_unparsed_deepseek,
- common_chat_parse(
+ test_chat_parse(
"<think>I'm\nthinking</think>Hello, world!\nWhat's up?",
/* is_partial= */ false,
{COMMON_CHAT_FORMAT_HERMES_2_PRO}));
// assert_msg_equals(message_assist_thoughts_unparsed_deepseek,
- // common_chat_parse(
+ // test_chat_parse(
// "I'm\nthinking</think>Hello, world!\nWhat's up?",
// COMMON_CHAT_FORMAT_HERMES_2_PRO));
assert_msg_equals(message_assist_thoughts,
- common_chat_parse(
+ test_chat_parse(
"<think>I'm\nthinking</think>Hello, world!\nWhat's up?",
/* is_partial= */ false,
{
/* .reasoning_format = */ COMMON_REASONING_FORMAT_DEEPSEEK,
}));
assert_msg_equals(message_assist_thoughts,
- common_chat_parse(
+ test_chat_parse(
"<think>I'm\nthinking</think>Hello, world!\nWhat's up?",
/* is_partial= */ true,
{
/* .reasoning_format = */ COMMON_REASONING_FORMAT_DEEPSEEK,
}));
assert_msg_equals(message_assist_thoughts_unparsed_md,
- common_chat_parse(
+ test_chat_parse(
"<think>I'm\nthinking</think>Hello, world!\nWhat's up?\n```json\n{}```",
/* is_partial= */ false,
{
/* .parse_tool_calls = */ false,
}));
assert_msg_equals(message_assist_thoughts_unparsed_md_partial,
- common_chat_parse(
+ test_chat_parse(
"<think>I'm\nthinking</think>Hello, world!\nWhat's up?\n```json\n{}```",
/* is_partial= */ true,
{
/* .thinking_forced_open = */ false,
}));
assert_msg_equals(message_assist_thoughts_unopened_unparsed,
- common_chat_parse(
+ test_chat_parse(
"I'm\nthinking</think>Hello, world!\nWhat's up?",
/* is_partial= */ false,
{
/* .reasoning_format = */ COMMON_REASONING_FORMAT_DEEPSEEK,
}));
assert_msg_equals(message_assist_thoughts,
- common_chat_parse(
+ test_chat_parse(
"I'm\nthinking</think>Hello, world!\nWhat's up?",
/* is_partial= */ false,
{
"</tool_call>");
assert_msg_equals(
simple_assist_msg("", /* reasoning_content= */ "<tool_call>nah uhg</tool_call>"),
- common_chat_parse(
+ test_chat_parse(
"<think><tool_call>nah uhg</tool_call>",
/* is_partial= */ false,
{
assert_equals(
message_assist_call,
- common_chat_parse(
+ test_chat_parse(
"{\"name\": \"special_function\", \"parameters\": {\"arg1\": 1}}",
/* is_partial= */ false,
{COMMON_CHAT_FORMAT_LLAMA_3_X}));
for (auto is_partial : { false, true }) {
assert_equals(
message_assist_call,
- common_chat_parse(
+ test_chat_parse(
"<function=special_function>{\"arg1\": 1}</function>",
is_partial,
{COMMON_CHAT_FORMAT_FUNCTIONARY_V3_1_LLAMA_3_1}));
assert_equals(
message_assist_call,
- common_chat_parse(
+ test_chat_parse(
"<function=special_function>{\"arg1\": 1}<",
/* is_partial= */ true,
{COMMON_CHAT_FORMAT_FUNCTIONARY_V3_1_LLAMA_3_1}));
"",
"special_function",
"{\"arg1\": 1}"),
- common_chat_parse(
+ test_chat_parse(
"all\n"
"Hello, world!\n"
"nono\n"
/* is_partial= */ false,
{COMMON_CHAT_FORMAT_FUNCTIONARY_V3_2}));
assert_msg_equals(message_assist_call_python_lines,
- common_chat_parse(
+ test_chat_parse(
"python\n"
"# This is a program:\n"
"print('hey')",
/* is_partial= */ false,
{COMMON_CHAT_FORMAT_FUNCTIONARY_V3_2}));
assert_msg_equals(message_assist_call_python_lines_unclosed,
- common_chat_parse(
+ test_chat_parse(
"python\n"
"# This is a program:\n"
"print('hey')",
/* is_partial= */ true,
{COMMON_CHAT_FORMAT_FUNCTIONARY_V3_2}));
assert_msg_equals(message_assist_call,
- common_chat_parse(
+ test_chat_parse(
"special_function\n"
"{\"arg1\": 1} \n ",
/* is_partial= */ false,
{COMMON_CHAT_FORMAT_FUNCTIONARY_V3_2}));
assert_msg_equals(message_assist,
- common_chat_parse(
+ test_chat_parse(
"all\n"
"Hello, world!\nWhat's up?",
/* is_partial= */ false,
test_templates(tmpls.get(), end_tokens, message_assist_thoughts, tools, "Hello, world!\nWhat's up?", /* expect_grammar_triggered= */ false);
assert_msg_equals(
simple_assist_msg("Hello, world!\nWhat's up?", "<think>I'm\nthinking"),
- common_chat_parse(
+ test_chat_parse(
"<think>I'm\nthinking</think>Hello, world!\nWhat's up?",
/* is_partial= */ false,
{
}));
assert_msg_equals(
simple_assist_msg("", "I need to remember the correct syntax. It starts with <|tool▁calls▁begin|> and ends with"),
- common_chat_parse(
+ test_chat_parse(
"I need to remember the correct syntax. It starts with <|tool▁calls▁begin|> and ends with",
/* is_partial= */ true,
{
/* .thinking_forced_open = */ true,
}));
assert_msg_equals(message_assist_thoughts,
- common_chat_parse(
+ test_chat_parse(
"<think>I'm\nthinking</think>Hello, world!\nWhat's up?",
/* is_partial= */ false,
{
/* .reasoning_format = */ COMMON_REASONING_FORMAT_DEEPSEEK,
}));
assert_msg_equals(message_assist_thoughts_unopened_unparsed,
- common_chat_parse(
+ test_chat_parse(
"I'm\nthinking</think>Hello, world!\nWhat's up?",
/* is_partial= */ false,
{
/* .reasoning_format = */ COMMON_REASONING_FORMAT_DEEPSEEK,
}));
assert_msg_equals(message_assist_thoughts,
- common_chat_parse(
+ test_chat_parse(
"I'm\nthinking</think>Hello, world!\nWhat's up?",
/* is_partial= */ false,
{
}));
assert_msg_equals(message_assist_thoughts,
// Latest template update (ast of 20250209) adds a trailing <think>\n if add_generation_prompt is true.
- common_chat_parse(
+ test_chat_parse(
"I'm\nthinking</think>Hello, world!\nWhat's up?",
/* is_partial= */ false,
{
test_templates(tmpls.get(), end_tokens, message_assist, tools, "Hello, world!\nWhat's up?", /* expect_grammar_triggered= */ false);
test_templates(tmpls.get(), end_tokens, message_assist_thoughts, tools, "Hello, world!\nWhat's up?", /* expect_grammar_triggered= */ false);
assert_msg_equals(message_assist_thoughts_unparsed_deepseek,
- common_chat_parse(
+ test_chat_parse(
"<think>I'm\nthinking</think>Hello, world!\nWhat's up?",
/* is_partial= */ false,
{COMMON_CHAT_FORMAT_DEEPSEEK_R1}));
assert_msg_equals(message_assist_thoughts,
- common_chat_parse(
+ test_chat_parse(
"<think>I'm\nthinking</think>Hello, world!\nWhat's up?",
/* is_partial= */ false,
{
/* .reasoning_format = */ COMMON_REASONING_FORMAT_DEEPSEEK,
}));
assert_msg_equals(message_assist_thoughts,
- common_chat_parse(
+ test_chat_parse(
"I'm\nthinking</think>Hello, world!\nWhat's up?",
/* is_partial= */ false,
{
}));
assert_msg_equals(message_assist_call_thoughts_unparsed,
- common_chat_parse(
+ test_chat_parse(
"<think>I'm\nthinking</think>\n\n"
"<|tool▁calls▁begin|><|tool▁call▁begin|>function<|tool▁sep|>special_function\n"
"```json\n"
/* is_partial= */ false,
{COMMON_CHAT_FORMAT_DEEPSEEK_R1}));
assert_msg_equals(message_assist_call,
- common_chat_parse(
+ test_chat_parse(
"<|tool▁calls|>function<|tool▁sep|>special_function\n"
"```json\n"
"{\"arg1\": 1}\n"
{COMMON_CHAT_FORMAT_DEEPSEEK_R1}));
assert_msg_equals(message_assist_call_thoughts,
- common_chat_parse(
+ test_chat_parse(
"<think>I'm\nthinking</think>\n\n"
"<|tool▁calls▁begin|><|tool▁call▁begin|>function<|tool▁sep|>special_function\n"
"```json\n"
// Test parsing regular content
assert_msg_equals(message_assist,
- common_chat_parse(
+ test_chat_parse(
"Hello, world!\nWhat's up?",
/* is_partial= */ false,
{COMMON_CHAT_FORMAT_GRANITE}));
assert_msg_equals(
message_assist,
- common_chat_parse(
+ test_chat_parse(
"Hello, world!\nWhat's up?",
/* is_partial= */ true,
{COMMON_CHAT_FORMAT_GRANITE}));
// Test parsing content with thinking
assert_msg_equals(message_assist_thoughts,
- common_chat_parse(
+ test_chat_parse(
"<think>I'm\nthinking</think>Hello, world!\nWhat's up?",
/* is_partial= */ false,
{
/* .reasoning_format = */ COMMON_REASONING_FORMAT_DEEPSEEK,
}));
assert_msg_equals(message_assist_thoughts_unparsed_deepseek,
- common_chat_parse(
+ test_chat_parse(
"<think>I'm\nthinking</think>Hello, world!\nWhat's up?",
/* is_partial= */ false,
{COMMON_CHAT_FORMAT_GRANITE}));
assert_msg_equals(message_assist_thoughts,
- common_chat_parse(
+ test_chat_parse(
"<think>I'm\nthinking</think><response>Hello, world!\nWhat's up?",
/* is_partial= */ true,
{
/* .reasoning_format = */ COMMON_REASONING_FORMAT_DEEPSEEK,
}));
assert_msg_equals(message_assist_thoughts,
- common_chat_parse(
+ test_chat_parse(
"<think>I'm\nthinking</think><response>Hello, world!\nWhat's up?</response>",
/* is_partial= */ false,
{
/* .reasoning_format = */ COMMON_REASONING_FORMAT_DEEPSEEK,
}));
assert_msg_equals(simple_assist_msg("<think>I'm\nthinking</think><response>Hello, world!\nWhat's up?</response>"),
- common_chat_parse(
+ test_chat_parse(
"<think>I'm\nthinking</think><response>Hello, world!\nWhat's up?</response>",
/* is_partial= */ false,
{COMMON_CHAT_FORMAT_GRANITE}));
assert_msg_equals(message_assist_empty,
- common_chat_parse(
+ test_chat_parse(
"<think",
/* is_partial= */ true,
{
/* .reasoning_format = */ COMMON_REASONING_FORMAT_DEEPSEEK,
}));
assert_msg_equals(message_assist_empty,
- common_chat_parse(
+ test_chat_parse(
"<think",
/* is_partial= */ true,
{COMMON_CHAT_FORMAT_GRANITE}));
assert_msg_equals(message_assist_thoughts_no_content,
- common_chat_parse(
+ test_chat_parse(
"<think>I'm\nthinking",
/* is_partial= */ true,
{
}));
assert_msg_equals(
message_assist_empty,
- common_chat_parse(
+ test_chat_parse(
"<think>I'm\nthinking</think><response",
/* is_partial= */ true,
{COMMON_CHAT_FORMAT_GRANITE}));
// Test parsing tool calls
assert_msg_equals(message_assist_call,
- common_chat_parse(
+ test_chat_parse(
"<|tool_call|>[{\"name\": \"special_function\", \"arguments\": {\"arg1\": 1}}]",
/* is_partial= */ false,
{COMMON_CHAT_FORMAT_GRANITE}));
assert_msg_equals(
message_assist_call_empty_args,
- common_chat_parse(
+ test_chat_parse(
"<|tool_call|>[{\"name\": \"special_function\"",
/* is_partial= */ true,
{COMMON_CHAT_FORMAT_GRANITE}));
assert_msg_equals(
message_assist_call_cutoff_args,
- common_chat_parse(
+ test_chat_parse(
"<|tool_call|>[{\"name\": \"special_function\", \"arguments\": {\"arg",
/* is_partial= */ true,
{COMMON_CHAT_FORMAT_GRANITE}));
assert_msg_equals(
message_assist_call_cutoff_args,
- common_chat_parse(
+ test_chat_parse(
"<|tool_call|>[{\"name\": \"special_function\", \"arguments\": {\"arg",
/* is_partial= */ true,
{
// Test parsing tool calls with thinking
assert_msg_equals(
message_assist_call_thoughts,
- common_chat_parse(
+ test_chat_parse(
"<think>I'm\nthinking</think><|tool_call|>[{\"name\": \"special_function\", \"arguments\": {\"arg1\": 1}, {",
/* is_partial= */ true,
{
assert_equals(COMMON_CHAT_FORMAT_GPT_OSS, common_chat_templates_apply(tmpls.get(), inputs_tools).format);
assert_msg_equals(simple_assist_msg("", "I'm\nthink"),
- common_chat_parse(
+ test_chat_parse(
"<|channel|>analysis<|message|>I'm\nthink",
/* is_partial= */ true,
{
/* .reasoning_format = */ COMMON_REASONING_FORMAT_AUTO,
}));
assert_msg_equals(simple_assist_msg("", "I'm\nthinking"),
- common_chat_parse(
+ test_chat_parse(
"<|channel|>analysis<|message|>I'm\nthinking<|end|>",
/* is_partial= */ true,
{
/* .reasoning_format = */ COMMON_REASONING_FORMAT_AUTO,
}));
assert_msg_equals(simple_assist_msg("Hello, world!\nWhat's up?", "I'm\nthinking"),
- common_chat_parse(
+ test_chat_parse(
"<|channel|>analysis<|message|>I'm\nthinking<|end|>"
"<|start|>assistant<|channel|>final<|message|>Hello, world!\nWhat's up?",
/* is_partial= */ false,
/* .reasoning_format = */ COMMON_REASONING_FORMAT_AUTO,
}));
assert_msg_equals(simple_assist_msg("", "I'm\nthinking", "special_function", "{\"arg1"),
- common_chat_parse(
+ test_chat_parse(
"<|channel|>analysis<|message|>I'm\nthinking<|end|>"
"<|start|>assistant<|channel|>commentary to=functions.special_function <|constrain|>json<|message|>{\"arg1",
/* is_partial= */ true,
/* .reasoning_format = */ COMMON_REASONING_FORMAT_AUTO,
}));
assert_msg_equals(simple_assist_msg("", "I'm\nthinking", "special_function", "{\"arg1"),
- common_chat_parse(
+ test_chat_parse(
"<|channel|>analysis<|message|>I'm\nthinking<|end|>"
"<|start|>assistant<|channel|>commentary to=functions.special_function<|message|>{\"arg1",
/* is_partial= */ true,
/* .reasoning_format = */ COMMON_REASONING_FORMAT_AUTO,
}));
assert_msg_equals(simple_assist_msg("", "I'm\nthinking", "special_function", "{\"arg1\": 1}"),
- common_chat_parse(
+ test_chat_parse(
"<|channel|>analysis<|message|>I'm\nthinking<|end|>"
"<|start|>assistant<|channel|>commentary to=functions.special_function <|constrain|>json<|message|>{\"arg1\": 1}",
/* is_partial= */ false,
/* .reasoning_format = */ COMMON_REASONING_FORMAT_AUTO,
}));
assert_msg_equals(simple_assist_msg("", "I'm\nthinking", "special_function", "{\"arg1\": 1}"),
- common_chat_parse(
+ test_chat_parse(
"<|channel|>analysis<|message|>I'm\nthinking<|end|>"
"<|start|>assistant<|channel|>analysis to=functions.special_function <|constrain|>json<|message|>{\"arg1\": 1}",
/* is_partial= */ false,
/* .reasoning_format = */ COMMON_REASONING_FORMAT_AUTO,
}));
assert_msg_equals(simple_assist_msg("Hello, world!\nWhat's up?", "I'm\nthinking"),
- common_chat_parse(
+ test_chat_parse(
"<|channel|>analysis<|message|>I'm\nthinking<|end|>"
"<|start|>assistant<|channel|>commentary<|message|>Hello, world!\nWhat's up?",
/* is_partial= */ true,
/* .reasoning_format = */ COMMON_REASONING_FORMAT_AUTO,
}));
assert_msg_equals(simple_assist_msg("Hello, world!\nWhat's up?", "I'm\nthinking", "special_function", "{\"arg1\": 1}"),
- common_chat_parse(
+ test_chat_parse(
"<|channel|>analysis<|message|>I'm\nthinking<|end|>"
"<|start|>assistant<|channel|>commentary<|message|>Hello, world!\nWhat's up?<|end|>"
"<|start|>assistant<|channel|>commentary to=functions.special_function <|constrain|>json<|message|>{\"arg1\": 1}",
// Test parse_tool_calls == false
assert_msg_equals(
simple_assist_msg("Hello, world!\nWhat's up?", "I'm\nthinking"),
- common_chat_parse(
+ test_chat_parse(
"<|channel|>analysis<|message|>I'm\nthinking<|end|>"
"<|start|>assistant<|channel|>final<|message|>Hello, world!\nWhat's up?",
/* is_partial= */ true,
}));
assert_msg_equals(
simple_assist_msg("", "I'm\nthinking"),
- common_chat_parse(
+ test_chat_parse(
"<|channel|>analysis<|message|>I'm\nthinking<|end|>"
"<|start|>assistant<|channel|>commentary to=functions.special_function<|message|>{\"arg1",
/* is_partial= */ true,
}));
assert_msg_equals(
simple_assist_msg("", "I'm\nthinking"),
- common_chat_parse(
+ test_chat_parse(
"<|channel|>analysis<|message|>I'm\nthinking<|end|>"
"<|start|>assistant<|channel|>commentary to=functions.special_function <|constrain|>json<|message|>{\"arg1\": 1}",
/* is_partial= */ false,
assert_msg_equals(
simple_assist_msg(
"<|channel|>analysis<|message|>I'm\nthinking<|end|>Hello, world!\nWhat's up?"),
- common_chat_parse(
+ test_chat_parse(
"<|channel|>analysis<|message|>I'm\nthinking<|end|>"
"<|start|>assistant<|channel|>final<|message|>Hello, world!\nWhat's up?",
/* is_partial= */ false,
assert_msg_equals(
simple_assist_msg(
"<|channel|>analysis<|message|>I'm\nthinking<|end|>Hello, world!\nWhat's up?"),
- common_chat_parse(
+ test_chat_parse(
"<|channel|>analysis<|message|>I'm\nthinking<|end|>"
"<|start|>assistant<|channel|>final<|message|>Hello, world!\nWhat's up?",
/* is_partial= */ false,
// Test tool calling in role header
assert_msg_equals(simple_assist_msg("", "", "special_function", "{\"arg1\": 1}"),
- common_chat_parse(
+ test_chat_parse(
" to=functions.special_function<|channel|>commentary <|constrain|>json<|message|>{\"arg1\": 1}",
/* is_partial= */ false,
{
/* .reasoning_format = */ COMMON_REASONING_FORMAT_AUTO,
}));
assert_msg_equals(simple_assist_msg("", "", "special_function", "{\"arg1\": 1}"),
- common_chat_parse(
+ test_chat_parse(
" to=functions.special_function<|channel|>analysis <|constrain|>json<|message|>{\"arg1\": 1}",
/* is_partial= */ false,
{
/* .reasoning_format = */ COMMON_REASONING_FORMAT_AUTO,
}));
assert_msg_equals(simple_assist_msg("", "I'm\nthinking", "special_function", "{\"arg1\": 1}"),
- common_chat_parse(
+ test_chat_parse(
"<|channel|>analysis<|message|>I'm\nthinking<|end|>"
"<|start|>assistant to=functions.special_function<|channel|>analysis <|constrain|>json<|message|>{\"arg1\": 1}",
/* is_partial= */ false,
// Test simple reasoning content
assert_msg_equals(
simple_assist_msg("Hello, world!", "I'm thinking about the answer"),
- common_chat_parse(
+ test_chat_parse(
"<seed:think>I'm thinking about the answer</seed:think>Hello, world!",
/* is_partial= */ false,
{
msg_budget_reflect.reasoning_content = "Token usage: 45/1000\nI should continue thinking to find the best solution.";
assert_msg_equals(
msg_budget_reflect,
- common_chat_parse(
+ test_chat_parse(
"<seed:think>Token usage: 45/1000\nI should continue thinking to find the best solution.</seed:think>"
"<seed:cot_budget_reflect>Token usage: 45/1000\nI should continue thinking to find the best solution.</seed:cot_budget_reflect>"
"I need to calculate this step by step.",
msg_tool_call.tool_calls.push_back({"calculate_sum", "{\"numbers\": [1, 2, 3]}", ""});
assert_msg_equals(
msg_tool_call,
- common_chat_parse(
+ test_chat_parse(
"<seed:tool_call>\n"
"<function=calculate_sum>\n"
"<parameter=numbers>[1, 2, 3]</parameter>\n"
msg_reasoning_tool.tool_calls.push_back({"calculate_sum", "{\"numbers\": [1, 2, 3]}", ""});
assert_msg_equals(
msg_reasoning_tool,
- common_chat_parse(
+ test_chat_parse(
"<seed:think>I need to calculate the sum of these numbers</seed:think>"
"<seed:tool_call>\n"
"<function=calculate_sum>\n"
std::size_t previousToolCalls = 0;
for (std::size_t i = std::string("<seed:tool_call>").length(); i < tool_msg.length() - 1; i++) {
auto partial = tool_msg.substr(0, i);
- auto partial_res = common_chat_parse(partial, true, { COMMON_CHAT_FORMAT_SEED_OSS, COMMON_REASONING_FORMAT_DEEPSEEK });
+ auto partial_res = test_chat_parse(partial, true, { COMMON_CHAT_FORMAT_SEED_OSS, COMMON_REASONING_FORMAT_DEEPSEEK });
if (partial_res.tool_calls.size() < previousToolCalls) {
throw std::runtime_error("Tool call size decreased on partial: " + partial + " from " + std::to_string(previousToolCalls) + " to " + std::to_string(partial_res.tool_calls.size()));
}
msg_multi_param.tool_calls.push_back({"process_data", "{\"input\": \"test\", \"format\": \"json\"}", ""});
assert_msg_equals(
msg_multi_param,
- common_chat_parse(
+ test_chat_parse(
"<seed:tool_call>\n"
"<function=process_data>\n"
"<parameter=input>test</parameter>\n"
// Test partial parsing for incomplete tool call - don't actually add the call until parsing parameters is done
assert_msg_equals(
simple_assist_msg("", "", "calculate_sum", "{\"numbers\":"),
- common_chat_parse(
+ test_chat_parse(
"<seed:tool_call>\n"
"<function=calculate_sum>\n"
"<parameter=numbers>[1,\n",
// Test incomplete reasoning tag
assert_msg_equals(
simple_assist_msg("", "I was thinking"),
- common_chat_parse(
+ test_chat_parse(
"<seed:think>I was thinking",
/* is_partial= */ true,
{
// Test content without reasoning
assert_msg_equals(
simple_assist_msg("This is a simple response without reasoning."),
- common_chat_parse(
+ test_chat_parse(
"This is a simple response without reasoning.",
/* is_partial= */ false,
{COMMON_CHAT_FORMAT_SEED_OSS}));
// Test parsing regular content
assert_msg_equals(message_assist,
- common_chat_parse(
+ test_chat_parse(
"Hello, world!\nWhat's up?",
/* is_partial= */ false,
{COMMON_CHAT_FORMAT_NEMOTRON_V2}));
// Test parsing content with thinking
assert_msg_equals(message_assist_thoughts,
- common_chat_parse(
+ test_chat_parse(
"<think>I'm\nthinking</think>Hello, world!\nWhat's up?",
/* is_partial= */ false,
{
// Test parsing tool calls
assert_msg_equals(message_assist_call,
- common_chat_parse(
+ test_chat_parse(
"<TOOLCALL>[{\"name\": \"special_function\", \"arguments\": {\"arg1\": 1}}]</TOOLCALL>",
/* is_partial= */ false,
{COMMON_CHAT_FORMAT_NEMOTRON_V2}));
// Test parsing tool calls with thinking
assert_msg_equals(message_assist_call_thoughts,
- common_chat_parse(
+ test_chat_parse(
"<think>I'm\nthinking</think><TOOLCALL>[{\"name\": \"special_function\", \"arguments\": {\"arg1\": 1}}]</TOOLCALL>",
/* is_partial= */ false,
{
// Test tool calls with extra content
assert_msg_equals(message_assist_call_content,
- common_chat_parse(
+ test_chat_parse(
"<TOOLCALL>[{\"name\": \"special_function\", \"arguments\": {\"arg1\": 1}}]</TOOLCALL>Hello, world!\nWhat's up?",
/* is_partial= */ false,
{COMMON_CHAT_FORMAT_NEMOTRON_V2}
// Test tool calls with extra content AND thinking
assert_msg_equals(message_assist_call_thoughts_content,
- common_chat_parse(
+ test_chat_parse(
"<think>I'm\nthinking</think><TOOLCALL>[{\"name\": \"special_function\", \"arguments\": {\"arg1\": 1}}]</TOOLCALL>Hello, world!\nWhat's up?",
/* is_partial= */ false,
{
test_templates(tmpls.get(), end_tokens, message_assist_thoughts, tools, "</think>Hello, world!\nWhat's up?", /* expect_grammar_triggered= */ false);
assert_msg_equals(
simple_assist_msg("Hello, world!\nWhat's up?", "I'm\nthinking"),
- common_chat_parse(
+ test_chat_parse(
"I'm\nthinking</think>Hello, world!\nWhat's up?",
/* is_partial= */ false,
{
// variant: thinking forced open, reasoning_format none
assert_msg_equals(
simple_assist_msg("REASONING</think>ok", ""),
- common_chat_parse(
+ test_chat_parse(
"REASONING</think>ok",
/* is_partial= */ false,
{
// variant: happy path for when it works as the model card says it should
assert_msg_equals(
simple_assist_msg("", "", "get_time", "{\"city\":\"Tokyo\"}"),
- common_chat_parse(
+ test_chat_parse(
"<|tool▁calls▁begin|><|tool▁call▁begin|>get_time<|tool▁sep|>{\"city\": \"Tokyo\"}<|tool▁call▁end|><|tool▁calls▁end|>",
/* is_partial= */ false,
{
// variant: simple + thinking open
assert_msg_equals(
simple_assist_msg("", "REASONING", "get_time", "{\"city\":\"Tokyo\"}"),
- common_chat_parse(
+ test_chat_parse(
"REASONING</think><|tool▁calls▁begin|><|tool▁call▁begin|>get_time<|tool▁sep|>{\"city\": \"Tokyo\"}<|tool▁call▁end|><|tool▁calls▁end|>",
/* is_partial= */ false,
{
message_assist_multiple_calls.tool_calls.push_back({"get_weather", "{\"city\":\"Paris\"}", ""});
assert_msg_equals(
message_assist_multiple_calls,
- common_chat_parse(
+ test_chat_parse(
"CONTENT<|tool▁calls▁begin|><|tool▁call▁begin|>get_time<|tool▁sep|>{\"city\": \"Paris\"}<|tool▁call▁end|><|tool▁call▁begin|>get_weather<|tool▁sep|>{\"city\": \"Paris\"}<|tool▁call▁end|><|tool▁calls▁end|>",
/* is_partial= */ false,
{
// variant: thinking forced open + tool call in reasoning content
assert_msg_equals(
simple_assist_msg("", "REASONING<|tool▁calls▁begin|><|tool▁call▁begin|>get_time2<|tool▁sep|>{\"city\": \"Tokyo2\"}<|tool▁call▁end|><|tool▁calls▁end|>REASONING", "get_time", "{\"city\":\"Tokyo\"}"),
- common_chat_parse(
+ test_chat_parse(
"REASONING<|tool▁calls▁begin|><|tool▁call▁begin|>get_time2<|tool▁sep|>{\"city\": \"Tokyo2\"}<|tool▁call▁end|><|tool▁calls▁end|>REASONING</think><|tool▁calls▁begin|><|tool▁call▁begin|>get_time<|tool▁sep|>{\"city\": \"Tokyo\"}<|tool▁call▁end|><|tool▁calls▁end|>",
/* is_partial= */ false,
{
// add the reasoning content as regular content and parse the tool calls.
assert_msg_equals(
simple_assist_msg("REASONING", "", "get_time", "{\"city\":\"Tokyo\"}"),
- common_chat_parse(
+ test_chat_parse(
"REASONING<|tool▁calls▁begin|><|tool▁call▁begin|>get_time<|tool▁sep|>{\"city\": \"Tokyo\"}<|tool▁call▁end|><|tool▁calls▁end|>",
/* is_partial= */ false,
{
// variant: thinking forced open + tool call in reasoning content + no closing think + partial
assert_msg_equals(
simple_assist_msg("", "REASONING<|tool▁calls▁begin|><|tool▁call▁begin|>get_time<|tool▁sep|>{\"city\": \"Tokyo\"}<|tool▁call▁end|><|tool▁calls▁end|>", "", ""),
- common_chat_parse(
+ test_chat_parse(
"REASONING<|tool▁calls▁begin|><|tool▁call▁begin|>get_time<|tool▁sep|>{\"city\": \"Tokyo\"}<|tool▁call▁end|><|tool▁calls▁end|>",
/* is_partial= */ true,
{
// variant: thinking not forced open + missing reasoning + no tool calls
assert_msg_equals(
simple_assist_msg("CONTENT", ""),
- common_chat_parse(
+ test_chat_parse(
"CONTENT",
/* is_partial= */ false,
{
// Test parsing regular content
assert_msg_equals(message_assist,
- common_chat_parse(
+ test_chat_parse(
"Hello, world!\nWhat's up?",
/* is_partial= */ false,
{COMMON_CHAT_FORMAT_APERTUS}));
// Test parsing content with thinking
assert_msg_equals(message_assist_thoughts,
- common_chat_parse(
+ test_chat_parse(
"<|inner_prefix|>I'm\nthinking<|inner_suffix|>Hello, world!\nWhat's up?",
/* is_partial= */ false,
{
// Test parsing tool calls
assert_msg_equals(message_assist_call,
- common_chat_parse(
+ test_chat_parse(
"<|tools_prefix|>[{\"special_function\": {\"arg1\": 1}}]<|tools_suffix|>",
/* is_partial= */ false,
{COMMON_CHAT_FORMAT_APERTUS}));
// Test parsing tool calls with thinking
assert_msg_equals(message_assist_call_thoughts,
- common_chat_parse(
+ test_chat_parse(
"<|inner_prefix|>I'm\nthinking<|inner_suffix|><|tools_prefix|>[{\"special_function\": {\"arg1\": 1}}]<|tools_suffix|>",
/* is_partial= */ false,
{
// Test tool calls with extra content
assert_msg_equals(message_assist_call_content,
- common_chat_parse(
+ test_chat_parse(
"<|tools_prefix|>[{\"special_function\": {\"arg1\": 1}}]<|tools_suffix|>Hello, world!\nWhat's up?",
/* is_partial= */ false,
{COMMON_CHAT_FORMAT_APERTUS}
// Test tool calls with extra content AND thinking
assert_msg_equals(message_assist_call_thoughts_content,
- common_chat_parse(
+ test_chat_parse(
"<|inner_prefix|>I'm\nthinking<|inner_suffix|><|tools_prefix|>[{\"special_function\": {\"arg1\": 1}}]<|tools_suffix|>Hello, world!\nWhat's up?",
/* is_partial= */ false,
{
// Test parsing regular content
assert_msg_equals(message_assist,
- common_chat_parse(
+ test_chat_parse(
"Hello, world!\nWhat's up?",
/* is_partial= */ false,
{COMMON_CHAT_FORMAT_LFM2_WITH_JSON_TOOLS}));
msg_single_tool_call.tool_calls.push_back({"special_function", "{\"arg1\":1}", ""});
assert_msg_equals(
msg_single_tool_call,
- common_chat_parse(
+ test_chat_parse(
"<|tool_call_start|>[{\"name\": \"special_function\", \"arguments\": {\"arg1\": 1}}]<|tool_call_end|>",
/* is_partial= */ false,
{COMMON_CHAT_FORMAT_LFM2_WITH_JSON_TOOLS}));
msg_tool_call_string.tool_calls.push_back({"get_weather", "{\"location\":\"Paris\"}", ""});
assert_msg_equals(
msg_tool_call_string,
- common_chat_parse(
+ test_chat_parse(
"<|tool_call_start|>[{\"name\": \"get_weather\", \"arguments\": {\"location\": \"Paris\"}}]<|tool_call_end|>",
/* is_partial= */ false,
{COMMON_CHAT_FORMAT_LFM2_WITH_JSON_TOOLS}));
msg_multi_args.tool_calls.push_back({"calculate", "{\"x\":10,\"y\":20,\"operation\":\"add\"}", ""});
assert_msg_equals(
msg_multi_args,
- common_chat_parse(
+ test_chat_parse(
"<|tool_call_start|>[{\"name\": \"calculate\", \"arguments\": {\"x\": 10, \"y\": 20, \"operation\": \"add\"}}]<|tool_call_end|>",
/* is_partial= */ false,
{COMMON_CHAT_FORMAT_LFM2_WITH_JSON_TOOLS}));
msg_multiple_tools.tool_calls.push_back({"get_time", "{\"timezone\":\"UTC\"}", ""});
assert_msg_equals(
msg_multiple_tools,
- common_chat_parse(
+ test_chat_parse(
"<|tool_call_start|>[{\"name\": \"get_weather\", \"arguments\": {\"location\": \"Paris\"}}, {\"name\": \"get_time\", \"arguments\": {\"timezone\": \"UTC\"}}]<|tool_call_end|>",
/* is_partial= */ false,
{COMMON_CHAT_FORMAT_LFM2_WITH_JSON_TOOLS}));
msg_content_before_tool.tool_calls.push_back({"get_weather", "{\"location\":\"Paris\"}", ""});
assert_msg_equals(
msg_content_before_tool,
- common_chat_parse(
+ test_chat_parse(
"Let me check the weather for you.<|tool_call_start|>[{\"name\": \"get_weather\", \"arguments\": {\"location\": \"Paris\"}}]<|tool_call_end|>",
/* is_partial= */ false,
{COMMON_CHAT_FORMAT_LFM2_WITH_JSON_TOOLS}));
msg_content_after_tool.tool_calls.push_back({"get_weather", "{\"location\":\"Paris\"}", ""});
assert_msg_equals(
msg_content_after_tool,
- common_chat_parse(
+ test_chat_parse(
"<|tool_call_start|>[{\"name\": \"get_weather\", \"arguments\": {\"location\": \"Paris\"}}]<|tool_call_end|>Here's the result.",
/* is_partial= */ false,
{COMMON_CHAT_FORMAT_LFM2_WITH_JSON_TOOLS}));
msg_tool_call_newlines.tool_calls.push_back({"get_current_time", "{\"location\":\"Paris\"}", ""});
assert_msg_equals(
msg_tool_call_newlines,
- common_chat_parse(
+ test_chat_parse(
"<|tool_call_start|>[{\n \"name\": \"get_current_time\",\n \"arguments\": {\n \"location\": \"Paris\"\n }\n}]<|tool_call_end|>",
/* is_partial= */ false,
{COMMON_CHAT_FORMAT_LFM2_WITH_JSON_TOOLS}));
// Test parsing regular content
assert_msg_equals(message_assist,
- common_chat_parse(
+ test_chat_parse(
"Hello, world!\nWhat's up?",
/* is_partial= */ false,
{COMMON_CHAT_FORMAT_MINIMAX_M2}));
// Test parsing content with thinking
assert_msg_equals(message_assist_thoughts,
- common_chat_parse(
+ test_chat_parse(
"<think>I'm\nthinking</think>Hello, world!\nWhat's up?",
/* is_partial= */ false,
{
// Test parsing tool calls
assert_msg_equals(message_assist_call,
- common_chat_parse(
+ test_chat_parse(
"<minimax:tool_call><invoke name=\"special_function\"><parameter name=\"arg1\">1</parameter></invoke></minimax:tool_call>",
/* is_partial= */ false,
{COMMON_CHAT_FORMAT_MINIMAX_M2}));
// Test parsing tool calls with thinking
assert_msg_equals(message_assist_call_thoughts,
- common_chat_parse(
+ test_chat_parse(
"<think>I'm\nthinking</think><minimax:tool_call><invoke name=\"special_function\"><parameter name=\"arg1\">1</parameter></invoke></minimax:tool_call>",
/* is_partial= */ false,
{
// Test tool calls with extra content
assert_msg_equals(message_assist_call_content,
- common_chat_parse(
+ test_chat_parse(
"<minimax:tool_call><invoke name=\"special_function\"><parameter name=\"arg1\">1</parameter></invoke></minimax:tool_call>Hello, world!\nWhat's up?",
/* is_partial= */ false,
{COMMON_CHAT_FORMAT_MINIMAX_M2}
// Test tool calls with extra content AND thinking
assert_msg_equals(message_assist_call_thoughts_content,
- common_chat_parse(
+ test_chat_parse(
"<think>I'm\nthinking</think><minimax:tool_call><invoke name=\"special_function\"><parameter name=\"arg1\">1</parameter></invoke></minimax:tool_call>Hello, world!\nWhat's up?",
/* is_partial= */ false,
{
// Test streaming
test_parser_with_streaming(message_assist_call_thoughts_content,
"<think>I'm\nthinking\n</think>Hello, world!\nWhat's up?\n<minimax:tool_call><invoke name=\"special_function\"><parameter name=\"arg1\">1</parameter></invoke></minimax:tool_call>",
- [&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {
+ [&](const std::string &msg) { return test_chat_parse(msg, /* is_partial= */ true, {
/* .format = */ COMMON_CHAT_FORMAT_MINIMAX_M2,
/* .reasoning_format = */ COMMON_REASONING_FORMAT_DEEPSEEK
}); });
test_parser_with_streaming(message_assist_call_thoughts_unparsed,
"<think>I'm\nthinking</think>\n\n<minimax:tool_call><invoke name=\"special_function\"><parameter name=\"arg1\">1</parameter></invoke></minimax:tool_call>",
- [&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {
+ [&](const std::string &msg) { return test_chat_parse(msg, /* is_partial= */ true, {
/* .format = */ COMMON_CHAT_FORMAT_MINIMAX_M2,
/* .reasoning_format = */ COMMON_REASONING_FORMAT_NONE
}); });
test_parser_with_streaming(message_assist_call_thoughts_content,
"<think>I'm\nthinking\n</think>\n\nHello, world!\nWhat's up?\n\n<minimax:tool_call>\n<invoke name=\"special_function\">\n<parameter name=\"arg1\">1</parameter>\n</invoke>\n</minimax:tool_call>\n",
- [&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {
+ [&](const std::string &msg) { return test_chat_parse(msg, /* is_partial= */ true, {
/* .format = */ COMMON_CHAT_FORMAT_MINIMAX_M2,
/* .reasoning_format = */ COMMON_REASONING_FORMAT_DEEPSEEK
}); });
test_parser_with_streaming(message_assist_call_withopt,
"<minimax:tool_call>\n<invoke name=\"special_function_with_opt\">\n<parameter name=\"arg1\">1</parameter>\n<parameter name=\"arg2\">2</parameter>\n</invoke>\n</minimax:tool_call>",
- [&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {
+ [&](const std::string &msg) { return test_chat_parse(msg, /* is_partial= */ true, {
/* .format = */ COMMON_CHAT_FORMAT_MINIMAX_M2,
/* .reasoning_format = */ COMMON_REASONING_FORMAT_NONE
}); });
// Test parsing regular content
assert_msg_equals(message_assist,
- common_chat_parse(
+ test_chat_parse(
"Hello, world!\nWhat's up?",
/* is_partial= */ false,
{COMMON_CHAT_FORMAT_GLM_4_5}));
// Test parsing content with thinking
assert_msg_equals(message_assist_thoughts,
- common_chat_parse(
+ test_chat_parse(
"\n<think>I'm\nthinking</think>\nHello, world!\nWhat's up?",
/* is_partial= */ false,
{
// Test parsing tool calls
assert_msg_equals(message_assist_call,
- common_chat_parse(
+ test_chat_parse(
"\n<tool_call>special_function\n<arg_key>arg1</arg_key>\n<arg_value>1</arg_value>\n</tool_call>",
/* is_partial= */ false,
{COMMON_CHAT_FORMAT_GLM_4_5}), true);
// Test parsing tool calls with thinking
assert_msg_equals(message_assist_call_thoughts,
- common_chat_parse(
+ test_chat_parse(
"\n<think>I'm\nthinking</think>\n<tool_call>special_function\n<arg_key>arg1</arg_key>\n<arg_value>1</arg_value>\n</tool_call>",
/* is_partial= */ false,
{
// Test tool calls with extra content
assert_msg_equals(message_assist_call_content,
- common_chat_parse(
+ test_chat_parse(
"\n<tool_call>special_function\n<arg_key>arg1</arg_key>\n<arg_value>1</arg_value>\n</tool_call>Hello, world!\nWhat's up?",
/* is_partial= */ false,
{COMMON_CHAT_FORMAT_GLM_4_5}
// Test tool calls with extra content AND thinking
assert_msg_equals(message_assist_call_thoughts_content,
- common_chat_parse(
+ test_chat_parse(
"\n<think>I'm\nthinking</think>Hello, world!\nWhat's up?\n<tool_call>special_function\n<arg_key>arg1</arg_key>\n<arg_value>1</arg_value>\n</tool_call>",
/* is_partial= */ false,
{
// Test streaming
test_parser_with_streaming(message_assist_call_thoughts_content,
"\n<think>I'm\nthinking</think>Hello, world!\nWhat's up?\n<tool_call>special_function\n<arg_key>arg1</arg_key>\n<arg_value>1</arg_value>\n</tool_call>",
- [&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {
+ [&](const std::string &msg) { return test_chat_parse(msg, /* is_partial= */ true, {
/* .format = */ COMMON_CHAT_FORMAT_GLM_4_5,
/* .reasoning_format = */ COMMON_REASONING_FORMAT_DEEPSEEK
}); });
test_parser_with_streaming(message_assist_call_thoughts_unparsed,
"\n<think>I'm\nthinking</think>\n\n<tool_call>special_function\n<arg_key>arg1</arg_key>\n<arg_value>1</arg_value>\n</tool_call>",
- [&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {
+ [&](const std::string &msg) { return test_chat_parse(msg, /* is_partial= */ true, {
/* .format = */ COMMON_CHAT_FORMAT_GLM_4_5,
/* .reasoning_format = */ COMMON_REASONING_FORMAT_NONE
}); });
test_parser_with_streaming(message_assist_call_withopt,
"\n<think></think>\n<tool_call>special_function_with_opt\n<arg_key>arg1</arg_key>\n<arg_value>1</arg_value>\n<arg_key>arg2</arg_key>\n<arg_value>2</arg_value>\n</tool_call>\n",
- [&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {
+ [&](const std::string &msg) { return test_chat_parse(msg, /* is_partial= */ true, {
/* .format = */ COMMON_CHAT_FORMAT_GLM_4_5,
/* .reasoning_format = */ COMMON_REASONING_FORMAT_DEEPSEEK
}); });
"<arg_key>score</arg_key>\n"
"<arg_value>95.5</arg_value>\n"
"</tool_call>",
- [&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_GLM_4_5}); });
+ [&](const std::string &msg) { return test_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_GLM_4_5}); });
test_parser_with_streaming(
simple_assist_msg("", "", "web_search", "{\"query\":\"\\\"From Zero\\\" Linkin Park album tracklist complete songs\",\"limit\":3,\"type\":\"text\"}"),
"<tool_call>web_search\n"
"<arg_key>type</arg_key>\n"
"<arg_value>text</arg_value>\n"
"</tool_call>",
- [&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_GLM_4_5}); });
+ [&](const std::string &msg) { return test_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_GLM_4_5}); });
// Test interleaved thinking
test_parser_with_streaming(simple_assist_msg("Hello, world!\n\nWhat's up?", "I'm\nthinkingThinking2", "special_function", "{\"arg1\": 1}"),
"\n<think>I'm\nthinking</think>Hello, world!\n<think>Thinking2</think>What's up?\n<tool_call>special_function\n<arg_key>arg1</arg_key>\n<arg_value>1</arg_value>\n</tool_call>",
- [&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {
+ [&](const std::string &msg) { return test_chat_parse(msg, /* is_partial= */ true, {
/* .format = */ COMMON_CHAT_FORMAT_GLM_4_5,
/* .reasoning_format = */ COMMON_REASONING_FORMAT_DEEPSEEK
}); });
test_parser_with_streaming(simple_assist_msg("\n<think>I'm\nthinking</think>Hello, world!\n<think>Thinking2</think>What's up?", "", "special_function", "{\"arg1\": 1}"),
"\n<think>I'm\nthinking</think>Hello, world!\n<think>Thinking2</think>What's up?\n<tool_call>special_function\n<arg_key>arg1</arg_key>\n<arg_value>1</arg_value>\n</tool_call>",
- [&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {
+ [&](const std::string &msg) { return test_chat_parse(msg, /* is_partial= */ true, {
/* .format = */ COMMON_CHAT_FORMAT_GLM_4_5,
/* .reasoning_format = */ COMMON_REASONING_FORMAT_NONE
}); });
// Test parsing regular content
assert_msg_equals(message_assist,
- common_chat_parse(
+ test_chat_parse(
"Hello, world!\nWhat's up?",
/* is_partial= */ false,
{COMMON_CHAT_FORMAT_KIMI_K2}));
// Test parsing content with thinking
assert_msg_equals(message_assist_thoughts,
- common_chat_parse(
+ test_chat_parse(
"<think>I'm\nthinking</think>Hello, world!\nWhat's up?",
/* is_partial= */ false,
{
// Test parsing tool calls
assert_msg_equals(message_assist_call,
- common_chat_parse(
+ test_chat_parse(
"<|tool_calls_section_begin|><|tool_call_begin|>functions.special_function:0<|tool_call_argument_begin|>{\"arg1\": 1}<|tool_call_end|><|tool_calls_section_end|>",
/* is_partial= */ false,
{COMMON_CHAT_FORMAT_KIMI_K2}));
// Test parsing tool calls with thinking
assert_msg_equals(message_assist_call_thoughts,
- common_chat_parse(
+ test_chat_parse(
"<think>I'm\nthinking</think><|tool_calls_section_begin|><|tool_call_begin|>functions.special_function:0<|tool_call_argument_begin|>{\"arg1\": 1}<|tool_call_end|><|tool_calls_section_end|>",
/* is_partial= */ false,
{
// Test tool calls with extra content
assert_msg_equals(message_assist_call_content,
- common_chat_parse(
+ test_chat_parse(
"<|tool_calls_section_begin|><|tool_call_begin|>functions.special_function:0<|tool_call_argument_begin|>{\"arg1\": 1}<|tool_call_end|><|tool_calls_section_end|>Hello, world!\nWhat's up?",
/* is_partial= */ false,
{COMMON_CHAT_FORMAT_KIMI_K2}
// Test tool calls with extra content AND thinking
assert_msg_equals(message_assist_call_thoughts_content,
- common_chat_parse(
+ test_chat_parse(
"<think>I'm\nthinking</think><|tool_calls_section_begin|><|tool_call_begin|>functions.special_function:0<|tool_call_argument_begin|>{\"arg1\": 1}<|tool_call_end|><|tool_calls_section_end|>Hello, world!\nWhat's up?",
/* is_partial= */ false,
{
// Test streaming
test_parser_with_streaming(message_assist_call_thoughts_content,
"<think>I'm\nthinking\n</think>Hello, world!\nWhat's up?\n<|tool_calls_section_begin|><|tool_call_begin|>functions.special_function:0<|tool_call_argument_begin|>{\"arg1\": 1}<|tool_call_end|><|tool_calls_section_end|>",
- [&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {
+ [&](const std::string &msg) { return test_chat_parse(msg, /* is_partial= */ true, {
/* .format = */ COMMON_CHAT_FORMAT_KIMI_K2,
/* .reasoning_format = */ COMMON_REASONING_FORMAT_DEEPSEEK
}); });
test_parser_with_streaming(message_assist_call_thoughts_unparsed,
"<think>I'm\nthinking</think>\n\n<|tool_calls_section_begin|><|tool_call_begin|>functions.special_function:0<|tool_call_argument_begin|>{\"arg1\": 1}<|tool_call_end|><|tool_calls_section_end|>",
- [&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {
+ [&](const std::string &msg) { return test_chat_parse(msg, /* is_partial= */ true, {
/* .format = */ COMMON_CHAT_FORMAT_KIMI_K2,
/* .reasoning_format = */ COMMON_REASONING_FORMAT_NONE
}); });
test_parser_with_streaming(message_assist_call_thoughts_content,
"<think>I'm\nthinking\n</think>\n\nHello, world!\nWhat's up?\n\n<|tool_calls_section_begin|><|tool_call_begin|>functions.special_function:0<|tool_call_argument_begin|>{\"arg1\": 1}<|tool_call_end|><|tool_calls_section_end|>\n",
- [&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {
+ [&](const std::string &msg) { return test_chat_parse(msg, /* is_partial= */ true, {
/* .format = */ COMMON_CHAT_FORMAT_KIMI_K2,
/* .reasoning_format = */ COMMON_REASONING_FORMAT_DEEPSEEK
}); });
test_parser_with_streaming(message_assist_call_withopt,
"<|tool_calls_section_begin|><|tool_call_begin|>functions.special_function_with_opt:0<|tool_call_argument_begin|>{\"arg1\": 1, \"arg2\": 2}<|tool_call_end|><|tool_calls_section_end|>",
- [&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {
+ [&](const std::string &msg) { return test_chat_parse(msg, /* is_partial= */ true, {
/* .format = */ COMMON_CHAT_FORMAT_KIMI_K2,
/* .reasoning_format = */ COMMON_REASONING_FORMAT_NONE
}); });
test_parser_with_streaming(simple_assist_msg("Hello, world!\nWhat's up?", "I'm\nthinking", "special_function", "{\"arg1\": \"123456\"}"),
"<think>I'm\nthinking</think>Hello, world!\nWhat's up?\n<|tool_calls_section_begin|><|tool_call_begin|>functions.special_function:0<|tool_call_argument_begin|>{\"arg1\": \"123456\"}<|tool_call_end|><|tool_calls_section_end|>",
- [&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {
+ [&](const std::string &msg) { return test_chat_parse(msg, /* is_partial= */ true, {
/* .format = */ COMMON_CHAT_FORMAT_KIMI_K2,
/* .reasoning_format = */ COMMON_REASONING_FORMAT_DEEPSEEK
}); });
test_parser_with_streaming(simple_assist_msg("Hello, world!\nWhat's up?", "I'm\nthinking", "special_function", "{\"arg1\": [1, 2, \"345\", 6]}"),
"<think>I'm\nthinking</think>Hello, world!\nWhat's up?\n<|tool_calls_section_begin|><|tool_call_begin|>functions.special_function:0<|tool_call_argument_begin|>{\"arg1\": [1, 2, \"345\", 6]}<|tool_call_end|><|tool_calls_section_end|>",
- [&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {
+ [&](const std::string &msg) { return test_chat_parse(msg, /* is_partial= */ true, {
/* .format = */ COMMON_CHAT_FORMAT_KIMI_K2,
/* .reasoning_format = */ COMMON_REASONING_FORMAT_DEEPSEEK
}); });
test_parser_with_streaming(simple_assist_msg("Hello, world!\nWhat's up?", "I'm\nthinking", "special_function", "{\"arg1\": {\"12\": 34, \"5\": [67, 8], \"9\": \"10\"}}"),
"<think>I'm\nthinking</think>Hello, world!\nWhat's up?\n<|tool_calls_section_begin|><|tool_call_begin|>functions.special_function:0<|tool_call_argument_begin|>{\"arg1\": {\"12\": 34, \"5\": [67, 8], \"9\": \"10\"}}<|tool_call_end|><|tool_calls_section_end|>",
- [&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {
+ [&](const std::string &msg) { return test_chat_parse(msg, /* is_partial= */ true, {
/* .format = */ COMMON_CHAT_FORMAT_KIMI_K2,
/* .reasoning_format = */ COMMON_REASONING_FORMAT_DEEPSEEK
}); });
"<|tool_calls_section_begin|><|tool_call_begin|>functions.complex_function:0<|tool_call_argument_begin|>"
"{\"name\": \"John Doe\", \"age\": 30, \"active\": true, \"score\": 95.5}"
"<|tool_call_end|><|tool_calls_section_end|>",
- [&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_KIMI_K2}); });
+ [&](const std::string &msg) { return test_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_KIMI_K2}); });
test_parser_with_streaming(
simple_assist_msg("", "", "web_search", "{\"query\":\"\\\"From Zero\\\" Linkin Park album tracklist complete songs\",\"limit\":3,\"type\":\"text\"}"),
"<|tool_calls_section_begin|><|tool_call_begin|>functions.web_search:0<|tool_call_argument_begin|>"
"{\"query\":\"\\\"From Zero\\\" Linkin Park album tracklist complete songs\",\"limit\":3,\"type\":\"text\"}"
"<|tool_call_end|><|tool_calls_section_end|>",
- [&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_KIMI_K2}); });
+ [&](const std::string &msg) { return test_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_KIMI_K2}); });
test_parser_with_streaming(
simple_assist_msg("", "", "read_file", "{\"args\": [{\"path\": \"src/providers/ThemeProvider.tsx\"}, {\"path\": \"src/components/Header.tsx\"}, {\"path\": \"src/components/ThemeToggle.tsx\"}, {\"path\": \"src/app/globals.css\"}, {\"path\": \"src/app/layout.tsx\"}]}"),
"<|tool_calls_section_begin|><|tool_call_begin|>functions.read_file:0<|tool_call_argument_begin|>"
"{\"args\": [{\"path\": \"src/providers/ThemeProvider.tsx\"}, {\"path\": \"src/components/Header.tsx\"}, {\"path\": \"src/components/ThemeToggle.tsx\"}, {\"path\": \"src/app/globals.css\"}, {\"path\": \"src/app/layout.tsx\"}]}"
"<|tool_call_end|><|tool_calls_section_end|>",
- [&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_KIMI_K2}); });
+ [&](const std::string &msg) { return test_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_KIMI_K2}); });
test_parser_with_streaming(
simple_assist_msg(
"Let me start by examining the relevant files to understand the current implementation.", "",
"<|tool_calls_section_begin|><|tool_call_begin|>functions.read_file:0<|tool_call_argument_begin|>"
"{\"files\":[{\"path\":\"src/app/Partners.tsx\",\"line_ranges\":[\"1-100\"]}]}"
"<|tool_call_end|><|tool_calls_section_end|>",
- [&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_KIMI_K2}); });
+ [&](const std::string &msg) { return test_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_KIMI_K2}); });
auto multi_tool_msg = simple_assist_msg("Let me call multiple tools.", "I'm thinking.");
multi_tool_msg.tool_calls.push_back({ "read_file", "{\"files\": [{\"path\": \"src/app/Partners.tsx\", \"line_ranges\": [\"1-100\"]}]}", "" });
multi_tool_msg.tool_calls.push_back({ "web_search", "{\"query\":\"\\\"From Zero\\\" Linkin Park album tracklist complete songs\",\"limit\":3,\"type\":\"text\"}", "" });
"{\"message\":\"Hello! 👋 🌟 🚀 Testing emojis: 😀😃😄😁 and symbols: ∑∏∆∇\"}"
"<|tool_call_end|>"
"<|tool_calls_section_end|>",
- [&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {
+ [&](const std::string &msg) { return test_chat_parse(msg, /* is_partial= */ true, {
COMMON_CHAT_FORMAT_KIMI_K2,
COMMON_REASONING_FORMAT_DEEPSEEK
}); });
"<think>I'm thinking<|tool_calls_section_begin|><|tool_call_begin|>functions.complex_function_in_think:0<|tool_call_argument_begin|>"
"{\"name\": \"John Doe\", \"age\": 30, \"active\": true, \"score\": 95.5}"
"<|tool_call_end|><|tool_calls_section_end|>",
- [&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {
+ [&](const std::string &msg) { return test_chat_parse(msg, /* is_partial= */ true, {
COMMON_CHAT_FORMAT_KIMI_K2,
COMMON_REASONING_FORMAT_DEEPSEEK
}); });
"<think>I'm thinking<|tool_calls_section_begin|><|tool_call_begin|>functions.complex_function_in_think:0<|tool_call_argument_begin|>"
"{\"name\": \"John Doe\", \"age\": 30, \"active\": true, \"score\": 95.5}"
"<|tool_call_end|><|tool_calls_section_end|>I'm still thinking</think>Hello",
- [&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {
+ [&](const std::string &msg) { return test_chat_parse(msg, /* is_partial= */ true, {
COMMON_CHAT_FORMAT_KIMI_K2,
COMMON_REASONING_FORMAT_DEEPSEEK
}); });
// Basic XML tool call parsing
assert_msg_equals(
message_assist_call,
- common_chat_parse(
+ test_chat_parse(
"<tool_call>\n"
" <function=special_function>\n"
" <parameter=arg1>\n"
" </parameter>\n"
" </function>\n"
"</tool_call>",
- [&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
+ [&](const std::string &msg) { return test_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
// Special characters and Unicode
common_chat_msg expected_special_chars;
" </parameter>\n"
" </function>\n"
"</tool_call>",
- [&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
+ [&](const std::string &msg) { return test_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
// Multiline content with newlines and indentation
common_chat_msg expected_multiline;
" </parameter>\n"
" </function>\n"
"</tool_call>",
- [&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
+ [&](const std::string &msg) { return test_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
// JSON object as parameter value
common_chat_msg expected_json_param;
" </parameter>\n"
" </function>\n"
"</tool_call>",
- [&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
+ [&](const std::string &msg) { return test_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
// Array as parameter value
common_chat_msg expected_array_param;
" </parameter>\n"
" </function>\n"
"</tool_call>",
- [&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
+ [&](const std::string &msg) { return test_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
// Empty parameter
common_chat_msg expected_empty_param;
" </parameter>\n"
" </function>\n"
"</tool_call>",
- [&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
+ [&](const std::string &msg) { return test_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
// Boolean values (true/false)
common_chat_msg expected_boolean;
" </parameter>\n"
" </function>\n"
"</tool_call>",
- [&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
+ [&](const std::string &msg) { return test_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
// Null value
common_chat_msg expected_null;
" </parameter>\n"
" </function>\n"
"</tool_call>",
- [&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
+ [&](const std::string &msg) { return test_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
// Negative numbers and scientific notation
common_chat_msg expected_numbers;
" </parameter>\n"
" </function>\n"
"</tool_call>",
- [&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
+ [&](const std::string &msg) { return test_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
// XML-like content in parameters (should be escaped)
common_chat_msg expected_xml_content;
" </parameter>\n"
" </function>\n"
"</tool_call>",
- [&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
+ [&](const std::string &msg) { return test_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
// Quotes and escape characters
common_chat_msg expected_quotes;
" </parameter>\n"
" </function>\n"
"</tool_call>",
- [&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
+ [&](const std::string &msg) { return test_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
// Long parameter value (simplified)
std::string long_text = "This is a long text parameter that should test the parser's ability to handle larger amounts of text data.";
" </parameter>\n"
" </function>\n"
"</tool_call>",
- [&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
+ [&](const std::string &msg) { return test_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
// Mixed content with text before and after tool call
common_chat_msg expected_mixed_content;
" </parameter>\n"
" </function>\n"
"</tool_call>",
- [&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
+ [&](const std::string &msg) { return test_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
// Compact format (no extra whitespace)
common_chat_msg expected_compact;
test_parser_with_streaming(
expected_compact,
"<tool_call><function=compact_function><parameter=param>value</parameter></function></tool_call>",
- [&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
+ [&](const std::string &msg) { return test_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
// Function name with underscores and numbers
common_chat_msg expected_complex_name;
" </parameter>\n"
" </function>\n"
"</tool_call>",
- [&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
+ [&](const std::string &msg) { return test_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
// Parameter names with underscores and numbers
common_chat_msg expected_complex_params;
" </parameter>\n"
" </function>\n"
"</tool_call>",
- [&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
+ [&](const std::string &msg) { return test_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
// Very deeply nested XML content in parameter
common_chat_msg expected_deep_xml;
" </parameter>\n"
" </function>\n"
"</tool_call>",
- [&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
+ [&](const std::string &msg) { return test_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
// Parameter with only whitespace
common_chat_msg expected_whitespace_param;
" </parameter>\n"
" </function>\n"
"</tool_call>",
- [&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
+ [&](const std::string &msg) { return test_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
// Parameter with tabs and mixed whitespace
common_chat_msg expected_mixed_whitespace;
" </parameter>\n"
" </function>\n"
"</tool_call>",
- [&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
+ [&](const std::string &msg) { return test_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
// Control characters and special Unicode
common_chat_msg expected_control_chars;
" </parameter>\n"
" </function>\n"
"</tool_call>",
- [&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
+ [&](const std::string &msg) { return test_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
// Emoji and extended Unicode characters
common_chat_msg expected_emoji;
" </parameter>\n"
" </function>\n"
"</tool_call>",
- [&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
+ [&](const std::string &msg) { return test_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
// Mathematical expressions and formulas
common_chat_msg expected_math;
" </parameter>\n"
" </function>\n"
"</tool_call>",
- [&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
+ [&](const std::string &msg) { return test_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
// SQL injection-like content (should be safely escaped)
common_chat_msg expected_sql;
" </parameter>\n"
" </function>\n"
"</tool_call>",
- [&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
+ [&](const std::string &msg) { return test_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
// HTML/XML injection content
common_chat_msg expected_html;
" </parameter>\n"
" </function>\n"
"</tool_call>",
- [&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
+ [&](const std::string &msg) { return test_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
// Binary-like content (base64)
common_chat_msg expected_binary;
" </parameter>\n"
" </function>\n"
"</tool_call>",
- [&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
+ [&](const std::string &msg) { return test_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
// Very large numbers (should be parsed as scientific notation)
common_chat_msg expected_large_numbers;
" </parameter>\n"
" </function>\n"
"</tool_call>",
- [&](const std::string &msg) { return common_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
+ [&](const std::string &msg) { return test_chat_parse(msg, /* is_partial= */ true, {COMMON_CHAT_FORMAT_QWEN3_CODER_XML}); });
}
{