Module agent_session

Module agent_session 

Source
Expand description

Agent-anchored session zones (Option E, PR 1 of 2).

A session zone is bound to the agent definition (definition_id), not the identity bundle the agent currently uses. Two agents that share an identity bundle keep separate session histories.

§Zone naming

  • Active: agent:<defId>:current
  • Archived: agent:<defId>:archive:<unix_ms>

Files inside a zone keep the existing shape: output.state.json (full UI snapshot) and output (raw NDJSON stream for crash-recovery replay).

§Migration (migrate_block_zones_v1)

On first srv startup after this PR ships, the per-block zones (the pre-Option-E layout where each blockId owned its own zone) are back-filled into the new per-agent layout:

  1. For each db_block row with meta.view = "agent" and a non-empty output.state.json in its block-keyed zone, copy the contents to agent:<defId>:archive:<block-zone-createdts>.
  2. For each definition, copy the most-recently-modified per-block snapshot to agent:<defId>:current.
  3. Write the marker file <data_dir>/migration_agent_zones_v1.flag.

The migration is read-only against the existing per-block zones — GC of those is a later PR.

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.

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.
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_session
Archive agent:<defId>:current to agent:<defId>:archive:<now_ms>.
collapse_preview 🔒
ensure_file 🔒
Ensure a file exists in zone. No-op when present.
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).
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.
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).