Repository navigation
feat(harness): add loop lifecycle seams and snapshot every turn - #108
Merged
Merged
Conversation
The drain took one state snapshot per exchange and reused it for every tool-use and steer turn, so a settings edit, a session binding or a tool declared mid-chain only landed at the next exchange, and nothing could step in between stages. The drain is now one flat loop that takes a fresh snapshot before each turn, and a new Hooks service gives it three seams, composed in fixed order in one place: - prepareNextTurn runs between turns with the fresh snapshot and may replace it - prepareRequest runs before every provider attempt, retries included, with the retry number and the previous failure - finishTurn runs after a turn commits and can end the run or ask for one more request. It also sees the input the next run would promote (steers, else the oldest follow-up), read without promoting it. An explicit resume or a recovered run now answers a reply that stopped mid-chain before a queued follow-up goes in, and still promotes steers that land while it loads. Prompts and wakes are unchanged. The seams are no-ops until a consumer is wired in. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
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.
What
The session drain took one state snapshot per exchange and reused it for every tool-use and steer turn. A settings edit, a session model binding or a tool declared mid-chain only took effect at the next exchange, and nothing could step in between stages.
Hooksservice (runner/hooks.ts) with three seams, composed in fixed order in its live layer (no registry, no self-registering handlers):prepareNextTurn(turn, next)runs between turns with the fresh snapshot and may replace it.prepareRequest(request, { retry, failed? })runs before every provider attempt, retries included.finishTurn(turn)runs after the turn commits and returns"end" | "continue" | undefined."end"wins over"continue"and leaves queued input for the next run."continue"only sends a request if something was appended after the reply.Completed.pending: what the next run would promote (queued steers, else the oldest follow-up), read without promoting it.The seams are no-ops until a consumer is wired in.
Behaviour changes
Verification
runner.loop.test.ts: tool declared mid-chain reaches the next request,finishTurnend and continue,prepareRequeston a retry (replacement model reaches the request), pending input shown without promotion, a steer landing while a resume loads. Artifact:test/__artifacts__/runner.hooks.json.settings.loop.test.tsexpectations updated from per-exchange to per-turn.vp check,vp run typecheckand the full harness suite pass.Not covered
finishTurn"continue"with an appended entry: nothing can append session entries yet.🤖 Generated with Claude Code