@xmanrui/dsh-im 4.18.1 → 4.19.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 +1 -0
- package/README.md +1 -0
- package/lib/client.js +917 -521
- package/lib/index.js +269 -267
- package/package.json +1 -1
- package/plugin-src/client/bot-alias.js +169 -0
- package/plugin-src/client/channels/dingtalk/api.js +3 -0
- package/plugin-src/client/channels/dingtalk/index.js +7 -1
- package/plugin-src/client/channels/feishu/api.js +3 -0
- package/plugin-src/client/channels/feishu/index.js +7 -1
- package/plugin-src/client/channels/qq/api.js +3 -0
- package/plugin-src/client/channels/qq/index.js +9 -1
- package/plugin-src/client/channels/shared/token-api.js +3 -0
- package/plugin-src/client/channels/shared/token-channel.js +9 -2
- package/plugin-src/client/channels/wecom/api.js +3 -0
- package/plugin-src/client/channels/wecom/index.js +9 -1
- package/plugin-src/client/channels/wecom-app/api.js +3 -0
- package/plugin-src/client/channels/wecom-app/index.js +9 -1
- package/plugin-src/client/channels/weixin/api.js +3 -0
- package/plugin-src/client/channels/weixin/index.js +7 -1
- package/plugin-src/client/channels/whatsapp/api.js +3 -0
- package/plugin-src/client/channels/whatsapp/index.js +9 -1
- package/plugin-src/client/i18n.js +10 -0
- package/plugin-src/client/styles.js +41 -6
- package/plugin-src/host/channels/dingtalk/rpc.mjs +11 -0
- package/plugin-src/host/channels/feishu/production.mjs +22 -0
- package/plugin-src/host/channels/feishu/rpc.mjs +14 -0
- package/plugin-src/host/channels/imessage/rpc.mjs +1 -0
- package/plugin-src/host/channels/qq/rpc.mjs +11 -0
- package/plugin-src/host/channels/shared/bot-alias-rpc.mjs +15 -0
- package/plugin-src/host/channels/shared/rpc.mjs +9 -0
- package/plugin-src/host/channels/slack/rpc.mjs +10 -0
- package/plugin-src/host/channels/wecom/rpc.mjs +11 -0
- package/plugin-src/host/channels/wecom-app/rpc.mjs +10 -0
- package/plugin-src/host/channels/weixin/rpc.mjs +11 -0
- package/plugin-src/host/channels/whatsapp/rpc.mjs +13 -0
- package/plugin-src/host/session-sync-coordinator.mjs +20 -1
- package/src/channels/feishu/bridge.mjs +330 -10
- package/src/channels/feishu/feishu-cards.mjs +1 -1
- package/src/channels/feishu/feishu-runtime.mjs +6 -0
- package/src/channels/feishu/state-store.mjs +17 -0
- package/src/channels/shared/bot-alias.mjs +29 -0
- package/src/channels/shared/bot-workspace-store.mjs +71 -3
- package/src/channels/shared/i18n-en/shared-a.mjs +2 -2
- package/src/channels/shared/message-failure.mjs +2 -1
- package/src/channels/shared/model-command.mjs +3 -2
- package/src/channels/shared/session-sync-registry.mjs +22 -0
package/package.json
CHANGED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { createPortal } from 'react-dom';
|
|
3
|
+
import { MAX_BOT_ALIAS_LENGTH, validateBotAlias } from '../../src/channels/shared/bot-alias.mjs';
|
|
4
|
+
import { h } from './i18n.js';
|
|
5
|
+
|
|
6
|
+
function AliasDialog({ bot, onSave, onClose }) {
|
|
7
|
+
const id = React.useId();
|
|
8
|
+
const dialogRef = React.useRef(null);
|
|
9
|
+
const inputRef = React.useRef(null);
|
|
10
|
+
const savingRef = React.useRef(false);
|
|
11
|
+
const [draft, setDraft] = React.useState(bot.alias ?? '');
|
|
12
|
+
const [saving, setSaving] = React.useState(false);
|
|
13
|
+
const [error, setError] = React.useState(null);
|
|
14
|
+
React.useEffect(() => {
|
|
15
|
+
const previous = globalThis.document?.activeElement;
|
|
16
|
+
dialogRef.current?.showModal?.();
|
|
17
|
+
inputRef.current?.focus?.();
|
|
18
|
+
inputRef.current?.select?.();
|
|
19
|
+
return () => { if (previous?.isConnected) previous.focus?.(); };
|
|
20
|
+
}, []);
|
|
21
|
+
const close = () => { if (!savingRef.current) onClose(); };
|
|
22
|
+
const save = async (value) => {
|
|
23
|
+
if (savingRef.current) return;
|
|
24
|
+
setError(null);
|
|
25
|
+
try {
|
|
26
|
+
const alias = validateBotAlias(value);
|
|
27
|
+
if (alias === (bot.alias ?? '')) { onClose(); return; }
|
|
28
|
+
savingRef.current = true;
|
|
29
|
+
setSaving(true);
|
|
30
|
+
await onSave(alias);
|
|
31
|
+
onClose();
|
|
32
|
+
} catch (cause) {
|
|
33
|
+
setError(cause?.message ?? '别名保存失败,请重试。');
|
|
34
|
+
} finally {
|
|
35
|
+
savingRef.current = false;
|
|
36
|
+
setSaving(false);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
const content = h('dialog', {
|
|
40
|
+
ref: dialogRef, className: 'dim-aliasDialog', 'aria-labelledby': `${id}-title`,
|
|
41
|
+
'aria-busy': saving,
|
|
42
|
+
onCancel: (event) => { event.preventDefault(); close(); },
|
|
43
|
+
onClick: (event) => event.stopPropagation(),
|
|
44
|
+
onKeyDown: (event) => event.stopPropagation(),
|
|
45
|
+
},
|
|
46
|
+
h('div', { className: 'dim-aliasHeader' },
|
|
47
|
+
h('h3', { id: `${id}-title` }, '修改别名'),
|
|
48
|
+
h('button', { type: 'button', className: 'dim-aliasClose', disabled: saving,
|
|
49
|
+
'aria-label': '关闭修改别名', onClick: close }, '×')),
|
|
50
|
+
h('div', { className: 'dim-aliasOriginal' }, h('span', null, '原名称'),
|
|
51
|
+
h('span', null, bot.originalName ?? bot.name)),
|
|
52
|
+
h('label', { htmlFor: `${id}-input` }, '别名'),
|
|
53
|
+
h('input', { id: `${id}-input`, ref: inputRef, value: draft, disabled: saving,
|
|
54
|
+
maxLength: MAX_BOT_ALIAS_LENGTH, placeholder: '例如:客服助手',
|
|
55
|
+
'aria-describedby': `${id}-help`,
|
|
56
|
+
onChange: (event) => setDraft(event.target.value),
|
|
57
|
+
onKeyDown: (event) => {
|
|
58
|
+
if (event.key === 'Enter' && !event.nativeEvent?.isComposing) {
|
|
59
|
+
event.preventDefault(); void save(draft);
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
}),
|
|
63
|
+
h('p', { id: `${id}-help`, className: 'dim-aliasHelp' }, '仅更改显示名称,留空则显示原名称。'),
|
|
64
|
+
error ? h('p', { className: 'dim-aliasError', role: 'alert' }, error) : null,
|
|
65
|
+
h('div', { className: 'dim-aliasFooter' },
|
|
66
|
+
h('button', { type: 'button', className: 'dim-aliasRestore',
|
|
67
|
+
disabled: saving || !bot.alias, onClick: () => void save('') }, '恢复原名称'),
|
|
68
|
+
h('div', { className: 'dim-aliasActions' },
|
|
69
|
+
h('button', { type: 'button', disabled: saving, onClick: close }, '取消'),
|
|
70
|
+
h('button', { type: 'button', className: 'dim-aliasSave', disabled: saving,
|
|
71
|
+
onClick: () => void save(draft) }, saving ? '保存中…' : '保存'))));
|
|
72
|
+
return globalThis.document?.body ? createPortal(content, document.body) : content;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function BotNameTooltip({ anchorRef, id, name, onDismiss }) {
|
|
76
|
+
const tooltipRef = React.useRef(null);
|
|
77
|
+
const [position, setPosition] = React.useState(null);
|
|
78
|
+
React.useLayoutEffect(() => {
|
|
79
|
+
const anchor = anchorRef.current;
|
|
80
|
+
const tooltip = tooltipRef.current;
|
|
81
|
+
if (!anchor || !tooltip) return undefined;
|
|
82
|
+
const document = anchor.ownerDocument;
|
|
83
|
+
const view = document.defaultView;
|
|
84
|
+
const place = () => {
|
|
85
|
+
const rect = anchor.getBoundingClientRect();
|
|
86
|
+
const { width, height } = tooltip.getBoundingClientRect();
|
|
87
|
+
const viewport = document.documentElement;
|
|
88
|
+
const margin = 8;
|
|
89
|
+
const below = rect.bottom + 6;
|
|
90
|
+
setPosition({
|
|
91
|
+
left: Math.max(margin, Math.min(rect.left, viewport.clientWidth - width - margin)),
|
|
92
|
+
top: Math.max(margin, Math.min(
|
|
93
|
+
below + height <= viewport.clientHeight - margin ? below : rect.top - height - 6,
|
|
94
|
+
viewport.clientHeight - height - margin,
|
|
95
|
+
)),
|
|
96
|
+
});
|
|
97
|
+
};
|
|
98
|
+
const dismiss = (event) => {
|
|
99
|
+
if (event.key === 'Escape') { event.stopPropagation(); onDismiss(); }
|
|
100
|
+
};
|
|
101
|
+
place();
|
|
102
|
+
view.addEventListener('resize', place);
|
|
103
|
+
// Capture nested scrolling containers as well as page scrolling.
|
|
104
|
+
document.addEventListener('scroll', onDismiss, true);
|
|
105
|
+
document.addEventListener('keydown', dismiss, true);
|
|
106
|
+
return () => {
|
|
107
|
+
view.removeEventListener('resize', place);
|
|
108
|
+
document.removeEventListener('scroll', onDismiss, true);
|
|
109
|
+
document.removeEventListener('keydown', dismiss, true);
|
|
110
|
+
};
|
|
111
|
+
}, [anchorRef, name, onDismiss]);
|
|
112
|
+
const body = anchorRef.current?.ownerDocument.body;
|
|
113
|
+
return body ? createPortal(h('span', {
|
|
114
|
+
ref: tooltipRef, id, role: 'tooltip', className: 'dim-botNameTooltip',
|
|
115
|
+
style: position ?? { visibility: 'hidden' },
|
|
116
|
+
}, name), body) : null;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export function BotName({ bot, id, disabled = false, onSave }) {
|
|
120
|
+
const [open, setOpen] = React.useState(false);
|
|
121
|
+
const nameRef = React.useRef(null);
|
|
122
|
+
const tooltipId = React.useId();
|
|
123
|
+
const [truncated, setTruncated] = React.useState(false);
|
|
124
|
+
const [hovered, setHovered] = React.useState(false);
|
|
125
|
+
const [focused, setFocused] = React.useState(false);
|
|
126
|
+
const [dismissed, setDismissed] = React.useState(false);
|
|
127
|
+
const dismissTooltip = React.useCallback(() => setDismissed(true), []);
|
|
128
|
+
const measure = React.useCallback(() => {
|
|
129
|
+
const node = nameRef.current;
|
|
130
|
+
setTruncated(Boolean(node && node.scrollWidth > node.clientWidth));
|
|
131
|
+
}, []);
|
|
132
|
+
React.useEffect(() => {
|
|
133
|
+
const node = nameRef.current;
|
|
134
|
+
if (!node) return undefined;
|
|
135
|
+
measure();
|
|
136
|
+
const view = node.ownerDocument.defaultView;
|
|
137
|
+
const observer = view.ResizeObserver ? new view.ResizeObserver(measure) : null;
|
|
138
|
+
observer?.observe(node);
|
|
139
|
+
view.addEventListener('resize', measure);
|
|
140
|
+
return () => { observer?.disconnect(); view.removeEventListener('resize', measure); };
|
|
141
|
+
}, [bot.name, measure]);
|
|
142
|
+
const showTooltip = truncated && !dismissed && !open && (hovered || focused);
|
|
143
|
+
return h('div', { className: 'dim-aliasName' },
|
|
144
|
+
h('h3', {
|
|
145
|
+
id, ref: nameRef, tabIndex: truncated ? 0 : undefined,
|
|
146
|
+
'aria-describedby': showTooltip ? tooltipId : undefined,
|
|
147
|
+
onMouseEnter: () => { measure(); setHovered(true); setDismissed(false); },
|
|
148
|
+
onMouseLeave: () => setHovered(false),
|
|
149
|
+
onFocus: () => { measure(); setFocused(true); setDismissed(false); },
|
|
150
|
+
onBlur: () => setFocused(false),
|
|
151
|
+
onClick: dismissTooltip,
|
|
152
|
+
}, bot.name),
|
|
153
|
+
showTooltip ? h(BotNameTooltip, {
|
|
154
|
+
anchorRef: nameRef, id: tooltipId, name: bot.name, onDismiss: dismissTooltip,
|
|
155
|
+
}) : null,
|
|
156
|
+
h('span', {
|
|
157
|
+
className: 'dim-aliasEntry',
|
|
158
|
+
onClick: (event) => event.stopPropagation(),
|
|
159
|
+
onKeyDown: (event) => event.stopPropagation(),
|
|
160
|
+
},
|
|
161
|
+
h('button', { type: 'button', className: 'dim-aliasEdit',
|
|
162
|
+
'aria-label': '修改别名', title: '修改别名', 'aria-haspopup': 'dialog',
|
|
163
|
+
disabled: disabled || typeof onSave !== 'function', onClick: () => setOpen(true) },
|
|
164
|
+
h('svg', { width: 14, height: 14, viewBox: '0 0 24 24', fill: 'none',
|
|
165
|
+
stroke: 'currentColor', strokeWidth: 1.7, strokeLinecap: 'round', strokeLinejoin: 'round',
|
|
166
|
+
'aria-hidden': true },
|
|
167
|
+
h('path', { d: 'm16 3 5 5M3 21l5-1L21 7a2.1 2.1 0 0 0-5-5L3 15Z' }))),
|
|
168
|
+
open ? h(AliasDialog, { bot, onSave, onClose: () => setOpen(false) }) : null));
|
|
169
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { normalizeBotAlias } from '../../../../src/channels/shared/bot-alias.mjs';
|
|
1
2
|
import { normalizeAgentPresetCatalog, normalizeAgentPresetId, SET_AGENT_PRESET_ENDPOINT } from '../../agent-preset.js';
|
|
2
3
|
import { normalizeModelCatalog, normalizeModelSelection, SET_MODEL_ENDPOINT } from '../../model-setting.js';
|
|
3
4
|
import { normalizeLastMessageError } from '../../last-message-error.js';
|
|
@@ -19,6 +20,7 @@ export const DINGTALK_ENDPOINTS = Object.freeze({
|
|
|
19
20
|
setAgentPreset: SET_AGENT_PRESET_ENDPOINT,
|
|
20
21
|
setContextEnhancement: 'bot.context-enhancement.set',
|
|
21
22
|
setAccessPolicy: 'bot.access-policy.set',
|
|
23
|
+
setAlias: 'bot.alias.set',
|
|
22
24
|
});
|
|
23
25
|
|
|
24
26
|
const ACCOUNT_STATES = new Set(['connected', 'connecting', 'offline', 'error']);
|
|
@@ -190,6 +192,7 @@ function normalizeBot(value) {
|
|
|
190
192
|
? { accessPolicy: normalizeAccessPolicy(value.accessPolicy) }
|
|
191
193
|
: {}),
|
|
192
194
|
bot: {
|
|
195
|
+
...normalizeBotAlias(bot),
|
|
193
196
|
name: optionalString(bot.name, 100) ?? '钉钉机器人',
|
|
194
197
|
clientIdMasked: optionalString(bot.clientIdMasked, 140) ?? '已安全保存',
|
|
195
198
|
},
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { BotName } from '../../bot-alias.js';
|
|
1
2
|
import * as React from 'react';
|
|
2
3
|
|
|
3
4
|
import { CredentialActionIcon, CredentialBindingPanel, QrActionIcon } from '../../credential-binding.js';
|
|
@@ -244,6 +245,7 @@ export function AccountCard({
|
|
|
244
245
|
removing,
|
|
245
246
|
onReconnect,
|
|
246
247
|
onWorkspaceSave,
|
|
248
|
+
onAliasSave,
|
|
247
249
|
onModelSave,
|
|
248
250
|
onAgentPresetSave,
|
|
249
251
|
onContextEnhancementSave,
|
|
@@ -263,7 +265,7 @@ export function AccountCard({
|
|
|
263
265
|
h('div', { className: 'ddt-accountIdentity dim-botIdentity' },
|
|
264
266
|
h('div', { className: 'ddt-avatar dim-botAvatar', 'aria-hidden': 'true' }, h(DingtalkIcon, { size: 29 })),
|
|
265
267
|
h('div', { className: 'dim-botName' },
|
|
266
|
-
h(
|
|
268
|
+
h(BotName, { bot: account.bot, disabled: Boolean(busy), onSave: onAliasSave }),
|
|
267
269
|
h('p', { title: account.bot.clientIdMasked }, account.bot.clientIdMasked))),
|
|
268
270
|
h('div', {
|
|
269
271
|
className: 'dim-botCardTools',
|
|
@@ -349,6 +351,7 @@ function AccountList(props) {
|
|
|
349
351
|
removing: props.removeTarget === account.botId,
|
|
350
352
|
onReconnect: () => props.onReconnect(account),
|
|
351
353
|
onWorkspaceSave: (workspace) => props.onWorkspaceSave(account, workspace),
|
|
354
|
+
onAliasSave: (alias) => props.onAliasSave(account, alias),
|
|
352
355
|
onModelSave: (model) => props.onModelSave(account, model),
|
|
353
356
|
onAgentPresetSave: (agentPreset) => props.onAgentPresetSave(account, agentPreset),
|
|
354
357
|
onContextEnhancementSave: (config) => props.onContextEnhancementSave(account, config),
|
|
@@ -928,6 +931,9 @@ export function DingtalkSettingsTab({ rpcCall }) {
|
|
|
928
931
|
removeTarget,
|
|
929
932
|
onReconnect: (account) => void reconnect(account),
|
|
930
933
|
onWorkspaceSave: saveWorkspace,
|
|
934
|
+
onAliasSave: (account, alias) => saveBotSetting(
|
|
935
|
+
account, 'alias', DINGTALK_ENDPOINTS.setAlias, { alias },
|
|
936
|
+
),
|
|
931
937
|
onModelSave: (account, selectedModel) => saveBotSetting(
|
|
932
938
|
account, 'model', DINGTALK_ENDPOINTS.setModel, { model: selectedModel },
|
|
933
939
|
),
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { normalizeBotAlias } from '../../../../src/channels/shared/bot-alias.mjs';
|
|
1
2
|
/**
|
|
2
3
|
* Browser-safe contract for the Feishu Host plugin.
|
|
3
4
|
*
|
|
@@ -31,6 +32,7 @@ export const FEISHU_ENDPOINTS = Object.freeze({
|
|
|
31
32
|
setAgentPreset: "bot.preset.set",
|
|
32
33
|
setContextEnhancement: "bot.context-enhancement.set",
|
|
33
34
|
setAccessPolicy: "bot.access-policy.set",
|
|
35
|
+
setAlias: 'bot.alias.set',
|
|
34
36
|
setGroupResponseMode: "bot.group-response-mode.set",
|
|
35
37
|
setGroupTopicReply: "bot.group-topic-reply.set",
|
|
36
38
|
setStepPush: "bot.step-push.set",
|
|
@@ -157,6 +159,7 @@ export function normalizeProvisioning(value, now = Date.now()) {
|
|
|
157
159
|
function normalizeBot(value) {
|
|
158
160
|
const source = isRecord(value) ? value : {};
|
|
159
161
|
return {
|
|
162
|
+
...normalizeBotAlias(source),
|
|
160
163
|
name: optionalString(source.name) ?? "飞书机器人",
|
|
161
164
|
avatarUrl: optionalString(source.avatarUrl),
|
|
162
165
|
appIdMasked: optionalString(source.appIdMasked),
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { BotName } from '../../bot-alias.js';
|
|
1
2
|
import * as React from "react";
|
|
2
3
|
|
|
3
4
|
import { FeishuLogoGlyph } from "../../channel-logos.js";
|
|
@@ -560,6 +561,7 @@ export function BotCard({
|
|
|
560
561
|
onReconnect,
|
|
561
562
|
onRepairCallback,
|
|
562
563
|
onWorkspaceSave,
|
|
564
|
+
onAliasSave,
|
|
563
565
|
onModelSave,
|
|
564
566
|
onAgentPresetSave,
|
|
565
567
|
onContextEnhancementSave,
|
|
@@ -600,7 +602,7 @@ export function BotCard({
|
|
|
600
602
|
h("div", { className: "bxf-avatar dim-botAvatar", "aria-hidden": "true" },
|
|
601
603
|
h(FeishuLogoGlyph, { size: 34 })),
|
|
602
604
|
h("div", { className: "bxf-botName dim-botName" },
|
|
603
|
-
h(
|
|
605
|
+
h(BotName, { bot, id: titleId, disabled: Boolean(busy), onSave: onAliasSave }),
|
|
604
606
|
h("p", { title: bot.appIdMasked }, bot.appIdMasked ?? "应用标识已安全保存")),
|
|
605
607
|
),
|
|
606
608
|
h("div", {
|
|
@@ -747,6 +749,7 @@ function BotList(props) {
|
|
|
747
749
|
onReconnect: () => props.onReconnect(bot),
|
|
748
750
|
onRepairCallback: () => props.onRepairCallback(bot),
|
|
749
751
|
onWorkspaceSave: (workspace) => props.onWorkspaceSave(bot, workspace),
|
|
752
|
+
onAliasSave: (alias) => props.onAliasSave(bot, alias),
|
|
750
753
|
onModelSave: (model) => props.onModelSave(bot, model),
|
|
751
754
|
onAgentPresetSave: (agentPreset) => props.onAgentPresetSave(bot, agentPreset),
|
|
752
755
|
onContextEnhancementSave: (config) => props.onContextEnhancementSave(bot, config),
|
|
@@ -1517,6 +1520,9 @@ export function FeishuSettingsTab({ rpcCall }) {
|
|
|
1517
1520
|
onReconnect: (bot) => void reconnectOneBot(bot),
|
|
1518
1521
|
onRepairCallback: repairCallback,
|
|
1519
1522
|
onWorkspaceSave: saveWorkspace,
|
|
1523
|
+
onAliasSave: (connection, alias) => saveBotSetting(
|
|
1524
|
+
connection, 'alias', FEISHU_ENDPOINTS.setAlias, { alias },
|
|
1525
|
+
),
|
|
1520
1526
|
onModelSave: (connection, selectedModel) => saveBotSetting(
|
|
1521
1527
|
connection, "model", FEISHU_ENDPOINTS.setModel, { model: selectedModel },
|
|
1522
1528
|
),
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { normalizeBotAlias } from '../../../../src/channels/shared/bot-alias.mjs';
|
|
1
2
|
import { normalizeAgentPresetCatalog, normalizeAgentPresetId, SET_AGENT_PRESET_ENDPOINT } from '../../agent-preset.js';
|
|
2
3
|
import { normalizeModelCatalog, normalizeModelSelection, SET_MODEL_ENDPOINT } from '../../model-setting.js';
|
|
3
4
|
import { normalizeLastMessageError } from '../../last-message-error.js';
|
|
@@ -19,6 +20,7 @@ export const QQ_ENDPOINTS = Object.freeze({
|
|
|
19
20
|
setAgentPreset: SET_AGENT_PRESET_ENDPOINT,
|
|
20
21
|
setContextEnhancement: 'bot.context-enhancement.set',
|
|
21
22
|
setAccessPolicy: 'bot.access-policy.set',
|
|
23
|
+
setAlias: 'bot.alias.set',
|
|
22
24
|
});
|
|
23
25
|
|
|
24
26
|
const PROVISION_STATES = new Set(['starting', 'pending', 'refreshing', 'connecting', 'connected', 'failed', 'cancelled']);
|
|
@@ -99,6 +101,7 @@ function normalizeBot(value) {
|
|
|
99
101
|
? { accessPolicy: normalizeAccessPolicy(value.accessPolicy) }
|
|
100
102
|
: {}),
|
|
101
103
|
bot: {
|
|
104
|
+
...normalizeBotAlias(value.bot),
|
|
102
105
|
name: text(value.bot?.name, 'QQ机器人', 100),
|
|
103
106
|
appIdMasked: text(value.bot?.appIdMasked, '应用标识已安全保存', 140),
|
|
104
107
|
},
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { BotName } from '../../bot-alias.js';
|
|
1
2
|
import * as React from 'react';
|
|
2
3
|
|
|
3
4
|
import { QqLogoGlyph } from '../../channel-logos.js';
|
|
@@ -173,6 +174,7 @@ export function AccountCard({
|
|
|
173
174
|
removing,
|
|
174
175
|
onReconnect,
|
|
175
176
|
onWorkspaceSave,
|
|
177
|
+
onAliasSave,
|
|
176
178
|
onModelSave,
|
|
177
179
|
onAgentPresetSave,
|
|
178
180
|
onContextEnhancementSave,
|
|
@@ -191,7 +193,7 @@ export function AccountCard({
|
|
|
191
193
|
h('div', { className: 'ddt-accountIdentity dim-botIdentity' },
|
|
192
194
|
h('div', { className: 'ddt-avatar dim-botAvatar dqq-avatar', 'aria-hidden': 'true' }, h(QqLogoGlyph, { size: 29 })),
|
|
193
195
|
h('div', { className: 'dim-botName' },
|
|
194
|
-
h(
|
|
196
|
+
h(BotName, { bot: account.bot, disabled: Boolean(busy), onSave: onAliasSave }), h('p', null, account.bot.appIdMasked))),
|
|
195
197
|
h('div', {
|
|
196
198
|
className: 'dim-botCardTools',
|
|
197
199
|
// The header is the collapse toggle; keep inner controls clickable.
|
|
@@ -504,6 +506,12 @@ export function QqSettingsTab({ rpcCall }) {
|
|
|
504
506
|
QQ_ENDPOINTS.setWorkspace,
|
|
505
507
|
{ botId: account.botId, workspace },
|
|
506
508
|
),
|
|
509
|
+
onAliasSave: (alias) => botAction(
|
|
510
|
+
account,
|
|
511
|
+
'alias',
|
|
512
|
+
QQ_ENDPOINTS.setAlias,
|
|
513
|
+
{ botId: account.botId, alias },
|
|
514
|
+
),
|
|
507
515
|
onModelSave: (selectedModel) => botAction(
|
|
508
516
|
account,
|
|
509
517
|
'model',
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { normalizeBotAlias } from '../../../../src/channels/shared/bot-alias.mjs';
|
|
1
2
|
import { normalizeAgentPresetCatalog, normalizeAgentPresetId, SET_AGENT_PRESET_ENDPOINT } from '../../agent-preset.js';
|
|
2
3
|
import { normalizeModelCatalog, normalizeModelSelection, SET_MODEL_ENDPOINT } from '../../model-setting.js';
|
|
3
4
|
import { normalizeLastMessageError } from '../../last-message-error.js';
|
|
@@ -35,6 +36,7 @@ export const TOKEN_BOT_ENDPOINTS = Object.freeze({
|
|
|
35
36
|
setAgentPreset: SET_AGENT_PRESET_ENDPOINT,
|
|
36
37
|
setContextEnhancement: 'bot.context-enhancement.set',
|
|
37
38
|
setAccessPolicy: 'bot.access-policy.set',
|
|
39
|
+
setAlias: 'bot.alias.set',
|
|
38
40
|
});
|
|
39
41
|
|
|
40
42
|
export function createTokenChannelApi(channel, connectionSummary, {
|
|
@@ -69,6 +71,7 @@ export function createTokenChannelApi(channel, connectionSummary, {
|
|
|
69
71
|
? { accessPolicy: normalizeAccessPolicy(value.accessPolicy) }
|
|
70
72
|
: {}),
|
|
71
73
|
bot: {
|
|
74
|
+
...normalizeBotAlias(value.bot),
|
|
72
75
|
name: text(value.bot?.name, `${channel}机器人`, 100),
|
|
73
76
|
username: text(value.bot?.username, '', 100),
|
|
74
77
|
idMasked: text(value.bot?.idMasked, '机器人标识已安全保存', 140),
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { BotName } from '../../bot-alias.js';
|
|
1
2
|
import * as React from 'react';
|
|
2
3
|
|
|
3
4
|
import { CredentialActionIcon, CredentialBindingPanel } from '../../credential-binding.js';
|
|
@@ -81,7 +82,7 @@ export function createTokenChannelSettings(definition) {
|
|
|
81
82
|
accountSettingsEndpoint = null,
|
|
82
83
|
} = definition;
|
|
83
84
|
|
|
84
|
-
function AccountCard({ account, busy, testNotice, removing, onReconnect, onWorkspaceSave, onModelSave, onAgentPresetSave, onContextEnhancementSave, onAccountSettingsSave, onRequestRemove, onConfirmRemove, onCancelRemove }) {
|
|
85
|
+
function AccountCard({ account, busy, testNotice, removing, onReconnect, onWorkspaceSave, onAliasSave, onModelSave, onAgentPresetSave, onContextEnhancementSave, onAccountSettingsSave, onRequestRemove, onConfirmRemove, onCancelRemove }) {
|
|
85
86
|
const state = busy === 'reconnect' ? 'connecting' : account.state;
|
|
86
87
|
const tone = account.connected ? 'success' : state === 'error' ? 'error' : 'warning';
|
|
87
88
|
const stateLabel = account.connected ? '运行正常' : state === 'connecting' ? '正在连接' : '连接未就绪';
|
|
@@ -96,7 +97,7 @@ export function createTokenChannelSettings(definition) {
|
|
|
96
97
|
h('div', { className: `ddt-avatar dim-botAvatar ${avatarClass}`, 'aria-hidden': 'true' },
|
|
97
98
|
h(LogoGlyph, { size: 29 })),
|
|
98
99
|
h('div', { className: 'dim-botName' },
|
|
99
|
-
h(
|
|
100
|
+
h(BotName, { bot: account.bot, disabled: Boolean(busy), onSave: onAliasSave }), h('p', null, identity))),
|
|
100
101
|
h('div', {
|
|
101
102
|
className: 'dim-botCardTools',
|
|
102
103
|
// The header is the collapse toggle; keep inner controls clickable.
|
|
@@ -345,6 +346,12 @@ export function createTokenChannelSettings(definition) {
|
|
|
345
346
|
endpoints.setWorkspace,
|
|
346
347
|
{ botId: account.botId, workspace },
|
|
347
348
|
),
|
|
349
|
+
onAliasSave: (alias) => botAction(
|
|
350
|
+
account,
|
|
351
|
+
'alias',
|
|
352
|
+
endpoints.setAlias,
|
|
353
|
+
{ botId: account.botId, alias },
|
|
354
|
+
),
|
|
348
355
|
onModelSave: (selectedModel) => botAction(
|
|
349
356
|
account,
|
|
350
357
|
'model',
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { normalizeBotAlias } from '../../../../src/channels/shared/bot-alias.mjs';
|
|
1
2
|
import { normalizeAgentPresetCatalog, normalizeAgentPresetId, SET_AGENT_PRESET_ENDPOINT } from '../../agent-preset.js';
|
|
2
3
|
import { normalizeModelCatalog, normalizeModelSelection, SET_MODEL_ENDPOINT } from '../../model-setting.js';
|
|
3
4
|
import { normalizeLastMessageError } from '../../last-message-error.js';
|
|
@@ -19,6 +20,7 @@ export const WECOM_ENDPOINTS = Object.freeze({
|
|
|
19
20
|
setAgentPreset: SET_AGENT_PRESET_ENDPOINT,
|
|
20
21
|
setContextEnhancement: 'bot.context-enhancement.set',
|
|
21
22
|
setAccessPolicy: 'bot.access-policy.set',
|
|
23
|
+
setAlias: 'bot.alias.set',
|
|
22
24
|
});
|
|
23
25
|
|
|
24
26
|
const PROVISION_STATES = new Set(['starting', 'pending', 'refreshing', 'connecting', 'connected', 'failed', 'cancelled']);
|
|
@@ -108,6 +110,7 @@ function normalizeBot(value) {
|
|
|
108
110
|
? { accessPolicy: normalizeAccessPolicy(value.accessPolicy) }
|
|
109
111
|
: {}),
|
|
110
112
|
bot: {
|
|
113
|
+
...normalizeBotAlias(value.bot),
|
|
111
114
|
name: text(value.bot?.name, '企业微信机器人', 100),
|
|
112
115
|
appIdMasked: text(value.bot?.appIdMasked, '应用标识已安全保存', 140),
|
|
113
116
|
},
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { BotName } from '../../bot-alias.js';
|
|
1
2
|
import * as React from 'react';
|
|
2
3
|
|
|
3
4
|
import { WecomLogoGlyph } from '../../channel-logos.js';
|
|
@@ -172,6 +173,7 @@ export function AccountCard({
|
|
|
172
173
|
removing,
|
|
173
174
|
onReconnect,
|
|
174
175
|
onWorkspaceSave,
|
|
176
|
+
onAliasSave,
|
|
175
177
|
onModelSave,
|
|
176
178
|
onAgentPresetSave,
|
|
177
179
|
onContextEnhancementSave,
|
|
@@ -190,7 +192,7 @@ export function AccountCard({
|
|
|
190
192
|
h('div', { className: 'ddt-accountIdentity dim-botIdentity' },
|
|
191
193
|
h('div', { className: 'ddt-avatar dim-botAvatar dwecom-avatar', 'aria-hidden': 'true' }, h(WecomLogoGlyph, { size: 29 })),
|
|
192
194
|
h('div', { className: 'dim-botName' },
|
|
193
|
-
h(
|
|
195
|
+
h(BotName, { bot: account.bot, disabled: Boolean(busy), onSave: onAliasSave }), h('p', null, account.bot.appIdMasked))),
|
|
194
196
|
h('div', {
|
|
195
197
|
className: 'dim-botCardTools',
|
|
196
198
|
// The header is the collapse toggle; keep inner controls clickable.
|
|
@@ -535,6 +537,12 @@ export function WecomSettingsTab({ rpcCall }) {
|
|
|
535
537
|
WECOM_ENDPOINTS.setWorkspace,
|
|
536
538
|
{ botId: account.botId, workspace },
|
|
537
539
|
),
|
|
540
|
+
onAliasSave: (alias) => botAction(
|
|
541
|
+
account,
|
|
542
|
+
'alias',
|
|
543
|
+
WECOM_ENDPOINTS.setAlias,
|
|
544
|
+
{ botId: account.botId, alias },
|
|
545
|
+
),
|
|
538
546
|
onModelSave: (selectedModel) => botAction(
|
|
539
547
|
account,
|
|
540
548
|
'model',
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { normalizeBotAlias } from '../../../../src/channels/shared/bot-alias.mjs';
|
|
1
2
|
import { normalizeAgentPresetCatalog, normalizeAgentPresetId, SET_AGENT_PRESET_ENDPOINT } from '../../agent-preset.js';
|
|
2
3
|
import { normalizeModelCatalog, normalizeModelSelection, SET_MODEL_ENDPOINT } from '../../model-setting.js';
|
|
3
4
|
import { normalizeLastMessageError } from '../../last-message-error.js';
|
|
@@ -18,6 +19,7 @@ export const WECOM_APP_ENDPOINTS = Object.freeze({
|
|
|
18
19
|
setAgentPreset: SET_AGENT_PRESET_ENDPOINT,
|
|
19
20
|
setContextEnhancement: 'bot.context-enhancement.set',
|
|
20
21
|
setAccessPolicy: 'bot.access-policy.set',
|
|
22
|
+
setAlias: 'bot.alias.set',
|
|
21
23
|
});
|
|
22
24
|
|
|
23
25
|
const ACCOUNT_STATES = new Set(['connected', 'connecting', 'offline', 'error']);
|
|
@@ -82,6 +84,7 @@ function normalizeBot(value) {
|
|
|
82
84
|
? { accessPolicy: normalizeAccessPolicy(value.accessPolicy) }
|
|
83
85
|
: {}),
|
|
84
86
|
bot: {
|
|
87
|
+
...normalizeBotAlias(value.bot),
|
|
85
88
|
name: text(value.bot?.name, '企业微信应用', 100),
|
|
86
89
|
corpIdMasked: text(value.bot?.corpIdMasked, '企业 ID 已保存', 140),
|
|
87
90
|
agentId: text(value.bot?.agentId, '', 32),
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { BotName } from '../../bot-alias.js';
|
|
1
2
|
import * as React from 'react';
|
|
2
3
|
|
|
3
4
|
import { WecomLogoGlyph } from '../../channel-logos.js';
|
|
@@ -246,6 +247,7 @@ export function AccountCard({
|
|
|
246
247
|
onSettingsSave,
|
|
247
248
|
onSecretReset,
|
|
248
249
|
onWorkspaceSave,
|
|
250
|
+
onAliasSave,
|
|
249
251
|
onModelSave,
|
|
250
252
|
onAgentPresetSave,
|
|
251
253
|
onContextEnhancementSave,
|
|
@@ -265,7 +267,7 @@ export function AccountCard({
|
|
|
265
267
|
h('div', { className: 'ddt-accountIdentity dim-botIdentity' },
|
|
266
268
|
h('div', { className: 'ddt-avatar dim-botAvatar dwecomapp-avatar', 'aria-hidden': 'true' }, h(WecomLogoGlyph, { size: 29 })),
|
|
267
269
|
h('div', { className: 'dim-botName' },
|
|
268
|
-
h(
|
|
270
|
+
h(BotName, { bot: account.bot, disabled: Boolean(busy), onSave: onAliasSave }),
|
|
269
271
|
h('p', null, `${account.bot.corpIdMasked} · AgentId ${account.bot.agentId}`))),
|
|
270
272
|
h('div', {
|
|
271
273
|
className: 'dim-botCardTools',
|
|
@@ -552,6 +554,12 @@ export function WecomAppSettingsTab({ rpcCall }) {
|
|
|
552
554
|
WECOM_APP_ENDPOINTS.setWorkspace,
|
|
553
555
|
{ botId: account.botId, workspace },
|
|
554
556
|
),
|
|
557
|
+
onAliasSave: (alias) => botAction(
|
|
558
|
+
account,
|
|
559
|
+
'alias',
|
|
560
|
+
WECOM_APP_ENDPOINTS.setAlias,
|
|
561
|
+
{ botId: account.botId, alias },
|
|
562
|
+
),
|
|
555
563
|
onModelSave: (selectedModel) => botAction(
|
|
556
564
|
account,
|
|
557
565
|
'model',
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { normalizeBotAlias } from '../../../../src/channels/shared/bot-alias.mjs';
|
|
1
2
|
import { normalizeAgentPresetCatalog, normalizeAgentPresetId, SET_AGENT_PRESET_ENDPOINT } from '../../agent-preset.js';
|
|
2
3
|
import { normalizeModelCatalog, normalizeModelSelection, SET_MODEL_ENDPOINT } from '../../model-setting.js';
|
|
3
4
|
import { normalizeLastMessageError } from '../../last-message-error.js';
|
|
@@ -18,6 +19,7 @@ export const WEIXIN_ENDPOINTS = Object.freeze({
|
|
|
18
19
|
setAgentPreset: SET_AGENT_PRESET_ENDPOINT,
|
|
19
20
|
setContextEnhancement: 'bot.context-enhancement.set',
|
|
20
21
|
setAccessPolicy: 'bot.access-policy.set',
|
|
22
|
+
setAlias: 'bot.alias.set',
|
|
21
23
|
});
|
|
22
24
|
|
|
23
25
|
const ACCOUNT_STATES = new Set(['connected', 'connecting', 'offline', 'error']);
|
|
@@ -133,6 +135,7 @@ function normalizeBot(value) {
|
|
|
133
135
|
? { accessPolicy: normalizeAccessPolicy(value.accessPolicy) }
|
|
134
136
|
: {}),
|
|
135
137
|
bot: {
|
|
138
|
+
...normalizeBotAlias(value.bot),
|
|
136
139
|
name: string(value.bot.name, '微信机器人'),
|
|
137
140
|
accountIdMasked: string(value.bot.accountIdMasked, '已安全保存'),
|
|
138
141
|
},
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { BotName } from '../../bot-alias.js';
|
|
1
2
|
import * as React from 'react';
|
|
2
3
|
|
|
3
4
|
import { WeixinLogoGlyph } from '../../channel-logos.js';
|
|
@@ -214,6 +215,7 @@ export function AccountCard({
|
|
|
214
215
|
removing,
|
|
215
216
|
onReconnect,
|
|
216
217
|
onWorkspaceSave,
|
|
218
|
+
onAliasSave,
|
|
217
219
|
onModelSave,
|
|
218
220
|
onAgentPresetSave,
|
|
219
221
|
onContextEnhancementSave,
|
|
@@ -231,7 +233,7 @@ export function AccountCard({
|
|
|
231
233
|
header: h('div', { className: 'dxw-accountTop dim-botCardTop' },
|
|
232
234
|
h('div', { className: 'dxw-accountIdentity dim-botIdentity' },
|
|
233
235
|
h('div', { className: 'dxw-avatar dim-botAvatar', 'aria-hidden': 'true' }, h(WeixinLogoGlyph, { size: 27 })),
|
|
234
|
-
h('div', { className: 'dim-botName' }, h(
|
|
236
|
+
h('div', { className: 'dim-botName' }, h(BotName, { bot: account.bot, disabled: Boolean(busy), onSave: onAliasSave }), h('p', null, account.bot.accountIdMasked))),
|
|
235
237
|
h('div', {
|
|
236
238
|
className: 'dim-botCardTools',
|
|
237
239
|
// The header is the collapse toggle; keep inner controls clickable.
|
|
@@ -318,6 +320,7 @@ function AccountList(props) {
|
|
|
318
320
|
removing: props.removeTarget === account.botId,
|
|
319
321
|
onReconnect: () => props.onReconnect(account),
|
|
320
322
|
onWorkspaceSave: (workspace) => props.onWorkspaceSave(account, workspace),
|
|
323
|
+
onAliasSave: (alias) => props.onAliasSave(account, alias),
|
|
321
324
|
onModelSave: (model) => props.onModelSave(account, model),
|
|
322
325
|
onAgentPresetSave: (agentPreset) => props.onAgentPresetSave(account, agentPreset),
|
|
323
326
|
onContextEnhancementSave: (config) => props.onContextEnhancementSave(account, config),
|
|
@@ -752,6 +755,9 @@ export function WeixinSettingsTab({ rpcCall }) {
|
|
|
752
755
|
removeTarget,
|
|
753
756
|
onReconnect: (account) => void reconnect(account),
|
|
754
757
|
onWorkspaceSave: saveWorkspace,
|
|
758
|
+
onAliasSave: (account, alias) => saveBotSetting(
|
|
759
|
+
account, 'alias', WEIXIN_ENDPOINTS.setAlias, { alias },
|
|
760
|
+
),
|
|
755
761
|
onModelSave: (account, selectedModel) => saveBotSetting(
|
|
756
762
|
account, 'model', WEIXIN_ENDPOINTS.setModel, { model: selectedModel },
|
|
757
763
|
),
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { normalizeBotAlias } from '../../../../src/channels/shared/bot-alias.mjs';
|
|
1
2
|
import { normalizeAgentPresetCatalog, normalizeAgentPresetId, SET_AGENT_PRESET_ENDPOINT } from '../../agent-preset.js';
|
|
2
3
|
import { normalizeModelCatalog, normalizeModelSelection, SET_MODEL_ENDPOINT } from '../../model-setting.js';
|
|
3
4
|
import { normalizeLastMessageError } from '../../last-message-error.js';
|
|
@@ -14,6 +15,7 @@ export const WHATSAPP_ENDPOINTS = Object.freeze({
|
|
|
14
15
|
reconnectBot: 'bot.reconnect',
|
|
15
16
|
deleteBot: 'bot.delete',
|
|
16
17
|
setAccessPolicy: 'bot.access-policy.set',
|
|
18
|
+
setAlias: 'bot.alias.set',
|
|
17
19
|
setWorkspace: 'bot.workspace.set',
|
|
18
20
|
setModel: SET_MODEL_ENDPOINT,
|
|
19
21
|
setAgentPreset: SET_AGENT_PRESET_ENDPOINT,
|
|
@@ -99,6 +101,7 @@ function normalizeBot(value) {
|
|
|
99
101
|
? { accessPolicy: normalizeAccessPolicy(value.accessPolicy) }
|
|
100
102
|
: {}),
|
|
101
103
|
bot: {
|
|
104
|
+
...normalizeBotAlias(value.bot),
|
|
102
105
|
name: text(value.bot?.name, 'WhatsApp机器人', 100),
|
|
103
106
|
idMasked: text(value.bot?.idMasked, 'WhatsApp账号', 140),
|
|
104
107
|
},
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { BotName } from '../../bot-alias.js';
|
|
1
2
|
import * as React from 'react';
|
|
2
3
|
|
|
3
4
|
import { WhatsappLogoGlyph } from '../../channel-logos.js';
|
|
@@ -191,6 +192,7 @@ export function WhatsappAccountCard({
|
|
|
191
192
|
removing,
|
|
192
193
|
onReconnect,
|
|
193
194
|
onWorkspaceSave,
|
|
195
|
+
onAliasSave,
|
|
194
196
|
onModelSave,
|
|
195
197
|
onAgentPresetSave,
|
|
196
198
|
onContextEnhancementSave,
|
|
@@ -213,7 +215,7 @@ export function WhatsappAccountCard({
|
|
|
213
215
|
'aria-hidden': 'true',
|
|
214
216
|
}, h(WhatsappLogoGlyph, { size: 29 })),
|
|
215
217
|
h('div', { className: 'dim-botName' },
|
|
216
|
-
h(
|
|
218
|
+
h(BotName, { bot: account.bot, disabled: Boolean(busy), onSave: onAliasSave }), h('p', null, account.bot.idMasked))),
|
|
217
219
|
h('div', {
|
|
218
220
|
className: 'dim-botCardTools',
|
|
219
221
|
// The header is the collapse toggle; keep inner controls clickable.
|
|
@@ -512,6 +514,12 @@ export function WhatsappSettingsTab({ rpcCall }) {
|
|
|
512
514
|
WHATSAPP_ENDPOINTS.setWorkspace,
|
|
513
515
|
{ botId: account.botId, workspace },
|
|
514
516
|
),
|
|
517
|
+
onAliasSave: (alias) => botAction(
|
|
518
|
+
account,
|
|
519
|
+
'alias',
|
|
520
|
+
WHATSAPP_ENDPOINTS.setAlias,
|
|
521
|
+
{ botId: account.botId, alias },
|
|
522
|
+
),
|
|
515
523
|
onModelSave: (selectedModel) => botAction(
|
|
516
524
|
account,
|
|
517
525
|
'model',
|