Session class final

A session: an append-only tree of records with an active leaf.

Ported from pi's Session class. All reads go through the storage's in-memory index; all writes append to the underlying JSONL file.

Constructors

Session(SessionStorage _storage, {Future<List<CustomRecord>> customRecordScan(Set<String> types)?})
Creates a Session over storage. customRecordScan, when given (the JSONL repo injects itself), lets the session read custom records RESIDENCY can hide — the windowed tail drops side-leaf and below-tail records from getEntries() (issue #488 class), while the raw scan streams the whole file chain. The obligations ledger's projection fallback is the consumer.

Properties

cachedId → String?
The session id when the storage caches the header synchronously (SessionHeaderCache — the full JsonlSessionStorage and the windowed WindowedSessionStorage always do); null otherwise. Used as the prompt-cache affinity key, where a synchronous read lets provider stream functions resolve it per call without an async hop.
no setter
cachedMetadata → SessionMetadata?
The session metadata when the storage caches the header synchronously (SessionHeaderCache) — used for the session-scoped .tools/<sessionId>.yaml path, which is derived from the session file's location; null otherwise.
no setter
customRecordScan → Future<List<CustomRecord>> Function(Set<String> types)?
Raw custom-record scan over the full session file chain, keyed by record type. Null when the session was built without a repo behind it (direct constructions in tools/tests) — consumers then degrade to the resident view only.
final
hashCode → int
The hash code for this object.
no setterinherited
runtimeType → Type
A representation of the runtime type of the object.
no setterinherited

Methods

appendActiveToolsChange(List<String> activeToolNames) → Future<String>
Appends an active-tools change. Returns the new record id.
appendCheckpoint({required int messageCount, String? goal}) → Future<String>
Appends a checkpoint mark for the checkpoint/rewind tools. Returns the new record id — the rewind uses it as the session-tree branch anchor. See CheckpointRecord.
appendCompactCheckpoint({required String firstRecordId, required String lastRecordId, required String text, required List<String> coversRecordIds, required List<String> flattenedRecordIds}) → Future<String>
Appends a structured-compaction checkpoint (issue #148 pass 2): the range firstRecordId, lastRecordId stops rendering individually and is replaced by text; coversRecordIds names every hidden segment the checkpoint subsumes, flattenedRecordIds the inner checkpoints folded in by the depth cap.
appendCompaction({required String summary, required String firstKeptEntryId, required int tokensBefore, Object? details, bool? fromHook}) → Future<String>
Appends a compaction record. Returns the new record id.
appendCustomEntry({required String customType, Object? data}) → Future<String>
Appends an application-defined record that stays out of model context. Returns the new record id.
appendCustomMessageEntry({required String customType, required Object content, required bool display, Object? details}) → Future<String>
Appends an application-defined record that projects into model context as a user message. content is a String or a List<ContentBlock>. Returns the new record id.
appendHiddenRange({required List<String> recordIds}) → Future<String>
Appends a structured-compaction hide event (issue #148 pass 1): the records in recordIds keep living in the file but project as one-line markers. Ids must be stable record ids of records already on the append path — never positions.
appendLabel(String targetId, String? label) → Future<String>
Attaches (or removes, when label is null) a label to targetId. Returns the new record id.
appendMessage(Message message) → Future<String>
Appends a conversation message at the active leaf. Returns the new record id.
appendModelChange({required String provider, required String modelId, String? baseUrl, String? customProvider}) → Future<String>
Appends a model change. Returns the new record id. baseUrl and customProvider pin the serving endpoint and the saved custom provider entry (gh-1000) so a restore re-resolves onto the same provider+key binding; leave both null for catalog-default switches.
appendSegmentPin({required List<String> recordIds, required bool pinned}) → Future<String>
Appends a segment pin event (issue #1379 tier 2): the records in recordIds become immune to every hide/compact path until an unpin event names them again. Recorded over stable record ids — replay applies pin records in file order, last one wins.
appendSessionName(String name) → Future<String>
Sets the session display name (newlines are sanitized away).
appendThinkingLevelChange(String thinkingLevel) → Future<String>
Appends a thinking-level change. Returns the new record id.
buildContext() → Future<SessionContext>
Rebuilds the full SessionContext (messages plus derived model state) for the active branch.
buildContextMessages() → Future<List<Message>>
Rebuilds the model context from the active branch: messages in branch order, with compaction, branch-summary, and custom-message records projected per pi's buildSessionContext + convertToLlm.
ensureCompactionBoundaryResident({int maxPages = 512, int? tokenBudget}) → Future<bool>
Pages older chunks into a windowed storage until the newest compaction record is resident — the "open from the end, up to the compaction" resume (owner directive): a marathon session opens in O(tail-after-compaction) instead of parsing gigabytes. Stops when the active branch carries a CompactionRecord, when tokenBudget is already covered by the resident tail, or when the file start is reached (sessions without compaction page everything, as before). A no-op for full storages. maxPages bounds pathological files.
getBranch({String? fromId}) → Future<List<SessionRecord>>
The records of the active branch (or of the branch ending at fromId), root-first.
getChildren(String? parentId) → Future<List<SessionRecord>>
The direct children of parentId (roots when null), in file order.
getEntries() → Future<List<SessionRecord>>
All records in file order.
getEntry(String id) → Future<SessionRecord?>
Looks up a record by id.
getLabel(String id) → Future<String?>
The current label attached to record id, if any.
getLeafId() → Future<String?>
The id of the active leaf record, or null at the tree root.
getMetadata() → Future<SessionMetadata>
The session metadata (from the file header).
getSessionName() → Future<String?>
The session's display name (last session_info record wins).
getStorage() → SessionStorage
The underlying storage.
moveTo(String? entryId, {String? summary, Object? details, bool? fromHook}) → Future<String?>
Moves the active leaf to entryId (or the tree root when null), appending a leaf record. When summary is provided, also appends a branch_summary record and returns its id; otherwise returns null.
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
projectPath(List<SessionRecord> path) → List<Message>
Projects an explicit record path (root-first) into messages — the same fold buildContext applies to the storage-walked branch. The windowed host keeps its own accumulated view path (storage residency is tail-anchored and drops old records), so the transcript renders through this instead of a second storage walk.
resolveSessionName({int maxPages = 64}) → Future<String?>
The session's display name, paging older chunks when the last session_info record sits outside a windowed storage's resident tail (a name written long before the newest records). maxPages bounds the scan for pathological files.
toString() → String
A string representation of this object.
inherited

Operators

operator ==(Object other) → bool
The equality operator.
inherited