@xmanrui/dsh-im 4.33.0 → 4.34.1
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.en.md +3 -1
- package/README.md +3 -1
- package/lib/client.js +20 -4
- package/lib/index.js +294 -291
- package/package.json +1 -1
- package/plugin-src/client/access-policy-settings.js +18 -3
- package/plugin-src/client/i18n.js +5 -0
- package/plugin-src/host/channels/feishu/production.mjs +11 -0
- package/plugin-src/host/channels/shared/access-policy-production.mjs +1 -0
- package/plugin-src/host/channels/shared/workspace-rpc.mjs +1 -0
- package/plugin-src/host/modern-harness-api.mjs +22 -0
- package/src/channels/discord/config-store.mjs +21 -1
- package/src/channels/discord/discord-api.mjs +32 -0
- package/src/channels/discord/discord-controller.mjs +22 -1
- package/src/channels/feishu/bridge.mjs +23 -1
- package/src/channels/feishu/feishu-cards.mjs +5 -0
- package/src/channels/feishu/slash-command-panel.mjs +2 -0
- package/src/channels/qq/qq-bridge.mjs +6 -1
- package/src/channels/shared/bot-workspace-store.mjs +9 -0
- package/src/channels/shared/command-list-snapshots.mjs +33 -0
- package/src/channels/shared/harness-client.mjs +6 -0
- package/src/channels/shared/i18n-en/feishu.mjs +2 -0
- package/src/channels/shared/i18n-en/permission.mjs +30 -0
- package/src/channels/shared/i18n-en.mjs +2 -0
- package/src/channels/shared/permission-command.mjs +149 -0
- package/src/channels/shared/preset-command.mjs +6 -51
- package/src/channels/telegram/telegram-runtime.mjs +12 -26
package/README.en.md
CHANGED
|
@@ -60,7 +60,7 @@ Connect IM bots to DeepSeek Harness by scanning a QR code, using an App Manifest
|
|
|
60
60
|
| 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 |
|
|
61
61
|
| QQ | Create a bot with mobile QQ QR scanning, or bind one with AppID + AppSecret | WebSocket connection; private chats show typing and receive one Markdown reply, while mentioned group chats receive only the final answer |
|
|
62
62
|
| 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 |
|
|
63
|
-
| 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; private chats
|
|
63
|
+
| 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; with thinking traces off, private chats, groups, and Topics edit a placeholder for progress and finalize rich replies in place, avoiding Drafts that block the Android private-chat composer; unsupported Rich delivery falls back to ordinary text |
|
|
64
64
|
| Discord | Enter a Bot Token generated in the Developer Portal | Gateway v10 connection; direct DM replies; the first mention in a server text or announcement channel creates a native Thread, where follow-up messages no longer need to mention the bot; replies stream through message edits |
|
|
65
65
|
| WhatsApp | Scan a QR code with mobile WhatsApp to link a device | WhatsApp Web connection; self-chat only by default, with optional selected-contact and open-response modes; read receipt and typing indicator, with tool progress and incremental answers shown by editing one message at one-second intervals; long replies split automatically and failed edits fall back to a complete text reply |
|
|
66
66
|
| iMessage | Sign in to iMessage in macOS Messages.app and grant the local permissions described in the [channel notes](docs/imessage.md) | Native macOS Messages.app transport for text DMs; no BlueBubbles or third-party gateway; one local iMessage identity per macOS user account |
|
|
@@ -205,6 +205,8 @@ Shells can embed the complete IM management panel through the optional `dshImCli
|
|
|
205
205
|
| `/preset` | Show this bot's Agent Preset setting for new Sessions. |
|
|
206
206
|
| `/preset <number or Preset ID>` | Set this bot's Agent Preset; use `/preset id:<ID>` for a numeric ID. |
|
|
207
207
|
| `/preset --default` | Clear this bot's explicit selection so later new Sessions follow the Host default. |
|
|
208
|
+
| `/permissionlist` | Feishu and QQ: list numbered permission presets for the bound session. |
|
|
209
|
+
| `/permission [number or full ID]` | Feishu and QQ: show or immediately switch the current session permissions; numeric IDs use `/permission id:<ID>`. |
|
|
208
210
|
| `/stop` | Immediately stop this chat's running task while preserving work that has not started. |
|
|
209
211
|
| `/steer <additional instruction>` | Inject an additional instruction into this chat's running task. |
|
|
210
212
|
| `/batch` | Start batch input in a direct chat and collect up to 10 text messages. |
|
package/README.md
CHANGED
|
@@ -64,7 +64,7 @@ Connect IM bots to DeepSeek Harness by scanning a QR code, using an App Manifest
|
|
|
64
64
|
| 企业微信应用 | 在企业微信管理后台创建自建应用,填写企业 ID、AgentId、Secret、Token、EncodingAESKey(可选代理地址) | HTTP 回调接收;私聊支持流式回复(微信端不支持时自动改为分段文本),支持图片输入与结果文件回传;成员的微信关注该企业的微信插件后可在微信中直接使用 |
|
|
65
65
|
| QQ | 使用手机 QQ 扫码创建机器人,或使用 AppID + AppSecret 手动绑定 | WebSocket 长连接;私聊显示“正在输入”并以单条 Markdown 回复,群聊被 @ 后只发送最终答案 |
|
|
66
66
|
| Slack | 使用预置 App Manifest 创建应用,再填写 Bot Token(`xoxb-`)和 App Token(`xapp-`) | Socket Mode 长连接;私聊直接回复,频道被 @ 后响应,优先使用官方流式消息 API |
|
|
67
|
-
| Telegram | 使用 @BotFather 生成的 Bot Token | Bot API
|
|
67
|
+
| Telegram | 使用 @BotFather 生成的 Bot Token | Bot API 长轮询;默认私聊直接响应、群聊被提及或回复时响应,也可为每个机器人独立启用私聊白名单安全模式;关闭思考过程留痕时,私聊、群聊和 Topic 均通过占位消息编辑展示进度并原位完成富文本回复,避免 Android 私聊 Draft 占用发送入口,平台不支持富文本时回退为普通文字 |
|
|
68
68
|
| Discord | 使用 Developer Portal 生成的 Bot Token | Gateway v10 长连接;私信直接回复;服务器文字/公告频道首次 @ 后创建原生 Thread,后续在线程中无需重复 @,并通过编辑消息流式显示回答 |
|
|
69
69
|
| WhatsApp | 使用手机 WhatsApp 扫码关联设备 | WhatsApp Web 长连接;默认仅响应账号自聊,也可切换到指定联系人或开放响应模式;显示已读和“正在输入”,通过每秒编辑同一条消息显示工具进度和逐步生成的回答,长回复自动分段,编辑失败时回退为完整文字回复 |
|
|
70
70
|
| iMessage | 在 macOS Messages.app 中登录 iMessage,并按[渠道说明](docs/imessage.md)授予本机权限 | 使用 macOS 原生 Messages.app 收发文本私聊;不依赖 BlueBubbles;每个 macOS 用户账户使用一个本机 iMessage 身份 |
|
|
@@ -207,6 +207,8 @@ Logo 由 dsh-im 的浏览器适配显示,无需修改 DSH。适配保留原始
|
|
|
207
207
|
| `/preset` | 查看当前机器人的新会话 Agent Preset 设置。 |
|
|
208
208
|
| `/preset <序号或 Preset ID>` | 设置当前机器人的 Agent Preset;纯数字 ID 使用 `/preset id:<ID>`。 |
|
|
209
209
|
| `/preset --default` | 清除当前机器人的显式选择,让后续新 Session 跟随 Host 默认。 |
|
|
210
|
+
| `/permissionlist` | 飞书、QQ:按序号列出当前绑定会话的可用权限档位。 |
|
|
211
|
+
| `/permission [序号或完整ID]` | 飞书、QQ:查看或直接切换当前会话权限;纯数字 ID 使用 `/permission id:<ID>`。 |
|
|
210
212
|
| `/stop` | 立即停止当前聊天正在运行的任务,并保留尚未开始的排队消息。 |
|
|
211
213
|
| `/steer <补充指令>` | 把补充指令立即加入当前聊天正在运行的任务。 |
|
|
212
214
|
| `/batch` | 在私聊中开启批量输入,最多收集 10 条纯文字消息。 |
|
package/lib/client.js
CHANGED
|
@@ -595,7 +595,7 @@ var React38 = __toESM(require("react"), 1);
|
|
|
595
595
|
// package.json
|
|
596
596
|
var package_default = {
|
|
597
597
|
name: "@xmanrui/dsh-im",
|
|
598
|
-
version: "4.
|
|
598
|
+
version: "4.34.1",
|
|
599
599
|
icon: "./assets/logo-plugin-message-link-gradient.webp",
|
|
600
600
|
description: "\u628A\u5FAE\u4FE1\u3001\u98DE\u4E66\u3001\u4F01\u5FAE\u3001\u9489\u9489\u3001QQ\u3001Telegram\u3001WhatsApp\u3001Slack\u3001Discord\u3001Matrix\u63A5\u5165DSH\u3002 Connect Telegram, WhatsApp, Slack, Discord, Matrix, WeChat, Feishu, WeCom, DingTalk, and QQ to DSH.",
|
|
601
601
|
keywords: [
|
|
@@ -1213,6 +1213,11 @@ var EN = Object.freeze({
|
|
|
1213
1213
|
"\u5C1A\u672A\u6DFB\u52A0\u7528\u6237": "No users added",
|
|
1214
1214
|
"\u5F53\u524D\u6E20\u9053\u4E0D\u652F\u6301\u7FA4\u804A": "Group chat is not supported by this channel",
|
|
1215
1215
|
"\u539F\u6240\u6709\u8005\u6216\u626B\u7801\u63A5\u5165\u8005\u59CB\u7EC8\u53EF\u4EE5\u8BBF\u95EE\u5E76\u6267\u884C\u547D\u4EE4\uFF1B\u4EE5\u4E0B\u8BBE\u7F6E\u4EC5\u7EA6\u675F\u5176\u4ED6\u7528\u6237\u3002": "The original owner or QR-code operator can always access the bot and run commands; the settings below apply only to other users.",
|
|
1216
|
+
"\u5DF2\u7531\u63A5\u5165\u6D41\u7A0B\u786E\u8BA4\u7684\u6240\u6709\u8005\u53EF\u4EE5\u8BBF\u95EE\u5E76\u6267\u884C\u547D\u4EE4\uFF0C\u4E0D\u53D7\u672C\u9875\u9650\u5236\u3002\u672A\u8BC6\u522B\u5230\u6240\u6709\u8005\u8EAB\u4EFD\u65F6\uFF0C\u6309\u672C\u9875\u8BBF\u95EE\u8BBE\u7F6E\u6267\u884C\u3002": "Owners confirmed during connection setup can access the bot and run commands regardless of these settings. When no owner has been identified, these access settings apply.",
|
|
1217
|
+
"\u767D\u540D\u5355\u8BF7\u586B\u5199\u4F7F\u7528\u8005\u7684 Open ID\uFF0C\u4E0D\u662F\u673A\u5668\u4EBA\u7684 Open ID\u3002\u4EC5\u4FDD\u5B58\u901A\u914D\u7B26\u7684\u63A5\u5165\u914D\u7F6E\u4E0D\u5305\u542B\u6240\u6709\u8005\u8EAB\u4EFD\u3002": "Enter the user\u2019s Open ID in the allowlist, not the bot\u2019s Open ID. A connection configured with only a wildcard has no identified owner.",
|
|
1218
|
+
"\u626B\u7801\u83B7\u5F97\u7684\u662F\u79C1\u804A\u8EAB\u4EFD\uFF0C\u7FA4\u804A\u53EA\u6709\u5339\u914D\u5DF2\u786E\u8BA4\u7684\u6240\u6709\u8005\u8EAB\u4EFD\u65F6\u624D\u8C41\u514D\uFF1B\u5176\u4ED6\u6210\u5458\u6309\u7FA4\u804A\u767D\u540D\u5355\u8BBE\u7F6E\u6267\u884C\u3002": "QR setup identifies the owner for direct messages. In groups, only a matching confirmed owner identity is exempt; other members follow the group allowlist settings.",
|
|
1219
|
+
"\u586B\u5199\u4F7F\u7528\u8005\u7684 Open ID\uFF08ou_xxx\uFF09\uFF0C\u4E0D\u662F\u673A\u5668\u4EBA ID": "Enter the user\u2019s Open ID (ou_xxx), not the bot ID",
|
|
1220
|
+
"\u8FD9\u91CC\u9700\u8981\u586B\u5199\u7528\u6237\u7684 Open ID\uFF0C\u4E0D\u80FD\u586B\u5199\u673A\u5668\u4EBA\u81EA\u5DF1\u7684 Open ID\u3002": "Enter a user Open ID here, not the bot\u2019s own Open ID.",
|
|
1216
1221
|
"\u6B64\u533A\u57DF\u65E0\u9700\u914D\u7F6E\uFF0C\u4FDD\u5B58\u79C1\u804A\u8BBE\u7F6E\u65F6\u4F1A\u4FDD\u7559\u73B0\u6709\u7FA4\u804A\u7B56\u7565\u3002": "No setup is needed here. Saving direct-message settings keeps the existing group policy.",
|
|
1217
1222
|
"\u8BBF\u95EE\u8BBE\u7F6E\u5DF2\u4FDD\u5B58\u3002": "Access settings saved.",
|
|
1218
1223
|
"\u8BBF\u95EE\u8BBE\u7F6E\u6682\u4E0D\u53EF\u7528\u3002": "Access settings are currently unavailable.",
|
|
@@ -7247,6 +7252,8 @@ var SLASH_COMMAND_MANIFEST = Object.freeze([
|
|
|
7247
7252
|
{ command: "reasoning", icon: "ai-deepthink_outlined", default: "\u67E5\u770B\u6216\u5207\u6362\u63A8\u7406\u7B49\u7EA7", en_us: "Show or switch the reasoning effort" },
|
|
7248
7253
|
{ command: "presetlist", icon: "skill_outlined", default: "\u5217\u51FA\u53EF\u7528 Agent \u9884\u8BBE", en_us: "List available Agent Presets" },
|
|
7249
7254
|
{ command: "preset", icon: "skill_outlined", default: "\u67E5\u770B\u6216\u5207\u6362 Agent \u9884\u8BBE", en_us: "Show or switch the Agent Preset" },
|
|
7255
|
+
{ command: "permissionlist", icon: "skill_outlined", default: "\u6309\u5E8F\u53F7\u5217\u51FA\u6743\u9650\u6863\u4F4D", en_us: "List numbered permission presets" },
|
|
7256
|
+
{ command: "permission", icon: "skill_outlined", default: "\u67E5\u770B\u6216\u5207\u6362\u5F53\u524D\u4F1A\u8BDD\u6743\u9650", en_us: "Show or switch current session permissions" },
|
|
7250
7257
|
{ command: "stop", icon: "clear_outlined", default: "\u505C\u6B62\u5F53\u524D\u4EFB\u52A1", en_us: "Stop the current task" },
|
|
7251
7258
|
{ command: "steer", icon: "promptword_outlined", default: "\u7ED9\u5F53\u524D\u4EFB\u52A1\u8865\u5145\u6307\u4EE4", en_us: "Send additional instructions to the current task" },
|
|
7252
7259
|
{ command: "batch", icon: "chat-ai_outlined", default: "\u5F00\u59CB\u6279\u91CF\u8F93\u5165\uFF08\u4EC5\u79C1\u804A\uFF09", en_us: "Start batch input (private chats only)" },
|
|
@@ -16176,6 +16183,7 @@ var React33 = __toESM(require("react"), 1);
|
|
|
16176
16183
|
// plugin-src/client/access-policy-settings.js
|
|
16177
16184
|
var React28 = __toESM(require("react"), 1);
|
|
16178
16185
|
var ACCESS_POLICY_ENDPOINT = "bot.access-policy.set";
|
|
16186
|
+
var CONFIRMED_OWNER_CHANNELS = /* @__PURE__ */ new Set(["weixin", "feishu", "qq", "whatsapp", "discord"]);
|
|
16179
16187
|
var ACCESS_CHANNEL_DEFINITIONS = Object.freeze({
|
|
16180
16188
|
weixin: Object.freeze({
|
|
16181
16189
|
directUserLabel: "\u5FAE\u4FE1\u7528\u6237 ID",
|
|
@@ -16184,9 +16192,9 @@ var ACCESS_CHANNEL_DEFINITIONS = Object.freeze({
|
|
|
16184
16192
|
}),
|
|
16185
16193
|
feishu: Object.freeze({
|
|
16186
16194
|
directUserLabel: "\u98DE\u4E66 Open ID",
|
|
16187
|
-
directPlaceholder: "
|
|
16195
|
+
directPlaceholder: "\u586B\u5199\u4F7F\u7528\u8005\u7684 Open ID\uFF08ou_xxx\uFF09\uFF0C\u4E0D\u662F\u673A\u5668\u4EBA ID",
|
|
16188
16196
|
groupUserLabel: "\u7FA4\u6210\u5458 Open ID",
|
|
16189
|
-
groupPlaceholder: "
|
|
16197
|
+
groupPlaceholder: "\u586B\u5199\u4F7F\u7528\u8005\u7684 Open ID\uFF08ou_xxx\uFF09\uFF0C\u4E0D\u662F\u673A\u5668\u4EBA ID"
|
|
16190
16198
|
}),
|
|
16191
16199
|
dingtalk: Object.freeze({
|
|
16192
16200
|
directUserLabel: "\u9489\u9489\u7528\u6237 ID",
|
|
@@ -16285,6 +16293,8 @@ function ScenePolicyEditor({
|
|
|
16285
16293
|
placeholder,
|
|
16286
16294
|
disabled = false,
|
|
16287
16295
|
unsupported = false,
|
|
16296
|
+
ownerHelp,
|
|
16297
|
+
identityHelp,
|
|
16288
16298
|
onChange
|
|
16289
16299
|
}) {
|
|
16290
16300
|
const ownerHelpId = React28.useId();
|
|
@@ -16330,7 +16340,7 @@ function ScenePolicyEditor({
|
|
|
16330
16340
|
id: ownerHelpId,
|
|
16331
16341
|
className: "dim-channelTooltip dim-accessHelpTooltip",
|
|
16332
16342
|
role: "tooltip"
|
|
16333
|
-
}, "
|
|
16343
|
+
}, ownerHelp, identityHelp ? h2("br") : null, identityHelp)
|
|
16334
16344
|
)
|
|
16335
16345
|
)
|
|
16336
16346
|
),
|
|
@@ -16479,6 +16489,8 @@ function ScenePolicyEditor({
|
|
|
16479
16489
|
}
|
|
16480
16490
|
function AccessPolicySettingsPage({ channel: channel7, account, rpcCall, onSaved }) {
|
|
16481
16491
|
const definition = ACCESS_CHANNEL_DEFINITIONS[channel7];
|
|
16492
|
+
const ownerHelp = CONFIRMED_OWNER_CHANNELS.has(channel7) ? "\u5DF2\u7531\u63A5\u5165\u6D41\u7A0B\u786E\u8BA4\u7684\u6240\u6709\u8005\u53EF\u4EE5\u8BBF\u95EE\u5E76\u6267\u884C\u547D\u4EE4\uFF0C\u4E0D\u53D7\u672C\u9875\u9650\u5236\u3002\u672A\u8BC6\u522B\u5230\u6240\u6709\u8005\u8EAB\u4EFD\u65F6\uFF0C\u6309\u672C\u9875\u8BBF\u95EE\u8BBE\u7F6E\u6267\u884C\u3002" : "\u539F\u6240\u6709\u8005\u6216\u626B\u7801\u63A5\u5165\u8005\u59CB\u7EC8\u53EF\u4EE5\u8BBF\u95EE\u5E76\u6267\u884C\u547D\u4EE4\uFF1B\u4EE5\u4E0B\u8BBE\u7F6E\u4EC5\u7EA6\u675F\u5176\u4ED6\u7528\u6237\u3002";
|
|
16493
|
+
const identityHelp = channel7 === "feishu" ? "\u767D\u540D\u5355\u8BF7\u586B\u5199\u4F7F\u7528\u8005\u7684 Open ID\uFF0C\u4E0D\u662F\u673A\u5668\u4EBA\u7684 Open ID\u3002\u4EC5\u4FDD\u5B58\u901A\u914D\u7B26\u7684\u63A5\u5165\u914D\u7F6E\u4E0D\u5305\u542B\u6240\u6709\u8005\u8EAB\u4EFD\u3002" : null;
|
|
16482
16494
|
const initialPolicy = normalizeAccessPolicy(account?.accessPolicy);
|
|
16483
16495
|
const initialKey = JSON.stringify(initialPolicy);
|
|
16484
16496
|
const [draft, setDraft] = React28.useState(() => clonePolicy(
|
|
@@ -16542,6 +16554,8 @@ function AccessPolicySettingsPage({ channel: channel7, account, rpcCall, onSaved
|
|
|
16542
16554
|
policy: draft.direct,
|
|
16543
16555
|
userLabel: definition.directUserLabel,
|
|
16544
16556
|
placeholder: definition.directPlaceholder,
|
|
16557
|
+
ownerHelp,
|
|
16558
|
+
identityHelp,
|
|
16545
16559
|
disabled: saving,
|
|
16546
16560
|
onChange: (direct) => {
|
|
16547
16561
|
setDraft((current) => ({ ...current, direct }));
|
|
@@ -16554,6 +16568,8 @@ function AccessPolicySettingsPage({ channel: channel7, account, rpcCall, onSaved
|
|
|
16554
16568
|
policy: draft.group,
|
|
16555
16569
|
userLabel: definition.groupUserLabel ?? definition.directUserLabel,
|
|
16556
16570
|
placeholder: definition.groupPlaceholder ?? definition.directPlaceholder,
|
|
16571
|
+
ownerHelp,
|
|
16572
|
+
identityHelp: channel7 === "qq" ? "\u626B\u7801\u83B7\u5F97\u7684\u662F\u79C1\u804A\u8EAB\u4EFD\uFF0C\u7FA4\u804A\u53EA\u6709\u5339\u914D\u5DF2\u786E\u8BA4\u7684\u6240\u6709\u8005\u8EAB\u4EFD\u65F6\u624D\u8C41\u514D\uFF1B\u5176\u4ED6\u6210\u5458\u6309\u7FA4\u804A\u767D\u540D\u5355\u8BBE\u7F6E\u6267\u884C\u3002" : identityHelp,
|
|
16557
16573
|
disabled: saving || definition.groupSupported === false,
|
|
16558
16574
|
unsupported: definition.groupSupported === false,
|
|
16559
16575
|
onChange: (group) => {
|