diff --git a/packages/opencode-go/src/endpoint.test.ts b/packages/opencode-go/src/endpoint.test.ts index 645a0d3fb..db1879043 100644 --- a/packages/opencode-go/src/endpoint.test.ts +++ b/packages/opencode-go/src/endpoint.test.ts @@ -17,6 +17,19 @@ describe("protocolForGoModel", () => { expect(protocolForGoModel("muse-spark-1.3-contributor")).toBe("responses"); expect(protocolForGoModel("muse-spark-1.2-contributor")).toBe("responses"); expect(protocolForGoModel("minimax-m3")).toBe("messages"); + expect(protocolForGoModel("minimax-m2.7")).toBe("messages"); + expect(protocolForGoModel("minimax-m2.5")).toBe("messages"); + expect(protocolForGoModel("qwen3.8-max")).toBe("messages"); + expect(protocolForGoModel("grok-4.5")).toBe("responses"); + expect(protocolForGoModel("grok-4.7")).toBe("responses"); + expect(protocolForGoModel("gpt-6-luna")).toBe("responses"); + expect(protocolForGoModel("claude-haiku-5-5")).toBe("messages"); + expect(protocolForGoModel("qwen3.8-flash")).toBe("messages"); + expect(protocolForGoModel("glm-5.3")).toBe("chat-completions"); + expect(protocolForGoModel("deepseek-v4.1-flash")).toBe("chat-completions"); + expect(protocolForGoModel("mimo-v2.6-flash")).toBe("chat-completions"); + expect(protocolForGoModel("hy4-preview")).toBe("chat-completions"); + expect(protocolForGoModel("space-bunny")).toBe("chat-completions"); }); test("returns undefined for unknown models", () => { @@ -63,10 +76,50 @@ describe("resolveGoEndpoint", () => { }); test("routes messages models to anthropic base", () => { - const ep = resolveGoEndpoint("minimax-m3"); - expect(ep.adapter).toBe("anthropic"); - expect(ep.protocol).toBe("messages"); - expect(ep.baseURL).toBe("https://opencode.ai/zen/go"); + for (const id of [ + "minimax-m3", + "minimax-m2.7", + "minimax-m2.5", + "qwen3.8-max", + "qwen3.8-flash", + "claude-haiku-5-5", + "qwen3.7-max", + ]) { + const ep = resolveGoEndpoint(id); + expect(ep.adapter).toBe("anthropic"); + expect(ep.protocol).toBe("messages"); + expect(ep.baseURL).toBe("https://opencode.ai/zen/go"); + } + }); + + test("routes responses models to openai-responses adapter (live Go docs)", () => { + for (const id of ["grok-4.7", "grok-4.6", "grok-4.5", "gpt-6-luna"]) { + const ep = resolveGoEndpoint(id); + expect(ep.adapter).toBe("openai-responses"); + expect(ep.protocol).toBe("responses"); + expect(ep.baseURL).toContain("/zen/go/v1"); + } + }); + + test("routes new chat-completions models to openai-compatible base (live Go docs)", () => { + for (const id of [ + "glm-5.3-flash", + "glm-5.3", + "longcat-2.0", + "longcat-2.5-preview-free", + "step-5-preview-free", + "deepseek-v4.1-flash", + "deepseek-v4-flash-vision-exp", + "mimo-v2.6-flash", + "mimo-v2.6-pro", + "hy4-preview", + "space-bunny", + ]) { + const ep = resolveGoEndpoint(id); + expect(ep.adapter).toBe("openai-compatible"); + expect(ep.protocol).toBe("chat-completions"); + expect(ep.baseURL).toContain("/zen/go/v1"); + } }); test("unknown models default to chat-completions", () => { @@ -136,6 +189,8 @@ describe("buildGoCatalogEntry", () => { expect(entry.name).toBe("opencode-go"); expect(entry.models.length).toBeGreaterThan(0); expect(entry.protocols["minimax-m3"]).toBe("messages"); + expect(entry.protocols["qwen3.8-max"]).toBe("messages"); + expect(entry.protocols["grok-4.5"]).toBe("responses"); expect(entry.protocols["kimi-k2.7-code"]).toBe("chat-completions"); }); }); diff --git a/packages/opencode-go/src/models.ts b/packages/opencode-go/src/models.ts index 4d49c6b29..ecce3b046 100644 --- a/packages/opencode-go/src/models.ts +++ b/packages/opencode-go/src/models.ts @@ -2,6 +2,7 @@ // Selectable ids come from live GET /zen/go/v1/models in the host; this // packaged list is used when that fetch has not succeeded. Protocol // routing stays here. Live ids absent from PROTOCOL_BY_ID use Chat Completions. +// MiniMax and Qwen3.8 Max are messages on Go, unlike Zen chat-completions. export type GoProtocol = "chat-completions" | "responses" | "messages"; @@ -12,7 +13,10 @@ interface GoModel { } export const OPENCODE_GO_MODELS = [ - { id: "grok-4.5", name: "Grok 4.5", protocol: "chat-completions" }, + { id: "grok-4.7", name: "Grok 4.7", protocol: "responses" }, + { id: "grok-4.6", name: "Grok 4.6", protocol: "responses" }, + { id: "grok-4.5", name: "Grok 4.5", protocol: "responses" }, + { id: "gpt-6-luna", name: "GPT 6 Luna", protocol: "responses" }, { id: "gpt-5.6-luna", name: "GPT 5.6 Luna", protocol: "responses" }, { id: "muse-spark-1.3-contributor", @@ -24,6 +28,17 @@ export const OPENCODE_GO_MODELS = [ name: "Muse Spark 1.2 Contributor", protocol: "responses", }, + { id: "claude-haiku-5-5", name: "Claude Haiku 5.5", protocol: "messages" }, + { id: "minimax-m3", name: "MiniMax M3", protocol: "messages" }, + { id: "minimax-m2.7", name: "MiniMax M2.7", protocol: "messages" }, + { id: "minimax-m2.5", name: "MiniMax M2.5", protocol: "messages" }, + { id: "qwen3.8-max", name: "Qwen3.8 Max", protocol: "messages" }, + { id: "qwen3.8-flash", name: "Qwen3.8 Flash", protocol: "messages" }, + { id: "qwen3.7-max", name: "Qwen3.7 Max", protocol: "messages" }, + { id: "qwen3.7-plus", name: "Qwen3.7 Plus", protocol: "messages" }, + { id: "qwen3.6-plus", name: "Qwen3.6 Plus", protocol: "messages" }, + { id: "glm-5.3-flash", name: "GLM-5.3-Flash", protocol: "chat-completions" }, + { id: "glm-5.3", name: "GLM-5.3", protocol: "chat-completions" }, { id: "glm-5.2", name: "GLM-5.2", protocol: "chat-completions" }, { id: "glm-5.1", name: "GLM-5.1", protocol: "chat-completions" }, { id: "kimi-k3", name: "Kimi K3", protocol: "chat-completions" }, @@ -33,6 +48,22 @@ export const OPENCODE_GO_MODELS = [ protocol: "chat-completions", }, { id: "kimi-k2.6", name: "Kimi K2.6", protocol: "chat-completions" }, + { id: "longcat-2.0", name: "LongCat-2.0", protocol: "chat-completions" }, + { + id: "longcat-2.5-preview-free", + name: "LongCat 2.5 Preview Free", + protocol: "chat-completions", + }, + { + id: "step-5-preview-free", + name: "Step 5 Preview Free", + protocol: "chat-completions", + }, + { + id: "deepseek-v4.1-flash", + name: "DeepSeek V4.1 Flash", + protocol: "chat-completions", + }, { id: "deepseek-v4-pro", name: "DeepSeek V4 Pro", @@ -43,16 +74,22 @@ export const OPENCODE_GO_MODELS = [ name: "DeepSeek V4 Flash", protocol: "chat-completions", }, + { + id: "deepseek-v4-flash-vision-exp", + name: "DeepSeek V4 Flash Vision Exp", + protocol: "chat-completions", + }, + { + id: "mimo-v2.6-flash", + name: "MiMo-V2.6-Flash", + protocol: "chat-completions", + }, + { id: "mimo-v2.6-pro", name: "MiMo-V2.6-Pro", protocol: "chat-completions" }, { id: "mimo-v2.5", name: "MiMo-V2.5", protocol: "chat-completions" }, { id: "mimo-v2.5-pro", name: "MiMo-V2.5-Pro", protocol: "chat-completions" }, - { id: "minimax-m3", name: "MiniMax M3", protocol: "messages" }, - { id: "minimax-m2.7", name: "MiniMax M2.7", protocol: "messages" }, - { id: "minimax-m2.5", name: "MiniMax M2.5", protocol: "messages" }, - { id: "qwen3.8-max", name: "Qwen3.8 Max", protocol: "messages" }, - { id: "qwen3.7-max", name: "Qwen3.7 Max", protocol: "messages" }, - { id: "qwen3.7-plus", name: "Qwen3.7 Plus", protocol: "messages" }, - { id: "qwen3.6-plus", name: "Qwen3.6 Plus", protocol: "messages" }, + { id: "hy4-preview", name: "Hy4 Preview", protocol: "chat-completions" }, { id: "hy3", name: "Hy3", protocol: "chat-completions" }, + { id: "space-bunny", name: "Space Bunny", protocol: "chat-completions" }, ] as const satisfies readonly GoModel[]; export type GoModelId = (typeof OPENCODE_GO_MODELS)[number]["id"]; diff --git a/src/config/inference-sources.test.ts b/src/config/inference-sources.test.ts index 5035abcd9..88856c800 100644 --- a/src/config/inference-sources.test.ts +++ b/src/config/inference-sources.test.ts @@ -478,14 +478,23 @@ describe("protocol flag routing", () => { expect(responses?.provider).toBe("openai-responses"); expect(responses?.baseURL).toBe("https://opencode.ai/zen/go/v1"); - const messages = buildInferenceSourceForRef( + const minimax = buildInferenceSourceForRef( { provider: "opencode-go", model: "minimax-m3" }, ctx, undefined, ); - expect(messages?.provider).toBe("opencode-go-messages"); - expect(messages?.baseURL).toBe("https://opencode.ai/zen/go"); - expect(messages?.model).toBe("minimax-m3"); + expect(minimax?.provider).toBe("opencode-go-messages"); + expect(minimax?.baseURL).toBe("https://opencode.ai/zen/go"); + expect(minimax?.model).toBe("minimax-m3"); + + const qwenMax = buildInferenceSourceForRef( + { provider: "opencode-go", model: "qwen3.8-max" }, + ctx, + undefined, + ); + expect(qwenMax?.provider).toBe("opencode-go-messages"); + expect(qwenMax?.baseURL).toBe("https://opencode.ai/zen/go"); + expect(qwenMax?.model).toBe("qwen3.8-max"); }); });