docs(turn-loop): document PromptTooLong archive+requeue, TurnOutcome=Result, credential-file session detection
This commit is contained in:
parent
90af3e8d0b
commit
dd7f8c5ebb
1 changed files with 25 additions and 14 deletions
|
|
@ -43,14 +43,18 @@ Each agent harness (`hive serve` — one binary for all agents) runs:
|
|||
the per-agent web UI login flow; on success the sentinel is
|
||||
cleared and the queued message drives the next turn normally.
|
||||
**Mtime-snapshot resumption**: `wait_for_login`
|
||||
snapshots the `~/.claude/` dir (newest file mtime + file count)
|
||||
at entry and only resumes when that snapshot advances — not
|
||||
just when credentials exist on disk. This prevents a silent
|
||||
infinite-401 loop: stale credentials already on disk at the
|
||||
time of the 401 no longer cause an immediate false-resume. The
|
||||
`DirSnapshot` struct tracks both axes; either a mtime advance
|
||||
OR a file-count change triggers resume (the count axis handles
|
||||
filesystems where `modified()` errors on every file).
|
||||
snapshots the `~/.claude/` dir (newest mtime + count over the
|
||||
credential files in `login::CRED_FILE_NAMES`) at entry and only
|
||||
resumes when that snapshot advances — not just when credentials
|
||||
exist on disk. This prevents a silent infinite-401 loop: stale
|
||||
credentials already on disk at the time of the 401 no longer cause
|
||||
an immediate false-resume. The `DirSnapshot` struct tracks both
|
||||
axes; either a mtime advance OR a file-count change triggers resume
|
||||
(the count axis handles filesystems where `modified()` errors on
|
||||
every file). Boot detection (`login::has_session`, deciding Online
|
||||
vs NeedsLogin) keys off the same `CRED_FILE_NAMES` set — the files
|
||||
`/logout` deletes — so leftover session-history files don't read as
|
||||
a live session after a logout + container recreate.
|
||||
7. Emit `LiveEvent::TurnEnd { ok, note }`. Sleep `poll_ms` to avoid
|
||||
tight loops on transient failures.
|
||||
|
||||
|
|
@ -108,14 +112,16 @@ and the manager fall through to operator).
|
|||
|
||||
### Turn outcomes
|
||||
|
||||
`turn::TurnOutcome` drives the post-claude branch:
|
||||
`turn::TurnOutcome` (`Result<bool, TurnError>` — `Ok(compacted)` on success,
|
||||
else a `TurnError`) drives the post-claude branch:
|
||||
|
||||
| Outcome | Action |
|
||||
| --- | --- |
|
||||
| `Ok` / `Compacted` | `ack_turn` |
|
||||
| `RateLimited` | sleep `HIVE_RATE_LIMIT_SLEEP_SECS` (default 300), requeue inflight, status back to `online` |
|
||||
| `AuthFailed` | emit `needs_login_idle` sentinel, requeue inflight, park in `wait_for_login` |
|
||||
| `Failed(err)` | route `[system] \`<qualified-label>\` claude turn failed:\n<err>` to `<parent>` via `send_to_parent` |
|
||||
| `Ok(_)` (`false` normal / `true` compacted) | `ack_turn` |
|
||||
| `Err(PromptTooLong)` | `drive_turn` archived the session (the lib already compacted + retried and it still overflowed); requeue inflight so the message redelivers into a fresh session that fits — no status park |
|
||||
| `Err(RateLimited)` | sleep `HIVE_RATE_LIMIT_SLEEP_SECS` (default 300), requeue inflight, status back to `online` |
|
||||
| `Err(AuthFailed)` | emit `needs_login_idle` sentinel, requeue inflight, park in `wait_for_login` |
|
||||
| `Err(Failed(err))` | route `[system] \`<qualified-label>\` claude turn failed:\n<err>` to `<parent>` via `send_to_parent` |
|
||||
|
||||
After the outcome handler, the stats sink records a row and the
|
||||
`hyperhive-continue` sentinel (dropped by the `request_next_turn`
|
||||
|
|
@ -233,7 +239,12 @@ window with two triggers baked into its `run`:
|
|||
- **Reactive** — claude-code prints `Prompt is too long`. The session is
|
||||
*already* past the window, so no turn can run on it — the session
|
||||
`/compact`s straight away and retries the same wake-up prompt once. No
|
||||
notes-checkpoint turn is possible here: the detail is gone.
|
||||
notes-checkpoint turn is possible here: the detail is gone. If the retry
|
||||
*still* overflows, `run` surfaces `Error::PromptTooLong`; `drive_turn`
|
||||
then archives the session (session lifecycle stays hive-side) and the
|
||||
serve loop requeues the message so it redelivers into a fresh session
|
||||
(see [Turn outcomes](#turn-outcomes) — the wake prompt itself is tiny, so
|
||||
the overflow was the accumulated context the archive clears).
|
||||
- **Proactive** — a turn finishes cleanly but the last inference's context
|
||||
size crossed the policy watermark. While the session is still healthy it
|
||||
runs one synthetic *notes-checkpoint* turn (`CHECKPOINT_PROMPT` —
|
||||
|
|
|
|||
Loading…
Reference in a new issue