From 50b724f96e73408fd717faf49503c70b9b087456 Mon Sep 17 00:00:00 2001 From: bacnh85 Date: Fri, 4 Sep 2026 09:40:27 +0700 Subject: [PATCH 1/2] fix(providers): route opencode-go/muse-spark-1.3-contributor to Responses API Upstream serves Muse Spark only on /v1/responses; without a registry targetFormat entry the executor falls back to /chat/completions and the upstream returns 500 (same class as #12196). Add base + minimal/low/medium/ high/xhigh effort aliases (verified via `opencode models opencode-go --refresh --verbose`) with targetFormat openai-responses, register the effort tiers for alias parsing, and cover with regression tests. Fixes #12674 --- .../providers/registry/opencode/go/index.ts | 72 ++++++++++++++++++ open-sse/executors/opencode.ts | 3 + .../opencode-go-muse-spark-1-3-12674.test.ts | 75 +++++++++++++++++++ 3 files changed, 150 insertions(+) create mode 100644 tests/unit/opencode-go-muse-spark-1-3-12674.test.ts diff --git a/open-sse/config/providers/registry/opencode/go/index.ts b/open-sse/config/providers/registry/opencode/go/index.ts index 645a828feda..8ac88f1a993 100644 --- a/open-sse/config/providers/registry/opencode/go/index.ts +++ b/open-sse/config/providers/registry/opencode/go/index.ts @@ -226,6 +226,78 @@ export const opencode_goProvider: RegistryEntry = { supportsVideo: true, targetFormat: "openai-responses", }, + // #12674: Muse Spark 1.3 Contributor — base + effort-tier aliases from the + // OpenCode Go registry (`opencode models opencode-go --refresh --verbose`; + // exact suffix set: minimal/low/medium/high/xhigh, no max — same as 1.2). + // Upstream serves Muse Spark only on the Responses API; without + // targetFormat:"openai-responses" these fall through to /chat/completions + // and the upstream returns 500 (same class as #12196). + { + id: "muse-spark-1.3-contributor", + name: "Muse Spark 1.3 Contributor", + contextLength: 1048576, + maxOutputTokens: 131072, + supportsReasoning: true, + supportsVision: true, + supportsAudio: true, + supportsVideo: true, + targetFormat: "openai-responses", + }, + { + id: "muse-spark-1.3-contributor-minimal", + name: "Muse Spark 1.3 Contributor (minimal effort)", + contextLength: 1048576, + maxOutputTokens: 131072, + supportsReasoning: true, + supportsVision: true, + supportsAudio: true, + supportsVideo: true, + targetFormat: "openai-responses", + }, + { + id: "muse-spark-1.3-contributor-low", + name: "Muse Spark 1.3 Contributor (low effort)", + contextLength: 1048576, + maxOutputTokens: 131072, + supportsReasoning: true, + supportsVision: true, + supportsAudio: true, + supportsVideo: true, + targetFormat: "openai-responses", + }, + { + id: "muse-spark-1.3-contributor-medium", + name: "Muse Spark 1.3 Contributor (medium effort)", + contextLength: 1048576, + maxOutputTokens: 131072, + supportsReasoning: true, + supportsVision: true, + supportsAudio: true, + supportsVideo: true, + targetFormat: "openai-responses", + }, + { + id: "muse-spark-1.3-contributor-high", + name: "Muse Spark 1.3 Contributor (high effort)", + contextLength: 1048576, + maxOutputTokens: 131072, + supportsReasoning: true, + supportsVision: true, + supportsAudio: true, + supportsVideo: true, + targetFormat: "openai-responses", + }, + { + id: "muse-spark-1.3-contributor-xhigh", + name: "Muse Spark 1.3 Contributor (xhigh effort)", + contextLength: 1048576, + maxOutputTokens: 131072, + supportsReasoning: true, + supportsVision: true, + supportsAudio: true, + supportsVideo: true, + targetFormat: "openai-responses", + }, // #8353: Grok 4.5 + effort tiers from the OpenCode Go registry. { id: "grok-4.5", diff --git a/open-sse/executors/opencode.ts b/open-sse/executors/opencode.ts index bb3c10845ba..11e4880b726 100644 --- a/open-sse/executors/opencode.ts +++ b/open-sse/executors/opencode.ts @@ -85,6 +85,8 @@ const OPENCODE_FREE_MODELS = new Set([ * grok-4.5 low/medium/high; hy3 none/low/high; kimi-k3 max; * qwen3.6-plus / qwen3.7-max / qwen3.7-plus high/max; * muse-spark-1.2-contributor minimal/low/medium/high/xhigh (no max) + * - #12674 Muse Spark 1.3 Contributor: minimal/low/medium/high/xhigh (no max), + * verified via `opencode models opencode-go --refresh --verbose` */ const EFFORT_TIERS: Record = { "deepseek-v4-pro": EFFORT_LEVELS, @@ -98,6 +100,7 @@ const EFFORT_TIERS: Record = { "qwen3.7-max": ["high", "max"], "qwen3.7-plus": ["high", "max"], "muse-spark-1.2-contributor": ["minimal", "low", "medium", "high", "xhigh"], + "muse-spark-1.3-contributor": ["minimal", "low", "medium", "high", "xhigh"], }; /** diff --git a/tests/unit/opencode-go-muse-spark-1-3-12674.test.ts b/tests/unit/opencode-go-muse-spark-1-3-12674.test.ts new file mode 100644 index 00000000000..bc9f485fb04 --- /dev/null +++ b/tests/unit/opencode-go-muse-spark-1-3-12674.test.ts @@ -0,0 +1,75 @@ +import assert from "node:assert/strict"; +import test from "node:test"; + +import { + parseEffortLevel, + resolveOpencodeTargetFormat, +} from "../../open-sse/executors/opencode.ts"; + +const { REGISTRY } = (await import("../../open-sse/config/providerRegistry.ts")) as { + REGISTRY: Record< + string, + { + models?: Array<{ + id: string; + targetFormat?: string; + supportsReasoning?: boolean; + contextLength?: number; + maxOutputTokens?: number; + }>; + } + >; +}; + +// #12674: opencode-go/muse-spark-1.3-contributor (upstream release 2026-09-02) +// 500s via /v1/chat/completions because the upstream serves Muse Spark only on +// the Responses API and the model had no registry targetFormat entry, so the +// executor fell back to "openai". Base + effort-tier alias set verified via +// `opencode models opencode-go --refresh --verbose` (minimal/low/medium/high/ +// xhigh, no max — same as 1.2). +const BASE = "muse-spark-1.3-contributor"; +const ALIASES = ["minimal", "low", "medium", "high", "xhigh"].map((effort) => ({ + alias: `${BASE}-${effort}`, + effort, +})); + +function goModels() { + const entry = REGISTRY["opencode-go"]; + assert.ok(entry, "opencode-go registry entry must exist"); + return entry.models ?? []; +} + +test("#12674 registry: 1.3 base + effort aliases target the Responses API", () => { + const models = goModels(); + for (const id of [BASE, ...ALIASES.map((a) => a.alias)]) { + const model = models.find((m) => m.id === id); + assert.ok(model, `${id} must be registered on opencode-go`); + assert.equal(model?.targetFormat, "openai-responses", `${id} must target Responses`); + assert.equal(model?.supportsReasoning, true, `${id} must support reasoning`); + assert.equal(model?.contextLength, 1048576, `${id} context must be 1M`); + assert.equal(model?.maxOutputTokens, 131072, `${id} max output must be 128K`); + } +}); + +test("#12674 executor: 1.3 resolves to openai-responses (URL selection)", () => { + assert.equal(resolveOpencodeTargetFormat("opencode-go", BASE), "openai-responses"); + assert.equal(resolveOpencodeTargetFormat("opencode-go", `${BASE}-high`), "openai-responses"); +}); + +for (const { alias, effort } of ALIASES) { + test(`#12674 parseEffortLevel: ${alias} → ${effort}`, () => { + assert.deepEqual(parseEffortLevel(alias), { baseModel: BASE, effort }); + }); +} + +test("#12674 parseEffortLevel: 1.3 has no max tier", () => { + assert.equal(parseEffortLevel(`${BASE}-max`), null); +}); + +test("#12674 catalog: 1.3 aliases stay Go-only (not on opencode-zen)", () => { + const zenIds = new Set((REGISTRY["opencode-zen"]?.models ?? []).map((m) => m.id)); + assert.equal(zenIds.has(BASE), false, "opencode-zen must not expose 1.3 base"); + for (const { alias } of ALIASES) { + assert.equal(zenIds.has(alias), false, `opencode-zen must not expose ${alias}`); + } +}); From f36d6ba4fa96b7864e2131058885f4f0831d64be Mon Sep 17 00:00:00 2001 From: bacnh85 Date: Fri, 4 Sep 2026 09:41:20 +0700 Subject: [PATCH 2/2] docs: changelog fragment for #12675 --- changelog.d/fixes/12675-opencode-go-muse-spark-1-3-responses.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/fixes/12675-opencode-go-muse-spark-1-3-responses.md diff --git a/changelog.d/fixes/12675-opencode-go-muse-spark-1-3-responses.md b/changelog.d/fixes/12675-opencode-go-muse-spark-1-3-responses.md new file mode 100644 index 00000000000..20dd6c71b96 --- /dev/null +++ b/changelog.d/fixes/12675-opencode-go-muse-spark-1-3-responses.md @@ -0,0 +1 @@ +- Fix `opencode-go/muse-spark-1.3-contributor` returning 500 by routing it (base + minimal/low/medium/high/xhigh effort aliases) to the Responses API like the 1.2 family. (#12675 — thanks @bacnh85)