From 4ad762dd643b5adc433ffe41f2341fba73c2cf0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CSebastian?= <64795732+slegarraga@users.noreply.github.com> Date: Thu, 11 Jun 2026 03:38:17 -0400 Subject: [PATCH] fix: expose openai-compatible none variants --- packages/cli/README.md | 4 ++++ packages/cli/src/provider/transform.ts | 11 ++++++++-- packages/cli/test/provider/transform.test.ts | 23 ++++++++++++++++++-- 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/packages/cli/README.md b/packages/cli/README.md index bcc920d..a43bcd8 100644 --- a/packages/cli/README.md +++ b/packages/cli/README.md @@ -68,6 +68,10 @@ Aictrl reads config from `.aictrl/` (project) or `~/.config/aictrl/` (global). | Google | `GOOGLE_API_KEY` | | OpenRouter | `OPENROUTER_API_KEY` | +Use `--variant` to select provider-specific reasoning effort. For OpenAI-compatible +Ollama models, `--variant none` sends `reasoning_effort: "none"` to disable +thinking; model `options` can also set `reasoning_effort: "none"` directly. + ## Local Development ```bash diff --git a/packages/cli/src/provider/transform.ts b/packages/cli/src/provider/transform.ts index 93f5a24..7bd60ff 100644 --- a/packages/cli/src/provider/transform.ts +++ b/packages/cli/src/provider/transform.ts @@ -331,7 +331,12 @@ export namespace ProviderTransform { const OPENAI_EFFORTS = ["none", "minimal", ...WIDELY_SUPPORTED_EFFORTS, "xhigh"] export function variants(model: Provider.Model): Record> { - if (!model.capabilities.reasoning) return {} + if (!model.capabilities.reasoning) { + if (model.api.npm === "@ai-sdk/openai-compatible") { + return { none: { reasoningEffort: "none" } } + } + return {} + } const id = model.id.toLowerCase() const isAnthropicAdaptive = ["opus-4-6", "opus-4.6", "sonnet-4-6", "sonnet-4.6"].some((v) => @@ -464,9 +469,11 @@ export namespace ProviderTransform { // https://v5.ai-sdk.dev/providers/ai-sdk-providers/deepinfra case "venice-ai-sdk-provider": // https://docs.venice.ai/overview/guides/reasoning-models#reasoning-effort - case "@ai-sdk/openai-compatible": return Object.fromEntries(WIDELY_SUPPORTED_EFFORTS.map((effort) => [effort, { reasoningEffort: effort }])) + case "@ai-sdk/openai-compatible": + return Object.fromEntries(OPENAI_EFFORTS.map((effort) => [effort, { reasoningEffort: effort }])) + case "@ai-sdk/azure": // https://v5.ai-sdk.dev/providers/ai-sdk-providers/azure if (id === "o1-mini") return {} diff --git a/packages/cli/test/provider/transform.test.ts b/packages/cli/test/provider/transform.test.ts index 8e3c36d..15366fa 100644 --- a/packages/cli/test/provider/transform.test.ts +++ b/packages/cli/test/provider/transform.test.ts @@ -1991,7 +1991,7 @@ describe("ProviderTransform.variants", () => { }) describe("@ai-sdk/openai-compatible", () => { - test("returns WIDELY_SUPPORTED_EFFORTS with reasoningEffort", () => { + test("returns OPENAI_EFFORTS with reasoningEffort", () => { const model = createMockModel({ id: "custom-provider/custom-model", providerID: "custom-provider", @@ -2002,10 +2002,29 @@ describe("ProviderTransform.variants", () => { }, }) const result = ProviderTransform.variants(model) - expect(Object.keys(result)).toEqual(["low", "medium", "high"]) + expect(Object.keys(result)).toEqual(["none", "minimal", "low", "medium", "high", "xhigh"]) + expect(result.none).toEqual({ reasoningEffort: "none" }) + expect(result.minimal).toEqual({ reasoningEffort: "minimal" }) expect(result.low).toEqual({ reasoningEffort: "low" }) expect(result.high).toEqual({ reasoningEffort: "high" }) }) + + test("returns none variant without reasoning capability", () => { + const model = createMockModel({ + id: "ollama/qwen3", + providerID: "ollama", + api: { + id: "qwen3", + url: "http://localhost:11434/v1", + npm: "@ai-sdk/openai-compatible", + }, + capabilities: { + reasoning: false, + }, + }) + const result = ProviderTransform.variants(model) + expect(result).toEqual({ none: { reasoningEffort: "none" } }) + }) }) describe("@ai-sdk/azure", () => {