feat: add Kimi Code and web APIs

This commit is contained in:
WHC
2026-10-19 10:41:00 +08:00
parent 60047ca5ce
commit 235652604d
21 changed files with 1189 additions and 49 deletions
+72
View File
@@ -298,6 +298,77 @@ static void test_cache_hints(void) {
cJSON_Delete(j);
}
static void test_kimi_wire_format(void) {
const char *old_no_cache = getenv("CST_NO_CACHE_HINTS");
const char *old_ttl = getenv("CST_KIMI_CACHE_TTL");
char *saved_no_cache = old_no_cache ? strdup(old_no_cache) : NULL;
char *saved_ttl = old_ttl ? strdup(old_ttl) : NULL;
setenv("CST_NO_CACHE_HINTS", "0", 1);
unsetenv("CST_KIMI_CACHE_TTL");
cst_message_t m[3];
m[0] = msg(CST_ROLE_USER, "think");
m[1] = msg(CST_ROLE_ASSISTANT, "answer");
m[1].reasoning = "private reasoning";
m[2] = msg(CST_ROLE_ASSISTANT, "continue");
m[2].prefix = 1;
cst_llm_request_t r;
memset(&r, 0, sizeof(r));
r.api_base = "https://api.moonshot.ai/v1";
r.model = "kimi-k2.6";
r.msgs = m;
r.nmsgs = 3;
r.send_reasoning = 1;
cJSON *j = build_req(&r);
const cJSON *thinking = cJSON_GetObjectItemCaseSensitive(j, "thinking");
EXPECT(cJSON_IsString(cJSON_GetObjectItemCaseSensitive(thinking, "type")) &&
strcmp(cJSON_GetObjectItemCaseSensitive(thinking, "type")->valuestring,
"enabled") == 0,
"Kimi K2 thinking enabled");
EXPECT(cJSON_IsString(cJSON_GetObjectItemCaseSensitive(thinking, "keep")) &&
strcmp(cJSON_GetObjectItemCaseSensitive(thinking, "keep")->valuestring,
"all") == 0,
"Kimi K2 keeps reasoning");
EXPECT(!cJSON_GetObjectItemCaseSensitive(j, "reasoning_effort"),
"Kimi K2 omits reasoning_effort");
const cJSON *cache =
cJSON_GetObjectItemCaseSensitive(j, "prompt_cache_options");
EXPECT(cJSON_IsString(cJSON_GetObjectItemCaseSensitive(cache, "ttl")) &&
strcmp(cJSON_GetObjectItemCaseSensitive(cache, "ttl")->valuestring,
"1h") == 0,
"Kimi implicit cache uses the long TTL by default");
const cJSON *partial =
cJSON_GetObjectItemCaseSensitive(msg_at(j, 2), "partial");
EXPECT(cJSON_IsTrue(partial) &&
!cJSON_GetObjectItemCaseSensitive(msg_at(j, 2), "prefix"),
"Kimi assistant prefill uses partial");
cJSON_Delete(j);
r.model = "kimi-k3";
r.reasoning_effort = "high";
j = build_req(&r);
EXPECT(cJSON_IsString(cJSON_GetObjectItemCaseSensitive(j, "reasoning_effort")) &&
strcmp(cJSON_GetObjectItemCaseSensitive(j, "reasoning_effort")->valuestring,
"high") == 0,
"Kimi K3 uses reasoning_effort");
EXPECT(!cJSON_GetObjectItemCaseSensitive(j, "thinking"),
"Kimi K3 omits K2 thinking object");
cJSON_Delete(j);
if (saved_no_cache) {
setenv("CST_NO_CACHE_HINTS", saved_no_cache, 1);
free(saved_no_cache);
} else {
unsetenv("CST_NO_CACHE_HINTS");
}
if (saved_ttl) {
setenv("CST_KIMI_CACHE_TTL", saved_ttl, 1);
free(saved_ttl);
} else {
unsetenv("CST_KIMI_CACHE_TTL");
}
}
static void test_tools_snapshot(void) {
cst_message_t m[1] = {msg(CST_ROLE_USER, "go")};
cst_llm_request_t r;
@@ -559,6 +630,7 @@ int main(void) {
test_document_parts();
test_reasoning_and_prefix();
test_cache_hints();
test_kimi_wire_format();
test_tools_snapshot();
test_gen_params();
test_escaping();