- 变更规模:新增 514 / 修改 62 / 重命名 155 / 删除 4(归档重组与文档轮次) - .gitignore 修:`归档/**/db-cwd归一-备份-*/` —— 原规则写绝对层级(归档/db-cwd归一-…), 目录搬进 归档/配置与备份/ 后**静默失效**,43 MB 的 DB 备份又变成未跟踪 - .gitignore 补:嵌套 git 内部数据(归档/内嵌git-20261008/、归档/skills-git-旧线-20261007/dotgit-原样移出/) - .gitignore 补:运行态与部署副本(.workbuddy/collab/、.workbuddy/tools/、.workbuddy/.load-pending、.workbuddy/tmp-*) - .gitignore 补:备份件(*.bak-*) - 未跟踪文件从 2190 降到 890(其余为 归档/ 归档件与 .workbuddy/memory/ 知识文件,按口径入库)
9.1 KiB
交付物 · IM 插件接入完备性审计(2026-09-25)
工作区:
E:/ProgramData/AIProject/aliyun-dsh-server|代码基线:D:/github/dsh_shenxian审计口径:用户两问 —— ① 插件调用用户自己配置的模型 ② IM 是否还需完善 / 插件如何接入 / 接口接入是否已完善 方法:只读取证(grep 实例化点与调用点),⛔ 不猜
⚠️ 本文已被后续落地推翻(2026-09-26 加此状态块,正文保留作过程档案)
本文写于 2026-09-25,当时结论 = "跨进程那一层不存在 ⇒ 插件今天接不进来"。该结论已作废。
本文当时说 现在的实情 依据 §0-2 / §4 G1「扩展点注册无跨进程通路」 ✅ 已通 —— /api/im/plugins/register+ SDKready()真 HTTP e2e §4 G2「入向回调是进程内函数调用」 ✅ 已通 —— 反向通道: onSpeakRule()(同步,带onTimeout)+onEvent()(异步,有界队列)2026-09-26 落地 · e2e 28 例 fail 0 · 已部署 47 §4 G3「出向投递无 HTTP 面」 ✅ 已通 —— out/frame+out/message同上 §4 G5「 ImDataPort按 pluginId 装配未做」✅ 已做(运行时取数口已落地;⚠️ 代码就绪,尚未部署 47/106 做真机验收) 交付物/插件数据面-运行时取数口落地-20260925.md§6「建议的桥(待拍板)」 ✅ 已拍板并已实现 「都需要实现完整,才能让插件接入」 🔴 权威口径 ⇒
dsh-server-docs/01-规范/09-IM插件SDK与扩展点契约.md(现为 §1–§16 完整契约); 上手指南 ⇒ 其 §12;可跑示例 ⇒poc/business-plugins-im/minimal-callbacks/。 ⛔ 本文只有历史价值(记录"当时为什么判断缺一层"),⛔ 不得据其设计。
§0 判定(三句话)
- 插件本身没问题:IM 内核、插件分发、数据面、用户自配模型 —— 这四块都已完善、可用。
- 🔴 但"接口接入"未完善:插件跑在用户实例内,而 IM 扩展点宿主装配在平台进程 ⇒ 两者跨进程, 而跨进程那一层不存在。⇒ 需要服务端逻辑的脚本型插件,今天接不进来。
- 缺的不是能力,是桥。七点扩展点 + 出向端口的契约与实现都在(含 2026-09-25 新增), 缺的是"实例内插件 ↔ 平台 IM 宿主"的协议。
§1 你第 1 点的架构含义(关键)
「插件调用用户自己配置的模型」这句话,把插件的位置钉死在用户实例内:
用户配模型 → credential_vault(route / base_url / api / models)
→ spawn 时写进实例的 $DSH_HOME/settings.yaml + .credentials.yaml
→ ✅ 只有**实例内**能拿到(平台进程拿不到,那是别人的模型)
(依据:src/db/schema.ts:261-278 的 V6 注释 —— 逐字写明"spawn 时按这四样写"。)
⇒ 🔴 推论:插件必须跑在实例内。这也与分发链路一致(08 §5:profile 写 link:<共享层路径>
→ pnpm 建链接 → 实例进程加载)。插件在实例内、IM 内核在平台 —— 这是本审计全部结论的起点。
§2 完备性矩阵(面 × 状态)
| 面 | 通路形态 | 状态 |
|---|---|---|
| IM 内核(房间 / 成员 / 消息 / 游标 / presence / 扇出 / 两档传输) | 平台进程 | ✅ 完善 |
插件分发(上传 → 检测 → 建库 → 发布 → 实例 link: 装配) |
平台侧 | ✅ 完善 |
| 插件数据面(读写自己的库) | 实例内插件 HTTP → 平台 /api/im/data/*(带 x-dsh-im-plugin-id) |
✅ 完善 |
| 用户自配模型 | credential_vault → spawn 写实例配置 |
✅ 完善(官方机制) |
| 客户端 UI 接管(会话内 tab) | 实例前端走官方 slot | ✅ 完善(E 单) |
| 面板清单 / 面板动作端点 | 平台侧 HTTP | ✅ 已加(2026-09-25) |
| 🔴 扩展点注册(房间类型 / 载荷 / 角色 / 发言规则 / bot / 事件 / 面板 / 出向) | 实例内插件 → 平台宿主 | ❌ 无通路 |
🔴 入向回调(checkSpeak / onEvent / renderPanel) |
平台 → 实例内插件 | ❌ 无通路(现为进程内函数调用) |
🔴 出向投递(frame / message) |
实例内插件 → 平台 | ❌ 无 HTTP 面 |
| 插件清单来源(谁注册、何时、版本) | — | ❌ 未定 |
ImDataPort 按 pluginId 装配 / approvedRoomTypes 来源 |
— | ❌ 未做(面板 reads 依赖前者) |
§3 插件类型 × 需求 × 现状(「各种类型能不能接」)
| 插件类型 | 例 | 需要 IM 的什么 | 现状 |
|---|---|---|---|
| 纯数据型 | 统计 / 排行榜 / 审核台账 | 数据面读写 | ✅ 能接 |
| 纯 UI 型 | 只读展示面板 | 客户端 slot + 数据面 | ✅ 能接 |
| 机器人助手型 | 团队记忆 / @bot 汇总 | bot + 事件订阅 + 用户模型 | ⚠️ 一半:模型 ✅、事件订阅 ❌ |
| 聊天增强型 | 任务卡 / 投票 / 公告 | 载荷 + 面板动作 + 落库发言 | ⚠️ 一半:载荷 ✅、落库发言 ❌ |
| 回合 / 限速型 | 跑团 / MUD 指令流 | 发言规则 hook | ❌ 接不了(纯入向回调) |
| 实时协同型 | 协作文档 / 白板 | 出向帧广播 + 大对象分片 | ❌ 接不了(帧出向无通路) |
| 外部集成型 | Email / CRM 同步 | 外部凭据通路 | ❌ 未立项(对接单 §2-3-3) |
⇒ 分界线很清楚:「插件单向发起」的能接,「平台要调插件」的接不了。
§4 缺口(按阻塞程度)
| # | 缺口 | 后果 | 归属 |
|---|---|---|---|
| G1 | 扩展点注册无跨进程通路 —— 插件在实例内,apply(host) 拿不到平台 ImSdkHost |
房间类型 / 发言规则 / bot / 事件 / 面板全注册不上 | 平台侧(新面) |
| G2 | 入向回调是进程内函数调用 —— rule.contract.check(input) 跨不了进程 |
回合制 / 限速 / 事件订阅 / 面板渲染做不了 | 平台侧(新面) |
| G3 | 出向投递无 HTTP 面 —— frame / message 只在平台侧端口 |
实时协同 / 插件主动发言做不了 | 平台侧(新面) |
| G4 | 插件清单来源未定 | 装好了插座没人插 | 投放线 |
| G5 | ImDataPort 按 pluginId 装配未做 |
面板 reads 取不到数 |
平台侧 |
🔴 对 2026-09-25 上一棒结论的自我修正:上一棒做的
createImPluginBinding()与出向端口 是平台侧装配的 —— 它只在「插件与宿主同进程」时有效。本审计查实真实部署形态是跨进程 ⇒ 那一层还不够,必须再加一层 HTTP 协议。契约(扩展点 8 / 面板动作 / 分片)可原样复用, ⛔ 不推翻;缺的是传输层。
§5 插件接入的完整姿势(现在 / 补桥后)
现在能做的(无需新平台能力):
- 声明数据面(
package.json#dsh.data.schema)→ 建库 → 用 HTTP 取数 SDK 读写自己的表。 - 声明客户端 UI(
lib/client.js)→ 走官方 slot 接管会话区 → 做面板交互。 - 调模型:在实例内直接用用户配置的模型(
settings.yaml的 provider 已在实例里)。 - 分发:打包 → admin 上传 → 检测 → 建库 → 发布 → 用户在「功能管理」启用。
补桥后新增(G1/G2/G3 落地后):
5. 启动时向平台登记自己声明的扩展点(房间类型 / 发言规则 / bot / 面板 / 出向)。
6. 平台在这些时机回调实例内插件:发言前判定 / 事件发生 / 面板渲染。
7. 插件主动投递:frame(高频广播,不落库)/ message(落库发言,以 bot 身份)。
§6 建议的桥(待拍板)
两条候选,各有优劣(⛔ 我不替拍):
-
甲案 · 登记 + 回调(推荐倾向):实例内插件启动时 HTTP 登记 manifest;平台需要回调时, 经实例既有可寻址通道调进实例(复用实例已有的 web 面,⛔ 不要求插件自己开端口 —— 那条被
09 §2-6明令禁止)。 优点:与既有纪律不冲突、契约可原样复用、断连可退化(插件不可达 ⇒ 回落自由并发,与现设计同向)。 缺点:要新增"平台 → 实例"的反向调用面(含鉴权与超时),有真实工作量。 -
乙案 · 宿主下沉:把 IM 的插件宿主从平台搬进每个实例。 优点:同进程、零跨进程复杂度,回调天然同步。 缺点:🔴 房间是跨用户公共资源(成员表、消息、presence 都在平台库)⇒ 每个实例各持一份宿主 会直接造成状态分叉(同一房间在不同实例里看到不同的发言规则与在线态)—— 我认为这条不成立。
§7 未做 / 边界
⛔ 本件只做审计,未改任何代码、未部署、未 commit/push、未动 47/106、未改对接单(别的工作区)。
上一棒的代码落地件见 交付物/IM插件接入面-20260925.md(本件是其续集,结论更前一层)。