small gleam coding and persistent agent daemon with a detachable cli and a canvas ui albedo.sh

discord: per-session bots on the inbox event queue #106

Closed okami.mom
targeting main from discord-bots
Closed opened by and assigned to okami.mom
targeting main from discord-bots

Per-session Discord bots whose messages land in the session's inbox.

Discord bots #

  • discord extension (off by default): one bot per session, a Python gateway process per bot (priv/python/albedo_discord.py, stdlib only), HTTP routes, kernel discord.send/dm/history/react/channels/status.
  • /discord TUI page: bots by session with live status, invite link, channel tree, DM whitelist.
  • Manual setup with a bot token and owner user ID. Automated bot creation, user-account login, browser provisioning, and MFA flows are removed.

Incoming reactions #

  • Reaction additions (for example a thumbs-up meaning "go ahead") arrive as inbox events with the reactor's user ID, the emoji, the target message ID and a message link.
  • They follow the same rules as messages: DMs only from the owner and allowed users, channel and thread delivery settings, and in mentions-only channels only when the target is a bot message or one already delivered. The bot's own reactions are ignored.
  • A replay after RESUME is delivered once. Reaction removals and reactions added while the bot process was down are not delivered.

Event queue #

  • Reuses the daemon's mail inbox. New kind Event(AfterTool | AfterTurn), stored as event_tool / event_turn.
  • AfterTool steers a running turn at its next tool boundary.
  • AfterTurn queues without steering; everything that waited starts the next turn together.
  • Webhooks now use AfterTurn too, instead of busy-refuse and retry, one turn each.
  • A migration copies an old mail table into the new kind check.

Channels #

  • Each channel is off, end of turn (AfterTurn), or after tool call (AfterTool), with an optional mentions-only switch. Threads follow their parent channel.
  • Other bots' messages are delivered; the bot's own are ignored. No cooldowns.
  • On reconnect, per-channel cursors catch up through REST without double delivery.

DMs #

  • Always AfterTool.
  • Only the owner (a required user ID) and allowed users get through. Anyone else becomes a "wants to DM you" request; enter allows them.
  • discord.dm only reaches the owner or allowed users.

Simplification #

Commit 29c2e7fd removes 4,780 net lines. The branch is now 8,975 net added lines against its common base with main, down from 13,755. This includes 1,729 lines of OpenAPI/generated code and 1,951 lines of tests. Message reactions remain supported.

Verification #

For b6b8435c, nix develop -c ./test.sh passed in full: formatting, lint, type checks, Rust, Gleam, Python harnesses, Go unit tests, Go E2E and Python E2E, including all seven Discord E2E scenarios (two new reaction scenarios). Tangled CI passed for the earlier simplification commit 29c2e7fd (pipeline 3my23rbygn722).

Commits 0