Files
deepseek-harness/packages/session-query/session-query/src/cold-read.ts
T

58 lines
2.4 KiB
TypeScript

/** One-shot cold session read through the handle-based persistence seam. */
import { interruptedTurnClosers } from '@deepseek-ai/dsh-session'
import type { SessionEvent, SessionHeader, SessionId, SessionLogOffset, SessionSeedEventState } from '@deepseek-ai/dsh-session'
import type SessionPersistence from '@deepseek-ai/dsh-session-persistence'
import type { SessionHandleReadResult } from '@deepseek-ai/dsh-session-persistence'
/** A stored session log balanced for read-only viewing. */
export interface ColdSessionLog {
/** Aliasing state of the persisted events; synthetic closers are locally owned. */
readonly eventState: SessionSeedEventState
/** The stored header, fixed when the read handle opened. */
readonly header: SessionHeader
/** Exact fork-inherited event count paired with {@link header}. */
readonly inheritedEventCount: SessionLogOffset
/** Stored events plus deterministic in-memory closers for an interrupted final turn; nothing is written back. */
readonly events: SessionEvent[]
}
/**
* Read one complete stored session log without taking ownership or mutating
* storage: open a read handle, read the validated contiguous log, close the
* handle, and append `interruptedTurnClosers` so a log whose writer crashed
* mid-turn folds as a balanced transcript. Backend failures propagate
* unmapped — each caller owns its error taxonomy.
* @param persistence - the mounted persistence service.
* @param sessionId - the stored session to read.
* @param signal - optional cancellation for the open and read work.
* @returns an adoptable seed in a caller-owned outer array, ready for in-place Session restoration.
*/
export async function readColdSessionLog(
persistence: SessionPersistence,
sessionId: SessionId,
signal?: AbortSignal,
): Promise<ColdSessionLog> {
const options = signal === undefined ? undefined : { signal }
const handle = await persistence.open(sessionId, 'read', options)
let read: SessionHandleReadResult
try {
read = await handle.read(0, undefined, options)
} catch (error: unknown) {
try {
await handle.close()
} catch {
// The read failure is the actionable cause; a close failure on the same broken handle adds nothing.
}
throw error
}
await handle.close()
const { events } = read
return {
eventState: read.eventState,
header: handle.header,
inheritedEventCount: handle.inheritedEventCount,
events: [...events, ...interruptedTurnClosers(events)],
}
}