Files
sausage/README.md
agent-pool-9 0995824c01
ci / check (push) Failing after 7m36s
Watch the world folder: auto spawn/upgrade, broker watch/unwatch, retire scan
The host watches the whole world folder recursively with the notify crate
(any writer counts, .sausage-tmp-* skipped, ~100 ms coalescing per path).
A new or changed actor/<id>/actor.wasm (or new folder actor/<id>) is
booted as at start once quiet: new = spawn (tested first), changed =
upgrade. The broker `scan` request is gone; the boot pass stays, plus a
full pass when the OS watcher overflows.

New broker requests watch/unwatch {path} (saved in actor.json `watches`)
deliver fs_changed {path, op: write|create|remove|rename, to?} from `fs`,
not routed, dropped when the mailbox is full; overflow sends every watcher
one fs_changed {path:"/actor", op:"rescan"}.

Card #91 (multi-host step 1).
2026-10-17 07:12:04 +00:00

87 lines
3.4 KiB
Markdown

# 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](https://nixos.org/download) with flakes, and an API token for
an LLM (OpenAI Responses or Anthropic Messages API). No clone needed:
```sh
nix run git+https://gitea.surma.technology/surma/sausage
```
This creates a world in `./world` the first time (it builds the agent, which
takes a few minutes), then starts it with a console. Later runs start the
existing world. The two steps on their own:
```sh
nix run git+https://gitea.surma.technology/surma/sausage -- init # creates ./world and builds the agent
nix run git+https://gitea.surma.technology/surma/sausage -- 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 `... -- run my-world`.
To keep a world on the newest version, run it in a loop:
```sh
nix run git+https://gitea.surma.technology/surma/sausage#loop # ./world, created if needed
nix run git+https://gitea.surma.technology/surma/sausage#loop -- my-world # an existing world
```
The loop runs `nix run --refresh git+https://gitea.surma.technology/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. Set
`SAUSAGE_FLAKE` to run another flake URL instead, for example your fork.
From a clone (`git clone https://gitea.surma.technology/surma/sausage`), the
same commands are `nix run`, `nix run -- init`, `nix run -- run` and
`nix run .#loop`.
In the console:
```text
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>/`:
```text
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; the host watches the
world folder and picks the file up once it stops changing. 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](PROTOCOL.md): messages, the filesystem, the broker, `cargo`.
Read this to write an actor in any language.
- [`sdk/`](sdk/): `sausage-actor`, the SDK for Rust actors.
- [`examples/notes`](examples/notes): a small actor with a test.
- [AGENTS.md](AGENTS.md): how to work on Sausage itself.