@@ -2,6 +2,10 @@
|
|||||||
|
|
||||||
## [Unreleased]
|
## [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
|
## [0.75.4] - 2026-05-20
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|||||||
@@ -183,12 +183,13 @@ export const streamBedrock: StreamFunction<"bedrock-converse-stream", BedrockOpt
|
|||||||
try {
|
try {
|
||||||
const client = new BedrockRuntimeClient(config);
|
const client = new BedrockRuntimeClient(config);
|
||||||
const cacheRetention = resolveCacheRetention(options.cacheRetention);
|
const cacheRetention = resolveCacheRetention(options.cacheRetention);
|
||||||
|
const inferenceMaxTokens = options.maxTokens ?? (isAnthropicClaudeModel(model) ? model.maxTokens : undefined);
|
||||||
let commandInput = {
|
let commandInput = {
|
||||||
modelId: model.id,
|
modelId: model.id,
|
||||||
messages: convertMessages(context, model, cacheRetention),
|
messages: convertMessages(context, model, cacheRetention),
|
||||||
system: buildSystemPrompt(context.systemPrompt, model, cacheRetention),
|
system: buildSystemPrompt(context.systemPrompt, model, cacheRetention),
|
||||||
inferenceConfig: {
|
inferenceConfig: {
|
||||||
...(options.maxTokens !== undefined && { maxTokens: options.maxTokens }),
|
...(inferenceMaxTokens !== undefined && { maxTokens: inferenceMaxTokens }),
|
||||||
...(options.temperature !== undefined && { temperature: options.temperature }),
|
...(options.temperature !== undefined && { temperature: options.temperature }),
|
||||||
},
|
},
|
||||||
toolConfig: convertToolConfig(context.tools, options.toolChoice),
|
toolConfig: convertToolConfig(context.tools, options.toolChoice),
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { describe, expect, it } from "vitest";
|
|||||||
import { getModel } from "../src/models.ts";
|
import { getModel } from "../src/models.ts";
|
||||||
import { type BedrockOptions, streamBedrock } from "../src/providers/amazon-bedrock.ts";
|
import { type BedrockOptions, streamBedrock } from "../src/providers/amazon-bedrock.ts";
|
||||||
import type { Context, Model } from "../src/types.ts";
|
import type { Context, Model } from "../src/types.ts";
|
||||||
|
import { hasBedrockCredentials } from "./bedrock-utils.ts";
|
||||||
|
|
||||||
interface BedrockThinkingPayload {
|
interface BedrockThinkingPayload {
|
||||||
additionalModelRequestFields?: {
|
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", () => {
|
describe("Application inference profile support", () => {
|
||||||
it("uses adaptive thinking when model.name contains the model name but ARN does not", async () => {
|
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");
|
const baseModel = getModel("amazon-bedrock", "global.anthropic.claude-opus-4-6-v1");
|
||||||
|
|||||||
Reference in New Issue
Block a user