Repository navigation
feat(conversation): budget exhaustion becomes a pause with invisible resume - #14
Merged
Merged
Conversation
…resume
no-hassle long-running turns — Lionidas plan 20261021T100758Z Stage A
(forensics: sess_e7cb501 died at hop 12 with 445 chunks of real work
reduced to one error line, session poisoned to error).
- catch seam: LoopError BUDGET_EXCEEDED stashes the full partial
transcript (LoopError.partial — tool results included) via new
Storage.stashPartial/takePartial (butler_turn_partials, one row per
session, sqlite + postgres), keeps the session ACTIVE, and fails the
turn with 'ran out of runway — the work so far is kept; send a
message to continue from where it stopped'. ABORTED and every other
failure keep today's honest session poisoning.
- send seam: the next message in that session seeds the stashed
transcript ahead of history plus a [resume] system note ('continue
from where it stopped — do not repeat completed steps'); the stash is
consumed one-shot (takePartial deletes). A corrupt stash can never
kill the next turn.
- tests: stash roundtrip one-shot+replace; exhaust → friendly fail +
active + seeded tool-role messages observed by the next provider
call; per-session isolation (no cross-session leakage); ABORTED
still poisons (regression guard).
Gates: tsc 0, budget spec 4/4, full suite 40 files / 230 passed
5 skipped (single fork).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Budget exhaustion becomes a pause with invisible resume
Lionidas plan
plans/20261021T100758Z-hop-budget-exhausted-sess-e7cb501-plan.mdStage A. Forensics: Lionidas sessionsess_e7cb501died withhop budget exhausted (12)— 12 model calls (~240k tokens) and 445 chunks of genuine work reduced to one error line, and the session flipped toerrorwith no way to continue except restarting from scratch (which re-burns the same hops and dies again).What changes
transport/conversation.tscatch seam):LoopErrorwithcode === 'BUDGET_EXCEEDED'now stashes the full partial transcript —LoopError.partial, tool results included — via newStorage.stashPartial/takePartial(newbutler_turn_partialstable, one row per session, sqlite + postgres impls). The session staysactive, and the turn fails with "ran out of runway — the work so far is kept; send a message to continue from where it stopped."[resume]system note ("continue from where it stopped — do not repeat completed steps"). One-shot: the stash is consumed on take. A corrupt stash can never kill the next turn.ABORTEDand non-budget failures still poison the session toerror— only the budget path softens. The wall-clock guard (provider-level abort at the deadline) and hop guard are untouched.Tests (
test/conversation-budget.test.ts, 4/4)Stash roundtrip (one-shot + replace-wins) · exhaust → friendly fail +
active+ the next provider call OBSERVES the seeded tool-role messages (history rows never carry roletool— this proves resume) · per-session isolation (no cross-session stash leakage) · ABORTED still poisons (regression guard).Gates:
tsc0, full suite 40 files / 230 passed, 5 skipped (single fork).Consumer note (Lionidas Stage B rides separately):
Storagegained two required members — consumers implementing their own storage must add them; Lionidas uses butler's ownSqliteStorage, so no action there.