feat(channel-runtime): Phase 1 — Lark bot end-to-end with direct webhook#172
feat(channel-runtime): Phase 1 — Lark bot end-to-end with direct webhook#172
Conversation
- 新增 ChannelRegistrationToolSource 和 ChannelRegistrationTool,使 NyxIdChatGAgent 能够通过 channel_registrations 工具管理频道机器人注册 - 引入 ChannelMetadataKeys 类,统一频道运行时上下文的元数据键,用于在 ChatRequestEvent.Metadata 中传递频道特定信息 - 更新 NyxIdApiClient.ListConversationRoutesAsync 以支持按 botId 筛选对话路由 - 扩展 NyxIdChannelBotsTool,增加 update_route 操作和更多平台(Lark、Discord)的注册字段支持,并支持群聊中的按发送者路由 - 改进 ChannelCallbackEndpoints,添加基于内存缓存的 webhook 去重机制,防止平台重试导致的重复处理 - 更新系统提示文档,提供多平台(Telegram、Lark、Discord)的频道机器人设置指南
- 注册后轮询新生成的ID,减少用户手动查询步骤 - 删除操作需二次确认,防止误删 - 更新返回消息以提供更明确的指引
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 03a45051a3
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (cache.TryGetValue(dedupeKey, out _)) | ||
| { |
There was a problem hiding this comment.
Make webhook dedup reservation atomic
The dedup logic performs TryGetValue and Set as separate steps, so two identical callbacks arriving at nearly the same time can both observe a cache miss and both dispatch to the actor, leading to duplicate processing/replies. This violates the intended “block concurrent duplicates” behavior; reserve the dedup key atomically (or via a per-key lock) before starting dispatch.
Useful? React with 👍 / 👎.
| var all = await _queryPort.QueryAllAsync(ct); | ||
| var newEntry = all.FirstOrDefault(e => !existingIds.Contains(e.Id)); | ||
| if (newEntry != null) |
There was a problem hiding this comment.
Correlate register polling to the submitted command
RegisterAsync infers the new registration by selecting the first ID absent from a pre-dispatch snapshot, which is unsafe under concurrent registrations: two callers can both detect the same "first new" row and one user gets another user's registration_id/URLs. This can misconfigure webhooks and break follow-up actions; the lookup needs a command-level correlation key (or another unique match) rather than global set-difference.
Useful? React with 👍 / 👎.
Codecov Report✅ All modified and coverable lines are covered by tests. @@ Coverage Diff @@
## dev #172 +/- ##
=======================================
Coverage 81.67% 81.68%
=======================================
Files 739 739
Lines 46986 46986
Branches 6233 6233
=======================================
+ Hits 38378 38382 +4
+ Misses 5916 5914 -2
+ Partials 2692 2690 -2
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
Summary
Aevatar Channel Runtime Phase 1: 让 Lark bot 端到端跑通。
架构背景
按照 NyxID #191 + aevatar #113 的架构决策:
CEO 决策(#204): "NyxID 零修改。身份映射由 Aevatar Channel Runtime 在业务层处理。"
本 PR 改动
Bug 修复:
ChannelCallbackEndpoints.cs:229webhook URL 插值/{null}bug可靠性增强:
NyxId Chat 工具:
channel_registrationstool(list/register/delete),NyxId chat agent 可以自主完成 channel 配置confirm=true,首次调用返回详情供用户确认代码质量:
ChannelMetadataKeys常量类,替换 hardcoded string keysAddMemoryCache()+ChannelRegistrationToolSource设计文档
完整设计文档:
~/.gstack/projects/aevatarAI-aevatar/zhaoyiqi-feature-bot-design-20260410-220049.md三阶段渐进式交付:
相关 Issues
改动文件
ChannelCallbackEndpoints.csChannelUserGAgent.csServiceCollectionExtensions.csChannelMetadataKeys.csChannelRegistrationTool.csChannelRegistrationToolSource.csTest plan
🤖 Generated with Claude Code