fengming 0.3.10 → 0.3.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (761) hide show
  1. package/dist/build-info.json +2 -2
  2. package/dist/canvas-host/a2ui/.bundle.hash +1 -1
  3. package/dist/cli-startup-metadata.json +8 -8
  4. package/dist/control-ui/assets/{activity-D-mnRThU.js → activity-wgT0-JR0.js} +2 -2
  5. package/dist/control-ui/assets/{agents-U_KSP5I_.js → agents-DG5PobrT.js} +2 -2
  6. package/dist/control-ui/assets/{channels-ohK9_G1O.js → channels-CX28oM42.js} +2 -2
  7. package/dist/control-ui/assets/{cron-6ZCzfU29.js → cron-B8ixwBqU.js} +2 -2
  8. package/dist/control-ui/assets/{debug-CSsDLg_s.js → debug-CnkYZUXy.js} +2 -2
  9. package/dist/control-ui/assets/{index-jUDczxhd.js → index-DQRZJKbO.js} +4 -4
  10. package/dist/control-ui/assets/{instances-782ZoDT4.js → instances-BE3mV1JC.js} +2 -2
  11. package/dist/control-ui/assets/{nodes-BMX16BKM.js → nodes-Cou4PWRX.js} +2 -2
  12. package/dist/control-ui/assets/{sessions-jLGSApYa.js → sessions-DpAaBT21.js} +2 -2
  13. package/dist/control-ui/assets/{skills-DweBwUhs.js → skills-DjA_j_20.js} +2 -2
  14. package/dist/control-ui/assets/{workboard-BsU-FXIo.js → workboard-BFnvbS0k.js} +2 -2
  15. package/dist/control-ui/index.html +1 -1
  16. package/dist/control-ui/sw.js +1 -1
  17. package/dist/gateway/protocol/index.d.ts +1 -1
  18. package/dist/{index-AZzJCgph.d.ts → index-DuDY3bCZ.d.ts} +2 -2
  19. package/dist/plugin-sdk/.boundary-entry-shims.stamp +1 -1
  20. package/dist/plugin-sdk/agent-config-primitives.d.ts +1 -1
  21. package/dist/plugin-sdk/{bundled-channel-config-schema-Dfn3b8sF.d.ts → bundled-channel-config-schema-BPFNnbwu.d.ts} +23 -23
  22. package/dist/plugin-sdk/bundled-channel-config-schema.d.ts +3 -3
  23. package/dist/plugin-sdk/channel-config-primitives.d.ts +2 -2
  24. package/dist/plugin-sdk/channel-config-schema-legacy.d.ts +3 -3
  25. package/dist/plugin-sdk/channel-config-schema.d.ts +2 -2
  26. package/dist/plugin-sdk/channel-core.d.ts +1 -1
  27. package/dist/plugin-sdk/channel-plugin-common.d.ts +1 -1
  28. package/dist/plugin-sdk/compat.d.ts +2 -2
  29. package/dist/plugin-sdk/{config-schema-DUddICQM.d.ts → config-schema-D7cABQ6o.d.ts} +1 -1
  30. package/dist/plugin-sdk/config-schema.d.ts +2 -2
  31. package/dist/plugin-sdk/core.d.ts +1 -1
  32. package/dist/plugin-sdk/discord.d.ts +2 -2
  33. package/dist/plugin-sdk/tts-runtime.d.ts +1 -1
  34. package/dist/plugin-sdk/{zod-schema.core-B4_b2R5K.d.ts → zod-schema.core-CwBNqcXp.d.ts} +1 -1
  35. package/package.json +4 -409
  36. package/CHANGELOG.md +0 -42
  37. package/THIRD_PARTY_NOTICES.md +0 -37
  38. package/docs/.i18n/README.md +0 -81
  39. package/docs/.i18n/ar-navigation.json +0 -18
  40. package/docs/.i18n/de-navigation.json +0 -18
  41. package/docs/.i18n/es-navigation.json +0 -18
  42. package/docs/.i18n/fr-navigation.json +0 -18
  43. package/docs/.i18n/glossary.ar.json +0 -78
  44. package/docs/.i18n/glossary.de.json +0 -78
  45. package/docs/.i18n/glossary.es.json +0 -78
  46. package/docs/.i18n/glossary.fa.json +0 -78
  47. package/docs/.i18n/glossary.fr.json +0 -78
  48. package/docs/.i18n/glossary.id.json +0 -78
  49. package/docs/.i18n/glossary.it.json +0 -78
  50. package/docs/.i18n/glossary.ja-JP.json +0 -98
  51. package/docs/.i18n/glossary.ko.json +0 -78
  52. package/docs/.i18n/glossary.nl.json +0 -78
  53. package/docs/.i18n/glossary.pl.json +0 -78
  54. package/docs/.i18n/glossary.pt-BR.json +0 -78
  55. package/docs/.i18n/glossary.th.json +0 -78
  56. package/docs/.i18n/glossary.tr.json +0 -78
  57. package/docs/.i18n/glossary.uk.json +0 -78
  58. package/docs/.i18n/glossary.vi.json +0 -78
  59. package/docs/.i18n/glossary.zh-CN.json +0 -1122
  60. package/docs/.i18n/glossary.zh-TW.json +0 -78
  61. package/docs/.i18n/id-navigation.json +0 -18
  62. package/docs/.i18n/it-navigation.json +0 -18
  63. package/docs/.i18n/ja-navigation.json +0 -18
  64. package/docs/.i18n/ko-navigation.json +0 -18
  65. package/docs/.i18n/pl-navigation.json +0 -18
  66. package/docs/.i18n/pt-BR-navigation.json +0 -18
  67. package/docs/.i18n/tr-navigation.json +0 -18
  68. package/docs/.i18n/translation-workflow.md +0 -111
  69. package/docs/.i18n/zh-Hans-navigation.json +0 -552
  70. package/docs/AGENTS.md +0 -36
  71. package/docs/CLAUDE.md +0 -1
  72. package/docs/agent-runtime-architecture.md +0 -48
  73. package/docs/announcements/bluebubbles-imessage.md +0 -79
  74. package/docs/auth-credential-semantics.md +0 -124
  75. package/docs/automation/auth-monitoring.md +0 -11
  76. package/docs/automation/clawflow.md +0 -12
  77. package/docs/automation/cron-jobs.md +0 -534
  78. package/docs/automation/cron-vs-heartbeat.md +0 -11
  79. package/docs/automation/gmail-pubsub.md +0 -11
  80. package/docs/automation/hooks.md +0 -387
  81. package/docs/automation/index.md +0 -135
  82. package/docs/automation/poll.md +0 -12
  83. package/docs/automation/standing-orders.md +0 -250
  84. package/docs/automation/taskflow.md +0 -155
  85. package/docs/automation/tasks.md +0 -374
  86. package/docs/automation/troubleshooting.md +0 -12
  87. package/docs/automation/webhook.md +0 -12
  88. package/docs/brave-search.md +0 -11
  89. package/docs/channels/access-groups.md +0 -201
  90. package/docs/channels/ambient-room-events.md +0 -214
  91. package/docs/channels/bot-loop-protection.md +0 -131
  92. package/docs/channels/broadcast-groups.md +0 -472
  93. package/docs/channels/channel-routing.md +0 -162
  94. package/docs/channels/clickclack.md +0 -138
  95. package/docs/channels/discord.md +0 -1758
  96. package/docs/channels/feishu.md +0 -650
  97. package/docs/channels/googlechat.md +0 -284
  98. package/docs/channels/group-messages.md +0 -95
  99. package/docs/channels/groups.md +0 -524
  100. package/docs/channels/imessage-from-bluebubbles.md +0 -259
  101. package/docs/channels/imessage.md +0 -839
  102. package/docs/channels/index.md +0 -64
  103. package/docs/channels/irc.md +0 -253
  104. package/docs/channels/line.md +0 -243
  105. package/docs/channels/location.md +0 -71
  106. package/docs/channels/matrix-migration.md +0 -370
  107. package/docs/channels/matrix-presentation.md +0 -77
  108. package/docs/channels/matrix-push-rules.md +0 -150
  109. package/docs/channels/matrix.md +0 -921
  110. package/docs/channels/mattermost.md +0 -542
  111. package/docs/channels/msteams.md +0 -1096
  112. package/docs/channels/nextcloud-talk.md +0 -176
  113. package/docs/channels/nostr.md +0 -253
  114. package/docs/channels/pairing.md +0 -214
  115. package/docs/channels/qqbot.md +0 -314
  116. package/docs/channels/signal.md +0 -417
  117. package/docs/channels/slack.md +0 -1623
  118. package/docs/channels/synology-chat.md +0 -187
  119. package/docs/channels/telegram.md +0 -1124
  120. package/docs/channels/tlon.md +0 -296
  121. package/docs/channels/troubleshooting.md +0 -162
  122. package/docs/channels/twitch.md +0 -431
  123. package/docs/channels/wechat.md +0 -171
  124. package/docs/channels/whatsapp.md +0 -796
  125. package/docs/channels/yuanbao.md +0 -416
  126. package/docs/channels/zalo.md +0 -253
  127. package/docs/channels/zalouser.md +0 -217
  128. package/docs/ci.md +0 -657
  129. package/docs/clawhub/publishing.md +0 -96
  130. package/docs/cli/acp.md +0 -370
  131. package/docs/cli/agent.md +0 -109
  132. package/docs/cli/agents.md +0 -253
  133. package/docs/cli/approvals.md +0 -190
  134. package/docs/cli/backup.md +0 -98
  135. package/docs/cli/browser.md +0 -307
  136. package/docs/cli/channels.md +0 -154
  137. package/docs/cli/clawbot.md +0 -25
  138. package/docs/cli/commitments.md +0 -90
  139. package/docs/cli/completion.md +0 -39
  140. package/docs/cli/config.md +0 -504
  141. package/docs/cli/configure.md +0 -77
  142. package/docs/cli/crestodian.md +0 -337
  143. package/docs/cli/cron.md +0 -304
  144. package/docs/cli/daemon.md +0 -67
  145. package/docs/cli/dashboard.md +0 -33
  146. package/docs/cli/devices.md +0 -240
  147. package/docs/cli/directory.md +0 -68
  148. package/docs/cli/dns.md +0 -53
  149. package/docs/cli/docs.md +0 -63
  150. package/docs/cli/doctor.md +0 -241
  151. package/docs/cli/flows.md +0 -52
  152. package/docs/cli/gateway.md +0 -572
  153. package/docs/cli/health.md +0 -43
  154. package/docs/cli/hooks.md +0 -345
  155. package/docs/cli/index.md +0 -400
  156. package/docs/cli/infer.md +0 -364
  157. package/docs/cli/logs.md +0 -68
  158. package/docs/cli/mcp.md +0 -529
  159. package/docs/cli/memory.md +0 -183
  160. package/docs/cli/message.md +0 -317
  161. package/docs/cli/migrate.md +0 -334
  162. package/docs/cli/models.md +0 -239
  163. package/docs/cli/node.md +0 -177
  164. package/docs/cli/nodes.md +0 -76
  165. package/docs/cli/onboard.md +0 -250
  166. package/docs/cli/pairing.md +0 -77
  167. package/docs/cli/path.md +0 -511
  168. package/docs/cli/plugins.md +0 -459
  169. package/docs/cli/policy.md +0 -886
  170. package/docs/cli/proxy.md +0 -89
  171. package/docs/cli/qr.md +0 -56
  172. package/docs/cli/reset.md +0 -39
  173. package/docs/cli/sandbox.md +0 -208
  174. package/docs/cli/secrets.md +0 -202
  175. package/docs/cli/security.md +0 -136
  176. package/docs/cli/sessions.md +0 -164
  177. package/docs/cli/setup.md +0 -59
  178. package/docs/cli/skills.md +0 -122
  179. package/docs/cli/status.md +0 -45
  180. package/docs/cli/system.md +0 -89
  181. package/docs/cli/tasks.md +0 -111
  182. package/docs/cli/transcripts.md +0 -151
  183. package/docs/cli/tui.md +0 -91
  184. package/docs/cli/uninstall.md +0 -44
  185. package/docs/cli/update.md +0 -243
  186. package/docs/cli/voicecall.md +0 -204
  187. package/docs/cli/webhooks.md +0 -117
  188. package/docs/cli/wiki.md +0 -256
  189. package/docs/concepts/active-memory.md +0 -856
  190. package/docs/concepts/agent-loop.md +0 -185
  191. package/docs/concepts/agent-runtimes.md +0 -276
  192. package/docs/concepts/agent-workspace.md +0 -230
  193. package/docs/concepts/agent.md +0 -140
  194. package/docs/concepts/architecture.md +0 -154
  195. package/docs/concepts/channel-docking.md +0 -145
  196. package/docs/concepts/commitments.md +0 -150
  197. package/docs/concepts/compaction.md +0 -203
  198. package/docs/concepts/context-engine.md +0 -347
  199. package/docs/concepts/context.md +0 -199
  200. package/docs/concepts/delegate-architecture.md +0 -319
  201. package/docs/concepts/dreaming.md +0 -264
  202. package/docs/concepts/experimental-features.md +0 -109
  203. package/docs/concepts/features.md +0 -91
  204. package/docs/concepts/fengming-sdk.md +0 -323
  205. package/docs/concepts/mantis-slack-desktop-runbook.md +0 -231
  206. package/docs/concepts/mantis.md +0 -744
  207. package/docs/concepts/markdown-formatting.md +0 -139
  208. package/docs/concepts/memory-builtin.md +0 -148
  209. package/docs/concepts/memory-honcho.md +0 -144
  210. package/docs/concepts/memory-qmd.md +0 -271
  211. package/docs/concepts/memory-search.md +0 -167
  212. package/docs/concepts/memory.md +0 -299
  213. package/docs/concepts/message-lifecycle-refactor.md +0 -1126
  214. package/docs/concepts/messages.md +0 -214
  215. package/docs/concepts/model-failover.md +0 -384
  216. package/docs/concepts/model-providers.md +0 -719
  217. package/docs/concepts/models.md +0 -371
  218. package/docs/concepts/multi-agent.md +0 -625
  219. package/docs/concepts/oauth.md +0 -198
  220. package/docs/concepts/parallel-specialist-lanes.md +0 -127
  221. package/docs/concepts/personal-agent-benchmark-pack.md +0 -74
  222. package/docs/concepts/presence.md +0 -117
  223. package/docs/concepts/progress-drafts.md +0 -406
  224. package/docs/concepts/qa-e2e-automation.md +0 -947
  225. package/docs/concepts/qa-matrix.md +0 -139
  226. package/docs/concepts/queue-steering.md +0 -90
  227. package/docs/concepts/queue.md +0 -136
  228. package/docs/concepts/retry.md +0 -86
  229. package/docs/concepts/session-pruning.md +0 -104
  230. package/docs/concepts/session-tool.md +0 -188
  231. package/docs/concepts/session.md +0 -164
  232. package/docs/concepts/soul.md +0 -116
  233. package/docs/concepts/streaming.md +0 -257
  234. package/docs/concepts/system-prompt.md +0 -328
  235. package/docs/concepts/timezone.md +0 -47
  236. package/docs/concepts/typebox.md +0 -309
  237. package/docs/concepts/typing-indicators.md +0 -88
  238. package/docs/concepts/usage-tracking.md +0 -66
  239. package/docs/date-time.md +0 -126
  240. package/docs/debug/node-issue.md +0 -90
  241. package/docs/diagnostics/flags.md +0 -182
  242. package/docs/docs.json +0 -1862
  243. package/docs/fengming-agent-runtime.md +0 -82
  244. package/docs/gateway/authentication.md +0 -256
  245. package/docs/gateway/background-process.md +0 -147
  246. package/docs/gateway/bonjour.md +0 -303
  247. package/docs/gateway/bridge-protocol.md +0 -97
  248. package/docs/gateway/cli-backends.md +0 -439
  249. package/docs/gateway/config-agents.md +0 -1525
  250. package/docs/gateway/config-channels.md +0 -945
  251. package/docs/gateway/config-tools.md +0 -774
  252. package/docs/gateway/configuration-examples.md +0 -704
  253. package/docs/gateway/configuration-reference.md +0 -1391
  254. package/docs/gateway/configuration.md +0 -739
  255. package/docs/gateway/diagnostics.md +0 -213
  256. package/docs/gateway/discovery.md +0 -154
  257. package/docs/gateway/doctor.md +0 -575
  258. package/docs/gateway/gateway-lock.md +0 -37
  259. package/docs/gateway/health.md +0 -73
  260. package/docs/gateway/heartbeat.md +0 -498
  261. package/docs/gateway/index.md +0 -383
  262. package/docs/gateway/local-model-services.md +0 -205
  263. package/docs/gateway/local-models.md +0 -355
  264. package/docs/gateway/logging.md +0 -149
  265. package/docs/gateway/multiple-gateways.md +0 -178
  266. package/docs/gateway/network-model.md +0 -15
  267. package/docs/gateway/openai-http-api.md +0 -378
  268. package/docs/gateway/openresponses-http-api.md +0 -347
  269. package/docs/gateway/openshell.md +0 -316
  270. package/docs/gateway/opentelemetry.md +0 -433
  271. package/docs/gateway/operator-scopes.md +0 -119
  272. package/docs/gateway/pairing.md +0 -207
  273. package/docs/gateway/prometheus.md +0 -249
  274. package/docs/gateway/protocol.md +0 -826
  275. package/docs/gateway/remote-gateway-readme.md +0 -169
  276. package/docs/gateway/remote.md +0 -280
  277. package/docs/gateway/sandbox-vs-tool-policy-vs-elevated.md +0 -148
  278. package/docs/gateway/sandboxing.md +0 -546
  279. package/docs/gateway/secrets-plan-contract.md +0 -159
  280. package/docs/gateway/secrets.md +0 -805
  281. package/docs/gateway/security/audit-checks.md +0 -127
  282. package/docs/gateway/security/exposure-runbook.md +0 -212
  283. package/docs/gateway/security/index.md +0 -1343
  284. package/docs/gateway/security/secure-file-operations.md +0 -76
  285. package/docs/gateway/security/shrinkwrap.md +0 -111
  286. package/docs/gateway/tailscale.md +0 -156
  287. package/docs/gateway/tools-invoke-http-api.md +0 -169
  288. package/docs/gateway/troubleshooting.md +0 -877
  289. package/docs/gateway/trusted-proxy-auth.md +0 -483
  290. package/docs/help/debugging.md +0 -341
  291. package/docs/help/environment.md +0 -233
  292. package/docs/help/faq-first-run.md +0 -870
  293. package/docs/help/faq-models.md +0 -556
  294. package/docs/help/faq.md +0 -2041
  295. package/docs/help/index.md +0 -39
  296. package/docs/help/scripts.md +0 -56
  297. package/docs/help/testing-live.md +0 -587
  298. package/docs/help/testing-updates-plugins.md +0 -299
  299. package/docs/help/testing.md +0 -977
  300. package/docs/help/troubleshooting.md +0 -449
  301. package/docs/index.md +0 -196
  302. package/docs/install/ansible.md +0 -233
  303. package/docs/install/azure.md +0 -315
  304. package/docs/install/bun.md +0 -59
  305. package/docs/install/clawdock.md +0 -112
  306. package/docs/install/development-channels.md +0 -148
  307. package/docs/install/digitalocean.md +0 -174
  308. package/docs/install/docker-vm-runtime.md +0 -154
  309. package/docs/install/docker.md +0 -564
  310. package/docs/install/exe-dev.md +0 -201
  311. package/docs/install/fly.md +0 -524
  312. package/docs/install/gcp.md +0 -418
  313. package/docs/install/hetzner.md +0 -285
  314. package/docs/install/hostinger.md +0 -98
  315. package/docs/install/index.md +0 -232
  316. package/docs/install/installer.md +0 -447
  317. package/docs/install/kubernetes.md +0 -196
  318. package/docs/install/macos-vm.md +0 -281
  319. package/docs/install/migrating-claude.md +0 -165
  320. package/docs/install/migrating-hermes.md +0 -178
  321. package/docs/install/migrating.md +0 -137
  322. package/docs/install/nix.md +0 -112
  323. package/docs/install/node.md +0 -142
  324. package/docs/install/northflank.mdx +0 -44
  325. package/docs/install/oracle.md +0 -218
  326. package/docs/install/podman.md +0 -216
  327. package/docs/install/railway.mdx +0 -92
  328. package/docs/install/raspberry-pi.md +0 -234
  329. package/docs/install/render.mdx +0 -167
  330. package/docs/install/uninstall.md +0 -131
  331. package/docs/install/updating.md +0 -284
  332. package/docs/install/upstash.md +0 -96
  333. package/docs/logging.md +0 -320
  334. package/docs/nav-tabs-underline.js +0 -100
  335. package/docs/network.md +0 -72
  336. package/docs/nodes/audio.md +0 -216
  337. package/docs/nodes/camera.md +0 -166
  338. package/docs/nodes/images.md +0 -77
  339. package/docs/nodes/index.md +0 -439
  340. package/docs/nodes/location-command.md +0 -102
  341. package/docs/nodes/media-understanding.md +0 -495
  342. package/docs/nodes/talk.md +0 -160
  343. package/docs/nodes/troubleshooting.md +0 -123
  344. package/docs/nodes/voicewake.md +0 -93
  345. package/docs/perplexity.md +0 -11
  346. package/docs/plan/codex-context-engine-harness.md +0 -624
  347. package/docs/plan/ui-channels.md +0 -284
  348. package/docs/platforms/digitalocean.md +0 -12
  349. package/docs/platforms/easyrunner.md +0 -109
  350. package/docs/platforms/index.md +0 -51
  351. package/docs/platforms/linux.md +0 -141
  352. package/docs/platforms/mac/bundled-gateway.md +0 -79
  353. package/docs/platforms/mac/canvas.md +0 -128
  354. package/docs/platforms/mac/child-process.md +0 -72
  355. package/docs/platforms/mac/dev-setup.md +0 -112
  356. package/docs/platforms/mac/health.md +0 -39
  357. package/docs/platforms/mac/icon.md +0 -36
  358. package/docs/platforms/mac/logging.md +0 -62
  359. package/docs/platforms/mac/menu-bar.md +0 -93
  360. package/docs/platforms/mac/peekaboo.md +0 -96
  361. package/docs/platforms/mac/permissions.md +0 -73
  362. package/docs/platforms/mac/remote.md +0 -123
  363. package/docs/platforms/mac/signing.md +0 -52
  364. package/docs/platforms/mac/skills.md +0 -43
  365. package/docs/platforms/mac/voice-overlay.md +0 -66
  366. package/docs/platforms/mac/voicewake.md +0 -73
  367. package/docs/platforms/mac/webchat.md +0 -54
  368. package/docs/platforms/mac/xpc.md +0 -66
  369. package/docs/platforms/oracle.md +0 -12
  370. package/docs/platforms/raspberry-pi.md +0 -13
  371. package/docs/platforms/windows.md +0 -286
  372. package/docs/plugins/adding-capabilities.md +0 -146
  373. package/docs/plugins/admin-http-rpc.md +0 -216
  374. package/docs/plugins/agent-tools.md +0 -13
  375. package/docs/plugins/architecture-internals.md +0 -1196
  376. package/docs/plugins/architecture.md +0 -483
  377. package/docs/plugins/building-extensions.md +0 -13
  378. package/docs/plugins/building-plugins.md +0 -335
  379. package/docs/plugins/bundles.md +0 -310
  380. package/docs/plugins/cli-backend-plugins.md +0 -310
  381. package/docs/plugins/codex-computer-use.md +0 -297
  382. package/docs/plugins/codex-harness-reference.md +0 -470
  383. package/docs/plugins/codex-harness-runtime.md +0 -268
  384. package/docs/plugins/codex-harness.md +0 -780
  385. package/docs/plugins/codex-native-plugins.md +0 -276
  386. package/docs/plugins/community.md +0 -77
  387. package/docs/plugins/compatibility.md +0 -167
  388. package/docs/plugins/copilot.md +0 -356
  389. package/docs/plugins/dependency-resolution.md +0 -176
  390. package/docs/plugins/google-meet.md +0 -1737
  391. package/docs/plugins/hooks.md +0 -484
  392. package/docs/plugins/install-overrides.md +0 -80
  393. package/docs/plugins/manage-plugins.md +0 -210
  394. package/docs/plugins/manifest.md +0 -1457
  395. package/docs/plugins/memory-lancedb.md +0 -385
  396. package/docs/plugins/memory-wiki.md +0 -529
  397. package/docs/plugins/message-presentation.md +0 -473
  398. package/docs/plugins/oc-path.md +0 -166
  399. package/docs/plugins/plugin-inventory.md +0 -189
  400. package/docs/plugins/plugin-permission-requests.md +0 -193
  401. package/docs/plugins/reference/acpx.md +0 -23
  402. package/docs/plugins/reference/admin-http-rpc.md +0 -23
  403. package/docs/plugins/reference/alibaba.md +0 -23
  404. package/docs/plugins/reference/amazon-bedrock-mantle.md +0 -23
  405. package/docs/plugins/reference/amazon-bedrock.md +0 -23
  406. package/docs/plugins/reference/anthropic-vertex.md +0 -19
  407. package/docs/plugins/reference/anthropic.md +0 -23
  408. package/docs/plugins/reference/arcee.md +0 -23
  409. package/docs/plugins/reference/azure-speech.md +0 -23
  410. package/docs/plugins/reference/bonjour.md +0 -19
  411. package/docs/plugins/reference/brave.md +0 -23
  412. package/docs/plugins/reference/browser.md +0 -23
  413. package/docs/plugins/reference/byteplus.md +0 -19
  414. package/docs/plugins/reference/canvas.md +0 -19
  415. package/docs/plugins/reference/cerebras.md +0 -23
  416. package/docs/plugins/reference/chutes.md +0 -23
  417. package/docs/plugins/reference/clickclack.md +0 -23
  418. package/docs/plugins/reference/cloudflare-ai-gateway.md +0 -23
  419. package/docs/plugins/reference/codex-supervisor.md +0 -27
  420. package/docs/plugins/reference/codex.md +0 -23
  421. package/docs/plugins/reference/comfy.md +0 -23
  422. package/docs/plugins/reference/copilot-proxy.md +0 -19
  423. package/docs/plugins/reference/copilot.md +0 -23
  424. package/docs/plugins/reference/deepgram.md +0 -23
  425. package/docs/plugins/reference/deepinfra.md +0 -23
  426. package/docs/plugins/reference/deepseek.md +0 -23
  427. package/docs/plugins/reference/diagnostics-otel.md +0 -19
  428. package/docs/plugins/reference/diagnostics-prometheus.md +0 -19
  429. package/docs/plugins/reference/diffs-language-pack.md +0 -19
  430. package/docs/plugins/reference/diffs.md +0 -19
  431. package/docs/plugins/reference/discord.md +0 -23
  432. package/docs/plugins/reference/document-extract.md +0 -23
  433. package/docs/plugins/reference/duckduckgo.md +0 -23
  434. package/docs/plugins/reference/elevenlabs.md +0 -23
  435. package/docs/plugins/reference/exa.md +0 -23
  436. package/docs/plugins/reference/fal.md +0 -23
  437. package/docs/plugins/reference/feishu.md +0 -23
  438. package/docs/plugins/reference/file-transfer.md +0 -19
  439. package/docs/plugins/reference/firecrawl.md +0 -23
  440. package/docs/plugins/reference/fireworks.md +0 -23
  441. package/docs/plugins/reference/github-copilot.md +0 -23
  442. package/docs/plugins/reference/gmi.md +0 -23
  443. package/docs/plugins/reference/google-meet.md +0 -23
  444. package/docs/plugins/reference/google.md +0 -23
  445. package/docs/plugins/reference/googlechat.md +0 -23
  446. package/docs/plugins/reference/gradium.md +0 -23
  447. package/docs/plugins/reference/groq.md +0 -23
  448. package/docs/plugins/reference/huggingface.md +0 -23
  449. package/docs/plugins/reference/imessage.md +0 -23
  450. package/docs/plugins/reference/inworld.md +0 -23
  451. package/docs/plugins/reference/irc.md +0 -23
  452. package/docs/plugins/reference/kilocode.md +0 -23
  453. package/docs/plugins/reference/kimi.md +0 -23
  454. package/docs/plugins/reference/line.md +0 -23
  455. package/docs/plugins/reference/litellm.md +0 -23
  456. package/docs/plugins/reference/llm-task.md +0 -19
  457. package/docs/plugins/reference/lmstudio.md +0 -23
  458. package/docs/plugins/reference/lobster.md +0 -19
  459. package/docs/plugins/reference/matrix.md +0 -23
  460. package/docs/plugins/reference/mattermost.md +0 -23
  461. package/docs/plugins/reference/memory-core.md +0 -19
  462. package/docs/plugins/reference/memory-lancedb.md +0 -23
  463. package/docs/plugins/reference/memory-wiki.md +0 -23
  464. package/docs/plugins/reference/microsoft-foundry.md +0 -19
  465. package/docs/plugins/reference/microsoft.md +0 -19
  466. package/docs/plugins/reference/migrate-claude.md +0 -19
  467. package/docs/plugins/reference/migrate-hermes.md +0 -19
  468. package/docs/plugins/reference/minimax.md +0 -23
  469. package/docs/plugins/reference/mistral.md +0 -23
  470. package/docs/plugins/reference/moonshot.md +0 -23
  471. package/docs/plugins/reference/msteams.md +0 -23
  472. package/docs/plugins/reference/nextcloud-talk.md +0 -23
  473. package/docs/plugins/reference/nostr.md +0 -23
  474. package/docs/plugins/reference/novita.md +0 -23
  475. package/docs/plugins/reference/nvidia.md +0 -23
  476. package/docs/plugins/reference/oc-path.md +0 -23
  477. package/docs/plugins/reference/ollama.md +0 -23
  478. package/docs/plugins/reference/open-prose.md +0 -19
  479. package/docs/plugins/reference/openai.md +0 -23
  480. package/docs/plugins/reference/opencode-go.md +0 -23
  481. package/docs/plugins/reference/opencode.md +0 -23
  482. package/docs/plugins/reference/openrouter.md +0 -23
  483. package/docs/plugins/reference/openshell.md +0 -19
  484. package/docs/plugins/reference/perplexity.md +0 -23
  485. package/docs/plugins/reference/pixverse.md +0 -23
  486. package/docs/plugins/reference/policy.md +0 -72
  487. package/docs/plugins/reference/qa-channel.md +0 -23
  488. package/docs/plugins/reference/qa-lab.md +0 -19
  489. package/docs/plugins/reference/qa-matrix.md +0 -19
  490. package/docs/plugins/reference/qianfan.md +0 -23
  491. package/docs/plugins/reference/qqbot.md +0 -23
  492. package/docs/plugins/reference/qwen.md +0 -23
  493. package/docs/plugins/reference/runway.md +0 -23
  494. package/docs/plugins/reference/searxng.md +0 -19
  495. package/docs/plugins/reference/senseaudio.md +0 -23
  496. package/docs/plugins/reference/sglang.md +0 -23
  497. package/docs/plugins/reference/signal.md +0 -23
  498. package/docs/plugins/reference/skill-workshop.md +0 -23
  499. package/docs/plugins/reference/slack.md +0 -23
  500. package/docs/plugins/reference/stepfun.md +0 -23
  501. package/docs/plugins/reference/synology-chat.md +0 -23
  502. package/docs/plugins/reference/synthetic.md +0 -23
  503. package/docs/plugins/reference/tavily.md +0 -23
  504. package/docs/plugins/reference/telegram.md +0 -23
  505. package/docs/plugins/reference/tencent.md +0 -23
  506. package/docs/plugins/reference/tlon.md +0 -23
  507. package/docs/plugins/reference/together.md +0 -23
  508. package/docs/plugins/reference/tokenjuice.md +0 -23
  509. package/docs/plugins/reference/tts-local-cli.md +0 -19
  510. package/docs/plugins/reference/twitch.md +0 -23
  511. package/docs/plugins/reference/venice.md +0 -23
  512. package/docs/plugins/reference/vercel-ai-gateway.md +0 -23
  513. package/docs/plugins/reference/vllm.md +0 -23
  514. package/docs/plugins/reference/voice-call.md +0 -23
  515. package/docs/plugins/reference/volcengine.md +0 -23
  516. package/docs/plugins/reference/voyage.md +0 -19
  517. package/docs/plugins/reference/vydra.md +0 -23
  518. package/docs/plugins/reference/web-readability.md +0 -19
  519. package/docs/plugins/reference/webhooks.md +0 -23
  520. package/docs/plugins/reference/whatsapp.md +0 -23
  521. package/docs/plugins/reference/workboard.md +0 -23
  522. package/docs/plugins/reference/xai.md +0 -23
  523. package/docs/plugins/reference/xiaomi.md +0 -23
  524. package/docs/plugins/reference/zai.md +0 -23
  525. package/docs/plugins/reference/zalo.md +0 -23
  526. package/docs/plugins/reference/zalouser.md +0 -24
  527. package/docs/plugins/reference.md +0 -145
  528. package/docs/plugins/sdk-agent-harness.md +0 -338
  529. package/docs/plugins/sdk-channel-inbound.md +0 -70
  530. package/docs/plugins/sdk-channel-ingress.md +0 -137
  531. package/docs/plugins/sdk-channel-message.md +0 -18
  532. package/docs/plugins/sdk-channel-outbound.md +0 -113
  533. package/docs/plugins/sdk-channel-plugins.md +0 -765
  534. package/docs/plugins/sdk-channel-turn.md +0 -9
  535. package/docs/plugins/sdk-entrypoints.md +0 -344
  536. package/docs/plugins/sdk-migration.md +0 -979
  537. package/docs/plugins/sdk-overview.md +0 -511
  538. package/docs/plugins/sdk-provider-plugins.md +0 -846
  539. package/docs/plugins/sdk-runtime.md +0 -676
  540. package/docs/plugins/sdk-setup.md +0 -550
  541. package/docs/plugins/sdk-subpaths.md +0 -391
  542. package/docs/plugins/sdk-testing.md +0 -403
  543. package/docs/plugins/skill-workshop.md +0 -713
  544. package/docs/plugins/tool-plugins.md +0 -411
  545. package/docs/plugins/voice-call.md +0 -942
  546. package/docs/plugins/webhooks.md +0 -192
  547. package/docs/plugins/workboard.md +0 -252
  548. package/docs/plugins/zalouser.md +0 -86
  549. package/docs/prose.md +0 -137
  550. package/docs/providers/alibaba.md +0 -158
  551. package/docs/providers/anthropic.md +0 -381
  552. package/docs/providers/arcee.md +0 -144
  553. package/docs/providers/azure-speech.md +0 -119
  554. package/docs/providers/bedrock-mantle.md +0 -211
  555. package/docs/providers/bedrock.md +0 -414
  556. package/docs/providers/cerebras.md +0 -130
  557. package/docs/providers/chutes.md +0 -153
  558. package/docs/providers/claude-max-api-proxy.md +0 -191
  559. package/docs/providers/cloudflare-ai-gateway.md +0 -119
  560. package/docs/providers/comfy.md +0 -362
  561. package/docs/providers/deepgram.md +0 -184
  562. package/docs/providers/deepinfra.md +0 -92
  563. package/docs/providers/deepseek.md +0 -146
  564. package/docs/providers/ds4.md +0 -309
  565. package/docs/providers/elevenlabs.md +0 -130
  566. package/docs/providers/fal.md +0 -240
  567. package/docs/providers/fireworks.md +0 -144
  568. package/docs/providers/github-copilot.md +0 -257
  569. package/docs/providers/gmi.md +0 -92
  570. package/docs/providers/google.md +0 -472
  571. package/docs/providers/gradium.md +0 -123
  572. package/docs/providers/groq.md +0 -171
  573. package/docs/providers/huggingface.md +0 -235
  574. package/docs/providers/index.md +0 -105
  575. package/docs/providers/inferrs.md +0 -272
  576. package/docs/providers/inworld.md +0 -120
  577. package/docs/providers/kilocode.md +0 -135
  578. package/docs/providers/litellm.md +0 -234
  579. package/docs/providers/lmstudio.md +0 -224
  580. package/docs/providers/minimax.md +0 -505
  581. package/docs/providers/mistral.md +0 -235
  582. package/docs/providers/models.md +0 -64
  583. package/docs/providers/moonshot.md +0 -413
  584. package/docs/providers/novita.md +0 -92
  585. package/docs/providers/nvidia.md +0 -158
  586. package/docs/providers/ollama-cloud.md +0 -115
  587. package/docs/providers/ollama.md +0 -1225
  588. package/docs/providers/openai.md +0 -1093
  589. package/docs/providers/opencode-go.md +0 -123
  590. package/docs/providers/opencode.md +0 -149
  591. package/docs/providers/openrouter.md +0 -349
  592. package/docs/providers/perplexity-provider.md +0 -123
  593. package/docs/providers/pixverse.md +0 -165
  594. package/docs/providers/qianfan.md +0 -132
  595. package/docs/providers/qwen-oauth.md +0 -115
  596. package/docs/providers/qwen.md +0 -364
  597. package/docs/providers/runway.md +0 -103
  598. package/docs/providers/senseaudio.md +0 -68
  599. package/docs/providers/sglang.md +0 -161
  600. package/docs/providers/stepfun.md +0 -229
  601. package/docs/providers/synthetic.md +0 -154
  602. package/docs/providers/tencent.md +0 -130
  603. package/docs/providers/together.md +0 -140
  604. package/docs/providers/venice.md +0 -312
  605. package/docs/providers/vercel-ai-gateway.md +0 -128
  606. package/docs/providers/vllm.md +0 -407
  607. package/docs/providers/volcengine.md +0 -199
  608. package/docs/providers/vydra.md +0 -180
  609. package/docs/providers/xai.md +0 -571
  610. package/docs/providers/xiaomi.md +0 -262
  611. package/docs/providers/zai.md +0 -224
  612. package/docs/refactor/access.md +0 -9
  613. package/docs/refactor/acp.md +0 -298
  614. package/docs/refactor/canvas.md +0 -131
  615. package/docs/refactor/database-first.md +0 -2256
  616. package/docs/refactor/ingress-core.md +0 -341
  617. package/docs/reference/AGENTS.default.md +0 -131
  618. package/docs/reference/RELEASING.md +0 -799
  619. package/docs/reference/api-usage-costs.md +0 -208
  620. package/docs/reference/application-modernization-plan.md +0 -208
  621. package/docs/reference/code-mode.md +0 -773
  622. package/docs/reference/credits.md +0 -33
  623. package/docs/reference/device-models.md +0 -50
  624. package/docs/reference/fengming-sdk-api-design.md +0 -390
  625. package/docs/reference/full-release-validation.md +0 -202
  626. package/docs/reference/memory-config.md +0 -604
  627. package/docs/reference/prompt-caching.md +0 -358
  628. package/docs/reference/release-performance-sweep.md +0 -360
  629. package/docs/reference/rich-output-protocol.md +0 -101
  630. package/docs/reference/rpc.md +0 -43
  631. package/docs/reference/secret-placeholder-conventions.md +0 -33
  632. package/docs/reference/secretref-credential-surface.md +0 -159
  633. package/docs/reference/secretref-user-supplied-credentials-matrix.json +0 -663
  634. package/docs/reference/session-management-compaction.md +0 -474
  635. package/docs/reference/templates/AGENTS.dev.md +0 -90
  636. package/docs/reference/templates/AGENTS.md +0 -227
  637. package/docs/reference/templates/BOOT.md +0 -16
  638. package/docs/reference/templates/BOOTSTRAP.md +0 -66
  639. package/docs/reference/templates/CLAUDE.md +0 -1
  640. package/docs/reference/templates/HEARTBEAT.md +0 -24
  641. package/docs/reference/templates/IDENTITY.dev.md +0 -52
  642. package/docs/reference/templates/IDENTITY.md +0 -34
  643. package/docs/reference/templates/SOUL.dev.md +0 -82
  644. package/docs/reference/templates/SOUL.md +0 -49
  645. package/docs/reference/templates/TOOLS.dev.md +0 -29
  646. package/docs/reference/templates/TOOLS.md +0 -51
  647. package/docs/reference/templates/USER.dev.md +0 -23
  648. package/docs/reference/templates/USER.md +0 -28
  649. package/docs/reference/test.md +0 -247
  650. package/docs/reference/token-use.md +0 -246
  651. package/docs/reference/transcript-hygiene.md +0 -214
  652. package/docs/reference/wizard.md +0 -252
  653. package/docs/security/CONTRIBUTING-THREAT-MODEL.md +0 -101
  654. package/docs/security/THREAT-MODEL-ATLAS.md +0 -611
  655. package/docs/security/formal-verification.md +0 -170
  656. package/docs/security/incident-response.md +0 -59
  657. package/docs/security/network-proxy.md +0 -268
  658. package/docs/snippets/plugin-publish/minimal-fengming.plugin.json +0 -12
  659. package/docs/snippets/plugin-publish/minimal-package.json +0 -16
  660. package/docs/specs/claw-supervisor.md +0 -247
  661. package/docs/start/bootstrapping.md +0 -49
  662. package/docs/start/docs-directory.md +0 -69
  663. package/docs/start/fengming.md +0 -252
  664. package/docs/start/getting-started.md +0 -152
  665. package/docs/start/hubs.md +0 -201
  666. package/docs/start/lore.md +0 -223
  667. package/docs/start/onboarding-overview.md +0 -72
  668. package/docs/start/onboarding.md +0 -98
  669. package/docs/start/quickstart.md +0 -25
  670. package/docs/start/setup.md +0 -178
  671. package/docs/start/showcase.md +0 -363
  672. package/docs/start/wizard-cli-automation.md +0 -232
  673. package/docs/start/wizard-cli-reference.md +0 -331
  674. package/docs/start/wizard.md +0 -141
  675. package/docs/style.css +0 -137
  676. package/docs/superpowers/specs/2026-04-22-tweakcn-custom-theme-import-design.md +0 -316
  677. package/docs/tools/acp-agents-setup.md +0 -351
  678. package/docs/tools/acp-agents.md +0 -854
  679. package/docs/tools/agent-send.md +0 -130
  680. package/docs/tools/apply-patch.md +0 -64
  681. package/docs/tools/brave-search.md +0 -139
  682. package/docs/tools/browser-control.md +0 -391
  683. package/docs/tools/browser-linux-troubleshooting.md +0 -173
  684. package/docs/tools/browser-login.md +0 -77
  685. package/docs/tools/browser-wsl2-windows-remote-cdp-troubleshooting.md +0 -219
  686. package/docs/tools/browser.md +0 -810
  687. package/docs/tools/btw.md +0 -159
  688. package/docs/tools/capability-cookbook.md +0 -12
  689. package/docs/tools/clawhub.md +0 -5
  690. package/docs/tools/code-execution.md +0 -173
  691. package/docs/tools/creating-skills.md +0 -158
  692. package/docs/tools/diffs.md +0 -525
  693. package/docs/tools/duckduckgo-search.md +0 -109
  694. package/docs/tools/elevated.md +0 -128
  695. package/docs/tools/exa-search.md +0 -152
  696. package/docs/tools/exec-approvals-advanced.md +0 -444
  697. package/docs/tools/exec-approvals.md +0 -494
  698. package/docs/tools/exec.md +0 -285
  699. package/docs/tools/firecrawl.md +0 -155
  700. package/docs/tools/gemini-search.md +0 -114
  701. package/docs/tools/goal.md +0 -217
  702. package/docs/tools/grok-search.md +0 -129
  703. package/docs/tools/image-generation.md +0 -493
  704. package/docs/tools/index.md +0 -178
  705. package/docs/tools/kimi-search.md +0 -105
  706. package/docs/tools/llm-task.md +0 -137
  707. package/docs/tools/lobster.md +0 -365
  708. package/docs/tools/loop-detection.md +0 -154
  709. package/docs/tools/media-overview.md +0 -160
  710. package/docs/tools/minimax-search.md +0 -102
  711. package/docs/tools/multi-agent-sandbox-tools.md +0 -409
  712. package/docs/tools/music-generation.md +0 -372
  713. package/docs/tools/ollama-search.md +0 -153
  714. package/docs/tools/pdf.md +0 -213
  715. package/docs/tools/perplexity-search.md +0 -220
  716. package/docs/tools/plugin.md +0 -363
  717. package/docs/tools/reactions.md +0 -100
  718. package/docs/tools/searxng-search.md +0 -141
  719. package/docs/tools/skills-config.md +0 -195
  720. package/docs/tools/skills.md +0 -569
  721. package/docs/tools/slash-commands.md +0 -487
  722. package/docs/tools/steer.md +0 -77
  723. package/docs/tools/subagents.md +0 -651
  724. package/docs/tools/tavily.md +0 -162
  725. package/docs/tools/thinking.md +0 -142
  726. package/docs/tools/tokenjuice.md +0 -84
  727. package/docs/tools/tool-search.md +0 -269
  728. package/docs/tools/trajectory.md +0 -229
  729. package/docs/tools/tts.md +0 -1009
  730. package/docs/tools/video-generation.md +0 -555
  731. package/docs/tools/web-fetch.md +0 -210
  732. package/docs/tools/web.md +0 -461
  733. package/docs/tts.md +0 -11
  734. package/docs/vps.md +0 -139
  735. package/docs/web/control-ui.md +0 -512
  736. package/docs/web/dashboard.md +0 -107
  737. package/docs/web/index.md +0 -133
  738. package/docs/web/tui.md +0 -250
  739. package/docs/web/webchat.md +0 -102
  740. package/npm-shrinkwrap.json +0 -12861
  741. package/patches/.gitkeep +0 -0
  742. package/patches/@agentclientprotocol__claude-agent-acp@0.37.0.patch +0 -41
  743. package/pnpm-workspace.yaml +0 -120
  744. package/scripts/crabbox-wrapper.mjs +0 -2004
  745. package/scripts/lib/official-external-channel-catalog.json +0 -560
  746. package/scripts/lib/official-external-plugin-catalog.json +0 -264
  747. package/scripts/lib/official-external-provider-catalog.json +0 -158
  748. package/scripts/lib/package-dist-imports.mjs +0 -171
  749. package/scripts/npm-runner.mjs +0 -91
  750. package/scripts/postinstall-bundled-plugins.mjs +0 -978
  751. package/scripts/preinstall-package-manager-warning.mjs +0 -64
  752. package/scripts/prepare-git-hooks.mjs +0 -72
  753. package/scripts/windows-cmd-helpers.mjs +0 -22
  754. package/skills/batch/SKILL.md +0 -118
  755. package/skills/code-review/SKILL.md +0 -107
  756. package/skills/debug/SKILL.md +0 -83
  757. package/skills/loop/SKILL.md +0 -118
  758. package/skills/run/SKILL.md +0 -79
  759. package/skills/run-skill-generator/SKILL.md +0 -179
  760. package/skills/verify/SKILL.md +0 -103
  761. package/src/agents/templates/HEARTBEAT.md +0 -3
