import type { WorkingStateSnapshot } from '../../compaction/wire.js'; import { type TurnRecorder } from '../../manager/session/turn-recorder.js'; import type { CheckpointScope, SessionCheckpointStore } from '../../store/checkpoint/index.js'; import type { SessionLog } from '../../store/session-log/index.js'; import type { SerializedSpanContext } from '../../telemetry/attributes.js'; import type { CheckpointId, CheckpointSummary, HITLDecisionRequest, HITLResumeDecision, PendingDecision } from '../../types/hitl/index.js'; import type { MessageId, TurnId } from '../../types/ids/index.js'; import { type Message, type UserMessage } from '../../types/message/index.js'; import { type Checkpoint } from '../../types/session/checkpoint.js'; import type { CheckpointListEntry } from '../../types/session/fork.js'; /** A checkpoint the turn just wrote: its id and the document. */ export interface CreatedCheckpoint { readonly id: CheckpointId; readonly document: Checkpoint; } /** * A checkpoint read back for a resume: the document, the context it * restores (the fold of the session log through `throughSeq`), and the * decision it is parked on, if any. */ export interface RestoredCheckpoint { readonly id: CheckpointId; readonly document: Checkpoint; readonly messages: Message[]; /** Ids of the restored messages that have records, by message. */ readonly messageIds: ReadonlyMap; readonly pending?: PendingDecision; readonly latestUserMessage?: UserMessage; } /** A decision one of a turn's checkpoints was parked on, as the log records it. */ export interface RecordedPark { readonly decisionId: string; readonly turnId: TurnId; readonly checkpointId: CheckpointId; readonly pending: PendingDecision; } /** Projection from a checkpoint document to the public listing entry. */ export declare function toCheckpointListEntry(cp: Checkpoint): CheckpointListEntry; /** * Every park a session log records, newest last: `decision_requested`, and * whether a `decision_resolved` or `decision_expired` has answered it. */ export declare function readParks(log: SessionLog, options?: { readonly turnId?: TurnId; }): Promise; /** * The newest park of a session (or of one of its turns) that is still * awaiting a human decision, or `null` when nothing is parked. * * Standalone so a host can ask the question without constructing a turn: an * approval-queue worker in a different process has the session log and * nothing else. An expired park is not outstanding. */ export declare function findPendingCheckpoint(log: SessionLog, options?: { readonly turnId?: TurnId; readonly now?: number; }): Promise; /** Whether a park's absolute deadline has passed. No deadline never expires. */ export declare function isExpiredPark(pending: PendingDecision, now?: number): boolean; /** * Every outstanding park of a session whose deadline has passed, so a host * can sweep them (`CheckpointManager.expire`, or `decision_expired` appended * under the session lease). */ export declare function listExpiredParks(log: SessionLog, options?: { readonly turnId?: TurnId; readonly now?: number; }): Promise; /** * What a {@link CheckpointManager} needs of the turn it serves: the log it * reads and appends to (in order with the turn's other records), and the * tenant decisions are attributed under. A {@link TurnRecorder} is one. */ export type CheckpointRecords = Pick; /** * A turn's checkpoints: documents in the session's checkpoint store, * committed by a `checkpoint_written` record, and the parks (`decision_*` * records) that reference them. * * A checkpoint holds no messages. Its context is the fold of the session log * through `throughSeq`; `restore` reads it back from the log and refuses a * checkpoint whose document or covered prefix no longer matches its record. */ export declare class CheckpointManager { private readonly recorder; private readonly store; private readonly scope; private workingStateSource?; private latestUserMessageSource?; private restoredUserMessage?; private restoredUserMessageId?; private answerReviewAttemptsSource?; private restoredAnswerAttempts; private structuredReviewAttemptsSource?; private restoredReviewAttempts; private nativeStructuredAttemptsSource?; private restoredNativeAttempts; private lastCreatedId?; private traceSource?; private parkTtlMs?; /** * The turn's attribution instant, identical on every checkpoint of the * turn: adopted from the checkpoint a resume came back through, or minted * from the turn's own start. */ private turnCreatedAt?; /** The turn where its iteration loop began; see {@link markLoopStart}. */ private loopStart?; constructor(recorder: CheckpointRecords, store: SessionCheckpointStore, scope: CheckpointScope); /** Wire compaction's state in, so every checkpoint carries a snapshot. */ setWorkingStateSource(source: () => WorkingStateSnapshot | undefined): void; /** One current intent snapshot, including checkpoints created by tool/HITL paths. */ setLatestUserMessageSource(source: () => UserMessage | undefined): void; get restoredLatestUserMessage(): UserMessage | undefined; setAnswerReviewAttemptsSource(source: () => number): void; get restoredAnswerReviewAttempts(): number; setNativeStructuredAttemptsSource(source: () => number): void; get restoredNativeStructuredAttempts(): number; setStructuredReviewAttemptsSource(source: () => number): void; get restoredStructuredReviewAttempts(): number; /** The turn's root span, so every checkpoint records the trace it was taken inside. */ setTraceSource(source: () => SerializedSpanContext | undefined): void; /** Default time-to-live applied to every park this manager records. */ setParkTtl(ttlMs: number | undefined): void; /** * Write a checkpoint of the turn as it stands: every queued record lands * first, the document names the log's head as `throughSeq`, and a * `checkpoint_written` record commits it. */ create(recorder: TurnRecorder, iteration: number): Promise; /** * Remember the turn as it stands where its iteration loop begins, before * the loop's first provider request. Nothing is written: the state is * only committed, by {@link createAtLoopStart}, when the turn has to * pause before it wrote a checkpoint of its own. */ markLoopStart(recorder: TurnRecorder): Promise; /** * A checkpoint of the turn as {@link markLoopStart} found it, so a turn * that fails recoverably before any checkpoint of its own has something * to pause on and resume from. It covers the log only through the loop's * start and counts none of the guards used since, so resuming from it * discards every iteration the turn ran before the fault, completed ones * included (a `max_tokens` continuation request opens a new iteration). * Its iteration is the one the loop began at: 0 for a fresh * turn, the restored count for a resumed one. `undefined` when no loop * start was marked. */ createAtLoopStart(recorder: TurnRecorder): Promise; /** The part of a checkpoint document that describes the turn at one instant. */ private captureState; private write; /** * The id of the record that carries a message's text: its own record, * or — for operator guidance delivered attached to a tool result — the * record of the tool result that carries it. */ private messageIdOf; /** Found once and kept: a compaction may later drop the carrier from the context. */ private readonly steeringCarriers; private steeringCarrierOf; /** The most recent checkpoint this manager wrote, if any. */ get lastCheckpointId(): CheckpointId | undefined; /** * The trace a checkpoint was taken inside, for parenting a resumed turn. * Never throws: telemetry continuity is not worth failing a resume over. */ readTraceContext(checkpointId: CheckpointId): Promise; /** * Record that the turn parked at `checkpoint` awaiting a human: a * `decision_requested` record naming the checkpoint, with an absolute * deadline when the turn has a park time-to-live. */ park(checkpoint: { readonly id: CheckpointId; }, request: HITLDecisionRequest, options?: { readonly ttlMs?: number; }): Promise; /** * Mark an expired park as no longer outstanding: `decision_expired`. The * request stays in the log as evidence of what was asked. */ expire(checkpointId: CheckpointId): Promise; /** * Record the answer, so an outstanding park stops looking outstanding: * `decision_resolved`. A no-op when the checkpoint was never parked or the * park is already answered. */ unpark(checkpointId: CheckpointId, decision: HITLResumeDecision): Promise; private openPark; /** The turn's outstanding park, if it has one. */ findPending(): Promise; /** * Read a checkpoint back for a resume. Refused when it is missing, when * its document no longer matches its record, or when the log prefix it * covers changed. */ restore(checkpointId: CheckpointId): Promise; /** The turn's checkpoint documents, oldest first. */ list(): Promise; /** Listing projection used by the public `listCheckpoints` API. */ listEntries(): Promise; /** * Collect old checkpoints until `keepLast` newer ones remain, never one an * open decision references; a `checkpoint_pruned` record names what went. */ prune(keepLast: number): Promise; static buildSummary(recorder: TurnRecorder, iteration: number): CheckpointSummary; } /** * The context a checkpoint restores: the fold of its session log through * `throughSeq`, the decision it is parked on, and the operator intent it * names. */ export declare function restoreCheckpointContext(log: SessionLog, document: Checkpoint): Promise; //# sourceMappingURL=checkpoint.d.ts.map