66 lines
2.6 KiB
Markdown
66 lines
2.6 KiB
Markdown
# 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/<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](DECISIONS.md) for every design decision and
|
|
[SPIKE.md](SPIKE.md) for the spike results.
|