Repository navigation
Drive crush through its server so runs are live, not a black box - #3
Merged
Merged
Conversation
crush runs previously went through `crush run`, whose quiet stdout made the monitor look frozen for minutes at a time and reported no token usage, so budget bands and spend declarations never had data and aborts were process kills. The crush adapter now implements the new SessionRunner interface: it spawns `crush server` on a private Unix socket, creates a workspace and session, holds the SSE event stream open (which is what keeps the workspace alive), and drives the prompt through the agent endpoint with a RunID. The event stream maps onto the runner's normalized events: live tool calls with their arguments, finished thinking blocks, assistant text, and cumulative token usage — so the monitor shows what the agent is doing while it does it, the budget bar moves on real numbers, spend rows are declared, and run_complete (correlated by RunID, foreign ones ignored) terminates the run with its final text or error. Aborts and budget refusals now cancel the remote session through the cancel endpoint before tearing the server down. Permission and question requests cannot be satisfied unattended; they fail closed (exit 2) naming the tool, with a note pointing at pre-allowing tools in a .crush/crushrc at the harness root. When the server cannot start, the run falls back to the old `crush run` path. The API surface was verified live against a real server (v0.96.1) and the whole flow is tested against an in-process fake speaking the same v1 API: happy path, permission fail-closed with remote cancel, run_complete errors, foreign-run filtering, and model override via the config/model endpoint (scope 1, model_type large, provider resolved from the `crush models` listing). 💘 Generated with Crush Assisted-by: Crush:rits/zai-org/glm-5-3
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
crush runs went through
crush run, whose quiet stdout made the monitor look frozen for minutes and reported no token usage — so budget bands and spend declarations never had data, and aborts were process kills. This PR drives crush throughcrush serverwith our UI as the client:SessionRunnerharness interface: the runner prefers a managed session backend over the one-shot process, sharing the same event pipeline (journal, sink, budget bands, needs-input detection), and falls back to the process path when the backend cannot start.crush serveron a private Unix socket, creates a workspace + session, holds the SSE stream open (that attachment is what keeps the workspace alive — discovered from crush's backend lifecycle), and drives the prompt with a RunID.run_complete(RunID-correlated; foreign runs ignored) terminates the turn with its final text or error.registry models spendrow — previously impossible withcrush run..crush/crushrcat the harness root.POST /config/model(scope 1, model_type large) with the provider resolved from thecrush modelslisting — model ids contain slashes, so the provider is taken from the listing line, not by splitting.Verification
crush server(v0.96.1): workspace/session creation, SSE envelope and part shapes, token-bearing session updates, RunID echo onrun_complete.run_completeerrors, foreign-run filtering, model override request shape, and runner-level integration (events to sink, usage-driven spend row, exit codes 0/1/2).💘 Generated with Crush