import type { Message } from 'src/types/message.js' /** * Check whether a message is a snip boundary marker. * * A snip boundary is a system message with `subtype === 'snip_boundary'` * and an optional `snipMetadata.removedUuids` array recording which * messages were removed by the snip operation. * * Used by: * - `Message.tsx` — render SnipBoundaryMessage component. * - `QueryEngine.ts` `snipReplay` — decide whether to replay the snip * on the mutableMessages store. */ export function isSnipBoundaryMessage(message: Message): boolean { if (message.type !== 'system') return false return (message as Record).subtype === 'snip_boundary' } /** * Project a "snipped view" of the message array suitable for sending to * the model. Messages whose UUIDs appear in any snip boundary's * `removedUuids` are filtered out; all others (including the boundary * messages themselves) are preserved. * * Used by: * - `getMessagesAfterCompactBoundary()` in messages.ts — after slicing * at the compact boundary, further filters out snipped messages so the * model-facing array does not include stale history. * * @param messages Message array that may contain one or more snip * boundaries. * @returns New array with removed messages stripped out. */ export function projectSnippedView(messages: Message[]): Message[] { // Collect all UUIDs that have been removed by any snip boundary const removedSet = new Set() for (const msg of messages) { if ( msg.type === 'system' && (msg as Record).subtype === 'snip_boundary' ) { const meta = (msg as Record).snipMetadata as | { removedUuids?: string[] } | undefined if (meta?.removedUuids) { for (const uuid of meta.removedUuids) { if (typeof uuid === 'string') removedSet.add(uuid) } } } } if (removedSet.size === 0) { return messages } return messages.filter(msg => !removedSet.has(msg.uuid)) }