v1.3.11

Execution Tools

Last updated


Tools that run commands in the foreground or in the background.
ToolDescription
run_commandExecute a binary with argv (argv-only schema, sandbox-wrapped via go-pkg/sandbox) in the foreground and return its combined output once it exits. A plain command with no shell metacharacter (|, &&, >, *, ~) is called directly, never wrapped; pipes, redirects and globbing need an explicit ['sh','-c','...'], whose script is parsed and validated command-by-command — every binary must be a bare command name, and anything on denied_command is rejected outright. ['cd', ...] is rejected: the work directory belongs to the user (set in the TUI with Shift+P), so a call passes absolute paths or ['sh','-c','cd <dir> && <command>'] instead — the agent cd that switched Executor.WorkDir was Removed in v1.3.0; rm is routed to the trash rather than deleting (inside the working directory it runs under auto, elsewhere in $HOME it asks, outside $HOME it needs the system password), and is rejected inside sh -c; on macOS open is rejected with a pointer to open_file, since the sandbox has no route to the app-launch service. Each call is capped at 30 min (RUN_COMMAND_TIMEOUT); a file watcher, a job likely over 5 minutes (BACKGROUND_THRESHOLD_MIN) or 跑完告訴我 / 背景跑 goes to background_command. Since v1.0.25 the sandbox keeps networking off by default: a command that has to reach a host (git clone / fetch / pull / push, npm / pip install, go mod download, curl) sets network: true, and such a call never counts as read-only, so it confirms under safe and runs without a prompt under auto. Since v1.3.2 a system package is installed through run_command itself: Linux → ['sudo','apt-get','install','-y','<pkg>'] (or dnf / yum / pacman / apk), macOS → ['brew','install','<pkg>'] with sandbox: false, never sudo with brew. Since v1.3.3 the manager comes from the system prompt's Host OS line, which also gives the OS version; command -v is the fallback only when that line names none. Commands on the read-only allowlist (configs/jsons/read_only_command.json, 532 entries since v1.3.3, 409 after cd left it in v1.3.0, merged with read_only_command from config.json) skip the confirm gate: since v1.0.25 the binary plus up to two following arguments are matched (git status, docker ps, kubectl get, ls, ...), and a match is cancelled when any argument is a sensitive path. The dedicated read-only command tool added in v1.0.23 (run_command_readonly, which ran in parallel) was removed in v1.0.25, and the short-lived run_script never shipped in a release; use run_command; since v1.3.3 calls that match the allowlist run concurrently, everything else serially. To write outside $HOME the call carries write_paths, which are bound in only after a password-backed approval. Since v1.3.2 argv ['sudo','<binary>', ...] is accepted: no sudo flags, no nested sudo / su, and the target must be a bare binary name not on denied_command; it raises a confirmation labelled sudo: <cmd> that always demands the system password (even in allow-all mode; allow rules never skip it), then runs as sudo -n <binary> ... outside the sandbox; since v1.3.11 cancelling it (here or in background_command) sends SIGTERM to sudo, which relays it to the root command, and sudo is killed only if it is still running after the 2-second WaitDelay. sudo rm deletes for real, while plain rm still moves to the trash. sudo inside sh -c is still rejected, with an error pointing to the argv form. Since v1.3.0 sandbox: false runs the command outside the sandbox with the user's full permissions, and network / write_paths are then ignored; it is meant for a command the sandbox blocked with a permission error that network or write_paths cannot fix (Homebrew needs it, since its own sandbox cannot nest), and every such call asks for the system password — allow rules and allow-all never skip that prompt, and a channel that cannot collect the password gets the call back unrun. When a sandboxed command fails with a permission error and no path outside $HOME can be granted through write_paths, the result appends advice that treats leaving the sandbox as the last resort (since v1.3.11; from v1.3.2 to v1.3.10 it said to re-run right away with sandbox: false): a connection or auth failure (Permission denied (publickey), could not resolve host) → network: true or report the credential problem; a write → a path under the work directory or write_paths; a genuine system socket, device or service, or a root-owned target → sandbox: false or argv ['sudo', ...]; otherwise report what was blocked and stop. Since v1.3.11 streamed output and the result are secret-masked, and an argv containing a masked value from an earlier tool result is refused with [Invalid]; a command that needs a key reads it inside the same call (['sh','-c','set -a; . ./.env; set +a; curl ...']). Since v1.0.11 a file watcher is rejected before it starts: --watch / --watch=..., a chokidar binary, or an npm / pnpm / yarn / bun script that resolves to one — the package script is parsed out of package.json and followed up to 4 levels (5 before v1.1.2), through sh -c too, and since v1.1.2 a script already visited is not followed again — because run_command waits for the process to exit and a watcher never does. Since v1.3.1 the error sends the watcher to the background tool (background_command since v1.3.2) with timeout_min, or to a one-shot build
background_commandrun_command_background was renamed background_command (Removed in v1.3.2). Added in v1.3.1 as run_command_background; v1.3.0 shipped the same behavior as a background mode of run_command, which now runs in the foreground only. Takes the same argv, network, write_paths and sandbox parameters (plus objective and next since v1.3.8) under the same sandbox, confirmation, read-only allowlist and allow-rule checks, and returns a task id at once so the turn continues. Meant for a file watcher (which runs only here), a job very likely over 5 minutes whose output does not decide the next tool call, or 跑完告訴我 / 背景跑. timeout_min (1-60, default 60) kills the command and reports a timeout; the final report keeps the last 31 KiB of output. The output is always watched: a new output line containing one of keywords (case-insensitive; default error, err!, fail, fatal, panic, exception, traceback, segmentation fault, core dumped, out of memory, permission denied, command not found, no such file) reports the latest output (up to 8 KiB) while the command keeps running, once the output settles (2 s of quiet, at most 10 s), and at most one report per 30 s. With a decision model set, a decision check first drops benign hits (such as 0 errors) and repeats of the last report; a failed check sends the output unchecked with the failure noted. Without a decision model every hit is reported. The interval and prompt parameters were Removed in v1.3.2; use keywords instead. While the command runs, its output is appended to ~/.config/agenvoy/sessions/<session>/background/<task id>.log, which is removed when the command ends; the start result gives that path and tells the agent to read its tail with read_files when asked how far it got. Excluded unless the request comes from the TUI (cli- origin with no deliver target) — since v1.3.2 no longer tied to having a decision model. Each session runs at most MAX_BACKGROUND_TASKS background tasks (DEFAULT_CONCURRENCY: half the CPU cores, at least 3), a pool shared with background_subagents. Since v1.3.8 legs started in the same turn form one group: its reports go to the starting task while that task is running or pending, and once it has ended the group runs objective + next + every report as a new task when all its legs finish (before, each finished task resumed the original task on its own). Pausing or cancelling the starting task stops its legs; a single leg is cancelled from the TUI Esc menu

pkg_manage was Removed in v1.3.2; use run_command with argv ['sudo', ...] (Linux package managers) or sandbox: false (Homebrew) instead.
中文