@xmanrui/dsh-im 0.17.1 → 0.19.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 +3 -2
- package/README.md +3 -2
- package/lib/client.js +1297 -600
- package/lib/index.js +190 -145
- package/package.json +1 -1
- package/plugin-src/client/agent-preset.js +110 -0
- package/plugin-src/client/channels/dingtalk/api.js +5 -0
- package/plugin-src/client/channels/dingtalk/index.js +48 -2
- package/plugin-src/client/channels/feishu/api.js +28 -5
- package/plugin-src/client/channels/feishu/index.js +330 -41
- package/plugin-src/client/channels/feishu/styles.js +46 -0
- package/plugin-src/client/channels/qq/api.js +5 -0
- package/plugin-src/client/channels/qq/index.js +37 -6
- package/plugin-src/client/channels/shared/token-api.js +5 -0
- package/plugin-src/client/channels/shared/token-channel.js +34 -6
- package/plugin-src/client/channels/wecom/api.js +5 -0
- package/plugin-src/client/channels/wecom/index.js +37 -6
- package/plugin-src/client/channels/weixin/api.js +5 -0
- package/plugin-src/client/channels/weixin/index.js +50 -4
- package/plugin-src/client/channels/whatsapp/api.js +5 -0
- package/plugin-src/client/channels/whatsapp/index.js +30 -4
- package/plugin-src/client/i18n.js +59 -0
- package/plugin-src/client/styles.js +8 -0
- package/plugin-src/host/channels/dingtalk/production.mjs +10 -4
- package/plugin-src/host/channels/dingtalk/rpc.mjs +12 -0
- package/plugin-src/host/channels/feishu/connection-supervisor.mjs +1 -1
- package/plugin-src/host/channels/feishu/production.mjs +8 -3
- package/plugin-src/host/channels/feishu/rpc.mjs +78 -7
- package/plugin-src/host/channels/qq/production.mjs +10 -4
- package/plugin-src/host/channels/qq/rpc.mjs +12 -0
- package/plugin-src/host/channels/shared/agent-preset-rpc.mjs +25 -0
- package/plugin-src/host/channels/shared/production.mjs +10 -4
- package/plugin-src/host/channels/shared/rpc.mjs +12 -0
- package/plugin-src/host/channels/shared/workspace-rpc.mjs +2 -0
- package/plugin-src/host/channels/slack/production.mjs +10 -4
- package/plugin-src/host/channels/slack/rpc.mjs +13 -0
- package/plugin-src/host/channels/wecom/production.mjs +10 -4
- package/plugin-src/host/channels/wecom/rpc.mjs +12 -0
- package/plugin-src/host/channels/weixin/production.mjs +10 -4
- package/plugin-src/host/channels/weixin/rpc.mjs +15 -0
- package/plugin-src/host/channels/whatsapp/production.mjs +10 -4
- package/plugin-src/host/channels/whatsapp/rpc.mjs +12 -0
- package/src/channels/discord/discord-api.mjs +1 -1
- package/src/channels/feishu/bridge.mjs +29 -4
- package/src/channels/feishu/feishu-runtime.mjs +14 -0
- package/src/channels/feishu/group-message-permission-manager.mjs +71 -0
- package/src/channels/feishu/group-response-mode.mjs +15 -0
- package/src/channels/feishu/multi-bot-controller.mjs +258 -9
- package/src/channels/feishu/plugin-config-store.mjs +3 -0
- package/src/channels/feishu/repair-manager.mjs +17 -3
- package/src/channels/shared/agent-preset.mjs +74 -0
- package/src/channels/shared/bot-workspace-store.mjs +141 -14
- package/src/channels/shared/harness-client.mjs +6 -4
- package/src/channels/telegram/telegram-api.mjs +31 -0
- package/src/channels/telegram/telegram-runtime.mjs +25 -1
- package/src/channels/weixin/weixin-api.mjs +1 -1
package/package.json
CHANGED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
import { h } from './i18n.js';
|
|
4
|
+
|
|
5
|
+
export const SET_AGENT_PRESET_ENDPOINT = 'bot.preset.set';
|
|
6
|
+
|
|
7
|
+
const PRESET_ID = /^[a-z0-9][a-z0-9-]*$/;
|
|
8
|
+
|
|
9
|
+
export const EMPTY_AGENT_PRESET_CATALOG = Object.freeze({
|
|
10
|
+
defaultId: '',
|
|
11
|
+
items: Object.freeze([]),
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
export const AgentPresetCatalogContext = React.createContext(EMPTY_AGENT_PRESET_CATALOG);
|
|
15
|
+
|
|
16
|
+
export function normalizeAgentPresetId(value) {
|
|
17
|
+
if (typeof value !== 'string') return '';
|
|
18
|
+
const id = value.trim();
|
|
19
|
+
return PRESET_ID.test(id) ? id : '';
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function normalizeAgentPresetCatalog(value) {
|
|
23
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
24
|
+
return { defaultId: '', items: [] };
|
|
25
|
+
}
|
|
26
|
+
const items = [];
|
|
27
|
+
const seen = new Set();
|
|
28
|
+
for (const entry of Array.isArray(value.items) ? value.items : []) {
|
|
29
|
+
const id = typeof entry === 'string'
|
|
30
|
+
? normalizeAgentPresetId(entry)
|
|
31
|
+
: normalizeAgentPresetId(entry?.id);
|
|
32
|
+
if (!id || seen.has(id)) continue;
|
|
33
|
+
seen.add(id);
|
|
34
|
+
const label = typeof entry?.label === 'string' && entry.label.trim()
|
|
35
|
+
? entry.label.trim().slice(0, 128)
|
|
36
|
+
: typeof entry?.name === 'string' && entry.name.trim()
|
|
37
|
+
? entry.name.trim().slice(0, 128)
|
|
38
|
+
: id;
|
|
39
|
+
items.push({ id, label });
|
|
40
|
+
}
|
|
41
|
+
return {
|
|
42
|
+
defaultId: normalizeAgentPresetId(value.defaultId),
|
|
43
|
+
items,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function AgentPresetEditor({ agentPreset = '', disabled = false, onSave }) {
|
|
48
|
+
const catalog = React.useContext(AgentPresetCatalogContext) ?? EMPTY_AGENT_PRESET_CATALOG;
|
|
49
|
+
const current = normalizeAgentPresetId(agentPreset);
|
|
50
|
+
const [saving, setSaving] = React.useState(false);
|
|
51
|
+
const [error, setError] = React.useState(null);
|
|
52
|
+
|
|
53
|
+
const items = [];
|
|
54
|
+
const seen = new Set();
|
|
55
|
+
for (const item of Array.isArray(catalog.items) ? catalog.items : []) {
|
|
56
|
+
if (!item?.id || seen.has(item.id)) continue;
|
|
57
|
+
seen.add(item.id);
|
|
58
|
+
items.push(item);
|
|
59
|
+
}
|
|
60
|
+
const currentUnavailable = Boolean(current && !seen.has(current));
|
|
61
|
+
if (currentUnavailable) items.push({ id: current, label: current, unavailable: true });
|
|
62
|
+
|
|
63
|
+
const inheritLabel = '跟随 Host 默认';
|
|
64
|
+
|
|
65
|
+
const change = async (event) => {
|
|
66
|
+
const next = event.target.value;
|
|
67
|
+
if (next === current || saving || disabled) return;
|
|
68
|
+
setSaving(true);
|
|
69
|
+
setError(null);
|
|
70
|
+
try {
|
|
71
|
+
await onSave?.(next || null);
|
|
72
|
+
} catch (cause) {
|
|
73
|
+
setError(cause?.message ?? 'Agent Preset 修改失败,请重试。');
|
|
74
|
+
} finally {
|
|
75
|
+
setSaving(false);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
return h('div', { className: 'dim-preset' },
|
|
80
|
+
h('div', { className: 'dim-presetHeader' },
|
|
81
|
+
h('span', null, 'Agent Preset'),
|
|
82
|
+
saving ? h('span', { className: 'dim-presetStatus' }, '保存中…') : null),
|
|
83
|
+
React.createElement('select', {
|
|
84
|
+
className: 'dim-presetSelect',
|
|
85
|
+
value: current,
|
|
86
|
+
disabled: disabled || saving,
|
|
87
|
+
'aria-label': 'Agent Preset',
|
|
88
|
+
onChange: (event) => { void change(event); },
|
|
89
|
+
},
|
|
90
|
+
h('option', { value: '' }, inheritLabel),
|
|
91
|
+
...items.map((item) => h(
|
|
92
|
+
'option',
|
|
93
|
+
{ key: item.id, value: item.id },
|
|
94
|
+
item.unavailable
|
|
95
|
+
? [item.id, '(已不可用)']
|
|
96
|
+
: item.label && item.label !== item.id ? `${item.label}(${item.id})` : item.id,
|
|
97
|
+
)),
|
|
98
|
+
),
|
|
99
|
+
h(
|
|
100
|
+
'small',
|
|
101
|
+
{ className: 'dim-presetHelp' },
|
|
102
|
+
'只影响新建会话;若当前聊天已有会话,先发送 /new,再发送普通消息生效。',
|
|
103
|
+
),
|
|
104
|
+
error || currentUnavailable ? h(
|
|
105
|
+
'p',
|
|
106
|
+
{ className: 'dim-presetError', role: error ? 'alert' : 'status' },
|
|
107
|
+
error ?? '当前 Agent Preset 已不可用,请选择其他 Preset 或跟随 Host 默认。',
|
|
108
|
+
) : null,
|
|
109
|
+
);
|
|
110
|
+
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { normalizeAgentPresetCatalog, normalizeAgentPresetId, SET_AGENT_PRESET_ENDPOINT } from '../../agent-preset.js';
|
|
2
|
+
|
|
1
3
|
export const DINGTALK_RPC_CHANNEL = '/dingtalk';
|
|
2
4
|
|
|
3
5
|
export const DINGTALK_ENDPOINTS = Object.freeze({
|
|
@@ -9,6 +11,7 @@ export const DINGTALK_ENDPOINTS = Object.freeze({
|
|
|
9
11
|
reconnectBot: 'bot.reconnect',
|
|
10
12
|
deleteBot: 'bot.delete',
|
|
11
13
|
setWorkspace: 'bot.workspace.set',
|
|
14
|
+
setAgentPreset: SET_AGENT_PRESET_ENDPOINT,
|
|
12
15
|
});
|
|
13
16
|
|
|
14
17
|
const ACCOUNT_STATES = new Set(['connected', 'connecting', 'offline', 'error']);
|
|
@@ -157,6 +160,7 @@ function normalizeBot(value) {
|
|
|
157
160
|
connected,
|
|
158
161
|
configured: value.configured !== false,
|
|
159
162
|
workspace: optionalString(value.workspace, 4_096) ?? '',
|
|
163
|
+
agentPreset: normalizeAgentPresetId(value.agentPreset),
|
|
160
164
|
bot: {
|
|
161
165
|
name: optionalString(bot.name, 100) ?? '钉钉机器人',
|
|
162
166
|
clientIdMasked: optionalString(bot.clientIdMasked, 140) ?? '已安全保存',
|
|
@@ -200,6 +204,7 @@ export function normalizeSnapshot(value) {
|
|
|
200
204
|
},
|
|
201
205
|
provisioning: source.provisioning ? normalizeProvisioning(source.provisioning) : null,
|
|
202
206
|
testMessage: normalizeTestMessage(source.testMessage),
|
|
207
|
+
agentPresetCatalog: normalizeAgentPresetCatalog(source.agentPresetCatalog),
|
|
203
208
|
};
|
|
204
209
|
}
|
|
205
210
|
|
|
@@ -3,6 +3,11 @@ import * as React from 'react';
|
|
|
3
3
|
import { CredentialActionIcon, CredentialBindingPanel, QrActionIcon } from '../../credential-binding.js';
|
|
4
4
|
import { h } from '../../i18n.js';
|
|
5
5
|
import { WorkspaceEditor } from '../../workspace-editor.js';
|
|
6
|
+
import {
|
|
7
|
+
AgentPresetCatalogContext,
|
|
8
|
+
AgentPresetEditor,
|
|
9
|
+
EMPTY_AGENT_PRESET_CATALOG,
|
|
10
|
+
} from '../../agent-preset.js';
|
|
6
11
|
import { useWorkspaceSnapshotFence } from '../../workspace-snapshot-fence.js';
|
|
7
12
|
import {
|
|
8
13
|
DINGTALK_ENDPOINTS,
|
|
@@ -213,6 +218,7 @@ export function AccountCard({
|
|
|
213
218
|
removing,
|
|
214
219
|
onReconnect,
|
|
215
220
|
onWorkspaceSave,
|
|
221
|
+
onAgentPresetSave,
|
|
216
222
|
onRequestRemove,
|
|
217
223
|
onConfirmRemove,
|
|
218
224
|
onCancelRemove,
|
|
@@ -241,6 +247,11 @@ export function AccountCard({
|
|
|
241
247
|
disabled: Boolean(busy),
|
|
242
248
|
onSave: onWorkspaceSave,
|
|
243
249
|
}),
|
|
250
|
+
h(AgentPresetEditor, {
|
|
251
|
+
agentPreset: account.agentPreset,
|
|
252
|
+
disabled: Boolean(busy),
|
|
253
|
+
onSave: onAgentPresetSave,
|
|
254
|
+
}),
|
|
244
255
|
h('div', { className: 'ddt-accountFooter dim-cardFooter' },
|
|
245
256
|
summary ? h('div', { className: 'ddt-summary dim-cardSummary' }, summary) : null,
|
|
246
257
|
feedback ? h('div', {
|
|
@@ -272,6 +283,7 @@ function AccountList(props) {
|
|
|
272
283
|
removing: props.removeTarget === account.botId,
|
|
273
284
|
onReconnect: () => props.onReconnect(account),
|
|
274
285
|
onWorkspaceSave: (workspace) => props.onWorkspaceSave(account, workspace),
|
|
286
|
+
onAgentPresetSave: (agentPreset) => props.onAgentPresetSave(account, agentPreset),
|
|
275
287
|
onRequestRemove: () => props.onRequestRemove(account),
|
|
276
288
|
onConfirmRemove: () => props.onConfirmRemove(account),
|
|
277
289
|
onCancelRemove: props.onCancelRemove,
|
|
@@ -283,6 +295,7 @@ const EMPTY_TOTALS = Object.freeze({ configured: 0, connected: 0 });
|
|
|
283
295
|
export function DingtalkSettingsTab({ rpcCall }) {
|
|
284
296
|
const [model, setModel] = React.useState({
|
|
285
297
|
phase: 'loading', bots: [], totals: EMPTY_TOTALS, revision: 0, error: null,
|
|
298
|
+
agentPresetCatalog: EMPTY_AGENT_PRESET_CATALOG,
|
|
286
299
|
});
|
|
287
300
|
const [provision, setProvision] = React.useState(null);
|
|
288
301
|
const [busy, setBusy] = React.useState(false);
|
|
@@ -389,6 +402,7 @@ export function DingtalkSettingsTab({ rpcCall }) {
|
|
|
389
402
|
totals: snapshot.totals,
|
|
390
403
|
revision: snapshot.revision,
|
|
391
404
|
error: null,
|
|
405
|
+
agentPresetCatalog: snapshot.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG,
|
|
392
406
|
});
|
|
393
407
|
discardStaleFeedback(snapshot);
|
|
394
408
|
if (restoreProvisioning && snapshot.provisioning) {
|
|
@@ -504,6 +518,7 @@ export function DingtalkSettingsTab({ rpcCall }) {
|
|
|
504
518
|
totals: snapshot.totals,
|
|
505
519
|
revision: snapshot.revision,
|
|
506
520
|
error: null,
|
|
521
|
+
agentPresetCatalog: snapshot.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG,
|
|
507
522
|
});
|
|
508
523
|
discardStaleFeedback(snapshot);
|
|
509
524
|
}
|
|
@@ -638,6 +653,7 @@ export function DingtalkSettingsTab({ rpcCall }) {
|
|
|
638
653
|
totals: snapshot.totals,
|
|
639
654
|
revision: snapshot.revision,
|
|
640
655
|
error: null,
|
|
656
|
+
agentPresetCatalog: snapshot.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG,
|
|
641
657
|
});
|
|
642
658
|
discardStaleFeedback(snapshot);
|
|
643
659
|
}
|
|
@@ -700,6 +716,33 @@ export function DingtalkSettingsTab({ rpcCall }) {
|
|
|
700
716
|
totals: snapshot.totals,
|
|
701
717
|
revision: snapshot.revision,
|
|
702
718
|
error: null,
|
|
719
|
+
agentPresetCatalog: snapshot.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG,
|
|
720
|
+
});
|
|
721
|
+
discardStaleFeedback(snapshot);
|
|
722
|
+
}
|
|
723
|
+
} finally {
|
|
724
|
+
const shouldRefresh = workspaceFence.endMutation();
|
|
725
|
+
if (shouldRefresh && mountedRef.current) void loadStatus({ silent: true });
|
|
726
|
+
if (mountedRef.current) setBotBusy(account.botId, null);
|
|
727
|
+
}
|
|
728
|
+
}, [discardStaleFeedback, invoke, loadStatus, setBotBusy, workspaceFence]);
|
|
729
|
+
|
|
730
|
+
const saveAgentPreset = React.useCallback(async (account, agentPreset) => {
|
|
731
|
+
const snapshotVersion = workspaceFence.beginMutation();
|
|
732
|
+
setBotBusy(account.botId, 'preset');
|
|
733
|
+
try {
|
|
734
|
+
const snapshot = normalizeSnapshot(await invoke(
|
|
735
|
+
DINGTALK_ENDPOINTS.setAgentPreset,
|
|
736
|
+
{ botId: account.botId, agentPreset },
|
|
737
|
+
));
|
|
738
|
+
if (mountedRef.current && workspaceFence.canCommitMutation(snapshotVersion)) {
|
|
739
|
+
setModel({
|
|
740
|
+
phase: 'ready',
|
|
741
|
+
bots: snapshot.bots,
|
|
742
|
+
totals: snapshot.totals,
|
|
743
|
+
revision: snapshot.revision,
|
|
744
|
+
error: null,
|
|
745
|
+
agentPresetCatalog: snapshot.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG,
|
|
703
746
|
});
|
|
704
747
|
discardStaleFeedback(snapshot);
|
|
705
748
|
}
|
|
@@ -762,7 +805,9 @@ export function DingtalkSettingsTab({ rpcCall }) {
|
|
|
762
805
|
})
|
|
763
806
|
: null;
|
|
764
807
|
|
|
765
|
-
return h(
|
|
808
|
+
return h(AgentPresetCatalogContext.Provider, {
|
|
809
|
+
value: model.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG,
|
|
810
|
+
}, h('section', { className: 'ddt-page dim-channelPage', 'aria-label': '钉钉设置' },
|
|
766
811
|
h(Heading, {
|
|
767
812
|
totals: model.totals,
|
|
768
813
|
adding: Boolean(provision),
|
|
@@ -798,11 +843,12 @@ export function DingtalkSettingsTab({ rpcCall }) {
|
|
|
798
843
|
removeTarget,
|
|
799
844
|
onReconnect: (account) => void reconnect(account),
|
|
800
845
|
onWorkspaceSave: saveWorkspace,
|
|
846
|
+
onAgentPresetSave: saveAgentPreset,
|
|
801
847
|
onRequestRemove: (account) => setRemoveTarget(account.botId),
|
|
802
848
|
onConfirmRemove: (account) => void remove(account),
|
|
803
849
|
onCancelRemove: () => setRemoveTarget(null),
|
|
804
850
|
})
|
|
805
|
-
: null));
|
|
851
|
+
: null)));
|
|
806
852
|
}
|
|
807
853
|
|
|
808
854
|
export function apply(ctx) {
|
|
@@ -6,12 +6,15 @@
|
|
|
6
6
|
* must never be returned by any endpoint on this channel.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
+
import { normalizeAgentPresetCatalog, normalizeAgentPresetId } from "../../agent-preset.js";
|
|
10
|
+
|
|
9
11
|
export const FEISHU_RPC_CHANNEL = "/feishu";
|
|
10
12
|
|
|
11
13
|
export const FEISHU_ENDPOINTS = Object.freeze({
|
|
12
14
|
status: "connection.status",
|
|
13
15
|
beginProvisioning: "provision.begin",
|
|
14
16
|
beginCallbackRepair: "bot.callback-repair.begin",
|
|
17
|
+
beginGroupMessagePermission: "bot.group-message-permission.begin",
|
|
15
18
|
pollProvisioning: "provision.poll",
|
|
16
19
|
cancelProvisioning: "provision.cancel",
|
|
17
20
|
bindCredentials: "bot.bind-credentials",
|
|
@@ -19,6 +22,8 @@ export const FEISHU_ENDPOINTS = Object.freeze({
|
|
|
19
22
|
disconnectBot: "bot.disconnect",
|
|
20
23
|
deleteBot: "bot.delete",
|
|
21
24
|
setWorkspace: "bot.workspace.set",
|
|
25
|
+
setAgentPreset: "bot.preset.set",
|
|
26
|
+
setGroupResponseMode: "bot.group-response-mode.set",
|
|
22
27
|
// Kept for rolling upgrades. The multi-bot UI never calls these endpoints.
|
|
23
28
|
testConnection: "connection.test",
|
|
24
29
|
disconnect: "connection.disconnect",
|
|
@@ -27,6 +32,7 @@ export const FEISHU_ENDPOINTS = Object.freeze({
|
|
|
27
32
|
export const FEISHU_REGISTRATION_OPERATIONS = Object.freeze({
|
|
28
33
|
PROVISION: "provision",
|
|
29
34
|
CALLBACK_REPAIR: "callback_repair",
|
|
35
|
+
GROUP_MESSAGE_PERMISSION: "group_message_permission",
|
|
30
36
|
});
|
|
31
37
|
|
|
32
38
|
const CONNECTION_STATES = new Set([
|
|
@@ -67,6 +73,10 @@ function optionalTimestamp(value) {
|
|
|
67
73
|
return undefined;
|
|
68
74
|
}
|
|
69
75
|
|
|
76
|
+
export function normalizeGroupResponseMode(value) {
|
|
77
|
+
return value === "all" ? "all" : "mention";
|
|
78
|
+
}
|
|
79
|
+
|
|
70
80
|
function clamp(value, min, max, fallback) {
|
|
71
81
|
return typeof value === "number" && Number.isFinite(value)
|
|
72
82
|
? Math.min(max, Math.max(min, value))
|
|
@@ -74,9 +84,18 @@ function clamp(value, min, max, fallback) {
|
|
|
74
84
|
}
|
|
75
85
|
|
|
76
86
|
function normalizeRegistrationOperation(value) {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
87
|
+
if (value === FEISHU_REGISTRATION_OPERATIONS.CALLBACK_REPAIR) {
|
|
88
|
+
return FEISHU_REGISTRATION_OPERATIONS.CALLBACK_REPAIR;
|
|
89
|
+
}
|
|
90
|
+
if (value === FEISHU_REGISTRATION_OPERATIONS.GROUP_MESSAGE_PERMISSION) {
|
|
91
|
+
return FEISHU_REGISTRATION_OPERATIONS.GROUP_MESSAGE_PERMISSION;
|
|
92
|
+
}
|
|
93
|
+
return FEISHU_REGISTRATION_OPERATIONS.PROVISION;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function isTargetedAppUpdate(operation) {
|
|
97
|
+
return operation === FEISHU_REGISTRATION_OPERATIONS.CALLBACK_REPAIR
|
|
98
|
+
|| operation === FEISHU_REGISTRATION_OPERATIONS.GROUP_MESSAGE_PERMISSION;
|
|
80
99
|
}
|
|
81
100
|
|
|
82
101
|
export function unwrapRpcResult(result) {
|
|
@@ -109,8 +128,8 @@ export function normalizeProvisioning(value, now = Date.now()) {
|
|
|
109
128
|
const expireIn = clamp(source.expireIn, 1, 60 * 60, 5 * 60);
|
|
110
129
|
const operation = normalizeRegistrationOperation(source.operation);
|
|
111
130
|
const botId = optionalString(source.botId);
|
|
112
|
-
if (operation
|
|
113
|
-
throw new Error("
|
|
131
|
+
if (isTargetedAppUpdate(operation) && !botId) {
|
|
132
|
+
throw new Error("飞书服务返回的应用更新信息缺少 botId");
|
|
114
133
|
}
|
|
115
134
|
return {
|
|
116
135
|
attemptId,
|
|
@@ -182,6 +201,9 @@ export function normalizeBotConnection(value, fallbackBotId) {
|
|
|
182
201
|
connected,
|
|
183
202
|
configured: value.configured !== false,
|
|
184
203
|
workspace: optionalString(value.workspace)?.slice(0, 4_096) ?? "",
|
|
204
|
+
agentPreset: normalizeAgentPresetId(value.agentPreset),
|
|
205
|
+
groupResponseMode: normalizeGroupResponseMode(value.groupResponseMode),
|
|
206
|
+
groupMessagePermissionGranted: value.groupMessagePermissionGranted === true,
|
|
185
207
|
bot: normalizeBot(value.bot),
|
|
186
208
|
health: normalizeHealth(value.health, connected),
|
|
187
209
|
error: normalizeError(value.error),
|
|
@@ -236,6 +258,7 @@ export function normalizeBotsSnapshot(value) {
|
|
|
236
258
|
? normalizeProvisioning(value.provisioning)
|
|
237
259
|
: undefined,
|
|
238
260
|
error: normalizeError(value.error),
|
|
261
|
+
agentPresetCatalog: normalizeAgentPresetCatalog(value.agentPresetCatalog),
|
|
239
262
|
};
|
|
240
263
|
}
|
|
241
264
|
|