From 680f5f87cd499ce4d1b7d58f6e478fb704a68928 Mon Sep 17 00:00:00 2001 From: Sergei Razmetov Date: Fri, 24 Jul 2026 16:51:56 +0300 Subject: [PATCH] feat: add moonshotai provider --- src/models.ts | 1 + test/models.test.ts | 57 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/src/models.ts b/src/models.ts index da691d5..89d6712 100644 --- a/src/models.ts +++ b/src/models.ts @@ -43,6 +43,7 @@ const PROVIDERS = new Map([ ["anthropic", { protocol: "anthropic", npm: "@ai-sdk/anthropic" }], ["deepseek", { protocol: "anthropic", npm: "@ai-sdk/anthropic" }], ["zai", { protocol: "openai", npm: "@ai-sdk/openai-compatible" }], + ["moonshotai", { protocol: "openai", npm: "@ai-sdk/openai-compatible" }], ]); type ModelDevEntry = { diff --git a/test/models.test.ts b/test/models.test.ts index d1e8875..55262c0 100644 --- a/test/models.test.ts +++ b/test/models.test.ts @@ -455,6 +455,63 @@ describe("buildConfigModels", () => { }); }); + it("merges Moonshot AI with OpenCode's built-in provider", () => { + const modelsDevData = { + moonshotai: { + models: { + "kimi-k3": { + id: "kimi-k3", + name: "Kimi K3", + limit: { context: 1048576, output: 131072 }, + attachment: true, + reasoning: true, + temperature: false, + tool_call: true, + interleaved: { field: "reasoning_content" }, + modalities: { + input: ["text", "image", "video"], + output: ["text"], + }, + cost: { input: 3, output: 15, cache_read: 0.3 }, + }, + }, + }, + }; + const hubData = { + providers: { + moonshotai: { + models: { + "kimi-k3": { display_name: "Kimi K3 from Hub" }, + }, + }, + }, + }; + + const { models, warnings } = buildConfigModels(modelsDevData, hubData); + + expect(warnings).toEqual([]); + expect(models["kimi-k3"]).toEqual({ + id: "kimi-k3", + name: "Kimi K3", + provider: { + api: "https://hub.coreinfra.ai/openai/api/v1", + npm: "@ai-sdk/openai-compatible", + }, + attachment: true, + reasoning: true, + temperature: false, + tool_call: true, + modalities: { + input: ["text", "image", "video"], + output: ["text"], + }, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 0 }, + limit: { context: 1048576, output: 131072 }, + interleaved: { field: "reasoning_content" }, + headers: {}, + }); + }); + it("uses Responses API for openai but Chat Completions for zai", () => { const modelsDevData = { openai: { models: { "gpt-x": { name: "GPT X" } } },