@xmanrui/dsh-im 0.13.0 → 0.15.0

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 (43) hide show
  1. package/README.en.md +25 -10
  2. package/README.md +26 -11
  3. package/assets/logo-dsh-im-connecting-readme-3x2.png +0 -0
  4. package/assets/logo-dsh-im-connecting-square-v4.png +0 -0
  5. package/assets/logo-plugin-phone.png +0 -0
  6. package/lib/client.js +815 -173
  7. package/lib/index.js +142 -130
  8. package/package.json +4 -3
  9. package/plugin-src/client/build.mjs +1 -6
  10. package/plugin-src/client/channel-logos.js +12 -0
  11. package/plugin-src/client/channels/office/api.js +44 -0
  12. package/plugin-src/client/channels/office/index.js +152 -0
  13. package/plugin-src/client/channels/office/styles.js +50 -0
  14. package/plugin-src/client/channels/shared/token-api.js +5 -1
  15. package/plugin-src/client/channels/shared/token-channel.js +16 -1
  16. package/plugin-src/client/channels/telegram/api.js +17 -2
  17. package/plugin-src/client/channels/telegram/index.js +112 -0
  18. package/plugin-src/client/channels/telegram/styles.js +26 -0
  19. package/plugin-src/client/i18n.js +76 -0
  20. package/plugin-src/client/index.js +22 -11
  21. package/plugin-src/client/styles.js +7 -4
  22. package/plugin-src/host/channels/office/index.mjs +10 -0
  23. package/plugin-src/host/channels/office/production.mjs +45 -0
  24. package/plugin-src/host/channels/office/rpc.mjs +48 -0
  25. package/plugin-src/host/channels/shared/production.mjs +9 -1
  26. package/plugin-src/host/channels/telegram/production.mjs +2 -0
  27. package/plugin-src/host/channels/telegram/rpc.mjs +58 -8
  28. package/plugin-src/host/index.mjs +3 -0
  29. package/src/channels/discord/discord-api.mjs +1 -1
  30. package/src/channels/office/config-store.mjs +107 -0
  31. package/src/channels/office/office-controller.mjs +167 -0
  32. package/src/channels/office/office-job-executor.mjs +390 -0
  33. package/src/channels/office/office-runtime.mjs +171 -0
  34. package/src/channels/office/office-transport.mjs +170 -0
  35. package/src/channels/office/protocol.mjs +43 -0
  36. package/src/channels/shared/token-bot-controller.mjs +28 -0
  37. package/src/channels/shared/token-config-store.mjs +14 -1
  38. package/src/channels/telegram/config-store.mjs +62 -1
  39. package/src/channels/telegram/telegram-controller.mjs +25 -1
  40. package/src/channels/telegram/telegram-runtime.mjs +26 -1
  41. package/src/channels/weixin/weixin-api.mjs +1 -1
  42. package/src/channels/weixin/weixin-controller.mjs +56 -12
  43. package/src/channels/weixin/weixin-runtime.mjs +12 -1
package/README.en.md CHANGED
@@ -1,9 +1,12 @@
1
- <h1><img src="assets/logo-icon.png" alt="dsh-im logo" width="40" align="absmiddle" style="vertical-align: middle;"> dsh-im</h1>
1
+ <p align="center">
2
+ <img src="assets/logo-dsh-im-connecting-readme-3x2.png" alt="DSH-IM — Connecting DeepSeek Harness" width="420" height="280" align="middle">&nbsp;&nbsp;
3
+ <img src="assets/logo-plugin-phone.png" alt="DSH-IM phone logo" width="280" height="280" align="middle">
4
+ </p>
2
5
 
3
6
  ---
4
7
 
5
8
  <div align="center">
6
- <p><strong>DeepSeek Harness, always within reach</strong></p>
9
+ <p><strong>Connecting DeepSeek Harness</strong></p>
7
10
 
8
11
  <p>
9
12
  <img src="https://dsh-im-random-badge.xmanrui-dsh-im.workers.dev" alt="滑动变祖器:今天是梁子或今天是梁圣(随机)">
@@ -32,7 +35,7 @@
32
35
 
33
36
  ## Introduction
34
37
 
