add proactive context-size compaction with a notes-checkpoint turn

This commit is contained in:
damocles 2026-05-20 12:38:50 +02:00 committed by Mara
parent f2015954d9
commit 9cbb05bb86
3 changed files with 152 additions and 9 deletions

View file

@ -18,8 +18,9 @@ Each agent harness (`hive-ag3nt serve` or `hive-m1nd serve`) runs:
over stdin.
5. Stream stdout (JSON lines) into the bus as
`LiveEvent::Stream(value)`. Pump stderr as `Note`.
6. Wait for claude to exit. On `Prompt is too long`, run `/compact`
on the session once and retry the turn.
6. Wait for claude to exit. Compaction is two-pronged — *reactive*
on `Prompt is too long` and *proactive* on a context watermark
(see [Compaction](#compaction) below).
7. Emit `LiveEvent::TurnEnd { ok, note }`. Sleep `poll_ms` to avoid
tight loops on transient failures.
@ -43,14 +44,40 @@ override path: `HYPERHIVE_MODEL_FILE` env var for tests.
`--continue` keeps a persistent session per agent (claude stores
sessions in `~/.claude/projects/`, which is bind-mounted
persistently). Auto-compact and auto-memory are disabled via
`--settings` because hyperhive owns compaction (`/compact` on
overflow, retry once; operator can also force one via `/api/compact`).
`--settings` because hyperhive owns compaction — see
[Compaction](#compaction) below.
A one-shot `--continue` suppression is available via
`POST /api/new-session` (or `/new-session` slash command in the
per-agent terminal) — `Bus::take_skip_continue()` flips an
`AtomicBool` once per turn, the next claude invocation drops
`--continue`, every subsequent turn resumes normal behaviour.
### Compaction
claude's own in-session auto-compact is off (`--settings`); hyperhive
owns it explicitly in `turn::drive_turn`. There are two triggers:
- **Reactive** — claude-code prints `Prompt is too long` (the
`PROMPT_TOO_LONG_MARKER`). The session is *already* past the context
window, so no turn can run on it — `drive_turn` runs `/compact`
straight away and retries the same wake-up prompt once. No
notes-checkpoint turn is possible here: the detail is gone.
- **Proactive** — a turn finishes cleanly but the last inference's
context size (`Bus::last_ctx_usage().context_tokens()`) is at or
above a watermark. While the session is still healthy, `drive_turn`
injects one synthetic *notes-checkpoint* turn (`CHECKPOINT_PROMPT`
— "context is filling up, flush durable state into `/state` now")
and *then* runs `/compact`. This gives the agent a chance to
persist in-flight task state, decisions, and file paths before the
conversation detail collapses into a summary.
The watermark is `HIVE_COMPACT_WATERMARK_TOKENS` (default `150_000`,
~75% of a 200k window); set it to `0` to disable proactive compaction
entirely (the reactive path always applies). The proactive path is
best-effort — a failed checkpoint turn or `/compact` is surfaced as a
`Note` but never fails the turn that already succeeded. The operator
can also force a compaction any time via `/api/compact`.
The child runs with `cwd = /state` (when the bind exists; falls
back to the parent's cwd in dev), so any relative path in a tool
call (`Read foo.md`, `Bash ls`, `Write notes.md`) lands in the