docs

Tools

The agent can call the following tools (each maps to a function in the API schema). All file tools are workspace-confined: paths resolve inside the current workspace and symlinks can't escape it.

Built-ins

ToolPurpose
readRead a file (path, paths, glob). Line-numbered, tab-expanded.
bashRun a shell command via sh -c (command).
writeWrite/overwrite a file (path, content, optional then_run).
editReplace text (path + edits[] of {oldText, newText} entries, optional batch-wide replaceAll, then_run). A legacy single oldText/newText pair is accepted and repaired into the batch. Matching tolerates indentation, trailing whitespace, and quote/dash variants.
grepFast frecency-ranked content search (fff engine): regex or plain text, typo-tolerant fuzzy fallback, respects .gitignore (pattern, output_mode, file_offset); truncated results end with a counted trailer naming the next file_offset.
findFuzzy frecency-ranked file-path search (fff engine, typo-tolerant) (pattern, limit).
lsList files and directories (path, default .).
ask_userAsk the user a structured question when a decision has 2–4 well-defined options; prefer plain text for anything open-ended.
delegate*Sub-agents via action: spawn a background child (explorer/reviewer/tester; resume_from continues one, model overrides — else inherits), wait (bounded, ≤120 s) fetches its result, stop cancels it, list shows this session's children. Daemon sessions only.
task*Background shell tasks: spawn detaches a command, output/wait read pages of output or wait for exit, stop cancels, list shows this session's tasks. Daemon sessions only.

* daemon sessions only (sub-agents and background tasks); the default native schema is 8 tools including ask_user. The model-facing schema registers grep and find; both are also dispatched under their fff-engine names ffgrep/fffind (dex run ffgrep … and older transcripts keep working).

Parallelism & then_run

Tool results are truncated before being sent back to the model, and a result cache (dex-tool-cache.json) is kept only when DEX_TOOL_CACHE=1. write/edit on distinct files run in parallel; same path, any bash, or any call carrying then_run serializes the batch.

write/edit take an optional then_run shell command that runs in the same call after a successful change, so a build, formatter, or test result arrives with the mutation instead of costing another round trip. It is skipped when the change fails; the observation reports [then_run:succeeded] / [then_run:failed (exit N)] followed by the command's clamped output. Because it executes shell, a call carrying then_run clears the shell permission gate (not the write gate), requires bash in a child agent's tool allowlist, and is logged to the audit trail as its own bash record. A command that times out, is cancelled, or fails to spawn reports plain [then_run:failed] with the reason as its output (no phantom exit code).

Permission modes

--permission / DEX_PERMISSION select among read-only, ask-writes, ask-shell, and trusted (default). In the interactive TUI, actions requiring approval open a dedicated overlay — arrow keys and Enter choose Allow once, Allow for this session, or Deny; y, s, and n are direct shortcuts. Session-level approvals also apply to sub-agents. Defaults: shell commands 120 s and 1 MiB per output stream; HTTP 10 s connect / 300 s overall; limits via DEX_TOOL_* and DEX_HTTP_* (see the environment reference).

One-shot tool mode

dex run <tool> <key>=<value>... executes a single tool and prints the raw result (errors go to stderr with exit code 1). Values that look like JSON numbers/booleans are coerced (limit=5, replaceAll=true); a single JSON object string is also accepted. Inside agent shell commands the binary is available as $DEX_BIN, so one bash call can stitch a whole read-only pipeline while intermediate output never enters the conversation:

"$DEX_BIN" run grep pattern=TODO output_mode=files | while IFS= read -r f; do
  "$DEX_BIN" run read "path=$f" limit=3
done

Sub-agents

delegate hands a self-contained task to a background child (three built-ins: explorer, reviewer, tester) that runs the same turn loop with its own context, tool allowlist, and JSONL transcript ($XDG_DATA_HOME/dex/sessions/<slug>/agents/*.jsonl). Completions are announced at the next turn boundary and, while the session is idle with a client attached, a wake turn surfaces them immediately (off with agent_wake: false / DEX_AGENT_WAKE=0). The same delegate tool's wait action fetches a result on demand.

  • Children may delegate further up to a nesting depth of 3.
  • A recoverable ending — interrupted, timed out, or budget-exhausted with progress on disk — is marked resumable in its result: delegate(resume_from: …) continues that child from its transcript as a new generation.
  • Over-cap spawns reject — there is no spawn queue and no idle reaper; the model waits for or cancels a child and retries. Re-entry is always manual: resume_from, no automatic recovery.
  • Under ask-* modes a mutating call parks a labeled prompt in the session's approval queue — "explorer wants to run bash: …" — unanswered for five minutes it denies.
  • The list action shows live, finished, and interrupted children.
  • Set DEX_SUBAGENTS=0 to unregister the tool.