Skip to content

Discord assistant: ask Factory about the codebase, then file issues or open PRs from a thread - #54

Merged
matthewp merged 1 commit into
mainfrom
feat/discord-assistant
Oct 7, 2026
Merged

matthewp merged 1 commit into
mainfrom
feat/discord-assistant

Conversation

@matthewp

@matthewp matthewp commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

Changes

  • Adds a Discord assistant. A maintainer mentions the bot in a thread (@Astro Factory where does this get normalized?), and Factory answers using a checkout of the repository. A mention in a regular channel starts a thread from that message. Only members with a role in DISCORD_ALLOWED_ROLE_IDS can use it; everyone else is ignored silently, so the bot can't be used to burn tokens.
  • Mentions arrive over the Discord Gateway, which is the only way Discord delivers ordinary messages. DiscordGateway is a single Durable Object holding that connection, with heartbeats and session resume. A one-minute cron trigger plus the object's own alarm reconnect it after deploys or drops. The protocol logic is in gateway-connection.ts, kept separate from the Durable Object so it can be tested.
  • Each thread gets one durable DiscordAssistant agent conversation and one sandbox. The sandbox reuses triage's checkout, install, and build; it sleeps after an hour idle and is rebuilt on the next mention. DiscordThreadCoordinator runs a thread's jobs in order. Mentions that arrive while it's busy are answered together in the next turn; approved PRs are never dropped.
  • The bot stays visible without spamming the thread. It replies right away ("On it.", or "Starting up a sandbox first…" when the sandbox has to be rebuilt), keeps the typing indicator up while it works, posts at most one "still working" note per long stage, and otherwise stays quiet until it has the answer.
  • The agent can only propose actions. An issue draft comes with Create issue / Dismiss buttons; a PR plan comes with Open PR / Dismiss. Clicks go to /channels/discord/interactions (@flue/discord verifies the signature), where the clicker's role is checked again. The proposal is claimed in the coordinator, so it's acted on only once. After approval, the agent implements the change on factory/discord-<id>. Factory's own code then commits, pushes, and opens the PR, and hands it to the author and reviewer personas. The agent never holds GitHub or Discord credentials.
  • New discord section in factory.yml (enabled, skill, model, thinkingLevel), on by default; the model defaults to triage.model. Worker settings live in wrangler.jsonc: DISCORD_GUILD_ID, DISCORD_ALLOWED_ROLE_IDS, DISCORD_REPOSITORY, DISCORD_PUBLIC_KEY, and optionally DISCORD_ASSISTANT_CHANNEL_IDS. The assistant stays off until the server, roles, and repository are set. Draft until those IDs are filled in and the Message Content intent and interactions endpoint are configured in the developer portal.
  • Heads-up: each active thread holds a sandbox container for up to an hour, and containers.max_instances is 10, shared with every other capability. We may need to raise it.

Testing

  • tests/discord-gateway.test.ts: covers identify and READY, heartbeats with the sequence number, reconnecting when heartbeats stop being acknowledged, resuming a persisted session, re-identifying after a session can't be resumed, stopping on fatal close codes, and thread naming.
  • tests/discord-thread-coordinator.test.ts: covers jobs running in order, coalescing of waiting mentions, dedupe of redelivered and finished jobs, reconciling after a workflow dies without reporting back, a proposal being claimed only once, the read cursor only moving forward, and remembering linked issues.
  • tests/discord-interactions.test.ts: covers the role check, queuing an approved PR with its buttons disabled, a double click acting once, dismissing, buttons that don't match their proposal, and filing an issue in the background.
  • tests/discord-assistant.test.ts: covers settings parsing, mention decisions (role, server, bots, webhooks, reply-without-mention), transcript rendering, issue reference parsing, button custom ids, proposal formatting, the single check-in heartbeat, and the bundled skill.
  • tests/config.test.ts: updated for the new discord defaults, plus override parsing.

Docs

  • The README documents the assistant, the discord config, and the Discord developer portal setup: Message Content intent, interactions endpoint, bot permissions, and the wrangler.jsonc variables.

…posals

Maintainers mention the bot in a Discord thread to ask about the codebase.
A Gateway Durable Object receives mentions from allowed roles; a per-thread
coordinator runs jobs in order; a workflow keeps one sandbox per thread
(sleeps after an hour, rebuilt on demand) and one durable agent conversation.

The agent can propose an issue or a pull request; maintainers confirm with
buttons on the HTTP interactions endpoint (signature and role checked).
Trusted code files issues, or commits, pushes, and opens pull requests and
hands them to the author and reviewer personas.
@matthewp
matthewp marked this pull request as ready for review October 7, 2026 20:54
@matthewp
matthewp merged commit e827755 into main Oct 7, 2026
1 check passed
ascorbic pushed a commit to emdash-cms/factory that referenced this pull request Oct 14, 2026
…ssistant"

This reverts commit e827755, reversing
changes made to f061842.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant