75 lines
3.6 KiB
Markdown
75 lines
3.6 KiB
Markdown
# beaver-gateway
|
|
|
|
A gateway for personal agents built on the Claude Agent SDK: conversations
|
|
with a lifecycle, windows to talk through, jobs, memory hooks, and a policy
|
|
boundary - without an opinion about what the agent is for. A setup is one
|
|
`config.py` (or a package next to it) that assembles a `Gateway`; this repo
|
|
holds the primitives, [beaver-agent](https://git.kotikot.com/beaver/beaver-agent)
|
|
is a full setup built on them.
|
|
|
|

|
|
|
|
## What it gives a setup
|
|
|
|
- **agents/** - what an agent is: a Claude agent with a prompt per
|
|
conversation kind, skill sets per kind, gateway tools, a `PreToolUse`
|
|
policy; a Raycast agent for cheap fast answers.
|
|
- **backends/** - how a turn runs: the Claude Agent SDK subprocess with a
|
|
session pool, transcripts and session stores; the Raycast wire.
|
|
- **conversations/** - the model of a conversation: kinds (master, branch,
|
|
deep, job, fork), rows and windows, the inject queue with priorities,
|
|
seeds, turns, questions, closing through a distiller, master rotation,
|
|
the envelope, the in-process gateway tools.
|
|
- **jobs/** - cron, webhook and event jobs on pgqueuer, deferred injects,
|
|
the subscription budget.
|
|
- **frontends/** - the windows: Telegram (master = General, topic = branch,
|
|
files out of the agent through `send_file`),
|
|
markdown files in a vault, `/api` + the admin SPA, an Anthropic-compatible
|
|
`/anthropic/v1/messages`, MCP re-exposure at `/mcp/<name>`, and
|
|
`WebhookFrontend` for a window a setup declares itself - its own request
|
|
and response schema, its own agent, its own token scope
|
|
(`docs/FRONTEND-PLUGINS.md`).
|
|
- **mcp/** - MCP servers a setup declares (stdio, http, python tools),
|
|
aggregated in-process and handed to agents by name.
|
|
- **vault/** - watching a directory of notes for the envelope.
|
|
- **security/** - bearer tokens, the audit log, credential redaction.
|
|
- **events/** - the in-process bus every frontend taps, and the stream
|
|
event protocol backends emit.
|
|
- **storage/** - SQLModel tables and the Postgres session store.
|
|
|
|
`config.py` defines `Gateway` and loads a setup; `app.py` builds the runtime
|
|
from it; `cli.py` is the entrypoint. The admin SPA in `ui/` is the browser
|
|
window on all of it: conversations by day, the thread with the tree of tool
|
|
calls, the context of the last turn, memory, jobs, usage, tokens and the audit.
|
|
|
|

|
|
|
|
 Every string the gateway puts in front of
|
|
a model or a user has an English default and is overridable
|
|
(`ConversationTexts`, `TelegramTexts`).
|
|
|
|
## Run
|
|
|
|
```sh
|
|
cd examples
|
|
CLAUDE_CODE_OAUTH_TOKEN=$(claude setup-token) docker compose up --build
|
|
```
|
|
|
|
`examples/config.py` is the smallest setup that starts: one agent, one
|
|
python tool, one cron job, the built-in frontends on port 8000; the compose
|
|
file next to it adds Postgres. Without Docker: `uv sync`, build the SPA with
|
|
`cd ui && bun install && bun run build`, then run `uv run beaver-gateway` with
|
|
`DATABASE_URL` and `CONFIG_PATH` set. A setup's own secrets come from `.env`
|
|
next to its config (`load_dotenv` runs before the config is executed).
|
|
|
|
## Develop
|
|
|
|
```sh
|
|
make check # ruff format --check, ruff check, ty, pytest
|
|
make fix
|
|
```
|
|
|
|
No comments in code: modules carry a one-line docstring saying what they are
|
|
for, public configuration fields carry a one-line docstring saying what they
|
|
mean; everything else is the code.
|