From 0b66ed026cdaaa159b010958393d42b9cd594a3f Mon Sep 17 00:00:00 2001 From: Chummy Date: Wed, 18 Feb 2026 22:04:56 +0800 Subject: [PATCH] fix(provider): polish kimi-code wiring and onboarding parity --- docs/providers-reference.md | 9 ++++++++- src/onboard/wizard.rs | 39 ++++++++++++++++++++++++++++++++++++- src/providers/mod.rs | 1 + 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/docs/providers-reference.md b/docs/providers-reference.md index f30c110..5ddc6d7 100644 --- a/docs/providers-reference.md +++ b/docs/providers-reference.md @@ -31,6 +31,7 @@ Runtime resolution order is: | `vercel` | `vercel-ai` | No | `VERCEL_API_KEY` | | `cloudflare` | `cloudflare-ai` | No | `CLOUDFLARE_API_KEY` | | `moonshot` | `kimi` | No | `MOONSHOT_API_KEY` | +| `kimi-code` | `kimi_coding`, `kimi_for_coding` | No | `KIMI_CODE_API_KEY`, `MOONSHOT_API_KEY` | | `synthetic` | — | No | `SYNTHETIC_API_KEY` | | `opencode` | `opencode-zen` | No | `OPENCODE_API_KEY` | | `zai` | `z.ai` | No | `ZAI_API_KEY` | @@ -51,6 +52,13 @@ Runtime resolution order is: | `lmstudio` | `lm-studio` | Yes | (optional; local by default) | | `nvidia` | `nvidia-nim`, `build.nvidia.com` | No | `NVIDIA_API_KEY` | +### Kimi Code Notes + +- Provider ID: `kimi-code` +- Endpoint: `https://api.kimi.com/coding/v1` +- Default onboarding model: `kimi-for-coding` (alternative: `kimi-k2.5`) +- Runtime auto-adds `User-Agent: KimiCLI/0.77` for compatibility. + ## Custom Endpoints - OpenAI-compatible endpoint: @@ -86,4 +94,3 @@ Then call with a hint model name (for example from tool or integration paths): ```text hint:reasoning ``` - diff --git a/src/onboard/wizard.rs b/src/onboard/wizard.rs index 27c47da..b725bee 100644 --- a/src/onboard/wizard.rs +++ b/src/onboard/wizard.rs @@ -471,6 +471,7 @@ fn canonical_provider_name(provider_name: &str) -> &str { "grok" => "xai", "together" => "together-ai", "google" | "google-gemini" => "gemini", + "kimi_coding" | "kimi_for_coding" => "kimi-code", _ => provider_name, } } @@ -688,6 +689,16 @@ fn curated_models_for_provider(provider_name: &str) -> Vec<(String, String)> { "Command R (stable fast baseline)".to_string(), ), ], + "kimi-code" => vec![ + ( + "kimi-for-coding".to_string(), + "Kimi for Coding (official coding-agent model)".to_string(), + ), + ( + "kimi-k2.5".to_string(), + "Kimi K2.5 (general coding endpoint model)".to_string(), + ), + ], "moonshot" => vec![ ( "kimi-latest".to_string(), @@ -1641,7 +1652,9 @@ fn setup_provider(workspace_dir: &Path) -> Result<(String, String, String, Optio key } } else { - let key_url = if is_moonshot_alias(provider_name) { + let key_url = if is_moonshot_alias(provider_name) + || canonical_provider_name(provider_name) == "kimi-code" + { "https://platform.moonshot.cn/console/api-keys" } else if is_glm_cn_alias(provider_name) || is_zai_cn_alias(provider_name) { "https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys" @@ -1807,6 +1820,13 @@ fn setup_provider(workspace_dir: &Path) -> Result<(String, String, String, Optio ("command-r-plus", "Command R+ (flagship)"), ("command-r", "Command R (fast)"), ], + "kimi-code" => vec![ + ( + "kimi-for-coding", + "Kimi for Coding (official coding-agent model)", + ), + ("kimi-k2.5", "Kimi K2.5 (general coding endpoint model)"), + ], "moonshot" => vec![ ("moonshot-v1-128k", "Moonshot V1 128K"), ("moonshot-v1-32k", "Moonshot V1 32K"), @@ -2031,6 +2051,7 @@ fn provider_env_var(name: &str) -> &'static str { "fireworks" | "fireworks-ai" => "FIREWORKS_API_KEY", "perplexity" => "PERPLEXITY_API_KEY", "cohere" => "COHERE_API_KEY", + "kimi-code" => "KIMI_CODE_API_KEY", "moonshot" => "MOONSHOT_API_KEY", "glm" => "GLM_API_KEY", "minimax" => "MINIMAX_API_KEY", @@ -4629,6 +4650,8 @@ mod tests { assert_eq!(canonical_provider_name("dashscope-us"), "qwen"); assert_eq!(canonical_provider_name("moonshot-intl"), "moonshot"); assert_eq!(canonical_provider_name("kimi-cn"), "moonshot"); + assert_eq!(canonical_provider_name("kimi_coding"), "kimi-code"); + assert_eq!(canonical_provider_name("kimi_for_coding"), "kimi-code"); assert_eq!(canonical_provider_name("glm-cn"), "glm"); assert_eq!(canonical_provider_name("bigmodel"), "glm"); assert_eq!(canonical_provider_name("minimax-cn"), "minimax"); @@ -4657,6 +4680,17 @@ mod tests { assert!(ids.contains(&"anthropic/claude-sonnet-4.5".to_string())); } + #[test] + fn curated_models_for_kimi_code_include_official_agent_model() { + let ids: Vec = curated_models_for_provider("kimi-code") + .into_iter() + .map(|(id, _)| id) + .collect(); + + assert!(ids.contains(&"kimi-for-coding".to_string())); + assert!(ids.contains(&"kimi-k2.5".to_string())); + } + #[test] fn supports_live_model_fetch_for_supported_and_unsupported_providers() { assert!(supports_live_model_fetch("openai")); @@ -4864,6 +4898,9 @@ mod tests { assert_eq!(provider_env_var("dashscope-us"), "DASHSCOPE_API_KEY"); assert_eq!(provider_env_var("glm-cn"), "GLM_API_KEY"); assert_eq!(provider_env_var("minimax-cn"), "MINIMAX_API_KEY"); + assert_eq!(provider_env_var("kimi-code"), "KIMI_CODE_API_KEY"); + assert_eq!(provider_env_var("kimi_coding"), "KIMI_CODE_API_KEY"); + assert_eq!(provider_env_var("kimi_for_coding"), "KIMI_CODE_API_KEY"); assert_eq!(provider_env_var("moonshot-intl"), "MOONSHOT_API_KEY"); assert_eq!(provider_env_var("zai-cn"), "ZAI_API_KEY"); assert_eq!(provider_env_var("nvidia"), "NVIDIA_API_KEY"); diff --git a/src/providers/mod.rs b/src/providers/mod.rs index 83e6a64..12ecc0f 100644 --- a/src/providers/mod.rs +++ b/src/providers/mod.rs @@ -1426,6 +1426,7 @@ mod tests { "moonshot-intl", "kimi-code", "moonshot-cn", + "kimi-code", "synthetic", "opencode", "zai",