From 7fd2bbe7fcf4700682d3bbf30e89c5dfcd66f737 Mon Sep 17 00:00:00 2001 From: Sawyer Cutler Date: Fri, 23 Oct 2026 09:32:07 -0700 Subject: [PATCH] fix(provider): wire reasoningEffort through OpenCode Go and Zen responses --- src/config/index.ts | 6 +++ src/config/inference-sources.test.ts | 60 +++++++++++++++++++++++++++ src/provider/openai-responses.test.ts | 16 +++++++ src/provider/openai-responses.ts | 2 +- 4 files changed, 83 insertions(+), 1 deletion(-) diff --git a/src/config/index.ts b/src/config/index.ts index 349b3850e..dddf89437 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -575,6 +575,9 @@ export function buildGoSource(fields: { providerOptions: { [OPENAI_SESSION_ID_OPTION]: fields.sessionId, [OPENCODE_SESSION_ID_OPTION]: fields.sessionId, + ...(fields.reasoningEffort !== undefined + ? { reasoning_effort: fields.reasoningEffort } + : {}), }, }, }; @@ -642,6 +645,9 @@ export function buildZenSource(fields: { providerOptions: { [OPENAI_SESSION_ID_OPTION]: fields.sessionId, [OPENCODE_SESSION_ID_OPTION]: fields.sessionId, + ...(fields.reasoningEffort !== undefined + ? { reasoning_effort: fields.reasoningEffort } + : {}), }, }, }; diff --git a/src/config/inference-sources.test.ts b/src/config/inference-sources.test.ts index 6cfc60ec4..9671bfc02 100644 --- a/src/config/inference-sources.test.ts +++ b/src/config/inference-sources.test.ts @@ -820,6 +820,66 @@ describe("reasoning effort on the wire", () => { ); }); + test("forwards reasoning effort on OpenCode Go and Zen openai-responses sources", () => { + const catalogEntries: ProviderCatalogEntry[] = [ + { + name: "opencode-go", + baseURL: "https://opencode.ai/zen/go/v1", + apiKey: "sk-go", + models: ["muse-spark-1.3-contributor", "grok-4.6", "gpt-5.6-luna"], + opencodeGo: true, + }, + { + name: ZEN_PROVIDER_ID, + baseURL: ZEN_DEFAULT_BASE_URL, + apiKey: "zen-key", + models: [ + "muse-spark-1.3-contributor-free", + "muse-spark-1.3", + "grok-4.6", + "gpt-5.6-luna", + ], + }, + ]; + for (const [provider, models] of [ + [ + "opencode-go", + ["muse-spark-1.3-contributor", "grok-4.6", "gpt-5.6-luna"], + ], + [ + ZEN_PROVIDER_ID, + [ + "muse-spark-1.3-contributor-free", + "muse-spark-1.3", + "grok-4.6", + "gpt-5.6-luna", + ], + ], + ] as const) { + for (const model of models) { + const withEffort = buildInferenceSourceForRef( + { provider, model, reasoningEffort: "low" }, + { sessionId: "s1", catalog: catalogEntries }, + undefined, + ); + expect(withEffort?.provider).toBe(OPENAI_RESPONSES_PROVIDER); + expect(withEffort?.defaults?.providerOptions).toMatchObject({ + reasoning_effort: "low", + }); + + const unset = buildInferenceSourceForRef( + { provider, model }, + { sessionId: "s1", catalog: catalogEntries }, + undefined, + ); + expect(unset?.provider).toBe(OPENAI_RESPONSES_PROVIDER); + expect(unset?.defaults?.providerOptions).not.toHaveProperty( + "reasoning_effort", + ); + } + } + }); + test("a hand-edited first-class row does not leak the operator ladder", () => { // The ladder override is a custom-OpenAI-compatible-provider concept. A // first-class row (OpenCode Go here) that somehow carries reasoningEfforts diff --git a/src/provider/openai-responses.test.ts b/src/provider/openai-responses.test.ts index a326e1bb3..5caa3f63f 100644 --- a/src/provider/openai-responses.test.ts +++ b/src/provider/openai-responses.test.ts @@ -70,6 +70,22 @@ describe("openai-responses buildRequest", () => { ) as Record; expect(body).not.toHaveProperty("prompt_cache_key"); }); + + test("serializes reasoning.effort from providerOptions.reasoning_effort", () => { + const body = JSON.parse( + adapter().buildRequest([userTurn("hi")], "gpt-5.6-luna", { + providerOptions: { reasoning_effort: "low" }, + }).body, + ) as Record; + expect(body["reasoning"]).toEqual({ summary: "auto", effort: "low" }); + }); + + test("omits reasoning.effort when providerOptions.reasoning_effort is absent", () => { + const body = JSON.parse( + adapter().buildRequest([userTurn("hi")], "gpt-5.6-luna", {}).body, + ) as Record; + expect(body["reasoning"]).toEqual({ summary: "auto" }); + }); }); describe("openai-responses promotion cache safety", () => { diff --git a/src/provider/openai-responses.ts b/src/provider/openai-responses.ts index 23452c2c2..0a8f5e9c2 100644 --- a/src/provider/openai-responses.ts +++ b/src/provider/openai-responses.ts @@ -21,7 +21,7 @@ export const hostQuirks: ResponsesQuirks = { }, systemPrompt: { role: "system", shape: "string" }, contentShape: "flat", - reasoning: { summary: "auto" }, + reasoning: { summary: "auto", effortOption: "reasoning_effort" }, }; export const createOpenAIResponsesAdapter: AdapterFactory =