35
- Connect IM bots to DeepSeek Harness by scanning a QR code, using an App Manifest, or entering existing bot credentials. One plugin and one settings entry provide unified management for Feishu, WeChat, DingTalk, WeCom, QQ, Slack, Telegram, Discord, and WhatsApp. **Every channel supports multiple bots**, each with independent connection state, workspace, and session bindings. It also supports switching workspaces and rebinding sessions.
38
+ Connect IM bots to DeepSeek Harness by scanning a QR code, using an App Manifest, or entering existing bot credentials, and let the local Harness connect outward to a public AI Office. One plugin and one settings entry manage nine multi-bot IM channels and the AI Office Connector.
36
39
 
37
40
  ## Interface
38
41
 
@@ -48,7 +51,7 @@ Connect IM bots to DeepSeek Harness by scanning a QR code, using an App Manifest
48
51
  | WeCom | Create an intelligent bot by QR code, or bind one with Bot ID + Secret | Official WebSocket connection; native thinking state, tool progress, and streaming replies |
49
52
  | QQ | Create a bot with mobile QQ QR scanning, or bind one with AppID + AppSecret | WebSocket connection; native typing and streaming replies in private chats, replies when mentioned in groups |
50
53
  | Slack | Create an app from the bundled App Manifest, then enter a Bot Token (`xoxb-`) and App Token (`xapp-`) | Socket Mode connection; direct DM replies, mention-only channel replies, and preferred native streaming API |
51
- | Telegram | Enter a Bot Token generated by @BotFather | Bot API long polling; direct private replies, mention-or-reply group handling, and streaming through message edits |
54
+ | Telegram | Enter a Bot Token generated by @BotFather | Bot API long polling; DMs work by default and groups respond to mentions or replies, while each bot can optionally enable a private-DM allowlist; streaming uses message edits |
52
55
  | Discord | Enter a Bot Token generated in the Developer Portal | Gateway v10 connection; direct DM replies, mention-only server replies, and streaming through message edits |
53
56
  | WhatsApp | Scan a QR code with mobile WhatsApp to link a device | WhatsApp Web connection; read receipt and typing indicator followed by the final answer |
54
57
 
@@ -56,6 +59,16 @@ Other IM platforms can be added through the same channel-adapter structure.
56
59
 
57
60
  All nine built-in channels can send JPEG, PNG, and WebP images, plus GIFs sent as image files, with optional captions to Harness. Each image is limited to 5 MB, and images in one message are limited to 20 MB in total.
58
61
 
62
+ ## AI Office Connector
63
+
64
+ The **AI Office** page lets the local Harness connect outward to a public Office. The machine needs no public IP, forwarded port, or WebSocket server. The Device Token is written only to the Harness credential provider; the ordinary config file contains only the device ID, Office origin, workspace aliases, and instruction-preset aliases. Office selects aliases and never receives local absolute paths.
65
+
66
+ The current protocol is `office-harness.v1`. The connector authenticates and advertises capabilities with `POST /api/harness/connector/heartbeat`, then opens the downstream event plane with `GET /api/harness/connector/stream` over SSE. The settings page derives every fixed hook from the Office Base URL and reconnects with backoff after a disconnect.
67
+
68
+ A `job.available` event makes the local connector fetch the payload, validate Workspace/Preset aliases, claim a 90-second lease, and renew it every 30 seconds. It creates an isolated Harness Session, reports safe status/tool/text progress, and writes a terminal result exactly once. Tool approvals and follow-up questions surface in Office; approve, reject, and text answers return over SSE to the original Session. Heartbeats and leases recover from dropped connections.
69
+
70
+ A successful heartbeat response must be JSON: `{"ok":true,"protocolVersion":"office-harness.v1"}`. This makes a successful connection test proof of a compatible Office Connector instead of any URL that happens to return 200.
71
+
59
72
  ## Installation
60
73
 
61
74
  Install the published stable release from npm (recommended):
@@ -81,6 +94,8 @@ After installation, follow the built-in instructions on each channel page to sca
81
94
  | Bot workspace | Each bot stores its workspace independently. New bots start with the Host's current working directory, which can later be changed from the bot card. |
82
95
  | Agent Preset | New Sessions inherit Harness's `agent-presets.default` unless the channel explicitly overrides it. Later changes do not affect existing Sessions. |
