From e8f4664d5ea10d3bd5acf2dfdc700d643a2b1f00 Mon Sep 17 00:00:00 2001 From: can1357 Date: Sun, 21 Jun 2026 02:15:26 +0200 Subject: [PATCH] feat(ai): added support for custom moonshot base url and kimi api key - Added `MOONSHOT_BASE_URL` environment variable support to redirect requests to the Kimi China platform. - Enabled `KIMI_API_KEY` as an alias for the moonshot provider to improve user experience. Fixes #2883 --- packages/ai/src/providers/openai-shared.ts | 10 ++++++++++ packages/catalog/src/provider-models/descriptors.ts | 4 +++- packages/catalog/src/provider-models/openai-compat.ts | 5 ++++- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/packages/ai/src/providers/openai-shared.ts b/packages/ai/src/providers/openai-shared.ts index 405e7bffd..9844917cc 100644 --- a/packages/ai/src/providers/openai-shared.ts +++ b/packages/ai/src/providers/openai-shared.ts @@ -155,6 +155,16 @@ export function resolveOpenAIRequestSetup( let copilotPremiumRequests: number | undefined; let baseUrl = model.baseUrl; + if (model.provider === "moonshot") { + // Bundled `moonshot` catalog models hardcode the international endpoint + // (`api.moonshot.ai`). MOONSHOT_BASE_URL lets users redirect the provider + // at the China platform (`api.moonshot.cn`), which only accepts China keys + // and rejects the international host. (#2883) + const moonshotBaseUrl = $env.MOONSHOT_BASE_URL?.trim(); + if (moonshotBaseUrl) { + baseUrl = moonshotBaseUrl; + } + } if (model.provider === "github-copilot") { apiKey = parseGitHubCopilotApiKey(rawApiKey).accessToken; const copilot = buildCopilotDynamicHeaders({ diff --git a/packages/catalog/src/provider-models/descriptors.ts b/packages/catalog/src/provider-models/descriptors.ts index e1d8600a0..9f1b644c1 100644 --- a/packages/catalog/src/provider-models/descriptors.ts +++ b/packages/catalog/src/provider-models/descriptors.ts @@ -219,7 +219,9 @@ export const CATALOG_PROVIDERS = [ { id: "moonshot", defaultModel: "kimi-k2.7-code", - envVars: ["MOONSHOT_API_KEY"], + // KIMI_API_KEY is the most intuitive name for a Kimi/Moonshot key; accept it + // as a fallback so China users need not learn MOONSHOT_API_KEY. (#2883) + envVars: ["MOONSHOT_API_KEY", "KIMI_API_KEY"], createModelManagerOptions: (config: ModelManagerConfig) => moonshotModelManagerOptions(config), catalogDiscovery: { label: "Moonshot" }, }, diff --git a/packages/catalog/src/provider-models/openai-compat.ts b/packages/catalog/src/provider-models/openai-compat.ts index eb8a4f1b3..91bbc92ad 100644 --- a/packages/catalog/src/provider-models/openai-compat.ts +++ b/packages/catalog/src/provider-models/openai-compat.ts @@ -2493,7 +2493,10 @@ export function moonshotModelManagerOptions( config?: MoonshotModelManagerConfig, ): ModelManagerOptions<"openai-completions"> { const apiKey = config?.apiKey; - const baseUrl = config?.baseUrl ?? "https://api.moonshot.ai/v1"; + // `MOONSHOT_BASE_URL` redirects discovery (and the streaming request that + // inherits this baseUrl) at the Kimi China platform `api.moonshot.cn`; an + // explicit `config.baseUrl` still wins. Mirrors LITELLM_BASE_URL/LM_STUDIO_BASE_URL. (#2883) + const baseUrl = config?.baseUrl ?? Bun.env.MOONSHOT_BASE_URL ?? "https://api.moonshot.ai/v1"; const references = createBundledReferenceMap<"openai-completions">("moonshot"); return { providerId: "moonshot",