- Add UUID type import and type guard in force-snip command - Add null/undefined checks in snipCompact, snipProjection, and sessionStorage - Improve optional chaining in SnipTool for safer property access - Prevent potential runtime errors from invalid UUID values Co-Authored-By: claude-sonnet-4-6 <noreply@anthropic.com>
61 lines
2.0 KiB
TypeScript
61 lines
2.0 KiB
TypeScript
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<string, unknown>).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<string>()
|
|
|
|
for (const msg of messages) {
|
|
if (
|
|
msg.type === 'system' &&
|
|
(msg as Record<string, unknown>).subtype === 'snip_boundary'
|
|
) {
|
|
const meta = (msg as Record<string, unknown>).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))
|
|
}
|