@xmanrui/dsh-im 4.10.0 → 4.11.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/PROACTIVE_DELIVERY.en.md +15 -1
- package/PROACTIVE_DELIVERY.md +15 -1
- package/README.en.md +5 -1
- package/README.md +6 -2
- package/lib/client.js +1619 -769
- package/lib/index.js +248 -244
- package/package.json +4 -3
- package/plugin-src/client/channel-card-meta.js +9 -1
- package/plugin-src/client/channels/dingtalk/api.js +4 -0
- package/plugin-src/client/channels/dingtalk/index.js +25 -2
- package/plugin-src/client/channels/feishu/api.js +4 -0
- package/plugin-src/client/channels/feishu/group-settings.js +581 -0
- package/plugin-src/client/channels/feishu/index.js +26 -204
- package/plugin-src/client/channels/qq/api.js +4 -0
- package/plugin-src/client/channels/qq/index.js +25 -2
- package/plugin-src/client/channels/shared/token-api.js +4 -0
- package/plugin-src/client/channels/shared/token-channel.js +25 -3
- package/plugin-src/client/channels/wecom/api.js +4 -0
- package/plugin-src/client/channels/wecom/index.js +25 -2
- package/plugin-src/client/channels/weixin/api.js +4 -0
- package/plugin-src/client/channels/weixin/index.js +25 -2
- package/plugin-src/client/channels/whatsapp/api.js +4 -0
- package/plugin-src/client/channels/whatsapp/index.js +24 -2
- package/plugin-src/client/delivery-settings.js +73 -5
- package/plugin-src/client/i18n.js +20 -0
- package/plugin-src/client/model-setting.js +104 -0
- package/plugin-src/client/styles.js +50 -0
- package/plugin-src/host/channels/dingtalk/production.mjs +3 -0
- package/plugin-src/host/channels/dingtalk/rpc.mjs +11 -0
- package/plugin-src/host/channels/feishu/production.mjs +3 -0
- package/plugin-src/host/channels/feishu/rpc.mjs +16 -0
- package/plugin-src/host/channels/qq/production.mjs +3 -0
- package/plugin-src/host/channels/qq/rpc.mjs +11 -0
- package/plugin-src/host/channels/shared/model-setting-rpc.mjs +19 -0
- package/plugin-src/host/channels/shared/production.mjs +3 -0
- package/plugin-src/host/channels/shared/rpc.mjs +9 -0
- package/plugin-src/host/channels/shared/workspace-rpc.mjs +2 -0
- package/plugin-src/host/channels/slack/production.mjs +3 -0
- package/plugin-src/host/channels/slack/rpc.mjs +9 -0
- package/plugin-src/host/channels/wecom/production.mjs +3 -0
- package/plugin-src/host/channels/wecom/rpc.mjs +11 -0
- package/plugin-src/host/channels/weixin/production.mjs +3 -0
- package/plugin-src/host/channels/weixin/rpc.mjs +11 -0
- package/plugin-src/host/channels/whatsapp/production.mjs +3 -0
- package/plugin-src/host/channels/whatsapp/rpc.mjs +11 -0
- package/plugin-src/host/delivery-adapter.mjs +141 -3
- package/plugin-src/host/delivery-rpc.mjs +12 -0
- package/plugin-src/host/delivery-service.mjs +110 -3
- package/plugin-src/host/delivery-suggestions.mjs +46 -0
- package/plugin-src/host/harness-session-coordinator.mjs +6 -5
- package/plugin-src/host/index.mjs +18 -1
- package/plugin-src/host/session-sync-coordinator.mjs +217 -0
- package/scripts/verify-package.mjs +12 -6
- package/src/channels/shared/bot-workspace-store.mjs +285 -38
- package/src/channels/shared/harness-client.mjs +124 -43
- package/src/channels/shared/model-setting.mjs +110 -0
|
@@ -8,7 +8,6 @@ import {
|
|
|
8
8
|
FEISHU_REGISTRATION_OPERATIONS,
|
|
9
9
|
formatRemaining,
|
|
10
10
|
normalizeBotsSnapshot,
|
|
11
|
-
normalizeGroupResponseMode,
|
|
12
11
|
normalizePollResult,
|
|
13
12
|
normalizeProvisioning,
|
|
14
13
|
presentError,
|
|
@@ -22,6 +21,11 @@ import {
|
|
|
22
21
|
AgentPresetEditor,
|
|
23
22
|
EMPTY_AGENT_PRESET_CATALOG,
|
|
24
23
|
} from "../../agent-preset.js";
|
|
24
|
+
import {
|
|
25
|
+
EMPTY_MODEL_CATALOG,
|
|
26
|
+
ModelCatalogContext,
|
|
27
|
+
ModelEditor,
|
|
28
|
+
} from "../../model-setting.js";
|
|
25
29
|
import { useWorkspaceSnapshotFence } from "../../workspace-snapshot-fence.js";
|
|
26
30
|
import {
|
|
27
31
|
BotSettingsButton,
|
|
@@ -459,133 +463,6 @@ function RemoveConfirmation({ bot, busy, onConfirm, onCancel }) {
|
|
|
459
463
|
);
|
|
460
464
|
}
|
|
461
465
|
|
|
462
|
-
function GroupResponseModeEditor({
|
|
463
|
-
value,
|
|
464
|
-
permissionGranted = false,
|
|
465
|
-
disabled = false,
|
|
466
|
-
authorizationDisabled = false,
|
|
467
|
-
onSave,
|
|
468
|
-
onAuthorize,
|
|
469
|
-
}) {
|
|
470
|
-
const current = normalizeGroupResponseMode(value);
|
|
471
|
-
const [saving, setSaving] = React.useState(false);
|
|
472
|
-
const [authorizing, setAuthorizing] = React.useState(false);
|
|
473
|
-
const [error, setError] = React.useState(null);
|
|
474
|
-
|
|
475
|
-
const change = async (event) => {
|
|
476
|
-
const next = normalizeGroupResponseMode(event.target.value);
|
|
477
|
-
if (next === current || saving || disabled) return;
|
|
478
|
-
setSaving(true);
|
|
479
|
-
setError(null);
|
|
480
|
-
try {
|
|
481
|
-
await onSave?.(next);
|
|
482
|
-
} catch (cause) {
|
|
483
|
-
setError(cause?.message ?? "群聊响应方式修改失败,请重试。");
|
|
484
|
-
} finally {
|
|
485
|
-
setSaving(false);
|
|
486
|
-
}
|
|
487
|
-
};
|
|
488
|
-
|
|
489
|
-
const authorize = async () => {
|
|
490
|
-
if (current !== "all" || saving || authorizing || disabled || authorizationDisabled) return;
|
|
491
|
-
setAuthorizing(true);
|
|
492
|
-
setError(null);
|
|
493
|
-
try {
|
|
494
|
-
await onAuthorize?.();
|
|
495
|
-
} catch (cause) {
|
|
496
|
-
setError(cause?.message ?? "群消息权限授权失败,请重试。");
|
|
497
|
-
} finally {
|
|
498
|
-
setAuthorizing(false);
|
|
499
|
-
}
|
|
500
|
-
};
|
|
501
|
-
|
|
502
|
-
return h("div", { className: "bxf-responseMode dim-responseMode" },
|
|
503
|
-
h("div", { className: "bxf-responseModeHeader dim-responseModeHeader" },
|
|
504
|
-
h("span", null, "群聊响应方式"),
|
|
505
|
-
saving || authorizing
|
|
506
|
-
? h("span", { className: "bxf-responseModeStatus dim-responseModeStatus" },
|
|
507
|
-
saving ? "保存中…" : "正在准备授权…")
|
|
508
|
-
: null),
|
|
509
|
-
h("select", {
|
|
510
|
-
className: "bxf-responseModeSelect dim-responseModeSelect",
|
|
511
|
-
value: current,
|
|
512
|
-
disabled: disabled || saving,
|
|
513
|
-
"aria-label": "群聊响应方式",
|
|
514
|
-
onChange: (event) => { void change(event); },
|
|
515
|
-
},
|
|
516
|
-
h("option", { value: "mention" }, "仅在 @机器人时响应(推荐)"),
|
|
517
|
-
h("option", { value: "all" }, "响应所有群消息"),
|
|
518
|
-
),
|
|
519
|
-
h("small", { className: "bxf-responseModeHelp dim-responseModeHelp" },
|
|
520
|
-
current === "mention"
|
|
521
|
-
? permissionGranted
|
|
522
|
-
? "私聊始终响应;群聊仅处理明确 @当前机器人的消息。群消息权限已开通,再次切换无需授权。"
|
|
523
|
-
: "私聊始终响应;群聊仅处理明确 @当前机器人的消息。选择全部消息后会打开飞书官方授权流程。"
|
|
524
|
-
: permissionGranted
|
|
525
|
-
? "已开通“获取群组中所有消息”权限(im:message.group_msg);机器人会处理群聊中的所有可见消息。"
|
|
526
|
-
: "尚未确认“获取群组中所有消息”权限,请完成飞书授权。"),
|
|
527
|
-
current === "all"
|
|
528
|
-
? h("div", { className: "bxf-responseModePermissionAction dim-responseModePermissionAction" },
|
|
529
|
-
h(Button, {
|
|
530
|
-
className: "bxf-responseModePermissionButton",
|
|
531
|
-
size: "small",
|
|
532
|
-
disabled: disabled || authorizationDisabled || saving || authorizing,
|
|
533
|
-
"aria-busy": authorizing ? "true" : undefined,
|
|
534
|
-
"aria-label": permissionGranted ? "重新授权群消息权限" : "授权群消息权限",
|
|
535
|
-
onClick: () => { void authorize(); },
|
|
536
|
-
}, authorizing ? "正在准备…" : permissionGranted ? "重新授权" : "去授权"))
|
|
537
|
-
: null,
|
|
538
|
-
error ? h("p", {
|
|
539
|
-
className: "bxf-responseModeError dim-responseModeError",
|
|
540
|
-
role: "alert",
|
|
541
|
-
}, error) : null,
|
|
542
|
-
);
|
|
543
|
-
}
|
|
544
|
-
|
|
545
|
-
function GroupTopicReplyEditor({ value = false, disabled = false, onSave }) {
|
|
546
|
-
const current = value === true ? "on" : "off";
|
|
547
|
-
const [saving, setSaving] = React.useState(false);
|
|
548
|
-
const [error, setError] = React.useState(null);
|
|
549
|
-
|
|
550
|
-
const change = async (event) => {
|
|
551
|
-
const next = event.target.value === "on";
|
|
552
|
-
if ((next ? "on" : "off") === current || saving || disabled) return;
|
|
553
|
-
setSaving(true);
|
|
554
|
-
setError(null);
|
|
555
|
-
try {
|
|
556
|
-
await onSave?.(next);
|
|
557
|
-
} catch (cause) {
|
|
558
|
-
setError(cause?.message ?? "群聊以话题方式回复设置保存失败,请重试。");
|
|
559
|
-
} finally {
|
|
560
|
-
setSaving(false);
|
|
561
|
-
}
|
|
562
|
-
};
|
|
563
|
-
|
|
564
|
-
return h("div", { className: "bxf-responseMode dim-responseMode" },
|
|
565
|
-
h("div", { className: "bxf-responseModeHeader dim-responseModeHeader" },
|
|
566
|
-
h("span", null, "群聊以话题方式回复"),
|
|
567
|
-
saving
|
|
568
|
-
? h("span", { className: "bxf-responseModeStatus dim-responseModeStatus" }, "保存中…")
|
|
569
|
-
: null),
|
|
570
|
-
h("select", {
|
|
571
|
-
className: "bxf-responseModeSelect dim-responseModeSelect",
|
|
572
|
-
value: current,
|
|
573
|
-
disabled: disabled || saving,
|
|
574
|
-
"aria-label": "群聊以话题方式回复",
|
|
575
|
-
onChange: (event) => { void change(event); },
|
|
576
|
-
},
|
|
577
|
-
h("option", { value: "off" }, "关闭(群内直接回复)"),
|
|
578
|
-
h("option", { value: "on" }, "开启(自动开启独立飞书话题)"),
|
|
579
|
-
),
|
|
580
|
-
h("small", { className: "bxf-responseModeHelp dim-responseModeHelp" },
|
|
581
|
-
"开启后,群聊中向机器人提问会自动开启独立飞书话题,回复落在话题内;每个话题是 dsh 会话列表里一条独立会话,上下文互不串。私聊不受影响。"),
|
|
582
|
-
error ? h("p", {
|
|
583
|
-
className: "bxf-responseModeError dim-responseModeError",
|
|
584
|
-
role: "alert",
|
|
585
|
-
}, error) : null,
|
|
586
|
-
);
|
|
587
|
-
}
|
|
588
|
-
|
|
589
466
|
export function BotCard({
|
|
590
467
|
connection,
|
|
591
468
|
busy,
|
|
@@ -598,11 +475,9 @@ export function BotCard({
|
|
|
598
475
|
onReconnect,
|
|
599
476
|
onRepairCallback,
|
|
600
477
|
onWorkspaceSave,
|
|
478
|
+
onModelSave,
|
|
601
479
|
onAgentPresetSave,
|
|
602
480
|
onContextEnhancementSave,
|
|
603
|
-
onGroupResponseModeSave,
|
|
604
|
-
onGroupTopicReplySave,
|
|
605
|
-
onGroupMessagePermissionAuthorize,
|
|
606
481
|
onRequestRemove,
|
|
607
482
|
onConfirmRemove,
|
|
608
483
|
onCancelRemove,
|
|
@@ -655,6 +530,11 @@ export function BotCard({
|
|
|
655
530
|
botName: bot.name,
|
|
656
531
|
connected,
|
|
657
532
|
accessPolicy: connection.accessPolicy,
|
|
533
|
+
channelSettings: {
|
|
534
|
+
groupResponseMode: connection.groupResponseMode,
|
|
535
|
+
groupTopicReply: connection.groupTopicReply,
|
|
536
|
+
groupMessagePermissionGranted: connection.groupMessagePermissionGranted,
|
|
537
|
+
},
|
|
658
538
|
})),
|
|
659
539
|
),
|
|
660
540
|
h(WorkspaceEditor, {
|
|
@@ -662,6 +542,11 @@ export function BotCard({
|
|
|
662
542
|
disabled: Boolean(busy),
|
|
663
543
|
onSave: onWorkspaceSave,
|
|
664
544
|
}),
|
|
545
|
+
h(ModelEditor, {
|
|
546
|
+
model: connection.model,
|
|
547
|
+
disabled: Boolean(busy),
|
|
548
|
+
onSave: onModelSave,
|
|
549
|
+
}),
|
|
665
550
|
h(AgentPresetEditor, {
|
|
666
551
|
agentPreset: connection.agentPreset,
|
|
667
552
|
disabled: Boolean(busy),
|
|
@@ -672,19 +557,6 @@ export function BotCard({
|
|
|
672
557
|
disabled: Boolean(busy),
|
|
673
558
|
onSave: onContextEnhancementSave,
|
|
674
559
|
}),
|
|
675
|
-
h(GroupResponseModeEditor, {
|
|
676
|
-
value: connection.groupResponseMode,
|
|
677
|
-
permissionGranted: connection.groupMessagePermissionGranted,
|
|
678
|
-
disabled: Boolean(busy),
|
|
679
|
-
authorizationDisabled: repairDisabled,
|
|
680
|
-
onSave: onGroupResponseModeSave,
|
|
681
|
-
onAuthorize: onGroupMessagePermissionAuthorize,
|
|
682
|
-
}),
|
|
683
|
-
h(GroupTopicReplyEditor, {
|
|
684
|
-
value: connection.groupTopicReply,
|
|
685
|
-
disabled: Boolean(busy),
|
|
686
|
-
onSave: onGroupTopicReplySave,
|
|
687
|
-
}),
|
|
688
560
|
provisionContent
|
|
689
561
|
? h("section", {
|
|
690
562
|
className: "bxf-botProvision dim-botProvision",
|
|
@@ -773,11 +645,9 @@ function BotList(props) {
|
|
|
773
645
|
onReconnect: () => props.onReconnect(bot),
|
|
774
646
|
onRepairCallback: () => props.onRepairCallback(bot),
|
|
775
647
|
onWorkspaceSave: (workspace) => props.onWorkspaceSave(bot, workspace),
|
|
648
|
+
onModelSave: (model) => props.onModelSave(bot, model),
|
|
776
649
|
onAgentPresetSave: (agentPreset) => props.onAgentPresetSave(bot, agentPreset),
|
|
777
650
|
onContextEnhancementSave: (config) => props.onContextEnhancementSave(bot, config),
|
|
778
|
-
onGroupResponseModeSave: (groupResponseMode) => props.onGroupResponseModeSave(bot, groupResponseMode),
|
|
779
|
-
onGroupTopicReplySave: (groupTopicReply) => props.onGroupTopicReplySave(bot, groupTopicReply),
|
|
780
|
-
onGroupMessagePermissionAuthorize: () => props.onGroupMessagePermissionAuthorize(bot),
|
|
781
651
|
onRequestRemove: () => props.onRequestRemove(bot),
|
|
782
652
|
onConfirmRemove: () => props.onConfirmRemove(bot),
|
|
783
653
|
onCancelRemove: props.onCancelRemove,
|
|
@@ -830,6 +700,7 @@ export function mergeFeishuSnapshotState(
|
|
|
830
700
|
pageError: null,
|
|
831
701
|
statusError: null,
|
|
832
702
|
agentPresetCatalog: snapshot.agentPresetCatalog ?? current.agentPresetCatalog,
|
|
703
|
+
modelCatalog: snapshot.modelCatalog ?? current.modelCatalog,
|
|
833
704
|
};
|
|
834
705
|
}
|
|
835
706
|
|
|
@@ -843,6 +714,7 @@ export function FeishuSettingsTab({ rpcCall }) {
|
|
|
843
714
|
pageError: null,
|
|
844
715
|
statusError: null,
|
|
845
716
|
agentPresetCatalog: EMPTY_AGENT_PRESET_CATALOG,
|
|
717
|
+
modelCatalog: EMPTY_MODEL_CATALOG,
|
|
846
718
|
});
|
|
847
719
|
const [pageBusy, setPageBusy] = React.useState(false);
|
|
848
720
|
const [provisionBusy, setProvisionBusy] = React.useState(false);
|
|
@@ -1384,56 +1256,6 @@ export function FeishuSettingsTab({ rpcCall }) {
|
|
|
1384
1256
|
}
|
|
1385
1257
|
}, [invoke, loadStatus, mergeSnapshot, setBotBusy, setBotError, workspaceFence]);
|
|
1386
1258
|
|
|
1387
|
-
const authorizeGroupMessages = React.useCallback(async (connection) => {
|
|
1388
|
-
const { botId } = connection;
|
|
1389
|
-
if (model.provisioning) {
|
|
1390
|
-
throw new Error("请先完成当前飞书授权操作,再开通群消息权限。");
|
|
1391
|
-
}
|
|
1392
|
-
setRemoveTargetId(null);
|
|
1393
|
-
setBotError(botId, null);
|
|
1394
|
-
setTestNoticesByBot((current) => {
|
|
1395
|
-
const next = { ...current };
|
|
1396
|
-
delete next[botId];
|
|
1397
|
-
return next;
|
|
1398
|
-
});
|
|
1399
|
-
await startProvisioning({
|
|
1400
|
-
operation: GROUP_MESSAGE_PERMISSION_OPERATION,
|
|
1401
|
-
bot: connection,
|
|
1402
|
-
});
|
|
1403
|
-
}, [model.provisioning, setBotError, startProvisioning]);
|
|
1404
|
-
|
|
1405
|
-
const saveGroupResponseMode = React.useCallback(async (connection, groupResponseMode) => {
|
|
1406
|
-
const { botId } = connection;
|
|
1407
|
-
if (groupResponseMode === "all" && connection.groupMessagePermissionGranted !== true) {
|
|
1408
|
-
await authorizeGroupMessages(connection);
|
|
1409
|
-
return;
|
|
1410
|
-
}
|
|
1411
|
-
const snapshotVersion = workspaceFence.beginMutation();
|
|
1412
|
-
setBotBusy(botId, "group-response-mode");
|
|
1413
|
-
setBotError(botId, null);
|
|
1414
|
-
try {
|
|
1415
|
-
const snapshot = normalizeBotsSnapshot(await invoke(
|
|
1416
|
-
FEISHU_ENDPOINTS.setGroupResponseMode,
|
|
1417
|
-
{ botId, groupResponseMode },
|
|
1418
|
-
));
|
|
1419
|
-
if (mountedRef.current && workspaceFence.canCommitMutation(snapshotVersion)) {
|
|
1420
|
-
mergeSnapshot(snapshot);
|
|
1421
|
-
}
|
|
1422
|
-
} finally {
|
|
1423
|
-
const shouldRefresh = workspaceFence.endMutation();
|
|
1424
|
-
if (shouldRefresh && mountedRef.current) void loadStatus({ silent: true });
|
|
1425
|
-
if (mountedRef.current) setBotBusy(botId, null);
|
|
1426
|
-
}
|
|
1427
|
-
}, [
|
|
1428
|
-
invoke,
|
|
1429
|
-
authorizeGroupMessages,
|
|
1430
|
-
loadStatus,
|
|
1431
|
-
mergeSnapshot,
|
|
1432
|
-
setBotBusy,
|
|
1433
|
-
setBotError,
|
|
1434
|
-
workspaceFence,
|
|
1435
|
-
]);
|
|
1436
|
-
|
|
1437
1259
|
const requestRemove = React.useCallback((connection) => {
|
|
1438
1260
|
setRemoveTargetId(connection.botId);
|
|
1439
1261
|
}, []);
|
|
@@ -1541,7 +1363,9 @@ export function FeishuSettingsTab({ rpcCall }) {
|
|
|
1541
1363
|
else removeButtonRefs.current.delete(botId);
|
|
1542
1364
|
}, []);
|
|
1543
1365
|
|
|
1544
|
-
return h(
|
|
1366
|
+
return h(ModelCatalogContext.Provider, {
|
|
1367
|
+
value: model.modelCatalog ?? EMPTY_MODEL_CATALOG,
|
|
1368
|
+
}, h(AgentPresetCatalogContext.Provider, {
|
|
1545
1369
|
value: model.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG,
|
|
1546
1370
|
}, h("section", { className: "bxf-page dim-channelPage", "aria-label": "飞书机器人设置" },
|
|
1547
1371
|
h(Heading, {
|
|
@@ -1589,17 +1413,15 @@ export function FeishuSettingsTab({ rpcCall }) {
|
|
|
1589
1413
|
onReconnect: (bot) => void reconnectOneBot(bot),
|
|
1590
1414
|
onRepairCallback: repairCallback,
|
|
1591
1415
|
onWorkspaceSave: saveWorkspace,
|
|
1416
|
+
onModelSave: (connection, selectedModel) => saveBotSetting(
|
|
1417
|
+
connection, "model", FEISHU_ENDPOINTS.setModel, { model: selectedModel },
|
|
1418
|
+
),
|
|
1592
1419
|
onAgentPresetSave: (connection, agentPreset) => saveBotSetting(
|
|
1593
1420
|
connection, "preset", FEISHU_ENDPOINTS.setAgentPreset, { agentPreset },
|
|
1594
1421
|
),
|
|
1595
1422
|
onContextEnhancementSave: (connection, config) => saveBotSetting(
|
|
1596
1423
|
connection, "context-enhancement", FEISHU_ENDPOINTS.setContextEnhancement, { config },
|
|
1597
1424
|
),
|
|
1598
|
-
onGroupResponseModeSave: saveGroupResponseMode,
|
|
1599
|
-
onGroupTopicReplySave: (connection, groupTopicReply) => saveBotSetting(
|
|
1600
|
-
connection, "group-topic-reply", FEISHU_ENDPOINTS.setGroupTopicReply, { groupTopicReply },
|
|
1601
|
-
),
|
|
1602
|
-
onGroupMessagePermissionAuthorize: authorizeGroupMessages,
|
|
1603
1425
|
onRequestRemove: requestRemove,
|
|
1604
1426
|
onConfirmRemove: (bot) => void confirmRemove(bot),
|
|
1605
1427
|
onCancelRemove: cancelRemove,
|
|
@@ -1608,5 +1430,5 @@ export function FeishuSettingsTab({ rpcCall }) {
|
|
|
1608
1430
|
})
|
|
1609
1431
|
: null,
|
|
1610
1432
|
),
|
|
1611
|
-
));
|
|
1433
|
+
)));
|
|
1612
1434
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { normalizeAgentPresetCatalog, normalizeAgentPresetId, SET_AGENT_PRESET_ENDPOINT } from '../../agent-preset.js';
|
|
2
|
+
import { normalizeModelCatalog, normalizeModelSelection, SET_MODEL_ENDPOINT } from '../../model-setting.js';
|
|
2
3
|
import { normalizeLastMessageError } from '../../last-message-error.js';
|
|
3
4
|
import { normalizeAccessPolicy } from '../../../../src/channels/shared/access-policy.mjs';
|
|
4
5
|
import { normalizeContextEnhancementConfig } from '../../../../src/channels/shared/context-enhancement.mjs';
|
|
@@ -14,6 +15,7 @@ export const QQ_ENDPOINTS = Object.freeze({
|
|
|
14
15
|
reconnectBot: 'bot.reconnect',
|
|
15
16
|
deleteBot: 'bot.delete',
|
|
16
17
|
setWorkspace: 'bot.workspace.set',
|
|
18
|
+
setModel: SET_MODEL_ENDPOINT,
|
|
17
19
|
setAgentPreset: SET_AGENT_PRESET_ENDPOINT,
|
|
18
20
|
setContextEnhancement: 'bot.context-enhancement.set',
|
|
19
21
|
setAccessPolicy: 'bot.access-policy.set',
|
|
@@ -90,6 +92,7 @@ function normalizeBot(value) {
|
|
|
90
92
|
connected,
|
|
91
93
|
state: connected ? 'connected' : state,
|
|
92
94
|
workspace: text(value.workspace, '', 4_096),
|
|
95
|
+
model: normalizeModelSelection(value.model),
|
|
93
96
|
agentPreset: normalizeAgentPresetId(value.agentPreset),
|
|
94
97
|
contextEnhancement: normalizeContextEnhancementConfig(value.contextEnhancement),
|
|
95
98
|
...(Object.hasOwn(value, 'accessPolicy')
|
|
@@ -132,6 +135,7 @@ export function normalizeSnapshot(value) {
|
|
|
132
135
|
totals: { configured: bots.length, connected: bots.filter((bot) => bot.connected).length },
|
|
133
136
|
provisioning: source.provisioning ? normalizeProvisioning(source.provisioning) : null,
|
|
134
137
|
agentPresetCatalog: normalizeAgentPresetCatalog(source.agentPresetCatalog),
|
|
138
|
+
modelCatalog: normalizeModelCatalog(source.modelCatalog),
|
|
135
139
|
...(testMessage ? { testMessage } : {}),
|
|
136
140
|
};
|
|
137
141
|
}
|
|
@@ -10,6 +10,11 @@ import {
|
|
|
10
10
|
AgentPresetEditor,
|
|
11
11
|
EMPTY_AGENT_PRESET_CATALOG,
|
|
12
12
|
} from '../../agent-preset.js';
|
|
13
|
+
import {
|
|
14
|
+
EMPTY_MODEL_CATALOG,
|
|
15
|
+
ModelCatalogContext,
|
|
16
|
+
ModelEditor,
|
|
17
|
+
} from '../../model-setting.js';
|
|
13
18
|
import { useWorkspaceSnapshotFence } from '../../workspace-snapshot-fence.js';
|
|
14
19
|
import {
|
|
15
20
|
BotSettingsButton,
|
|
@@ -167,6 +172,7 @@ export function AccountCard({
|
|
|
167
172
|
removing,
|
|
168
173
|
onReconnect,
|
|
169
174
|
onWorkspaceSave,
|
|
175
|
+
onModelSave,
|
|
170
176
|
onAgentPresetSave,
|
|
171
177
|
onContextEnhancementSave,
|
|
172
178
|
onRequestRemove,
|
|
@@ -204,6 +210,11 @@ export function AccountCard({
|
|
|
204
210
|
disabled: Boolean(busy),
|
|
205
211
|
onSave: onWorkspaceSave,
|
|
206
212
|
}),
|
|
213
|
+
h(ModelEditor, {
|
|
214
|
+
model: account.model,
|
|
215
|
+
disabled: Boolean(busy),
|
|
216
|
+
onSave: onModelSave,
|
|
217
|
+
}),
|
|
207
218
|
h(AgentPresetEditor, {
|
|
208
219
|
agentPreset: account.agentPreset,
|
|
209
220
|
disabled: Boolean(busy),
|
|
@@ -238,6 +249,7 @@ export function QqSettingsTab({ rpcCall }) {
|
|
|
238
249
|
const [model, setModel] = React.useState({
|
|
239
250
|
phase: 'loading', bots: [], totals: { configured: 0, connected: 0 }, error: null,
|
|
240
251
|
agentPresetCatalog: EMPTY_AGENT_PRESET_CATALOG,
|
|
252
|
+
modelCatalog: EMPTY_MODEL_CATALOG,
|
|
241
253
|
});
|
|
242
254
|
const [provision, setProvision] = React.useState(null);
|
|
243
255
|
const [busy, setBusy] = React.useState(false);
|
|
@@ -278,6 +290,7 @@ export function QqSettingsTab({ rpcCall }) {
|
|
|
278
290
|
setModel({
|
|
279
291
|
phase: 'ready', bots: snapshot.bots, totals: snapshot.totals, error: null,
|
|
280
292
|
agentPresetCatalog: snapshot.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG,
|
|
293
|
+
modelCatalog: snapshot.modelCatalog ?? EMPTY_MODEL_CATALOG,
|
|
281
294
|
});
|
|
282
295
|
if (restore && snapshot.provisioning) setProvision({
|
|
283
296
|
...snapshot.provisioning,
|
|
@@ -345,6 +358,7 @@ export function QqSettingsTab({ rpcCall }) {
|
|
|
345
358
|
setModel({
|
|
346
359
|
phase: 'ready', bots: snapshot.bots, totals: snapshot.totals, error: null,
|
|
347
360
|
agentPresetCatalog: snapshot.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG,
|
|
361
|
+
modelCatalog: snapshot.modelCatalog ?? EMPTY_MODEL_CATALOG,
|
|
348
362
|
});
|
|
349
363
|
}
|
|
350
364
|
setCredentialOpen(false);
|
|
@@ -408,6 +422,7 @@ export function QqSettingsTab({ rpcCall }) {
|
|
|
408
422
|
setModel({
|
|
409
423
|
phase: 'ready', bots: snapshot.bots, totals: snapshot.totals, error: null,
|
|
410
424
|
agentPresetCatalog: snapshot.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG,
|
|
425
|
+
modelCatalog: snapshot.modelCatalog ?? EMPTY_MODEL_CATALOG,
|
|
411
426
|
});
|
|
412
427
|
}
|
|
413
428
|
return snapshot;
|
|
@@ -478,6 +493,12 @@ export function QqSettingsTab({ rpcCall }) {
|
|
|
478
493
|
QQ_ENDPOINTS.setWorkspace,
|
|
479
494
|
{ botId: account.botId, workspace },
|
|
480
495
|
),
|
|
496
|
+
onModelSave: (selectedModel) => botAction(
|
|
497
|
+
account,
|
|
498
|
+
'model',
|
|
499
|
+
QQ_ENDPOINTS.setModel,
|
|
500
|
+
{ botId: account.botId, model: selectedModel },
|
|
501
|
+
),
|
|
481
502
|
onAgentPresetSave: (agentPreset) => botAction(
|
|
482
503
|
account,
|
|
483
504
|
'preset',
|
|
@@ -513,7 +534,9 @@ export function QqSettingsTab({ rpcCall }) {
|
|
|
513
534
|
})
|
|
514
535
|
: null;
|
|
515
536
|
|
|
516
|
-
return h(
|
|
537
|
+
return h(ModelCatalogContext.Provider, {
|
|
538
|
+
value: model.modelCatalog ?? EMPTY_MODEL_CATALOG,
|
|
539
|
+
}, h(AgentPresetCatalogContext.Provider, {
|
|
517
540
|
value: model.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG,
|
|
518
541
|
}, h('section', { className: 'ddt-page dqq-page dim-channelPage', 'aria-label': 'QQ 设置' },
|
|
519
542
|
h(Heading, {
|
|
@@ -533,5 +556,5 @@ export function QqSettingsTab({ rpcCall }) {
|
|
|
533
556
|
provisionView,
|
|
534
557
|
model.bots.length === 0 && !provision && !credentialOpen
|
|
535
558
|
? h(EmptyView, { busy, onStart: () => void startProvisioning() }) : null,
|
|
536
|
-
botList)));
|
|
559
|
+
botList))));
|
|
537
560
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { normalizeAgentPresetCatalog, normalizeAgentPresetId, SET_AGENT_PRESET_ENDPOINT } from '../../agent-preset.js';
|
|
2
|
+
import { normalizeModelCatalog, normalizeModelSelection, SET_MODEL_ENDPOINT } from '../../model-setting.js';
|
|
2
3
|
import { normalizeLastMessageError } from '../../last-message-error.js';
|
|
3
4
|
import { normalizeAccessPolicy } from '../../../../src/channels/shared/access-policy.mjs';
|
|
4
5
|
import { normalizeContextEnhancementConfig } from '../../../../src/channels/shared/context-enhancement.mjs';
|
|
@@ -30,6 +31,7 @@ export const TOKEN_BOT_ENDPOINTS = Object.freeze({
|
|
|
30
31
|
reconnectBot: 'bot.reconnect',
|
|
31
32
|
deleteBot: 'bot.delete',
|
|
32
33
|
setWorkspace: 'bot.workspace.set',
|
|
34
|
+
setModel: SET_MODEL_ENDPOINT,
|
|
33
35
|
setAgentPreset: SET_AGENT_PRESET_ENDPOINT,
|
|
34
36
|
setContextEnhancement: 'bot.context-enhancement.set',
|
|
35
37
|
setAccessPolicy: 'bot.access-policy.set',
|
|
@@ -60,6 +62,7 @@ export function createTokenChannelApi(channel, connectionSummary, {
|
|
|
60
62
|
connected,
|
|
61
63
|
state: connected ? 'connected' : state,
|
|
62
64
|
workspace: text(value.workspace, '', 4_096),
|
|
65
|
+
model: normalizeModelSelection(value.model),
|
|
63
66
|
agentPreset: normalizeAgentPresetId(value.agentPreset),
|
|
64
67
|
contextEnhancement: normalizeContextEnhancementConfig(value.contextEnhancement),
|
|
65
68
|
...(Object.hasOwn(value, 'accessPolicy')
|
|
@@ -97,6 +100,7 @@ export function createTokenChannelApi(channel, connectionSummary, {
|
|
|
97
100
|
bots,
|
|
98
101
|
totals: { configured: bots.length, connected: bots.filter((bot) => bot.connected).length },
|
|
99
102
|
agentPresetCatalog: normalizeAgentPresetCatalog(source.agentPresetCatalog),
|
|
103
|
+
modelCatalog: normalizeModelCatalog(source.modelCatalog),
|
|
100
104
|
};
|
|
101
105
|
};
|
|
102
106
|
|
|
@@ -10,6 +10,11 @@ import {
|
|
|
10
10
|
AgentPresetEditor,
|
|
11
11
|
EMPTY_AGENT_PRESET_CATALOG,
|
|
12
12
|
} from '../../agent-preset.js';
|
|
13
|
+
import {
|
|
14
|
+
EMPTY_MODEL_CATALOG,
|
|
15
|
+
ModelCatalogContext,
|
|
16
|
+
ModelEditor,
|
|
17
|
+
} from '../../model-setting.js';
|
|
13
18
|
import { useWorkspaceSnapshotFence } from '../../workspace-snapshot-fence.js';
|
|
14
19
|
import {
|
|
15
20
|
BotSettingsButton,
|
|
@@ -75,7 +80,7 @@ export function createTokenChannelSettings(definition) {
|
|
|
75
80
|
accountSettingsEndpoint = null,
|
|
76
81
|
} = definition;
|
|
77
82
|
|
|
78
|
-
function AccountCard({ account, busy, testNotice, removing, onReconnect, onWorkspaceSave, onAgentPresetSave, onContextEnhancementSave, onAccountSettingsSave, onRequestRemove, onConfirmRemove, onCancelRemove }) {
|
|
83
|
+
function AccountCard({ account, busy, testNotice, removing, onReconnect, onWorkspaceSave, onModelSave, onAgentPresetSave, onContextEnhancementSave, onAccountSettingsSave, onRequestRemove, onConfirmRemove, onCancelRemove }) {
|
|
79
84
|
const state = busy === 'reconnect' ? 'connecting' : account.state;
|
|
80
85
|
const tone = account.connected ? 'success' : state === 'error' ? 'error' : 'warning';
|
|
81
86
|
const stateLabel = account.connected ? '运行正常' : state === 'connecting' ? '正在连接' : '连接未就绪';
|
|
@@ -110,6 +115,11 @@ export function createTokenChannelSettings(definition) {
|
|
|
110
115
|
disabled: Boolean(busy),
|
|
111
116
|
onSave: onWorkspaceSave,
|
|
112
117
|
}),
|
|
118
|
+
h(ModelEditor, {
|
|
119
|
+
model: account.model,
|
|
120
|
+
disabled: Boolean(busy),
|
|
121
|
+
onSave: onModelSave,
|
|
122
|
+
}),
|
|
113
123
|
h(AgentPresetEditor, {
|
|
114
124
|
agentPreset: account.agentPreset,
|
|
115
125
|
disabled: Boolean(busy),
|
|
@@ -161,6 +171,7 @@ export function createTokenChannelSettings(definition) {
|
|
|
161
171
|
const [model, setModel] = React.useState({
|
|
162
172
|
phase: 'loading', bots: [], totals: { configured: 0, connected: 0 }, error: null,
|
|
163
173
|
agentPresetCatalog: EMPTY_AGENT_PRESET_CATALOG,
|
|
174
|
+
modelCatalog: EMPTY_MODEL_CATALOG,
|
|
164
175
|
});
|
|
165
176
|
const [credentialOpen, setCredentialOpen] = React.useState(false);
|
|
166
177
|
const [credentialError, setCredentialError] = React.useState(null);
|
|
@@ -198,6 +209,7 @@ export function createTokenChannelSettings(definition) {
|
|
|
198
209
|
setModel({
|
|
199
210
|
phase: 'ready', bots: snapshot.bots, totals: snapshot.totals, error: null,
|
|
200
211
|
agentPresetCatalog: snapshot.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG,
|
|
212
|
+
modelCatalog: snapshot.modelCatalog ?? EMPTY_MODEL_CATALOG,
|
|
201
213
|
});
|
|
202
214
|
} catch (error) {
|
|
203
215
|
if (error?.name !== 'AbortError' && mounted.current && !signal?.aborted
|
|
@@ -244,6 +256,7 @@ export function createTokenChannelSettings(definition) {
|
|
|
244
256
|
setModel({
|
|
245
257
|
phase: 'ready', bots: snapshot.bots, totals: snapshot.totals, error: null,
|
|
246
258
|
agentPresetCatalog: snapshot.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG,
|
|
259
|
+
modelCatalog: snapshot.modelCatalog ?? EMPTY_MODEL_CATALOG,
|
|
247
260
|
});
|
|
248
261
|
}
|
|
249
262
|
setCredentialOpen(false);
|
|
@@ -266,6 +279,7 @@ export function createTokenChannelSettings(definition) {
|
|
|
266
279
|
setModel({
|
|
267
280
|
phase: 'ready', bots: snapshot.bots, totals: snapshot.totals, error: null,
|
|
268
281
|
agentPresetCatalog: snapshot.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG,
|
|
282
|
+
modelCatalog: snapshot.modelCatalog ?? EMPTY_MODEL_CATALOG,
|
|
269
283
|
});
|
|
270
284
|
}
|
|
271
285
|
if (mounted.current && operation === 'reconnect') {
|
|
@@ -318,6 +332,12 @@ export function createTokenChannelSettings(definition) {
|
|
|
318
332
|
endpoints.setWorkspace,
|
|
319
333
|
{ botId: account.botId, workspace },
|
|
320
334
|
),
|
|
335
|
+
onModelSave: (selectedModel) => botAction(
|
|
336
|
+
account,
|
|
337
|
+
'model',
|
|
338
|
+
endpoints.setModel,
|
|
339
|
+
{ botId: account.botId, model: selectedModel },
|
|
340
|
+
),
|
|
321
341
|
onAgentPresetSave: (agentPreset) => botAction(
|
|
322
342
|
account,
|
|
323
343
|
'preset',
|
|
@@ -350,7 +370,9 @@ export function createTokenChannelSettings(definition) {
|
|
|
350
370
|
})))))
|
|
351
371
|
: null;
|
|
352
372
|
|
|
353
|
-
return h(
|
|
373
|
+
return h(ModelCatalogContext.Provider, {
|
|
374
|
+
value: model.modelCatalog ?? EMPTY_MODEL_CATALOG,
|
|
375
|
+
}, h(AgentPresetCatalogContext.Provider, {
|
|
354
376
|
value: model.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG,
|
|
355
377
|
}, h('section', {
|
|
356
378
|
className: `ddt-page ${pageClass} dim-channelPage`,
|
|
@@ -418,7 +440,7 @@ export function createTokenChannelSettings(definition) {
|
|
|
418
440
|
'aria-hidden': 'true',
|
|
419
441
|
}, h(LogoGlyph, { size: 64 }))))
|
|
420
442
|
: null,
|
|
421
|
-
botList)));
|
|
443
|
+
botList))));
|
|
422
444
|
}
|
|
423
445
|
|
|
424
446
|
return { SettingsTab, AccountCard };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { normalizeAgentPresetCatalog, normalizeAgentPresetId, SET_AGENT_PRESET_ENDPOINT } from '../../agent-preset.js';
|
|
2
|
+
import { normalizeModelCatalog, normalizeModelSelection, SET_MODEL_ENDPOINT } from '../../model-setting.js';
|
|
2
3
|
import { normalizeLastMessageError } from '../../last-message-error.js';
|
|
3
4
|
import { normalizeAccessPolicy } from '../../../../src/channels/shared/access-policy.mjs';
|
|
4
5
|
import { normalizeContextEnhancementConfig } from '../../../../src/channels/shared/context-enhancement.mjs';
|
|
@@ -14,6 +15,7 @@ export const WECOM_ENDPOINTS = Object.freeze({
|
|
|
14
15
|
reconnectBot: 'bot.reconnect',
|
|
15
16
|
deleteBot: 'bot.delete',
|
|
16
17
|
setWorkspace: 'bot.workspace.set',
|
|
18
|
+
setModel: SET_MODEL_ENDPOINT,
|
|
17
19
|
setAgentPreset: SET_AGENT_PRESET_ENDPOINT,
|
|
18
20
|
setContextEnhancement: 'bot.context-enhancement.set',
|
|
19
21
|
setAccessPolicy: 'bot.access-policy.set',
|
|
@@ -99,6 +101,7 @@ function normalizeBot(value) {
|
|
|
99
101
|
connected,
|
|
100
102
|
state: connected ? 'connected' : state,
|
|
101
103
|
workspace: text(value.workspace, '', 4_096),
|
|
104
|
+
model: normalizeModelSelection(value.model),
|
|
102
105
|
agentPreset: normalizeAgentPresetId(value.agentPreset),
|
|
103
106
|
contextEnhancement: normalizeContextEnhancementConfig(value.contextEnhancement),
|
|
104
107
|
...(Object.hasOwn(value, 'accessPolicy')
|
|
@@ -131,6 +134,7 @@ export function normalizeSnapshot(value) {
|
|
|
131
134
|
provisioning: source.provisioning ? normalizeProvisioning(source.provisioning) : null,
|
|
132
135
|
testMessage: normalizeTestMessage(source.testMessage),
|
|
133
136
|
agentPresetCatalog: normalizeAgentPresetCatalog(source.agentPresetCatalog),
|
|
137
|
+
modelCatalog: normalizeModelCatalog(source.modelCatalog),
|
|
134
138
|
};
|
|
135
139
|
}
|
|
136
140
|
|