Files

2.6 KiB

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, but with WASM instead of a Lisp image.

Quick start

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:

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/<id>/{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 for every design decision and SPIKE.md for the spike results.