From da4a91b3647f90fcab3c980150e6d0d476bdc28d Mon Sep 17 00:00:00 2001 From: Ryan Loney Date: Mon, 24 Aug 2026 04:34:00 -0700 Subject: [PATCH] fix(opencode): preserve Cerebras completion limit (#13289) * fix(opencode): preserve Cerebras completion limit * chore: annotate Kilo-specific changes --- packages/opencode/src/provider/transform.ts | 13 ++++++ packages/opencode/src/session/llm.ts | 16 ++++++- .../opencode/test/provider/transform.test.ts | 42 +++++++++++++++++++ 3 files changed, 69 insertions(+), 2 deletions(-) diff --git a/packages/opencode/src/provider/transform.ts b/packages/opencode/src/provider/transform.ts index 386a174741..a2c6094126 100644 --- a/packages/opencode/src/provider/transform.ts +++ b/packages/opencode/src/provider/transform.ts @@ -1724,6 +1724,19 @@ export function maxOutputTokens(model: Provider.Model, outputTokenMax = OUTPUT_T return Math.min(model.limit.output, outputTokenMax) || outputTokenMax } +// kilocode_change start +export function maxOutputTokensForRequest(input: { + model: Provider.Model + options: Record + maxOutputTokens: number | undefined +}): number | undefined { + if (input.model.api.npm === "@ai-sdk/cerebras" && input.options.max_completion_tokens !== undefined) { + return undefined + } + return input.maxOutputTokens +} +// kilocode_change end + type JsonRecord = Record function isPlainObject(value: unknown): value is JsonRecord { diff --git a/packages/opencode/src/session/llm.ts b/packages/opencode/src/session/llm.ts index 9f16e2e017..620a8e6fe2 100644 --- a/packages/opencode/src/session/llm.ts +++ b/packages/opencode/src/session/llm.ts @@ -312,7 +312,13 @@ const live: Layer.Layer< temperature: prepared.params.temperature, topP: prepared.params.topP, topK: prepared.params.topK, - maxOutputTokens: prepared.params.maxOutputTokens, + // kilocode_change start + maxOutputTokens: ProviderTransform.maxOutputTokensForRequest({ + model: input.model, + options: prepared.params.options, + maxOutputTokens: prepared.params.maxOutputTokens, + }), + // kilocode_change end providerOptions: prepared.params.options, headers: prepared.headers, abort: input.abort, @@ -388,9 +394,15 @@ const live: Layer.Layer< topK: prepared.params.topK, providerOptions: ProviderTransform.providerOptions(input.model, prepared.params.options), activeTools: Object.keys(prepared.tools).filter((x) => x !== "invalid"), + // kilocode_change start tools: prepared.tools, toolChoice: input.toolChoice, - maxOutputTokens: prepared.params.maxOutputTokens, + maxOutputTokens: ProviderTransform.maxOutputTokensForRequest({ + model: input.model, + options: prepared.params.options, + maxOutputTokens: prepared.params.maxOutputTokens, + }), + // kilocode_change end abortSignal: input.abort, ...KiloLLM.timeout({ options: prepared.params.options, fallback: item.options, log: l }), // kilocode_change headers: prepared.headers, diff --git a/packages/opencode/test/provider/transform.test.ts b/packages/opencode/test/provider/transform.test.ts index 0a96b4782a..f5107fabdf 100644 --- a/packages/opencode/test/provider/transform.test.ts +++ b/packages/opencode/test/provider/transform.test.ts @@ -4699,6 +4699,48 @@ describe("ProviderTransform.variants", () => { expect(result.low).toEqual({ reasoningEffort: "low" }) expect(result.high).toEqual({ reasoningEffort: "high" }) }) + + // kilocode_change start + test("omits the generic output cap when an exact max_completion_tokens value is configured", () => { + const model = createMockModel({ + id: "cerebras/gpt-oss-120b", + providerID: "cerebras", + api: { + id: "gpt-oss-120b", + url: "https://api.cerebras.ai/v1", + npm: "@ai-sdk/cerebras", + }, + }) + + const result = ProviderTransform.maxOutputTokensForRequest({ + model, + options: { max_completion_tokens: 64 }, + maxOutputTokens: 32_000, + }) + + expect(result).toBeUndefined() + }) + + test("keeps the generic output cap when no exact value is configured", () => { + const model = createMockModel({ + id: "cerebras/gpt-oss-120b", + providerID: "cerebras", + api: { + id: "gpt-oss-120b", + url: "https://api.cerebras.ai/v1", + npm: "@ai-sdk/cerebras", + }, + }) + + const result = ProviderTransform.maxOutputTokensForRequest({ + model, + options: {}, + maxOutputTokens: 32_000, + }) + + expect(result).toBe(32_000) + }) + // kilocode_change end }) describe("@ai-sdk/togetherai", () => {