@modesto_ma/dsh-channels 0.5.0-beta.2 → 0.5.0-beta.3
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.
- package/README.md +6 -6
- package/docs/attachment-pipeline-v2.md +2 -2
- package/docs/feishu-onboarding.md +4 -3
- package/lib/index.js +1606 -248
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
- package/src/config.ts +26 -14
- package/src/feishu/scopes.ts +13 -1
- package/src/feishu/wiki/a1.ts +97 -0
- package/src/feishu/wiki/api.ts +21 -6
- package/src/feishu/wiki/base-api.ts +267 -0
- package/src/feishu/wiki/base-tools.ts +423 -0
- package/src/feishu/wiki/shared.ts +284 -0
- package/src/feishu/wiki/sheet-api.ts +250 -0
- package/src/feishu/wiki/sheet-tools.ts +493 -0
- package/src/feishu/wiki/tools.ts +102 -189
- package/src/feishu-channel.ts +14 -1
- package/src/settings/surface.ts +6 -6
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@ DeepSeek Harness(DSH)飞书渠道插件:**一个 dsh 实例对应一个飞
|
|
|
8
8
|
- 工作区归属:**每用户一个工作区**(私聊 = 用户;群聊 = 群 × 用户,同群不同用户互不影响);每个话题在工作区内拥有独立工作目录(默认 `topics/<话题 id>/`,Git 仓库工作区可自动改用 worktree),因此话题之间的文件互不干扰,而工作区数量只随用户增长
|
|
9
9
|
- **入站附件(v2,零等待)**:收到消息时**会话、话题、流式卡片立即建立,不等附件下载**。触发消息中的图片自动预取为首轮原生 `ImageBlock`,模型直接可见;文件默认不下载,prompt 用 `<feishu_context>` 清单声明“附件未加载”,模型需要时调用 `feishu_attachment_fetch` 按 `message_id` 懒取;引用消息与话题历史以 `<feishu_quote>` / `<feishu_history>` 摘录,更早的消息用 `feishu_topic_messages` 翻页(发现的资源同时获得 fetch 授权)。**只发附件、不带说明的消息完全静默**:不回复、不建会话、不下载、不加表情,本地也不留任何状态;要让模型看到它,请引用那条消息再提问(多个文件可合并转发后引用),话题内的附件也可由模型用 `feishu_topic_messages` 读到。所有入站图片/文件统一存入 **DSH 原生附件库**(不可变、内容寻址去重、读取校验、随 Session 回放;插件不承担入站附件清理)。显式 `attachmentStore: 'archive'`、宿主未挂载原生附件服务或关闭 fetch 工具时退回旧版工作区 `attachments/` 落盘。完整设计见 [docs/attachment-pipeline-v2.md](docs/attachment-pipeline-v2.md)。
|
|
10
10
|
- **把生成的文件发给用户**:模型在话题工作目录里生成图片、报告、表格等文件后,可调用 `feishu_send_file` 直接发回当前话题/会话(可识别图片 ≤10 MB 以图片消息发送,其余以文件消息发送,文件上限 30 MB)。只能发送**当前话题工作目录内**的普通文件(`..` 与符号链接都按真实路径校验,不能读到其他话题或系统文件);需开通 `im:resource` 权限,缺失时工具返回可读的 `PERMISSION_DENIED`,回合不受影响。开关:`feishuTools.sendFile`(默认开)
|
|
11
|
-
- **知识库读写**:开启 `feishuTools.wikiRead` / `feishuTools.wikiWrite`(默认都关)并在 `wikiRoots` 里配置知识空间链接 `https://<租户>.feishu.cn/wiki/space/<space_id>` 或节点链接 `https://<租户>.feishu.cn/wiki/<node_token>` 后,模型可用 `feishu_wiki_list` 浏览、`feishu_wiki_read` 读取飞书文档(Markdown,或带 block id 的飞书文档 XML,支持目录/章节/区间/关键词局部读取)、`feishu_wiki_create`
|
|
11
|
+
- **知识库读写**:开启 `feishuTools.wikiRead` / `feishuTools.wikiWrite`(默认都关)并在 `wikiRoots` 里配置知识空间链接 `https://<租户>.feishu.cn/wiki/space/<space_id>` 或节点链接 `https://<租户>.feishu.cn/wiki/<node_token>` 后,模型可用 `feishu_wiki_list` 浏览、`feishu_wiki_read` 读取飞书文档(Markdown,或带 block id 的飞书文档 XML,支持目录/章节/区间/关键词局部读取)、`feishu_wiki_create` 在范围内新建飞书文档、电子表格或多维表格(新节点也可作为子目录继续往下建)、`feishu_wiki_edit` 修改**本应用创建的**文档(追加、在块后插入、替换/删除块、文本替换、整篇重写;必须带上读取时的 `revision_id`,文档被他人改过会被拒绝)。电子表格用 `feishu_wiki_sheet_read` 按子表和 A1 范围读成 CSV(每行带 `[row=N]` 真实行号),`feishu_wiki_sheet_edit` 向**本应用创建的**表格写入单元格值或公式、在数据末尾追加行(追加位置会越过空行找到真正的最后一行,目标单元格非空时失败、不会覆盖;同样校验 `revision_id`;不改样式、图表和行列结构)。多维表格用 `feishu_wiki_base_read` 列数据表、读字段和记录(支持筛选、排序、关键词搜索、分页),`feishu_wiki_base_edit` 增改删记录:**本应用创建的**多维表格可增改删,其他多维表格**只能新增记录**(不改表和字段结构)。所有调用都用应用身份,并且:只有**管理员或知识库白名单**(`/auth wiki add @用户`)里的人发起的话题能用;`wikiRoots` 之外一律拒绝;打开某个文档或表格、每次新建、每次修改都会在话题里弹出**授权卡**,只有话题发起人能点(读取授权在本话题内对该文档持续有效,`/renew` 或重启后重新询问),超时(`approvalTimeoutMs`)自动拒绝;浏览目录不弹卡。需开通 `wiki:wiki`、`docx:document`、`sheets:spreadsheet`、`bitable:app`(只读可用 `wiki:wiki:readonly` / `docx:document:readonly` / `sheets:spreadsheet:readonly` / `bitable:app:readonly`),且应用要是目标知识空间的成员(可把包含机器人的群加为空间成员/管理员)
|
|
12
12
|
- **HITL 审批**:当模型请求需要授权的动作(如 bash 沙箱升级 `sandbox_permissions`)时,插件监听主机 `approval/request` 事件,在同一话题里**新发一张独立审批决策卡**:卡上直接显示将执行的命令(或工具参数)和提权目标,提供 ✅ 允许 / ❌ 拒绝 / ♾️ 本话题不再询问 三个按钮;也可以在话题里直接回复「允许」「拒绝」「全部允许」,回复其他内容视为拒绝并作为下一条指令。等待期间流式主卡显示「⏳ 等待你审批」。超时(`approvalTimeoutMs`,默认 5 分钟)自动拒绝(fail-closed),非会话发起人点击或回复无效
|
|
13
13
|
- **结构化提问**:模型调用 `ask_user_question` 时,插件监听主机 `user-questions/request` 瀑布并发一张问答卡(每个问题一组选项按钮,多选先勾选再「提交本题选择」),答案回填给模型;主机自带的应答者只有 Web 客户端,没有本插件时纯飞书会话会以 `NO_PROVIDER` 失败。超时(`questionTimeoutMs`,默认 5 分钟)或回合取消时本轮提问失败(fail-closed);没有可选项的问题直接提示用文字作答,**阻塞期间普通文本回复即作为该问题的自由文本答案**(同时支持多选后的自定义文本)
|
|
14
14
|
- **准入与授权(默认开启)**:**管理员不受白名单限制**(私聊、任意群聊——包括尚未授权的群——都能直接发起会话);其他人私聊只收到一条固定提示(`/userid` 例外),群聊需要「群已授权 + 用户在全局白名单」两层同时命中。机器人被拉进群后私聊管理员发**群信息卡**(未授权群附授权按钮,用于放行白名单用户);已授权群里未授权用户 @ 会触发用户授权卡。授权入口:飞书 `/auth` 命令、授权卡、Web 设置面板;管理员 user_id 在面板配置(私聊 `/userid` 获取),**留空时自动使用飞书应用所有者**
|
|
@@ -170,7 +170,7 @@ src/
|
|
|
170
170
|
│ ├── slash-commands.ts # 连接后把命令注册表幂等同步到飞书原生斜杠指令面板
|
|
171
171
|
│ ├── tools.ts # feishu_attachment_fetch / feishu_topic_messages 与每 route 白名单
|
|
172
172
|
│ ├── send-file.ts # feishu_send_file:把话题工作目录内的图片/文件发回当前会话
|
|
173
|
-
│ ├── wiki/ # 知识库工具:links(wikiRoots 链接解析)、api(wiki/docx/docs_ai 接口)、scope(范围判定)、consent(授权卡)、tools
|
|
173
|
+
│ ├── wiki/ # 知识库工具:links(wikiRoots 链接解析)、api(wiki/docx/docs_ai 接口)、sheet-api / base-api(电子表格、多维表格接口)、scope(范围判定)、consent(授权卡)、shared(失败码与公共步骤)、tools / sheet-tools / base-tools、a1(A1 范围)
|
|
174
174
|
│ └── agent-context.ts # agent 作用域 system prompt:native/archive 双模式附件指引
|
|
175
175
|
├── routing/
|
|
176
176
|
│ └── inbound.ts # 入站路由:去重、准入、路由决策树、建/续会话、首触引导
|
|
@@ -265,8 +265,8 @@ npm 发行包已包含构建产物:Host 入口是 `lib/index.js`(profile 直
|
|
|
265
265
|
topicMessages: true # feishu_topic_messages:读取引用消息 / 话题历史并授权其附件
|
|
266
266
|
topicMessagesTimeoutMs: 20000 # 单次话题读取整段超时(20 s;被动摘录用独立 3 s 预算)
|
|
267
267
|
sendFile: true # feishu_send_file:把话题工作目录内生成的图片/文件发给用户(需 im:resource)
|
|
268
|
-
wikiRead: false # feishu_wiki_list / feishu_wiki_read:浏览 wikiRoots
|
|
269
|
-
wikiWrite: false # feishu_wiki_create / feishu_wiki_edit
|
|
268
|
+
wikiRead: false # feishu_wiki_list / feishu_wiki_read / feishu_wiki_sheet_read / feishu_wiki_base_read:浏览 wikiRoots 内的知识库,读取文档、电子表格、多维表格
|
|
269
|
+
wikiWrite: false # feishu_wiki_create / feishu_wiki_edit / feishu_wiki_sheet_edit / feishu_wiki_base_edit:新建文档/表格,修改本应用创建的文档和表格,向多维表格写记录
|
|
270
270
|
wikiRoots: # 知识库范围(空 = 不挂载知识库工具;最多 20 条)
|
|
271
271
|
- 'https://mi.feishu.cn/wiki/space/7xxxxxxxxxxxxxxxxx' # 整个知识空间
|
|
272
272
|
- 'https://mi.feishu.cn/wiki/AbCdEfGhIjKlMn' # 某个节点及其下所有子节点
|
|
@@ -319,12 +319,12 @@ FEISHU_APP_SECRET: xxxxxxxx
|
|
|
319
319
|
- 「获取应用信息」权限(**可选**,如 `admin:app.info:readonly` / `application:application:self_manage`,以控制台要求为准):未配置 `adminUserId` 时,插件在每次连接时调用 `application/v6/applications/:app_id` 查询应用所有者并让其成为管理员;调不通(企业内不便申请该权限等)时日志与面板会给出飞书返回的错误码,并提示在「访问授权」手动填写管理员 user_id,填写后不再依赖它
|
|
320
320
|
- 回调:**卡片回传交互 card.action.trigger**(流式卡停止按钮、`/model` 等选择卡、HITL 审批 / `ask_user_question` 问答按钮的回传事件,同样走长连接)
|
|
321
321
|
- `im:resource`(获取与上传图片或文件资源,**可选**;`im:resource:upload` 亦可):`feishu_send_file` 上传图片/文件后发给用户。未开通时该工具返回可读的 `PERMISSION_DENIED`;关闭 `feishuTools.sendFile` 后自检不再检查此项
|
|
322
|
-
- `wiki:wiki
|
|
322
|
+
- `wiki:wiki`、`docx:document`、`sheets:spreadsheet`、`bitable:app`(**可选**,仅开启知识库工具时需要;只读可用 `wiki:wiki:readonly` / `docx:document:readonly` / `sheets:spreadsheet:readonly` / `bitable:app:readonly`,也接受新版细分权限 `sheets:spreadsheet:read` / `sheets:spreadsheet:write_only` / `base:record:read` / `base:record:create` / `base:record:update` / `base:record:delete`):浏览知识库节点,读取/新建/修改飞书文档、电子表格、多维表格。应用还必须是目标知识空间的成员,否则调用返回 `NO_ACCESS`
|
|
323
323
|
- `im:message.reactions:write_only`(发送、删除消息表情回复)
|
|
324
324
|
- `im:message:update`(更新卡片)
|
|
325
325
|
|
|
326
326
|
> 消息读取权限缺失时不会报死错:引用摘录与首轮话题历史静默省略(插件生命周期内首次降级输出一条 warn,之后 debug 级),显式调用 `feishu_topic_messages` 返回可读的 `PERMISSION_DENIED`。附件下载仍依赖 `im:message` 一类的消息资源权限;下载被拒时工具与 archive 路径都会返回可读原因。
|
|
327
|
-
> **连接后权限自检**:每次连上飞书后,插件调用 `application/v6/scopes` 读取应用的租户权限授予状态,与上面的清单对比(私聊关闭时不检查 `im:message.p2p_msg:readonly`,`requireMention: false` 时 `im:message.group_msg` 升为必需;`feishuTools.sendFile` 关闭时不检查 `im:resource`;知识库工具未挂载时不检查 `wiki:wiki` / `docx:document`;未配置管理员且应用所有者查询被飞书拒绝时追加可选项「获取应用信息」)。缺失项在 Web 设置「连接」页以红字列出(标注必需/可选与用途,每项附开发者后台权限页深链,另有一键打开全部缺失项的链接),并在日志打印一条 warn;读取失败时显示飞书返回的原因。自检只做提示,不阻断连接;开通权限后需发布新版本并重新连接才会刷新。
|
|
327
|
+
> **连接后权限自检**:每次连上飞书后,插件调用 `application/v6/scopes` 读取应用的租户权限授予状态,与上面的清单对比(私聊关闭时不检查 `im:message.p2p_msg:readonly`,`requireMention: false` 时 `im:message.group_msg` 升为必需;`feishuTools.sendFile` 关闭时不检查 `im:resource`;知识库工具未挂载时不检查 `wiki:wiki` / `docx:document` / `sheets:spreadsheet` / `bitable:app`;未配置管理员且应用所有者查询被飞书拒绝时追加可选项「获取应用信息」)。缺失项在 Web 设置「连接」页以红字列出(标注必需/可选与用途,每项附开发者后台权限页深链,另有一键打开全部缺失项的链接),并在日志打印一条 warn;读取失败时显示飞书返回的原因。自检只做提示,不阻断连接;开通权限后需发布新版本并重新连接才会刷新。
|
|
328
328
|
3. 事件订阅方式选**长连接**(WebSocket,免公网)。
|
|
329
329
|
4. 发布版本并把用户加入可用范围;将机器人拉入测试群。
|
|
330
330
|
|
|
@@ -228,8 +228,8 @@ native 后端下,准入通过后由 `inboundAttachmentState` 做**不下载的
|
|
|
228
228
|
| `promptContextTimeoutMs` | `3000` | 100 – 10000 ms;被动引用/历史预算 | 模型工具 |
|
|
229
229
|
| `feishuTools.attachmentFetch` | `true` | 关闭即整体回退 archive | 模型工具 |
|
|
230
230
|
| `feishuTools.attachmentFetchMaxResources` | `10` | 1 – 50 | 模型工具 |
|
|
231
|
-
| `feishuTools.attachmentFetchMaxBytes` | `104857600`(100 MiB) | 1 B
|
|
232
|
-
| `feishuTools.attachmentFetchTimeoutMs` | `120000` | 1000 –
|
|
231
|
+
| `feishuTools.attachmentFetchMaxBytes` | `104857600`(100 MiB) | ≥ 1 B,无上限 | 模型工具 |
|
|
232
|
+
| `feishuTools.attachmentFetchTimeoutMs` | `120000` | 1000 – 2147483647 ms | 模型工具 |
|
|
233
233
|
| `feishuTools.topicMessages` | `true` | 关闭只关模型工具,被动摘录仍生效 | 模型工具 |
|
|
234
234
|
| `feishuTools.topicMessagesTimeoutMs` | `20000` | 1000 – 120000 ms | 模型工具 |
|
|
235
235
|
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
| `im:message.reactions:write_only`(发送、删除消息表情回复) | Typing / DONE / No 表态 |
|
|
26
26
|
| `im:resource`(获取与上传图片或文件资源,**可选**;`im:resource:upload` 亦可) | 模型用 `feishu_send_file` 把生成的图片/文件发给用户;不开通时该工具返回可读错误 |
|
|
27
27
|
| `im:message:update`(更新消息卡片) | 流式卡片刷新(patch) |
|
|
28
|
-
| `wiki:wiki
|
|
28
|
+
| `wiki:wiki`、`docx:document`、`sheets:spreadsheet`、`bitable:app`(**可选**,只读可用对应的 `:readonly` 权限) | 知识库工具(`feishuTools.wikiRead` / `wikiWrite` + `wikiRoots`):浏览知识库,读取/新建/修改飞书文档、电子表格、多维表格;应用还需是目标知识空间的成员 |
|
|
29
29
|
| `im:chat:readonly` 一类(获取群信息) | 入群通知卡展示群名/成员数(具体 scope 以控制台要求为准) |
|
|
30
30
|
| 「获取应用信息」一类(如 `admin:app.info:readonly` / `application:application:self_manage`,**可选**,以控制台要求为准) | 未配置 `adminUserId` 时连接后自动把应用所有者设为管理员;不便申请时跳过即可,按 3.3 手动设置管理员 |
|
|
31
31
|
| `application:app_slash_command:read` 与 `application:app_slash_command:write`(读取/管理应用斜杠指令,可选,仅 `slashCommandPanel: true` 时需要) | 连接后把插件命令同步到飞书原生斜杠指令面板(输入 `/` 时列出,客户端约 5 分钟后刷新);缺失时只是面板没有列表,直接输入命令不受影响 |
|
|
@@ -168,8 +168,8 @@ chmod 600 $DSH_HOME/.credentials.yaml
|
|
|
168
168
|
| `promptContextTimeoutMs` | `3000` | 被动引用/首轮历史读取的整段预算(100–10000 ms);超时即省略对应块、回合照跑。模型主动调用工具的读取超时另由 `feishuTools.topicMessagesTimeoutMs` 控制 |
|
|
169
169
|
| `feishuTools.attachmentFetch` | `true` | 是否挂载 `feishu_attachment_fetch`;关闭后文件无法懒取,插件**整体回退 archive 后端** |
|
|
170
170
|
| `feishuTools.attachmentFetchMaxResources` | `10` | 单次工具调用最多取回的附件数(1–50);超出返回可读原因,可按 `file_key` 拆分重试 |
|
|
171
|
-
| `feishuTools.attachmentFetchMaxBytes` | `104857600` | 单次工具调用的总下载字节预算(100 MiB
|
|
172
|
-
| `feishuTools.attachmentFetchTimeoutMs` | `120000` | 单次 `feishu_attachment_fetch` 整段超时(1000–
|
|
171
|
+
| `feishuTools.attachmentFetchMaxBytes` | `104857600` | 单次工具调用的总下载字节预算(100 MiB,≥ 1 B,无上限);文件流式写入、不整文件缓冲 |
|
|
172
|
+
| `feishuTools.attachmentFetchTimeoutMs` | `120000` | 单次 `feishu_attachment_fetch` 整段超时(1000–2147483647 ms);到期取消并逐项报告;大文件需同步调大 |
|
|
173
173
|
| `feishuTools.topicMessages` | `true` | 是否挂载 `feishu_topic_messages`;只影响模型工具,被动引用/历史摘录仍生效 |
|
|
174
174
|
| `feishuTools.topicMessagesTimeoutMs` | `20000` | 单次 `feishu_topic_messages` 整段超时(1000–120000 ms) |
|
|
175
175
|
| `loggerLevel` | `info` | 官方 SDK 日志级别 |
|
|
@@ -271,6 +271,7 @@ DSH_HOME=$DSH_HOME pnpm dsh web # 默认 http://127.0.0.1:3080
|
|
|
271
271
|
| 14a | 群授权与群内准入 | 管理员点「授权本群」(或在群内发 `/auth allow`);未授权用户 @;管理员 `/auth user add <user_id>` 后该用户再 @ | 授权前非管理员 @ 无响应(管理员除外);授权后白名单用户可分别开会话;未授权用户 @ 不建会话且管理员收到用户授权卡;授权该用户后可正常开会话 |
|
|
272
272
|
| 15 | 撤销与持久化 | `/auth revoke`(群内)/ `/auth user remove <user_id>`;重启 dsh 后再试 | 撤销后对应主体立即无法开启对话;重启后已授权群/用户仍有效(持久化) |
|
|
273
273
|
| 15a | 知识库读写 | 开启 `wikiRead`/`wikiWrite`、配置 `wikiRoots`;白名单用户在话题里让模型列目录、读一篇文档、新建一篇、再修改它 | 列目录不弹卡;第一次读取弹「📚 知识库授权」卡,只有话题发起人能点,允许后同一篇再读不弹卡;新建、修改每次都弹卡;修改人工创建的文档返回 `NOT_OWNED`;不在白名单的用户发起的话题返回 `NOT_AUTHORIZED` |
|
|
274
|
+
| 15b | 知识库表格 | 同上;让模型读一个电子表格、新建一个电子表格并写入几行再追加一行;读一个人建的多维表格并新增一条记录、尝试修改已有记录;新建一个多维表格后增改删记录 | 表格读取返回带 `[row=N]` 的 CSV;写入和追加落在正确的单元格;人建的电子表格修改返回 `NOT_OWNED`;人建的多维表格能新增记录、修改/删除返回 `NOT_OWNED`;本应用建的多维表格可增改删;每次写入都弹卡 |
|
|
274
275
|
| 16 | 话题越权防护 | 授权群里用户 A 创建话题后,用户 B 在 A 的话题里发普通消息/附件/回答提问 | B 的消息被静默丢弃,不会进入 A 的 Session、不会写入 A 的话题目录;A 自己发言正常 |
|
|
275
276
|
|
|
276
277
|
### 5.0 HITL 审批验证点(重点)
|