Skip to content

Commit 87c1ed9

Browse files
authored
add test copied from ggml-org#16946
1 parent 836ab26 commit 87c1ed9

File tree

1 file changed

+100
-5
lines changed

1 file changed

+100
-5
lines changed

tests/test-chat.cpp

Lines changed: 100 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,21 @@ static common_chat_msg normalize(const common_chat_msg & msg) {
7575
}
7676
return normalized;
7777
}
78+
79+
80+
// trim whitespace from the beginning and end of a string
81+
static std::string trim(const std::string & str) {
82+
size_t start = 0;
83+
size_t end = str.size();
84+
while (start < end && isspace(static_cast<unsigned char>(str[start]))) {
85+
start += 1;
86+
}
87+
while (end > start && isspace(static_cast<unsigned char>(str[end - 1]))) {
88+
end -= 1;
89+
}
90+
return str.substr(start, end - start);
91+
}
92+
7893
template <>
7994
bool equals(const common_chat_msg & expected, const common_chat_msg & actual) {
8095
return normalize(expected) == normalize(actual);
@@ -148,15 +163,15 @@ static std::string renormalize_json(const std::string & json_str) {
148163
return json_str;
149164
}
150165
}
151-
static void assert_msg_equals(const common_chat_msg & expected, const common_chat_msg & actual) {
166+
static void assert_msg_equals(const common_chat_msg & expected, const common_chat_msg & actual, bool ignore_whitespace_differences = false) {
152167
assert_equals(expected.role, actual.role);
153-
assert_equals(expected.content, actual.content);
168+
assert_equals(expected.content, ignore_whitespace_differences ? trim(actual.content) : actual.content);
154169
assert_equals(expected.content_parts.size(), actual.content_parts.size());
155170
for (size_t i = 0; i < expected.content_parts.size(); i++) {
156171
const auto & expected_part = expected.content_parts[i];
157172
const auto & actual_part = actual.content_parts[i];
158173
assert_equals(expected_part.type, actual_part.type);
159-
assert_equals(expected_part.text, actual_part.text);
174+
assert_equals(expected_part.text, ignore_whitespace_differences ? trim(actual_part.text) : actual_part.text);
160175
}
161176
assert_equals(expected.reasoning_content, actual.reasoning_content);
162177
assert_equals(expected.tool_calls.size(), actual.tool_calls.size());
@@ -280,14 +295,19 @@ static void test_templates(const struct common_chat_templates * tmpls, const std
280295
const std::string & expected_delta = "",
281296
bool expect_grammar_triggered = true,
282297
bool test_grammar_if_triggered = true,
283-
common_reasoning_format reasoning_format = COMMON_REASONING_FORMAT_NONE) {
298+
common_reasoning_format reasoning_format = COMMON_REASONING_FORMAT_NONE,
299+
bool ignore_whitespace_differences = false
300+
) {
284301
common_chat_msg user_message;
285302
user_message.role = "user";
286303
user_message.content = "Hello, world!";
287304

288305
for (const auto & tool_choice : std::vector<common_chat_tool_choice> {COMMON_CHAT_TOOL_CHOICE_AUTO, COMMON_CHAT_TOOL_CHOICE_REQUIRED}) {
289306
auto data = init_delta(tmpls, end_tokens, user_message, test_message, tools, tool_choice);
290307
if (!expected_delta.empty()) {
308+
if (ignore_whitespace_differences) {
309+
data.delta = trim(data.delta);
310+
}
291311
assert_equals(expected_delta, data.delta);
292312
}
293313

@@ -296,7 +316,7 @@ static void test_templates(const struct common_chat_templates * tmpls, const std
296316
syntax.format = data.params.format;
297317
syntax.reasoning_format = reasoning_format;
298318
const auto msg = common_chat_parse(data.delta, /* is_partial= */ false, syntax);
299-
assert_msg_equals(test_message, msg);
319+
assert_msg_equals(test_message, msg, ignore_whitespace_differences);
300320
}
301321

302322
if (!test_message.tool_calls.empty()) {
@@ -2288,6 +2308,81 @@ Hey there!<|im_end|>
22882308
// above verify edge cases and format variations for the tool call output format.
22892309
}
22902310

2311+
{
2312+
auto tmpls = read_templates("models/templates/unsloth-MiniMax-M2.jinja");
2313+
std::vector<std::string> end_tokens{ "[e~[" };
2314+
2315+
assert_equals(COMMON_CHAT_FORMAT_MINIMAX_M2, common_chat_templates_apply(tmpls.get(), inputs_no_tools).format);
2316+
assert_equals(COMMON_CHAT_FORMAT_MINIMAX_M2, common_chat_templates_apply(tmpls.get(), inputs_tools).format);
2317+
2318+
// Test parsing regular content
2319+
assert_msg_equals(message_assist,
2320+
common_chat_parse(
2321+
"Hello, world!\nWhat's up?",
2322+
/* is_partial= */ false,
2323+
{COMMON_CHAT_FORMAT_MINIMAX_M2}));
2324+
2325+
// Test parsing content with thinking
2326+
assert_msg_equals(message_assist_thoughts,
2327+
common_chat_parse(
2328+
"<think>I'm\nthinking</think>Hello, world!\nWhat's up?",
2329+
/* is_partial= */ false,
2330+
{
2331+
/* .format = */ COMMON_CHAT_FORMAT_MINIMAX_M2,
2332+
/* .reasoning_format = */ COMMON_REASONING_FORMAT_DEEPSEEK,
2333+
}));
2334+
2335+
// Test parsing tool calls
2336+
assert_msg_equals(message_assist_call,
2337+
common_chat_parse(
2338+
"<minimax:tool_call><invoke name=\"special_function\"><parameter name=\"arg1\">1</parameter></invoke></minimax:tool_call>",
2339+
/* is_partial= */ false,
2340+
{COMMON_CHAT_FORMAT_MINIMAX_M2}));
2341+
2342+
// Test parsing tool calls with thinking
2343+
assert_msg_equals(message_assist_call_thoughts,
2344+
common_chat_parse(
2345+
"<think>I'm\nthinking</think><minimax:tool_call><invoke name=\"special_function\"><parameter name=\"arg1\">1</parameter></invoke></minimax:tool_call>",
2346+
/* is_partial= */ false,
2347+
{
2348+
/* .format = */ COMMON_CHAT_FORMAT_MINIMAX_M2,
2349+
/* .reasoning_format = */ COMMON_REASONING_FORMAT_DEEPSEEK
2350+
}));
2351+
2352+
// Test tool calls with extra content
2353+
assert_msg_equals(message_assist_call_content,
2354+
common_chat_parse(
2355+
"<minimax:tool_call><invoke name=\"special_function\"><parameter name=\"arg1\">1</parameter></invoke></minimax:tool_call>Hello, world!\nWhat's up?",
2356+
/* is_partial= */ false,
2357+
{COMMON_CHAT_FORMAT_MINIMAX_M2}
2358+
));
2359+
2360+
// Test tool calls with extra content AND thinking
2361+
assert_msg_equals(message_assist_call_thoughts_content,
2362+
common_chat_parse(
2363+
"<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?",
2364+
/* is_partial= */ false,
2365+
{
2366+
/* .format = */ COMMON_CHAT_FORMAT_MINIMAX_M2,
2367+
/* .reasoning_format = */ COMMON_REASONING_FORMAT_DEEPSEEK
2368+
}));
2369+
2370+
// Test template generation for regular content
2371+
test_templates(tmpls.get(), end_tokens, message_assist, tools,
2372+
"Hello, world!\nWhat's up?",
2373+
/* expect_grammar_triggered= */ false);
2374+
2375+
// Test template generation for tool calls
2376+
test_templates(tmpls.get(), end_tokens, message_assist_call, tools,
2377+
"<minimax:tool_call>\n<invoke name=\"special_function\">\n<parameter name=\"arg1\">1</parameter>\n</invoke>\n</minimax:tool_call>",
2378+
/* expect_grammar_triggered= */ true,
2379+
/* test_grammar_if_triggered= */ true,
2380+
/* common_reasoning_format= */ COMMON_REASONING_FORMAT_NONE,
2381+
/* ignore_whitespace_differences= */ true
2382+
);
2383+
2384+
}
2385+
22912386
}
22922387

22932388
static void test_msg_diffs_compute() {

0 commit comments

Comments
 (0)