fix(tools): send init_command through the same framing as user commands 🤖🤖🤖 - #201
Open
shoemoney wants to merge 1 commit into
Open
fix(tools): send init_command through the same framing as user commands 🤖🤖🤖#201shoemoney wants to merge 1 commit into
shoemoney wants to merge 1 commit into
Conversation
…ds 🤖🤖🤖 start() composes init_script as raw shell text with the control protocol lines appended, while run() and stream() both go through _build_script (base64 payload plus </dev/null), the framing PR NVIDIA-NeMo#149 introduced to keep bash's parser away from the protocol. An init_command with an unbalanced quote swallows the protocol lines as string content, and one that reads stdin (cat) consumes them as input; either way start() blocks for its full 60s timeout and the session is unusable. Route init_command through the same _build_script framing, and log a warning when the init command exits nonzero so a failed env setup is visible instead of silent. Sibling precedent: PR NVIDIA-NeMo#149 (merged 2026-08-18), which fixed the same bug class for user commands. Written in conjunction with my pair programmer Claude. Signed-off-by: Jeremy Schoemaker <jeremy@shoemoney.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 does this PR do?
Routes the one-time
init_commandinBashSession.start()through_build_script, the same framingrun()andstream()already use, and logs a warning when the init command exits nonzero.On main,
start()composesinit_scriptas raw shell text with the control protocol lines appended (src/nooa/tools/_bash_session.py:213), while user commands go through_build_script(:289, :345), which base64-encodes the payload and redirects stdin from /dev/null. PR #149 introduced that framing to keep bash's parser away from the protocol, but the init path never got it. Two consequences:init_commandwith an unbalanced quote (echo "unclosed) makes bash read the protocol lines as string content, so the sentinel never arrives andstart()blocks for its full 60s timeout.init_commandthat reads stdin (cat) consumes the protocol lines as its own input, same 60s wedge.With the framing applied, both cases return promptly and the session stays usable. A nonzero init exit now also logs
init_command ... exited Ninstead of passing silently.Deliberately not changed: a failed init still does not abort
start(), it only warns, matching howrun()reports command failures in-band rather than raising. Whether a bad init should fail session creation is a design call for maintainers.Related issues
None on file. Sibling precedent: PR #149 (merged 2026-08-18), which fixed this same bug class for user commands.
How tested
Four regression tests in
tests/tools/test_bash_session_framing.py::TestInitCommandUsesTheSameFraming. With the source change reverted and the tests kept in place, the two wedge tests fail on timeout and the warning test fails on the missing log record (3 failed, 19 passed); the benign-init test passes both ways, since the old code handled well-formed inits. With the fix,22 passedin the framing file and302 passedacrosstests/tools/.Checklist
uv run ruff check .anduv run ruff format --check .pass)uv run pytest)Written in conjunction with my pair programmer Claude. 🤖🤖🤖