M1/F2+F4: platform registry, Moonshot API-key channel, dynamic model sync

F2 — fixed three-platform registry in kigi-models: kimi-code
(subscription, OAuth bearer, base kigi_env::coding_api_base_url()),
moonshot-cn (https://api.moonshot.cn/v1), moonshot-ai
(https://api.moonshot.ai/v1) with kimi-k model-prefix filtering.
Moonshot API keys via KIGI_MOONSHOT_CN_API_KEY / KIGI_MOONSHOT_AI_API_KEY
(+ KIGI_MOONSHOT_API_KEY shared fallback) or ~/.kigi/config.toml;
values redacted from logs/display.

F4 — model catalog now syncs from GET {base}/models (Bearer auth,
wire shape per official kimi-cli: id/context_length/supports_reasoning/
supports_image_in/supports_video_in/display_name) with the official
capability-derivation rules (thinking / always_thinking-in-name /
kimi-k2 implicit set). Managed keys {platform_id}/{model_id}; default
model = first list entry; default thinking iff capabilities contain
thinking/always_thinking. Sync failure → last cache; no cache →
built-in fallback table seeded from ids sourced in official kimi-cli
(kimi-for-coding, kimi-k2-turbo-preview, kimi-k2-thinking-turbo).
401 during sync forces one token refresh and retries.

Model resolution priority preserved: CLI > env > config > server >
fallback. Grok model artifacts (grok-4*/grok-build catalog, tier
gating remnants) removed from non-test code.

All first-party endpoints re-verified live: device_authorization mints
real codes; /models on all three platforms answers with real API auth
errors when unauthenticated.

Gates: check/clippy --all-targets 0/0, fmt clean, deny ok,
kigi-shell lib 5136 green, kigi-tui lib 6819 green, kigi-models 8.
This commit is contained in:
ZacharyZhang-NY committed 2026-07-17 09:23:44 -04:00
1 parent 021b82443d
commit fe1f885bb3
25 files changed
+2148 -430

No files matched your search

@@ -655,7 +655,7 @@ impl SessionActor {
let request = ConversationRequest {
items,
tools: vec![],
model: Some("grok-build".to_owned()),
model: Some(crate::models::default_model().to_owned()),
temperature: Some(0.3),
max_output_tokens: Some(1024),
..Default::default()
@@ -507,7 +507,7 @@ impl SessionActor {
let model = match model_override {
Some(m) => m.to_owned(),
None => "grok-build".to_owned(),
None => crate::models::default_model().to_owned(),
};
let request = ConversationRequest {
@@ -569,10 +569,10 @@ impl SessionActor {
/// (`KIGI_PROMPT_SUGGESTIONS_MODEL`) > `[models] prompt_suggestion`
/// (config.toml) > remote `prompt_suggestion_model` (remote settings) >
/// (config.toml) > remote `prompt_suggestion_model` (remote settings) >
/// [`prompt_suggest::DEFAULT_SUGGEST_MODEL`] (`grok-build-0.1`). Every
/// [`prompt_suggest::default_suggest_model`]. Every
/// tier except env is catalog-guarded against this shell's own model
/// catalog — when the effective model is not sampleable here (e.g.
/// `grok-build-0.1` for OAuth users) the request is **skipped
/// a model the catalog does not offer) the request is **skipped
/// entirely** instead of fired doomed. The session model is never used:
/// a per-turn background call must stay on the small model.
/// Temperature, max_output_tokens, and