Expand description
Agent-anchored session zones: one zone per agent definition, keyed by
definition_id (not identity bundle or block).
Zone names: active = agent:<defId>:current,
archived = agent:<defId>:archive:<unix_ms>. Each zone holds
output.state.json (full UI snapshot) and output (raw NDJSON stream).
See docs/specs/SPEC_CONTINUATION_SESSION_PERSISTENCE_2026_05_23.md.
Structs§
- Archive
Summary - A single archive row. Mirrors the shape of
RecentSessionRow’s preview fields so the frontend can reuse the same row component. - Migration
Stats - Stats from
migrate_block_zones_v1. Logged at INFO at startup. - Template
Promote Stats - Stats from
migrate_promote_template_sessions_v1. Logged at INFO.
Enums§
- Copy
Action 🔒 - Per-file decision inside
move_zone’s retry-aware loop. See the doc comment inmove_zonefor which round each variant addresses.
Constants§
- MIGRATION_
MARKER_ V1 - Marker file name for the per-data-dir one-shot migration gate.
- OUTPUT_
FILE - Raw NDJSON stream for crash-recovery replay.
- SNAPSHOT_
FILE - Full UI snapshot (JSON). Frontend reads this on pane mount.
- TEMPLATE_
PROMOTE_ MARKER_ V1 - Marker file name for the Phase 1 two-tier-picker migration.
Statics§
- GLOBAL_
TRANSCRIPT_ 🔒STORE - Process-global handle to the GLOBAL transcript FileStore (the one rooted at
<shared>/agents/transcripts, opened once inmain.rs). Backs theagent:<defId>:currentzone so a conversation loads when the agent is opened from any build/channel — finishing the cross-channel arc (#1387–#1396).Noneuntilset_global_transcript_storeruns (or never, in unit tests / when the shared root can’t be resolved), in which case the hot-path mirror is a no-op and reads fall back to the per-channel store.
Functions§
- agent_
archive_ zone agent:<definition_id>:archive:<ts_ms>.- agent_
current_ zone agent:<definition_id>:current. Panics in debug ifdefinition_idis invalid; callers shouldvalidate_definition_idfirst in release.- agent_
zone_ for_ block_ meta - Resolve the agent’s GLOBAL
agent:<defId>:currentzone from a block’s meta. - append_
session_ output - Append
line(with a trailing newline added if not present) tooutputinagent:<defId>:current. Creates the file if missing. - archive_
global_ 🔒current - Archive the agent’s GLOBAL
agent:<defId>:currentcontent into a local (per-filestore) archive zone, so a cross-channel viewer’s conversation is preserved + browsable in this channel before the global current is cleared. - archive_
session - Archive
agent:<defId>:currenttoagent:<defId>:archive:<now_ms>. - clear_
global_ 🔒current_ zone - Delete
output.state.json+outputfrom the agent’s GLOBALagent:<defId>:currentzone, if a global store is installed. Best-effort: a missing file is the expected “agent never mirrored” case (silent), other errors are logged but never propagated. Keeps the global zone in lockstep with the per-channel:currentclear inarchive_session. - clear_
local_ 🔒current_ zone - Delete
output.state.json+outputfrom a per-channel:currentzone, only for files that are present (so absence isn’t logged as an error). Best-effort — used after the global-preferred archive has persisted the content, to retire this channel’s (subset) copy. - collapse_
preview 🔒 - ensure_
file 🔒 - Ensure a file exists in
zone. No-op when present. - global_
transcript_ store - Borrow the global transcript store, if installed.
- heal_
global_ snapshot_ source_ block_ ids - One-shot heal for global snapshots poisoned before the normalize-on-mirror fix
(a channel-local
sourceBlockIdwas mirrored intoagent:<defId>:current, breaking cross-channel opens). For eachdef_id, rewrite its global snapshot’ssourceBlockIdto “” iff it isn’t already. Idempotent and cheap (one small JSON per agent); returns the number healed. Best-effort per agent. - is_
valid_ definition_ id - Returns true if
smatches[A-Za-z0-9_-]+. Rejects empty. - list_
archives - List archive zones for
definition_id, newest first. - migrate_
block_ zones_ v1 - One-shot migration of per-block agent session zones to per-agent
zones. Gated by a marker file under
data_dir; running twice is a no-op. - migrate_
promote_ template_ sessions_ v1 - Phase 1 two-tier picker migration: promote any seeded template that
carries a session zone into a fresh user-owned definition, then move
its
:current+:archive:*zones onto the new definition_id. - move_
zone 🔒 - Move every file in
old_zonetonew_zone, preserving names + bytes. Implemented as read-write-delete because FileStore doesn’t expose a native rename; the cost is bounded by the per-zone file count (1-2 in practice —output.state.json+output). - normalize_
snapshot_ for_ global - Strip
sourceBlockIdto “” for the GLOBAL (cross-channel) snapshot mirror. - now_ms 🔒
- read_
archive_ 🔒preview - Pull a small preview + node_count out of an archive’s
output.state.json. Returns("", 0)on any error. - read_
session_ state - Read
output.state.jsonfromagent:<defId>:current. ReturnsOk((None, None))when the zone doesn’t exist — that’s the “fresh agent, nothing to restore” path and is NOT an error. - read_
snapshot_ 🔒bytes - Read a zone file’s full bytes, mapping absence to
Ok(None). - read_
snapshot_ 🔒from - Read
output.state.jsonfromzoneinstore.Ok(None)when absent. - set_
global_ transcript_ store - Install the global transcript store. Called once from
main.rsstartup. Idempotent — a second call is ignored (the first store wins). - validate_
and_ current - Convenience: validate + build the current-zone string. Returns
Errwith a stable error prefix on bad input so RPC callers see a consistent message. - write_
session_ state - Write
contenttooutput.state.jsoninagent:<defId>:current. Idempotent — creates the file if missing, overwrites otherwise. - write_
zone_ 🔒file - Write the entire contents of a file in
zone. Creates the file if missing, otherwise replaces all parts atomically (FileStore single-tx).