feat: 新增 Discord 渠道接入 - #82
Open
aurevian-biz wants to merge 26 commits into
Open
Conversation
Collaborator
|
@aurevian-biz |
Author
|
我没有主观故意性,应该是提交时没修改git的帐号,周四我会修改后再次提交。 |
Collaborator
|
好的,十分感谢 |
aurevian-biz
force-pushed
the
feat/discord-channel
branch
from
August 14, 2026 08:28
a8e8ab7 to
20e5adc
Compare
Author
|
已经将作者和提交者修改完成。 |
- SUPPORTED_CHANNELS/CHANNEL_META 增加 discord 条目 - channels/__init__.py 注册 DiscordStreamManager 单例与启停 - service_identity 增加 discord 标签与账号稳定键 - service_intake 将 discord 纳入 durable 渠道与 replay 解码
aurevian-biz
force-pushed
the
feat/discord-channel
branch
from
August 14, 2026 09:28
20e5adc to
5872d99
Compare
为 Discord 渠道 8 项功能扩展奠定共享地基: - ChannelCapability 枚举 + ChannelCapabilityAdapter 可选协议, 存量渠道自动降级为空能力集 - ChannelDelivery 新增 payload_json/thread_id/batch_id/delivery_kind 字段 - ChannelInboundEvent 新增 thread_id/mention_user_ids/command 字段(信封 v2) - SQLite 就地迁移 _migrate_channel_envelope_v2_schema, 幂等补列 - channel_capabilities_of 双防御(callable+isinstance) 保证向后兼容 本地验证: pytest 9 个新测试通过, ruff 通过
按 design-discord-channel-features.md 实现全部功能:
- 原生斜杠命令: commands.Bot+CommandTree 注册 5 命令, 回调走 durable inbox 管道复用幂等/重试
- 线程: 入站识别 is_thread/thread_id, 出站 target.thread_id 优先, 白名单按父频道
- 批处理: TokenBucket 限流(容量5/每5s补1) + BatchJob 状态机 + 幂等键 batch:{job}:{index}
- 回填: fetch_history REST 分页 + status=backfilled 不触发 agent + message_id 幂等 + web 合并可见
- 权限白名单: config_json.allowlist 六重 fence 校验, 拒绝落库 rejected 可审计
- typing: send_typing(每8s) + TypingManager 三进门禁(hasattr+能力声明+features 开关)
- 语音: VOICE 默认关闭, ffmpeg 缺失自动不声明, outbox delivery_kind==voice 分派
- 富媒体: embeds(≤10裁剪)+files(≤8MiB multipart)+payload_json 全链路传递+入站附件提取
另修复真实链路缺陷: ChannelInbound dataclass 无 .get() 致回填必崩,
新增 _backfill_message_dict 归一化; features.slash_commands/typing 开关接线。
本地验证: pytest 相关集合 1511 passed(5 预存/flaky 与本次无关), ruff 通过
- DiscordFeatureConfig: 8 功能开关(features) + 白名单编辑器(mode/ID 列表) + 回填触发按钮 + 批量发送面板(轮询进度) - ChannelMessageAttachments: 会话消息附件卡片渲染(image/pdf/文件名) - ChannelsPage 挂载功能配置 section 与附件渲染分支 - types: ChannelAllowlistConfig/ChannelFeatureFlags 等 6 个新类型, config_json 收紧为 ChannelBindingConfigJson - i18n: 补充 33 条 Discord 功能区词条 本地验证: build 通过, vitest 26 files/97 tests 通过
agent 运行生成的 harness 工作区文件此前只在 web 端展示(harness_artifacts 元数据),渠道投递所需的 channel_payload.files 载荷无生产写入方,导致 Discord 渠道永远只收到纯文本回复。 在 stage_channel_delivery 中对 discord 渠道补齐桥接:读取工作区文件字节 (base64),受 8MiB 单文件上限约束,读取失败静默降级;仅 discord 渠道生效, 微信/飞书/钉钉/企微路径零影响;显式 channel_payload 优先于桥接。 新增 test_channel_harness_payload.py 覆盖构造/超限跳过/非 discord 不桥接/ 文件缺失降级/显式载荷优先。
此前 Web 端提问从不外投,仅 assistant 回复经 outbox 回投 Discord, 方向不对称。新增 stage_user_message_mirror 登记 kind=user_mirror 投递,接入 harness_v2_engine.run 与定时任务草稿路径;仅 web 来源 且会话完整锚定渠道时触发,幂等按 message.id 去重,失败静默不 影响 Web 主流程,渠道来源不镜像以防回声。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
数字员工现在可以接入 Discord 作为第 5 个消息渠道,并具备完整的渠道能力矩阵:原生斜杠命令、线程(含自动建线程)、批量发送、历史回填、权限白名单、连接/typing 指示、语音投递、富媒体(embeds/附件)发送。此前接入渠道仅支持微信、企业微信、飞书、钉钉;本 PR 复用现有渠道无关内核(入站 staging、出站 outbox、身份服务、凭证生命周期、能力声明协议)。
实现方式
完全遵循既有渠道接入模式,无内核结构性改动;新增能力通过
ChannelCapability能力声明协议(channel_capabilities_of空集自动降级,存量渠道零影响)与config_json结构化配置(allowlist/features/batch/backfill,向后兼容)扩展:backend/app/channels/adapters/discord.py):normalize/send/start_ingress/stop_ingress协议实现 + 每绑定一线程的DiscordStreamManager(daemon 线程 + 独立 event loop + 5s reconcile),错误分类沿用PermanentError/TransientError分层service_discord_inbox.py+discord_runtime.py):stage-before-ACK 模式,(binding_id, event_id)幂等,绑定围栏校验(channel/active/revision/account-key/白名单),envelope v2(thread_id/mention_user_ids/command)service_outbox.py+batch_service.py+typing_manager.py):payload_json全链路传递(content/embeds/files/audio)、delivery_kind(text/voice)、TokenBucket 限流(容量 5/每 5s 补 1)、BatchJob 状态机、batch:{job_id}:{index}幂等键、TypingManager 每 8s 触发commands.Bot+app_commands.CommandTree注册 5 命令(/employee /switch /current /help /bind),回调序列化为文本指令走 durable inbox 管道(幂等/重试免费获得),parse_command单一事实来源,按 guild 同步is_thread(session_id=thread_id)、出站target.thread_id优先、白名单按父频道;自动建线程(auto_thread 开关,默认关):群聊 reply 投递前POST /channels/{id}/threads(type:11)建线程,线程名三级解析(metadata.thread_name → 首条用户消息 → 兜底),建线程失败自动降级主频道并标记 blocked 不重试fetch_history(REST 分页 limit=100)+status=backfilled不触发 agent + message_id 幂等 + web 会话消息页合并展示回填数据config_json.allowlist(mode/guild/channel/user_ids + deny,deny 优先)+ 入站 fence 校验 + 拒绝落库 rejected 可审计attachment_bridge复用管道POST /channels/{id}/typingGET /users/@me)、discord:bot:{len}:{id}外部账号键、_quiesce_binding_or_409暂停/恢复衔接DiscordSetup.tsx配置界面 +DiscordFeatureConfig.tsx功能配置面板(8 开关 + 白名单编辑器 + 批量发送 + 回填按钮 + 附件渲染),i18n 全量词条关键设计决策
ChannelCapabilityStrEnum + 可选协议混入status=backfilled事件写库验证
npm run build(tsc + vite)通过;i18n:check 通过connected=True,Discord 发消息 → AgentLoop 回复delivered(群聊 + DM 双场景);harness 产物文件实际投递到 Discord 附件;真实 bug 修复(文件未投递/开关回显丢失)均经 Oracle 复核闭环测试清单
test_channel_discord.py:normalize/send/validate/stage 幂等/fence/stream manager 生命周期/nonce 映射test_discord_features.py(+460 行):typing/白名单/线程/回填/富媒体/命令树/语音/create_threadtest_channel_outbox.py(+700 行):payload_json 传递/voice 分派/自动建线程矩阵/降级与幂等test_channel_batch_service.py/test_channel_batch_backfill_api.py:TokenBucket/BatchJob/回填 APItest_channel_typing_manager.py/test_channel_capabilities.py:typing 双门禁/能力协议test_channel_harness_payload.py:harness 产物→附件桥接(超限跳过/非 discord 不构造/显式优先)test_discord_api.py:凭证端点(200/400/409/502/凭证不泄漏)DiscordSetup.test.tsx/DiscordFeatureConfig.test.tsx(开关回显/保存透传/白名单编辑器)风险与说明
content为空(UI 有启用提示)