Repository navigation
feat(channels): run Slack, Discord and Telegram on the AgentController - #54
hamchowderr wants to merge 2 commits into
Conversation
The three channel bots called agent.generate() directly, so they had no way to show or answer tool approvals (every Zapier write stalled), no schedules or subagents, a 5-step cap, in-memory Chat SDK state, a Discord Gateway that stopped after 24 hours, and a /link that broke the DM it was typed in. They now run on the Foreman AgentController's channels, the same engine as the web chat: - one Session per channel thread, owned by the sender's Foreman user (shared memory with web), in its own scope so it never touches the web session - sender's user id + workspace stamped on every run and approval click; only the thread's owner can use its session - Approve/Deny buttons for gated tools; same auto-allowed tools as web - Postgres-backed Chat SDK state; Discord Gateway auto-reconnects - /link moves earlier channel threads onto the linked account; link codes are now tied to their app and claimed atomically - old /slack|/discord|/telegram/webhook paths forward to the new routes; the :4112 server and inbox worker no longer host these three - new Slack OAuth installs load into the live adapter Removes the old bots, the FOREMAN_NATIVE_CHANNELS Agent.channels scaffolding and dev:telegram (polling now starts with the agent server). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01T3R2sPwBzA2bpj3HT2BDv2
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2add2ca7d0
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
toolDisplay "text" made core treat Discord as unable to render approval buttons, so it auto-resumed gated tools and Zapier writes from Discord ran without approval. Use core's default "cards" display, and test that no platform is configured with a display that drops the buttons. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01T3R2sPwBzA2bpj3HT2BDv2
|
This PR has been split into three stacked PRs, one concern each, to be merged in this order:
Once all three are merged, the code is identical to this PR's last green commit (869e0c2). I'm closing this PR in favour of them. Generated by Claude Code |
Requested by Chowderr · project thread
Before: Slack, Discord and Telegram called
agent.generate()directly. Any action that needed approval (every Zapier write) stalled with no way to answer it, and the reply came back empty. Runs were capped at 5 steps, so a normal Zapier action couldn't finish. There were no schedules or subagents. The Discord bot went deaf 24 hours after each deploy. Typing/linkbroke the DM it was typed in, because the old thread still belonged to the pre-link user and Mastra refuses that mismatch.After: all three run on the Foreman AgentController, the same engine as the web chat. Actions that need approval post Approve / Deny buttons in the chat, and Zapier writes always ask. Schedules, subagents and plan mode work. Memory is shared with the web chat. The Discord Gateway reconnects on its own.
/linkmoves your earlier channel conversations onto your web account.How
src/channels/controller-channels.tsbuilds thechannelsconfig forcreateForemanAgentController, including only the platforms that have credentials:resolveResourceIdmakes the sender's Foreman user own each channel thread.resolveSessioncreates one Session per channel thread, scopedchannel:<threadId>so it never reuses or re-points the user's web session. It grants the same auto-allowed tools as web and refuses anyone who isn't the thread's owner, posting a note in the chat when it does.userIdandworkspaceIdon the RequestContext before dispatch.src/channels/relink.ts: after a successful/link, moves the threads of the sender's previous owner viaupdateThreadResourceId. For a channel-only placeholder it moves every thread on that platform. For a real account it moves only the chat the code was typed in.redeemChannelLinkCodenow rejects codes made for a different app and claims codes atomically./api/agent-controllers/foreman-agent-controller/channels/<platform>/webhook. The old/slack|/discord|/telegram/webhookpaths forward there, so registered URLs keep working.webhook-server.tsandinbox-worker-server.tscallskipControllerChannels(), so only the main server hosts the channels. Two hosts would answer every message twice.FOREMAN_NATIVE_CHANNELSAgent.channels scaffolding (3i9k) anddev:telegram. Telegram now polls by itself undernpm run dev.Known limits:
:4112.AgentControllerroute test.Checks:
tscclean,npm run lintclean (warnings only, none new),npm test543 passed / 10 skipped.Generated by Claude Code