fix: complete immutable message migration

This commit is contained in:
_Kerman
2026-07-28 14:15:23 +08:00
parent f5ec71f5b1
commit 350c296cff
27 changed files with 231 additions and 60 deletions

View File

@@ -45,6 +45,7 @@ import {
materializeSessionResultFilters,
} from './filters.ts'
import * as tracing from './tracing.ts'
import { snapshotEvent } from './snapshot.ts'
export type * from './types.ts'
export { SessionSearchCursor } from './cursor.ts'
@@ -146,7 +147,7 @@ export abstract class SessionQueryService extends Service {
new Session(sessionId, loaded.events, loaded.header)
return {
session: structuredClone(loaded.header),
events: loaded.events.map(event => structuredClone(event)),
events: loaded.events.map(snapshotEvent),
}
}
@@ -330,10 +331,13 @@ export abstract class SessionQueryService extends Service {
}
const startSeq = Math.max(0, seq - before)
const endSeq = Math.min(loaded.events.length - 1, seq + after)
const targetSnapshot = snapshotEvent(target)
const events = loaded.events.slice(startSeq, endSeq + 1)
.map(event => event === target ? targetSnapshot : snapshotEvent(event))
return {
session: loaded.header,
target,
events: loaded.events.slice(startSeq, endSeq + 1),
session: structuredClone(loaded.header),
target: targetSnapshot,
events,
startSeq,
endSeq,
}

View File

@@ -0,0 +1,27 @@
/** Detached session-query snapshots that preserve message immutability. */
import { deepFreeze } from '@deepseek-ai/dsh-llm'
import type { SessionEvent } from '@deepseek-ai/dsh-session'
/**
* Clone one event while retaining the invariant that every identified message is frozen.
* @param event - source event from one corpus observation.
* @returns a detached event whose message value, if any, is deeply frozen.
*/
export function snapshotEvent<T extends SessionEvent>(event: T): T {
const snapshot = structuredClone(event)
switch (snapshot.type) {
case 'user/message':
deepFreeze(snapshot.data)
break
case 'assistant/message':
case 'tool/result':
case 'steering/message':
deepFreeze(snapshot.data.message)
break
default:
// SessionEventMap is merge-extensible; plugin-owned log-only events carry no core message.
break
}
return snapshot
}

View File

@@ -10,6 +10,7 @@ import type {
SessionLineageTrace,
SessionRecord,
} from './types.ts'
import { snapshotEvent } from './snapshot.ts'
interface EventLogAnalysis {
records: SessionEventRecord[]
@@ -51,7 +52,7 @@ export function currentSurfaceEvents(
'SESSION_QUERY_INVALID_SURFACE',
)
}
return structuredClone(event)
return snapshotEvent(event)
})
}