fix(gateway): redact audio payloads from chat history

This commit is contained in:
Peter Steinberger
2026-04-22 20:22:38 +01:00
parent 64a98dea8d
commit 0e761cdba8
2 changed files with 51 additions and 0 deletions

View File

@@ -700,6 +700,17 @@ function sanitizeChatHistoryContentBlock(
entry.bytes = bytes;
changed = true;
}
if (type === "audio" && entry.source && typeof entry.source === "object") {
const source = { ...(entry.source as Record<string, unknown>) };
if (source.type === "base64" && typeof source.data === "string") {
const bytes = Buffer.byteLength(source.data, "utf8");
delete source.data;
source.omitted = true;
source.bytes = bytes;
entry.source = source;
changed = true;
}
}
return { block: changed ? entry : block, changed };
}

View File

@@ -263,6 +263,46 @@ describe("injectTimestamp", () => {
});
describe("sanitizeChatHistoryMessages", () => {
it("redacts base64 audio content blocks from chat history", () => {
const data = Buffer.from("voice-bytes").toString("base64");
const result = sanitizeChatHistoryMessages([
{
role: "assistant",
content: [
{ type: "text", text: "Audio reply" },
{
type: "audio",
source: {
type: "base64",
media_type: "audio/mp3",
data,
},
},
],
timestamp: 1,
},
]);
expect(result).toEqual([
{
role: "assistant",
content: [
{ type: "text", text: "Audio reply" },
{
type: "audio",
source: {
type: "base64",
media_type: "audio/mp3",
omitted: true,
bytes: Buffer.byteLength(data, "utf8"),
},
},
],
timestamp: 1,
},
]);
});
it("drops commentary-only assistant entries when phase exists only in textSignature", () => {
const result = sanitizeChatHistoryMessages([
{