Files
CST-agent/include/cst_models.h
T
WHC 895b47274c v0.7.0: image input, model registry, prefix-cache savings
Images
- vision gate: text-only models get a note instead of image parts and no
  view_image tool; unknown models retry once without images on HTTP 400
- paste: Ctrl+V and /attach paste read the clipboard (wl-paste, xclip,
  pngpaste/osascript, Win32 PNG or CF_DIB converted to PNG); pasting image
  file paths attaches them
- MCP image content is stored in the session and sent with the tool result
- attach: rel path validation, base64 decode, /retry keeps images

Model registry
- built-in src/models_builtin.json embedded at build time, merged with
  <config>/models.json and cached GET /models metadata (context, vision,
  pricing); most specific rule wins per field
- /model labels, /status source, --list-models [provider]

Cache and cost
- stable request prefix (frozen tools, notes as messages), DeepSeek prefix
  completion, OpenAI/Anthropic cache hints, /cost and hit rate in the status
2026-10-08 20:34:09 +08:00

93 lines
3.7 KiB
C

#ifndef CST_MODELS_H
#define CST_MODELS_H
/* Model registry: what cst-agent knows about providers and models.
*
* Three layers, highest first, merged field by field:
* 1. <config>/models.json user overrides and extra providers
* 2. <config>/models-cache/<provider>.json GET /models metadata, exact id
* 3. built-in data (src/models_builtin.json, embedded at build time)
* then defaults (128000 tokens, vision unknown). Model rules match the name
* without its "vendor/" prefix, case-insensitively: a plain "match" is a
* prefix, one with '*' is a glob, one with '/' is tested against the full
* id. Within a layer the most specific rule (most literal characters) that
* sets a field wins, so table order does not matter.
*
* CST_CTX_TOKENS, CST_PRICE, CST_MODELS and CST_NO_CACHE_HINTS still
* override everything. */
#include "cst_agent.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
long context; /* tokens */
int vision; /* 1 takes images, 0 text only, -1 unknown */
int cache_style; /* cst_cache_style_t */
int reasoning; /* takes OpenAI-style reasoning_effort */
int has_price;
cst_price_t price;
/* Layers that supplied anything, highest first: "user+api+built-in",
* "default", "env+built-in"... */
char source[48];
} cst_model_info_t;
/* provider may be NULL: then every provider's fetched cache is searched. */
void cst_model_info(const char *provider, const char *model,
cst_model_info_t *out);
/* Short picker label: "1M · vision", "200K · text only", "128K". */
void cst_model_info_label(const cst_model_info_t *mi, char *out, size_t n);
/* One entry of GET /models, with the optional OpenRouter-style metadata. */
typedef struct {
char id[128];
long context; /* 0 = not given */
int vision; /* -1 = not given */
int has_price; /* prices in USD per 1M tokens */
double miss, hit, write, out;
} cst_model_meta_t;
/* Like cst_llm_list_models, keeping context_length,
* architecture.input_modalities (or modalities) and pricing when present. */
int cst_llm_list_models_meta(const char *api_base, const char *api_key,
cst_model_meta_t *out, int max_out, char *err,
size_t err_sz);
#define CST_MODELS_CACHE_TTL (24L * 3600)
/* Store a fetched list as <config>/models-cache/<provider>.json and use it
* from now on. 0 / -1. */
int cst_models_cache_save(const char *provider, const char *api_base,
const cst_model_meta_t *list, int n);
/* The cached list for provider: count (up to max), or -1 when there is
* none. *age_s gets the seconds since it was fetched. */
int cst_models_cache_load(const char *provider, cst_model_meta_t *out, int max,
long *age_s);
/* The "models" a provider entry lists (built-in or user file). */
int cst_provider_models(const cst_provider_t *p, char out[][128], int max);
/* Where a provider entry came from: "built-in" or "user". */
const char *cst_provider_source(const cst_provider_t *p);
/* The user file's path (it may not exist). */
int cst_models_user_path(char *out, size_t out_sz);
/* Drop everything and read the built-in data, the user file and the caches
* again. Provider pointers stay valid but may name another provider. */
void cst_models_reload(void);
/* Tests: load these documents instead of the built-in data and the user
* file (NULL = none). Caches still come from <config>. 0, or -1 with err. */
int cst_models_load_json(const char *builtin_json, const char *user_json,
char *err, size_t err_sz);
/* The embedded built-in document. */
const char *cst_models_builtin_json(void);
/* Problems found while loading (bad user file...), or "". */
const char *cst_models_load_error(void);
#ifdef __cplusplus
}
#endif
#endif