fix: complete immutable message migration
This commit is contained in:
@@ -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,
|
||||
}
|
||||
|
||||
27
packages/session-query/session-query/src/snapshot.ts
Normal file
27
packages/session-query/session-query/src/snapshot.ts
Normal 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
|
||||
}
|
||||
@@ -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)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user