eve-agent #
eve.dev agent deployed on eve.boxd.sh.
- Model: OpenCode Zen
deepseek-v4-flash-free(OpenAI-compatible Chat Completions) - Channels: built-in eve channel + IRC via irc-bridge (POST
/irc/inbound+ SSE/irc/out) - AV (optional): av-bridge (Rust) — freeq MoQ media planes + internet radio (
av-bridge/, freeqeve-av-bridge); stream.place watch (:8792) and publish (RTMP egress) - Tools: cowsay, ATProto, rook/thermals, Anna, Linear (eve project),
guess_emotion,play_radio/stop_radio/stop_media(stream to freeq AV; stop_media = all planes),enter_voice_mode/exit_voice_mode/voice_status(Grok Voice duplex, default Eve timbre),enter_slide_mode/exit_slide_mode/slide_status(AV caption card: speech/text → tile only, no TTS),watch_stream/publish_stream(stream.place in/out),memory_bank_add/memory_bank_list(durable song/note list) - Skills:
vit,vit-request-watch,anna,linear,freeq-irc,irc-backlog,embody-emotion,freeq-radio,freeq-voice,freeq-slide - Schedules:
vit-request-capsevery 10m → explore kind:request on controlled beacons → IRC#test - Secrets: API keys pulled live from OpenBao (
openbao.boxd.sh) viascripts/fetch-keys.sh— never committed
Layout #
agent/
agent.ts # model + agent definition
instructions.md
channels/ # eve.ts, irc.ts (HTTP+SSE only — no IRC socket)
lib/ tools/ skills/ schedules/
irc-bridge/
server.mjs # freeq IRC → POST /irc/inbound ; SSE /irc/out → PRIVMSG
systemd/user/ # user unit templates (eve, irc-bridge, optional av-bridge + streamplace plane (:8792))
scripts/
prep.sh, start.sh, install-systemd.sh, fetch-keys.sh, sync-freeq-session.mjs
flake.nix
rook.host tools #
Public (no identity):
| Tool | Purpose |
|---|---|
thermals_stats |
Board totals |
thermals_requests / thermals_request |
Open work requests |
thermals_rook |
Profile + track record by did/handle |
thermals_leaderboard |
Ranked rooks |
Local CLI (@solpbc/rook):
| Tool | Purpose |
|---|---|
rook_whoami / rook_doctor |
Identity + readiness |
rook_enroll |
Enroll with human invite URL + handle |
rook_profile |
Show / publish / remove thermals profile |
rook_submit |
fork → push → pr → ship from a local clone |
Optional env: ROOK_IDENTITY_FILE, THERMALS_URL (default https://thermals.cloud).
Agent-facing docs: https://rook.host/llms.txt · https://thermals.cloud/llms.txt
Anna's Archive tools #
| Tool | Purpose |
|---|---|
anna_search |
Books by ISBN/title via annas-mcp → MD5s |
anna_download |
Member API → save file under ~/archive (or ANNA_DOWNLOAD_DIR) |
anna_article_search |
Papers by DOI/keywords (annas-mcp) |
openlibrary_isbn |
Open Library bibliography |
anna_record |
Unified AA metadata for one MD5 |
anna_fast_download |
Member API → URL only (ANNA_API_KEY) |
anna_torrents |
Bulk torrent catalog (large dumps) |
Single-book flow: anna_search → pick md5 → anna_download (or anna_fast_download for URL only).
| Variable | Notes |
|---|---|
ANNA_API_KEY |
OpenBao membership key for JSON download API |
ANNA_DOWNLOAD_DIR |
Default $HOME/archive |
ANNAS_MCP_BIN |
Optional path to annas-mcp |
ANNA_ARCHIVE_BASE |
Default https://annas-archive.gl |
bash scripts/install-annas-mcp.sh # → ~/.local/bin/annas-mcp
Skill: load_skill → anna.
Linear tools (eve project) #
All Linear tools are scoped to the Linear project named eve (override with LINEAR_PROJECT_NAME or LINEAR_PROJECT_ID). Issues outside that project are rejected.
| Tool | Purpose |
|---|---|
linear_status |
Project progress + counts by state + sample open issues |
linear_issues |
List/filter issues (query, state, assignee); default open only |
linear_issue |
Full detail for one identifier/UUID |
linear_create_issue |
Create issue always on the eve project |
linear_update_issue |
Update title/description/priority/state/assignee (eve only) |
| Variable | Notes |
|---|---|
LINEAR_API_KEY |
OpenBao ai-api-keys personal API key |
LINEAR_PROJECT_NAME |
Default eve |
LINEAR_PROJECT_ID |
Optional UUID (skips name lookup) |
Skill: load_skill → linear.
Slide mode (freeform AV caption card) #
You say something → Eve shows it on the freeq AV slide only. No TTS speak-back (avoids mic feedback loops). Repeats until exit.
| Trigger | Action |
|---|---|
eve: enter slide mode |
Start listening |
| type anything / speak in call | Slide shows it (display only) |
eve: exit slide mode |
Stop |
Tools: enter_slide_mode, exit_slide_mode, slide_status. Skill: freeq-slide. Join freeq AV to see the tile.
Voice / conversation mode (Grok Voice) #
Duplex speech in freeq AV via Cloudflare Workers AI xai/grok-voice (default spoken voice eve).
| Trigger | Action |
|---|---|
eve: enter voice mode / enter conversation mode |
Start duplex + short spoken greeting |
eve: exit voice mode |
Stop Grok session |
eve: voice status |
Live/off probe |
Tools: enter_voice_mode, exit_voice_mode, voice_status. Skill: freeq-voice.
| Variable | Notes |
|---|---|
CLOUDFLARE_ACCOUNT_ID |
Workers AI account (config / runtime.env) |
CLOUDFLARE_API_TOKEN |
From OpenBao ai-api-keys |
GROK_VOICE |
Default eve |
Users must join the freeq voice call in the channel. stop_media also ends voice mode.
Memory bank (saved songs / notes) #
Host file (not the sandbox). IRC: “add song to memory bank”, “read the memory bank”.
| Tool | Purpose |
|---|---|
memory_bank_add |
Append one entry (usually current now playing / radio_title) |
memory_bank_list |
List saved entries |
| Variable | Default |
|---|---|
MEMORY_BANK_PATH |
$HOME/memory-bank.txt |
Never claim a save without a tool result. Skill: freeq-radio.
freeq IRC nick / SASL #
If the bot appears as Guest… or logs SASL failed (904), the freeq OAuth session expired.
# on the eve VM
npx --yes @solpbc/rook login
node scripts/sync-freeq-session.mjs # or /home/boxd/my-agent/scripts/…
# restart agent (start.sh)
Skill: load_skill → freeq-irc. Target nick: eve / handle eve.boxd.sh (PDS https://pds.eve.boxd.sh).
Local dev #
nix develop # or: direnv allow
npm install
export OPENCODE_API_KEY=… # or other provider keys
npm run dev
Boxd (eve.boxd.sh) #
On the VM, secrets come from OpenBao. Production path uses systemd user units
(eve, eve-irc-bridge, optional eve-av-bridge) — see systemd/README.md.
export OPENBAO_ADDR=https://openbao.boxd.sh
export OPENBAO_TOKEN=… # boxd secret / service token
npm install
bash scripts/install-systemd.sh # once (writes units + ~/.config/eve/)
# put OPENBAO_* in ~/.config/eve/openbao.env (mode 0600)
loginctl enable-linger "$USER" # once, if units should survive logout
npm run boxd:start # systemctl --user start eve.target
Legacy (no units): bash scripts/start.sh --legacy (prep + nohup bridge + foreground eve).
Optional IRC env (defaults match freeq; set in ~/.config/eve/config.env for units):
| Variable | Default |
|---|---|
IRC_HOST |
irc.freeq.at |
IRC_PORT |
6697 |
IRC_TLS |
1 |
IRC_NICK |
eve |
IRC_CHANNEL |
#test |
IRC_PASSWORD |
(unset) |
IRC_OWNERS |
(unset) |
vit request-cap schedule #
| Variable | Default |
|---|---|
VIT_CONTROLLED_BEACONS |
codegod100 repo beacons (comma-separated overrides) |
VIT_CONTROLLED_BEACON_OWNERS |
codegod100 (substring match on beacon) |
VIT_REQUEST_REPORT_EMPTY |
unset = quiet when no matches; 1 = always report |
VIT_EXPLORE_URL |
https://explore.v-it.org |
npm run boxd:start runs eve build && eve start so the cron fires. Locally with eve dev, fire once:
curl -X POST http://127.0.0.1:8000/eve/v1/dev/schedules/vit-request-caps
Framework docs #
See node_modules/eve/docs/ or https://eve.dev/docs.