@xmanrui/dsh-im 1.0.2 → 1.2.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.
- package/README.en.md +23 -3
- package/README.md +23 -3
- package/assets/logo-dsh-im-chinese-readme-3x2.png +0 -0
- package/assets/logo_cn.png +0 -0
- package/lib/client.js +815 -560
- package/lib/index.js +163 -163
- package/package.json +1 -1
- package/plugin-src/client/agent-preset.js +15 -6
- package/plugin-src/client/channel-card-meta.js +48 -0
- package/plugin-src/client/channels/dingtalk/index.js +25 -19
- package/plugin-src/client/channels/dingtalk/styles.js +0 -6
- package/plugin-src/client/channels/feishu/index.js +41 -35
- package/plugin-src/client/channels/feishu/styles.js +0 -5
- package/plugin-src/client/channels/qq/index.js +24 -16
- package/plugin-src/client/channels/shared/token-channel.js +32 -24
- package/plugin-src/client/channels/wecom/index.js +24 -16
- package/plugin-src/client/channels/weixin/index.js +29 -23
- package/plugin-src/client/channels/weixin/styles.js +0 -5
- package/plugin-src/client/channels/whatsapp/api.js +11 -0
- package/plugin-src/client/channels/whatsapp/index.js +152 -23
- package/plugin-src/client/channels/whatsapp/styles.js +25 -0
- package/plugin-src/client/i18n.js +20 -0
- package/plugin-src/client/styles.js +23 -8
- package/plugin-src/host/channels/whatsapp/rpc.mjs +19 -1
- package/plugin-src/host/index.mjs +14 -1
- package/src/channels/dingtalk/dingtalk-api.mjs +215 -2
- package/src/channels/dingtalk/dingtalk-bridge.mjs +155 -4
- package/src/channels/discord/discord-api.mjs +134 -6
- package/src/channels/discord/discord-runtime.mjs +15 -4
- package/src/channels/feishu/bridge.mjs +223 -15
- package/src/channels/feishu/feishu-channel.mjs +227 -1
- package/src/channels/feishu/plugin-controller.mjs +1 -0
- package/src/channels/qq/qq-bridge.mjs +217 -10
- package/src/channels/shared/editable-message-stream.mjs +18 -1
- package/src/channels/shared/harness-client.mjs +99 -7
- package/src/channels/shared/semantic/artifact.mjs +748 -0
- package/src/channels/shared/semantic/delivery.mjs +153 -0
- package/src/channels/shared/text-harness-bridge.mjs +149 -3
- package/src/channels/shared/workspace-session.mjs +15 -1
- package/src/channels/slack/manifest.mjs +1 -0
- package/src/channels/slack/slack-api.mjs +167 -4
- package/src/channels/slack/slack-runtime.mjs +21 -5
- package/src/channels/telegram/telegram-api.mjs +111 -5
- package/src/channels/telegram/telegram-runtime.mjs +18 -4
- package/src/channels/wecom/wecom-bridge.mjs +260 -12
- package/src/channels/weixin/weixin-api.mjs +268 -2
- package/src/channels/weixin/weixin-bridge.mjs +134 -3
- package/src/channels/weixin/weixin-controller.mjs +5 -1
- package/src/channels/weixin/weixin-runtime.mjs +5 -1
- package/src/channels/whatsapp/config-store.mjs +43 -0
- package/src/channels/whatsapp/whatsapp-controller.mjs +22 -1
- package/src/channels/whatsapp/whatsapp-runtime.mjs +149 -5
package/package.json
CHANGED
|
@@ -46,6 +46,7 @@ export function normalizeAgentPresetCatalog(value) {
|
|
|
46
46
|
|
|
47
47
|
export function AgentPresetEditor({ agentPreset = '', disabled = false, onSave }) {
|
|
48
48
|
const catalog = React.useContext(AgentPresetCatalogContext) ?? EMPTY_AGENT_PRESET_CATALOG;
|
|
49
|
+
const helpId = React.useId();
|
|
49
50
|
const current = normalizeAgentPresetId(agentPreset);
|
|
50
51
|
const [saving, setSaving] = React.useState(false);
|
|
51
52
|
const [error, setError] = React.useState(null);
|
|
@@ -78,7 +79,20 @@ export function AgentPresetEditor({ agentPreset = '', disabled = false, onSave }
|
|
|
78
79
|
|
|
79
80
|
return h('div', { className: 'dim-preset' },
|
|
80
81
|
h('div', { className: 'dim-presetHeader' },
|
|
81
|
-
h('span',
|
|
82
|
+
h('span', { className: 'dim-presetTitle' },
|
|
83
|
+
h('span', null, 'Agent Preset'),
|
|
84
|
+
h('span', { className: 'dim-presetHelp' },
|
|
85
|
+
h('button', {
|
|
86
|
+
type: 'button',
|
|
87
|
+
className: 'dim-presetHelpButton',
|
|
88
|
+
'aria-label': '查看 Agent Preset 说明',
|
|
89
|
+
'aria-describedby': helpId,
|
|
90
|
+
}, h('span', { 'aria-hidden': 'true' }, '?')),
|
|
91
|
+
h('span', {
|
|
92
|
+
id: helpId,
|
|
93
|
+
className: 'dim-presetTooltip',
|
|
94
|
+
role: 'tooltip',
|
|
95
|
+
}, '只影响新建会话;若当前聊天已有会话,先发送 /new,再发送普通消息生效。'))),
|
|
82
96
|
saving ? h('span', { className: 'dim-presetStatus' }, '保存中…') : null),
|
|
83
97
|
React.createElement('select', {
|
|
84
98
|
className: 'dim-presetSelect',
|
|
@@ -96,11 +110,6 @@ export function AgentPresetEditor({ agentPreset = '', disabled = false, onSave }
|
|
|
96
110
|
: item.label && item.label !== item.id ? `${item.label}(${item.id})` : item.id,
|
|
97
111
|
)),
|
|
98
112
|
),
|
|
99
|
-
h(
|
|
100
|
-
'small',
|
|
101
|
-
{ className: 'dim-presetHelp' },
|
|
102
|
-
'只影响新建会话;若当前聊天已有会话,先发送 /new,再发送普通消息生效。',
|
|
103
|
-
),
|
|
104
113
|
error || currentUnavailable ? h(
|
|
105
114
|
'p',
|
|
106
115
|
{ className: 'dim-presetError', role: error ? 'alert' : 'status' },
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
import { h } from './i18n.js';
|
|
4
|
+
|
|
5
|
+
export function ChannelListHeading({ className = '', id, title, connectionLabel }) {
|
|
6
|
+
const helpId = React.useId();
|
|
7
|
+
return h('div', { className: `${className} dim-listHeading`.trim() },
|
|
8
|
+
h('div', { className: 'dim-listTitle' },
|
|
9
|
+
h('h3', id ? { id } : null, title),
|
|
10
|
+
h('span', { className: 'dim-channelHelp' },
|
|
11
|
+
h('button', {
|
|
12
|
+
type: 'button',
|
|
13
|
+
className: 'dim-channelHelpButton',
|
|
14
|
+
'aria-label': '查看消息通道说明',
|
|
15
|
+
'aria-describedby': helpId,
|
|
16
|
+
}, h('span', { 'aria-hidden': 'true' }, '?')),
|
|
17
|
+
h('span', {
|
|
18
|
+
id: helpId,
|
|
19
|
+
className: 'dim-channelTooltip',
|
|
20
|
+
role: 'tooltip',
|
|
21
|
+
},
|
|
22
|
+
h('span', null, '消息通道'),
|
|
23
|
+
h('strong', null, connectionLabel)))));
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function BotStatusMeta({
|
|
27
|
+
className = '',
|
|
28
|
+
dotClassName = '',
|
|
29
|
+
tone,
|
|
30
|
+
stateLabel,
|
|
31
|
+
lastCheckedAt,
|
|
32
|
+
formatCheckedTime,
|
|
33
|
+
healthState,
|
|
34
|
+
}) {
|
|
35
|
+
return h('div', { className: 'dim-botHealthGroup' },
|
|
36
|
+
h('div', {
|
|
37
|
+
className: `${className} dim-botHealth`.trim(),
|
|
38
|
+
...(healthState ? { 'data-health': healthState } : {}),
|
|
39
|
+
},
|
|
40
|
+
h('span', {
|
|
41
|
+
className: `${dotClassName} dim-healthDot`.trim(),
|
|
42
|
+
'data-tone': tone,
|
|
43
|
+
}),
|
|
44
|
+
h('span', null, stateLabel)),
|
|
45
|
+
h('div', { className: 'dim-lastChecked' },
|
|
46
|
+
h('span', null, '最近检查'),
|
|
47
|
+
h('span', null, formatCheckedTime(lastCheckedAt))));
|
|
48
|
+
}
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
EMPTY_AGENT_PRESET_CATALOG,
|
|
10
10
|
} from '../../agent-preset.js';
|
|
11
11
|
import { useWorkspaceSnapshotFence } from '../../workspace-snapshot-fence.js';
|
|
12
|
+
import { BotStatusMeta, ChannelListHeading } from '../../channel-card-meta.js';
|
|
12
13
|
import {
|
|
13
14
|
DINGTALK_ENDPOINTS,
|
|
14
15
|
DINGTALK_RPC_CHANNEL,
|
|
@@ -235,13 +236,14 @@ export function AccountCard({
|
|
|
235
236
|
h('div', { className: 'dim-botName' },
|
|
236
237
|
h('h3', { title: account.bot.name }, account.bot.name),
|
|
237
238
|
h('p', { title: account.bot.clientIdMasked }, account.bot.clientIdMasked))),
|
|
238
|
-
h(
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
239
|
+
h(BotStatusMeta, {
|
|
240
|
+
className: 'ddt-health',
|
|
241
|
+
dotClassName: 'ddt-dot',
|
|
242
|
+
tone,
|
|
243
|
+
stateLabel,
|
|
244
|
+
lastCheckedAt: account.health.lastCheckedAt,
|
|
245
|
+
formatCheckedTime: checkedTime,
|
|
246
|
+
})),
|
|
245
247
|
h(WorkspaceEditor, {
|
|
246
248
|
workspace: account.workspace,
|
|
247
249
|
disabled: Boolean(busy),
|
|
@@ -253,16 +255,17 @@ export function AccountCard({
|
|
|
253
255
|
onSave: onAgentPresetSave,
|
|
254
256
|
}),
|
|
255
257
|
h('div', { className: 'ddt-accountFooter dim-cardFooter' },
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
h(
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
'
|
|
258
|
+
h('div', { className: 'dim-cardFooterLayout' },
|
|
259
|
+
h('div', { className: 'ddt-actions dim-cardActions' },
|
|
260
|
+
h(Button, { className: 'dim-cardAction', onClick: onReconnect, disabled: Boolean(busy) },
|
|
261
|
+
busy === 'reconnect' ? '检查中…' : account.connected ? '检查连接' : '重试连接'),
|
|
262
|
+
h(Button, { className: 'dim-cardAction', kind: 'danger', onClick: onRequestRemove, disabled: Boolean(busy) },
|
|
263
|
+
'移除接入')),
|
|
264
|
+
summary ? h('div', { className: 'ddt-summary dim-cardSummary' }, summary) : null,
|
|
265
|
+
feedback ? h('div', {
|
|
266
|
+
className: 'ddt-summary dim-cardFeedback',
|
|
267
|
+
role: 'status',
|
|
268
|
+
}, feedback) : null))),
|
|
266
269
|
removing ? h(RemoveConfirmation, {
|
|
267
270
|
account,
|
|
268
271
|
busy: busy === 'delete',
|
|
@@ -273,8 +276,11 @@ export function AccountCard({
|
|
|
273
276
|
|
|
274
277
|
function AccountList(props) {
|
|
275
278
|
return h('section', { className: 'dim-listSection' },
|
|
276
|
-
h(
|
|
277
|
-
|
|
279
|
+
h(ChannelListHeading, {
|
|
280
|
+
className: 'ddt-listHeading',
|
|
281
|
+
title: '已接入的钉钉机器人',
|
|
282
|
+
connectionLabel: 'Stream 长连接',
|
|
283
|
+
}),
|
|
278
284
|
h('ul', { className: 'ddt-list dim-botList' }, props.bots.map((account) => h('li', { key: account.botId },
|
|
279
285
|
h(AccountCard, {
|
|
280
286
|
account,
|
|
@@ -86,10 +86,6 @@ const CSS = String.raw`
|
|
|
86
86
|
.ddt-accountIdentity h3 { overflow: hidden; font-size: 15px; text-overflow: ellipsis; white-space: nowrap; }
|
|
87
87
|
.ddt-accountIdentity p { margin-top: 4px; color: var(--dsw-alias-label-secondary, #646a73); font: 12px ui-monospace, SFMono-Regular, monospace; }
|
|
88
88
|
.ddt-health { display: inline-flex; align-items: center; gap: 7px; color: var(--dsw-alias-label-secondary, #646a73); font-size: 12px; white-space: nowrap; }
|
|
89
|
-
.ddt-metrics { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; margin: 20px 0; }
|
|
90
|
-
.ddt-metric { min-width: 0; padding: 12px; border-radius: 9px; background: var(--dsw-alias-interactive-bg-hover, #f7f8fa); }
|
|
91
|
-
.ddt-metric dt { color: var(--dsw-alias-label-tertiary, #8f959e); font-size: 11px; }
|
|
92
|
-
.ddt-metric dd { overflow: hidden; margin: 5px 0 0; font-size: 13px; text-overflow: ellipsis; white-space: nowrap; }
|
|
93
89
|
.ddt-accountFooter { display: flex; align-items: center; justify-content: space-between; gap: 15px; padding-top: 16px; border-top: 1px solid var(--dsw-alias-border-l1, #eef0f3); }
|
|
94
90
|
.ddt-accountFooter .ddt-actions { flex: none; flex-wrap: nowrap; gap: 8px; margin-top: 0; }
|
|
95
91
|
.ddt-accountFooter .ddt-button { flex: none; white-space: nowrap; }
|
|
@@ -110,8 +106,6 @@ const CSS = String.raw`
|
|
|
110
106
|
.ddt-qrLayout { grid-template-columns: minmax(0, 1fr); justify-items: center; gap: 24px; }
|
|
111
107
|
.ddt-qrColumn { width: 100%; min-width: 0; }
|
|
112
108
|
.ddt-qrCopy { width: 100%; }
|
|
113
|
-
.ddt-metrics { gap: 8px; }
|
|
114
|
-
.ddt-metric { padding: 10px; }
|
|
115
109
|
}
|
|
116
110
|
@media (max-width: 720px) {
|
|
117
111
|
.ddt-heading, .ddt-accountTop { flex-direction: column; align-items: stretch; }
|
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
EMPTY_AGENT_PRESET_CATALOG,
|
|
24
24
|
} from "../../agent-preset.js";
|
|
25
25
|
import { useWorkspaceSnapshotFence } from "../../workspace-snapshot-fence.js";
|
|
26
|
+
import { BotStatusMeta, ChannelListHeading } from "../../channel-card-meta.js";
|
|
26
27
|
import { installFeishuStyles } from "./styles.js";
|
|
27
28
|
|
|
28
29
|
export const name = "feishu-settings";
|
|
@@ -591,15 +592,15 @@ export function BotCard({
|
|
|
591
592
|
h("h3", { id: titleId, title: bot.name }, bot.name),
|
|
592
593
|
h("p", { title: bot.appIdMasked }, bot.appIdMasked ?? "应用标识已安全保存")),
|
|
593
594
|
),
|
|
594
|
-
h(
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
595
|
+
h(BotStatusMeta, {
|
|
596
|
+
className: "bxf-healthPill",
|
|
597
|
+
dotClassName: "bxf-dot",
|
|
598
|
+
tone,
|
|
599
|
+
stateLabel: HEALTH_LABELS[stateForDisplay] ?? "状态未知",
|
|
600
|
+
lastCheckedAt: health.lastCheckedAt,
|
|
601
|
+
formatCheckedTime,
|
|
602
|
+
healthState: stateForDisplay,
|
|
603
|
+
}),
|
|
603
604
|
),
|
|
604
605
|
h(WorkspaceEditor, {
|
|
605
606
|
workspace: connection.workspace,
|
|
@@ -629,30 +630,31 @@ export function BotCard({
|
|
|
629
630
|
}, provisionContent)
|
|
630
631
|
: null,
|
|
631
632
|
h("div", { className: "bxf-connectedFooter dim-cardFooter" },
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
h(
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
"
|
|
655
|
-
|
|
633
|
+
h("div", { className: "dim-cardFooterLayout" },
|
|
634
|
+
h("div", { className: "bxf-actions bxf-botActions dim-cardActions" },
|
|
635
|
+
h(Button, {
|
|
636
|
+
className: "dim-cardAction", onClick: onReconnect,
|
|
637
|
+
disabled: Boolean(busy), "aria-busy": busy === "reconnect" ? "true" : undefined,
|
|
638
|
+
"aria-label": `${connected ? "检查连接" : "重试连接"}${bot.name}`,
|
|
639
|
+
}, busy === "reconnect" ? (connected ? "检查中…" : "正在连接…") : connected ? "检查连接" : "重试连接"),
|
|
640
|
+
h(Button, {
|
|
641
|
+
className: "bxf-repairButton dim-cardAction",
|
|
642
|
+
onClick: onRepairCallback,
|
|
643
|
+
disabled: Boolean(busy) || repairDisabled,
|
|
644
|
+
"aria-busy": busy === "callback-repair" ? "true" : undefined,
|
|
645
|
+
"aria-label": `修复${bot.name}的卡片按钮`,
|
|
646
|
+
}, busy === "callback-repair" ? "等待扫码…" : "修复卡片按钮"),
|
|
647
|
+
h(Button, {
|
|
648
|
+
className: "dim-cardAction", kind: "danger", onClick: onRequestRemove,
|
|
649
|
+
disabled: Boolean(busy), ref: removeButtonRef,
|
|
650
|
+
"aria-label": `从 DeepSeek Harness 移除${bot.name}`,
|
|
651
|
+
}, "移除接入")),
|
|
652
|
+
summary ? h("div", { className: "bxf-healthSummary dim-cardSummary", "data-error": actionError || connection.error ? "true" : undefined },
|
|
653
|
+
summary) : null,
|
|
654
|
+
testNotice ? h("div", {
|
|
655
|
+
className: "bxf-healthSummary dim-cardFeedback",
|
|
656
|
+
role: "status",
|
|
657
|
+
}, testNotice) : null),
|
|
656
658
|
),
|
|
657
659
|
),
|
|
658
660
|
removing
|
|
@@ -668,8 +670,12 @@ export function BotCard({
|
|
|
668
670
|
|
|
669
671
|
function BotList(props) {
|
|
670
672
|
return h("section", { className: "bxf-listSection dim-listSection", "aria-labelledby": "bxf-bot-list-title" },
|
|
671
|
-
h(
|
|
672
|
-
|
|
673
|
+
h(ChannelListHeading, {
|
|
674
|
+
className: "bxf-listHeading",
|
|
675
|
+
id: "bxf-bot-list-title",
|
|
676
|
+
title: "已接入的机器人",
|
|
677
|
+
connectionLabel: "长连接",
|
|
678
|
+
}),
|
|
673
679
|
h("ul", { className: "bxf-botList dim-botList", role: "list" },
|
|
674
680
|
props.bots.map((bot) => h("li", { key: bot.botId },
|
|
675
681
|
h(BotCard, {
|
|
@@ -402,10 +402,6 @@ const CSS = String.raw`
|
|
|
402
402
|
.bxf-healthPill[data-health="degraded"], .bxf-healthPill[data-health="checking"], .bxf-healthPill[data-health="connecting"] { color: var(--bxf-warning); background: color-mix(in srgb, var(--bxf-warning) 10%, transparent); }
|
|
403
403
|
.bxf-healthPill[data-health="offline"], .bxf-healthPill[data-health="error"] { color: var(--bxf-error); background: color-mix(in srgb, var(--bxf-error) 10%, transparent); }
|
|
404
404
|
|
|
405
|
-
.bxf-statusGrid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; margin-top: 22px; }
|
|
406
|
-
.bxf-metric { min-width: 0; border: 1px solid var(--dsw-alias-border-l2, #dee0e3); border-radius: 9px; padding: 12px 13px; background: var(--dsw-alias-bg-module-platform, #f7f8fa); }
|
|
407
|
-
.bxf-metric dt { color: var(--dsw-alias-label-tertiary, #8f959e); font-size: 11px; line-height: 17px; }
|
|
408
|
-
.bxf-metric dd { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--dsw-alias-label-primary, #1f2329); font-size: 12px; line-height: 18px; font-weight: 550; margin: 3px 0 0; }
|
|
409
405
|
|
|
410
406
|
.bxf-responseMode { min-width: 0; display: grid; grid-template-columns: minmax(0, 1fr) max-content; align-items: center; column-gap: 10px; row-gap: 5px; margin-top: 6px; padding: 8px 10px; border: 1px solid var(--dsw-alias-border-l1, #eef0f3); border-radius: 9px; background: var(--dsw-alias-bg-module-platform, #f7f8fa); }
|
|
411
407
|
.bxf-responseModeHeader { display: contents; color: var(--dsw-alias-label-secondary, #646a73); font-size: 12px; line-height: normal; }
|
|
@@ -517,7 +513,6 @@ const CSS = String.raw`
|
|
|
517
513
|
.bxf-qrLayout { grid-template-columns: minmax(0, 1fr); justify-items: center; }
|
|
518
514
|
.bxf-botProvision .bxf-qrLayout { grid-template-columns: minmax(0, 1fr); }
|
|
519
515
|
.bxf-qrCopy { width: 100%; }
|
|
520
|
-
.bxf-statusGrid { grid-template-columns: minmax(0, 1fr); }
|
|
521
516
|
.bxf-connectedTop { align-items: flex-start; flex-direction: column; }
|
|
522
517
|
.bxf-inlineError { grid-template-columns: minmax(0, 1fr); padding: 20px; }
|
|
523
518
|
.bxf-statusNotice { align-items: flex-start; flex-wrap: wrap; }
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
EMPTY_AGENT_PRESET_CATALOG,
|
|
11
11
|
} from '../../agent-preset.js';
|
|
12
12
|
import { useWorkspaceSnapshotFence } from '../../workspace-snapshot-fence.js';
|
|
13
|
+
import { BotStatusMeta, ChannelListHeading } from '../../channel-card-meta.js';
|
|
13
14
|
import { installDingtalkStyles } from '../dingtalk/styles.js';
|
|
14
15
|
import {
|
|
15
16
|
QQ_ENDPOINTS,
|
|
@@ -176,11 +177,14 @@ export function AccountCard({
|
|
|
176
177
|
h('div', { className: 'ddt-avatar dim-botAvatar dqq-avatar', 'aria-hidden': 'true' }, h(QqLogoGlyph, { size: 29 })),
|
|
177
178
|
h('div', { className: 'dim-botName' },
|
|
178
179
|
h('h3', null, account.bot.name), h('p', null, account.bot.appIdMasked))),
|
|
179
|
-
h(
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
180
|
+
h(BotStatusMeta, {
|
|
181
|
+
className: 'ddt-health',
|
|
182
|
+
dotClassName: 'ddt-dot',
|
|
183
|
+
tone,
|
|
184
|
+
stateLabel,
|
|
185
|
+
lastCheckedAt: account.health.lastCheckedAt,
|
|
186
|
+
formatCheckedTime: checkedTime,
|
|
187
|
+
})),
|
|
184
188
|
h(WorkspaceEditor, {
|
|
185
189
|
workspace: account.workspace,
|
|
186
190
|
disabled: Boolean(busy),
|
|
@@ -192,15 +196,16 @@ export function AccountCard({
|
|
|
192
196
|
onSave: onAgentPresetSave,
|
|
193
197
|
}),
|
|
194
198
|
h('div', { className: 'ddt-accountFooter dim-cardFooter' },
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
'
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
199
|
+
h('div', { className: 'dim-cardFooterLayout' },
|
|
200
|
+
h('div', { className: 'ddt-actions dim-cardActions' },
|
|
201
|
+
h(Button, { className: 'dim-cardAction', onClick: onReconnect, disabled: Boolean(busy) }, busy === 'reconnect' ? '检查中…' : account.connected ? '检查连接' : '重试连接'),
|
|
202
|
+
h(Button, { className: 'dim-cardAction', kind: 'danger', onClick: onRequestRemove, disabled: Boolean(busy) }, '移除接入')),
|
|
203
|
+
summary ? h('div', { className: 'ddt-summary dim-cardSummary' }, summary) : null,
|
|
204
|
+
feedback ? h('div', {
|
|
205
|
+
className: 'ddt-summary dim-cardFeedback',
|
|
206
|
+
role: 'status',
|
|
207
|
+
'aria-live': 'polite',
|
|
208
|
+
}, feedback) : null))),
|
|
204
209
|
removing ? h(RemoveConfirmation, {
|
|
205
210
|
account, busy: busy === 'delete', onConfirm: onConfirmRemove, onCancel: onCancelRemove,
|
|
206
211
|
}) : null);
|
|
@@ -432,8 +437,11 @@ export function QqSettingsTab({ rpcCall }) {
|
|
|
432
437
|
|
|
433
438
|
const botList = model.bots.length > 0
|
|
434
439
|
? h('section', { className: 'dim-listSection' },
|
|
435
|
-
h(
|
|
436
|
-
|
|
440
|
+
h(ChannelListHeading, {
|
|
441
|
+
className: 'ddt-listHeading',
|
|
442
|
+
title: '已绑定的 QQ 机器人',
|
|
443
|
+
connectionLabel: 'WebSocket 长连接',
|
|
444
|
+
}),
|
|
437
445
|
h('ul', { className: 'ddt-list dim-botList' }, model.bots.map((account) =>
|
|
438
446
|
h('li', { key: account.botId }, h(AccountCard, {
|
|
439
447
|
account,
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
EMPTY_AGENT_PRESET_CATALOG,
|
|
11
11
|
} from '../../agent-preset.js';
|
|
12
12
|
import { useWorkspaceSnapshotFence } from '../../workspace-snapshot-fence.js';
|
|
13
|
+
import { BotStatusMeta, ChannelListHeading } from '../../channel-card-meta.js';
|
|
13
14
|
|
|
14
15
|
const Button = React.forwardRef(function Button(
|
|
15
16
|
{ children, kind = 'secondary', className = '', ...props },
|
|
@@ -82,14 +83,14 @@ export function createTokenChannelSettings(definition) {
|
|
|
82
83
|
h(LogoGlyph, { size: 29 })),
|
|
83
84
|
h('div', { className: 'dim-botName' },
|
|
84
85
|
h('h3', null, account.bot.name), h('p', null, identity))),
|
|
85
|
-
h(
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
86
|
+
h(BotStatusMeta, {
|
|
87
|
+
className: 'ddt-health',
|
|
88
|
+
dotClassName: 'ddt-dot',
|
|
89
|
+
tone,
|
|
90
|
+
stateLabel,
|
|
91
|
+
lastCheckedAt: account.health.lastCheckedAt,
|
|
92
|
+
formatCheckedTime: checkedTime,
|
|
93
|
+
})),
|
|
93
94
|
h(WorkspaceEditor, {
|
|
94
95
|
workspace: account.workspace,
|
|
95
96
|
disabled: Boolean(busy),
|
|
@@ -106,20 +107,24 @@ export function createTokenChannelSettings(definition) {
|
|
|
106
107
|
onSave: onAccountSettingsSave,
|
|
107
108
|
}) : null,
|
|
108
109
|
h('div', { className: 'ddt-accountFooter dim-cardFooter' },
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
110
|
+
h('div', { className: 'dim-cardFooterLayout' },
|
|
111
|
+
h('div', { className: 'ddt-actions dim-cardActions' },
|
|
112
|
+
h(Button, {
|
|
113
|
+
className: 'dim-cardAction',
|
|
114
|
+
onClick: onReconnect,
|
|
115
|
+
disabled: Boolean(busy),
|
|
116
|
+
}, busy === 'reconnect' ? '检查中…' : account.connected ? '检查连接' : '重试连接'),
|
|
117
|
+
h(Button, {
|
|
118
|
+
className: 'dim-cardAction',
|
|
119
|
+
kind: 'danger',
|
|
120
|
+
onClick: onRequestRemove,
|
|
121
|
+
disabled: Boolean(busy),
|
|
122
|
+
}, '移除接入')),
|
|
123
|
+
summary ? h('div', { className: 'ddt-summary dim-cardSummary' }, summary) : null,
|
|
124
|
+
testNotice ? h('div', {
|
|
125
|
+
className: 'ddt-summary dim-cardFeedback',
|
|
126
|
+
role: 'status',
|
|
127
|
+
}, testNotice) : null))),
|
|
123
128
|
removing ? h('div', { className: 'ddt-confirm dim-confirm', role: 'alertdialog' },
|
|
124
129
|
h('strong', null, `从 DeepSeek Harness 移除“${account.bot.name}”?`),
|
|
125
130
|
h('p', null, `这会停止消息连接,并删除本机保存的 ${credentialNoun}、机器人配置及会话映射。${platformLabel}中的机器人不会被自动删除。`),
|
|
@@ -267,8 +272,11 @@ export function createTokenChannelSettings(definition) {
|
|
|
267
272
|
|
|
268
273
|
const botList = model.bots.length > 0
|
|
269
274
|
? h('section', { className: 'dim-listSection' },
|
|
270
|
-
h(
|
|
271
|
-
|
|
275
|
+
h(ChannelListHeading, {
|
|
276
|
+
className: 'ddt-listHeading',
|
|
277
|
+
title: `已接入的 ${channel} 机器人`,
|
|
278
|
+
connectionLabel,
|
|
279
|
+
}),
|
|
272
280
|
h('ul', { className: 'ddt-list dim-botList' }, model.bots.map((account) =>
|
|
273
281
|
h('li', { key: account.botId }, h(AccountCard, {
|
|
274
282
|
account,
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
EMPTY_AGENT_PRESET_CATALOG,
|
|
11
11
|
} from '../../agent-preset.js';
|
|
12
12
|
import { useWorkspaceSnapshotFence } from '../../workspace-snapshot-fence.js';
|
|
13
|
+
import { BotStatusMeta, ChannelListHeading } from '../../channel-card-meta.js';
|
|
13
14
|
import { installDingtalkStyles } from '../dingtalk/styles.js';
|
|
14
15
|
import {
|
|
15
16
|
WECOM_ENDPOINTS,
|
|
@@ -175,11 +176,14 @@ export function AccountCard({
|
|
|
175
176
|
h('div', { className: 'ddt-avatar dim-botAvatar dwecom-avatar', 'aria-hidden': 'true' }, h(WecomLogoGlyph, { size: 29 })),
|
|
176
177
|
h('div', { className: 'dim-botName' },
|
|
177
178
|
h('h3', null, account.bot.name), h('p', null, account.bot.appIdMasked))),
|
|
178
|
-
h(
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
179
|
+
h(BotStatusMeta, {
|
|
180
|
+
className: 'ddt-health',
|
|
181
|
+
dotClassName: 'ddt-dot',
|
|
182
|
+
tone,
|
|
183
|
+
stateLabel,
|
|
184
|
+
lastCheckedAt: account.health.lastCheckedAt,
|
|
185
|
+
formatCheckedTime: checkedTime,
|
|
186
|
+
})),
|
|
183
187
|
h(WorkspaceEditor, {
|
|
184
188
|
workspace: account.workspace,
|
|
185
189
|
disabled: Boolean(busy),
|
|
@@ -191,15 +195,16 @@ export function AccountCard({
|
|
|
191
195
|
onSave: onAgentPresetSave,
|
|
192
196
|
}),
|
|
193
197
|
h('div', { className: 'ddt-accountFooter dim-cardFooter' },
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
'
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
198
|
+
h('div', { className: 'dim-cardFooterLayout' },
|
|
199
|
+
h('div', { className: 'ddt-actions dim-cardActions' },
|
|
200
|
+
h(Button, { className: 'dim-cardAction', onClick: onReconnect, disabled: Boolean(busy) }, busy === 'reconnect' ? '检查中…' : account.connected ? '检查连接' : '重试连接'),
|
|
201
|
+
h(Button, { className: 'dim-cardAction', kind: 'danger', onClick: onRequestRemove, disabled: Boolean(busy) }, '移除接入')),
|
|
202
|
+
summary ? h('div', { className: 'ddt-summary dim-cardSummary' }, summary) : null,
|
|
203
|
+
feedback ? h('div', {
|
|
204
|
+
className: 'ddt-summary dim-cardFeedback',
|
|
205
|
+
role: 'status',
|
|
206
|
+
'aria-live': 'polite',
|
|
207
|
+
}, feedback) : null))),
|
|
203
208
|
removing ? h(RemoveConfirmation, {
|
|
204
209
|
account, busy: busy === 'delete', onConfirm: onConfirmRemove, onCancel: onCancelRemove,
|
|
205
210
|
}) : null);
|
|
@@ -463,8 +468,11 @@ export function WecomSettingsTab({ rpcCall }) {
|
|
|
463
468
|
|
|
464
469
|
const botList = model.bots.length > 0
|
|
465
470
|
? h('section', { className: 'dim-listSection' },
|
|
466
|
-
h(
|
|
467
|
-
|
|
471
|
+
h(ChannelListHeading, {
|
|
472
|
+
className: 'ddt-listHeading',
|
|
473
|
+
title: '已绑定的企业微信机器人',
|
|
474
|
+
connectionLabel: 'WebSocket 长连接',
|
|
475
|
+
}),
|
|
468
476
|
h('ul', { className: 'ddt-list dim-botList' }, model.bots.map((account) =>
|
|
469
477
|
h('li', { key: account.botId }, h(AccountCard, {
|
|
470
478
|
account,
|
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
EMPTY_AGENT_PRESET_CATALOG,
|
|
23
23
|
} from '../../agent-preset.js';
|
|
24
24
|
import { useWorkspaceSnapshotFence } from '../../workspace-snapshot-fence.js';
|
|
25
|
+
import { BotStatusMeta, ChannelListHeading } from '../../channel-card-meta.js';
|
|
25
26
|
import { installWeixinStyles } from './styles.js';
|
|
26
27
|
|
|
27
28
|
export const name = 'weixin-settings';
|
|
@@ -221,14 +222,14 @@ export function AccountCard({
|
|
|
221
222
|
h('div', { className: 'dxw-accountIdentity dim-botIdentity' },
|
|
222
223
|
h('div', { className: 'dxw-avatar dim-botAvatar', 'aria-hidden': 'true' }, h(WeixinLogoGlyph, { size: 27 })),
|
|
223
224
|
h('div', { className: 'dim-botName' }, h('h3', null, account.bot.name), h('p', null, account.bot.accountIdMasked))),
|
|
224
|
-
h(
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
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
|
+
})),
|
|
232
233
|
h(WorkspaceEditor, {
|
|
233
234
|
workspace: account.workspace,
|
|
234
235
|
disabled: Boolean(busy),
|
|
@@ -240,20 +241,21 @@ export function AccountCard({
|
|
|
240
241
|
onSave: onAgentPresetSave,
|
|
241
242
|
}),
|
|
242
243
|
h('div', { className: 'dxw-accountFooter dim-cardFooter' },
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
244
|
+
h('div', { className: 'dim-cardFooterLayout' },
|
|
245
|
+
h('div', { className: 'dxw-actions dim-cardActions' },
|
|
246
|
+
h(Button, { className: 'dim-cardAction', onClick: onReconnect, disabled: Boolean(busy) },
|
|
247
|
+
busy === 'reconnect' ? '检查中…' : account.connected ? '检查连接' : '重试连接'),
|
|
248
|
+
h(Button, { className: 'dim-cardAction', kind: 'danger', onClick: onRequestRemove, disabled: Boolean(busy) }, '移除接入')),
|
|
249
|
+
summary ? h('div', { className: 'dxw-summary dim-cardSummary' }, summary) : null,
|
|
250
|
+
account.lastMessageError ? h('div', {
|
|
251
|
+
className: 'dxw-summary dim-cardSummary',
|
|
252
|
+
role: 'status',
|
|
253
|
+
}, `最近一条消息处理失败:${account.lastMessageError.message}`) : null,
|
|
254
|
+
feedback ? h('div', {
|
|
255
|
+
className: 'dxw-summary dim-cardFeedback',
|
|
256
|
+
role: 'status',
|
|
257
|
+
'aria-live': 'polite',
|
|
258
|
+
}, feedback) : null))),
|
|
257
259
|
removing ? h('div', { className: 'dxw-confirm dim-confirm', role: 'alertdialog' },
|
|
258
260
|
h('strong', null, '从此 Harness 移除这个微信账号?'),
|
|
259
261
|
h('p', null, '这会停止消息连接,并删除本机保存的 bot_token、账号配置和会话映射。其他微信账号不受影响。'),
|
|
@@ -266,7 +268,11 @@ export function AccountCard({
|
|
|
266
268
|
|
|
267
269
|
function AccountList(props) {
|
|
268
270
|
return h('section', { className: 'dim-listSection' },
|
|
269
|
-
h(
|
|
271
|
+
h(ChannelListHeading, {
|
|
272
|
+
className: 'dxw-listHeading',
|
|
273
|
+
title: '已接入的微信账号',
|
|
274
|
+
connectionLabel: 'iLink 长轮询',
|
|
275
|
+
}),
|
|
270
276
|
h('ul', { className: 'dxw-list dim-botList' }, props.bots.map((account) => h('li', { key: account.botId },
|
|
271
277
|
h(AccountCard, {
|
|
272
278
|
account,
|