#ifndef _DEFAULT_SOURCE #define _DEFAULT_SOURCE #endif #include "cst_agent.h" #include #include #include #include #include #define CHECK(c) \ do { \ if (!(c)) { \ fprintf(stderr, "%s:%d: CHECK(%s) failed\n", __FILE__, __LINE__, #c); \ exit(1); \ } \ } while (0) static char g_dir[256]; static void write_file(const char *name, const char *text) { char path[512]; snprintf(path, sizeof(path), "%s/cst-agent/%s", g_dir, name); FILE *fp = fopen(path, "w"); CHECK(fp); fputs(text, fp); fclose(fp); } static void test_creds(void) { char key[512]; const char *from = NULL; CHECK(cst_creds_resolve("deepseek", key, sizeof(key), &from) != 0); /* legacy single-key file follows its api_base */ write_file("credentials", "api_key=sk-legacy\n" "api_base=https://api.minimax.cn/v1/\n"); CHECK(cst_creds_load("minimax", key, sizeof(key)) == 0); CHECK(strcmp(key, "sk-legacy") == 0); CHECK(cst_creds_load("deepseek", key, sizeof(key)) != 0); write_file("credentials", "api_key=sk-old\n"); CHECK(cst_creds_load("minimax", key, sizeof(key)) == 0); CHECK(cst_creds_load("openai", key, sizeof(key)) != 0); CHECK(cst_creds_save("deepseek", "sk-ds-1") == 0); CHECK(cst_creds_save("openai", "sk-oa") == 0); CHECK(cst_creds_save("deepseek", "sk-ds-2") == 0); CHECK(cst_creds_load("deepseek", key, sizeof(key)) == 0); CHECK(strcmp(key, "sk-ds-2") == 0); CHECK(cst_creds_load("openai", key, sizeof(key)) == 0); CHECK(strcmp(key, "sk-oa") == 0); CHECK(cst_creds_load("minimax", key, sizeof(key)) == 0); /* legacy kept */ CHECK(strcmp(key, "sk-old") == 0); CHECK(cst_creds_save("deepseek", "bad\nkey") != 0); char path[512]; snprintf(path, sizeof(path), "%s/cst-agent/credentials", g_dir); struct stat st; CHECK(stat(path, &st) == 0); CHECK((st.st_mode & 0077) == 0); CHECK(cst_creds_resolve("deepseek", key, sizeof(key), &from) == 0); CHECK(strcmp(from, "saved") == 0); setenv("MINIMAX_API_KEY", "sk-env", 1); unlink(path); CHECK(cst_creds_resolve("minimax", key, sizeof(key), &from) == 0); CHECK(strcmp(key, "sk-env") == 0 && strcmp(from, "MINIMAX_API_KEY") == 0); unsetenv("MINIMAX_API_KEY"); } static void test_settings(void) { cst_settings_t s; CHECK(cst_settings_load(&s) != 0); CHECK(cst_settings_model(&s, "deepseek") == NULL); cst_agent_config_t cfg; memset(&cfg, 0, sizeof(cfg)); snprintf(cfg.provider, sizeof(cfg.provider), "deepseek"); snprintf(cfg.model, sizeof(cfg.model), "deepseek-v4-pro"); snprintf(cfg.effort, sizeof(cfg.effort), "high"); CHECK(cst_settings_remember(&cfg) == 0); snprintf(cfg.provider, sizeof(cfg.provider), "openai"); snprintf(cfg.model, sizeof(cfg.model), "gpt-5"); snprintf(cfg.effort, sizeof(cfg.effort), "max"); CHECK(cst_settings_remember(&cfg) == 0); CHECK(cst_settings_load(&s) == 0); CHECK(strcmp(s.provider, "openai") == 0); CHECK(strcmp(s.effort, "max") == 0); CHECK(strcmp(cst_settings_model(&s, "deepseek"), "deepseek-v4-pro") == 0); CHECK(strcmp(cst_settings_model(&s, "openai"), "gpt-5") == 0); CHECK(s.nmodels == 2); write_file("settings.json", "{not json"); CHECK(cst_settings_load(&s) != 0); CHECK(s.provider[0] == 0); } static void test_effort(void) { CHECK(cst_effort_valid("low") && cst_effort_valid("max")); CHECK(!cst_effort_valid("ultra") && !cst_effort_valid(NULL)); CHECK(strcmp(cst_effort_wire("deepseek", "deepseek-flash", "max"), "max") == 0); CHECK(strcmp(cst_effort_wire("openai", "o3-mini", "max"), "high") == 0); CHECK(cst_effort_wire("openai", "gpt-4.1-mini", "high") == NULL); CHECK(cst_effort_wire("minimax", "MiniMax-M2.7", "high") == NULL); cst_message_t m = {0}; m.role = CST_ROLE_USER; m.content = "hi"; cst_llm_request_t req = {0}; req.model = "deepseek-flash"; req.msgs = &m; req.nmsgs = 1; char *body = cst_llm_build_body(&req); CHECK(body && !strstr(body, "reasoning_effort")); free(body); req.reasoning_effort = "high"; body = cst_llm_build_body(&req); CHECK(body && strstr(body, "\"reasoning_effort\":\"high\"")); free(body); } int main(void) { snprintf(g_dir, sizeof(g_dir), "/tmp/cst-config-XXXXXX"); CHECK(mkdtemp(g_dir)); setenv("XDG_CONFIG_HOME", g_dir, 1); unsetenv("DEEPSEEK_API_KEY"); unsetenv("MINIMAX_API_KEY"); unsetenv("OPENAI_API_KEY"); char sub[300]; snprintf(sub, sizeof(sub), "%s/cst-agent", g_dir); CHECK(mkdir(sub, 0700) == 0); test_creds(); test_settings(); test_effort(); char cmd[400]; snprintf(cmd, sizeof(cmd), "rm -rf '%s'", g_dir); CHECK(system(cmd) == 0); printf("test_config: OK\n"); return 0; }