@xmanrui/dsh-im 4.0.0 → 4.1.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 (74) hide show
  1. package/PROACTIVE_DELIVERY.en.md +321 -0
  2. package/PROACTIVE_DELIVERY.md +321 -0
  3. package/README.en.md +11 -5
  4. package/README.md +11 -5
  5. package/lib/client.js +1200 -110
  6. package/lib/index.js +229 -229
  7. package/package.json +4 -1
  8. package/plugin-src/client/channel-card-meta.js +44 -0
  9. package/plugin-src/client/channels/dingtalk/index.js +16 -8
  10. package/plugin-src/client/channels/feishu/index.js +17 -9
  11. package/plugin-src/client/channels/qq/index.js +16 -8
  12. package/plugin-src/client/channels/shared/token-channel.js +16 -8
  13. package/plugin-src/client/channels/wecom/index.js +16 -8
  14. package/plugin-src/client/channels/weixin/index.js +16 -8
  15. package/plugin-src/client/channels/whatsapp/index.js +16 -8
  16. package/plugin-src/client/delivery-settings.js +749 -0
  17. package/plugin-src/client/i18n.js +82 -0
  18. package/plugin-src/client/index.js +59 -22
  19. package/plugin-src/client/styles.js +72 -0
  20. package/plugin-src/host/channels/dingtalk/index.mjs +3 -0
  21. package/plugin-src/host/channels/dingtalk/production.mjs +4 -0
  22. package/plugin-src/host/channels/discord/index.mjs +6 -1
  23. package/plugin-src/host/channels/feishu/index.mjs +3 -0
  24. package/plugin-src/host/channels/feishu/production.mjs +4 -0
  25. package/plugin-src/host/channels/qq/index.mjs +6 -1
  26. package/plugin-src/host/channels/qq/production.mjs +2 -0
  27. package/plugin-src/host/channels/shared/production.mjs +7 -0
  28. package/plugin-src/host/channels/slack/index.mjs +6 -1
  29. package/plugin-src/host/channels/slack/production.mjs +4 -0
  30. package/plugin-src/host/channels/telegram/index.mjs +6 -1
  31. package/plugin-src/host/channels/wecom/index.mjs +6 -1
  32. package/plugin-src/host/channels/wecom/production.mjs +4 -0
  33. package/plugin-src/host/channels/weixin/index.mjs +3 -0
  34. package/plugin-src/host/channels/weixin/production.mjs +4 -0
  35. package/plugin-src/host/channels/whatsapp/index.mjs +6 -1
  36. package/plugin-src/host/channels/whatsapp/production.mjs +4 -0
  37. package/plugin-src/host/delivery-adapter.mjs +179 -0
  38. package/plugin-src/host/delivery-http.mjs +132 -0
  39. package/plugin-src/host/delivery-rpc.mjs +158 -0
  40. package/plugin-src/host/delivery-service.mjs +224 -0
  41. package/plugin-src/host/delivery-suggestions.mjs +135 -0
  42. package/plugin-src/host/index.mjs +32 -5
  43. package/scripts/verify-package.mjs +3 -0
  44. package/src/channels/dingtalk/dingtalk-api.mjs +33 -0
  45. package/src/channels/dingtalk/dingtalk-bridge.mjs +2 -2
  46. package/src/channels/dingtalk/dingtalk-controller.mjs +14 -0
  47. package/src/channels/dingtalk/dingtalk-runtime.mjs +39 -0
  48. package/src/channels/discord/discord-runtime.mjs +16 -0
  49. package/src/channels/feishu/bridge.mjs +4 -4
  50. package/src/channels/feishu/feishu-cards.mjs +4 -4
  51. package/src/channels/feishu/feishu-runtime.mjs +35 -0
  52. package/src/channels/feishu/multi-bot-controller.mjs +15 -0
  53. package/src/channels/qq/qq-bridge.mjs +2 -2
  54. package/src/channels/qq/qq-controller.mjs +14 -0
  55. package/src/channels/qq/qq-runtime.mjs +23 -0
  56. package/src/channels/shared/bot-workspace-store.mjs +192 -6
  57. package/src/channels/shared/i18n-en/feishu.mjs +6 -2
  58. package/src/channels/shared/i18n-en/shared-a.mjs +4 -0
  59. package/src/channels/shared/preset-command.mjs +2 -2
  60. package/src/channels/shared/text-harness-bridge.mjs +7 -2
  61. package/src/channels/shared/token-bot-controller.mjs +16 -0
  62. package/src/channels/shared/workspace-command.mjs +1 -1
  63. package/src/channels/slack/slack-controller.mjs +14 -0
  64. package/src/channels/slack/slack-runtime.mjs +24 -0
  65. package/src/channels/telegram/telegram-runtime.mjs +26 -0
  66. package/src/channels/wecom/state-store.mjs +4 -0
  67. package/src/channels/wecom/wecom-bridge.mjs +2 -2
  68. package/src/channels/wecom/wecom-controller.mjs +14 -0
  69. package/src/channels/wecom/wecom-runtime.mjs +21 -0
  70. package/src/channels/weixin/weixin-bridge.mjs +2 -2
  71. package/src/channels/weixin/weixin-controller.mjs +14 -0
  72. package/src/channels/weixin/weixin-runtime.mjs +24 -0
  73. package/src/channels/whatsapp/whatsapp-controller.mjs +14 -0
  74. package/src/channels/whatsapp/whatsapp-runtime.mjs +19 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xmanrui/dsh-im",
