Module agent_session

Module agent_session 

Source
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§

ArchiveSummary
A single archive row. Mirrors the shape of RecentSessionRow’s preview fields so the frontend can reuse the same row component.
MigrationStats
Stats from migrate_block_zones_v1. Logged at INFO at startup.
TemplatePromoteStats
Stats from migrate_promote_template_sessions_v1. Logged at INFO.

Enums§

CopyAction 🔒
Per-file decision inside move_zone’s retry-aware loop. See the doc comment in move_zone for 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 in main.rs). Backs the agent:<defId>:current zone so a conversation loads when the agent is opened from any build/channel — finishing the cross-channel arc (#1387–#1396). None until set_global_transcript_store runs (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 if definition_id is invalid; callers should validate_definition_id first in release.
agent_zone_for_block_meta
Resolve the agent’s GLOBAL agent:<defId>:current zone from a block’s meta.
append_session_output
Append line (with a trailing newline added if not present) to output in agent:<defId>:current. Creates the file if missing.
archive_global_current 🔒
Archive the agent’s GLOBAL agent:<defId>:current content 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>:current to agent:<defId>:archive:<now_ms>.
clear_global_current_zone 🔒
Delete output.state.json + output from the agent’s GLOBAL agent:<defId>:current zone, 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 :current clear in archive_session.
clear_local_current_zone 🔒
Delete output.state.json + output from a per-channel :current zone, 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 sourceBlockId was mirrored into agent:<defId>:current, breaking cross-channel opens). For each def_id, rewrite its global snapshot’s sourceBlockId to “” 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 s matches [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_zone to new_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 sourceBlockId to “” 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.json from agent:<defId>:current. Returns Ok((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.json from zone in store. Ok(None) when absent.
set_global_transcript_store
Install the global transcript store. Called once from main.rs startup. Idempotent — a second call is ignored (the first store wins).
validate_and_current
Convenience: validate + build the current-zone string. Returns Err with a stable error prefix on bad input so RPC callers see a consistent message.
write_session_state
Write content to output.state.json in agent:<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).