fix: harden embedded text normalization (#58555)

Co-authored-by: Morrow <271612559+agent-morrow@users.noreply.github.com>
This commit is contained in:
Morrow
2026-04-01 04:10:49 +03:00
committed by GitHub
parent 50cc28c559
commit be5a035d97
6 changed files with 74 additions and 21 deletions

View File

@@ -61,4 +61,22 @@ describe("shared/chat-content", () => {
}),
).toBeNull();
});
it("tolerates sanitize and normalize hooks that return non-string values", () => {
expect(
extractTextFromChatContent("hello", {
sanitizeText: () => undefined as unknown as string,
}),
).toBeNull();
expect(
extractTextFromChatContent([{ type: "text", text: "hello" }], {
sanitizeText: () => 42 as unknown as string,
}),
).toBe("42");
expect(
extractTextFromChatContent("hello", {
normalizeText: () => undefined as unknown as string,
}),
).toBeNull();
});
});

View File

@@ -6,11 +6,19 @@ export function extractTextFromChatContent(
normalizeText?: (text: string) => string;
},
): string | null {
const normalize = opts?.normalizeText ?? ((text: string) => text.replace(/\s+/g, " ").trim());
const normalizeText = opts?.normalizeText ?? ((text: string) => text.replace(/\s+/g, " ").trim());
const joinWith = opts?.joinWith ?? " ";
const coerceText = (value: unknown): string =>
typeof value === "string" ? value : value == null ? "" : String(value);
const sanitize = (text: unknown): string => {
const raw = coerceText(text);
const sanitized = opts?.sanitizeText ? opts.sanitizeText(raw) : raw;
return coerceText(sanitized);
};
const normalize = (text: unknown): string => coerceText(normalizeText(coerceText(text)));
if (typeof content === "string") {
const value = opts?.sanitizeText ? opts.sanitizeText(content) : content;
const value = sanitize(content);
const normalized = normalize(value);
return normalized ? normalized : null;
}
@@ -28,10 +36,7 @@ export function extractTextFromChatContent(
continue;
}
const text = (block as { text?: unknown }).text;
if (typeof text !== "string") {
continue;
}
const value = opts?.sanitizeText ? opts.sanitizeText(text) : text;
const value = sanitize(text);
if (value.trim()) {
chunks.push(value);
}