# Sausage You can see how the sausage is made. Sausage is a system of actors that you grow by talking to it. Every actor is a WASI program (a `.wasm` file) with stdin and stdout. Actors send each other newline-delimited JSON messages through a broker. The agent is an actor too: it does inference over HTTP, writes new actors, and can change its own code. Inspired by [Jiti](https://ghuntley.com/lisp/), but with WASM instead of a Lisp image. ## Quick start ```sh nix develop cargo build --release export SAUSAGE_API_TOKEN=... # or type it at the prompt ./target/release/sausage init world --api openai-responses \ --base-url https://api.example.com --model some-model ./target/release/sausage run world ``` `init` builds the agent (the first build takes a few minutes) and writes its configuration to `world/private/agent/data/config.json`. The source contains no endpoint and no token. In the console: ```text hello → text to the agent @notes {"type":"add","text":"milk"} → a JSON message to an actor @agent what actors exist? → text to an actor /deploy notes examples/notes → build with cargo, then spawn or upgrade /list → list actors /await agent 300 → wait for the next message (scripts) /quit ``` ## Concepts - **Actor**: a `wasi:cli/command` program. It reads messages on stdin and writes messages on stdout. Logs go to stderr. - **Message**: `{"id", "from", "reply_to"?, "body"}` on stdin; `{"to"?, "id"?, "reply_to"?, "body"}` on stdout. No `to` = publish to subscribers. There is no request/response: a reply is a new message with `reply_to`. Delivery is at most once. - **Broker**: routes messages, owns mailboxes, and runs actors. It accepts only `.wasm` files: `spawn`, `upgrade`, `rollback`, `stop`, `start`, `remove`, `subscribe`, `unsubscribe`, `list`. - **cargo**: the built-in Rust compiler actor. `build` a source folder, get a `.wasm` path back. Other actors can add other languages. - **Filesystem** of each actor: - `/data`: private state - `/public`: its public files - `/actor//{public,source,status.json,stderr.log}`: every actor, read-only A write becomes visible when the writer closes the file (commit on close). - **Upgrade**: the broker tests the candidate on a copy of `/data` and `/public` (transcripts in `source/tests/*.jsonl`). Then it holds new messages, stops the old version, starts the new one, and delivers the held messages. A new version that crashes 3 times in 30 seconds is rolled back. See [DECISIONS.md](DECISIONS.md) for every design decision and [SPIKE.md](SPIKE.md) for the spike results.