`xai` and `openai` carry `restrict_to_enriched`, so a live listing id the enrichment catalog does not know is dropped. The bundled snapshot knew neither `grok-4.7` nor `gpt-6-astra`, which left both invisible offline and until the 24h models.dev refresh landed. Regeneration also tripped the generator's fail-fast: models.dev renamed the Kimi coding provider. `kimi-for-coding` is now `kimi-code-plan-cn` (api.kimi.com — kigi's endpoint), with `kimi-code-plan-global` the api.kimi.ai twin; the model set is unchanged. Both registry rows, the generator target and the two snapshot lookups follow the new id, and the cache `keep_set` guard invalidates any cache filtered under the old one.
78 lines
2.9 KiB
Python
78 lines
2.9 KiB
Python
#!/usr/bin/env python3
|
|
"""Regenerate the bundled models.dev enrichment snapshot.
|
|
|
|
Usage:
|
|
curl -s https://models.dev/api.json -o /tmp/modelsdev-api.json
|
|
python3 scripts/gen_enrichment_snapshot.py /tmp/modelsdev-api.json
|
|
|
|
PURE FILTER, NO TRANSFORM: writes the raw models.dev per-provider objects
|
|
(only the providers kigi references) to
|
|
crates/codegen/kigi-models/enrichment_snapshot.json. All field
|
|
interpretation lives in ONE place — `kigi_models::enrichment::parse_api_json`
|
|
— which parses this snapshot and runtime refreshes identically.
|
|
|
|
Keep TARGETS in sync with the registry's `models_dev_id` values (a registry
|
|
test cross-checks coverage). `openrouter` is deliberately absent: its
|
|
/models wire serves context_length itself.
|
|
"""
|
|
|
|
import json
|
|
import pathlib
|
|
import sys
|
|
|
|
TARGETS = [
|
|
"anthropic", "azure", "openai", "deepseek", "nvidia", "google",
|
|
"amazon-bedrock", "mistral", "groq", "cerebras", "cloudflare-ai-gateway",
|
|
"xai", "togetherai", "fireworks-ai", "opencode", "opencode-go",
|
|
"kimi-code-plan-cn", "moonshotai", "moonshotai-cn", "minimax", "minimax-cn",
|
|
"alibaba-token-plan", "alibaba-token-plan-cn", "xiaomi",
|
|
"xiaomi-token-plan-cn", "zai-coding-plan", "zhipuai-coding-plan",
|
|
"github-copilot", "vercel",
|
|
]
|
|
|
|
# Per-model keys the Rust parser consumes; everything else is dropped to keep
|
|
# the bundled file lean (cost/date/experimental fields are dead weight).
|
|
MODEL_KEYS = ("name", "reasoning", "reasoning_options", "limit", "modalities",
|
|
"tool_call")
|
|
|
|
|
|
def main() -> int:
|
|
if len(sys.argv) != 2:
|
|
print(__doc__, file=sys.stderr)
|
|
return 2
|
|
src = json.load(open(sys.argv[1]))
|
|
missing = [pid for pid in TARGETS if pid not in src]
|
|
if missing:
|
|
# Fail fast: a target vanishing from models.dev needs a human look.
|
|
print(f"providers missing from api.json: {missing}", file=sys.stderr)
|
|
return 1
|
|
out = {}
|
|
# Provenance stamp (parse_api_json skips keys starting with "_").
|
|
out["_meta"] = {
|
|
"source": "https://models.dev/api.json (github.com/sst/models.dev, MIT)",
|
|
"note": "filtered snapshot for kigi model-metadata enrichment; "
|
|
"regenerate via scripts/gen_enrichment_snapshot.py",
|
|
}
|
|
out |= {
|
|
pid: {
|
|
"models": {
|
|
mid: {k: m[k] for k in MODEL_KEYS if k in m}
|
|
for mid, m in src[pid]["models"].items()
|
|
}
|
|
}
|
|
for pid in TARGETS
|
|
}
|
|
dst = pathlib.Path(__file__).resolve().parent.parent / (
|
|
"crates/codegen/kigi-models/enrichment_snapshot.json"
|
|
)
|
|
dst.write_text(json.dumps(out, separators=(",", ":"), sort_keys=True) + "\n")
|
|
providers = [k for k in out if not k.startswith("_")]
|
|
n_models = sum(len(out[p]["models"]) for p in providers)
|
|
print(f"wrote {dst}: {len(providers)} providers, {n_models} models, "
|
|
f"{dst.stat().st_size} bytes")
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|