wasm-agent
A ReAct (Thought, Action, Observation, Final Answer) agent loop in plain synchronous Rust, with no async runtime and no I/O, so it builds for wasm32-unknown-unknown and runs in browsers, edge workers and plugins.
Most agent frameworks assume Tokio, threads and an HTTP client. This crate keeps only the part that is pure logic: parse what the model said, dispatch the tool it asked for, record the observation, and keep the conversation within a token budget. You make the LLM call however your platform allows (fetch in a Worker, a host function in a plugin) and hand the response text to the runner.
Features
parse_react_step: parsesThought: ...,Action: tool(input),Action: tool: inputandFinal Answer: ...into aReActStep.ToolRegistry: register synchronous tools (Box<dyn Fn(&str) -> ToolResult>, noSendneeded) with aToolSpec(name, description, JSON schema), dispatch by name, and generate a tools section for the system prompt withtools_prompt().LoopRunner:step(llm_response)parses one response, runs the tool on anAction, and appends both the response and the tool output to history.run_scriptedreplays a list of responses for deterministic tests.ConversationHistory: token-limited history that evicts the oldest non-system messages when full.AgentConfig: max iterations, context token limit, timeout and model name.- Dependencies are only
serde,serde_jsonandthiserror.
Quick start
use ;
use ToolResult;
Build for WebAssembly:
How it works
| File | What it holds |
|---|---|
src/loop_runner.rs |
parse_react_step, LoopRunner |
src/tools.rs |
ToolRegistry, ToolSpec, ToolFn |
src/history.rs |
ConversationHistory with token-limit eviction |
src/types.rs |
ReActStep, Message, Role, AgentConfig, ToolResult |
src/error.rs |
AgentError |
The runner never calls a model itself. That keeps it deterministic and testable, and lets the same code run natively or in WASM.
Status and limitations
Version 0.1.
- No LLM client and no JS bindings are included; you supply the model call (for example via
wasm-bindgenandfetch). - Token counts are estimates, not a real tokenizer.
AgentConfig::timeout_msis stored but not enforced by the runner.- The parser expects one step per response and matches the prefixes at the start of the text.
License
MIT, see LICENSE.
Part of a set of Rust crates for LLM agents, see rust-crates.