Add models.dev metadata-enrichment pipeline (providers P0c-2)

Provider /models listings that return bare ids (OpenAI-style) get context
windows, thinking levels, image support, and display names from models.dev:
kigi-models owns the transform (parse_api_json — ONE field interpretation
for the bundled snapshot AND runtime refreshes), enrich_wire_model fills
gaps with wire values always winning and model availability strictly
wire-truth. Spec rows gained models_dev_id + wire_serves_metadata; all
three current platforms are wire-served, so this pipeline is provably
inert for them (byte-identical catalogs, zero egress, zero ~/.kigi writes
— adversarially verified).

Shell side: enrichment_fetch with a 24h disk cache guarded by binary
version + keep-set + future-stamp sanity (a registry change or downgrade
refetches instead of serving a catalog missing new providers), refresh of
https://models.dev/api.json filtered to registry ids, KIGI_MODELS_DEV_URL
override with case/whitespace-tolerant kill switch, fallback chain
fresh-cache > refresh > stale-cache > bundled (each step logged). The
fast path returns an empty catalog without forcing the bundled parse.

From the review: blast-radius-confined parsing (one drifted provider on
models.dev warn-skips instead of failing the whole refresh), registry-
coverage and field-coverage tests guarding script/parser drift, a path-
injectable core with 8 state-machine tests (one of which caught a guard
patch that had failed to apply), _meta provenance stamp in the snapshot,
and models.dev (MIT) attribution in NOTICE. Snapshot: 29 providers, 1124
models, 246KB, regenerated by scripts/gen_enrichment_snapshot.py (pure
filter, no transform).
This commit is contained in:
2026-07-21 03:36:51 -04:00
parent 83e6935189
commit fdf9b956f5
11 changed files with 953 additions and 8 deletions
+26
View File
@@ -16,6 +16,8 @@
use std::sync::LazyLock;
pub mod enrichment;
// ── Platform registry (PRD F2) ──────────────────────────────────────────────
/// Env var holding the moonshot-cn API key (wins over the generic name).
@@ -82,6 +84,13 @@ struct PlatformSpec {
console_host: Option<&'static str>,
/// Interactive login-picker label. `None` = fall back to `display_name`.
login_label: Option<&'static str>,
/// This platform's provider id on models.dev, for metadata enrichment.
/// `None` = not covered there (enrichment silently skips).
models_dev_id: Option<&'static str>,
/// True when the platform's `/models` listing itself serves context
/// window / thinking metadata — enrichment (and its network refresh) is
/// skipped entirely for such platforms.
wire_serves_metadata: bool,
}
const KIMI_CODE_SPEC: PlatformSpec = PlatformSpec {
@@ -94,6 +103,8 @@ const KIMI_CODE_SPEC: PlatformSpec = PlatformSpec {
vendor: "Kimi",
console_host: None,
login_label: None,
models_dev_id: Some("kimi-for-coding"),
wire_serves_metadata: true,
};
const MOONSHOT_CN_SPEC: PlatformSpec = PlatformSpec {
@@ -109,6 +120,8 @@ const MOONSHOT_CN_SPEC: PlatformSpec = PlatformSpec {
vendor: "Moonshot",
console_host: Some("platform.moonshot.cn"),
login_label: Some("Moonshot Open Platform (API key \u{b7} moonshot.cn)"),
models_dev_id: Some("moonshotai-cn"),
wire_serves_metadata: true,
};
const MOONSHOT_AI_SPEC: PlatformSpec = PlatformSpec {
@@ -124,6 +137,8 @@ const MOONSHOT_AI_SPEC: PlatformSpec = PlatformSpec {
vendor: "Moonshot",
console_host: Some("platform.moonshot.ai"),
login_label: Some("Moonshot Open Platform (API key \u{b7} moonshot.ai)"),
models_dev_id: Some("moonshotai"),
wire_serves_metadata: true,
};
/// The platform registry. Platforms are compiled-in spec rows; there is no
@@ -217,6 +232,17 @@ impl PlatformId {
pub fn login_label(self) -> &'static str {
self.spec().login_label.unwrap_or(self.spec().display_name)
}
/// This platform's provider id on models.dev (metadata enrichment).
pub fn models_dev_id(self) -> Option<&'static str> {
self.spec().models_dev_id
}
/// True when the live `/models` wire serves metadata itself — enrichment
/// and its network refresh are skipped for such platforms.
pub fn wire_serves_metadata(self) -> bool {
self.spec().wire_serves_metadata
}
}
/// Split a managed catalog key `{platform_id}/{model_id}` back into its