/** * Pure filter applied after context-mode's `context` handler: its upstream * build appends one `{ role: "user", content }` message whose parts are * `"\n\n"`-joined and whose first part is a routing anchor that duplicates — * and contradicts — the bundle-owned `config/prompt/routing.jsonc`. The anchor * part is stripped; remaining parts (active memory, resume snapshot) stay. * No other message is touched; when nothing changes the input array is * returned unchanged (same reference). */ export const CONTEXT_MODE_ANCHOR_PREFIX = "context-mode active. Hierarchy:"; type MessageLike = { role?: unknown; content?: unknown } & Record; export function filterContextModeMessages( before: readonly T[], after: readonly T[], ): T[] { if (after.length <= before.length) return after as T[]; let result: T[] | null = null; for (let i = after.length - 1; i >= before.length; i--) { const message = after[i]; if (message === null || typeof message !== "object") continue; if (message.role !== "user" || typeof message.content !== "string") continue; const parts = message.content.split("\n\n"); const kept = parts.filter((part) => !part.startsWith(CONTEXT_MODE_ANCHOR_PREFIX)); if (kept.length === parts.length) continue; result ??= after.slice(); if (kept.length === 0) { result.splice(i, 1); } else { result[i] = { ...message, content: kept.join("\n\n") }; } } return result ?? (after as T[]); }