From c32f32aa71ae0dfdafb49693ec210fd688937fc6 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Thu, 16 Apr 2026 17:08:46 +0000 Subject: [PATCH 1/2] fix: add adaptive thinking support for Claude Opus 4.7+ Claude Opus 4.7 only supports adaptive thinking mode (thinking.type: 'adaptive') and rejects the legacy budget-based thinking (thinking.type: 'enabled'). This change: - Adds model detection to automatically use adaptive thinking for Opus 4.7+ - Uses adaptive thinking by default for Opus 4.6 and Sonnet 4.6 (recommended) - Falls back to budget-based thinking for older models (Sonnet 4.5, etc.) - Adds thinking support for google-vertex-anthropic and amazon-bedrock providers - Adds ANTHROPIC_EFFORT env var to control thinking depth (low/medium/high/max) Fixes #SOU-918 Co-authored-by: Michael Sukkarieh --- packages/shared/src/env.server.ts | 7 ++ .../web/src/features/chat/utils.server.ts | 78 +++++++++++++++++-- 2 files changed, 79 insertions(+), 6 deletions(-) diff --git a/packages/shared/src/env.server.ts b/packages/shared/src/env.server.ts index 22bf2242e..1dc49948c 100644 --- a/packages/shared/src/env.server.ts +++ b/packages/shared/src/env.server.ts @@ -203,6 +203,13 @@ const options = { ANTHROPIC_API_KEY: z.string().optional(), ANTHROPIC_AUTH_TOKEN: z.string().optional(), ANTHROPIC_THINKING_BUDGET_TOKENS: numberSchema.default(12000), + /** + * The effort level for Anthropic models using adaptive thinking. + * Controls how much thinking Claude uses when responding. + * Valid values: 'low', 'medium', 'high' (default), 'max' + * @see https://docs.anthropic.com/en/docs/build-with-claude/effort + */ + ANTHROPIC_EFFORT: z.enum(['low', 'medium', 'high', 'max']).default('high'), AZURE_API_KEY: z.string().optional(), AZURE_RESOURCE_NAME: z.string().optional(), diff --git a/packages/web/src/features/chat/utils.server.ts b/packages/web/src/features/chat/utils.server.ts index 4e7af7983..ba10f5111 100644 --- a/packages/web/src/features/chat/utils.server.ts +++ b/packages/web/src/features/chat/utils.server.ts @@ -26,6 +26,66 @@ import fs from 'fs'; import path from 'path'; import { LanguageModelInfo, SBChatMessage } from './types'; +type AnthropicThinkingMode = 'adaptive' | 'budget' | 'disabled'; + +/** + * Determines the appropriate thinking configuration for an Anthropic model. + * + * - Claude Opus 4.7+: Only supports adaptive thinking (budget mode is rejected) + * - Claude Opus 4.6/Sonnet 4.6+: Supports both but adaptive is recommended + * - Older models (Sonnet 4.5, Opus 4.5, etc.): Only support budget-based thinking + */ +const getAnthropicThinkingMode = (modelId: string): AnthropicThinkingMode => { + const lowerModelId = modelId.toLowerCase(); + + // Claude Opus 4.7 and later versions ONLY support adaptive thinking + // Model IDs: claude-opus-4-7, claude-opus-4-7-*, claude-opus-4-8, etc. + if (lowerModelId.includes('opus-4-7') || + lowerModelId.includes('opus-4-8') || + lowerModelId.includes('opus-4-9') || + lowerModelId.includes('opus-5') || + lowerModelId.includes('mythos')) { + return 'adaptive'; + } + + // Claude Opus 4.6 and Sonnet 4.6+ support both, but adaptive is recommended + // Model IDs: claude-opus-4-6, claude-sonnet-4-6, etc. + if (lowerModelId.includes('opus-4-6') || lowerModelId.includes('sonnet-4-6')) { + return 'adaptive'; + } + + // Older models (Sonnet 4.5, Opus 4.5, Sonnet 3.7, etc.) only support budget-based thinking + return 'budget'; +}; + +/** + * Builds the Anthropic thinking provider options based on the model and environment configuration. + */ +const getAnthropicThinkingOptions = (modelId: string): AnthropicProviderOptions => { + const thinkingMode = getAnthropicThinkingMode(modelId); + + if (thinkingMode === 'disabled') { + return {}; + } + + if (thinkingMode === 'adaptive') { + return { + thinking: { + type: 'adaptive', + }, + effort: env.ANTHROPIC_EFFORT, + }; + } + + // Budget-based thinking for older models + return { + thinking: { + type: 'enabled', + budgetTokens: env.ANTHROPIC_THINKING_BUDGET_TOKENS, + }, + }; +}; + /** * Checks if the current user (authenticated or anonymous) is the owner of a chat. */ @@ -192,8 +252,16 @@ export const getAISDKLanguageModelAndOptions = async (config: LanguageModel): Pr : undefined, }); + // Add thinking options for Anthropic models on Bedrock + const isAnthropicModel = modelId.toLowerCase().includes('anthropic') || + modelId.toLowerCase().includes('claude'); + const providerOptions = isAnthropicModel + ? { anthropic: getAnthropicThinkingOptions(modelId) } + : undefined; + return { model: aws(modelId), + providerOptions, }; } case 'anthropic': { @@ -213,12 +281,7 @@ export const getAISDKLanguageModelAndOptions = async (config: LanguageModel): Pr return { model: anthropic(modelId), providerOptions: { - anthropic: { - thinking: { - type: "enabled", - budgetTokens: env.ANTHROPIC_THINKING_BUDGET_TOKENS, - } - } satisfies AnthropicProviderOptions, + anthropic: getAnthropicThinkingOptions(modelId), }, }; } @@ -326,6 +389,9 @@ export const getAISDKLanguageModelAndOptions = async (config: LanguageModel): Pr return { model: vertexAnthropic(modelId), + providerOptions: { + anthropic: getAnthropicThinkingOptions(modelId), + }, }; } case 'mistral': { From 13c8924b8440359265475d2ec0f42bf78bfd8008 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Thu, 16 Apr 2026 17:09:42 +0000 Subject: [PATCH 2/2] docs: add CHANGELOG entry for Claude Opus 4.7 adaptive thinking fix Co-authored-by: Michael Sukkarieh --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2cc17a67a..457fc65e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Fixed +- Fixed Claude Opus 4.7 compatibility by using adaptive thinking mode instead of budget-based thinking. Also added `ANTHROPIC_EFFORT` environment variable to control thinking depth, and extended thinking support to `google-vertex-anthropic` and `amazon-bedrock` providers. [#1125](https://github.com/sourcebot-dev/sourcebot/pull/1125) + ## [4.16.9] - 2026-04-15 ### Added