68 lines
3.7 KiB
Markdown
68 lines
3.7 KiB
Markdown
# @mosaicstack/discord-plugin
|
|
|
|
Official Discord channel adapter for Mosaic Stack.
|
|
|
|
## Behavior
|
|
|
|
- Runs independently of the bound agent's Claude, Codex, Pi, OpenCode, or future harness.
|
|
- Routes authorized untagged messages in configured agent channels and replies in-channel.
|
|
- Creates a public Discord thread when the bot is mentioned in a parent channel, or reuses the thread already attached to that same message.
|
|
- Keeps follow-ups in existing threads without requiring repeated mentions.
|
|
- Keeps `/approve` and `/stop <approval>` on the current durable session.
|
|
- Applies guild, parent-channel, user, pairing, role, and per-minute abuse limits before thread creation or gateway dispatch.
|
|
- Authenticates to the gateway and signs ingress envelopes with the injected service token.
|
|
|
|
## Required configuration
|
|
|
|
| Variable | Purpose |
|
|
| --------------------------------------- | -------------------------------------------------------------------- |
|
|
| `DISCORD_BOT_TOKEN` | Discord bot credential |
|
|
| `DISCORD_SERVICE_TOKEN` | High-entropy plugin-to-gateway credential |
|
|
| `DISCORD_SERVICE_USER_ID` | Provisioned Mosaic service principal |
|
|
| `DISCORD_ALLOWED_GUILD_IDS` | Comma-separated guild allowlist |
|
|
| `DISCORD_ALLOWED_CHANNEL_IDS` | Comma-separated parent-channel allowlist |
|
|
| `DISCORD_ALLOWED_USER_IDS` | Comma-separated Discord user allowlist |
|
|
| `DISCORD_INTERACTION_BINDINGS` | JSON channel→logical-agent bindings and paired-user roles |
|
|
| `DISCORD_GATEWAY_URL` | Gateway base URL; defaults to the gateway's local development URL |
|
|
| `DISCORD_MESSAGE_RATE_LIMIT_PER_MINUTE` | Authorized turns per guild/channel/user per minute; default `30` |
|
|
| `DISCORD_THREAD_RATE_LIMIT_PER_MINUTE` | Mention-thread routes per guild/channel/user per minute; default `5` |
|
|
|
|
Supply credentials through the approved runtime secret mechanism. Never commit tokens or binding data containing secrets.
|
|
|
|
Example binding shape (identifiers are placeholders):
|
|
|
|
```json
|
|
[
|
|
{
|
|
"instanceId": "interaction-agent",
|
|
"agentConfigId": "agent-config-id",
|
|
"guildId": "guild-id",
|
|
"channelId": "channel-id",
|
|
"pairedUsers": {
|
|
"discord-user-id": {
|
|
"role": "operator",
|
|
"mosaicUserId": "mosaic-user-id"
|
|
}
|
|
}
|
|
}
|
|
]
|
|
```
|
|
|
|
Each binding's trusted `agentConfigId` must identify a provisioned database agent configuration whose name exactly matches its `instanceId`. Roles are `viewer`, `operator`, and `admin`. `viewer` cannot send agent turns. Runtime approval and stop operations require an `admin` pairing with a provisioned `mosaicUserId`.
|
|
|
|
The bot needs Discord permissions to view/send messages in configured channels and create/send in public threads. A channel category is not an authorization boundary; threads inherit authorization only from their configured parent text channel.
|
|
|
|
## Shared contract
|
|
|
|
The adapter implements `OfficialChannelAdapter` from `@mosaicstack/types`. `ChannelConversationRouteDto` carries only stable logical-agent/channel identity and a response target. Gateway durable-session and provider layers own runtime selection and handoff; Discord code must not import a harness SDK.
|
|
|
|
## Development
|
|
|
|
```bash
|
|
pnpm --filter @mosaicstack/types build
|
|
pnpm --filter @mosaicstack/discord-plugin typecheck
|
|
pnpm --filter @mosaicstack/discord-plugin lint
|
|
pnpm --filter @mosaicstack/discord-plugin test
|
|
pnpm --filter @mosaicstack/discord-plugin build
|
|
```
|