Skip to main content
crates/tools is the runtime layer that turns model tool calls into real actions. The agent loop asks it to build a tool runtime for a turn, then routes each provider tool call through that runtime. Tool execution is protected by the turn permission and sandboxing system. Each turn carries an effective permission profile and a TurnExecutionSecuritySnapshot. The tools runtime evaluates side-effecting actions before execution, checks the relevant filesystem, network, and process policy, and then either executes, rejects, or opens a client approval request. The tools layer is where model output becomes a side effect. Reading a file, running a command, calling an MCP server, applying a patch, and using computer control all execute on the gateway host.
A remote gateway means the tool runs on the remote host; a local gateway means it runs on the local host. Within that host, Pioneer applies turn permission profiles, resource policies, scoped approval grants, and the selected native or provider sandbox backend.

Why this layer exists

Tools need a common runtime because Pioneer has several capability sources: built-ins, MCP servers, skills, and task orchestration. The model should not need to know which subsystem owns a tool. It should see a clean tool name, JSON schema, and result. At the same time, Pioneer needs consistent behavior after execution: timeline events, model-visible output, storage output, recovery evidence, retries, and diagnostics. If every subsystem returned raw text directly to the model, context windows would explode and recovery would be unreliable.

Runtime pieces

Permission evaluation

Every tool invocation receives a PermissionEvaluationContext containing the workspace, thread, turn, and TurnPermissionProfileSnapshot, plus the turn’s TurnExecutionSecuritySnapshot. Before execution, the orchestrator extracts a PermissionIntent, classifies the action kind, and evaluates it against the profile’s ToolPermissionPolicySnapshot. Supported action kinds are: Policy evaluation returns one of three behaviors: Approval requests include a normalized request key and scope hash. If the user chooses allow_for_turn, the tools runtime caches that request key for the rest of the turn so matching actions can proceed without repeated prompts. allow_once applies only to the current request. The tools layer emits permission audit events for profile decisions, approval requests, approval resolutions, cached approvals, and denied actions. The gateway persists those events through the same durable turn-event path as ordinary tool lifecycle events.

Sandbox and resource policy

Permission approval is not the only gate. The orchestrator and handlers also enforce the execution security snapshot: Scoped approvals can extend a restricted snapshot for the current invocation or the rest of the turn. For example, approving a specific download can add both the network grant and destination write grant needed for that operation without switching the whole turn to full access.

Built-in tools

The core built-ins are intentionally small and always eligible for agent turns when tool calling is available:
  • exec_command
  • write_stdin
  • read_file
  • list_dir
  • grep_files
  • apply_patch
  • web_search
  • web_fetch
  • download_url
  • read_skill
  • request_tools
Large domain tools are registered in the same router but hidden until turn preflight or an explicit request_tools call makes them visible. Artifact tools are lazy-domain tools. artifact_prepare gives the model a safe turn-scoped staging path for a user-visible output file. artifact_register imports a completed regular file into the workspace artifact store and binds it to the current turn. Tool authors should not invent filesystem scanning or tool-specific discovery paths; all agent-created user results use this explicit registration contract. Shell execution uses unified sessions. exec_command can start a process and return either final output or a session id. write_stdin can continue an existing session. Active sessions are bounded and buffered so long-running commands do not grow memory without limit. Filesystem tools are intentionally direct: read files, list directories, search with grep-style behavior, and apply patches. Manual patch edits in Pioneer are routed through the patch tool path rather than ad hoc file rewriting. These handlers call the file policy checker before opening paths when a turn security snapshot is present. Web tools are optional at runtime and controlled by gateway configuration. They can search, fetch, and download with limits. They call the network policy checker before network access; downloads also call the file policy checker before creating the destination file. Computer use uses native automation/screenshot dependencies where available. It is part of the same tool router, not a special client-side channel, but the computer_use schema is hidden until preflight or request_tools reveals the computer_use domain.

Lazy visibility

The router stores all specs for a turn, but the model only receives the currently visible subset. Turn preflight is the first visibility selector. It receives a compact PreflightToolIndex: coreTools plus concrete hidden-domain candidateTools with name, domain, short summary, and mutation flag. It does not receive full JSON schemas. The preflight output tools.visibleTools must be exact tool names from candidateTools, never domain names. request_tools is the in-turn expansion path. Its schema accepts:
domains is an enum: memory, task, artifact, or computer_use. The handler expands each requested domain to every registered and available tool in that domain, reports already-visible and unavailable tools, and returns a compact result without embedding hidden schemas. The agent loop applies the result before the next provider round and keeps visibility monotonic for the rest of the turn.

Dynamic tools

Dynamic tools are exposed through ToolExtensionBundle. MCP tools are created from live MCP server catalogs. Pioneer maps a server tool into a callable tool descriptor, then calls back into McpService when the model invokes it. Skill tools are declared by installed skills and validated by the skills runtime. They can represent shell, HTTP, or function-proxy style tools depending on the skill declaration and policy. Task tools are injected when task orchestration is available. They let an agent create attached tasks, wait for them, cancel them, detach them, and observe terminal child task results. Dynamic tools do not bypass the router. They use the same runtime and output projection path, and emit the same tool events as built-in tools. The agent loop can therefore handle shell commands, MCP calls, and skill functions through one execution contract. Dynamic extension tools that are not in the built-in domain map are independent of preflight domain selection and request_tools. If an MCP server or skill contributes a turn-specific tool, including through an explicit composer capability, the final visibility pass keeps it available as a dynamic extension when it is registered and has a handler. Visibility is not authorization. A tool may be visible to the model and still require approval when called. The permission evaluator is the last policy gate before execution.

Output projection

A tool call produces more than one view of output. The model-visible view may be shorter or structured differently from the timeline view. Storage may keep full output, a summary, metadata only, or nothing depending on policy. Recovery evidence can include exit status, error class, retry hints, excerpts, and fingerprints. This matters because a large shell output or MCP response should not automatically flood the LLM context window. Tool authors should define output policies deliberately.

Retry and recovery

Tool failures are normalized into ToolOutcome with status and error class. Recoverable errors can trigger another provider round with a retry instruction. Fatal errors are surfaced to the model or fail the turn depending on context. The agent does not blindly retry forever. Retry decisions are constrained by per-episode and per-tool budgets, and the tool loop itself has a separate round/call budget.

What not to put here

Provider-specific tool-call parsing belongs in Provider System. The tools crate should receive normalized tool calls. Prompt prose about when to use tools belongs in Prompt And Context. The tools crate should define capabilities and execution behavior, not assistant personality. MCP server lifecycle belongs in MCP Architecture. Skills installation and trust policy belong in Skills Architecture. The tools layer only receives their already-materialized tool descriptors and handlers.