Fix Bedrock blank text blocks

closes #4975
This commit is contained in:
Mario Zechner
2026-06-01 18:03:49 +02:00
parent 893ba99466
commit 34719d3f4f
4 changed files with 187 additions and 60 deletions

View File

@@ -117,7 +117,7 @@ describe("bedrock convertMessages skips unknown content types", () => {
expect(p.messages[0].content[0]).toEqual({ text: "hello" });
});
it("skips user messages with only unknown content blocks", async () => {
it("replaces user messages with only unknown content blocks with a placeholder", async () => {
const messages: Message[] = [
{
role: "user",
@@ -128,9 +128,95 @@ describe("bedrock convertMessages skips unknown content types", () => {
const payload = await capturePayload({ messages });
expect(payload).toBeDefined();
const p = payload as { messages: Array<{ role: string; content: unknown[] }> };
expect(p.messages).toHaveLength(1);
expect(p.messages[0].content).toEqual([{ text: "<empty>" }]);
});
it("replaces blank user string content with a placeholder", async () => {
const payload = await capturePayload({
messages: [{ role: "user", content: " ", timestamp: Date.now() }],
});
expect(payload).toBeDefined();
const p = payload as { messages: Array<{ role: string; content: unknown[] }> };
expect(p.messages).toHaveLength(1);
expect(p.messages[0].content).toEqual([{ text: "<empty>" }]);
});
it("filters blank user text blocks when other content remains", async () => {
const payload = await capturePayload({
messages: [
{
role: "user",
content: [
{ type: "text", text: "" },
{ type: "text", text: "hello" },
],
timestamp: Date.now(),
},
],
});
expect(payload).toBeDefined();
const p = payload as { messages: Array<{ role: string; content: unknown[] }> };
expect(p.messages).toHaveLength(1);
expect(p.messages[0].content).toEqual([{ text: "hello" }]);
});
it("replaces user content emptied by surrogate sanitization with a placeholder", async () => {
const payload = await capturePayload({
messages: [{ role: "user", content: String.fromCharCode(0xd83d), timestamp: Date.now() }],
});
expect(payload).toBeDefined();
const p = payload as { messages: Array<{ role: string; content: unknown[] }> };
expect(p.messages).toHaveLength(1);
expect(p.messages[0].content).toEqual([{ text: "<empty>" }]);
});
it("skips assistant text blocks emptied by surrogate sanitization", async () => {
const messages: Message[] = [
{
role: "assistant",
content: [{ type: "text", text: String.fromCharCode(0xd83d) }],
api: "bedrock-converse-stream",
provider: "amazon-bedrock",
model: baseModel.id,
usage: {
input: 0,
output: 0,
cacheRead: 0,
cacheWrite: 0,
totalTokens: 0,
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
},
stopReason: "stop",
timestamp: Date.now(),
},
];
const payload = await capturePayload({ messages });
expect(payload).toBeDefined();
const p = payload as { messages: Array<{ role: string; content: unknown[] }> };
expect(p.messages).toHaveLength(0);
});
it("replaces blank tool result content with a placeholder", async () => {
const messages: Message[] = [
{
role: "toolResult",
toolCallId: "tool-1",
toolName: "tool",
content: [{ type: "text", text: "" }],
isError: false,
timestamp: Date.now(),
},
];
const payload = await capturePayload({ messages });
expect(payload).toBeDefined();
const p = payload as {
messages: Array<{ role: string; content: Array<{ toolResult: { content: unknown[] } }> }>;
};
expect(p.messages).toHaveLength(1);
expect(p.messages[0].content[0].toolResult.content).toEqual([{ text: "<empty>" }]);
});
it("skips assistant messages with only unknown content blocks", async () => {
const messages: Message[] = [
{