fix: hide message_id hints in web chat
This commit is contained in:
42
src/gateway/chat-sanitize.test.ts
Normal file
42
src/gateway/chat-sanitize.test.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import { describe, expect, test } from "vitest";
|
||||
import { stripEnvelopeFromMessage } from "./chat-sanitize.js";
|
||||
|
||||
describe("stripEnvelopeFromMessage", () => {
|
||||
test("removes message_id hint lines from user messages", () => {
|
||||
const input = {
|
||||
role: "user",
|
||||
content: "[WhatsApp 2026-01-24 13:36] yolo\n[message_id: 7b8b]",
|
||||
};
|
||||
const result = stripEnvelopeFromMessage(input) as { content?: string };
|
||||
expect(result.content).toBe("yolo");
|
||||
});
|
||||
|
||||
test("removes message_id hint lines from text content arrays", () => {
|
||||
const input = {
|
||||
role: "user",
|
||||
content: [{ type: "text", text: "hi\n[message_id: abc123]" }],
|
||||
};
|
||||
const result = stripEnvelopeFromMessage(input) as {
|
||||
content?: Array<{ type: string; text?: string }>;
|
||||
};
|
||||
expect(result.content?.[0]?.text).toBe("hi");
|
||||
});
|
||||
|
||||
test("does not strip inline message_id text that is part of a line", () => {
|
||||
const input = {
|
||||
role: "user",
|
||||
content: "I typed [message_id: 123] on purpose",
|
||||
};
|
||||
const result = stripEnvelopeFromMessage(input) as { content?: string };
|
||||
expect(result.content).toBe("I typed [message_id: 123] on purpose");
|
||||
});
|
||||
|
||||
test("does not strip assistant messages", () => {
|
||||
const input = {
|
||||
role: "assistant",
|
||||
content: "note\n[message_id: 123]",
|
||||
};
|
||||
const result = stripEnvelopeFromMessage(input) as { content?: string };
|
||||
expect(result.content).toBe("note\n[message_id: 123]");
|
||||
});
|
||||
});
|
||||
@@ -14,6 +14,8 @@ const ENVELOPE_CHANNELS = [
|
||||
"BlueBubbles",
|
||||
];
|
||||
|
||||
const MESSAGE_ID_LINE = /^\s*\[message_id:\s*[^\]]+\]\s*$/i;
|
||||
|
||||
function looksLikeEnvelopeHeader(header: string): boolean {
|
||||
if (/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}Z\b/.test(header)) return true;
|
||||
if (/\d{4}-\d{2}-\d{2} \d{2}:\d{2}\b/.test(header)) return true;
|
||||
@@ -28,13 +30,20 @@ export function stripEnvelope(text: string): string {
|
||||
return text.slice(match[0].length);
|
||||
}
|
||||
|
||||
function stripMessageIdHints(text: string): string {
|
||||
if (!text.includes("[message_id:")) return text;
|
||||
const lines = text.split(/\r?\n/);
|
||||
const filtered = lines.filter((line) => !MESSAGE_ID_LINE.test(line));
|
||||
return filtered.length === lines.length ? text : filtered.join("\n");
|
||||
}
|
||||
|
||||
function stripEnvelopeFromContent(content: unknown[]): { content: unknown[]; changed: boolean } {
|
||||
let changed = false;
|
||||
const next = content.map((item) => {
|
||||
if (!item || typeof item !== "object") return item;
|
||||
const entry = item as Record<string, unknown>;
|
||||
if (entry.type !== "text" || typeof entry.text !== "string") return item;
|
||||
const stripped = stripEnvelope(entry.text);
|
||||
const stripped = stripMessageIdHints(stripEnvelope(entry.text));
|
||||
if (stripped === entry.text) return item;
|
||||
changed = true;
|
||||
return {
|
||||
@@ -55,7 +64,7 @@ export function stripEnvelopeFromMessage(message: unknown): unknown {
|
||||
const next: Record<string, unknown> = { ...entry };
|
||||
|
||||
if (typeof entry.content === "string") {
|
||||
const stripped = stripEnvelope(entry.content);
|
||||
const stripped = stripMessageIdHints(stripEnvelope(entry.content));
|
||||
if (stripped !== entry.content) {
|
||||
next.content = stripped;
|
||||
changed = true;
|
||||
@@ -67,7 +76,7 @@ export function stripEnvelopeFromMessage(message: unknown): unknown {
|
||||
changed = true;
|
||||
}
|
||||
} else if (typeof entry.text === "string") {
|
||||
const stripped = stripEnvelope(entry.text);
|
||||
const stripped = stripMessageIdHints(stripEnvelope(entry.text));
|
||||
if (stripped !== entry.text) {
|
||||
next.text = stripped;
|
||||
changed = true;
|
||||
|
||||
Reference in New Issue
Block a user