W21: anthropic Stream+Tools + --prompt batch + sanitizer fix + plugin unit tests (W21.1-W21.6)
Some checks failed
CI / Determine matrix (push) Has been cancelled
CI / ${{ matrix.os }} / ${{ matrix.build_type }} (push) Has been cancelled
CI / Sanitizer (ASan+UBSan) / ubuntu-24.04 (push) Has been cancelled

- W21.1: ci-sanitize preset 独立 Linux-clang + ci-threadsan (TSan)
- W21.2: anthropic tool_use content_block 解析 + configure 缓存 tools_json
- W21.3: --prompt 非交互批处理模式
- W21.4: session auto-save 失败告警 + 当前目录 fallback
- W21.5: smoke 补 tool_calls 边界用例 4 块 12 断言
- W21.6: anthropic 11 块 78 CHECK + deepseek 12 块 78 CHECK

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-27 20:40:58 +08:00
parent 20ead86e88
commit b2b381b9b3
14 changed files with 1671 additions and 34 deletions

View File

@@ -24,6 +24,13 @@ static int g_regression_failures = 0;
} \
} while (0)
// ---- W21.5 mock tool handler (qa-xu) ----
static int g_mock_tool_called = 0;
static char* mock_tool_handler(const char* /*args_json*/) {
g_mock_tool_called++;
return dstalk_strdup("{\"mock_result\":\"ok\"}");
}
int main()
{
const auto dir = std::filesystem::temp_directory_path() / "dstalk-smoke-test";
@@ -560,6 +567,103 @@ int main()
}
}
// ========================================================================
// W21.5 Tool Calls 边界测试 (qa-xu 徐磊)
// 覆盖: null tool_calls_json / 空数组 "[]" / 有效 tool_calls mock 验证
// ========================================================================
std::cout << "\n--- Tool Calls Boundary Tests (W21.5) ---\n";
if (tools && session) {
// ---- W21.5-1: null tool_calls_json → 正常处理(不崩溃)----
{
int before = 0;
session->history(&before);
dstalk_message_t msg_null_tc = {
"assistant", "content with null tool_calls_json", nullptr, nullptr
};
session->add(&msg_null_tc);
int after = 0;
const dstalk_message_t* hist = session->history(&after);
REGCHECK(after == before + 1,
"W21.5-1a: null tool_calls_json add — count +1 (no crash)");
if (hist && after > 0) {
REGCHECK(hist[after - 1].tool_calls_json == nullptr,
"W21.5-1b: null tool_calls_json — retrieved field is nullptr");
}
}
// ---- W21.5-2: 空 JSON 数组 "[]" → 正常处理(不崩溃)----
{
int before = 0;
session->history(&before);
dstalk_message_t msg_empty = {
"assistant", "content with empty [] tool_calls", nullptr, "[]"
};
session->add(&msg_empty);
int after = 0;
const dstalk_message_t* hist = session->history(&after);
REGCHECK(after == before + 1,
"W21.5-2a: empty [] tool_calls_json add — count +1 (no crash)");
if (hist && after > 0) {
REGCHECK(hist[after - 1].tool_calls_json != nullptr &&
std::strcmp(hist[after - 1].tool_calls_json, "[]") == 0,
"W21.5-2b: empty [] tool_calls_json — retrieved as \"[]\"");
}
}
// ---- W21.5-3: 有效 tool_calls JSON → 验证 execute 被调用 (mock) ----
{
g_mock_tool_called = 0;
int reg = tools->register_tool(
"__w21_5_mock",
"W21.5 mock tool for boundary test",
"{}",
mock_tool_handler
);
REGCHECK(reg == 0, "W21.5-3a: register mock tool ok");
char* result = tools->execute("__w21_5_mock", "{}");
REGCHECK(g_mock_tool_called == 1,
"W21.5-3b: mock tool handler was called (execute works)");
if (result) {
REGCHECK(std::strstr(result, "mock_result") != nullptr,
"W21.5-3c: execute returned mock result json");
dstalk_free(result);
}
tools->unregister_tool("__w21_5_mock");
// 验证已注销的工具返回 error 而非崩溃
char* err_result = tools->execute("__w21_5_mock", "{}");
REGCHECK(err_result && std::strstr(err_result, "error") != nullptr,
"W21.5-3d: unregistered tool returns error (not crash)");
if (err_result) dstalk_free(err_result);
}
// ---- W21.5-4: save/load 往返保留 tool_calls_json ----
if (file_io) {
const auto rtt_path = dir / "w21_5_tc_rtt.jsonl";
int ret = session->save(rtt_path.string().c_str());
REGCHECK(ret == 0, "W21.5-4a: session save with tool_calls msgs ok");
session->clear();
ret = session->load(rtt_path.string().c_str());
REGCHECK(ret == 0, "W21.5-4b: session load round-trip ok");
int count = 0;
session->history(&count);
REGCHECK(count > 0, "W21.5-4c: history non-empty after load round-trip");
}
session->clear();
} else {
std::cerr << "[WARN] W21.5: tools or session service not available\n";
}
// 清理
dstalk_shutdown();
std::cout << "[OK] dstalk_shutdown succeeded\n";