Skip to content
This repository was archived by the owner on May 15, 2026. It is now read-only.

Commit 12c4471

Browse files
committed
fix(bedrock): exclude temperature for Opus 4.7 and add test coverage
- Add supportsTemperature: false to Opus 4.7 model definition - Conditionally exclude temperature from inferenceConfig when unsupported - Add tests for adaptive thinking and temperature exclusion Ported from PR #12288 commits a682355 and c2274d8
1 parent ba20c0d commit 12c4471

3 files changed

Lines changed: 113 additions & 2 deletions

File tree

packages/types/src/providers/bedrock.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ export const bedrockModels = {
173173
supportsImages: true,
174174
supportsPromptCache: true,
175175
supportsReasoningBudget: true,
176+
supportsTemperature: false,
176177
inputPrice: 5.0, // $5 per million input tokens (≤200K context)
177178
outputPrice: 25.0, // $25 per million output tokens (≤200K context)
178179
cacheWritesPrice: 6.25, // $6.25 per million tokens

src/api/providers/__tests__/bedrock-reasoning.spec.ts

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,110 @@ describe("AwsBedrockHandler - Extended Thinking", () => {
282282
expect(reasoningChunks[1].text).toBe(" about this problem.")
283283
})
284284

285+
it("should use adaptive thinking for Opus 4.7 instead of enabled with budget_tokens", async () => {
286+
handler = new AwsBedrockHandler({
287+
apiProvider: "bedrock",
288+
apiModelId: "anthropic.claude-opus-4-7",
289+
awsRegion: "us-east-1",
290+
enableReasoningEffort: true,
291+
modelMaxTokens: 8192,
292+
modelMaxThinkingTokens: 4096,
293+
})
294+
295+
mockSend.mockResolvedValue({
296+
stream: (async function* () {
297+
yield { messageStart: { role: "assistant" } }
298+
yield {
299+
contentBlockStart: {
300+
content_block: { type: "thinking", thinking: "Thinking adaptively..." },
301+
contentBlockIndex: 0,
302+
},
303+
}
304+
yield { metadata: { usage: { inputTokens: 100, outputTokens: 50 } } }
305+
})(),
306+
})
307+
308+
const messages = [{ role: "user" as const, content: "Test message" }]
309+
const stream = handler.createMessage("System prompt", messages)
310+
311+
const chunks = []
312+
for await (const chunk of stream) {
313+
chunks.push(chunk)
314+
}
315+
316+
// Opus 4.7 must use thinking.type: "adaptive" with output_config.effort
317+
expect(mockSend).toHaveBeenCalledTimes(1)
318+
expect(capturedPayload).toBeDefined()
319+
expect(capturedPayload.additionalModelRequestFields).toBeDefined()
320+
expect(capturedPayload.additionalModelRequestFields.thinking).toEqual({
321+
type: "adaptive",
322+
})
323+
expect(capturedPayload.additionalModelRequestFields.output_config).toEqual({
324+
effort: "high",
325+
})
326+
327+
// Must NOT have budget_tokens (causes 400 error on Opus 4.7)
328+
expect(capturedPayload.additionalModelRequestFields.thinking).not.toHaveProperty("budget_tokens")
329+
})
330+
331+
it("should exclude temperature from inferenceConfig for Opus 4.7 (supportsTemperature: false)", async () => {
332+
handler = new AwsBedrockHandler({
333+
apiProvider: "bedrock",
334+
apiModelId: "anthropic.claude-opus-4-7",
335+
awsRegion: "us-east-1",
336+
modelTemperature: 0.7,
337+
})
338+
339+
mockSend.mockResolvedValue({
340+
stream: (async function* () {
341+
yield { messageStart: { role: "assistant" } }
342+
yield { metadata: { usage: { inputTokens: 100, outputTokens: 50 } } }
343+
})(),
344+
})
345+
346+
const messages = [{ role: "user" as const, content: "Test message" }]
347+
const stream = handler.createMessage("System prompt", messages)
348+
349+
for await (const chunk of stream) {
350+
// consume stream
351+
}
352+
353+
expect(mockSend).toHaveBeenCalledTimes(1)
354+
expect(capturedPayload).toBeDefined()
355+
// Temperature must NOT be present for Opus 4.7
356+
expect(capturedPayload.inferenceConfig).not.toHaveProperty("temperature")
357+
// maxTokens should still be present
358+
expect(capturedPayload.inferenceConfig).toHaveProperty("maxTokens")
359+
})
360+
361+
it("should include temperature in inferenceConfig for models that support it", async () => {
362+
handler = new AwsBedrockHandler({
363+
apiProvider: "bedrock",
364+
apiModelId: "anthropic.claude-sonnet-4-20250514-v1:0",
365+
awsRegion: "us-east-1",
366+
modelTemperature: 0.5,
367+
})
368+
369+
mockSend.mockResolvedValue({
370+
stream: (async function* () {
371+
yield { messageStart: { role: "assistant" } }
372+
yield { metadata: { usage: { inputTokens: 100, outputTokens: 50 } } }
373+
})(),
374+
})
375+
376+
const messages = [{ role: "user" as const, content: "Test message" }]
377+
const stream = handler.createMessage("System prompt", messages)
378+
379+
for await (const chunk of stream) {
380+
// consume stream
381+
}
382+
383+
expect(mockSend).toHaveBeenCalledTimes(1)
384+
expect(capturedPayload).toBeDefined()
385+
// Temperature should be present for Sonnet 4
386+
expect(capturedPayload.inferenceConfig).toHaveProperty("temperature", 0.5)
387+
})
388+
285389
it("should support API key authentication", async () => {
286390
handler = new AwsBedrockHandler({
287391
apiProvider: "bedrock",

src/api/providers/bedrock.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,10 @@ export class AwsBedrockHandler extends BaseProvider implements SingleCompletionH
431431

432432
const inferenceConfig: BedrockInferenceConfig = {
433433
maxTokens: modelConfig.maxTokens || (modelConfig.info.maxTokens as number),
434-
temperature: modelConfig.temperature ?? (this.options.modelTemperature as number),
434+
// Only include temperature if the model supports it (Opus 4.7 deprecated temperature)
435+
...(modelConfig.info.supportsTemperature !== false && {
436+
temperature: modelConfig.temperature ?? (this.options.modelTemperature as number),
437+
}),
435438
}
436439

437440
// Check if 1M context is enabled for supported Claude 4 models
@@ -769,7 +772,10 @@ export class AwsBedrockHandler extends BaseProvider implements SingleCompletionH
769772

770773
const inferenceConfig: BedrockInferenceConfig = {
771774
maxTokens: modelConfig.maxTokens || (modelConfig.info.maxTokens as number),
772-
temperature: modelConfig.temperature ?? (this.options.modelTemperature as number),
775+
// Only include temperature if the model supports it (Opus 4.7 deprecated temperature)
776+
...(modelConfig.info.supportsTemperature !== false && {
777+
temperature: modelConfig.temperature ?? (this.options.modelTemperature as number),
778+
}),
773779
}
774780

775781
// For completePrompt, use a unique conversation ID based on the prompt

0 commit comments

Comments
 (0)