Repository navigation
feat: run Gortex post-task diagnostics when the agent finishes - #57
Draft
vitaliyslion wants to merge 4 commits into
Draft
vitaliyslion wants to merge 4 commits into
vitaliyslion wants to merge 4 commits into
Conversation
On agent_before_settle after a completed run, send `gortex hook` a stop with the last assistant reply. Diagnostics or a block reason go back as a displayed message and continue the run for one more request, matching Claude Code's Stop hook. The stop after that continuation is flagged stop_hook_active and never continues again, since Pi has no loop guard. Tool calls are forwarded record-only when enforcement is off, so Gortex can scope the diagnostics to files this session wrote, and the stop waits for records still in flight. Tool calls now read the session id through getSessionId(). Refs #44
Gortex writes its diagnostics in Markdown, which drew with its syntax showing. They now render through Pi's Markdown component inside the custom message box, under a short Gortex label, since the briefing brings its own heading.
With enforcement off, records were fire-and-forget, so parallel edits ran concurrent hooks that each rewrite the session's state in Gortex and could drop a file from the briefing. Records now run one at a time and the stop waits for the last. The loop guard is cleared on agent_settled, so a continuation another extension cancelled no longer marks the next run's stop as a rerun. The stop budget drops to 10 s: Esc cannot cut it short, since Pi gives agent_before_settle no abort signal.
This branch has not been deployed
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.
Summary
Runs Gortex's post-task diagnostics when the Pi agent finishes, matching Claude Code's Stop hook.
On
agent_before_settleafter a completed run, the extension sendsgortex hookastopwith the last assistant reply. Gortex's diagnostics, or its claim-check block reason, go back as a displayed message and continue the run for one more model request, as a Stop hook's context does in Claude Code. Pi has no loop guard for a continuation, so the stop after the extension's own continuation is flaggedstop_hook_activeand never continues again. Aborted and failed runs skip the stop, and the stop gets a 10 s budget since Gortex runs its checks one after another. Esc cannot cut that wait short, because Pi givesagent_before_settleno abort signal, so the budget stays tight.The diagnostics are scoped to the files this session wrote, which Gortex learns from forwarded tool calls. With enforcement off, tool calls are now still forwarded, marked
record_only, and their decisions are ignored. Records run one at a time, since Gortex rewrites the session's state for each, and the stop waits for the last. Tool calls also read the session id throughgetSessionId()now.Depends on zzet/gortex#1215, which adds the
stopslot and write attribution to the bridge. Against a Gortex without it, a stop gets an empty answer and nothing happens, butrecord_onlyis ignored there, so an enforcement-off session would run every forwarded call through the full hook. Merge after a Gortex release ships #1215, withMIN_GORTEX_VERSIONbumped to it.Closes #44
Testing
npm run checkpassesExtensionRunner(seedocs/tests.md)pi -e /path/to/checkout), if user-visibletest/post-task.test.tscovers the stop envelope and its budget, the continuation with diagnostics and with a block, the silent stop after the continuation, aborted and failed runs, a continuation that was aborted or cancelled by another extension, sessions without graph tools, record-only forwarding, its ordering and the wait on it, and the rendering. The harness'ssettlecomputescanContinuethe way Pi does, which caught a guard that skipped every stop.Also verified outside the harness: a real Pi
AgentSessionwith a scripted model, the extension spawning a locally built Gortex with #1215 against a running daemon. The model edited an indexed file from a subdirectory cwd, received "Your edits this session: 2 symbol(s) across 1 file(s)" on finish, and the second stop was silent with no further model call, with enforcement on and off.Tried by hand in Pi 1.4.0 with
pi --no-extensions -e builtin:mcp -e <checkout>, a real model and the locally built Gortex. After the model editedsrc/runtime.ts, a "Gortex" box rendered the diagnostics as Markdown: the session's own edit, other dirty files listed as not attributed to the session, and the first lines with an expand hint that ctrl+o opens. The model acted on them by running the tests, and the run settled after that one continuation.Checklist
docs/architecture.mdupdated briefly, only if a design decision changedThe hook call now passes its own timeout to the spawn. The full suite passes on windows-latest CI. Under Windows Node 24 in Wine it passes too, apart from known Wine gaps that fail the same way on main: libuv's
process.titlelookup crashes files that load Pi's TUI stack, and Wine's cmd.exe rejects cross-spawn's escaped bat path. Withprocess.titlestubbed, 209 of 210 pass, and the bat-path test is the one failure.