@@ -2,6 +2,10 @@
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed Amazon Bedrock Claude requests to send the model output token cap by default, matching Anthropic requests and avoiding Bedrock's 4096-token default truncation ([#4848](https://github.com/earendil-works/pi/issues/4848)).
|
||||
|
||||
## [0.75.4] - 2026-05-20
|
||||
|
||||
### Changed
|
||||
|
||||
@@ -183,12 +183,13 @@ export const streamBedrock: StreamFunction<"bedrock-converse-stream", BedrockOpt
|
||||
try {
|
||||
const client = new BedrockRuntimeClient(config);
|
||||
const cacheRetention = resolveCacheRetention(options.cacheRetention);
|
||||
const inferenceMaxTokens = options.maxTokens ?? (isAnthropicClaudeModel(model) ? model.maxTokens : undefined);
|
||||
let commandInput = {
|
||||
modelId: model.id,
|
||||
messages: convertMessages(context, model, cacheRetention),
|
||||
system: buildSystemPrompt(context.systemPrompt, model, cacheRetention),
|
||||
inferenceConfig: {
|
||||
...(options.maxTokens !== undefined && { maxTokens: options.maxTokens }),
|
||||
...(inferenceMaxTokens !== undefined && { maxTokens: inferenceMaxTokens }),
|
||||
...(options.temperature !== undefined && { temperature: options.temperature }),
|
||||
},
|
||||
toolConfig: convertToolConfig(context.tools, options.toolChoice),
|
||||
|
||||
@@ -2,6 +2,7 @@ import { describe, expect, it } from "vitest";
|
||||
import { getModel } from "../src/models.ts";
|
||||
import { type BedrockOptions, streamBedrock } from "../src/providers/amazon-bedrock.ts";
|
||||
import type { Context, Model } from "../src/types.ts";
|
||||
import { hasBedrockCredentials } from "./bedrock-utils.ts";
|
||||
|
||||
interface BedrockThinkingPayload {
|
||||
additionalModelRequestFields?: {
|
||||
@@ -112,6 +113,39 @@ describe("Bedrock thinking payload", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe.skipIf(!hasBedrockCredentials())("Bedrock Claude max tokens E2E", () => {
|
||||
it(
|
||||
"uses the model maxTokens cap instead of Bedrock's 4096-token default for adaptive Claude models",
|
||||
{ retry: 2, timeout: 180000 },
|
||||
async () => {
|
||||
const baseModel = getModel("amazon-bedrock", "global.anthropic.claude-sonnet-4-6");
|
||||
const model: Model<"bedrock-converse-stream"> = {
|
||||
...baseModel,
|
||||
maxTokens: 6000,
|
||||
};
|
||||
|
||||
const response = await streamBedrock(
|
||||
model,
|
||||
{
|
||||
systemPrompt: "You are a deterministic text generator. Follow the requested output format exactly.",
|
||||
messages: [
|
||||
{
|
||||
role: "user",
|
||||
content:
|
||||
"Output exactly 5200 repetitions of the token alpha, separated by single spaces. Do not number them. Do not use markdown. Do not add any other text.",
|
||||
timestamp: Date.now(),
|
||||
},
|
||||
],
|
||||
},
|
||||
{ reasoning: "low" },
|
||||
).result();
|
||||
|
||||
expect(response.stopReason, response.errorMessage).not.toBe("error");
|
||||
expect(response.usage.output).toBeGreaterThan(4096);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
describe("Application inference profile support", () => {
|
||||
it("uses adaptive thinking when model.name contains the model name but ARN does not", async () => {
|
||||
const baseModel = getModel("amazon-bedrock", "global.anthropic.claude-opus-4-6-v1");
|
||||
|
||||
Reference in New Issue
Block a user