Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions open-sse/config/providers/registry/opencode/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,26 @@ export const opencodeProvider: RegistryEntry = {
supportsReasoning: true,
interleavedField: "reasoning_content",
},
// #MUSE_SPARK: Muse Spark is served by OpenCode Zen ONLY on the OpenAI
// Responses API (https://opencode.ai/zen/v1/responses), not /chat/completions
// (confirmed in the official OpenCode Zen docs: https://opencode.ai/docs/zen/).
// Without targetFormat:"openai-responses" these models fall through to the
// default chat/completions pass-through and the upstream returns null/empty
// content (see issue #10867). The opencode provider is passthrough, so
// declaring them here only sets the wire format / capability flags — the
// live upstream model list already advertises both ids.
{
id: "muse-spark-1.2",
name: "Muse Spark 1.2",
supportsReasoning: true,
targetFormat: "openai-responses",
},
{
id: "muse-spark-1.2-contributor-free",
name: "Muse Spark 1.2 Contributor Free",
supportsReasoning: true,
targetFormat: "openai-responses",
},
{ id: "deepseek-v4-flash-free", name: "DeepSeek V4 Flash Free", supportsReasoning: true },
// #6998: 2026-07-14 refresh — the upstream free tier rotated its lineup;
// minimax-m3-free, minimax-m2.5-free, ling-2.6-1t-free,
Expand Down
20 changes: 20 additions & 0 deletions tests/unit/opencode-muse-spark-responses-10867.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import test from "node:test";
import assert from "node:assert/strict";
import { opencodeProvider } from "../../open-sse/config/providers/registry/opencode/index.ts";

// #10867: Muse Spark is served by OpenCode Zen only on the OpenAI Responses API
// (/responses), not /chat/completions. Without targetFormat:"openai-responses"
// these models fall through to the default chat/completions pass-through and the
// upstream returns null/empty content.
test("muse-spark-1.2 and muse-spark-1.2-contributor-free route to the Responses API", () => {
for (const id of ["muse-spark-1.2", "muse-spark-1.2-contributor-free"]) {
const model = opencodeProvider.models.find((m) => m.id === id);
assert.ok(model, `${id} should be registered in the opencode provider`);
assert.equal(
model?.targetFormat,
"openai-responses",
`${id} must target the Responses API, not the default chat/completions pass-through`
);
assert.equal(model?.supportsReasoning, true);
}
});