3
- "version": "4.0.0",
3
+ "version": "4.1.0",
4
4
  "description": "把九种 IM 机器人和公网 AI Office 接入本机 DeepSeek Harness。 Connect nine IM channels and a public AI Office to a local DeepSeek Harness.",
5
5
  "keywords": [
6
6
  "deepseek-harness",
@@ -64,6 +64,8 @@
64
64
  "plugin-src",
65
65
  "scripts",
66
66
  "src",
67
+ "PROACTIVE_DELIVERY.md",
68
+ "PROACTIVE_DELIVERY.en.md",
67
69
  "LICENSE",
68
70
  "README.md",
69
71
  "README.en.md",
@@ -100,6 +102,7 @@
100
102
  "qrcode": "1.5.4"
101
103
  },
102
104
  "devDependencies": {
105
+ "@deepseek-ai/cordis": "4.0.1",
103
106
  "@larksuiteoapi/node-sdk": "1.73.0",
104
107
  "@whiskeysockets/baileys": "7.0.0-rc14",
105
108
  "esbuild": "0.25.9",
@@ -2,6 +2,50 @@ import * as React from 'react';
2
2
 
3
3
  import { h, isEnglish } from './i18n.js';
4
4
 
5
+ export const BotSettingsContext = React.createContext(Object.freeze({
6
+ openBotSettings() {},
7
+ }));
8
+
9
+ function SettingsGlyph() {
10
+ return h('svg', {
11
+ viewBox: '0 0 24 24',
12
+ width: 16,
13
+ height: 16,
14
+ fill: 'none',
15
+ stroke: 'currentColor',
16
+ strokeWidth: 1.8,
17
+ strokeLinecap: 'round',
18
+ strokeLinejoin: 'round',
19
+ 'aria-hidden': 'true',
20
+ },
21
+ h('circle', { cx: 12, cy: 12, r: 3 }),
22
+ h('path', { d: 'M19.4 15a1.7 1.7 0 0 0 .34 1.88l.06.06-2.83 2.83-.06-.06a1.7 1.7 0 0 0-1.88-.34 1.7 1.7 0 0 0-1.03 1.55V21h-4v-.08A1.7 1.7 0 0 0 8.97 19.4a1.7 1.7 0 0 0-1.88.34l-.06.06-2.83-2.83.06-.06A1.7 1.7 0 0 0 4.6 15a1.7 1.7 0 0 0-1.52-1.03H3v-4h.08A1.7 1.7 0 0 0 4.6 8.97a1.7 1.7 0 0 0-.34-1.88l-.06-.06L7.03 4.2l.06.06a1.7 1.7 0 0 0 1.88.34A1.7 1.7 0 0 0 10 3.08V3h4v.08a1.7 1.7 0 0 0 1.03 1.52 1.7 1.7 0 0 0 1.88-.34l.06-.06 2.83 2.83-.06.06a1.7 1.7 0 0 0-.34 1.88A1.7 1.7 0 0 0 20.92 10H21v4h-.08A1.7 1.7 0 0 0 19.4 15Z' }));
23
+ }
24
+
25
+ export function BotSettingsButton({ channel, botId, botName, connected }) {
26
+ const { openBotSettings } = React.useContext(BotSettingsContext);
27
+ const tooltipId = React.useId();
28
+ return h('span', { className: 'dim-botSettingsAction' },
29
+ h('button', {
30
+ type: 'button',
31
+ className: 'dim-botSettingsButton',
32
+ 'data-delivery-channel': channel,
33
+ 'aria-label': '更多机器人设置',
34
+ 'aria-describedby': tooltipId,
35
+ onClick: () => openBotSettings?.({
36
+ channel,
37
+ botId,
38
+ botName,
39
+ connected: Boolean(connected),
40
+ }),
41
+ }, h(SettingsGlyph)),
42
+ h('span', {
43
+ id: tooltipId,
44
+ className: 'dim-botSettingsTooltip',
45
+ role: 'tooltip',
46
+ }, '更多机器人设置'));
47
+ }
48
+
5
49
  function messageErrorTime(value) {
6
50
  try {
7
51
  return new Intl.DateTimeFormat(isEnglish() ? 'en-US' : 'zh-CN', {
@@ -11,6 +11,7 @@ import {
11
11
  } from '../../agent-preset.js';
12
12
  import { useWorkspaceSnapshotFence } from '../../workspace-snapshot-fence.js';
13
13
  import {
14
+ BotSettingsButton,
14
15
  BotStatusMeta,
15
16
  ChannelListHeading,
16
17
  LastMessageErrorSummary,
@@ -238,14 +239,21 @@ export function AccountCard({
238
239
  h('div', { className: 'dim-botName' },
239
240
  h('h3', { title: account.bot.name }, account.bot.name),
240
241
  h('p', { title: account.bot.clientIdMasked }, account.bot.clientIdMasked))),
241
- h(BotStatusMeta, {
242
- className: 'ddt-health',
243
- dotClassName: 'ddt-dot',
244
- tone,
245
- stateLabel,
246
- lastCheckedAt: account.health.lastCheckedAt,
247
- formatCheckedTime: checkedTime,
248
- })),
242
+ h('div', { className: 'dim-botCardTools' },
243
+ h(BotStatusMeta, {
244
+ className: 'ddt-health',
245
+ dotClassName: 'ddt-dot',
246
+ tone,
247
+ stateLabel,
248
+ lastCheckedAt: account.health.lastCheckedAt,
249
+ formatCheckedTime: checkedTime,
250
+ }),
251
+ h(BotSettingsButton, {
252
+ channel: 'dingtalk',
253
+ botId: account.botId,
254
+ botName: account.bot.name,
255
+ connected: account.connected,
256
+ }))),
249
257
  h(WorkspaceEditor, {
250
258
  workspace: account.workspace,
251
259
  disabled: Boolean(busy),
@@ -24,6 +24,7 @@ import {
24
24
  } from "../../agent-preset.js";
25
25
  import { useWorkspaceSnapshotFence } from "../../workspace-snapshot-fence.js";
26
26
  import {
27
+ BotSettingsButton,
27
28
  BotStatusMeta,
28
29
  ChannelListHeading,
29
30
  LastMessageErrorSummary,
@@ -593,15 +594,22 @@ export function BotCard({
593
594
  h("h3", { id: titleId, title: bot.name }, bot.name),
594
595
  h("p", { title: bot.appIdMasked }, bot.appIdMasked ?? "应用标识已安全保存")),
595
596
  ),
596
- h(BotStatusMeta, {
597
- className: "bxf-healthPill",
598
- dotClassName: "bxf-dot",
599
- tone,
600
- stateLabel: HEALTH_LABELS[stateForDisplay] ?? "状态未知",
601
- lastCheckedAt: health.lastCheckedAt,
602
- formatCheckedTime,
603
- healthState: stateForDisplay,
604
- }),
597
+ h("div", { className: "dim-botCardTools" },
598
+ h(BotStatusMeta, {
599
+ className: "bxf-healthPill",
600
+ dotClassName: "bxf-dot",
601
+ tone,
602
+ stateLabel: HEALTH_LABELS[stateForDisplay] ?? "状态未知",
603
+ lastCheckedAt: health.lastCheckedAt,
604
+ formatCheckedTime,
605
+ healthState: stateForDisplay,
606
+ }),
607
+ h(BotSettingsButton, {
608
+ channel: "feishu",
609
+ botId: connection.botId,
610
+ botName: bot.name,
611
+ connected,
612
+ })),
605
613
  ),
606
614
  h(WorkspaceEditor, {
607
615
  workspace: connection.workspace,
@@ -12,6 +12,7 @@ import {
12
12
  } from '../../agent-preset.js';
13
13
  import { useWorkspaceSnapshotFence } from '../../workspace-snapshot-fence.js';
14
14
  import {
15
+ BotSettingsButton,
15
16
  BotStatusMeta,
16
17
  ChannelListHeading,
17
18
  LastMessageErrorSummary,
@@ -182,14 +183,21 @@ export function AccountCard({
182
183
  h('div', { className: 'ddt-avatar dim-botAvatar dqq-avatar', 'aria-hidden': 'true' }, h(QqLogoGlyph, { size: 29 })),
183
184
  h('div', { className: 'dim-botName' },
184
185
  h('h3', null, account.bot.name), h('p', null, account.bot.appIdMasked))),
185
- h(BotStatusMeta, {
186
- className: 'ddt-health',
187
- dotClassName: 'ddt-dot',
188
- tone,
189
- stateLabel,
190
- lastCheckedAt: account.health.lastCheckedAt,
191
- formatCheckedTime: checkedTime,
192
- })),
186
+ h('div', { className: 'dim-botCardTools' },
187
+ h(BotStatusMeta, {
188
+ className: 'ddt-health',
189
+ dotClassName: 'ddt-dot',
190
+ tone,
191
+ stateLabel,
192
+ lastCheckedAt: account.health.lastCheckedAt,
193
+ formatCheckedTime: checkedTime,
194
+ }),
195
+ h(BotSettingsButton, {
196
+ channel: 'qq',
197
+ botId: account.botId,
198
+ botName: account.bot.name,
199
+ connected: account.connected,
200
+ }))),
193
201
  h(WorkspaceEditor, {
194
202
  workspace: account.workspace,
195
203
  disabled: Boolean(busy),
@@ -12,6 +12,7 @@ import {
12
12
  } from '../../agent-preset.js';
13
13
  import { useWorkspaceSnapshotFence } from '../../workspace-snapshot-fence.js';
14
14
  import {
15
+ BotSettingsButton,
15
16
  BotStatusMeta,
16
17
  ChannelListHeading,
17
18
  LastMessageErrorSummary,
@@ -88,14 +89,21 @@ export function createTokenChannelSettings(definition) {
88
89
  h(LogoGlyph, { size: 29 })),
89
90
  h('div', { className: 'dim-botName' },
90
91
  h('h3', null, account.bot.name), h('p', null, identity))),
91
- h(BotStatusMeta, {
92
- className: 'ddt-health',
93
- dotClassName: 'ddt-dot',
94
- tone,
95
- stateLabel,
96
- lastCheckedAt: account.health.lastCheckedAt,
97
- formatCheckedTime: checkedTime,
98
- })),
92
+ h('div', { className: 'dim-botCardTools' },
93
+ h(BotStatusMeta, {
94
+ className: 'ddt-health',
95
+ dotClassName: 'ddt-dot',
96
+ tone,
97
+ stateLabel,
98
+ lastCheckedAt: account.health.lastCheckedAt,
99
+ formatCheckedTime: checkedTime,
100
+ }),
101
+ h(BotSettingsButton, {
102
+ channel: channel.toLowerCase(),
103
+ botId: account.botId,
104
+ botName: account.bot.name,
105
+ connected: account.connected,
106
+ }))),
99
107
  h(WorkspaceEditor, {
100
108
  workspace: account.workspace,
101
109
  disabled: Boolean(busy),
@@ -12,6 +12,7 @@ import {
12
12
  } from '../../agent-preset.js';
13
13
  import { useWorkspaceSnapshotFence } from '../../workspace-snapshot-fence.js';
14
14
  import {
15
+ BotSettingsButton,
15
16
  BotStatusMeta,
16
17
  ChannelListHeading,
17
18
  LastMessageErrorSummary,
@@ -181,14 +182,21 @@ export function AccountCard({
181
182
  h('div', { className: 'ddt-avatar dim-botAvatar dwecom-avatar', 'aria-hidden': 'true' }, h(WecomLogoGlyph, { size: 29 })),
182
183
  h('div', { className: 'dim-botName' },
183
184
  h('h3', null, account.bot.name), h('p', null, account.bot.appIdMasked))),
184
- h(BotStatusMeta, {
185
- className: 'ddt-health',
186
- dotClassName: 'ddt-dot',
187
- tone,
188
- stateLabel,
189
- lastCheckedAt: account.health.lastCheckedAt,
190
- formatCheckedTime: checkedTime,
191
- })),
185
+ h('div', { className: 'dim-botCardTools' },
186
+ h(BotStatusMeta, {
187
+ className: 'ddt-health',
188
+ dotClassName: 'ddt-dot',
189
+ tone,
190
+ stateLabel,
191
+ lastCheckedAt: account.health.lastCheckedAt,
192
+ formatCheckedTime: checkedTime,
193
+ }),
194
+ h(BotSettingsButton, {
195
+ channel: 'wecom',
196
+ botId: account.botId,
197
+ botName: account.bot.name,
198
+ connected: account.connected,
199
+ }))),
192
200
  h(WorkspaceEditor, {
193
201
  workspace: account.workspace,
194
202
  disabled: Boolean(busy),
@@ -23,6 +23,7 @@ import {
23
23
  } from '../../agent-preset.js';
24
24
  import { useWorkspaceSnapshotFence } from '../../workspace-snapshot-fence.js';
25
25
  import {
26
+ BotSettingsButton,
26
27
  BotStatusMeta,
27
28
  ChannelListHeading,
28
29
  LastMessageErrorSummary,
@@ -222,14 +223,21 @@ export function AccountCard({
222
223
  h('div', { className: 'dxw-accountIdentity dim-botIdentity' },
223
224
  h('div', { className: 'dxw-avatar dim-botAvatar', 'aria-hidden': 'true' }, h(WeixinLogoGlyph, { size: 27 })),
224
225
  h('div', { className: 'dim-botName' }, h('h3', null, account.bot.name), h('p', null, account.bot.accountIdMasked))),
225
- h(BotStatusMeta, {
226
- className: 'dxw-health',
227
- dotClassName: 'dxw-dot',
228
- tone,
229
- stateLabel: account.connected ? '运行正常' : state === 'connecting' ? '正在连接' : '连接未就绪',
230
- lastCheckedAt: account.health.lastCheckedAt,
231
- formatCheckedTime: checkedTime,
232
- })),
226
+ h('div', { className: 'dim-botCardTools' },
227
+ h(BotStatusMeta, {
228
+ className: 'dxw-health',
229
+ dotClassName: 'dxw-dot',
230
+ tone,
231
+ stateLabel: account.connected ? '运行正常' : state === 'connecting' ? '正在连接' : '连接未就绪',
232
+ lastCheckedAt: account.health.lastCheckedAt,
233
+ formatCheckedTime: checkedTime,
234
+ }),
235
+ h(BotSettingsButton, {
236
+ channel: 'weixin',
237
+ botId: account.botId,
238
+ botName: account.bot.name,
239
+ connected: account.connected,
240
+ }))),
233
241
  h(WorkspaceEditor, {
234
242
  workspace: account.workspace,
235
243
  disabled: Boolean(busy),
@@ -12,6 +12,7 @@ import {
12
12
  } from '../../agent-preset.js';
13
13
  import { useWorkspaceSnapshotFence } from '../../workspace-snapshot-fence.js';
14
14
  import {
15
+ BotSettingsButton,
15
16
  BotStatusMeta,
16
17
  ChannelListHeading,
17
18
  LastMessageErrorSummary,
@@ -318,14 +319,21 @@ export function WhatsappAccountCard({
318
319
  }, h(WhatsappLogoGlyph, { size: 29 })),
319
320
  h('div', { className: 'dim-botName' },
320
321
  h('h3', null, account.bot.name), h('p', null, account.bot.idMasked))),
321
- h(BotStatusMeta, {
322
- className: 'ddt-health',
323
- dotClassName: 'ddt-dot',
324
- tone,
325
- stateLabel,
326
- lastCheckedAt: account.health.lastCheckedAt,
327
- formatCheckedTime: checkedTime,
328
- })),
322
+ h('div', { className: 'dim-botCardTools' },
323
+ h(BotStatusMeta, {
324
+ className: 'ddt-health',
325
+ dotClassName: 'ddt-dot',
326
+ tone,
327
+ stateLabel,
328
+ lastCheckedAt: account.health.lastCheckedAt,
329
+ formatCheckedTime: checkedTime,
330
+ }),
331
+ h(BotSettingsButton, {
332
+ channel: 'whatsapp',
333
+ botId: account.botId,
334
+ botName: account.bot.name,
335
+ connected: account.connected,
336
+ }))),
329
337
  h(WorkspaceEditor, {
330
338
  workspace: account.workspace,
331
339
  disabled: Boolean(busy),