Skip to content

Commit a839be7

Browse files
committed
Add tests for both happy path and broken fenced DeepSeek V3.1 tool call variants.
1 parent 52d5488 commit a839be7

File tree

1 file changed

+27
-7
lines changed

1 file changed

+27
-7
lines changed

tests/test-chat-parser.cpp

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -204,8 +204,17 @@ static void test_deepseek_v3_1() {
204204
}
205205
}
206206

207+
template<typename T>
208+
static void assert_equals(const char* label, const T& expected, const T& actual) {
209+
if (!(expected == actual)) {
210+
std::ostringstream oss; oss << label << "\nExpected: " << expected << "\nActual: " << actual;
211+
throw std::runtime_error(oss.str());
212+
}
213+
}
207214

208215
static void test_deepseek_v3_1_tool_calls() {
216+
// variant: happy path for when it works as the model card says it should
217+
const char* variant = "simple";
209218
common_chat_syntax syntax = {
210219
/* .format = */ COMMON_CHAT_FORMAT_DEEPSEEK_V3_1,
211220
/* .reasoning_format = */ COMMON_REASONING_FORMAT_DEEPSEEK,
@@ -215,12 +224,24 @@ static void test_deepseek_v3_1_tool_calls() {
215224
};
216225
const std::string input = "<|tool▁calls▁begin|><|tool▁call▁begin|>get_time<|tool▁sep|>{\"city\": \"Tokyo\"}<|tool▁call▁end|><|tool▁calls▁end|>";
217226
auto msg = common_chat_parse(input, false, syntax);
218-
assert_equals(static_cast<std::size_t>(1), msg.tool_calls.size());
219-
assert_equals(std::string("get_time"), msg.tool_calls[0].name);
227+
assert_equals(variant, static_cast<std::size_t>(1), msg.tool_calls.size());
228+
assert_equals(variant, std::string("get_time"), msg.tool_calls[0].name);
220229
// JSON arguments are dumped without spaces
221-
assert_equals(std::string("{\"city\":\"Tokyo\"}"), msg.tool_calls[0].arguments);
222-
assert_equals(std::string(""), msg.content);
223-
assert_equals(std::string(""), msg.reasoning_content);
230+
assert_equals(variant, std::string("{\"city\":\"Tokyo\"}"), msg.tool_calls[0].arguments);
231+
assert_equals(variant, std::string(""), msg.content);
232+
assert_equals(variant, std::string(""), msg.reasoning_content);
233+
234+
// variant: function + fenced JSON
235+
{
236+
const char* variant = "fenced";
237+
const std::string in = "<|tool▁calls▁begin|><|tool▁call▁begin|>function<|tool▁sep|>get_time\n```json\n{\"city\": \"Tokyo\"}\n```<|tool▁call▁end|><|tool▁calls▁end|>";
238+
auto m = common_chat_parse(in, false, syntax);
239+
assert_equals<std::size_t>(variant, 1, m.tool_calls.size());
240+
assert_equals(variant, std::string("get_time"), m.tool_calls[0].name);
241+
assert_equals(variant, std::string("{\"city\":\"Tokyo\"}"), m.tool_calls[0].arguments);
242+
assert_equals(variant, std::string(""), m.content);
243+
assert_equals(variant, std::string(""), m.reasoning_content);
244+
}
224245
}
225246

226247
static void test_with_args(const std::string & input, const std::string & expected, bool parse_as_partial = true, bool is_partial = true) {
@@ -366,8 +387,6 @@ static void test_positions() {
366387
assert_throws([&]() { builder.finish(); });
367388
assert_equals<size_t>(0, builder.pos());
368389

369-
test_deepseek_v3_1_tool_calls();
370-
371390
builder.move_to(builder.input().size());
372391
builder.finish();
373392
}
@@ -387,6 +406,7 @@ int main() {
387406
test_reasoning();
388407
test_regex();
389408
test_deepseek_v3_1();
409+
test_deepseek_v3_1_tool_calls();
390410
std::cout << "All tests passed!\n";
391411
return 0;
392412
}

0 commit comments

Comments
 (0)