@@ -1,1758 +0,0 @@
1
- ---
2
- summary: "Discord bot support status, capabilities, and configuration"
3
- read_when:
4
- - Working on Discord channel features
5
- title: "Discord"
6
- ---
7
-
8
- Ready for DMs and guild channels via the official Discord gateway.
9
-
10
- <CardGroup cols={3}>
11
- <Card title="Pairing" icon="link" href="/channels/pairing">
12
- Discord DMs default to pairing mode.
13
- </Card>
14
- <Card title="Slash commands" icon="terminal" href="/tools/slash-commands">
15
- Native command behavior and command catalog.
16
- </Card>
17
- <Card title="Channel troubleshooting" icon="wrench" href="/channels/troubleshooting">
18
- Cross-channel diagnostics and repair flow.
19
- </Card>
20
- </CardGroup>
21
-
22
- ## Quick setup
23
-
24
- You will need to create a new application with a bot, add the bot to your server, and pair it to FengMing. We recommend adding your bot to your own private server. If you don't have one yet, [create one first](https://support.discord.com/hc/en-us/articles/204849977-How-do-I-create-a-server) (choose **Create My Own > For me and my friends**).
25
-
26
- <Steps>
27
- <Step title="Create a Discord application and bot">
28
- Go to the [Discord Developer Portal](https://discord.com/developers/applications) and click **New Application**. Name it something like "FengMing".
29
-
30
- Click **Bot** on the sidebar. Set the **Username** to whatever you call your FengMing agent.
31
-
32
- </Step>
33
-
34
- <Step title="Enable privileged intents">
35
- Still on the **Bot** page, scroll down to **Privileged Gateway Intents** and enable:
36
-
37
- - **Message Content Intent** (required)
38
- - **Server Members Intent** (recommended; required for role allowlists and name-to-ID matching)
39
- - **Presence Intent** (optional; only needed for presence updates)
40
-
41
- </Step>
42
-
43
- <Step title="Copy your bot token">
44
- Scroll back up on the **Bot** page and click **Reset Token**.
45
-
46
- <Note>
47
- Despite the name, this generates your first token — nothing is being "reset."
48
- </Note>
49
-
50
- Copy the token and save it somewhere. This is your **Bot Token** and you will need it shortly.
51
-
52
- </Step>
53
-
54
- <Step title="Generate an invite URL and add the bot to your server">
55
- Click **OAuth2** on the sidebar. You'll generate an invite URL with the right permissions to add the bot to your server.
56
-
57
- Scroll down to **OAuth2 URL Generator** and enable:
58
-
59
- - `bot`
60
- - `applications.commands`
61
-
62
- A **Bot Permissions** section will appear below. Enable at least:
63
-
64
- **General Permissions**
65
- - View Channels
66
- **Text Permissions**
67
- - Send Messages
68
- - Read Message History
69
- - Embed Links
70
- - Attach Files
71
- - Add Reactions (optional)
72
-
73
- This is the baseline set for normal text channels. If you plan to post in Discord threads, including forum or media channel workflows that create or continue a thread, also enable **Send Messages in Threads**.
74
- Copy the generated URL at the bottom, paste it into your browser, select your server, and click **Continue** to connect. You should now see your bot in the Discord server.
75
-
76
- </Step>
77
-
78
- <Step title="Enable Developer Mode and collect your IDs">
79
- Back in the Discord app, you need to enable Developer Mode so you can copy internal IDs.
80
-
81
- 1. Click **User Settings** (gear icon next to your avatar) → **Advanced** → toggle on **Developer Mode**
82
- 2. Right-click your **server icon** in the sidebar → **Copy Server ID**
83
- 3. Right-click your **own avatar** → **Copy User ID**
84
-
85
- Save your **Server ID** and **User ID** alongside your Bot Token — you'll send all three to FengMing in the next step.
86
-
87
- </Step>
88
-
89
- <Step title="Allow DMs from server members">
90
- For pairing to work, Discord needs to allow your bot to DM you. Right-click your **server icon** → **Privacy Settings** → toggle on **Direct Messages**.
91
-
92
- This lets server members (including bots) send you DMs. Keep this enabled if you want to use Discord DMs with FengMing. If you only plan to use guild channels, you can disable DMs after pairing.
93
-
94
- </Step>
95
-
96
- <Step title="Set your bot token securely (do not send it in chat)">
97
- Your Discord bot token is a secret (like a password). Set it on the machine running FengMing before messaging your agent.
98
-
99
- ```bash
100
- export DISCORD_BOT_TOKEN="YOUR_BOT_TOKEN"
101
- cat > discord.patch.json5 <<'JSON5'
102
- {
103
- channels: {
104
- discord: {
105
- enabled: true,
106
- token: { source: "env", provider: "default", id: "DISCORD_BOT_TOKEN" },
107
- },
108
- },
109
- }
110
- JSON5
111
- fengming config patch --file ./discord.patch.json5 --dry-run
112
- fengming config patch --file ./discord.patch.json5
113
- fengming gateway
114
- ```
115
-
116
- If FengMing is already running as a background service, restart it via the FengMing Mac app or by stopping and restarting the `fengming gateway run` process.
117
- For managed service installs, run `fengming gateway install` from a shell where `DISCORD_BOT_TOKEN` is present, or store the variable in `~/.fengming/.env`, so the service can resolve the env SecretRef after restart.
118
- If your host is blocked or rate-limited by Discord's startup application lookup, set the Discord application/client ID from the Developer Portal so startup can skip that REST call. Use `channels.discord.applicationId` for the default account, or `channels.discord.accounts.<accountId>.applicationId` when you run multiple Discord bots.
119
-
120
- </Step>
121
-
122
- <Step title="Configure FengMing and pair">
123
-
124
- <Tabs>
125
- <Tab title="Ask your agent">
126
- Chat with your FengMing agent on any existing channel (e.g. Telegram) and tell it. If Discord is your first channel, use the CLI / config tab instead.
127
-
128
- > "I already set my Discord bot token in config. Please finish Discord setup with User ID `<user_id>` and Server ID `<server_id>`."
129
- </Tab>
130
- <Tab title="CLI / config">
131
- If you prefer file-based config, set:
132
-
133
- ```json5
134
- {
135
- channels: {
136
- discord: {
137
- enabled: true,
138
- token: {
139
- source: "env",
140
- provider: "default",
141
- id: "DISCORD_BOT_TOKEN",
142
- },
143
- },
144
- },
145
- }
146
- ```
147
-
148
- Env fallback for the default account:
149
-
150
- ```bash
151
- DISCORD_BOT_TOKEN=...
152
- ```
153
-
154
- For scripted or remote setup, write the same JSON5 block with `fengming config patch --file ./discord.patch.json5 --dry-run` and then rerun without `--dry-run`. Plaintext `token` values are supported. SecretRef values are also supported for `channels.discord.token` across env/file/exec providers. See [Secrets Management](/gateway/secrets).
155
-
156
- For multiple Discord bots, keep each bot token and application ID under its account. A top-level `channels.discord.applicationId` is inherited by accounts, so only set it there when every account should use the same application ID.
157
-
158
- ```json5
159
- {
160
- channels: {
161
- discord: {
162
- enabled: true,
163
- accounts: {
164
- personal: {
165
- token: { source: "env", provider: "default", id: "DISCORD_PERSONAL_TOKEN" },
166
- applicationId: "111111111111111111",
167
- },
168
- work: {
169
- token: { source: "env", provider: "default", id: "DISCORD_WORK_TOKEN" },
170
- applicationId: "222222222222222222",
171
- },
172
- },
173
- },
174
- },
175
- }
176
- ```
177
-
178
- </Tab>
179
- </Tabs>
180
-
181
- </Step>
182
-
183
- <Step title="Approve first DM pairing">
184
- Wait until the gateway is running, then DM your bot in Discord. It will respond with a pairing code.
185
-
186
- <Tabs>
187
- <Tab title="Ask your agent">
188
- Send the pairing code to your agent on your existing channel:
189
-
190
- > "Approve this Discord pairing code: `<CODE>`"
191
- </Tab>
192
- <Tab title="CLI">
193
-
194
- ```bash
195
- fengming pairing list discord
196
- fengming pairing approve discord <CODE>
197
- ```
198
-
199
- </Tab>
200
- </Tabs>
201
-
202
- Pairing codes expire after 1 hour.
203
-
204
- You should now be able to chat with your agent in Discord via DM.
205
-
206
- </Step>
207
- </Steps>
208
-
209
- <Note>
210
- Token resolution is account-aware. Config token values win over env fallback. `DISCORD_BOT_TOKEN` is only used for the default account.
211
- If two enabled Discord accounts resolve to the same bot token, FengMing starts only one gateway monitor for that token. A config-sourced token wins over the default env fallback; otherwise the first enabled account wins and the duplicate account is reported disabled.
212
- For advanced outbound calls (message tool/channel actions), an explicit per-call `token` is used for that call. This applies to send and read/probe-style actions (for example read/search/fetch/thread/pins/permissions). Account policy/retry settings still come from the selected account in the active runtime snapshot.
213
- </Note>
214
-
215
- ## Recommended: Set up a guild workspace
216
-
217
- Once DMs are working, you can set up your Discord server as a full workspace where each channel gets its own agent session with its own context. This is recommended for private servers where it's just you and your bot.
218
-
219
- <Steps>
220
- <Step title="Add your server to the guild allowlist">
221
- This enables your agent to respond in any channel on your server, not just DMs.
222
-
223
- <Tabs>
224
- <Tab title="Ask your agent">
225
- > "Add my Discord Server ID `<server_id>` to the guild allowlist"
226
- </Tab>
227
- <Tab title="Config">
228
-
229
- ```json5
230
- {
231
- channels: {
232
- discord: {
233
- groupPolicy: "allowlist",
234
- guilds: {
235
- YOUR_SERVER_ID: {
236
- requireMention: true,
237
- users: ["YOUR_USER_ID"],
238
- },
239
- },
240
- },
241
- },
242
- }
243
- ```
244
-
245
- </Tab>
246
- </Tabs>
247
-
248
- </Step>
249
-
250
- <Step title="Allow responses without @mention">
251
- By default, your agent only responds in guild channels when @mentioned. For a private server, you probably want it to respond to every message.
252
-
253
- In guild channels, normal replies post automatically by default. For shared always-on rooms, opt into `messages.groupChat.visibleReplies: "message_tool"` so the agent can lurk and only post when it decides a channel reply is useful. This works best with latest-generation, tool-reliable models such as GPT 5.5. Ambient room events stay quiet unless the tool sends. See [Ambient room events](/channels/ambient-room-events) for the full lurk-mode config.
254
-
255
- If Discord shows typing and the logs show token usage but no posted message, check whether the turn was configured as an ambient room event or opted into message-tool visible replies.
256
-
257
- <Tabs>
258
- <Tab title="Ask your agent">
259
- > "Allow my agent to respond on this server without having to be @mentioned"
260
- </Tab>
261
- <Tab title="Config">
262
- Set `requireMention: false` in your guild config:
263
-
264
- ```json5
265
- {
266
- channels: {
267
- discord: {
268
- guilds: {
269
- YOUR_SERVER_ID: {
270
- requireMention: false,
271
- },
272
- },
273
- },
274
- },
275
- }
276
- ```
277
-
278
- To require message-tool sends for visible group/channel replies, set `messages.groupChat.visibleReplies: "message_tool"`.
279
-
280
- </Tab>
281
- </Tabs>
282
-
283
- </Step>
284
-
285
- <Step title="Plan for memory in guild channels">
286
- By default, long-term memory (MEMORY.md) only loads in DM sessions. Guild channels do not auto-load MEMORY.md.
287
-
288
- <Tabs>
289
- <Tab title="Ask your agent">
290
- > "When I ask questions in Discord channels, use memory_search or memory_get if you need long-term context from MEMORY.md."
291
- </Tab>
292
- <Tab title="Manual">
293
- If you need shared context in every channel, put the stable instructions in `AGENTS.md` or `USER.md` (they are injected for every session). Keep long-term notes in `MEMORY.md` and access them on demand with memory tools.
294
- </Tab>
295
- </Tabs>
296
-
297
- </Step>
298
- </Steps>
299
-
300
- Now create some channels on your Discord server and start chatting. Your agent can see the channel name, and each channel gets its own isolated session — so you can set up `#coding`, `#home`, `#research`, or whatever fits your workflow.
301
-
302
- ## Runtime model
303
-
304
- - Gateway owns the Discord connection.
305
- - Reply routing is deterministic: Discord inbound replies back to Discord.
306
- - Discord guild/channel metadata is added to the model prompt as untrusted
307
- context, not as a user-visible reply prefix. If a model copies that envelope
308
- back, FengMing strips the copied metadata from outbound replies and from
309
- future replay context.
310
- - By default (`session.dmScope=main`), direct chats share the agent main session (`agent:main:main`).
311
- - Guild channels are isolated session keys (`agent:<agentId>:discord:channel:<channelId>`).
312
- - Group DMs are ignored by default (`channels.discord.dm.groupEnabled=false`).
313
- - Native slash commands run in isolated command sessions (`agent:<agentId>:discord:slash:<userId>`), while still carrying `CommandTargetSessionKey` to the routed conversation session.
314
- - Text-only cron/heartbeat announce delivery to Discord uses the final
315
- assistant-visible answer once. Media and structured component payloads remain
316
- multi-message when the agent emits multiple deliverable payloads.
317
-
318
- ## Forum channels
319
-
320
- Discord forum and media channels only accept thread posts. FengMing supports two ways to create them:
321
-
322
- - Send a message to the forum parent (`channel:<forumId>`) to auto-create a thread. The thread title uses the first non-empty line of your message.
323
- - Use `fengming message thread create` to create a thread directly. Do not pass `--message-id` for forum channels.
324
-
325
- Example: send to forum parent to create a thread
326
-
327
- ```bash
328
- fengming message send --channel discord --target channel:<forumId> \
329
- --message "Topic title\nBody of the post"
330
- ```
331
-
332
- Example: create a forum thread explicitly
333
-
334
- ```bash
335
- fengming message thread create --channel discord --target channel:<forumId> \
336
- --thread-name "Topic title" --message "Body of the post"
337
- ```
338
-
339
- Forum parents do not accept Discord components. If you need components, send to the thread itself (`channel:<threadId>`).
340
-
341
- ## Interactive components
342
-
343
- FengMing supports Discord components v2 containers for agent messages. Use the message tool with a `components` payload. Interaction results are routed back to the agent as normal inbound messages and follow the existing Discord `replyToMode` settings.
344
-
345
- Supported blocks:
346
-
347
- - `text`, `section`, `separator`, `actions`, `media-gallery`, `file`
348
- - Action rows allow up to 5 buttons or a single select menu
349
- - Select types: `string`, `user`, `role`, `mentionable`, `channel`
350
-
351
- By default, components are single use. Set `components.reusable=true` to allow buttons, selects, and forms to be used multiple times until they expire.
352
-
353
- To restrict who can click a button, set `allowedUsers` on that button (Discord user IDs, tags, or `*`). When configured, unmatched users receive an ephemeral denial.
354
-
355
- Component callbacks expire after 30 minutes by default. Set `channels.discord.agentComponents.ttlMs` to change that callback registry lifetime for the default Discord account, or `channels.discord.accounts.<accountId>.agentComponents.ttlMs` to override one account in a multi-account setup. The value is milliseconds, must be a positive integer, and is capped at `86400000` (24 hours). Longer TTLs are useful for review or approval workflows that need buttons to remain usable, but they also extend the window where an old Discord message can still trigger an action. Prefer the shortest TTL that fits the workflow, and keep the default when stale callbacks would be surprising.
356
-
357
- The `/model` and `/models` slash commands open an interactive model picker with provider, model, and compatible runtime dropdowns plus a Submit step. `/models add` is deprecated and now returns a deprecation message instead of registering models from chat. The picker reply is ephemeral and only the invoking user can use it. Discord select menus are limited to 25 options, so add `provider/*` entries to `agents.defaults.models` when you want the picker to show dynamically discovered models only for selected providers such as `openai` or `vllm`.
358
-
359
- File attachments:
360
-
361
- - `file` blocks must point to an attachment reference (`attachment://<filename>`)
362
- - Provide the attachment via `media`/`path`/`filePath` (single file); use `media-gallery` for multiple files
363
- - Use `filename` to override the upload name when it should match the attachment reference
364
-
365
- Modal forms:
366
-
367
- - Add `components.modal` with up to 5 fields
368
- - Field types: `text`, `checkbox`, `radio`, `select`, `role-select`, `user-select`
369
- - FengMing adds a trigger button automatically
370
-
371
- Example:
372
-
373
- ```json5
374
- {
375
- channel: "discord",
376
- action: "send",
377
- to: "channel:123456789012345678",
378
- message: "Optional fallback text",
379
- components: {
380
- reusable: true,
381
- text: "Choose a path",
382
- blocks: [
383
- {
384
- type: "actions",
385
- buttons: [
386
- {
387
- label: "Approve",
388
- style: "success",
389
- allowedUsers: ["123456789012345678"],
390
- },
391
- { label: "Decline", style: "danger" },
392
- ],
393
- },
394
- {
395
- type: "actions",
396
- select: {
397
- type: "string",
398
- placeholder: "Pick an option",
399
- options: [
400
- { label: "Option A", value: "a" },
401
- { label: "Option B", value: "b" },
402
- ],
403
- },
404
- },
405
- ],
406
- modal: {
407
- title: "Details",
408
- triggerLabel: "Open form",
409
- fields: [
410
- { type: "text", label: "Requester" },
411
- {
412
- type: "select",
413
- label: "Priority",
414
- options: [
415
- { label: "Low", value: "low" },
416
- { label: "High", value: "high" },
417
- ],
418
- },
419
- ],
420
- },
421
- },
422
- }
423
- ```
424
-
425
- ## Access control and routing
426
-
427
- <Tabs>
428
- <Tab title="DM policy">
429
- `channels.discord.dmPolicy` controls DM access. `channels.discord.allowFrom` is the canonical DM allowlist.
430
-
431
- - `pairing` (default)
432
- - `allowlist`
433
- - `open` (requires `channels.discord.allowFrom` to include `"*"`)
434
- - `disabled`
435
-
436
- If DM policy is not open, unknown users are blocked (or prompted for pairing in `pairing` mode).
437
-
438
- Multi-account precedence:
439
-
440
- - `channels.discord.accounts.default.allowFrom` applies only to the `default` account.
441
- - For one account, `allowFrom` takes precedence over legacy `dm.allowFrom`.
442
- - Named accounts inherit `channels.discord.allowFrom` when their own `allowFrom` and legacy `dm.allowFrom` are unset.
443
- - Named accounts do not inherit `channels.discord.accounts.default.allowFrom`.
444
-
445
- Legacy `channels.discord.dm.policy` and `channels.discord.dm.allowFrom` still read for compatibility. `fengming doctor --fix` migrates them to `dmPolicy` and `allowFrom` when it can do so without changing access.
446
-
447
- DM target format for delivery:
448
-
449
- - `user:<id>`
450
- - `<@id>` mention
451
-
452
- Bare numeric IDs normally resolve as channel IDs when a channel default is active, but IDs listed in the account's effective DM `allowFrom` are treated as user DM targets for compatibility.
453
-
454
- </Tab>
455
-
456
- <Tab title="Access groups">
457
- Discord DMs and text command authorization can use dynamic `accessGroup:<name>` entries in `channels.discord.allowFrom`.
458
-
459
- Access group names are shared across message channels. Use `type: "message.senders"` for a static group whose members are expressed in each channel's normal `allowFrom` syntax, or `type: "discord.channelAudience"` when a Discord channel's current `ViewChannel` audience should define membership dynamically. Shared access-group behavior is documented here: [Access groups](/channels/access-groups).
460
-
461
- ```json5
462
- {
463
- accessGroups: {
464
- operators: {
465
- type: "message.senders",
466
- members: {
467
- "*": ["global-owner-id"],
468
- discord: ["discord:123456789012345678"],
469
- telegram: ["987654321"],
470
- },
471
- },
472
- },
473
- channels: {
474
- discord: {
475
- dmPolicy: "allowlist",
476
- allowFrom: ["accessGroup:operators"],
477
- },
478
- },
479
- }
480
- ```
481
-
482
- A Discord text channel has no separate member list. `type: "discord.channelAudience"` models membership as: the DM sender is a member of the configured guild and currently has effective `ViewChannel` permission on the configured channel after role and channel overwrites are applied.
483
-
484
- Example: allow anyone who can see `#maintainers` to DM the bot, while keeping DMs closed to everyone else.
485
-
486
- ```json5
487
- {
488
- accessGroups: {
489
- maintainers: {
490
- type: "discord.channelAudience",
491
- guildId: "1456350064065904867",
492
- channelId: "1456744319972282449",
493
- membership: "canViewChannel",
494
- },
495
- },
496
- channels: {
497
- discord: {
498
- dmPolicy: "allowlist",
499
- allowFrom: ["accessGroup:maintainers"],
500
- },
501
- },
502
- }
503
- ```
504
-
505
- You can mix dynamic and static entries:
506
-
507
- ```json5
508
- {
509
- accessGroups: {
510
- maintainers: {
511
- type: "discord.channelAudience",
512
- guildId: "1456350064065904867",
513
- channelId: "1456744319972282449",
514
- },
515
- },
516
- channels: {
517
- discord: {
518
- dmPolicy: "allowlist",
519
- allowFrom: ["accessGroup:maintainers", "discord:123456789012345678"],
520
- },
521
- },
522
- }
523
- ```
524
-
525
- Lookups fail closed. If Discord returns `Missing Access`, the member lookup fails, or the channel belongs to a different guild, the DM sender is treated as unauthorized.
526
-
527
- Enable the Discord Developer Portal **Server Members Intent** for the bot when using channel-audience access groups. DMs do not include guild member state, so FengMing resolves the member through Discord REST at authorization time.
528
-
529
- </Tab>
530
-
531
- <Tab title="Guild policy">
532
- Guild handling is controlled by `channels.discord.groupPolicy`:
533
-
534
- - `open`
535
- - `allowlist`
536
- - `disabled`
537
-
538
- Secure baseline when `channels.discord` exists is `allowlist`.
539
-
540
- `allowlist` behavior:
541
-
542
- - guild must match `channels.discord.guilds` (`id` preferred, slug accepted)
543
- - optional sender allowlists: `users` (stable IDs recommended) and `roles` (role IDs only); if either is configured, senders are allowed when they match `users` OR `roles`
544
- - direct name/tag matching is disabled by default; enable `channels.discord.dangerouslyAllowNameMatching: true` only as break-glass compatibility mode
545
- - names/tags are supported for `users`, but IDs are safer; `fengming security audit` warns when name/tag entries are used
546
- - if a guild has `channels` configured, non-listed channels are denied
547
- - if a guild has no `channels` block, all channels in that allowlisted guild are allowed
548
-
549
- Example:
550
-
551
- ```json5
552
- {
553
- channels: {
554
- discord: {
555
- groupPolicy: "allowlist",
556
- guilds: {
557
- "123456789012345678": {
558
- requireMention: true,
559
- ignoreOtherMentions: true,
560
- users: ["987654321098765432"],
561
- roles: ["123456789012345678"],
562
- channels: {
563
- general: { allow: true },
564
- help: { allow: true, requireMention: true },
565
- },
566
- },
567
- },
568
- },
569
- },
570
- }
571
- ```
572
-
573
- If you only set `DISCORD_BOT_TOKEN` and do not create a `channels.discord` block, runtime fallback is `groupPolicy="allowlist"` (with a warning in logs), even if `channels.defaults.groupPolicy` is `open`.
574
-
575
- </Tab>
576
-
577
- <Tab title="Mentions and group DMs">
578
- Guild messages are mention-gated by default.
579
-
580
- Mention detection includes:
581
-
582
- - explicit bot mention
583
- - configured mention patterns (`agents.list[].groupChat.mentionPatterns`, fallback `messages.groupChat.mentionPatterns`)
584
- - implicit reply-to-bot behavior in supported cases
585
-
586
- When writing outbound Discord messages, use canonical mention syntax: `<@USER_ID>` for users, `<#CHANNEL_ID>` for channels, and `<@&ROLE_ID>` for roles. Do not use the legacy `<@!USER_ID>` nickname mention form.
587
-
588
- `requireMention` is configured per guild/channel (`channels.discord.guilds...`).
589
- `ignoreOtherMentions` optionally drops messages that mention another user/role but not the bot (excluding @everyone/@here).
590
-
591
- Group DMs:
592
-
593
- - default: ignored (`dm.groupEnabled=false`)
594
- - optional allowlist via `dm.groupChannels` (channel IDs or slugs)
595
-
596
- </Tab>
597
- </Tabs>
598
-
599
- ### Role-based agent routing
600
-
601
- Use `bindings[].match.roles` to route Discord guild members to different agents by role ID. Role-based bindings accept role IDs only and are evaluated after peer or parent-peer bindings and before guild-only bindings. If a binding also sets other match fields (for example `peer` + `guildId` + `roles`), all configured fields must match.
602
-
603
- ```json5
604
- {
605
- bindings: [
606
- {
607
- agentId: "opus",
608
- match: {
609
- channel: "discord",
610
- guildId: "123456789012345678",
611
- roles: ["111111111111111111"],
612
- },
613
- },
614
- {
615
- agentId: "sonnet",
616
- match: {
617
- channel: "discord",
618
- guildId: "123456789012345678",
619
- },
620
- },
621
- ],
622
- }
623
- ```
624
-
625
- ## Native commands and command auth
626
-
627
- - `commands.native` defaults to `"auto"` and is enabled for Discord.
628
- - Per-channel override: `channels.discord.commands.native`.
629
- - `commands.native=false` skips Discord slash-command registration and cleanup during startup. Previously registered commands may remain visible in Discord until you remove them from the Discord app.
630
- - Native command auth uses the same Discord allowlists/policies as normal message handling.
631
- - Commands may still be visible in Discord UI for users who are not authorized; execution still enforces FengMing auth and returns "not authorized".
632
-
633
- See [Slash commands](/tools/slash-commands) for command catalog and behavior.
634
-
635
- Default slash command settings:
636
-
637
- - `ephemeral: true`
638
-
639
- ## Feature details
640
-
641
- <AccordionGroup>
642
- <Accordion title="Reply tags and native replies">
643
- Discord supports reply tags in agent output:
644
-
645
- - `[[reply_to_current]]`
646
- - `[[reply_to:<id>]]`
647
-
648
- Controlled by `channels.discord.replyToMode`:
649
-
650
- - `off` (default)
651
- - `first`
652
- - `all`
653
- - `batched`
654
-
655
- Note: `off` disables implicit reply threading. Explicit `[[reply_to_*]]` tags are still honored.
656
- `first` always attaches the implicit native reply reference to the first outbound Discord message for the turn.
657
- `batched` only attaches Discord's implicit native reply reference when the
658
- inbound event was a debounced batch of multiple messages. This is useful
659
- when you want native replies mainly for ambiguous bursty chats, not every
660
- single-message turn.
661
-
662
- Message IDs are surfaced in context/history so agents can target specific messages.
663
-
664
- </Accordion>
665
-
666
- <Accordion title="Link previews">
667
- Discord generates rich link embeds for URLs by default. FengMing suppresses those generated embeds on outbound Discord messages by default, so agent-sent URLs stay as plain links unless you opt in:
668
-
669
- ```json5
670
- {
671
- channels: {
672
- discord: {
673
- suppressEmbeds: false,
674
- },
675
- },
676
- }
677
- ```
678
-
679
- Set `channels.discord.accounts.<id>.suppressEmbeds` to override one account. Agent message-tool sends can also pass `suppressEmbeds: false` for a single message. Explicit Discord `embeds` payloads are not suppressed by the default link-preview setting.
680
-
681
- </Accordion>
682
-
683
- <Accordion title="Live stream preview">
684
- FengMing can stream draft replies by sending a temporary message and editing it as text arrives. `channels.discord.streaming` takes `off` | `partial` | `block` | `progress` (default). `progress` keeps one editable status draft and updates it with tool progress until final delivery; the shared starter label is a rolling line, so it scrolls away like the rest once enough work appears. `streamMode` is a legacy runtime alias. Run `fengming doctor --fix` to rewrite persisted config to the canonical key.
685
-
686
- Set `channels.discord.streaming.mode` to `off` to disable Discord preview edits. If Discord block streaming is explicitly enabled, FengMing skips the preview stream to avoid double-streaming.
687
-
688
- ```json5
689
- {
690
- channels: {
691
- discord: {
692
- streaming: {
693
- mode: "progress",
694
- progress: {
695
- label: "auto",
696
- maxLines: 8,
697
- maxLineChars: 120,
698
- toolProgress: true,
699
- commentary: false,
700
- },
701
- },
702
- },
703
- },
704
- }
705
- ```
706
-
707
- - `partial` edits a single preview message as tokens arrive.
708
- - `block` emits draft-sized chunks (use `draftChunk` to tune size and breakpoints, clamped to `textChunkLimit`).
709
- - Media, error, and explicit-reply finals cancel pending preview edits.
710
- - `streaming.preview.toolProgress` (default `true`) controls whether tool/progress updates reuse the preview message.
711
- - Tool/progress rows render as compact emoji + title + detail when available, for example `🛠️ Bash: run tests` or `🔎 Web Search: for "query"`.
712
- - `streaming.progress.commentary` (default `false`) opts into assistant commentary/preamble text in the temporary progress draft. Commentary is cleaned before display, stays transient, and does not change final answer delivery.
713
- - `streaming.progress.maxLineChars` controls the per-line progress preview budget. Prose is shortened on word boundaries; command and path details keep useful suffixes.
714
- - `streaming.preview.commandText` / `streaming.progress.commandText` controls command/exec detail in compact progress lines: `raw` (default) or `status` (tool label only).
715
-
716
- Hide raw command/exec text while keeping compact progress lines:
717
-
718
- ```json
719
- {
720
- "channels": {
721
- "discord": {
722
- "streaming": {
723
- "mode": "progress",
724
- "progress": {
725
- "toolProgress": true,
726
- "commandText": "status"
727
- }
728
- }
729
- }
730
- }
731
- }
732
- ```
733
-
734
- Preview streaming is text-only; media replies fall back to normal delivery. When `block` streaming is explicitly enabled, FengMing skips the preview stream to avoid double-streaming.
735
-
736
- </Accordion>
737
-
738
- <Accordion title="History, context, and thread behavior">
739
- Guild history context:
740
-
741
- - `channels.discord.historyLimit` default `20`
742
- - fallback: `messages.groupChat.historyLimit`
743
- - `0` disables
744
-
745
- DM history controls:
746
-
747
- - `channels.discord.dmHistoryLimit`
748
- - `channels.discord.dms["<user_id>"].historyLimit`
749
-
750
- Thread behavior:
751
-
752
- - Discord threads route as channel sessions and inherit parent channel config unless overridden.
753
- - Thread sessions inherit the parent channel's session-level `/model` selection as a model-only fallback; thread-local `/model` selections still take precedence and parent transcript history is not copied unless transcript inheritance is enabled.
754
- - `channels.discord.thread.inheritParent` (default `false`) opts new auto-threads into seeding from the parent transcript. Per-account overrides live under `channels.discord.accounts.<id>.thread.inheritParent`.
755
- - Message-tool reactions can resolve `user:<id>` DM targets.
756
- - `guilds.<guild>.channels.<channel>.requireMention: false` is preserved during reply-stage activation fallback.
757
-
758
- Channel topics are injected as **untrusted** context. Allowlists gate who can trigger the agent, not a full supplemental-context redaction boundary.
759
-
760
- </Accordion>
761
-
762
- <Accordion title="Thread-bound sessions for subagents">
763
- Discord can bind a thread to a session target so follow-up messages in that thread keep routing to the same session (including subagent sessions).
764
-
765
- Commands:
766
-
767
- - `/focus <target>` bind current/new thread to a subagent/session target
768
- - `/unfocus` remove current thread binding
769
- - `/agents` show active runs and binding state
770
- - `/session idle <duration|off>` inspect/update inactivity auto-unfocus for focused bindings
771
- - `/session max-age <duration|off>` inspect/update hard max age for focused bindings
772
-
773
- Config:
774
-
775
- ```json5
776
- {
777
- session: {
778
- threadBindings: {
779
- enabled: true,
780
- idleHours: 24,
781
- maxAgeHours: 0,
782
- },
783
- },
784
- channels: {
785
- discord: {
786
- threadBindings: {
787
- enabled: true,
788
- idleHours: 24,
789
- maxAgeHours: 0,
790
- spawnSessions: true,
791
- defaultSpawnContext: "fork",
792
- },
793
- },
794
- },
795
- }
796
- ```
797
-
798
- Notes:
799
-
800
- - `session.threadBindings.*` sets global defaults.
801
- - `channels.discord.threadBindings.*` overrides Discord behavior.
802
- - `spawnSessions` controls auto-create/bind threads for `sessions_spawn({ thread: true })` and ACP thread spawns. Default: `true`.
803
- - `defaultSpawnContext` controls native subagent context for thread-bound spawns. Default: `"fork"`.
804
- - Deprecated `spawnSubagentSessions`/`spawnAcpSessions` keys are migrated by `fengming doctor --fix`.
805
- - If thread bindings are disabled for an account, `/focus` and related thread binding operations are unavailable.
806
-
807
- See [Sub-agents](/tools/subagents), [ACP Agents](/tools/acp-agents), and [Configuration Reference](/gateway/configuration-reference).
808
-
809
- </Accordion>
810
-
811
- <Accordion title="Persistent ACP channel bindings">
812
- For stable "always-on" ACP workspaces, configure top-level typed ACP bindings targeting Discord conversations.
813
-
814
- Config path:
815
-
816
- - `bindings[]` with `type: "acp"` and `match.channel: "discord"`
817
-
818
- Example:
819
-
820
- ```json5
821
- {
822
- agents: {
823
- list: [
824
- {
825
- id: "codex",
826
- runtime: {
827
- type: "acp",
828
- acp: {
829
- agent: "codex",
830
- backend: "acpx",
831
- mode: "persistent",
832
- cwd: "/workspace/fengming",
833
- },
834
- },
835
- },
836
- ],
837
- },
838
- bindings: [
839
- {
840
- type: "acp",
841
- agentId: "codex",
842
- match: {
843
- channel: "discord",
844
- accountId: "default",
845
- peer: { kind: "channel", id: "222222222222222222" },
846
- },
847
- acp: { label: "codex-main" },
848
- },
849
- ],
850
- channels: {
851
- discord: {
852
- guilds: {
853
- "111111111111111111": {
854
- channels: {
855
- "222222222222222222": {
856
- requireMention: false,
857
- },
858
- },
859
- },
860
- },
861
- },
862
- },
863
- }
864
- ```
865
-
866
- Notes:
867
-
868
- - `/acp spawn codex --bind here` binds the current channel or thread in place and keeps future messages on the same ACP session. Thread messages inherit the parent channel binding.
869
- - In a bound channel or thread, `/new` and `/reset` reset the same ACP session in place. Temporary thread bindings can override target resolution while active.
870
- - `spawnSessions` gates child thread creation/binding via `--thread auto|here`.
871
-
872
- See [ACP Agents](/tools/acp-agents) for binding behavior details.
873
-
874
- </Accordion>
875
-
876
- <Accordion title="Reaction notifications">
877
- Per-guild reaction notification mode:
878
-
879
- - `off`
880
- - `own` (default)
881
- - `all`
882
- - `allowlist` (uses `guilds.<id>.users`)
883
-
884
- Reaction events are turned into system events and attached to the routed Discord session.
885
-
886
- </Accordion>
887
-
888
- <Accordion title="Ack reactions">
889
- `ackReaction` sends an acknowledgement emoji while FengMing is processing an inbound message.
890
-
891
- Resolution order:
892
-
893
- - `channels.discord.accounts.<accountId>.ackReaction`
894
- - `channels.discord.ackReaction`
895
- - `messages.ackReaction`
896
- - agent identity emoji fallback (`agents.list[].identity.emoji`, else "👀")
897
-
898
- Notes:
899
-
900
- - Discord accepts unicode emoji or custom emoji names.
901
- - Use `""` to disable the reaction for a channel or account.
902
-
903
- </Accordion>
904
-
905
- <Accordion title="Config writes">
906
- Channel-initiated config writes are enabled by default.
907
-
908
- This affects `/config set|unset` flows (when command features are enabled).
909
-
910
- Disable:
911
-
912
- ```json5
913
- {
914
- channels: {
915
- discord: {
916
- configWrites: false,
917
- },
918
- },
919
- }
920
- ```
921
-
922
- </Accordion>
923
-
924
- <Accordion title="Gateway proxy">
925
- Route Discord gateway WebSocket traffic and startup REST lookups (application ID + allowlist resolution) through an HTTP(S) proxy with `channels.discord.proxy`.
926
-
927
- ```json5
928
- {
929
- channels: {
930
- discord: {
931
- proxy: "http://proxy.example:8080",
932
- },
933
- },
934
- }
935
- ```
936
-
937
- Per-account override:
938
-
939
- ```json5
940
- {
941
- channels: {
942
- discord: {
943
- accounts: {
944
- primary: {
945
- proxy: "http://proxy.example:8080",
946
- },
947
- },
948
- },
949
- },
950
- }
951
- ```
952
-
953
- </Accordion>
954
-
955
- <Accordion title="PluralKit support">
956
- Enable PluralKit resolution to map proxied messages to system member identity:
957
-
958
- ```json5
959
- {
960
- channels: {
961
- discord: {
962
- pluralkit: {
963
- enabled: true,
964
- token: "pk_live_...", // optional; needed for private systems
965
- },
966
- },
967
- },
968
- }
969
- ```
970
-
971
- Notes:
972
-
973
- - allowlists can use `pk:<memberId>`
974
- - member display names are matched by name/slug only when `channels.discord.dangerouslyAllowNameMatching: true`
975
- - lookups use original message ID and are time-window constrained
976
- - if lookup fails, proxied messages are treated as bot messages and dropped unless `allowBots=true`
977
-
978
- </Accordion>
979
-
980
- <Accordion title="Outbound mention aliases">
981
- Use `mentionAliases` when agents need deterministic outbound mentions for known Discord users. Keys are handles without the leading `@`; values are Discord user IDs. Unknown handles, `@everyone`, `@here`, and mentions inside Markdown code spans are left unchanged.
982
-
983
- ```json5
984
- {
985
- channels: {
986
- discord: {
987
- mentionAliases: {
988
- Vladislava: "123456789012345678",
989
- },
990
- accounts: {
991
- ops: {
992
- mentionAliases: {
993
- OpsLead: "234567890123456789",
994
- },
995
- },
996
- },
997
- },
998
- },
999
- }
1000
- ```
1001
-
1002
- </Accordion>
1003
-
1004
- <Accordion title="Presence configuration">
1005
- Presence updates are applied when you set a status or activity field, or when you enable auto presence.
1006
-
1007
- Status only example:
1008
-
1009
- ```json5
1010
- {
1011
- channels: {
1012
- discord: {
1013
- status: "idle",
1014
- },
1015
- },
1016
- }
1017
- ```
1018
-
1019
- Activity example (custom status is the default activity type):
1020
-
1021
- ```json5
1022
- {
1023
- channels: {
1024
- discord: {
1025
- activity: "Focus time",
1026
- activityType: 4,
1027
- },
1028
- },
1029
- }
1030
- ```
1031
-
1032
- Streaming example:
1033
-
1034
- ```json5
1035
- {
1036
- channels: {
1037
- discord: {
1038
- activity: "Live coding",
1039
- activityType: 1,
1040
- activityUrl: "https://twitch.tv/fengming",
1041
- },
1042
- },
1043
- }
1044
- ```
1045
-
1046
- Activity type map:
1047
-
1048
- - 0: Playing
1049
- - 1: Streaming (requires `activityUrl`)
1050
- - 2: Listening
1051
- - 3: Watching
1052
- - 4: Custom (uses the activity text as the status state; emoji is optional)
1053
- - 5: Competing
1054
-
1055
- Auto presence example (runtime health signal):
1056
-
1057
- ```json5
1058
- {
1059
- channels: {
1060
- discord: {
1061
- autoPresence: {
1062
- enabled: true,
1063
- intervalMs: 30000,
1064
- minUpdateIntervalMs: 15000,
1065
- exhaustedText: "token exhausted",
1066
- },
1067
- },
1068
- },
1069
- }
1070
- ```
1071
-
1072
- Auto presence maps runtime availability to Discord status: healthy => online, degraded or unknown => idle, exhausted or unavailable => dnd. Optional text overrides:
1073
-
1074
- - `autoPresence.healthyText`
1075
- - `autoPresence.degradedText`
1076
- - `autoPresence.exhaustedText` (supports `{reason}` placeholder)
1077
-
1078
- </Accordion>
1079
-
1080
- <Accordion title="Approvals in Discord">
1081
- Discord supports button-based approval handling in DMs and can optionally post approval prompts in the originating channel.
1082
-
1083
- Config path:
1084
-
1085
- - `channels.discord.execApprovals.enabled`
1086
- - `channels.discord.execApprovals.approvers` (optional; falls back to `commands.ownerAllowFrom` when possible)
1087
- - `channels.discord.execApprovals.target` (`dm` | `channel` | `both`, default: `dm`)
1088
- - `agentFilter`, `sessionFilter`, `cleanupAfterResolve`
1089
-
1090
- Discord auto-enables native exec approvals when `enabled` is unset or `"auto"` and at least one approver can be resolved, either from `execApprovals.approvers` or from `commands.ownerAllowFrom`. Discord does not infer exec approvers from channel `allowFrom`, legacy `dm.allowFrom`, or direct-message `defaultTo`. Set `enabled: false` to disable Discord as a native approval client explicitly.
1091
-
1092
- For sensitive owner-only group commands such as `/diagnostics` and `/export-trajectory`, FengMing sends approval prompts and final results privately. It tries Discord DM first when the invoking owner has a Discord owner route; if that is not available, it falls back to the first available owner route from `commands.ownerAllowFrom`, such as Telegram.
1093
-
1094
- When `target` is `channel` or `both`, the approval prompt is visible in the channel. Only resolved approvers can use the buttons; other users receive an ephemeral denial. Approval prompts include the command text, so only enable channel delivery in trusted channels. If the channel ID cannot be derived from the session key, FengMing falls back to DM delivery.
1095
-
1096
- Discord also renders the shared approval buttons used by other chat channels. The native Discord adapter mainly adds approver DM routing and channel fanout.
1097
- When those buttons are present, they are the primary approval UX; FengMing
1098
- should only include a manual `/approve` command when the tool result says
1099
- chat approvals are unavailable or manual approval is the only path.
1100
- If the Discord native approval runtime is not active, FengMing keeps the
1101
- local deterministic `/approve <id> <decision>` prompt visible. If the
1102
- runtime is active but a native card cannot be delivered to any target,
1103
- FengMing sends a same-chat fallback notice with the exact `/approve`
1104
- command from the pending approval.
1105
-
1106
- Gateway auth and approval resolution follow the shared Gateway client contract (`plugin:` IDs resolve through `plugin.approval.resolve`; other IDs through `exec.approval.resolve`). Approvals expire after 30 minutes by default.
1107
-
1108
- See [Exec approvals](/tools/exec-approvals).
1109
-
1110
- </Accordion>
1111
- </AccordionGroup>
1112
-
1113
- ## Tools and action gates
1114
-
1115
- Discord message actions include messaging, channel admin, moderation, presence, and metadata actions.
1116
-
1117
- Core examples:
1118
-
1119
- - messaging: `sendMessage`, `readMessages`, `editMessage`, `deleteMessage`, `threadReply`
1120
- - reactions: `react`, `reactions`, `emojiList`
1121
- - moderation: `timeout`, `kick`, `ban`
1122
- - presence: `setPresence`
1123
-
1124
- The `event-create` action accepts an optional `image` parameter (URL or local file path) to set the scheduled event cover image.
1125
-
1126
- Action gates live under `channels.discord.actions.*`.
1127
-
1128
- Default gate behavior:
1129
-
1130
- | Action group | Default |
1131
- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------- |
1132
- | reactions, messages, threads, pins, polls, search, memberInfo, roleInfo, channelInfo, channels, voiceStatus, events, stickers, emojiUploads, stickerUploads, permissions | enabled |
1133
- | roles | disabled |
1134
- | moderation | disabled |
1135
- | presence | disabled |
1136
-
1137
- ## Components v2 UI
1138
-
1139
- FengMing uses Discord components v2 for exec approvals and cross-context markers. Discord message actions can also accept `components` for custom UI (advanced; requires constructing a component payload via the discord tool), while legacy `embeds` remain available but are not recommended.
1140
-
1141
- - `channels.discord.ui.components.accentColor` sets the accent color used by Discord component containers (hex).
1142
- - Set per account with `channels.discord.accounts.<id>.ui.components.accentColor`.
1143
- - `channels.discord.agentComponents.ttlMs` controls how long sent Discord component callbacks remain registered (default `1800000`, maximum `86400000`). Set per account with `channels.discord.accounts.<id>.agentComponents.ttlMs`.
1144
- - `embeds` are ignored when components v2 are present.
1145
- - Plain URL previews are suppressed by default. Set `suppressEmbeds: false` on a message action when a single outbound link should expand.
1146
-
1147
- Example:
1148
-
1149
- ```json5
1150
- {
1151
- channels: {
1152
- discord: {
1153
- ui: {
1154
- components: {
1155
- accentColor: "#5865F2",
1156
- },
1157
- },
1158
- },
1159
- },
1160
- }
1161
- ```
1162
-
1163
- ## Voice
1164
-
1165
- Discord has two distinct voice surfaces: realtime **voice channels** (continuous conversations) and **voice message attachments** (the waveform preview format). The gateway supports both.
1166
-
1167
- ### Voice channels
1168
-
1169
- Setup checklist:
1170
-
1171
- 1. Enable Message Content Intent in the Discord Developer Portal.
1172
- 2. Enable Server Members Intent when role/user allowlists are used.
1173
- 3. Invite the bot with `bot` and `applications.commands` scopes.
1174
- 4. Grant Connect, Speak, Send Messages, and Read Message History in the target voice channel.
1175
- 5. Enable native commands (`commands.native` or `channels.discord.commands.native`).
1176
- 6. Configure `channels.discord.voice`.
1177
-
1178
- Use `/vc join|leave|status` to control sessions. The command uses the account default agent and follows the same allowlist and group policy rules as other Discord commands.
1179
-
1180
- ```bash
1181
- /vc join channel:<voice-channel-id>
1182
- /vc status
1183
- /vc leave
1184
- ```
1185
-
1186
- To inspect the bot's effective permissions before joining, run:
1187
-
1188
- ```bash
1189
- fengming channels capabilities --channel discord --target channel:<voice-channel-id>
1190
- ```
1191
-
1192
- Auto-join example:
1193
-
1194
- ```json5
1195
- {
1196
- channels: {
1197
- discord: {
1198
- voice: {
1199
- enabled: true,
1200
- model: "openai/gpt-5.5",
1201
- autoJoin: [
1202
- {
1203
- guildId: "123456789012345678",
1204
- channelId: "234567890123456789",
1205
- },
1206
- ],
1207
- allowedChannels: [
1208
- {
1209
- guildId: "123456789012345678",
1210
- channelId: "234567890123456789",
1211
- },
1212
- ],
1213
- daveEncryption: true,
1214
- decryptionFailureTolerance: 24,
1215
- connectTimeoutMs: 30000,
1216
- reconnectGraceMs: 15000,
1217
- realtime: {
1218
- provider: "openai",
1219
- model: "gpt-realtime-2",
1220
- speakerVoice: "cedar",
1221
- },
1222
- },
1223
- },
1224
- },
1225
- }
1226
- ```
1227
-
1228
- Notes:
1229
-
1230
- - `voice.tts` overrides `messages.tts` for `stt-tts` voice playback only. Realtime modes use `voice.realtime.speakerVoice`.
1231
- - `voice.mode` controls the conversation path. The default is `agent-proxy`: a realtime voice front end handles turn timing, interruption, and playback, delegates substantive work to the routed FengMing agent through `fengming_agent_consult`, and treats the result like a typed Discord prompt from that speaker. `stt-tts` keeps the older batch STT plus TTS flow. `bidi` lets the realtime model converse directly while exposing `fengming_agent_consult` for the FengMing brain.
1232
- - `voice.agentSession` controls which FengMing conversation receives voice turns. Leave it unset for the voice channel's own session, or set `{ mode: "target", target: "channel:<text-channel-id>" }` to make the voice channel act as the microphone/speaker extension of an existing Discord text channel session such as `#maintainers`.
1233
- - `voice.model` overrides the FengMing agent brain for Discord voice responses and realtime consults. Leave it unset to inherit the routed agent model. It is separate from `voice.realtime.model`.
1234
- - `voice.followUsers` lets the bot join, move, and leave Discord voice with selected users. See [Follow users in voice](#follow-users-in-voice) for behavior rules and examples.
1235
- - `agent-proxy` routes speech through `discord-voice`, which preserves normal owner/tool authorization for the speaker and target session but hides the agent `tts` tool because Discord voice owns playback. By default, `agent-proxy` gives the consult full owner-equivalent tool access for owner speakers (`voice.realtime.toolPolicy: "owner"`) and strongly prefers consulting the FengMing agent before substantive answers (`voice.realtime.consultPolicy: "always"`). In that default `always` mode, the realtime layer does not auto-speak filler before the consult answer; it captures and transcribes speech, then speaks the routed FengMing answer. If multiple forced consult answers finish while Discord is still playing the first answer, later exact-speech answers are queued until playback idles instead of replacing speech mid-sentence.
1236
- - In `stt-tts` mode, STT uses `tools.media.audio`; `voice.model` does not affect transcription.
1237
- - In realtime modes, `voice.realtime.provider`, `voice.realtime.model`, and `voice.realtime.speakerVoice` configure the realtime audio session. For OpenAI Realtime 2 plus the Codex brain, use `voice.realtime.model: "gpt-realtime-2"` and `voice.model: "openai/gpt-5.5"`.
1238
- - Realtime voice modes include small `IDENTITY.md`, `USER.md`, and `SOUL.md` profile files in the realtime provider instructions by default so fast direct turns keep the same identity, user grounding, and persona as the routed FengMing agent. Set `voice.realtime.bootstrapContextFiles` to a subset to customize this, or `[]` to disable it. The supported realtime bootstrap files are limited to those profile files; `AGENTS.md` stays in the normal agent context. The injected profile context does not replace `fengming_agent_consult` for workspace work, current facts, memory lookup, or tool-backed actions.
1239
- - In OpenAI `agent-proxy` realtime mode, set `voice.realtime.requireWakeName: true` to keep Discord realtime voice silent until a transcript starts or ends with a wake name. Configured wake names must be one or two words. If `voice.realtime.wakeNames` is unset, FengMing uses the routed agent `name` plus `FengMing`, falling back to the agent id plus `FengMing`. Wake-name gating disables realtime provider auto-response, routes accepted turns through the FengMing agent consult path, and gives a short spoken acknowledgement when a leading wake name is recognized from partial transcription before the final transcript arrives.
1240
- - The OpenAI realtime provider accepts current Realtime 2 event names and legacy Codex-compatible aliases for output audio and transcript events, so compatible provider snapshots can drift without dropping assistant audio.
1241
- - `voice.realtime.bargeIn` controls whether Discord speaker-start events interrupt active realtime playback. If unset, it follows the realtime provider's input-audio interruption setting.
1242
- - `voice.realtime.minBargeInAudioEndMs` controls the minimum assistant playback duration before an OpenAI realtime barge-in truncates audio. Default: `250`. Set `0` for immediate interruption in low-echo rooms, or raise it for echo-heavy speaker setups.
1243
- - For an OpenAI voice on Discord playback, set `voice.tts.provider: "openai"` and choose a Text-to-speech voice under `voice.tts.providers.openai.speakerVoice`. `cedar` is a good masculine-sounding choice on the current OpenAI TTS model.
1244
- - Per-channel Discord `systemPrompt` overrides apply to voice transcript turns for that voice channel.
1245
- - Voice transcript turns derive owner status from Discord `allowFrom` (or `dm.allowFrom`) for owner-gated commands and channel actions. Agent tool visibility follows the configured tool policy for the routed session.
1246
- - Discord voice is opt-in for text-only configs; set `channels.discord.voice.enabled=true` (or keep an existing `channels.discord.voice` block) to enable `/vc` commands, the voice runtime, and the `GuildVoiceStates` gateway intent.
1247
- - `channels.discord.intents.voiceStates` can explicitly override voice-state intent subscription. Leave it unset for the intent to follow effective voice enablement.
1248
- - If `voice.autoJoin` has multiple entries for the same guild, FengMing joins the last configured channel for that guild.
1249
- - `voice.allowedChannels` is an optional residency allowlist. Leave it unset to allow `/vc join` into any authorized Discord voice channel. When set, `/vc join`, startup auto-join, and bot voice-state moves are restricted to the listed `{ guildId, channelId }` entries. Set it to an empty array to deny all Discord voice joins. If Discord moves the bot outside the allowlist, FengMing leaves that channel and rejoins the configured auto-join target when one is available.
1250
- - `voice.daveEncryption` and `voice.decryptionFailureTolerance` pass through to `@discordjs/voice` join options.
1251
- - `@discordjs/voice` defaults are `daveEncryption=true` and `decryptionFailureTolerance=24` if unset.
1252
- - FengMing uses the bundled `libopus-wasm` codec for Discord voice receive and realtime raw PCM playback. It ships a pinned libopus WebAssembly build and does not require native opus addons.
1253
- - `voice.connectTimeoutMs` controls the initial `@discordjs/voice` Ready wait for `/vc join` and auto-join attempts. Default: `30000`.
1254
- - `voice.reconnectGraceMs` controls how long FengMing waits for a disconnected voice session to begin reconnecting before destroying it. Default: `15000`.
1255
- - In `stt-tts` mode, voice playback does not stop just because another user starts speaking. To avoid feedback loops, FengMing ignores new voice capture while TTS is playing; speak after playback finishes for the next turn. Realtime modes forward speaker starts as barge-in signals to the realtime provider.
1256
- - In realtime modes, echo from speakers into an open mic can look like barge-in and interrupt playback. For echo-heavy Discord rooms, set `voice.realtime.providers.openai.interruptResponseOnInputAudio: false` to keep OpenAI from auto-interrupting on input audio. Add `voice.realtime.bargeIn: true` if you still want Discord speaker-start events to interrupt active playback. The OpenAI realtime bridge ignores playback truncations shorter than `voice.realtime.minBargeInAudioEndMs` as likely echo/noise and logs them as skipped instead of clearing Discord playback.
1257
- - `voice.captureSilenceGraceMs` controls how long FengMing waits after Discord reports a speaker has stopped before finalizing that audio segment for STT. Default: `2000`; raise this if Discord splits normal pauses into choppy partial transcripts.
1258
- - When ElevenLabs is the selected TTS provider, Discord voice playback uses streaming TTS and starts from the provider response stream. Providers without streaming support fall back to the synthesized temp-file path.
1259
- - FengMing also watches receive decrypt failures and auto-recovers by leaving/rejoining the voice channel after repeated failures in a short window.
1260
- - If receive logs repeatedly show `DecryptionFailed(UnencryptedWhenPassthroughDisabled)` after updating, collect a dependency report and logs. The bundled `@discordjs/voice` line includes the upstream padding fix from discord.js PR #11449, which closed discord.js issue #11419.
1261
- - `The operation was aborted` receive events are expected when FengMing finalizes a captured speaker segment; they are verbose diagnostics, not warnings.
1262
- - Verbose Discord voice logs include a bounded one-line STT transcript preview for each accepted speaker segment, so debugging shows both the user side and the agent reply side without dumping unbounded transcript text.
1263
- - In `agent-proxy` mode, forced consult fallback skips likely incomplete transcript fragments such as text ending in `...` or a trailing connector like `and`, plus obvious non-actionable closings like “be right back” or “bye”. Logs show `forced agent consult skipped reason=...` when this prevents a stale queued answer.
1264
-
1265
- ### Follow users in voice
1266
-
1267
- Use `voice.followUsers` when you want the Discord voice bot to stay with one or more known Discord users instead of joining a fixed channel at startup or waiting for `/vc join`.
1268
-
1269
- ```json5
1270
- {
1271
- channels: {
1272
- discord: {
1273
- voice: {
1274
- enabled: true,
1275
- followUsersEnabled: true,
1276
- followUsers: ["discord:123456789012345678"],
1277
- allowedChannels: [
1278
- {
1279
- guildId: "123456789012345678",
1280
- channelId: "234567890123456789",
1281
- },
1282
- ],
1283
- },
1284
- },
1285
- },
1286
- }
1287
- ```
1288
-
1289
- Behavior:
1290
-
1291
- - `followUsers` accepts raw Discord user IDs and `discord:<id>` values. FengMing normalizes both forms before matching voice-state events.
1292
- - `followUsersEnabled` defaults to `true` when `followUsers` is configured. Set it to `false` to keep the saved list but stop automatic voice following.
1293
- - When a followed user joins an allowed voice channel, FengMing joins that channel. When the user moves, FengMing moves with them. When the active followed user disconnects, FengMing leaves.
1294
- - If multiple followed users are in the same guild and the active followed user leaves, FengMing moves to another tracked followed user's channel before leaving the guild. If several followed users move at once, the latest observed voice-state event wins.
1295
- - `allowedChannels` still applies. A followed user in a disallowed channel is ignored, and a follow-owned session moves to another followed user or leaves.
1296
- - FengMing reconciles missed voice-state events on startup and at a bounded interval. Reconciliation samples configured guilds and caps REST lookups per run, so very large `followUsers` lists may take more than one interval to converge.
1297
- - If Discord or an admin moves the bot while it is following a user, FengMing rebuilds the voice session and preserves follow ownership when the destination is allowed. If the bot is moved outside `allowedChannels`, FengMing leaves and rejoins the configured target when one exists.
1298
- - DAVE receive recovery may leave and rejoin the same channel after repeated decrypt failures. Follow-owned sessions keep their follow ownership through that recovery path, so a later followed-user disconnect still leaves the channel.
1299
-
1300
- Choose between the join modes:
1301
-
1302
- - Use `followUsers` for personal or operator setups where the bot should automatically be in voice when you are.
1303
- - Use `autoJoin` for fixed-room bots that should be present even when no tracked user is in voice.
1304
- - Use `/vc join` for one-off joins or rooms where automatic voice presence would be surprising.
1305
-
1306
- Discord voice codec:
1307
-
1308
- - Voice receive logs show `discord voice: opus decoder: libopus-wasm`.
1309
- - Realtime playback encodes raw 48 kHz stereo PCM to Opus with the same bundled `libopus-wasm` package before handing packets to `@discordjs/voice`.
1310
- - File and provider-stream playback transcodes to raw 48 kHz stereo PCM with ffmpeg, then uses `libopus-wasm` for the Opus packet stream sent to Discord.
1311
-
1312
- STT plus TTS pipeline:
1313
-
1314
- - Discord PCM capture is converted to a WAV temp file.
1315
- - `tools.media.audio` handles STT, for example `openai/gpt-4o-mini-transcribe`.
1316
- - The transcript is sent through Discord ingress and routing while the response LLM runs with a voice-output policy that hides the agent `tts` tool and asks for returned text, because Discord voice owns final TTS playback.
1317
- - `voice.model`, when set, overrides only the response LLM for this voice-channel turn.
1318
- - `voice.tts` is merged over `messages.tts`; streaming-capable providers feed the player directly, otherwise the resulting audio file is played in the joined channel.
1319
-
1320
- Default agent-proxy voice-channel session example:
1321
-
1322
- ```json5
1323
- {
1324
- channels: {
1325
- discord: {
1326
- voice: {
1327
- enabled: true,
1328
- model: "openai/gpt-5.5",
1329
- followUsersEnabled: true,
1330
- followUsers: ["123456789012345678"],
1331
- realtime: {
1332
- provider: "openai",
1333
- model: "gpt-realtime-2",
1334
- speakerVoice: "cedar",
1335
- },
1336
- },
1337
- },
1338
- },
1339
- }
1340
- ```
1341
-
1342
- With no `voice.agentSession` block, each voice channel gets its own routed FengMing session. For example, `/vc join channel:234567890123456789` talks to the session for that Discord voice channel. The realtime model is only the voice front end; substantive requests are handed to the configured FengMing agent. If the realtime model produces a final transcript without calling the consult tool, FengMing forces the consult as a fallback so the default still behaves like talking to the agent.
1343
-
1344
- Legacy STT plus TTS example:
1345
-
1346
- ```json5
1347
- {
1348
- channels: {
1349
- discord: {
1350
- voice: {
1351
- enabled: true,
1352
- mode: "stt-tts",
1353
- model: "openai/gpt-5.4-mini",
1354
- tts: {
1355
- provider: "openai",
1356
- providers: {
1357
- openai: {
1358
- model: "gpt-4o-mini-tts",
1359
- speakerVoice: "cedar",
1360
- },
1361
- },
1362
- },
1363
- },
1364
- },
1365
- },
1366
- }
1367
- ```
1368
-
1369
- Realtime bidi example:
1370
-
1371
- ```json5
1372
- {
1373
- channels: {
1374
- discord: {
1375
- voice: {
1376
- enabled: true,
1377
- mode: "bidi",
1378
- model: "openai/gpt-5.5",
1379
- realtime: {
1380
- provider: "openai",
1381
- model: "gpt-realtime-2",
1382
- speakerVoice: "cedar",
1383
- toolPolicy: "safe-read-only",
1384
- consultPolicy: "always",
1385
- },
1386
- },
1387
- },
1388
- },
1389
- }
1390
- ```
1391
-
1392
- Voice as an extension of an existing Discord channel session:
1393
-
1394
- ```json5
1395
- {
1396
- channels: {
1397
- discord: {
1398
- voice: {
1399
- enabled: true,
1400
- mode: "agent-proxy",
1401
- model: "openai/gpt-5.5",
1402
- agentSession: {
1403
- mode: "target",
1404
- target: "channel:123456789012345678",
1405
- },
1406
- realtime: {
1407
- provider: "openai",
1408
- model: "gpt-realtime-2",
1409
- speakerVoice: "cedar",
1410
- },
1411
- },
1412
- },
1413
- },
1414
- }
1415
- ```
1416
-
1417
- In `agent-proxy` mode the bot joins the configured voice channel, but FengMing agent turns use the target channel's normal routed session and agent. The realtime voice session speaks the returned result back into the voice channel. The supervisor agent can still use normal message tools according to its tool policy, including sending a separate Discord message if that is the right action.
1418
-
1419
- While a delegated FengMing run is active, new Discord voice transcripts are treated as live run control before starting another agent turn. Phrases such as "status", "cancel that", "use the smaller fix", or "when you're done also check tests" are classified as status, cancel, steering, or follow-up input for the active session. Status, cancel, accepted steering, and follow-up outcomes are spoken back into the voice channel so the caller knows whether FengMing handled the request.
1420
-
1421
- Useful target forms:
1422
-
1423
- - `target: "channel:123456789012345678"` routes through a Discord text channel session.
1424
- - `target: "123456789012345678"` is treated as a channel target.
1425
- - `target: "dm:123456789012345678"` or `target: "user:123456789012345678"` routes through that direct-message session.
1426
-
1427
- Echo-heavy OpenAI Realtime example:
1428
-
1429
- ```json5
1430
- {
1431
- channels: {
1432
- discord: {
1433
- voice: {
1434
- enabled: true,
1435
- mode: "bidi",
1436
- model: "openai/gpt-5.5",
1437
- realtime: {
1438
- provider: "openai",
1439
- model: "gpt-realtime-2",
1440
- speakerVoice: "cedar",
1441
- bargeIn: true,
1442
- minBargeInAudioEndMs: 500,
1443
- consultPolicy: "always",
1444
- providers: {
1445
- openai: {
1446
- interruptResponseOnInputAudio: false,
1447
- },
1448
- },
1449
- },
1450
- },
1451
- },
1452
- },
1453
- }
1454
- ```
1455
-
1456
- Use this when the model hears its own Discord playback through an open mic, but you still want to interrupt it by speaking. FengMing keeps OpenAI from auto-interrupting on raw input audio, while `bargeIn: true` lets Discord speaker-start events and already-active speaker audio cancel active realtime responses before the next captured turn reaches OpenAI. Very early barge-in signals with `audioEndMs` below `minBargeInAudioEndMs` are treated as likely echo/noise and ignored so the model does not cut off at the first playback frame.
1457
-
1458
- Expected voice logs:
1459
-
1460
- - On join: `discord voice: joining ... voiceSession=... supervisorSession=... agentSessionMode=... voiceModel=... realtimeModel=...`
1461
- - On realtime start: `discord voice: realtime bridge starting ... autoRespond=false interruptResponse=false bargeIn=false minBargeInAudioEndMs=...`
1462
- - On speaker audio: `discord voice: realtime speaker turn opened ...`, `discord voice: realtime input audio started ... outputAudioMs=... outputActive=...`, and `discord voice: realtime speaker turn closed ... chunks=... discordBytes=... realtimeBytes=... interruptedPlayback=...`
1463
- - On skipped stale speech: `discord voice: realtime forced agent consult skipped reason=incomplete-transcript ...` or `reason=non-actionable-closing ...`
1464
- - On realtime response completion: `discord voice: realtime audio playback finishing reason=response.done ... audioMs=... chunks=...`
1465
- - On playback stop/reset: `discord voice: realtime audio playback stopped reason=... audioMs=... elapsedMs=... chunks=...`
1466
- - On realtime consult: `discord voice: realtime consult requested ... voiceSession=... supervisorSession=... question=...`
1467
- - On agent answer: `discord voice: agent turn answer ...`
1468
- - On queued exact speech: `discord voice: realtime exact speech queued ... queued=... outputAudioMs=... outputActive=...`, followed by `discord voice: realtime exact speech dequeued reason=player-idle ...`
1469
- - On barge-in detection: `discord voice: realtime barge-in detected source=speaker-start ...` or `discord voice: realtime barge-in detected source=active-speaker-audio ...`, followed by `discord voice: realtime barge-in requested reason=... outputAudioMs=... outputActive=...`
1470
- - On realtime interruption: `discord voice: realtime model interrupt requested client:response.cancel reason=barge-in`, followed by either `discord voice: realtime model audio truncated client:conversation.item.truncate reason=barge-in audioEndMs=...` or `discord voice: realtime model interrupt confirmed server:response.done status=cancelled ...`
1471
- - On ignored echo/noise: `discord voice: realtime model interrupt ignored client:conversation.item.truncate.skipped reason=barge-in audioEndMs=0 minAudioEndMs=250`
1472
- - On disabled barge-in: `discord voice: realtime capture ignored during playback (barge-in disabled) ...`
1473
- - On idle playback: `discord voice: realtime barge-in ignored reason=... outputActive=false ... playbackChunks=0`
1474
-
1475
- To debug cut-off audio, read the realtime voice logs as a timeline:
1476
-
1477
- 1. `realtime audio playback started` means Discord has begun playing assistant audio. The bridge starts counting assistant output chunks, Discord PCM bytes, provider realtime bytes, and synthesized audio duration from this point.
1478
- 2. `realtime speaker turn opened` marks a Discord speaker becoming active. If playback is already active and `bargeIn` is enabled, this can be followed by `barge-in detected source=speaker-start`.
1479
- 3. `realtime input audio started` marks the first actual audio frame received for that speaker turn. `outputActive=true` or a nonzero `outputAudioMs` here means the mic is sending input while assistant playback is still active.
1480
- 4. `barge-in detected source=active-speaker-audio` means FengMing saw live speaker audio while assistant playback was active. This is useful for distinguishing a real interruption from a Discord speaker-start event with no useful audio.
1481
- 5. `barge-in requested reason=...` means FengMing asked the realtime provider to cancel or truncate the active response. It includes `outputAudioMs`, `outputActive`, and `playbackChunks` so you can see how much assistant audio had actually played before the interruption.
1482
- 6. `realtime audio playback stopped reason=...` is the local Discord playback reset point. The reason says who stopped playback: `barge-in`, `player-idle`, `provider-clear-audio`, `forced-agent-consult`, `stream-close`, or `session-close`.
1483
- 7. `realtime speaker turn closed` summarizes the captured input turn. `chunks=0` or `hasAudio=false` means the speaker turn opened but no usable audio reached the realtime bridge. `interruptedPlayback=true` means that input turn overlapped assistant output and triggered barge-in logic.
1484
-
1485
- Useful fields:
1486
-
1487
- - `outputAudioMs`: assistant audio duration generated by the realtime provider before the log line.
1488
- - `audioMs`: assistant audio duration that FengMing counted before playback stopped.
1489
- - `elapsedMs`: wall-clock time between opening and closing the playback stream or speaker turn.
1490
- - `discordBytes`: 48 kHz stereo PCM bytes sent to or received from Discord voice.
1491
- - `realtimeBytes`: provider-format PCM bytes sent to or received from the realtime provider.
1492
- - `playbackChunks`: assistant audio chunks forwarded to Discord for the active response.
1493
- - `sinceLastAudioMs`: gap between the last captured speaker audio frame and the speaker turn closing.
1494
-
1495
- Common patterns:
1496
-
1497
- - Immediate cut-off with `source=active-speaker-audio`, small `outputAudioMs`, and the same user nearby usually points to speaker echo entering the mic. Raise `voice.realtime.minBargeInAudioEndMs`, lower speaker volume, use headphones, or set `voice.realtime.providers.openai.interruptResponseOnInputAudio: false`.
1498
- - `source=speaker-start` followed by `speaker turn closed ... hasAudio=false` means Discord reported a speaker start but no audio reached FengMing. That can be a transient Discord voice event, noise gate behavior, or a client briefly keying the mic.
1499
- - `audio playback stopped reason=stream-close` without a nearby barge-in or `provider-clear-audio` means the local Discord playback stream ended unexpectedly. Check the preceding provider and Discord player logs.
1500
- - `capture ignored during playback (barge-in disabled)` means FengMing intentionally dropped input while assistant audio was active. Enable `voice.realtime.bargeIn` if you want speech to interrupt playback.
1501
- - `barge-in ignored ... outputActive=false` means Discord or provider VAD reported speech, but FengMing had no active playback to interrupt. This should not cut off audio.
1502
-
1503
- Credentials are resolved per component: LLM route auth for `voice.model`, STT auth for `tools.media.audio`, TTS auth for `messages.tts`/`voice.tts`, and realtime provider auth for `voice.realtime.providers` or the provider's normal auth config.
1504
-
1505
- ### Voice messages
1506
-
1507
- Discord voice messages show a waveform preview and require OGG/Opus audio. FengMing generates the waveform automatically, but needs `ffmpeg` and `ffprobe` on the gateway host to inspect and convert.
1508
-
1509
- - Provide a **local file path** (URLs are rejected).
1510
- - Omit text content (Discord rejects text + voice message in the same payload).
1511
- - Any audio format is accepted; FengMing converts to OGG/Opus as needed.
1512
-
1513
- ```bash
1514
- message(action="send", channel="discord", target="channel:123", path="/path/to/audio.mp3", asVoice=true)
1515
- ```
1516
-
1517
- ## Troubleshooting
1518
-
1519
- <AccordionGroup>
1520
- <Accordion title="Used disallowed intents or bot sees no guild messages">
1521
-
1522
- - enable Message Content Intent
1523
- - enable Server Members Intent when you depend on user/member resolution
1524
- - restart gateway after changing intents
1525
-
1526
- </Accordion>
1527
-
1528
- <Accordion title="Guild messages blocked unexpectedly">
1529
-
1530
- - verify `groupPolicy`
1531
- - verify guild allowlist under `channels.discord.guilds`
1532
- - if guild `channels` map exists, only listed channels are allowed
1533
- - verify `requireMention` behavior and mention patterns
1534
-
1535
- Useful checks:
1536
-
1537
- ```bash
1538
- fengming doctor
1539
- fengming channels status --probe
1540
- fengming logs --follow
1541
- ```
1542
-
1543
- </Accordion>
1544
-
1545
- <Accordion title="Require mention false but still blocked">
1546
- Common causes:
1547
-
1548
- - `groupPolicy="allowlist"` without matching guild/channel allowlist
1549
- - `requireMention` configured in the wrong place (must be under `channels.discord.guilds` or channel entry)
1550
- - sender blocked by guild/channel `users` allowlist
1551
-
1552
- </Accordion>
1553
-
1554
- <Accordion title="Long-running Discord turns or duplicate replies">
1555
-
1556
- Typical logs:
1557
-
1558
- - `Slow listener detected ...`
1559
- - `stuck session: sessionKey=agent:...:discord:... state=processing ...`
1560
-
1561
- Discord gateway queue knobs:
1562
-
1563
- - single-account: `channels.discord.eventQueue.listenerTimeout`
1564
- - multi-account: `channels.discord.accounts.<accountId>.eventQueue.listenerTimeout`
1565
- - this only controls Discord gateway listener work, not agent turn lifetime
1566
-
1567
- Discord does not apply a channel-owned timeout to queued agent turns. Message listeners hand off immediately, and queued Discord runs preserve per-session ordering until the session/tool/runtime lifecycle completes or aborts the work.
1568
-
1569
- ```json5
1570
- {
1571
- channels: {
1572
- discord: {
1573
- accounts: {
1574
- default: {
1575
- eventQueue: {
1576
- listenerTimeout: 120000,
1577
- },
1578
- },
1579
- },
1580
- },
1581
- },
1582
- }
1583
- ```
1584
-
1585
- </Accordion>
1586
-
1587
- <Accordion title="Gateway metadata lookup timeout warnings">
1588
- FengMing fetches Discord `/gateway/bot` metadata before connecting. Transient failures fall back to Discord's default gateway URL and are rate-limited in logs.
1589
-
1590
- Metadata timeout knobs:
1591
-
1592
- - single-account: `channels.discord.gatewayInfoTimeoutMs`
1593
- - multi-account: `channels.discord.accounts.<accountId>.gatewayInfoTimeoutMs`
1594
- - env fallback when config is unset: `FENGMING_DISCORD_GATEWAY_INFO_TIMEOUT_MS`
1595
- - default: `30000` (30 seconds), max: `120000`
1596
-
1597
- </Accordion>
1598
-
1599
- <Accordion title="Gateway READY timeout restarts">
1600
- FengMing waits for Discord's gateway `READY` event during startup and after runtime reconnects. Multi-account setups with startup staggering can need a longer startup READY window than the default.
1601
-
1602
- READY timeout knobs:
1603
-
1604
- - startup single-account: `channels.discord.gatewayReadyTimeoutMs`
1605
- - startup multi-account: `channels.discord.accounts.<accountId>.gatewayReadyTimeoutMs`
1606
- - startup env fallback when config is unset: `FENGMING_DISCORD_READY_TIMEOUT_MS`
1607
- - startup default: `15000` (15 seconds), max: `120000`
1608
- - runtime single-account: `channels.discord.gatewayRuntimeReadyTimeoutMs`
1609
- - runtime multi-account: `channels.discord.accounts.<accountId>.gatewayRuntimeReadyTimeoutMs`
1610
- - runtime env fallback when config is unset: `FENGMING_DISCORD_RUNTIME_READY_TIMEOUT_MS`
1611
- - runtime default: `30000` (30 seconds), max: `120000`
1612
-
1613
- </Accordion>
1614
-
1615
- <Accordion title="Permissions audit mismatches">
1616
- `channels status --probe` permission checks only work for numeric channel IDs.
1617
-
1618
- If you use slug keys, runtime matching can still work, but probe cannot fully verify permissions.
1619
-
1620
- </Accordion>
1621
-
1622
- <Accordion title="DM and pairing issues">
1623
-
1624
- - DM disabled: `channels.discord.dm.enabled=false`
1625
- - DM policy disabled: `channels.discord.dmPolicy="disabled"` (legacy: `channels.discord.dm.policy`)
1626
- - awaiting pairing approval in `pairing` mode
1627
-
1628
- </Accordion>
1629
-
1630
- <Accordion title="Bot to bot loops">
1631
- By default bot-authored messages are ignored.
1632
-
1633
- If you set `channels.discord.allowBots=true`, use strict mention and allowlist rules to avoid loop behavior.
1634
- Prefer `channels.discord.allowBots="mentions"` to only accept bot messages that mention the bot.
1635
-
1636
- FengMing also ships shared [bot loop protection](/channels/bot-loop-protection). Whenever `allowBots` lets bot-authored messages reach dispatch, Discord maps the inbound event to `(account, channel, bot pair)` facts and the generic pair guard suppresses the pair after it crosses the configured event budget. The guard prevents runaway two-bot loops that previously had to be stopped by Discord rate limits; it does not affect single-bot deployments or one-shot bot replies that stay under the budget.
1637
-
1638
- Default settings (active when `allowBots` is set):
1639
-
1640
- - `maxEventsPerWindow: 20` -- bot pair can exchange 20 messages within the sliding window
1641
- - `windowSeconds: 60` -- sliding window length
1642
- - `cooldownSeconds: 60` -- once the budget trips, every additional bot-to-bot message in either direction is dropped for one minute
1643
-
1644
- Configure the shared default once under `channels.defaults.botLoopProtection`, then override Discord when a legitimate workflow needs more headroom. Precedence is:
1645
-
1646
- - `channels.discord.accounts.<account>.botLoopProtection`
1647
- - `channels.discord.botLoopProtection`
1648
- - `channels.defaults.botLoopProtection`
1649
- - built-in defaults
1650
-
1651
- Discord uses the generic `maxEventsPerWindow`, `windowSeconds`, and `cooldownSeconds` keys.
1652
-
1653
- ```json5
1654
- {
1655
- channels: {
1656
- defaults: {
1657
- botLoopProtection: {
1658
- maxEventsPerWindow: 20,
1659
- windowSeconds: 60,
1660
- cooldownSeconds: 60,
1661
- },
1662
- },
1663
- discord: {
1664
- // Optional Discord-wide override. Account blocks override individual
1665
- // fields and inherit omitted fields from here.
1666
- botLoopProtection: {
1667
- maxEventsPerWindow: 4,
1668
- },
1669
- accounts: {
1670
- mantis: {
1671
- // Mantis listens to other bots only when they mention her.
1672
- allowBots: "mentions",
1673
- },
1674
- molty: {
1675
- // Molty listens to all bot-authored Discord messages.
1676
- allowBots: true,
1677
- mentionAliases: {
1678
- // Lets Molty write a Mantis Discord mention with the configured user id.
1679
- Mantis: "MANTIS_DISCORD_USER_ID",
1680
- },
1681
- botLoopProtection: {
1682
- // Allow up to five messages per minute before suppressing the pair.
1683
- maxEventsPerWindow: 5,
1684
- windowSeconds: 60,
1685
- cooldownSeconds: 90,
1686
- },
1687
- },
1688
- },
1689
- },
1690
- },
1691
- }
1692
- ```
1693
-
1694
- </Accordion>
1695
-
1696
- <Accordion title="Voice STT drops with DecryptionFailed(...)">
1697
-
1698
- - keep FengMing current (`fengming update`) so the Discord voice receive recovery logic is present
1699
- - confirm `channels.discord.voice.daveEncryption=true` (default)
1700
- - start from `channels.discord.voice.decryptionFailureTolerance=24` (upstream default) and tune only if needed
1701
- - watch logs for:
1702
- - `discord voice: DAVE decrypt failures detected`
1703
- - `discord voice: repeated decrypt failures; attempting rejoin`
1704
- - if failures continue after automatic rejoin, collect logs and compare against the upstream DAVE receive history in [discord.js #11419](https://github.com/discordjs/discord.js/issues/11419) and [discord.js #11449](https://github.com/discordjs/discord.js/pull/11449)
1705
-
1706
- </Accordion>
1707
- </AccordionGroup>
1708
-
1709
- ## Configuration reference
1710
-
1711
- Primary reference: [Configuration reference - Discord](/gateway/config-channels#discord).
1712
-
1713
- <Accordion title="High-signal Discord fields">
1714
-
1715
- - startup/auth: `enabled`, `token`, `accounts.*`, `allowBots`
1716
- - policy: `groupPolicy`, `dm.*`, `guilds.*`, `guilds.*.channels.*`
1717
- - command: `commands.native`, `commands.useAccessGroups`, `configWrites`, `slashCommand.*`
1718
- - event queue: `eventQueue.listenerTimeout` (listener budget), `eventQueue.maxQueueSize`, `eventQueue.maxConcurrency`
1719
- - gateway: `gatewayInfoTimeoutMs`, `gatewayReadyTimeoutMs`, `gatewayRuntimeReadyTimeoutMs`
1720
- - reply/history: `replyToMode`, `historyLimit`, `dmHistoryLimit`, `dms.*.historyLimit`
1721
- - delivery: `textChunkLimit`, `chunkMode`, `maxLinesPerMessage`
1722
- - streaming: `streaming` (legacy alias: `streamMode`), `streaming.preview.toolProgress`, `draftChunk`, `blockStreaming`, `blockStreamingCoalesce`
1723
- - media/retry: `mediaMaxMb` (caps outbound Discord uploads, default `100MB`), `retry`
1724
- - actions: `actions.*`
1725
- - presence: `activity`, `status`, `activityType`, `activityUrl`
1726
- - UI: `ui.components.accentColor`
1727
- - features: `threadBindings`, top-level `bindings[]` (`type: "acp"`), `pluralkit`, `execApprovals`, `intents`, `agentComponents.enabled`, `agentComponents.ttlMs`, `heartbeat`, `responsePrefix`
1728
-
1729
- </Accordion>
1730
-
1731
- ## Safety and operations
1732
-
1733
- - Treat bot tokens as secrets (`DISCORD_BOT_TOKEN` preferred in supervised environments).
1734
- - Grant least-privilege Discord permissions.
1735
- - If command deploy/state is stale, restart gateway and re-check with `fengming channels status --probe`.
1736
-
1737
- ## Related
1738
-
1739
- <CardGroup cols={2}>
1740
- <Card title="Pairing" icon="link" href="/channels/pairing">
1741
- Pair a Discord user to the gateway.
1742
- </Card>
1743
- <Card title="Groups" icon="users" href="/channels/groups">
1744
- Group chat and allowlist behavior.
1745
- </Card>
1746
- <Card title="Channel routing" icon="route" href="/channels/channel-routing">
1747
- Route inbound messages to agents.
1748
- </Card>
1749
- <Card title="Security" icon="shield" href="/gateway/security">
1750
- Threat model and hardening.
1751
- </Card>
1752
- <Card title="Multi-agent routing" icon="sitemap" href="/concepts/multi-agent">
1753
- Map guilds and channels to agents.
1754
- </Card>
1755
- <Card title="Slash commands" icon="terminal" href="/tools/slash-commands">
1756
- Native command behavior.
1757
- </Card>
1758
- </CardGroup>