Repository navigation
fix: run the hook bridge asynchronously and deliver guidance per call - #55
Merged
Merged
Conversation
The hook ran through execFileSync with inherited stderr, so a slow hook froze Pi's TUI and Esc for its whole run, and anything it wrote to stderr was painted into the editor. The process seam now runs it asynchronously with stderr piped and dropped, and an Esc abort kills it. On Windows, a .cmd shim's timeout or abort kills the whole tree under cmd.exe, so gortex is not left running. A reply that is not a JSON object, such as null, now fails open instead of blocking the call. Pi's powershell tool maps to Bash. Soft guidance is appended to the result of the call it concerns (the top-level call for one a script made) instead of a displayed steer that cost a model request per advised call. Closes #24
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
The hook bridge ran
gortex hook --agent=pithroughexecFileSyncwith inherited stderr. Every tool call paid for that in the TUI, and the same path had a few contract gaps.src/runtime.ts): the process seam is now an asyncexecFile, with stdin piped and closed and stderr collected and dropped.ctx.signal..cmd/.batshim, a timeout or an abort kills the whole tree undercmd.exe(taskkill /T /F). Node alone kills onlycmd.exeand leaves gortex running. The oldexecFileSynctimeout leaked the same way.src/hook.ts):callHookreturns an empty decision for any reply that is not a JSON object. Before,nullthrew inside thetool_callhandler and blocked the call.powershelltool maps toBash, as Gortex's own Copilot adapter does. Cmdlet forms such asGet-Contentstill pass, because Gortex's shell classifier knows only POSIX commands. That half belongs upstream.src/index.ts):additional_contextis held per call and appended to that call'stool_result. Before, it was a displayed steer that arrived after the batch and cost one model request per advised call. A call a codemode script makes has its guidance carried to the top-level call's result, so the script's result is not altered.docs/architecture.md(Channel 2, Failure posture).Item 3 of the issue no longer applies since #36.
User-visible change: guidance now sits inside the tool result, so it shows only when the row is expanded (ctrl+o). Before, it was always shown as a
[gortex]chat block.Reproduction
Real Pi 1.3.0 loading this checkout with
pi -e, a fake OpenAI-compatible model, and a wrapper around the real gortex v0.64.8 onPATH.bashcalls, Esc at about 4 sGORTEX_HOOK_MODE=enrich, 2 parallel readscatof indexed source viabashandpowershellpowershellreached the hook raw and was allowedBashand are blockednullCloses #24
Testing
npm run checkpasses (180 tests)ExtensionRunner(seedocs/tests.md):test/hook.test.tscovers Pi's event loop running while a gated hook is pending, an abort throughctx.signal, anullreply, and soft guidance. The guidance cases are: in its own call's result, never sent as a message, parallel calls, a call ending without a result, keptstructuredContent, a result with no content, and calls made by a script.nodechildren: stdin, non-zero exit, missing binary, timeout, stderr kept off the host's, and abort killing the child.ctx.signal.pi -e /path/to/checkout), Pi 1.3.0 on Linux against a live gortex daemon:readof indexed source is still blockededitstill renders its diffpgrep -af "gortex hook"is empty after an Esc abortChecklist
No runtime dependencies added
README configuration table updated, if config changed (no config change)
docs/architecture.mdupdated briefly, only if a design decision changed: the hook runs off Pi's event loop and is killed on abort, and guidance travels with its call's resultWorks on Windows paths and process spawning, if touching either. Verified with Windows Node 24 under Wine, using npm's
gortex.cmdshim in a path with spaces and parentheses:readblocked" % ^ & | < > !, unicode and a newline arrives intactcmd.exeis gone; before the tree kill it survived bothtest/hook.test.tspasses 38/38On
windows-latestall 184 tests pass with none skipped, including the bat-by-path-with-spaces test (which fails only under Wine'scmd.exe),diff.test.ts(which crashes at load under Wine) and both tree-kill tests.