diff --git a/packages/ai/src/providers/gitlab-duo.ts b/packages/ai/src/providers/gitlab-duo.ts index 834717c09..8ddc8cf3b 100644 --- a/packages/ai/src/providers/gitlab-duo.ts +++ b/packages/ai/src/providers/gitlab-duo.ts @@ -267,6 +267,11 @@ export function streamGitLabDuo( ...options.headers, }; + const reasoningEffort = + options.reasoning === "off" + ? undefined + : (options.reasoning as "minimal" | "low" | "medium" | "high" | "xhigh" | undefined); + const inner = mapping.provider === "anthropic" ? streamAnthropic( @@ -295,11 +300,11 @@ export function streamGitLabDuo( sessionId: options.sessionId, providerSessionState: options.providerSessionState, onPayload: options.onPayload, - thinkingEnabled: Boolean(options.reasoning) && model.reasoning, - thinkingBudgetTokens: options.reasoning - ? (options.thinkingBudgets?.[options.reasoning] ?? ANTHROPIC_THINKING[options.reasoning]) + thinkingEnabled: Boolean(reasoningEffort) && model.reasoning, + thinkingBudgetTokens: reasoningEffort + ? (options.thinkingBudgets?.[reasoningEffort] ?? ANTHROPIC_THINKING[reasoningEffort]) : undefined, - reasoning: options.reasoning, + reasoning: reasoningEffort, toolChoice: mapAnthropicToolChoice(options.toolChoice), }, ) @@ -329,7 +334,7 @@ export function streamGitLabDuo( sessionId: options.sessionId, providerSessionState: options.providerSessionState, onPayload: options.onPayload, - reasoning: options.reasoning, + reasoning: reasoningEffort, toolChoice: options.toolChoice, } satisfies OpenAIResponsesOptions, ) @@ -358,7 +363,7 @@ export function streamGitLabDuo( sessionId: options.sessionId, providerSessionState: options.providerSessionState, onPayload: options.onPayload, - thinkingLevel: options.reasoning, + reasoning: reasoningEffort, toolChoice: options.toolChoice, } satisfies OpenAICompletionsOptions, ); diff --git a/packages/ai/src/providers/kimi.ts b/packages/ai/src/providers/kimi.ts index 07e7e9108..f9729bf79 100644 --- a/packages/ai/src/providers/kimi.ts +++ b/packages/ai/src/providers/kimi.ts @@ -62,9 +62,10 @@ export function streamKimi( // Calculate thinking budget from reasoning level const reasoning = options?.reasoning; - const thinkingEnabled = !!reasoning && model.reasoning; - const thinkingBudget = reasoning - ? (options?.thinkingBudgets?.[reasoning] ?? ANTHROPIC_THINKING[reasoning]) + const reasoningEffort = reasoning === "off" ? undefined : reasoning; + const thinkingEnabled = !!reasoningEffort && model.reasoning; + const thinkingBudget = reasoningEffort + ? (options?.thinkingBudgets?.[reasoningEffort] ?? ANTHROPIC_THINKING[reasoningEffort]) : undefined; const innerStream = streamAnthropic(anthropicModel, context, { @@ -89,6 +90,7 @@ export function streamKimi( } } else { // OpenAI format - use original model with Kimi headers + const reasoningEffort = options?.reasoning === "off" ? undefined : options?.reasoning; const innerStream = streamOpenAICompletions(model, context, { apiKey: options?.apiKey, temperature: options?.temperature, @@ -102,7 +104,7 @@ export function streamKimi( headers: mergedHeaders, sessionId: options?.sessionId, onPayload: options?.onPayload, - thinkingLevel: options?.reasoning, + reasoning: reasoningEffort, }); for await (const event of innerStream) { diff --git a/packages/ai/src/providers/synthetic.ts b/packages/ai/src/providers/synthetic.ts index d6ea05653..3d6dd1d54 100644 --- a/packages/ai/src/providers/synthetic.ts +++ b/packages/ai/src/providers/synthetic.ts @@ -59,9 +59,10 @@ export function streamSynthetic( // Calculate thinking budget from reasoning level const reasoning = options?.reasoning; - const thinkingEnabled = !!reasoning && model.reasoning; - const thinkingBudget = reasoning - ? (options?.thinkingBudgets?.[reasoning] ?? ANTHROPIC_THINKING[reasoning]) + const reasoningEffort = reasoning === "off" ? undefined : reasoning; + const thinkingEnabled = !!reasoningEffort && model.reasoning; + const thinkingBudget = reasoningEffort + ? (options?.thinkingBudgets?.[reasoningEffort] ?? ANTHROPIC_THINKING[reasoningEffort]) : undefined; const innerStream = streamAnthropic(anthropicModel, context, { @@ -92,6 +93,7 @@ export function streamSynthetic( headers: mergedHeaders, }; + const reasoningEffort = options?.reasoning === "off" ? undefined : options?.reasoning; const innerStream = streamOpenAICompletions(syntheticModel, context, { apiKey: options?.apiKey, temperature: options?.temperature, @@ -105,7 +107,7 @@ export function streamSynthetic( headers: mergedHeaders, sessionId: options?.sessionId, onPayload: options?.onPayload, - thinkingLevel: options?.reasoning, + reasoning: reasoningEffort, }); for await (const event of innerStream) { diff --git a/packages/ai/test/stream.test.ts b/packages/ai/test/stream.test.ts index 94247eff6..fd5180ca6 100644 --- a/packages/ai/test/stream.test.ts +++ b/packages/ai/test/stream.test.ts @@ -534,7 +534,7 @@ describe("Generate E2E Tests", () => { it( "should handle thinking", async () => { - await handleThinking(llm, { thinkingLevel: "high" }); + await handleThinking(llm, { reasoning: "high" }); }, { retry: 2 }, ); @@ -542,7 +542,7 @@ describe("Generate E2E Tests", () => { it( "should handle multi-turn with thinking and tools", async () => { - await multiTurn(llm, { thinkingLevel: "high" }); + await multiTurn(llm, { reasoning: "high" }); }, { retry: 3 }, ); @@ -658,7 +658,7 @@ describe("Generate E2E Tests", () => { it( "should handle thinking mode", async () => { - await handleThinking(llm, { thinkingLevel: "medium" }); + await handleThinking(llm, { reasoning: "medium" }); }, { retry: 3 }, ); @@ -666,7 +666,7 @@ describe("Generate E2E Tests", () => { it( "should handle multi-turn with thinking and tools", async () => { - await multiTurn(llm, { thinkingLevel: "medium" }); + await multiTurn(llm, { reasoning: "medium" }); }, { retry: 3 }, ); @@ -702,7 +702,7 @@ describe("Generate E2E Tests", () => { it( "should handle thinking mode", async () => { - await handleThinking(llm, { thinkingLevel: "medium" }); + await handleThinking(llm, { reasoning: "medium" }); }, { retry: 3 }, ); @@ -710,7 +710,7 @@ describe("Generate E2E Tests", () => { it( "should handle multi-turn with thinking and tools", async () => { - await multiTurn(llm, { thinkingLevel: "medium" }); + await multiTurn(llm, { reasoning: "medium" }); }, { retry: 3 }, ); @@ -746,7 +746,7 @@ describe("Generate E2E Tests", () => { it( "should handle thinking mode", async () => { - await handleThinking(llm, { thinkingLevel: "medium" }); + await handleThinking(llm, { reasoning: "medium" }); }, { retry: 3 }, ); @@ -754,7 +754,7 @@ describe("Generate E2E Tests", () => { it( "should handle multi-turn with thinking and tools", async () => { - await multiTurn(llm, { thinkingLevel: "medium" }); + await multiTurn(llm, { reasoning: "medium" }); }, { retry: 3 }, ); @@ -790,7 +790,7 @@ describe("Generate E2E Tests", () => { it( "should handle thinking mode", async () => { - await handleThinking(llm, { thinkingLevel: "medium" }); + await handleThinking(llm, { reasoning: "medium" }); }, { retry: 3 }, ); @@ -798,7 +798,7 @@ describe("Generate E2E Tests", () => { it( "should handle multi-turn with thinking and tools", async () => { - await multiTurn(llm, { thinkingLevel: "medium" }); + await multiTurn(llm, { reasoning: "medium" }); }, { retry: 2 }, ); @@ -842,7 +842,7 @@ describe("Generate E2E Tests", () => { it.skip( "should handle thinking mode", async () => { - await handleThinking(llm, { thinkingLevel: "medium" }); + await handleThinking(llm, { reasoning: "medium" }); }, { retry: 3 }, ); @@ -850,7 +850,7 @@ describe("Generate E2E Tests", () => { it( "should handle multi-turn with thinking and tools", async () => { - await multiTurn(llm, { thinkingLevel: "medium" }); + await multiTurn(llm, { reasoning: "medium" }); }, { retry: 3 }, ); @@ -886,7 +886,7 @@ describe("Generate E2E Tests", () => { it( "should handle thinking mode", async () => { - await handleThinking(llm, { thinkingLevel: "medium" }); + await handleThinking(llm, { reasoning: "medium" }); }, { retry: 3 }, ); @@ -894,7 +894,7 @@ describe("Generate E2E Tests", () => { it( "should handle multi-turn with thinking and tools", async () => { - await multiTurn(llm, { thinkingLevel: "medium" }); + await multiTurn(llm, { reasoning: "medium" }); }, { retry: 3 }, ); @@ -950,7 +950,7 @@ describe("Generate E2E Tests", () => { it( "should handle multi-turn with thinking and tools", async () => { - await multiTurn(llm, { thinkingLevel: "medium" }); + await multiTurn(llm, { reasoning: "medium" }); }, { retry: 3 }, ); @@ -1076,7 +1076,7 @@ describe("Generate E2E Tests", () => { "should handle thinking", async () => { const thinkingModel = getBundledModel("github-copilot", "gpt-5-mini"); - await handleThinking(thinkingModel, { apiKey: githubCopilotToken, thinkingLevel: "high" }); + await handleThinking(thinkingModel, { apiKey: githubCopilotToken, reasoning: "high" }); }, { retry: 2 }, ); @@ -1085,7 +1085,7 @@ describe("Generate E2E Tests", () => { "should handle multi-turn with thinking and tools", async () => { const thinkingModel = getBundledModel("github-copilot", "gpt-5-mini"); - await multiTurn(thinkingModel, { apiKey: githubCopilotToken, thinkingLevel: "high" }); + await multiTurn(thinkingModel, { apiKey: githubCopilotToken, reasoning: "high" }); }, { retry: 3 }, ); @@ -1318,7 +1318,7 @@ describe("Generate E2E Tests", () => { it.skipIf(!openaiCodexToken)( "should handle thinking", async () => { - await handleThinking(llm, { apiKey: openaiCodexToken, thinkingLevel: "high" }); + await handleThinking(llm, { apiKey: openaiCodexToken, reasoning: "high" }); }, { retry: 3 }, ); @@ -1490,7 +1490,7 @@ describe("Generate E2E Tests", () => { "should handle thinking mode", async () => { if (!llm) return; - await handleThinking(llm, { apiKey: "test", thinkingLevel: "medium" }); + await handleThinking(llm, { apiKey: "test", reasoning: "medium" }); }, { retry: 3 }, ); @@ -1499,7 +1499,7 @@ describe("Generate E2E Tests", () => { "should handle multi-turn with thinking and tools", async () => { if (!llm) return; - await multiTurn(llm, { apiKey: "test", thinkingLevel: "medium" }); + await multiTurn(llm, { apiKey: "test", reasoning: "medium" }); }, { retry: 3 }, ); diff --git a/packages/ai/test/xhigh.test.ts b/packages/ai/test/xhigh.test.ts index 1d3d4955a..5fa795e1a 100644 --- a/packages/ai/test/xhigh.test.ts +++ b/packages/ai/test/xhigh.test.ts @@ -21,7 +21,7 @@ describe.skipIf(!e2eApiKey("OPENAI_API_KEY"))("xhigh reasoning", () => { // Note: codex models only support the responses API, not chat completions it("should work with openai-responses", async () => { const model = getBundledModel("openai", "gpt-5.1-codex-max"); - const s = stream(model, makeContext(), { thinkingLevel: "xhigh" }); + const s = stream(model, makeContext(), { reasoning: "xhigh" }); let hasThinking = false; for await (const event of s) { @@ -40,7 +40,7 @@ describe.skipIf(!e2eApiKey("OPENAI_API_KEY"))("xhigh reasoning", () => { describe("gpt-5-mini (does not support xhigh)", () => { it("should error with openai-responses when using xhigh", async () => { const model = getBundledModel("openai", "gpt-5-mini"); - const s = stream(model, makeContext(), { thinkingLevel: "xhigh" }); + const s = stream(model, makeContext(), { reasoning: "xhigh" }); for await (const _ of s) { // drain events @@ -56,7 +56,7 @@ describe.skipIf(!e2eApiKey("OPENAI_API_KEY"))("xhigh reasoning", () => { ...getBundledModel("openai", "gpt-5-mini"), api: "openai-completions", }; - const s = stream(model, makeContext(), { thinkingLevel: "xhigh" }); + const s = stream(model, makeContext(), { reasoning: "xhigh" }); for await (const _ of s) { // drain events