83
96
 
97
+ Each Telegram bot has its own access-mode control on its bot card. Existing and newly connected bots both default to **Compatible mode**: DMs receive replies, while group messages require a mention of or reply to the bot. Restrictions apply only after explicitly switching that bot to **Safe mode (private-chat allowlist)**. Safe mode ignores every group message and admits only numeric User IDs in that bot's allowlist. Enter one ID per line. Switching back to Compatible mode retains the allowlist without enforcing it, so it is available when Safe mode is enabled again. An empty allowlist in Safe mode rejects all inbound messages for that bot.
98
+
84
99
  ## Bot commands
85
100
 
86
101
  | Command | Description |
@@ -121,7 +136,7 @@ Example: send `/models`, then `/model 2` to switch to the second model in the li
121
136
  - `/session` accepts exactly one Session ID obtained from `/sessionlist`. It neither creates a session nor immediately prompts the model; later messages in the current chat continue the bound session. Regular archived sessions can be bound without being unarchived, while subagent sessions cannot be bound.
122
137
  - `/session` locates the session's unique workspace automatically. Binding inside the current workspace replaces only this chat's mapping. A cross-workspace binding switches the bot workspace, clears the old session mappings for all of that bot's chats, and then binds this chat, so it affects the bot's other chats. A reply already being generated may still finish.
123
138
  - Workspace switches and session bindings only clear or replace dsh-im chat mappings. They never delete, empty, or archive old Session contents; an old Session can still be listed and bound again.
124
- - Any user who is already within the platform bot's visibility scope and can normally message it can run these commands; there is no additional administrator/ordinary-user distinction.
139
+ - Any user within the platform bot's visibility scope who can normally message it can run these commands; there is no separate administrator role. Telegram Compatible mode follows the original DM and group mention/reply rules. Safe mode admits only private users in that bot's allowlist and always ignores group commands.
125
140
  - The list comes from the Harness Host's global registry and can include local absolute paths for other bots, other channels, or non-IM projects. Restrict the bot's visibility to trusted users.
126
141
  - Session results also come from the global Harness Host. Session IDs and titles can belong to other bots, other channels, or non-IM projects, and may contain sensitive metadata. Enable these commands only when every user in the bot's visibility scope is trusted.
127
142
  - Any user who can run `/session` can continue the selected session and use later messages to write to it or invoke its available tools. Expose the bot and session list only to trusted users.
@@ -139,12 +154,12 @@ Example: send `/models`, then `/model 2` to switch to the second model in the li
139
154
 
140
155
  ## Design
141
156
 
142
- - Registers a single **IM Bot** settings page in Harness.
143
- - Maintains all nine channel Host, client, and runtime sources in this repository without external standalone channel plugins.
157
+ - Registers one **IM Bot** settings page containing nine IM channels and one AI Office Connector.
158
+ - Maintains the Host, client, and runtime sources for all nine channels and the Office Connector in this repository without external standalone plugins.
144
159
  - Follows the DeepSeek Harness language preference and switches the settings UI live between Chinese and English.
145
- - Uses channel logos for WeChat, Feishu, DingTalk, WeCom, QQ, Slack, Telegram, Discord, and WhatsApp navigation without enable/disable switches.
146
- - Keeps RPC endpoints, credentials, connection supervision, and session mappings isolated by channel.
147
- - Returns only QR codes, the public Slack Manifest, and redacted status data to the browser. Manually entered secrets and Tokens travel one way to the local Host; no RPC response returns App Secrets, `bot_token`, DingTalk `client_secret`, WeCom Secrets, QQ `app_secret`, Slack Bot/App Tokens, Telegram/Discord Bot Tokens, WhatsApp linked-device keys, or raw user identifiers.
160
+ - Uses logos for WeChat, Feishu, DingTalk, WeCom, QQ, Slack, Telegram, Discord, WhatsApp, and AI Office navigation without enable/disable switches.
161
+ - Keeps RPC endpoints, credentials, connection supervision, and session mappings isolated by IM channel; the Office Connector separately owns Device credentials, Job leases, approval waits, and concurrency limits.
162
+ - Returns only QR codes, the public Slack Manifest, redacted status data, and the access mode and allowlist User IDs that the user explicitly saved for the current Telegram bot. Manually entered secrets and Tokens travel one way to the local Host; no RPC response returns App Secrets, `bot_token`, DingTalk `client_secret`, WeCom Secrets, QQ `app_secret`, Slack Bot/App Tokens, Telegram/Discord Bot Tokens, WhatsApp linked-device keys, AI Office Device Tokens, or other raw user identifiers observed from platform messages.
148
163
 
