# Compaction and Reset

How a long run is kept inside the model's window, and what reset and remove clear.

## In-run compaction

Beyond the stored tiers, `internal/agents/exec/compact` keeps a single long run inside the model's window. Each step is a separate stage, applied in order and only as far as needed:

| Stage | Trigger | Effect |
|---|---|---|
| `CheckThreshold(model)` | Every iteration | Token budget for the current model — 80 % of its context window. Since v1.0.11 the window comes from a live table fetched once per hour from `https://llm-io.agenvoy.com/` and keyed by vendor + model, replacing the hard-coded per-family sizes; a model missing from the table falls back to 128 K. Since v1.0.25 a `copilot@` model missing from the table uses the `max_context_window_tokens` that Copilot's own `/models` endpoint reports (fetched in the background, refreshed every 24 h) instead of the former flat 256 K |
| `ExtractOldHistories` | Budget exceeded, first time in the run | Fold older conversation turns into the rolling summary |
| `ToolHistory` | Budget exceeded again, or there were no older turns to fold | Summarize the oldest tool-call exchanges into text |
| `TrimFallback` | Provider returns a context-length error | Since v1.1.1 the error first runs the same `ExtractOldHistories` → `ToolHistory` pass and resends; only when that pass cannot compact is the oldest exchange dropped before resending |
| `RawToolFallback` | Model switch mid-run | Convert tool history to plain text so the new model can read it |

Manual compaction runs from the TUI (`/compact`; the `/memory` command was removed, reset is now `/reset`) or `POST /v1/session/:id/memory`. That one endpoint takes an `action`: `compact` drops older messages and returns `removed`, `summary` rebuilds the rolling summary and returns `count`, and `reset` clears the conversation — `mode: "summary"` keeps the rolling summary, `mode: "all"` wipes it too. Since v1.1.1 the TUI popup also has a read-only `summary` tab that shows the current rolling summary.

### Search routing

| `match` parameter | Source | Use case |
|---|---|---|
| `semantic` (default) | ToriiDB VSearch | "What did we discuss about X?" — meaning-based |
| `keyword` | SQLite FTS5 (archive) + ToriiDB substring (recent) | "Find messages containing 'sandbox'" — exact text |

### Cross-session error memory

Tool failures and the fix that resolved them persist across sessions in `error_memory` with **90-day TTL**. Only records written with `outcome=resolved` are stored; `failed` / `abandoned` writes are discarded, so abandoned strategies are no longer kept. On hit (either via keyword `Contains` or `db.VSearch`), the entry's TTL is refreshed via `db.Expire`.

When the same tool name fails in a future session, `toolCall.go` automatically queries `error_memory` and appends up to 3 related records to the failed tool result as `related_errors`; the agent applies the recorded fix.

A record's recorded action can be edited from the web dashboard's Lessons view (`PATCH /v1/torii/error`, which rewrites `action` and keeps the TTL); `GET /v1/torii/error` lists records.

## Reset / remove behavior

| Operation | `history.json` | ToriiDB `DBSessionHist` | SQLite (messages + meta) | `summary.json` |
|---|---|---|---|---|
| Compact (auto) | Trimmed to 80% | Entries < cutoff removed | Untouched (already has all data) | Untouched |
| Reset (`/reset`, `mode=summary`) | Deleted | Cleared | Cleared | Preserved |
| Reset (`mode=all`) | Deleted | Cleared | Cleared | Deleted |
| Remove session | Directory deleted | Cleared | Cleared | Directory deleted |
