Skip to content

Commit b917925

Browse files
committed
feat(bedrock): support Claude 4.7+ adaptive thinking and remove temperature
Claude Opus/Sonnet 4.7 introduced breaking API changes: - temperature/top_p/top_k removed (causes 400 error) - thinking.type 'enabled' + budget_tokens removed (causes 400 error) - New thinking.type 'adaptive' with output_config.effort levels - New display: 'summarized' option to surface thinking content Changes: - Detect Gen 4.7+ models via baseModelId.includes('opus-4-7' | 'sonnet-4-7') - Omit temperature from inferenceConfig for 4.7+ models - Use thinking: { type: 'adaptive', display: 'summarized' } for 4.7+ - Set output_config.effort: 'xhigh' (highest level for coding/agentic tasks) - Maintain full backward compatibility with 4.6 and earlier models - Expanded BedrockAdditionalModelFields interface to support both formats References: - Claude 4.7 release notes (Apr 16, 2026) - effort levels: low | medium | high | xhigh | max
1 parent 140867f commit b917925

1 file changed

Lines changed: 39 additions & 12 deletions

File tree

src/api/providers/bedrock.ts

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,20 @@ interface BedrockInferenceConfig {
6161
// Define interface for Bedrock additional model request fields
6262
// This includes thinking configuration, 1M context beta, and other model-specific parameters
6363
interface BedrockAdditionalModelFields {
64-
thinking?: {
65-
type: "enabled"
66-
budget_tokens: number
64+
thinking?:
65+
| {
66+
type: "enabled"
67+
budget_tokens: number
68+
}
69+
| {
70+
// Claude 4.7+ adaptive thinking — no budget_tokens, uses output_config.effort instead
71+
type: "adaptive"
72+
// "summarized" shows thinking content in UI; omit to keep thinking internal only
73+
display?: "summarized" | "none"
74+
}
75+
output_config?: {
76+
// Claude 4.7+ effort levels: "low" | "medium" | "high" | "xhigh" | "max"
77+
effort: string
6778
}
6879
anthropic_beta?: string[]
6980
[key: string]: any // Add index signature to be compatible with DocumentType
@@ -381,6 +392,11 @@ export class AwsBedrockHandler extends BaseProvider implements SingleCompletionH
381392
let additionalModelRequestFields: BedrockAdditionalModelFields | undefined
382393
let thinkingEnabled = false
383394

395+
// Detect model generation for API compatibility
396+
// Claude 4.7+ removed sampling params (temperature/top_p/top_k) and uses adaptive thinking
397+
const baseModelId = this.parseBaseModelId(modelConfig.id)
398+
const isGen47Model = baseModelId.includes("opus-4-7") || baseModelId.includes("sonnet-4-7")
399+
384400
// Determine if thinking should be enabled
385401
// metadata?.thinking?.enabled: Explicitly enabled through API metadata (direct request)
386402
// shouldUseReasoningBudget(): Enabled through user settings (enableReasoningEffort = true)
@@ -392,27 +408,38 @@ export class AwsBedrockHandler extends BaseProvider implements SingleCompletionH
392408

393409
if ((isThinkingExplicitlyEnabled || isThinkingEnabledBySettings) && modelConfig.info.supportsReasoningBudget) {
394410
thinkingEnabled = true
395-
additionalModelRequestFields = {
396-
thinking: {
397-
type: "enabled",
398-
budget_tokens: metadata?.thinking?.maxThinkingTokens || modelConfig.reasoningBudget || 4096,
399-
},
411+
if (isGen47Model) {
412+
// Claude 4.7+ uses adaptive thinking with effort levels — budget_tokens causes 400 error
413+
// display: "summarized" surfaces thinking content in Zoo Code UI
414+
additionalModelRequestFields = {
415+
thinking: { type: "adaptive", display: "summarized" },
416+
output_config: { effort: "xhigh" },
417+
}
418+
} else {
419+
additionalModelRequestFields = {
420+
thinking: {
421+
type: "enabled",
422+
budget_tokens: metadata?.thinking?.maxThinkingTokens || modelConfig.reasoningBudget || 4096,
423+
},
424+
}
400425
}
401426
logger.info("Extended thinking enabled for Bedrock request", {
402427
ctx: "bedrock",
403428
modelId: modelConfig.id,
404-
thinking: additionalModelRequestFields.thinking,
429+
thinking: additionalModelRequestFields?.thinking,
405430
})
406431
}
407432

408433
const inferenceConfig: BedrockInferenceConfig = {
409434
maxTokens: modelConfig.maxTokens || (modelConfig.info.maxTokens as number),
410-
temperature: modelConfig.temperature ?? (this.options.modelTemperature as number),
435+
// Claude 4.7+ removed temperature parameter entirely — causes 400 error if sent
436+
...(isGen47Model
437+
? {}
438+
: { temperature: modelConfig.temperature ?? (this.options.modelTemperature as number) }),
411439
}
412440

413441
// Check if 1M context is enabled for supported Claude 4 models
414-
// Use parseBaseModelId to handle cross-region inference prefixes
415-
const baseModelId = this.parseBaseModelId(modelConfig.id)
442+
// Use parseBaseModelId to handle cross-region inference prefixes (computed above)
416443
const is1MContextEnabled =
417444
BEDROCK_1M_CONTEXT_MODEL_IDS.includes(baseModelId as any) && this.options.awsBedrock1MContext
418445

0 commit comments

Comments
 (0)