149
164
  ## Local development
150
165
 
package/README.md CHANGED
@@ -1,10 +1,13 @@
1
- <h1><img src="assets/logo-icon.png" alt="dsh-im logo" width="40" align="absmiddle" style="vertical-align: middle;"> dsh-im</h1>
1
+ <p align="center">
2
+ <img src="assets/logo-dsh-im-connecting-readme-3x2.png" alt="DSH-IM — Connecting DeepSeek Harness" width="420" height="280" align="middle">&nbsp;&nbsp;
3
+ <img src="assets/logo-plugin-phone.png" alt="DSH-IM phone logo" width="280" height="280" align="middle">
4
+ </p>
2
5
 
3
6
  ---
4
7
 
5
8
  <div align="center">
6
9
  <p><strong>让 DeepSeek Harness 触手可及</strong></p>
7
- <p><strong>DeepSeek Harness, always within reach</strong></p>
10
+ <p><strong>Connecting DeepSeek Harness</strong></p>
8
11
 
9
12
  <p>
10
13
  <img src="https://dsh-im-random-badge.xmanrui-dsh-im.workers.dev" alt="滑动变祖器:今天是梁子或今天是梁圣(随机)">
@@ -33,9 +36,9 @@
33
36
 
34
37
  ## 简介
35
38
 
36
- 通过扫码、App Manifest 或已有机器人凭据把 IM 机器人接入 DeepSeek Harness。一个插件、一个设置入口,统一管理飞书、微信、钉钉、企业微信、QQ、Slack、Telegram、Discord WhatsApp。**每个渠道都支持接入多个机器人**,各机器人的连接状态、工作区和会话绑定彼此独立。支持切换工作区和重新绑定会话。
39
+ 通过扫码、App Manifest 或已有机器人凭据把 IM 机器人接入 DeepSeek Harness,并让本机 Harness 主动连接公网 AI Office。一个插件、一个设置入口,统一管理九种 IM 渠道和 AI Office Connector。**每个 IM 渠道都支持接入多个机器人**,各机器人的连接状态、工作区和会话绑定彼此独立。
37
40
 
38
- Connect IM bots to DeepSeek Harness by scanning a QR code, using an App Manifest, or entering existing bot credentials. One plugin and one settings entry provide unified management for Feishu, WeChat, DingTalk, WeCom, QQ, Slack, Telegram, Discord, and WhatsApp. **Every channel supports multiple bots**, each with independent connection state, workspace, and session bindings. It also supports switching workspaces and rebinding sessions.
41
+ Connect IM bots to DeepSeek Harness by scanning a QR code, using an App Manifest, or entering existing bot credentials, and let the local Harness connect outward to a public AI Office. One plugin and one settings entry manage nine multi-bot IM channels and the AI Office Connector.
39
42
 
40
43
  ## 界面
41
44
 
@@ -51,7 +54,7 @@ Connect IM bots to DeepSeek Harness by scanning a QR code, using an App Manifest
51
54
  | 企业微信 | 使用企业微信 App 扫码创建智能机器人,或使用 Bot ID + Secret 手动绑定 | 官方 WebSocket 长连接;原生显示“正在思考中”、工具执行进度和流式回答 |
52
55
  | QQ | 使用手机 QQ 扫码创建机器人,或使用 AppID + AppSecret 手动绑定 | WebSocket 长连接;私聊显示“正在输入”和流式回答,群聊被 @ 后回复 |
53
56
  | Slack | 使用预置 App Manifest 创建应用,再填写 Bot Token(`xoxb-`)和 App Token(`xapp-`) | Socket Mode 长连接;私聊直接回复,频道被 @ 后响应,优先使用官方流式消息 API |
