# Sessions & Agents

## Session

A session is the core unit in Agenvoy. Each session has its own conversation context, memory, agent persona, and tool configuration.

Storage path: `~/.config/agenvoy/sessions/<sid>/`

| File | Purpose |
|---|---|
| `history.json` | Recent conversation, delta-appended |
| `summary.json` / `.summary_cursor` | Rolling summary and its incremental cursor |
| `action.log` | Tool call audit log. One line per event, `[timestamp][window_hash][kind][task_hash] body` (`window_hash` is the writing window's hash, the same value events carry as `window_hash`); the trailing `task_hash` bracket was added in v1.0.2 so every line can be traced back to the run that wrote it, and the replay parser treats it as optional so pre-v1.0.2 lines still load |
| `.cmd_history` | TUI input history for this session |
| `.claude_code/<model>_<hash>.json` | Since v1.1.3, one per `claude-code` model and system prompt hash used in the session (`_plain` appended for calls without tools): its Claude Code session id, message fingerprints and last answer, so a restarted daemon can `--resume` instead of replaying history (`@`, `/` and `\|` become `_`). v1.1.1 to v1.1.2 wrote one `claude_code_<model>.json` per model in the session directory |
| `pending/` | Pending `ask_user` / confirm metadata, one JSON per task hash |

Everything else moved into `~/.config/agenvoy/.store/history.db`:

| SQLite table | Content |
|---|---|
| `session` | Display name, `self_id`, persona (`role`), model, reasoning level. Since v1.1.0 the persona is written to both the `role` column and the legacy `rule` column, and read from `role` first |
| `note` + `note_fts5` | Removed in v1.0.23 along with operator notes; tables left in an older database are no longer read |
| `messages` + `messages_fts5` | Full message archive and its full-text index |
| `action_history` | Finished runs and their tool results |
| `file_history` | Recorded versions of every file the tools changed. Since v1.0.14 the unique index is `(dir, name, task_id, session_id)` for rows that carry a task, so one task records a given file once — the first version it saw — instead of one row per save; the migration deletes the duplicates already stored. Rows with an empty `task_id` are unaffected |
| `usage` | Per-model token spend, 28-day retention. Carries `elapsed_ms` per send since v1.0.11, which the summaries turn into `output_tps`. Since v1.0.26 each row also records the ids of the tool calls in that reply (`tool_calls`); since v1.1.0 `input` for `claude` and `claude-code` includes cache writes, matching how other providers report uncached input |

Vectors, tool cache, error memory, and running-task presence live in ToriiDB (`.store/db_0` ... `db_3`). Up to v1.1.1 the daemon migrated legacy per-session `bot.json`, `bot.md`, `config.json`, `status.json`, `usage.log`, `summary.meta.json` and the `history/` task directory into SQLite at startup; v1.1.2 removed those migrations, so such files left by an older install are no longer read — upgrade through v1.1.1 first to carry them over. The `state` table was dropped in v0.35.3: a running task is now an `action:<session_id>:<task_hash>` key in ToriiDB, refreshed every 55 s with a 60 s TTL, so a killed process stops being online on its own rather than needing a PID liveness check.

### Session prefixes and lifetime

| Prefix | Lifetime |
|---|---|
| `cli-*` | Permanent — local CLI / TUI work (TUI `/new`, or `POST /v1/session`) |
| `chat-*` | Permanent — web / API work (`POST /v1/send` with `persist=true`) |
| `dc-*` | Permanent (Discord channels) |
| `tg-*` | Permanent (Telegram chats — per-chat, shared across users in that chat) |
| `temp-*` | Reaped after 30 min idle (default for `POST /v1/send` and subagent sessions) |

Cleanup runs every 30 minutes via cron (and once on startup) against the `temp-*` prefix only — `cli-*`, `chat-*`, `dc-*`, and `tg-*` are never auto-reaped.

The prefix also decides where a confirmation goes back to (since v1.2.0 a run started from the TUI asks only the TUI window that started it), and it is what the TUI session picker groups by: with at least two groups present the picker shows an `all` tab plus one tab per prefix, current session first. A daemon-side `fsnotify` watcher logs the ID and configured name of every newly created session directory.
