Skip to content

Commit ed7c5d5

Browse files
committed
test(bedrock,vercel): address Sonnet 5 PR review feedback
- Add Bedrock createMessage adaptive-thinking test for claude-sonnet-5 (mirrors Opus 4.7/4.8: asserts thinking.type 'adaptive', output_config.effort 'xhigh', and temperature omitted). - Tighten Vercel AI Gateway Sonnet 5 temperature assertion to extract the call arg directly instead of objectContaining({ temperature: undefined }), which can't distinguish absent from explicitly undefined. Refs #778
1 parent e4fdf27 commit ed7c5d5

2 files changed

Lines changed: 38 additions & 7 deletions

File tree

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1457,6 +1457,36 @@ describe("AwsBedrockHandler", () => {
14571457
expect(commandArg.inferenceConfig?.temperature).toBeUndefined()
14581458
})
14591459

1460+
it("should send adaptive thinking with effort xhigh for Claude Sonnet 5 when reasoning is enabled", async () => {
1461+
// End-to-end regression guard for the Sonnet 5 handler branch. The
1462+
// isAdaptiveThinkingModel predicate is unit-covered, but a regression in
1463+
// the createMessage adaptive-thinking branch for this specific model
1464+
// wouldn't be caught without a request-level test (see review feedback).
1465+
const sonnet5Handler = new AwsBedrockHandler({
1466+
apiModelId: "anthropic.claude-sonnet-5",
1467+
awsAccessKey: "test-access-key",
1468+
awsSecretKey: "test-secret-key",
1469+
awsRegion: "us-east-1",
1470+
enableReasoningEffort: true,
1471+
})
1472+
1473+
const generator = sonnet5Handler.createMessage("System prompt", messages)
1474+
await generator.next()
1475+
1476+
expect(mockConverseStreamCommand).toHaveBeenCalled()
1477+
const commandArg = mockConverseStreamCommand.mock.calls[0][0] as any
1478+
1479+
// Sonnet 5 uses the same adaptive-thinking contract as Opus 4.7/4.8 —
1480+
// budget_tokens causes a 400, so thinking.type is "adaptive" with effort.
1481+
expect(commandArg.additionalModelRequestFields?.thinking).toEqual({
1482+
type: "adaptive",
1483+
display: "summarized",
1484+
})
1485+
expect(commandArg.additionalModelRequestFields?.output_config).toEqual({ effort: "xhigh" })
1486+
// Sonnet 5 rejects sampling parameters: temperature must be omitted entirely.
1487+
expect(commandArg.inferenceConfig?.temperature).toBeUndefined()
1488+
})
1489+
14601490
it("should omit thinking and temperature for Claude Opus 4.8 when reasoning is disabled", async () => {
14611491
const opus48Handler = new AwsBedrockHandler({
14621492
apiModelId: "anthropic.claude-opus-4-8",

src/api/providers/__tests__/vercel-ai-gateway.spec.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -325,13 +325,14 @@ describe("VercelAiGatewayHandler", () => {
325325

326326
await handler.createMessage("You are a helpful assistant.", [{ role: "user", content: "Hello" }]).next()
327327

328-
expect(mockCreate).toHaveBeenCalledWith(
329-
expect.objectContaining({
330-
model: "anthropic/claude-sonnet-5",
331-
temperature: undefined,
332-
max_completion_tokens: 128000,
333-
}),
334-
)
328+
// Assert directly on the extracted call arg. `objectContaining({
329+
// temperature: undefined })` passes whether temperature is explicitly
330+
// undefined or simply absent, so it wouldn't catch a regression where the
331+
// handler stops consulting supportsTemperature.
332+
const call = mockCreate.mock.calls[mockCreate.mock.calls.length - 1][0]
333+
expect(call.model).toBe("anthropic/claude-sonnet-5")
334+
expect(call.temperature).toBeUndefined()
335+
expect(call.max_completion_tokens).toBe(128000)
335336
})
336337

337338
it("adds cache breakpoints for supported models", async () => {

0 commit comments

Comments
 (0)