54
- | Telegram | 使用 @BotFather 生成的 Bot Token | Bot API 长轮询;私聊直接回复,群聊被提及或收到对机器人消息的回复时响应,通过编辑消息流式显示回答 |
57
+ | Telegram | 使用 @BotFather 生成的 Bot Token | Bot API 长轮询;默认私聊直接响应、群聊被提及或回复时响应,也可为每个机器人独立启用私聊白名单安全模式;通过编辑消息流式显示回答 |
55
58
  | Discord | 使用 Developer Portal 生成的 Bot Token | Gateway v10 长连接;私信直接回复,服务器频道被提及时响应,通过编辑消息流式显示回答 |
56
59
  | WhatsApp | 使用手机 WhatsApp 扫码关联设备 | WhatsApp Web 长连接;显示已读和“正在输入”,再发送最终回答 |
57
60
 
@@ -59,6 +62,16 @@ Connect IM bots to DeepSeek Harness by scanning a QR code, using an App Manifest
59
62
 
60
63
  九个内置渠道均支持把 JPEG、PNG、WebP 图片,以及以图片文件方式发送的 GIF,连同可选文字说明发送给 Harness;单张图片上限为 5 MB,单条消息中的图片总大小上限为 20 MB。
61
64
 
65
+ ## AI Office Connector
66
+
67
+ 「AI Office」页让本机 Harness 主动连接公网 Office,本机无需公网 IP、端口转发或 WebSocket 服务。Device Token 只写入 Harness 凭据存储;普通配置文件仅保存设备 ID、Office Origin、工作区 alias 和 Instruction Preset alias。Office 只能选择 alias,不会收到本机绝对路径。
68
+
69
+ 当前协议版本为 `office-harness.v1`。连接器使用 `POST /api/harness/connector/heartbeat` 完成鉴权和能力握手,再以 `GET /api/harness/connector/stream` 建立 SSE 下行;设置页会从 Office Base URL 自动展示全部固定 Hook,并在断线后按退避策略自动重连。
70
+
71
+ Office 的 `job.available` 会触发本机拉取任务、校验 Workspace/Preset alias、领取 90 秒租约并每 30 秒续租。连接器创建独立 Harness Session,把状态、工具名和增量文字安全回传 Office,终态只允许写入一次。Harness 发起的工具审批或补充问题会进入 Office 人工面板;批准、拒绝或文字答案再经 SSE 回到原 Session,断线时由租约与 Heartbeat 恢复。
72
+
73
+ Heartbeat 成功响应必须是 JSON:`{"ok":true,"protocolVersion":"office-harness.v1"}`。这使「连接测试通过」代表命中了兼容的 Office Connector,而不只是某个碰巧返回 200 的网址。
74
+
62
75
  ## 安装
63
76
 
64
77
  推荐从 npm 安装已发布的稳定版本:
@@ -84,6 +97,8 @@ GitHub 源安装会直接拉取并构建 Git 依赖;pnpm 10 及以上版本可
84
97
  | 机器人工作区 | 每个机器人独立保存工作区。新机器人默认使用 Host 当时的工作目录;之后可在机器人卡片中修改。 |
85
98
  | Agent Preset | 新会话默认继承 Harness 的 `agent-presets.default`;渠道显式配置优先,已有会话不受后续修改影响。 |
86
99
 
100
+ 每个 Telegram 机器人都可以在自己的卡片中切换访问模式。旧机器人和新接入机器人均默认使用**兼容模式**:私聊直接响应,群聊仅在提及机器人或回复机器人消息时响应。只有主动切换到**安全模式(私聊白名单)**后,机器人才会忽略全部群聊,并只接受该机器人白名单中的数字 User ID。白名单每行一个 ID、按机器人独立保存;切回兼容模式时会保留但不使用,再切回安全模式即可继续使用。安全模式的空白名单会拒绝该机器人的所有入站消息。
101
+
87
102
  ## 机器人命令
88
103
 
89
104
  | 命令 | 作用 |
@@ -124,7 +139,7 @@ GitHub 源安装会直接拉取并构建 Git 依赖;pnpm 10 及以上版本可
124
139
  - `/session` 只接受一个由 `/sessionlist` 获得的 Session ID。它不会新建会话或立即向模型发送消息;绑定成功后,当前聊天的后续消息会继续该会话。普通归档会话可以绑定但不会自动取消归档,子代理会话不能绑定。
