diff --git a/packages/opencode/src/provider/transform.ts b/packages/opencode/src/provider/transform.ts index ded416e66d95..c1c115f6c0b9 100644 --- a/packages/opencode/src/provider/transform.ts +++ b/packages/opencode/src/provider/transform.ts @@ -355,6 +355,7 @@ export namespace ProviderTransform { switch (model.api.npm) { case "@openrouter/ai-sdk-provider": if (!model.id.includes("gpt") && !model.id.includes("gemini-3")) return {} + return Object.fromEntries(OPENAI_EFFORTS.map((effort) => [effort, { reasoning: { effort } }])) // TODO: YOU CANNOT SET max_tokens if this is set!!! @@ -395,6 +396,36 @@ export namespace ProviderTransform { case "@ai-sdk/deepinfra": // https://v5.ai-sdk.dev/providers/ai-sdk-providers/deepinfra case "@ai-sdk/openai-compatible": + // When using openai-compatible SDK with Claude/Anthropic models, + // we must use snake_case (budget_tokens) as the SDK doesn't convert parameter names + // and the OpenAI-compatible API spec uses snake_case + if ( + model.providerID === "anthropic" || + model.api.id.includes("anthropic") || + model.api.id.includes("claude") || + model.id.includes("anthropic") || + model.id.includes("claude") + ) { + return { + high: { + thinking: { + type: "enabled", + budget_tokens: 16000, + }, + }, + max: { + thinking: { + type: "enabled", + budget_tokens: 31999, + }, + }, + } + } + // Following logic for the `@ai-sdk/openai` case + if (id.includes("codex")) { + if (id.includes("5.2")) return Object.fromEntries([...WIDELY_SUPPORTED_EFFORTS, "xhigh"].map((effort) => [effort, { reasoning: { effort } }])) + return Object.fromEntries(WIDELY_SUPPORTED_EFFORTS.map((effort) => [effort, { reasoning: { effort } }])) + } return Object.fromEntries(WIDELY_SUPPORTED_EFFORTS.map((effort) => [effort, { reasoningEffort: effort }])) case "@ai-sdk/azure":