Repository navigation
Support background processes and live-streamed bash output #41
Description
Problem
The bash tool is fully synchronous: it runs bash -c <command>, buffers
stdout/stderr, and returns the combined output only when the process exits,
killing the process group on timeout (internal/tools/bash.go). Each call is a
fresh process, so cd and exported variables don't carry over (already noted in
the README).
This makes the most common real-world workflows impossible for the agent:
- Start a dev server or test daemon in one step, then hit it in a later step.
- Run a long build, watch mode, or migration and react to its output.
- Interact with a REPL or a CLI that keeps running.
Proposed improvement
Add a small in-process process registry to the tool executor and three new tools
alongside the existing six:
start_process— launchbash -c <command>in the background; return a
process id and the first chunk of output.read_process— return output produced since the last read, with optional
timeout(block up to N ms for new output) andtail.stop_process— kill the process group and report the exit status and
trailing output.
Also add an optional stream flag to the foreground bash tool so long output
is emitted as it is produced instead of only at the end.
Processes run as children of tinyagent (reusing the existing setProcessGroup
kill path). On run end, Ctrl-C, or a step/time/cost limit, any surviving
background processes are killed and their tails summarized into the trajectory,
so nothing is left running.
For example, the agent can start_process a server, read_process its startup
log until it reports "listening", run tests against it, then stop_process.
Acceptance criteria
- Three new tools (
start_process,read_process,stop_process) are exposed
in the tool schema with clear descriptions. - A background process keeps running across steps; output is buffered per
process andread_processreturns only new output (no duplication). stop_processkills the whole process group (children included) and reports
the exit status.- The foreground
bashtool is unchanged by default; with streaming enabled,
output appears as it is produced. - Surviving processes are always cleaned up on run end, interrupt, and limits;
no orphaned children remain. - The number of concurrent background processes is bounded (configurable) and
per-process output buffers are capped to avoid unbounded memory. go test ./...passes; tests cover the start/read/stop lifecycle, streaming,
cleanup on interrupt, and the buffer cap.
Implementation pointers
The change fits in internal/tools/ (a new process.go plus wiring in
tools.go and bash.go), reusing the existing setProcessGroup kill path. The
process registry lives on tools.Executor, scoped per run. A config key (e.g.
max_background_processes) extends internal/config/config.go. Update the
README "Notes" section and the tool-schema descriptions.
Activity
Add background process tools and optional bash output streaming (#41) (…