SYSTEMS NOMINAL

AI pipelines as DOT graphs

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.

System Architecture
05 smasher-web HTMX dashboard, live SSE, human-in-the-loop
04 smasher-cli complete, chat, run, serve commands
03 smasher-attractor DOT graph engine, handlers, transforms
02 smasher-agent Tool loop, steering, subagents, events
01 smasher-llm OpenAI + Anthropic + Gemini unified client

What it does

Pipelines

DOT graph orchestration

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.

Multi-LLM

Talk to any LLM

OpenAI, Anthropic, Gemini. Same client, same types. Swap models per-node with a --var model=... flag. Streaming works everywhere.

Agents

Agents that write code

Codergen nodes spin up an agent session with read, write, edit, shell, grep, and glob tools. The agent works inside its own sandboxed directory.

Control

Humans in the loop

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.

Dashboard

Web dashboard

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.

Isolation

Isolated runs

Every run gets its own directory: manifest, node logs, checkpoints, events. Run ten pipelines at once and they won't step on each other.

The stack

01 smasher-llm LLM client. Provider catalog picks the right API from the model name. Errors know if they're retryable.
02 smasher-agent Agent loop. Register tools, set steering rules, delegate to subagents. Everything runs in a sandboxed environment.
03 smasher-attractor The graph engine. Parses DOT with winnow, resolves nodes, dispatches handlers. Stylesheets and transforms let you reshape graphs before execution.
04 smasher-cli Four subcommands: complete (one-shot), chat (REPL), run (pipeline), serve (dashboard). Tracing goes to stderr, exit codes are structured.
05 smasher-web axum + askama + HTMX. Events arrive over SSE, graphs re-render as SVG, and the interviewer handles human Q&A.

Pipelines Are Just Graphs

human-gate.dot
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;
}
Terminal
$ 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

Up and running

01

Install

Clone and build from source. Requires Rust 1.92+.

git clone https://github.com/2389-ai/smasher.git
cd smasher && cargo build --release
02

Set API Keys

Export at least one provider key. Smasher figures out which providers you have from the environment.

export ANTHROPIC_API_KEY=sk-ant-...
# or OPENAI_API_KEY, GEMINI_API_KEY
03

Run a Pipeline

Execute any DOT graph. Pass variables with --var flags.

smasher run examples/hello-world.dot
smasher run examples/multi-step.dot --var model=claude-sonnet-4-20250514
5
Crates
2,388+
Tests Passing
3
LLM Providers
7
Node Types

Go build something

It's open source. Clone it, break it, ship it.