Files
sausage/README.md
T
Sausage Agent 3435b556fb Broker exit request and nix run .#loop for self-updating hosts
- broker: `{"type":"exit"}` answers `exiting`; `sausage run` then stops all
  actors and exits with code 75.
- flake: apps `loop` / `loop-internal` run `nix run --refresh git+ssh://.../surma/sausage -- run <world>`
  in a loop; exit code 0 (/quit) ends the loop, anything else restarts.
- PROTOCOL.md, README.md, test in cli/tests/host.rs.

Not compiled: written by the Sausage agent, which cannot build the native host.
2026-10-16 00:37:25 +00:00

2.6 KiB

Sausage

You can see how the sausage is made.

Sausage is a world of small programs ("actors") that you grow by talking to it. Each actor is a WASI program with stdin and stdout. Actors send each other JSON messages, one per line, through a broker. The agent is an actor too: it writes new actors in Rust, builds them, tests them, starts them, and can change its own code.

Start

You need Nix with flakes.

nix run -- init     # creates ./world and builds the agent (a few minutes)
nix run -- run      # starts the world and a console

init asks for the API shape (openai-responses or anthropic-messages), the base URL, the model, and the token. It reads SAUSAGE_API, SAUSAGE_BASE_URL, SAUSAGE_MODEL, and SAUSAGE_API_TOKEN first. The values go to world/actor/agent/data/config.json. Both commands take another folder as an argument, for example nix run -- run my-world.

To keep a world on the newest version, run it in a loop:

nix run .#loop -- my-world            # or .#loop-internal (Gitea on the LAN)

The loop runs nix run --refresh git+ssh://…/surma/sausage -- run my-world. When the host crashes or an actor sends @broker {"type":"exit"}, the loop fetches the newest commit and starts it again. /quit ends the loop.

In the console:

write an actor "notes" that stores notes, and start it   → text to the agent
@notes {"type":"add","text":"milk"}                      → a JSON message to an actor
@agent hello                                             → text to an actor
/quit

The world folder

The folder is the source of truth. Every actor lives in world/actor/<id>/:

actor.wasm     the current version
actor.json     installed version, running, subscriptions
source/        the source of the current version
public/        files that the actor publishes
data/          the actor's state
stderr.log     what the actor and the broker write about it
versions/<n>/  every installed version: actor.wasm, source/, meta.json

To add or replace an actor by hand, put an actor.wasm (and its source/, with the tests in source/tests/) into its folder. Then restart the world or send @broker {"type":"scan"}. The broker tests the file before it uses it. If the tests fail, the old version keeps running, and stderr.log says why.

More

  • PROTOCOL.md: messages, the filesystem, the broker, cargo. Read this to write an actor in any language.
  • sdk/: sausage-actor, the SDK for Rust actors.
  • examples/notes: a small actor with a test.
  • AGENTS.md: how to work on Sausage itself.