/* models.h - 拉取并解析服务端的模型列表 (GET {base_url}/models) * * 只为了 /model 不带参数时的那个交互式选择列表. OpenAI 兼容的响应体长这样: * * {"object": "list", "data": [{"id": "deepseek-chat", ...}, ...]} * * 我们只取 id. 别的字段 (object / owned_by / created)对挑模型没有帮助, * 各家还都不一样 —— 取了反而要跟着人家的变化改. */ #ifndef LIGENT_MODELS_H #define LIGENT_MODELS_H #include "config.h" #include /* 从 /models 的响应体里取模型名. 保序、去重, 返回 malloc 的字符串数组 * (元素也是 malloc), *out_n 回填个数. 解析不出任何模型名时返回 NULL. * * 兼容两种形状: {"data":[...]} 和裸数组 [...]. 纯函数, 可单测. */ char **models_parse(const char *json, size_t *out_n); /* 响应体是不是"格式没问题、但里面一个模型都没有"? * 用来把"服务端没给你任何模型"和"响应根本解析不了"分开报 —— * 这两种情况的下一步动作完全不同, 含糊地说成"拿不到列表"就是误导. */ int models_is_empty_list(const char *json); /* 打一次网络: GET {base_url}/models, 解析出模型名. * 成功返回数组 (调用方用 models_free 释放), 失败返回 NULL 并把原因写进 err. * verbose 会打印 HTTP 细节. */ char **models_fetch(const LigentConfig *cfg, size_t *out_n, int verbose, char *err, size_t errlen); /* 释放 models_parse / models_fetch 返回的数组 */ void models_free(char **list, size_t n); #endif /* LIGENT_MODELS_H */