79 lines
2.5 KiB
TypeScript
79 lines
2.5 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { getModel } from "../src/models.js";
|
|
import { streamBedrock } from "../src/providers/amazon-bedrock.js";
|
|
import type { Context, Model, SimpleStreamOptions } from "../src/types.js";
|
|
|
|
interface BedrockThinkingPayload {
|
|
additionalModelRequestFields?: {
|
|
thinking?: { type: string; budget_tokens?: number };
|
|
output_config?: { effort?: string };
|
|
anthropic_beta?: string[];
|
|
};
|
|
}
|
|
|
|
function makeContext(): Context {
|
|
return {
|
|
messages: [{ role: "user", content: "Hello", timestamp: Date.now() }],
|
|
};
|
|
}
|
|
|
|
async function capturePayload(
|
|
model: Model<"bedrock-converse-stream">,
|
|
options?: SimpleStreamOptions,
|
|
): Promise<BedrockThinkingPayload> {
|
|
let capturedPayload: BedrockThinkingPayload | undefined;
|
|
const s = streamBedrock(model, makeContext(), {
|
|
...options,
|
|
reasoning: options?.reasoning ?? "high",
|
|
signal: AbortSignal.abort(),
|
|
onPayload: (payload) => {
|
|
capturedPayload = payload as BedrockThinkingPayload;
|
|
return payload;
|
|
},
|
|
});
|
|
|
|
for await (const event of s) {
|
|
if (event.type === "error") {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!capturedPayload) {
|
|
throw new Error("Expected Bedrock payload to be captured before request abort");
|
|
}
|
|
|
|
return capturedPayload;
|
|
}
|
|
|
|
describe("Bedrock thinking payload", () => {
|
|
it("uses adaptive thinking for Claude Opus 4.7 when reasoning is enabled", async () => {
|
|
const baseModel = getModel("amazon-bedrock", "global.anthropic.claude-opus-4-6-v1");
|
|
const model: Model<"bedrock-converse-stream"> = {
|
|
...baseModel,
|
|
id: "global.anthropic.claude-opus-4-7-v1",
|
|
name: "Claude Opus 4.7 (Global)",
|
|
};
|
|
|
|
const payload = await capturePayload(model);
|
|
|
|
expect(payload.additionalModelRequestFields?.thinking).toEqual({ type: "adaptive" });
|
|
expect(payload.additionalModelRequestFields?.output_config).toEqual({ effort: "high" });
|
|
expect(payload.additionalModelRequestFields?.anthropic_beta).toBeUndefined();
|
|
});
|
|
|
|
it("maps xhigh reasoning to effort=xhigh for Claude Opus 4.7", async () => {
|
|
const baseModel = getModel("amazon-bedrock", "global.anthropic.claude-opus-4-6-v1");
|
|
const model: Model<"bedrock-converse-stream"> = {
|
|
...baseModel,
|
|
id: "global.anthropic.claude-opus-4-7-v1",
|
|
name: "Claude Opus 4.7 (Global)",
|
|
};
|
|
|
|
const payload = await capturePayload(model, { reasoning: "xhigh" });
|
|
|
|
expect(payload.additionalModelRequestFields?.thinking).toEqual({ type: "adaptive" });
|
|
expect(payload.additionalModelRequestFields?.output_config).toEqual({ effort: "xhigh" });
|
|
expect(payload.additionalModelRequestFields?.anthropic_beta).toBeUndefined();
|
|
});
|
|
});
|