125
140
  - `/session` 会自动定位会话唯一所属的工作区。同工作区绑定只替换当前聊天的映射;跨工作区绑定会切换该机器人的工作区、清除该机器人所有聊天的旧会话映射,再绑定当前聊天,因此会影响该机器人的其他聊天。已经开始生成的回复仍可完成。
126
141
  - 工作区切换和会话绑定只会清除或替换 dsh-im 的聊天映射,不会删除、清空或归档任何旧 Session 内容;旧 Session 仍可再次列出和绑定。
127
- - 任何已在对应平台可见范围内、能够正常向机器人发消息的用户都可以执行这些命令,不区分管理员和普通用户。
142
+ - 任何已在对应平台可见范围内、能够正常向机器人发消息的用户都可以执行这些命令,不区分管理员和普通用户。Telegram 兼容模式遵循原有私聊及群聊提及/回复规则;安全模式只允许当前机器人白名单中的私聊用户执行,群聊命令始终忽略。
128
143
  - 工作区列表来自 Harness Host 的全局登记信息,可能包含其他机器人、其他渠道或非 IM 项目的本机绝对路径。请将机器人可见范围限制给可信用户。
129
144
  - 会话列表同样来自该全局 Harness Host;会话 ID 和标题可能属于其他机器人、其他渠道或非 IM 项目,并可能包含敏感元数据。开放命令前请确保所有可见用户都可信。
130
145
  - 任何能执行 `/session` 的用户都能接续所选会话,并通过后续消息写入会话或触发其可用工具。请只向可信用户开放机器人及其会话列表。
@@ -142,12 +157,12 @@ GitHub 源安装会直接拉取并构建 Git 依赖;pnpm 10 及以上版本可
142
157
 
143
158
  ## 设计
144
159
 
145
- - Harness 中只注册一个「IM机器人」设置页;
146
- - 九个渠道的 Host、客户端与运行时源码都在本仓库维护,不依赖外部独立渠道插件;
160
+ - Harness 中只注册一个「IM机器人」设置页,其中包含九个 IM 渠道和一个 AI Office Connector;
161
+ - 九个渠道及 Office Connector 的 Host、客户端与运行时源码都在本仓库维护,不依赖外部独立插件;
147
162
  - 设置页跟随 DeepSeek Harness 的语言选择,在中文和 English 之间即时切换;
148
- - 左侧使用渠道 Logo 切换微信、飞书、钉钉、企业微信、QQ、Slack、Telegram、Discord 和 WhatsApp,不使用启用/停用开关;
149
- - 九个渠道保持独立的 RPC、凭据、连接监督和会话映射;
150
- - 浏览器只获得二维码、Manifest 和脱敏状态;手动输入的 Secret 或 Token 仅单向提交给本机 Host,任何 RPC 响应都不会返回 App Secret、`bot_token`、钉钉 `client_secret`、企业微信 Secret、QQ `app_secret`、Slack Bot/App Token、Telegram/Discord Bot Token、WhatsApp 关联设备密钥或原始用户标识。
163
+ - 左侧使用 Logo 切换微信、飞书、钉钉、企业微信、QQ、Slack、Telegram、Discord、WhatsAppAI Office,不使用启用/停用开关;
164
+ - 九个 IM 渠道保持独立的 RPC、凭据、连接监督和会话映射;Office Connector 另行维护设备凭据、Job 租约、审批等待与并发上限;
165
+ - 浏览器只获得二维码、Manifest、脱敏状态,以及用户为当前 Telegram 机器人主动保存的访问模式和白名单 User ID;手动输入的 Secret 或 Token 仅单向提交给本机 Host,任何 RPC 响应都不会返回 App Secret、`bot_token`、钉钉 `client_secret`、企业微信 Secret、QQ `app_secret`、Slack Bot/App Token、Telegram/Discord Bot Token、WhatsApp 关联设备密钥、AI Office Device Token,或从平台消息中观察到的其他原始用户标识。
151
166
 
152
167
  ## 本地开发
153
168
 
Binary file