fix: add type guards and null checks for UUID handling in snip functionality
- 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>
This commit is contained in:
parent
de83394e8a
commit
ecb0df50d3
|
|
@ -79,13 +79,11 @@ Guidelines:
|
|||
},
|
||||
|
||||
async call(input: SnipInput) {
|
||||
// Snip implementation is handled by the query engine's projection system.
|
||||
// The tool call itself records the intent; the query engine intercepts
|
||||
// snip tool results and adjusts its message projection accordingly.
|
||||
const ids = input?.message_ids ?? []
|
||||
return {
|
||||
data: {
|
||||
snipped_count: input.message_ids.length,
|
||||
summary: input.reason ?? `Snipped ${input.message_ids.length} messages`,
|
||||
snipped_count: ids.length,
|
||||
summary: input?.reason ?? `Snipped ${ids.length} messages`,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import type { UUID } from 'crypto'
|
||||
import { randomUUID } from 'crypto'
|
||||
import type { Command, LocalCommandCall } from '../types/command.js'
|
||||
import type { Message } from '../types/message.js'
|
||||
|
|
@ -25,7 +26,7 @@ const call: LocalCommandCall = async (_args, context) => {
|
|||
// Collect UUIDs of every message that will be snipped (everything currently
|
||||
// in the conversation). The next call to `snipCompactIfNeeded` will honour
|
||||
// the boundary and strip these from the model-facing view.
|
||||
const removedUuids = messages.map(m => m.uuid)
|
||||
const removedUuids = messages.map(m => m.uuid).filter((u): u is UUID => !!u)
|
||||
|
||||
const boundaryMessage: Message = {
|
||||
type: 'system',
|
||||
|
|
|
|||
|
|
@ -126,12 +126,15 @@ export function snipCompactIfNeeded(
|
|||
}
|
||||
|
||||
// Filter out messages whose UUIDs are listed in removedUuids
|
||||
const removedSet = new Set(removedUuids)
|
||||
// Guard: filter out any falsy entries (e.g. messages that lacked a uuid)
|
||||
const removedSet = new Set<string>(
|
||||
removedUuids.filter((u): u is string => typeof u === 'string'),
|
||||
)
|
||||
const kept: Message[] = []
|
||||
let tokensFreed = 0
|
||||
|
||||
for (const msg of messages) {
|
||||
if (removedSet.has(msg.uuid)) {
|
||||
if (msg.uuid && removedSet.has(msg.uuid)) {
|
||||
tokensFreed += estimateMessageTokens(msg)
|
||||
continue
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ export function projectSnippedView(messages: Message[]): Message[] {
|
|||
| undefined
|
||||
if (meta?.removedUuids) {
|
||||
for (const uuid of meta.removedUuids) {
|
||||
removedSet.add(uuid)
|
||||
if (typeof uuid === 'string') removedSet.add(uuid)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1996,7 +1996,9 @@ function applySnipRemovals(messages: Map<UUID, TranscriptMessage>): void {
|
|||
for (const entry of messages.values()) {
|
||||
const removedUuids = (entry as WithSnipMeta).snipMetadata?.removedUuids
|
||||
if (!removedUuids) continue
|
||||
for (const uuid of removedUuids) toDelete.add(uuid)
|
||||
for (const uuid of removedUuids) {
|
||||
if (uuid) toDelete.add(uuid)
|
||||
}
|
||||
}
|
||||
if (toDelete.size === 0) return
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user