Skip to main content
Browse the documentation

Extending the agent

The agent writes its own tools

When a capability is missing, the agent can author a tool at runtime — generate Rust, compile it to WASM, and register it without a restart.

If the agent needs something no tool provides, it can write the tool, register it, and use it in the same session. No restart, no redeployment.

> write a tool that converts our CSV exports into the summary format

The agent generates a Rust scaffold, compiles it to wasm32-wasip2, validates the resulting component, and registers it into the running tool registry.

What it needs on your machine

A Rust toolchain and the wasm32-wasip2 target. If they are missing, the first create_tool call installs them — roughly 200 MB for rustup and 50 MB for the target, once.

That is a real cost on a machine you did not intend to put a compiler on, and a tool takes tens of seconds to build the first time. If that is the wrong trade for you, there is now a second path.

JavaScript — nothing needs to be installed

> write a tool that converts our CSV exports into the summary format

create_js_tool needs no toolchain at all. The interpreter is compiled to WASM when Snaga itself is built and travels inside the binary, so creating a tool is three file writes and a smoke run rather than a compile.

That cheapness buys back a check the compiled path never had: the tool is executed before it is registered, because doing so costs about a millisecond.

One interpreter is shared by every script tool — each differs only in the script it runs and the policy it runs under — so the runtime compiles the interpreter once for all of them, and an ahead-of-time cache keeps even that across restarts.

JavaScriptRust
Toolchain needednonerustup + wasm32-wasip2
First toolabout a secondtens of seconds
Run before registeringyesno
Capabilitiesdeclaredinferred from source at compile time

Prefer JavaScript unless you need something Rust gives you. The one real difference in the security model is that last row: the Rust path can scan generated source to infer what a tool needs, and a substring scan cannot be sound over a dynamic language — so a script tool's capabilities are declared and enforced by the runtime gate. That gate is what the sandbox treats as authoritative in both cases anyway.

The sandbox is otherwise identical: a script tool is an ordinary WASM component under the same memory and CPU budgets, the same wall-clock timeout, and the same per-tool capability bits.

Building many tools

Dependencies are built once into a shared tree rather than per tool. Two tools created in a row, measured end to end through the agent:

before   35.41s   33.24s
after    30.33s    1.19s

The cost is a shared build tree of about 164 MB, and one consequence worth knowing: two tools building at the same time now serialise, because the build tool locks the directory.

What compiling does and does not verify

The build succeeding means the code type-checks. It does not mean the tool works — nothing runs it before it is registered. Ask the agent to exercise a new tool before you rely on it.

Where tools live

.snaga/tools/
├── my_tool.wasm          # the compiled component
├── my_tool.rs            # the Rust source, kept
└── my_tool.policy.toml   # capabilities and limits

The policy file is readable and is the authority on what a tool may do. If you want to know what something the agent wrote is allowed to touch, that file answers it — see Capabilities and the sandbox.

Manage them with list_wasm_tools, find_tool, activate_tool, deactivate_tool and remove_tool. Deactivating hides a tool from the agent while leaving it on disk; removing deletes the files and unregisters it.

The sandbox applies to tools the agent wrote

A generated tool is an ordinary WASM component under the same runtime as anything you install: the same memory and CPU budgets, the same wall-clock timeout, the same per-tool capability bits. The agent writing the code does not grant the code any additional trust.

Capabilities for a generated tool are inferred at compile time by scanning the generated source, and enforced at runtime by the capability gate — the gate is what actually holds.

When not to write one

If somebody has already written it, install theirs — see Installing tools from the registry. Writing a tool is for the case where the capability does not exist yet, and publishing it afterwards is how it stops being that case for the next person.