Write a directed graph. Smasher runs it: agents, tools, conditionals, human approval gates. Rust all the way down, five crates deep.
Built on the ideas from attractor by strongDM. Reimplemented from scratch in Rust.
Your pipeline is a digraph. Nodes have shapes that tell the engine what they are: circles start, boxes run code, diamonds branch, houses ask humans. Edges are dependencies.
OpenAI, Anthropic, Gemini. Same client, same types. Swap models per-node with a --var model=... flag. Streaming works everywhere.
Codergen nodes spin up an agent session with read, write, edit, shell, grep, and glob tools. The agent works inside its own sandboxed directory.
Manager nodes stop the pipeline and ask a question. Answer in the terminal or the web dashboard. Your response picks which edge to follow next.
Submit pipelines, watch events stream in over SSE, see the graph update as nodes complete. Token counters and a Q&A panel for answering human gates.
Every run gets its own directory: manifest, node logs, checkpoints, events. Run ten pipelines at once and they won't step on each other.
digraph HumanGate { // Entry point start [shape=circle]; // Processing step process [shape=box, label="Process Changes"]; // Human approval gate human_gate [shape=house, question="Approve?"]; approved [shape=box, label="Apply Changes"]; done [shape=doublecircle]; rejected [shape=doublecircle]; start -> process; process -> human_gate; human_gate -> approved [label="success"]; human_gate -> rejected [label="failure"]; approved -> done; }
$ smasher run human-gate.dot Run directory: artifacts/a1b2c3d4/ Pipeline: HumanGate Nodes: 6 [engine] start [engine] process → Process Changes [tool] read_file... ok (12ms) [tool] edit_file... ok (8ms) [tool] shell... ok (340ms) [engine] human_gate ? Do you approve this change? > yes [engine] approved → Apply Changes [engine] done Pipeline completed. Steps: 6 | Nodes visited: 5
Clone and build from source. Requires Rust 1.92+.
Export at least one provider key. Smasher figures out which providers you have from the environment.
Execute any DOT graph. Pass variables with --var flags.