feat(voice,agents,memory): voice points get their own branch, agent and keys

This commit is contained in:
hh
2026-09-06 23:26:35 +02:00
parent b9eb95d8c0
commit 4dd199147c
14 changed files with 747 additions and 4 deletions
+33 -1
View File
@@ -94,8 +94,38 @@ Everything is on one port under its own path; Caddy forwards the whole domain as
- any Anthropic client: `http://localhost:62990/anthropic` or `https://<DOMAIN>/anthropic`, model = agent name (`beaver-opus-high` etc)
- MCP clients (Claude Desktop, Raycast extension): `/mcp/<name>/`, discovery page at `/mcp/`
- Obsidian companion plugin: `/md` as the plugin's "Base URL", `/api` for the panel
- voice points around the flat: `POST /voice/` with a key of scope `voice` (see below)
- **Admin UI:** `http://localhost:62990/` or `https://<DOMAIN>/`, login from `ADMIN_USER` / `ADMIN_PASS`
## Voice points (`beaver_agent/voice/`)
ESP32 boxes with microphones around the flat, built by a neighbour, post
their own JSON and get an answer back:
```sh
curl -X POST https://<DOMAIN>/voice/ -H "X-Api-Key: <VOICE_KEY>" -d '{
"room": "andreii", "device": "esp32-1",
"request_id": "3fd0d6ed-...", "content": "ало клод как дела"}'
{"request_id":"3fd0d6ed-...","room":"andreii","device":"esp32-1",
"reply":"живу, слушаю","conversation":"…"}
```
`"stream": true` in the body answers `text/event-stream` instead: `delta`
frames with pieces of the text, `done` with the same body as above.
- **One branch for the whole flat**, titled 🎤 Голосовой, so Telegram gives
it a topic under that name: what was asked and what was answered is
readable there, and writing in that topic talks to the same agent.
A cron at 04:05 starts the branch over in the same topic, the way the
master rotates; a day nobody spoke in is left alone.
- **Its own agent** (`beaver-voice`, haiku): `cwd=/tmp`, no tools, no MCP
hands, no gateway tools, and a prompt that ships in this repo instead of
the vault. A stranger may be standing at the speaker, so the agent has
nothing to leak rather than instructions not to - and `Recall`/`ReplyLog`
are muted for it, so the envelope never hands it pointers into the vault.
- **Its own keys**: scope `voice` (Tokens → Create), which opens nothing
else - not `/api`, not the panel, not the token page.
## Exposing to the internet
`caddy/site.caddy` holds the routes (one `reverse_proxy`, domain from `BEAVER_DOMAIN`); on a shared server it is bind-mounted into that server's Caddy as `projects.d/beaver-agent/`, on its own box `caddy/docker-compose.yml` runs a Caddy around it.
@@ -156,7 +186,9 @@ pieces live in `beaver_agent/`, one concern per module:
- `agents.py` - the roles (dispatcher, deep, distiller, curator, triage,
raycast) and the list of instances with models and effort
- `frontends.py` - the windows: Telegram for master and branches, vault
files for deep chats, `/api`, `/admin`, `/anthropic`, `/mcp`
files for deep chats, `/api`, `/admin`, `/anthropic`, `/mcp`, `/voice`
- `voice/` - the voice points: the window, the branch and its nightly
rotation, the prompt the cheap agent runs on
- `texts.py` - everything the gateway says to the model or to the user,
in Russian (the gateway's own defaults are English)
- `memory/` - the recall block under a message, the reply log, handouts