@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
package/lib/client.js
CHANGED
|
@@ -566,12 +566,12 @@ __export(index_exports, {
|
|
|
566
566
|
name: () => name
|
|
567
567
|
});
|
|
568
568
|
module.exports = __toCommonJS(index_exports);
|
|
569
|
-
var
|
|
569
|
+
var React26 = __toESM(require("react"), 1);
|
|
570
570
|
|
|
571
571
|
// package.json
|
|
572
572
|
var package_default = {
|
|
573
573
|
name: "@xmanrui/dsh-im",
|
|
574
|
-
version: "4.
|
|
574
|
+
version: "4.11.0",
|
|
575
575
|
description: "\u628A\u4E5D\u79CD IM \u673A\u5668\u4EBA\u548C\u516C\u7F51 AI Office \u63A5\u5165\u672C\u673A DeepSeek Harness\u3002 Connect nine IM channels and a public AI Office to a local DeepSeek Harness.",
|
|
576
576
|
keywords: [
|
|
577
577
|
"deepseek-harness",
|
|
@@ -660,11 +660,12 @@ var package_default = {
|
|
|
660
660
|
platform: "web"
|
|
661
661
|
},
|
|
662
662
|
compatibility: {
|
|
663
|
-
dsh: "0.1.2-alpha.4 || 0.1.2-alpha.5 || 0.1.2-rc.1",
|
|
663
|
+
dsh: "0.1.2-alpha.4 || 0.1.2-alpha.5 || 0.1.2-rc.1 || 0.1.3-alpha.1",
|
|
664
664
|
dshReleases: {
|
|
665
665
|
"0.1.2-alpha.4": "compatible",
|
|
666
666
|
"0.1.2-alpha.5": "compatible",
|
|
667
|
-
"0.1.2-rc.1": "compatible"
|
|
667
|
+
"0.1.2-rc.1": "compatible",
|
|
668
|
+
"0.1.3-alpha.1": "compatible"
|
|
668
669
|
},
|
|
669
670
|
profiles: [
|
|
670
671
|
"web"
|
|
@@ -1204,6 +1205,13 @@ var EN = Object.freeze({
|
|
|
1204
1205
|
"\u8BF7\u9009\u62E9 Agent Preset\u3002": "Choose an Agent Preset.",
|
|
1205
1206
|
"Agent Preset \u65E0\u6548\u3002": "The Agent Preset is invalid.",
|
|
1206
1207
|
"Agent Preset \u4E0D\u5B58\u5728\u6216\u4E0D\u53EF\u7528\u3002": "The Agent Preset does not exist or is unavailable.",
|
|
1208
|
+
"\u6A21\u578B": "Model",
|
|
1209
|
+
"\u67E5\u770B\u6A21\u578B\u8BBE\u7F6E\u8BF4\u660E": "View model setting help",
|
|
1210
|
+
"\u8DDF\u968F\u9ED8\u8BA4\u6A21\u578B": "Follow the default model",
|
|
1211
|
+
"\u6A21\u578B\u4FEE\u6539\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5\u3002": "Could not update the model. Try again.",
|
|
1212
|
+
"\u6A21\u578B\u65E0\u6548\u3002": "The model is invalid.",
|
|
1213
|
+
"\u6A21\u578B\u4E0D\u5B58\u5728\u6216\u4E0D\u53EF\u7528\u3002": "The model does not exist or is unavailable.",
|
|
1214
|
+
"\u5F53\u524D\u6A21\u578B\u5DF2\u4E0D\u53EF\u7528\uFF0C\u8BF7\u9009\u62E9\u5176\u4ED6\u6A21\u578B\u6216\u8DDF\u968F\u9ED8\u8BA4\u6A21\u578B\u3002": "The current model is unavailable. Choose another model or follow the default.",
|
|
1207
1215
|
"\u5C1A\u672A\u68C0\u67E5": "Not checked yet",
|
|
1208
1216
|
"\u521A\u521A": "Just now",
|
|
1209
1217
|
"\u68C0\u67E5\u8FDE\u63A5": "Check connection",
|
|
@@ -1619,6 +1627,10 @@ var EN = Object.freeze({
|
|
|
1619
1627
|
"\u586B\u5199\u63A5\u6536\u6D88\u606F\u7684\u7528\u6237 ID": "Enter the recipient user ID",
|
|
1620
1628
|
"\u79C1\u804A": "Direct message",
|
|
1621
1629
|
"\u7FA4\u804A": "Group",
|
|
1630
|
+
"\u7FA4\u804A\u8BBE\u7F6E": "Group settings",
|
|
1631
|
+
"\u5F53\u524D\u673A\u5668\u4EBA": "Current bot",
|
|
1632
|
+
"\u98DE\u4E66\u7FA4\u804A\u8BBE\u7F6E\u6682\u4E0D\u53EF\u7528\u3002": "Feishu group settings are currently unavailable.",
|
|
1633
|
+
"\u98DE\u4E66\u670D\u52A1\u6CA1\u6709\u8FD4\u56DE\u5F53\u524D\u673A\u5668\u4EBA\u7684\u8BBE\u7F6E": "Feishu did not return settings for this bot",
|
|
1622
1634
|
"\u7FA4 Chat ID": "Group Chat ID",
|
|
1623
1635
|
"\u7528\u6237 ID": "User ID",
|
|
1624
1636
|
"\u586B\u5199\u9489\u9489\u7528\u6237 ID": "Enter the DingTalk user ID",
|
|
@@ -1681,6 +1693,15 @@ var EN = Object.freeze({
|
|
|
1681
1693
|
"\uFF1F\u4F7F\u7528\u8FD9\u4E2A targetId \u7684\u5916\u90E8\u8C03\u7528\u5C06\u8FD4\u56DE unknown-target\u3002": "? External calls using this targetId will return unknown-target.",
|
|
1682
1694
|
"\u6B63\u5728\u5220\u9664\u2026": "Deleting\u2026",
|
|
1683
1695
|
"\u786E\u8BA4\u5220\u9664": "Delete target",
|
|
1696
|
+
"\u4F1A\u8BDD\u53CC\u5411\u540C\u6B65": "Two-way Session sync",
|
|
1697
|
+
"\u81EA\u52A8\u8DDF\u968F\u8BE5\u79C1\u804A\u7684\u5F53\u524D\u4F1A\u8BDD": "Automatically follow this direct message\u2019s current Session",
|
|
1698
|
+
"\u7B49\u5F85\u8BE5\u79C1\u804A\u5EFA\u7ACB\u65B0\u4F1A\u8BDD": "Waiting for this direct message to establish a new Session",
|
|
1699
|
+
"\u5173\u95ED\u65F6\u4E0D\u53D1\u9001 DSH \u4F1A\u8BDD\u6D88\u606F": "DSH Session messages are not sent while disabled",
|
|
1700
|
+
"\u4EC5\u652F\u6301\u5DF2\u7ECF\u804A\u8FC7\u3001\u5DF2\u5EFA\u7ACB\u5F53\u524D\u4F1A\u8BDD\u4E14\u4F7F\u7528\u5F53\u524D Host Harness \u7684\u79C1\u804A\u76EE\u6807": "Only a known direct message with a current Session on this Host Harness is supported",
|
|
1701
|
+
"\u4F1A\u8BDD\u540C\u6B65\u4EC5\u652F\u6301\u5DF2\u7ECF\u804A\u8FC7\u3001\u5DF2\u5EFA\u7ACB\u5F53\u524D\u4F1A\u8BDD\u4E14\u4F7F\u7528\u5F53\u524D Host Harness \u7684\u79C1\u804A\u76EE\u6807\u3002": "Session sync requires a known direct message with a current Session on this Host Harness.",
|
|
1702
|
+
"\u4F1A\u8BDD\u540C\u6B65\u8BBE\u7F6E\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002": "Could not update Session sync. Try again later.",
|
|
1703
|
+
"\u4FEE\u6539\u63A5\u6536\u4F4D\u7F6E\u4F1A\u5173\u95ED\u4F1A\u8BDD\u53CC\u5411\u540C\u6B65\u3002": "Changing the destination disables two-way Session sync.",
|
|
1704
|
+
" \u4F1A\u8BDD\u540C\u6B65\u8BBE\u7F6E\u4E5F\u4F1A\u4E00\u5E76\u5220\u9664\u3002": " Its Session sync setting will also be deleted.",
|
|
1684
1705
|
"\u6295\u9012\u76EE\u6807\u8BBE\u7F6E\u6682\u4E0D\u53EF\u7528\u3002": "Delivery target settings are unavailable.",
|
|
1685
1706
|
"\u65E0\u6CD5\u8BFB\u53D6\u6295\u9012\u76EE\u6807\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002": "Could not load delivery targets. Try again later.",
|
|
1686
1707
|
"\u2190 \u8FD4\u56DE\u673A\u5668\u4EBA\u5217\u8868": "\u2190 Back to bots",
|
|
@@ -1988,6 +2009,186 @@ function AgentPresetEditor({ agentPreset = "", disabled = false, onSave }) {
|
|
|
1988
2009
|
);
|
|
1989
2010
|
}
|
|
1990
2011
|
|
|
2012
|
+
// plugin-src/client/model-setting.js
|
|
2013
|
+
var React4 = __toESM(require("react"), 1);
|
|
2014
|
+
|
|
2015
|
+
// src/channels/shared/model-setting.mjs
|
|
2016
|
+
var MAX_PROVIDER_ID_LENGTH = 256;
|
|
2017
|
+
var MAX_MODEL_ID_LENGTH = 1024;
|
|
2018
|
+
var MAX_LABEL_LENGTH = 256;
|
|
2019
|
+
var UNSAFE_DISPLAY_TEXT = /[\p{Cc}\p{Cf}\p{Zl}\p{Zp}]+/gu;
|
|
2020
|
+
var UNSAFE_ID_TEXT = /[\p{Cc}\p{Cf}\p{Zl}\p{Zp}]/u;
|
|
2021
|
+
function cleanId(value, maxLength) {
|
|
2022
|
+
if (typeof value !== "string") return "";
|
|
2023
|
+
const id5 = value.trim();
|
|
2024
|
+
if (!id5 || id5.length > maxLength || UNSAFE_ID_TEXT.test(id5)) return "";
|
|
2025
|
+
return id5;
|
|
2026
|
+
}
|
|
2027
|
+
function cleanLabel(value, fallback) {
|
|
2028
|
+
if (typeof value !== "string") return fallback;
|
|
2029
|
+
const label = value.replace(UNSAFE_DISPLAY_TEXT, " ").replace(/\s+/gu, " ").trim();
|
|
2030
|
+
return label ? label.slice(0, MAX_LABEL_LENGTH) : fallback;
|
|
2031
|
+
}
|
|
2032
|
+
var EMPTY_MODEL_CATALOG = Object.freeze({
|
|
2033
|
+
groups: Object.freeze([]),
|
|
2034
|
+
failures: Object.freeze([])
|
|
2035
|
+
});
|
|
2036
|
+
function normalizeModelSelection(value) {
|
|
2037
|
+
if (value == null) return null;
|
|
2038
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
2039
|
+
const provider = cleanId(value.provider, MAX_PROVIDER_ID_LENGTH);
|
|
2040
|
+
const model = cleanId(value.model, MAX_MODEL_ID_LENGTH);
|
|
2041
|
+
return provider && model ? { provider, model } : null;
|
|
2042
|
+
}
|
|
2043
|
+
function modelSelectionId(value) {
|
|
2044
|
+
const selection = normalizeModelSelection(value);
|
|
2045
|
+
return selection ? `${selection.provider}/${selection.model}` : "";
|
|
2046
|
+
}
|
|
2047
|
+
function normalizeModelCatalog(value) {
|
|
2048
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
2049
|
+
return { groups: [], failures: [] };
|
|
2050
|
+
}
|
|
2051
|
+
const groups = [];
|
|
2052
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2053
|
+
for (const candidate of Array.isArray(value.groups) ? value.groups : []) {
|
|
2054
|
+
if (!candidate || typeof candidate !== "object" || Array.isArray(candidate)) continue;
|
|
2055
|
+
const provider = cleanId(candidate.id, MAX_PROVIDER_ID_LENGTH);
|
|
2056
|
+
if (!provider) continue;
|
|
2057
|
+
const models = [];
|
|
2058
|
+
for (const entry of Array.isArray(candidate.models) ? candidate.models : []) {
|
|
2059
|
+
if (!entry || typeof entry !== "object" || Array.isArray(entry)) continue;
|
|
2060
|
+
const model = cleanId(entry.id, MAX_MODEL_ID_LENGTH);
|
|
2061
|
+
if (!model) continue;
|
|
2062
|
+
const key = `${provider}\0${model}`;
|
|
2063
|
+
if (seen.has(key)) continue;
|
|
2064
|
+
seen.add(key);
|
|
2065
|
+
models.push({
|
|
2066
|
+
id: model,
|
|
2067
|
+
name: cleanLabel(entry.name, model)
|
|
2068
|
+
});
|
|
2069
|
+
}
|
|
2070
|
+
if (models.length > 0) {
|
|
2071
|
+
groups.push({
|
|
2072
|
+
id: provider,
|
|
2073
|
+
name: cleanLabel(candidate.name, provider),
|
|
2074
|
+
models
|
|
2075
|
+
});
|
|
2076
|
+
}
|
|
2077
|
+
}
|
|
2078
|
+
const failures = [];
|
|
2079
|
+
for (const candidate of Array.isArray(value.failures) ? value.failures : []) {
|
|
2080
|
+
if (!candidate || typeof candidate !== "object" || Array.isArray(candidate)) continue;
|
|
2081
|
+
const id5 = cleanId(candidate.id, MAX_PROVIDER_ID_LENGTH);
|
|
2082
|
+
if (!id5) continue;
|
|
2083
|
+
failures.push({ id: id5, name: cleanLabel(candidate.name, id5) });
|
|
2084
|
+
}
|
|
2085
|
+
return { groups, failures };
|
|
2086
|
+
}
|
|
2087
|
+
|
|
2088
|
+
// plugin-src/client/model-setting.js
|
|
2089
|
+
var SET_MODEL_ENDPOINT = "bot.model.set";
|
|
2090
|
+
var ModelCatalogContext = React4.createContext(EMPTY_MODEL_CATALOG);
|
|
2091
|
+
function optionValue(selection) {
|
|
2092
|
+
return JSON.stringify([selection.provider, selection.model]);
|
|
2093
|
+
}
|
|
2094
|
+
function ModelEditor({ model = null, disabled = false, onSave }) {
|
|
2095
|
+
const catalog = normalizeModelCatalog(
|
|
2096
|
+
React4.useContext(ModelCatalogContext) ?? EMPTY_MODEL_CATALOG
|
|
2097
|
+
);
|
|
2098
|
+
const helpId = React4.useId();
|
|
2099
|
+
const current = normalizeModelSelection(model);
|
|
2100
|
+
const [saving, setSaving] = React4.useState(false);
|
|
2101
|
+
const [error, setError] = React4.useState(null);
|
|
2102
|
+
const currentValue = current ? optionValue(current) : "";
|
|
2103
|
+
const currentAvailable = !current || catalog.groups.some(
|
|
2104
|
+
(group) => group.id === current.provider && group.models.some((entry) => entry.id === current.model)
|
|
2105
|
+
);
|
|
2106
|
+
const selections = /* @__PURE__ */ new Map();
|
|
2107
|
+
for (const group of catalog.groups) {
|
|
2108
|
+
for (const entry of group.models) {
|
|
2109
|
+
const selection = { provider: group.id, model: entry.id };
|
|
2110
|
+
selections.set(optionValue(selection), selection);
|
|
2111
|
+
}
|
|
2112
|
+
}
|
|
2113
|
+
if (current && !currentAvailable) selections.set(currentValue, current);
|
|
2114
|
+
const change = async (event) => {
|
|
2115
|
+
const nextValue = event.target.value;
|
|
2116
|
+
if (nextValue === currentValue || saving || disabled) return;
|
|
2117
|
+
const next = nextValue ? selections.get(nextValue) : null;
|
|
2118
|
+
if (nextValue && !next) return;
|
|
2119
|
+
setSaving(true);
|
|
2120
|
+
setError(null);
|
|
2121
|
+
try {
|
|
2122
|
+
await onSave?.(next);
|
|
2123
|
+
} catch (cause) {
|
|
2124
|
+
setError(cause?.message ?? "\u6A21\u578B\u4FEE\u6539\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5\u3002");
|
|
2125
|
+
} finally {
|
|
2126
|
+
setSaving(false);
|
|
2127
|
+
}
|
|
2128
|
+
};
|
|
2129
|
+
return h2(
|
|
2130
|
+
"div",
|
|
2131
|
+
{ className: "dim-preset dim-modelSetting" },
|
|
2132
|
+
h2(
|
|
2133
|
+
"div",
|
|
2134
|
+
{ className: "dim-presetHeader" },
|
|
2135
|
+
h2(
|
|
2136
|
+
"span",
|
|
2137
|
+
{ className: "dim-presetTitle" },
|
|
2138
|
+
h2("span", null, "\u6A21\u578B"),
|
|
2139
|
+
h2(
|
|
2140
|
+
"span",
|
|
2141
|
+
{ className: "dim-presetHelp" },
|
|
2142
|
+
h2("button", {
|
|
2143
|
+
type: "button",
|
|
2144
|
+
className: "dim-presetHelpButton",
|
|
2145
|
+
"aria-label": "\u67E5\u770B\u6A21\u578B\u8BBE\u7F6E\u8BF4\u660E",
|
|
2146
|
+
"aria-describedby": helpId
|
|
2147
|
+
}, h2("span", { "aria-hidden": "true" }, "?")),
|
|
2148
|
+
h2("span", {
|
|
2149
|
+
id: helpId,
|
|
2150
|
+
className: "dim-presetTooltip",
|
|
2151
|
+
role: "tooltip"
|
|
2152
|
+
}, "\u53EA\u5F71\u54CD\u65B0\u5EFA\u4F1A\u8BDD\uFF1B\u82E5\u5F53\u524D\u804A\u5929\u5DF2\u6709\u4F1A\u8BDD\uFF0C\u5148\u53D1\u9001 /new\uFF0C\u518D\u53D1\u9001\u666E\u901A\u6D88\u606F\u751F\u6548\u3002")
|
|
2153
|
+
)
|
|
2154
|
+
),
|
|
2155
|
+
saving ? h2("span", { className: "dim-presetStatus" }, "\u4FDD\u5B58\u4E2D\u2026") : null
|
|
2156
|
+
),
|
|
2157
|
+
h2(
|
|
2158
|
+
"select",
|
|
2159
|
+
{
|
|
2160
|
+
className: "dim-presetSelect dim-modelSelect",
|
|
2161
|
+
value: currentValue,
|
|
2162
|
+
disabled: disabled || saving,
|
|
2163
|
+
"aria-label": "\u6A21\u578B",
|
|
2164
|
+
onChange: (event) => {
|
|
2165
|
+
void change(event);
|
|
2166
|
+
}
|
|
2167
|
+
},
|
|
2168
|
+
h2("option", { value: "" }, "\u8DDF\u968F\u9ED8\u8BA4\u6A21\u578B"),
|
|
2169
|
+
...catalog.groups.map((group) => h2(
|
|
2170
|
+
"optgroup",
|
|
2171
|
+
{ key: group.id, label: group.name },
|
|
2172
|
+
...group.models.map((entry) => {
|
|
2173
|
+
const selection = { provider: group.id, model: entry.id };
|
|
2174
|
+
const id5 = modelSelectionId(selection);
|
|
2175
|
+
return h2(
|
|
2176
|
+
"option",
|
|
2177
|
+
{ key: id5, value: optionValue(selection) },
|
|
2178
|
+
entry.name && entry.name !== entry.id ? `${entry.name}\uFF08${id5}\uFF09` : id5
|
|
2179
|
+
);
|
|
2180
|
+
})
|
|
2181
|
+
)),
|
|
2182
|
+
current && !currentAvailable ? h2("option", { value: currentValue }, [modelSelectionId(current), "\uFF08\u5DF2\u4E0D\u53EF\u7528\uFF09"]) : null
|
|
2183
|
+
),
|
|
2184
|
+
error || !currentAvailable ? h2(
|
|
2185
|
+
"p",
|
|
2186
|
+
{ className: "dim-presetError", role: error ? "alert" : "status" },
|
|
2187
|
+
error ?? "\u5F53\u524D\u6A21\u578B\u5DF2\u4E0D\u53EF\u7528\uFF0C\u8BF7\u9009\u62E9\u5176\u4ED6\u6A21\u578B\u6216\u8DDF\u968F\u9ED8\u8BA4\u6A21\u578B\u3002"
|
|
2188
|
+
) : null
|
|
2189
|
+
);
|
|
2190
|
+
}
|
|
2191
|
+
|
|
1991
2192
|
// plugin-src/client/last-message-error.js
|
|
1992
2193
|
function text(value, maxLength) {
|
|
1993
2194
|
if (typeof value !== "string") return null;
|
|
@@ -2241,6 +2442,7 @@ var DINGTALK_ENDPOINTS = Object.freeze({
|
|
|
2241
2442
|
reconnectBot: "bot.reconnect",
|
|
2242
2443
|
deleteBot: "bot.delete",
|
|
2243
2444
|
setWorkspace: "bot.workspace.set",
|
|
2445
|
+
setModel: SET_MODEL_ENDPOINT,
|
|
2244
2446
|
setAgentPreset: SET_AGENT_PRESET_ENDPOINT,
|
|
2245
2447
|
setContextEnhancement: "bot.context-enhancement.set",
|
|
2246
2448
|
setAccessPolicy: "bot.access-policy.set"
|
|
@@ -2386,6 +2588,7 @@ function normalizeBot(value) {
|
|
|
2386
2588
|
connected,
|
|
2387
2589
|
configured: value.configured !== false,
|
|
2388
2590
|
workspace: optionalString(value.workspace, 4096) ?? "",
|
|
2591
|
+
model: normalizeModelSelection(value.model),
|
|
2389
2592
|
agentPreset: normalizeAgentPresetId(value.agentPreset),
|
|
2390
2593
|
contextEnhancement: normalizeContextEnhancementConfig(value.contextEnhancement),
|
|
2391
2594
|
...Object.hasOwn(value, "accessPolicy") ? { accessPolicy: normalizeAccessPolicy(value.accessPolicy) } : {},
|
|
@@ -2429,7 +2632,8 @@ function normalizeSnapshot(value) {
|
|
|
2429
2632
|
},
|
|
2430
2633
|
provisioning: source.provisioning ? normalizeProvisioning(source.provisioning) : null,
|
|
2431
2634
|
testMessage: normalizeTestMessage(source.testMessage),
|
|
2432
|
-
agentPresetCatalog: normalizeAgentPresetCatalog(source.agentPresetCatalog)
|
|
2635
|
+
agentPresetCatalog: normalizeAgentPresetCatalog(source.agentPresetCatalog),
|
|
2636
|
+
modelCatalog: normalizeModelCatalog(source.modelCatalog)
|
|
2433
2637
|
};
|
|
2434
2638
|
}
|
|
2435
2639
|
function connectionTestFeedback(result) {
|
|
@@ -2452,10 +2656,10 @@ function formatRemaining(milliseconds) {
|
|
|
2452
2656
|
}
|
|
2453
2657
|
|
|
2454
2658
|
// plugin-src/client/channels/dingtalk/index.js
|
|
2455
|
-
var
|
|
2659
|
+
var React11 = __toESM(require("react"), 1);
|
|
2456
2660
|
|
|
2457
2661
|
// plugin-src/client/credential-binding.js
|
|
2458
|
-
var
|
|
2662
|
+
var React5 = __toESM(require("react"), 1);
|
|
2459
2663
|
function ActionIcon({ children }) {
|
|
2460
2664
|
return h2("svg", {
|
|
2461
2665
|
className: "dim-actionIcon",
|
|
@@ -2515,9 +2719,9 @@ function CredentialBindingPanel({
|
|
|
2515
2719
|
onSubmit,
|
|
2516
2720
|
onCancel
|
|
2517
2721
|
}) {
|
|
2518
|
-
const [identity, setIdentity] =
|
|
2519
|
-
const [secret, setSecret] =
|
|
2520
|
-
const headingId =
|
|
2722
|
+
const [identity, setIdentity] = React5.useState("");
|
|
2723
|
+
const [secret, setSecret] = React5.useState("");
|
|
2724
|
+
const headingId = React5.useId();
|
|
2521
2725
|
const hasIdentity = Boolean(identityLabel);
|
|
2522
2726
|
const submit = (event) => {
|
|
2523
2727
|
event.preventDefault();
|
|
@@ -2596,10 +2800,10 @@ function CredentialBindingPanel({
|
|
|
2596
2800
|
}
|
|
2597
2801
|
|
|
2598
2802
|
// plugin-src/client/workspace-editor.js
|
|
2599
|
-
var
|
|
2803
|
+
var React7 = __toESM(require("react"), 1);
|
|
2600
2804
|
|
|
2601
2805
|
// plugin-src/client/workspace-directory-picker.js
|
|
2602
|
-
var
|
|
2806
|
+
var React6 = __toESM(require("react"), 1);
|
|
2603
2807
|
var import_react_dom = require("react-dom");
|
|
2604
2808
|
function pickerErrorCode(error) {
|
|
2605
2809
|
return error?.rpcError?.code ?? error?.code;
|
|
@@ -2620,7 +2824,7 @@ function pickerErrorMessage(error) {
|
|
|
2620
2824
|
return error?.rpcError?.message ?? error?.message ?? "\u65E0\u6CD5\u8BFB\u53D6\u76EE\u5F55\uFF0C\u8BF7\u91CD\u8BD5\u3002";
|
|
2621
2825
|
}
|
|
2622
2826
|
function FolderIcon() {
|
|
2623
|
-
return
|
|
2827
|
+
return React6.createElement(
|
|
2624
2828
|
"svg",
|
|
2625
2829
|
{
|
|
2626
2830
|
viewBox: "0 0 24 24",
|
|
@@ -2631,11 +2835,11 @@ function FolderIcon() {
|
|
|
2631
2835
|
strokeLinejoin: "round",
|
|
2632
2836
|
"aria-hidden": "true"
|
|
2633
2837
|
},
|
|
2634
|
-
|
|
2838
|
+
React6.createElement("path", { d: "M3.5 7.25A2.25 2.25 0 0 1 5.75 5h4.1l1.8 2h6.6a2.25 2.25 0 0 1 2.25 2.25v7A2.75 2.75 0 0 1 17.75 19h-12A2.25 2.25 0 0 1 3.5 16.75v-9.5Z" })
|
|
2635
2839
|
);
|
|
2636
2840
|
}
|
|
2637
2841
|
function ChevronIcon() {
|
|
2638
|
-
return
|
|
2842
|
+
return React6.createElement("svg", {
|
|
2639
2843
|
viewBox: "0 0 20 20",
|
|
2640
2844
|
fill: "none",
|
|
2641
2845
|
stroke: "currentColor",
|
|
@@ -2643,7 +2847,7 @@ function ChevronIcon() {
|
|
|
2643
2847
|
strokeLinecap: "round",
|
|
2644
2848
|
strokeLinejoin: "round",
|
|
2645
2849
|
"aria-hidden": "true"
|
|
2646
|
-
},
|
|
2850
|
+
}, React6.createElement("path", { d: "m7.5 4.5 5 5.5-5 5.5" }));
|
|
2647
2851
|
}
|
|
2648
2852
|
function displayCrumbs(listing) {
|
|
2649
2853
|
const homeIndex = listing.crumbs.findIndex((crumb) => crumb.path === listing.home);
|
|
@@ -2659,28 +2863,28 @@ function WorkspaceDirectoryPicker({
|
|
|
2659
2863
|
onPicked,
|
|
2660
2864
|
onCancel
|
|
2661
2865
|
}) {
|
|
2662
|
-
const [listing, setListing] =
|
|
2663
|
-
const [loading, setLoading] =
|
|
2664
|
-
const [error, setError] =
|
|
2665
|
-
const [pathDraft, setPathDraft] =
|
|
2666
|
-
const [showHidden, setShowHidden] =
|
|
2667
|
-
const [retryKey, setRetryKey] =
|
|
2668
|
-
const requestRef =
|
|
2669
|
-
const controllerRef =
|
|
2670
|
-
const dialogRef =
|
|
2671
|
-
const bodyRef =
|
|
2672
|
-
const titleId =
|
|
2673
|
-
const noticeId =
|
|
2674
|
-
const pathInputId =
|
|
2675
|
-
const errorId =
|
|
2676
|
-
const initialPathRef =
|
|
2677
|
-
const onPickedRef =
|
|
2678
|
-
const onCancelRef =
|
|
2679
|
-
const busyRef =
|
|
2866
|
+
const [listing, setListing] = React6.useState(null);
|
|
2867
|
+
const [loading, setLoading] = React6.useState(false);
|
|
2868
|
+
const [error, setError] = React6.useState(null);
|
|
2869
|
+
const [pathDraft, setPathDraft] = React6.useState(startPath ?? "");
|
|
2870
|
+
const [showHidden, setShowHidden] = React6.useState(false);
|
|
2871
|
+
const [retryKey, setRetryKey] = React6.useState(0);
|
|
2872
|
+
const requestRef = React6.useRef(0);
|
|
2873
|
+
const controllerRef = React6.useRef(null);
|
|
2874
|
+
const dialogRef = React6.useRef(null);
|
|
2875
|
+
const bodyRef = React6.useRef(null);
|
|
2876
|
+
const titleId = React6.useId();
|
|
2877
|
+
const noticeId = React6.useId();
|
|
2878
|
+
const pathInputId = React6.useId();
|
|
2879
|
+
const errorId = React6.useId();
|
|
2880
|
+
const initialPathRef = React6.useRef(startPath);
|
|
2881
|
+
const onPickedRef = React6.useRef(onPicked);
|
|
2882
|
+
const onCancelRef = React6.useRef(onCancel);
|
|
2883
|
+
const busyRef = React6.useRef(busy);
|
|
2680
2884
|
onPickedRef.current = onPicked;
|
|
2681
2885
|
onCancelRef.current = onCancel;
|
|
2682
2886
|
busyRef.current = busy;
|
|
2683
|
-
const loadDirectory =
|
|
2887
|
+
const loadDirectory = React6.useCallback(async (path, { reportError = true } = {}) => {
|
|
2684
2888
|
const request = requestRef.current + 1;
|
|
2685
2889
|
requestRef.current = request;
|
|
2686
2890
|
controllerRef.current?.abort();
|
|
@@ -2704,7 +2908,7 @@ function WorkspaceDirectoryPicker({
|
|
|
2704
2908
|
if (request === requestRef.current) setLoading(false);
|
|
2705
2909
|
}
|
|
2706
2910
|
}, [picker]);
|
|
2707
|
-
|
|
2911
|
+
React6.useEffect(() => {
|
|
2708
2912
|
if (!open) return void 0;
|
|
2709
2913
|
let active = true;
|
|
2710
2914
|
setListing(null);
|
|
@@ -2784,10 +2988,10 @@ function WorkspaceDirectoryPicker({
|
|
|
2784
2988
|
"nav",
|
|
2785
2989
|
{ className: "dim-directoryCrumbs", "aria-label": "\u5F53\u524D\u76EE\u5F55" },
|
|
2786
2990
|
crumbs.map((crumb, index) => h2(
|
|
2787
|
-
|
|
2991
|
+
React6.Fragment,
|
|
2788
2992
|
{ key: crumb.path },
|
|
2789
2993
|
index > 0 ? h2("span", { className: "dim-directoryCrumbSeparator", "aria-hidden": "true" }, "\u203A") : null,
|
|
2790
|
-
|
|
2994
|
+
React6.createElement("button", {
|
|
2791
2995
|
type: "button",
|
|
2792
2996
|
title: crumb.path,
|
|
2793
2997
|
disabled: loading || busy,
|
|
@@ -2850,7 +3054,7 @@ function WorkspaceDirectoryPicker({
|
|
|
2850
3054
|
) : listing ? entries.length > 0 ? h2("ul", { className: "dim-directoryList" }, entries.map((entry) => h2(
|
|
2851
3055
|
"li",
|
|
2852
3056
|
{ key: entry.path },
|
|
2853
|
-
|
|
3057
|
+
React6.createElement(
|
|
2854
3058
|
"button",
|
|
2855
3059
|
{
|
|
2856
3060
|
type: "button",
|
|
@@ -2859,7 +3063,7 @@ function WorkspaceDirectoryPicker({
|
|
|
2859
3063
|
onClick: () => void loadDirectory(entry.path)
|
|
2860
3064
|
},
|
|
2861
3065
|
h2("span", { className: "dim-directoryFolder" }, h2(FolderIcon)),
|
|
2862
|
-
|
|
3066
|
+
React6.createElement("span", { className: "dim-directoryName" }, entry.name),
|
|
2863
3067
|
h2("span", { className: "dim-directoryChevron" }, h2(ChevronIcon))
|
|
2864
3068
|
)
|
|
2865
3069
|
))) : h2(
|
|
@@ -2912,21 +3116,21 @@ function WorkspaceDirectoryPicker({
|
|
|
2912
3116
|
}
|
|
2913
3117
|
|
|
2914
3118
|
// plugin-src/client/workspace-editor.js
|
|
2915
|
-
var WorkspaceDirectoryPickerContext =
|
|
3119
|
+
var WorkspaceDirectoryPickerContext = React7.createContext(null);
|
|
2916
3120
|
function WorkspaceEditor({ workspace, directoryPicker, disabled = false, onSave }) {
|
|
2917
|
-
const sharedDirectoryPicker =
|
|
3121
|
+
const sharedDirectoryPicker = React7.useContext(WorkspaceDirectoryPickerContext);
|
|
2918
3122
|
const activeDirectoryPicker = directoryPicker ?? sharedDirectoryPicker;
|
|
2919
|
-
const [open, setOpen] =
|
|
2920
|
-
const [saving, setSaving] =
|
|
2921
|
-
const [error, setError] =
|
|
2922
|
-
const editButtonRef =
|
|
2923
|
-
const savingRef =
|
|
2924
|
-
const close =
|
|
3123
|
+
const [open, setOpen] = React7.useState(false);
|
|
3124
|
+
const [saving, setSaving] = React7.useState(false);
|
|
3125
|
+
const [error, setError] = React7.useState(null);
|
|
3126
|
+
const editButtonRef = React7.useRef(null);
|
|
3127
|
+
const savingRef = React7.useRef(false);
|
|
3128
|
+
const close = React7.useCallback(() => {
|
|
2925
3129
|
setOpen(false);
|
|
2926
3130
|
setError(null);
|
|
2927
3131
|
queueMicrotask(() => editButtonRef.current?.focus?.());
|
|
2928
3132
|
}, []);
|
|
2929
|
-
const pick =
|
|
3133
|
+
const pick = React7.useCallback(async (value) => {
|
|
2930
3134
|
if (!value || savingRef.current || disabled) return;
|
|
2931
3135
|
if (value === workspace) {
|
|
2932
3136
|
close();
|
|
@@ -2963,7 +3167,7 @@ function WorkspaceEditor({ workspace, directoryPicker, disabled = false, onSave
|
|
|
2963
3167
|
disabled: disabled || !activeDirectoryPicker
|
|
2964
3168
|
}, "\u9009\u62E9\u76EE\u5F55")
|
|
2965
3169
|
),
|
|
2966
|
-
workspace ?
|
|
3170
|
+
workspace ? React7.createElement("code", {
|
|
2967
3171
|
className: "dim-workspacePath",
|
|
2968
3172
|
title: workspace
|
|
2969
3173
|
}, workspace) : h2("code", { className: "dim-workspacePath" }, "\u672A\u8BBE\u7F6E"),
|
|
@@ -2980,7 +3184,7 @@ function WorkspaceEditor({ workspace, directoryPicker, disabled = false, onSave
|
|
|
2980
3184
|
}
|
|
2981
3185
|
|
|
2982
3186
|
// plugin-src/client/context-enhancement.js
|
|
2983
|
-
var
|
|
3187
|
+
var React8 = __toESM(require("react"), 1);
|
|
2984
3188
|
var import_react_dom2 = require("react-dom");
|
|
2985
3189
|
var FIELD_LABELS = Object.freeze({
|
|
2986
3190
|
channel: "\u6E20\u9053",
|
|
@@ -3225,7 +3429,7 @@ function ContextEnhancementScopeEditor({
|
|
|
3225
3429
|
);
|
|
3226
3430
|
}
|
|
3227
3431
|
function ContextEnhancementDialog({ config, groupSupported, disabled, onSave, onClose, returnFocusRef, id: id5 }) {
|
|
3228
|
-
const [draft, setDraft] =
|
|
3432
|
+
const [draft, setDraft] = React8.useState(() => {
|
|
3229
3433
|
const normalized = normalizeContextEnhancementConfig(config);
|
|
3230
3434
|
return {
|
|
3231
3435
|
...normalized,
|
|
@@ -3234,23 +3438,23 @@ function ContextEnhancementDialog({ config, groupSupported, disabled, onSave, on
|
|
|
3234
3438
|
} : {}
|
|
3235
3439
|
};
|
|
3236
3440
|
});
|
|
3237
|
-
const [saving, setSaving] =
|
|
3238
|
-
const [error, setError] =
|
|
3239
|
-
const [activeScope, setActiveScope] =
|
|
3240
|
-
const savingRef =
|
|
3241
|
-
const dialogRef =
|
|
3242
|
-
const mountedRef =
|
|
3243
|
-
const groupTabRef =
|
|
3244
|
-
const directTabRef =
|
|
3245
|
-
const titleId =
|
|
3246
|
-
const descriptionId =
|
|
3247
|
-
const scopeIdPrefix =
|
|
3441
|
+
const [saving, setSaving] = React8.useState(false);
|
|
3442
|
+
const [error, setError] = React8.useState(null);
|
|
3443
|
+
const [activeScope, setActiveScope] = React8.useState("direct");
|
|
3444
|
+
const savingRef = React8.useRef(false);
|
|
3445
|
+
const dialogRef = React8.useRef(null);
|
|
3446
|
+
const mountedRef = React8.useRef(true);
|
|
3447
|
+
const groupTabRef = React8.useRef(null);
|
|
3448
|
+
const directTabRef = React8.useRef(null);
|
|
3449
|
+
const titleId = React8.useId();
|
|
3450
|
+
const descriptionId = React8.useId();
|
|
3451
|
+
const scopeIdPrefix = React8.useId();
|
|
3248
3452
|
const groupGuidanceExample = localizeText(CONTEXT_GROUP_GUIDANCE_EXAMPLE);
|
|
3249
3453
|
const directGuidanceExample = localizeText(CONTEXT_DIRECT_GUIDANCE_EXAMPLE);
|
|
3250
3454
|
const busy = disabled || saving;
|
|
3251
3455
|
const scopeKinds = ["direct", "group"];
|
|
3252
3456
|
const tabRefs = { group: groupTabRef, direct: directTabRef };
|
|
3253
|
-
|
|
3457
|
+
React8.useEffect(() => {
|
|
3254
3458
|
mountedRef.current = true;
|
|
3255
3459
|
dialogRef.current?.focus?.();
|
|
3256
3460
|
const keepFocus = (event) => {
|
|
@@ -3441,17 +3645,17 @@ function ContextEnhancementDialog({ config, groupSupported, disabled, onSave, on
|
|
|
3441
3645
|
return globalThis.document?.body ? (0, import_react_dom2.createPortal)(content, document.body) : content;
|
|
3442
3646
|
}
|
|
3443
3647
|
function ContextEnhancementEditor({ config, groupSupported = true, disabled = false, onSave }) {
|
|
3444
|
-
const [open, setOpen] =
|
|
3445
|
-
const entryRef =
|
|
3446
|
-
const dialogId =
|
|
3447
|
-
const statusId =
|
|
3648
|
+
const [open, setOpen] = React8.useState(false);
|
|
3649
|
+
const entryRef = React8.useRef(null);
|
|
3650
|
+
const dialogId = React8.useId();
|
|
3651
|
+
const statusId = React8.useId();
|
|
3448
3652
|
const saved = normalizeContextEnhancementConfig(config);
|
|
3449
3653
|
const label = contextEnhancementLabel(groupSupported ? saved : {
|
|
3450
3654
|
...saved,
|
|
3451
3655
|
group: { ...saved.group, enabled: false }
|
|
3452
3656
|
});
|
|
3453
3657
|
return h2(
|
|
3454
|
-
|
|
3658
|
+
React8.Fragment,
|
|
3455
3659
|
null,
|
|
3456
3660
|
h2(
|
|
3457
3661
|
"button",
|
|
@@ -3485,10 +3689,10 @@ function ContextEnhancementEditor({ config, groupSupported = true, disabled = fa
|
|
|
3485
3689
|
}
|
|
3486
3690
|
|
|
3487
3691
|
// plugin-src/client/workspace-snapshot-fence.js
|
|
3488
|
-
var
|
|
3692
|
+
var React9 = __toESM(require("react"), 1);
|
|
3489
3693
|
function useWorkspaceSnapshotFence() {
|
|
3490
|
-
const state =
|
|
3491
|
-
return
|
|
3694
|
+
const state = React9.useRef({ version: 0, pendingMutations: 0 });
|
|
3695
|
+
return React9.useMemo(() => Object.freeze({
|
|
3492
3696
|
beginStatus() {
|
|
3493
3697
|
return state.current.pendingMutations === 0 ? state.current.version : null;
|
|
3494
3698
|
},
|
|
@@ -3511,8 +3715,8 @@ function useWorkspaceSnapshotFence() {
|
|
|
3511
3715
|
}
|
|
3512
3716
|
|
|
3513
3717
|
// plugin-src/client/channel-card-meta.js
|
|
3514
|
-
var
|
|
3515
|
-
var BotSettingsContext =
|
|
3718
|
+
var React10 = __toESM(require("react"), 1);
|
|
3719
|
+
var BotSettingsContext = React10.createContext(Object.freeze({
|
|
3516
3720
|
openBotSettings() {
|
|
3517
3721
|
}
|
|
3518
3722
|
}));
|
|
@@ -3534,9 +3738,16 @@ function SettingsGlyph() {
|
|
|
3534
3738
|
h2("path", { d: "M19.4 15a1.7 1.7 0 0 0 .34 1.88l.06.06-2.83 2.83-.06-.06a1.7 1.7 0 0 0-1.88-.34 1.7 1.7 0 0 0-1.03 1.55V21h-4v-.08A1.7 1.7 0 0 0 8.97 19.4a1.7 1.7 0 0 0-1.88.34l-.06.06-2.83-2.83.06-.06A1.7 1.7 0 0 0 4.6 15a1.7 1.7 0 0 0-1.52-1.03H3v-4h.08A1.7 1.7 0 0 0 4.6 8.97a1.7 1.7 0 0 0-.34-1.88l-.06-.06L7.03 4.2l.06.06a1.7 1.7 0 0 0 1.88.34A1.7 1.7 0 0 0 10 3.08V3h4v.08a1.7 1.7 0 0 0 1.03 1.52 1.7 1.7 0 0 0 1.88-.34l.06-.06 2.83 2.83-.06.06a1.7 1.7 0 0 0-.34 1.88A1.7 1.7 0 0 0 20.92 10H21v4h-.08A1.7 1.7 0 0 0 19.4 15Z" })
|
|
3535
3739
|
);
|
|
3536
3740
|
}
|
|
3537
|
-
function BotSettingsButton({
|
|
3538
|
-
|
|
3539
|
-
|
|
3741
|
+
function BotSettingsButton({
|
|
3742
|
+
channel: channel4,
|
|
3743
|
+
botId,
|
|
3744
|
+
botName,
|
|
3745
|
+
connected,
|
|
3746
|
+
accessPolicy,
|
|
3747
|
+
channelSettings
|
|
3748
|
+
}) {
|
|
3749
|
+
const { openBotSettings } = React10.useContext(BotSettingsContext);
|
|
3750
|
+
const tooltipId = React10.useId();
|
|
3540
3751
|
return h2(
|
|
3541
3752
|
"span",
|
|
3542
3753
|
{ className: "dim-botSettingsAction" },
|
|
@@ -3547,6 +3758,7 @@ function BotSettingsButton({ channel: channel4, botId, botName, connected, acces
|
|
|
3547
3758
|
"aria-label": "\u66F4\u591A\u673A\u5668\u4EBA\u8BBE\u7F6E",
|
|
3548
3759
|
"aria-describedby": tooltipId,
|
|
3549
3760
|
onClick: () => openBotSettings?.({
|
|
3761
|
+
...channelSettings && typeof channelSettings === "object" ? channelSettings : {},
|
|
3550
3762
|
channel: channel4,
|
|
3551
3763
|
botId,
|
|
3552
3764
|
botName,
|
|
@@ -3575,7 +3787,7 @@ function messageErrorTime(value) {
|
|
|
3575
3787
|
}
|
|
3576
3788
|
}
|
|
3577
3789
|
function ChannelListHeading({ className = "", id: id5, title, connectionLabel }) {
|
|
3578
|
-
const helpId =
|
|
3790
|
+
const helpId = React10.useId();
|
|
3579
3791
|
return h2(
|
|
3580
3792
|
"div",
|
|
3581
3793
|
{ className: `${className} dim-listHeading`.trim() },
|
|
@@ -3656,7 +3868,7 @@ function LastMessageErrorSummary({ className = "", error }) {
|
|
|
3656
3868
|
h2("span", null, "\u53C2\u8003\u53F7"),
|
|
3657
3869
|
` ${error.referenceId}`,
|
|
3658
3870
|
occurredAt ? h2(
|
|
3659
|
-
|
|
3871
|
+
React10.Fragment,
|
|
3660
3872
|
null,
|
|
3661
3873
|
" \xB7 ",
|
|
3662
3874
|
h2("time", { dateTime: new Date(error.at).toISOString() }, occurredAt)
|
|
@@ -3819,7 +4031,7 @@ function DingtalkIcon({ size = 28 }) {
|
|
|
3819
4031
|
d: "M37.05 22.783c-6.758-5.216-14.378-12.128-22.73-19.538-.655-.585-1.242-.354-1.536.42-1.88 4.973-.058 9.386 2.889 11.932s7.368 4.912 10.058 6.155c.105.049.013.203-.093.163-4.953-2.182-8.397-3.765-13.07-7.368-.497-.388-1.01-.242-1.07.521-.384 4.748 2.657 8.483 6.058 9.745 2.1.781 4.398 1.212 6.53 1.474.109.015.084.178-.027.178-2.747.01-6.058-.654-8.935-1.751-.606-.233-.818.25-.722.633.491 2.008 2.974 5.076 6.926 5.73a12 12 0 0 0 2.228.115c.164 0 .208.089.154.217q-2.685 4.6-2.803 4.797c-.091.152-.036.275.156.275h3.543c.164 0 .264.106.18.246l-4.958 8.196c-.191.328.035.565.395.301s15.212-11.133 15.636-11.448c.195-.142.148-.327-.124-.327h-3.18c-.206 0-.252-.14-.111-.28.14-.141 3.602-3.594 4.837-4.888 1.283-1.35 1.938-3.825-.231-5.498"
|
|
3820
4032
|
}));
|
|
3821
4033
|
}
|
|
3822
|
-
var Button =
|
|
4034
|
+
var Button = React11.forwardRef(function Button2({ children, kind = "secondary", className = "", ...props }, ref) {
|
|
3823
4035
|
return h2("button", {
|
|
3824
4036
|
...props,
|
|
3825
4037
|
ref,
|
|
@@ -3915,13 +4127,13 @@ function EmptyView({ busy, onStart }) {
|
|
|
3915
4127
|
);
|
|
3916
4128
|
}
|
|
3917
4129
|
function QrPanel({ provision, now, busy, onRefresh, onCancel }) {
|
|
3918
|
-
const [imageFailed, setImageFailed] =
|
|
4130
|
+
const [imageFailed, setImageFailed] = React11.useState(false);
|
|
3919
4131
|
const source = safeQrSource(provision.qrCodeDataUrl);
|
|
3920
4132
|
const remaining = Math.max(0, provision.expiresAt - now);
|
|
3921
4133
|
const expired = remaining === 0 || provision.status === "expired";
|
|
3922
4134
|
const duration = Math.max(1, provision.durationMs ?? 10 * 6e4);
|
|
3923
4135
|
const progress = Math.round(Math.min(1, remaining / duration) * 100);
|
|
3924
|
-
|
|
4136
|
+
React11.useEffect(() => setImageFailed(false), [source]);
|
|
3925
4137
|
return h2(
|
|
3926
4138
|
"div",
|
|
3927
4139
|
{ className: "ddt-card dim-surfaceCard" },
|
|
@@ -4013,7 +4225,7 @@ function ConnectionErrorDiagnostic({ error }) {
|
|
|
4013
4225
|
{ className: "ddt-errorCode" },
|
|
4014
4226
|
h2("span", null, "\u9519\u8BEF\u7801"),
|
|
4015
4227
|
`: ${error.code}`,
|
|
4016
|
-
error.referenceId ? h2(
|
|
4228
|
+
error.referenceId ? h2(React11.Fragment, null, " \xB7 ", h2("span", null, "\u53C2\u8003\u53F7"), `: ${error.referenceId}`) : null
|
|
4017
4229
|
)
|
|
4018
4230
|
);
|
|
4019
4231
|
}
|
|
@@ -4036,7 +4248,7 @@ function ProvisionError({ provision, busy, onRetry, onClose }) {
|
|
|
4036
4248
|
"div",
|
|
4037
4249
|
{ className: "ddt-actions dim-viewActions" },
|
|
4038
4250
|
connectionFailed ? h2(Button, { kind: "primary", onClick: onClose, disabled: busy }, "\u67E5\u770B\u5DF2\u4FDD\u5B58\u7684\u673A\u5668\u4EBA") : h2(
|
|
4039
|
-
|
|
4251
|
+
React11.Fragment,
|
|
4040
4252
|
null,
|
|
4041
4253
|
h2(Button, { kind: "primary", onClick: onRetry, disabled: busy }, "\u91CD\u65B0\u751F\u6210\u4E8C\u7EF4\u7801"),
|
|
4042
4254
|
h2(Button, { onClick: onClose, disabled: busy }, "\u5173\u95ED")
|
|
@@ -4058,8 +4270,8 @@ function checkedTime(value) {
|
|
|
4058
4270
|
}
|
|
4059
4271
|
}
|
|
4060
4272
|
function RemoveConfirmation({ account, busy, onConfirm, onCancel }) {
|
|
4061
|
-
const cancelRef =
|
|
4062
|
-
|
|
4273
|
+
const cancelRef = React11.useRef(null);
|
|
4274
|
+
React11.useEffect(() => cancelRef.current?.focus(), []);
|
|
4063
4275
|
return h2(
|
|
4064
4276
|
"div",
|
|
4065
4277
|
{
|
|
@@ -4091,6 +4303,7 @@ function AccountCard({
|
|
|
4091
4303
|
removing,
|
|
4092
4304
|
onReconnect,
|
|
4093
4305
|
onWorkspaceSave,
|
|
4306
|
+
onModelSave,
|
|
4094
4307
|
onAgentPresetSave,
|
|
4095
4308
|
onContextEnhancementSave,
|
|
4096
4309
|
onRequestRemove,
|
|
@@ -4146,6 +4359,11 @@ function AccountCard({
|
|
|
4146
4359
|
disabled: Boolean(busy),
|
|
4147
4360
|
onSave: onWorkspaceSave
|
|
4148
4361
|
}),
|
|
4362
|
+
h2(ModelEditor, {
|
|
4363
|
+
model: account.model,
|
|
4364
|
+
disabled: Boolean(busy),
|
|
4365
|
+
onSave: onModelSave
|
|
4366
|
+
}),
|
|
4149
4367
|
h2(AgentPresetEditor, {
|
|
4150
4368
|
agentPreset: account.agentPreset,
|
|
4151
4369
|
disabled: Boolean(busy),
|
|
@@ -4216,6 +4434,7 @@ function AccountList(props) {
|
|
|
4216
4434
|
removing: props.removeTarget === account.botId,
|
|
4217
4435
|
onReconnect: () => props.onReconnect(account),
|
|
4218
4436
|
onWorkspaceSave: (workspace) => props.onWorkspaceSave(account, workspace),
|
|
4437
|
+
onModelSave: (model) => props.onModelSave(account, model),
|
|
4219
4438
|
onAgentPresetSave: (agentPreset) => props.onAgentPresetSave(account, agentPreset),
|
|
4220
4439
|
onContextEnhancementSave: (config) => props.onContextEnhancementSave(account, config),
|
|
4221
4440
|
onRequestRemove: () => props.onRequestRemove(account),
|
|
@@ -4227,30 +4446,31 @@ function AccountList(props) {
|
|
|
4227
4446
|
}
|
|
4228
4447
|
var EMPTY_TOTALS = Object.freeze({ configured: 0, connected: 0 });
|
|
4229
4448
|
function DingtalkSettingsTab({ rpcCall }) {
|
|
4230
|
-
const [model, setModel] =
|
|
4449
|
+
const [model, setModel] = React11.useState({
|
|
4231
4450
|
phase: "loading",
|
|
4232
4451
|
bots: [],
|
|
4233
4452
|
totals: EMPTY_TOTALS,
|
|
4234
4453
|
revision: 0,
|
|
4235
4454
|
error: null,
|
|
4236
|
-
agentPresetCatalog: EMPTY_AGENT_PRESET_CATALOG
|
|
4455
|
+
agentPresetCatalog: EMPTY_AGENT_PRESET_CATALOG,
|
|
4456
|
+
modelCatalog: EMPTY_MODEL_CATALOG
|
|
4237
4457
|
});
|
|
4238
|
-
const [provision, setProvision] =
|
|
4239
|
-
const [busy, setBusy] =
|
|
4240
|
-
const [busyByBot, setBusyByBot] =
|
|
4241
|
-
const [feedbackByBot, setFeedbackByBot] =
|
|
4242
|
-
const [removeTarget, setRemoveTarget] =
|
|
4243
|
-
const [credentialOpen, setCredentialOpen] =
|
|
4244
|
-
const [credentialError, setCredentialError] =
|
|
4245
|
-
const [notice, setNotice] =
|
|
4246
|
-
const [now, setNow] =
|
|
4247
|
-
const addButtonRef =
|
|
4248
|
-
const mountedRef =
|
|
4249
|
-
const statusRequestRef =
|
|
4458
|
+
const [provision, setProvision] = React11.useState(null);
|
|
4459
|
+
const [busy, setBusy] = React11.useState(false);
|
|
4460
|
+
const [busyByBot, setBusyByBot] = React11.useState({});
|
|
4461
|
+
const [feedbackByBot, setFeedbackByBot] = React11.useState({});
|
|
4462
|
+
const [removeTarget, setRemoveTarget] = React11.useState(null);
|
|
4463
|
+
const [credentialOpen, setCredentialOpen] = React11.useState(false);
|
|
4464
|
+
const [credentialError, setCredentialError] = React11.useState(null);
|
|
4465
|
+
const [notice, setNotice] = React11.useState("");
|
|
4466
|
+
const [now, setNow] = React11.useState(() => Date.now());
|
|
4467
|
+
const addButtonRef = React11.useRef(null);
|
|
4468
|
+
const mountedRef = React11.useRef(true);
|
|
4469
|
+
const statusRequestRef = React11.useRef(0);
|
|
4250
4470
|
const workspaceFence = useWorkspaceSnapshotFence();
|
|
4251
|
-
const noticeFrameRef =
|
|
4252
|
-
const focusFrameRef =
|
|
4253
|
-
|
|
4471
|
+
const noticeFrameRef = React11.useRef(null);
|
|
4472
|
+
const focusFrameRef = React11.useRef(null);
|
|
4473
|
+
React11.useEffect(() => {
|
|
4254
4474
|
mountedRef.current = true;
|
|
4255
4475
|
return () => {
|
|
4256
4476
|
mountedRef.current = false;
|
|
@@ -4265,8 +4485,8 @@ function DingtalkSettingsTab({ rpcCall }) {
|
|
|
4265
4485
|
}
|
|
4266
4486
|
};
|
|
4267
4487
|
}, []);
|
|
4268
|
-
|
|
4269
|
-
const announce =
|
|
4488
|
+
React11.useEffect(() => installDingtalkStyles(), []);
|
|
4489
|
+
const announce = React11.useCallback((message) => {
|
|
4270
4490
|
if (!mountedRef.current) return;
|
|
4271
4491
|
if (noticeFrameRef.current !== null) {
|
|
4272
4492
|
window.cancelAnimationFrame(noticeFrameRef.current);
|
|
@@ -4280,7 +4500,7 @@ function DingtalkSettingsTab({ rpcCall }) {
|
|
|
4280
4500
|
});
|
|
4281
4501
|
}
|
|
4282
4502
|
}, []);
|
|
4283
|
-
const discardStaleFeedback =
|
|
4503
|
+
const discardStaleFeedback = React11.useCallback((snapshot) => {
|
|
4284
4504
|
const botsById = new Map(snapshot.bots.map((bot) => [bot.botId, bot]));
|
|
4285
4505
|
setFeedbackByBot((current) => {
|
|
4286
4506
|
let changed = false;
|
|
@@ -4295,7 +4515,7 @@ function DingtalkSettingsTab({ rpcCall }) {
|
|
|
4295
4515
|
return changed ? next : current;
|
|
4296
4516
|
});
|
|
4297
4517
|
}, []);
|
|
4298
|
-
const focusAddButton =
|
|
4518
|
+
const focusAddButton = React11.useCallback(() => {
|
|
4299
4519
|
if (!mountedRef.current) return;
|
|
4300
4520
|
if (focusFrameRef.current !== null) window.cancelAnimationFrame(focusFrameRef.current);
|
|
4301
4521
|
focusFrameRef.current = window.requestAnimationFrame(() => {
|
|
@@ -4303,11 +4523,11 @@ function DingtalkSettingsTab({ rpcCall }) {
|
|
|
4303
4523
|
if (mountedRef.current) addButtonRef.current?.focus();
|
|
4304
4524
|
});
|
|
4305
4525
|
}, []);
|
|
4306
|
-
const invoke =
|
|
4526
|
+
const invoke = React11.useCallback(async (endpoint, payload = {}, signal) => {
|
|
4307
4527
|
if (typeof rpcCall !== "function") throw new TypeError("\u9489\u9489\u8BBE\u7F6E\u9875\u7F3A\u5C11 RPC \u8FDE\u63A5");
|
|
4308
4528
|
return unwrapRpcResult(await rpcCall(endpoint, payload, signal));
|
|
4309
4529
|
}, [rpcCall]);
|
|
4310
|
-
const loadStatus =
|
|
4530
|
+
const loadStatus = React11.useCallback(async ({
|
|
4311
4531
|
signal,
|
|
4312
4532
|
silent = false,
|
|
4313
4533
|
restoreProvisioning = false
|
|
@@ -4330,7 +4550,8 @@ function DingtalkSettingsTab({ rpcCall }) {
|
|
|
4330
4550
|
totals: snapshot.totals,
|
|
4331
4551
|
revision: snapshot.revision,
|
|
4332
4552
|
error: null,
|
|
4333
|
-
agentPresetCatalog: snapshot.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG
|
|
4553
|
+
agentPresetCatalog: snapshot.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG,
|
|
4554
|
+
modelCatalog: snapshot.modelCatalog ?? EMPTY_MODEL_CATALOG
|
|
4334
4555
|
});
|
|
4335
4556
|
discardStaleFeedback(snapshot);
|
|
4336
4557
|
if (restoreProvisioning && snapshot.provisioning) {
|
|
@@ -4351,12 +4572,12 @@ function DingtalkSettingsTab({ rpcCall }) {
|
|
|
4351
4572
|
return void 0;
|
|
4352
4573
|
}
|
|
4353
4574
|
}, [discardStaleFeedback, invoke, workspaceFence]);
|
|
4354
|
-
|
|
4575
|
+
React11.useEffect(() => {
|
|
4355
4576
|
const controller = new AbortController();
|
|
4356
4577
|
void loadStatus({ signal: controller.signal, restoreProvisioning: true });
|
|
4357
4578
|
return () => controller.abort();
|
|
4358
4579
|
}, [loadStatus]);
|
|
4359
|
-
|
|
4580
|
+
React11.useEffect(() => {
|
|
4360
4581
|
if (model.phase !== "ready") return void 0;
|
|
4361
4582
|
const controller = new AbortController();
|
|
4362
4583
|
let running = false;
|
|
@@ -4375,14 +4596,14 @@ function DingtalkSettingsTab({ rpcCall }) {
|
|
|
4375
4596
|
window.clearInterval(timer);
|
|
4376
4597
|
};
|
|
4377
4598
|
}, [loadStatus, model.phase]);
|
|
4378
|
-
|
|
4599
|
+
React11.useEffect(() => {
|
|
4379
4600
|
if (!provision || !ACTIVE_PROVISION_STATES.has(provision.status)) return void 0;
|
|
4380
4601
|
const timer = window.setInterval(() => {
|
|
4381
4602
|
if (mountedRef.current) setNow(Date.now());
|
|
4382
4603
|
}, 1e3);
|
|
4383
4604
|
return () => window.clearInterval(timer);
|
|
4384
4605
|
}, [provision?.attemptId, provision?.status]);
|
|
4385
|
-
const startProvisioning =
|
|
4606
|
+
const startProvisioning = React11.useCallback(async ({ replace = false } = {}) => {
|
|
4386
4607
|
if (!mountedRef.current) return;
|
|
4387
4608
|
setCredentialOpen(false);
|
|
4388
4609
|
setCredentialError(null);
|
|
@@ -4420,7 +4641,7 @@ function DingtalkSettingsTab({ rpcCall }) {
|
|
|
4420
4641
|
if (mountedRef.current) setBusy(false);
|
|
4421
4642
|
}
|
|
4422
4643
|
}, [announce, invoke, provision?.attemptId]);
|
|
4423
|
-
const bindCredentials =
|
|
4644
|
+
const bindCredentials = React11.useCallback(async ({ identity, secret }) => {
|
|
4424
4645
|
if (!mountedRef.current) return;
|
|
4425
4646
|
const snapshotVersion = workspaceFence.beginMutation();
|
|
4426
4647
|
setBusy(true);
|
|
@@ -4438,7 +4659,8 @@ function DingtalkSettingsTab({ rpcCall }) {
|
|
|
4438
4659
|
totals: snapshot.totals,
|
|
4439
4660
|
revision: snapshot.revision,
|
|
4440
4661
|
error: null,
|
|
4441
|
-
agentPresetCatalog: snapshot.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG
|
|
4662
|
+
agentPresetCatalog: snapshot.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG,
|
|
4663
|
+
modelCatalog: snapshot.modelCatalog ?? EMPTY_MODEL_CATALOG
|
|
4442
4664
|
});
|
|
4443
4665
|
discardStaleFeedback(snapshot);
|
|
4444
4666
|
}
|
|
@@ -4452,7 +4674,7 @@ function DingtalkSettingsTab({ rpcCall }) {
|
|
|
4452
4674
|
if (mountedRef.current) setBusy(false);
|
|
4453
4675
|
}
|
|
4454
4676
|
}, [announce, discardStaleFeedback, invoke, loadStatus, workspaceFence]);
|
|
4455
|
-
const cancelProvisioning =
|
|
4677
|
+
const cancelProvisioning = React11.useCallback(async () => {
|
|
4456
4678
|
if (!mountedRef.current) return;
|
|
4457
4679
|
setBusy(true);
|
|
4458
4680
|
try {
|
|
@@ -4470,7 +4692,7 @@ function DingtalkSettingsTab({ rpcCall }) {
|
|
|
4470
4692
|
if (mountedRef.current) setBusy(false);
|
|
4471
4693
|
}
|
|
4472
4694
|
}, [announce, focusAddButton, invoke, provision?.attemptId, provision?.status]);
|
|
4473
|
-
|
|
4695
|
+
React11.useEffect(() => {
|
|
4474
4696
|
const attemptId = provision?.attemptId;
|
|
4475
4697
|
if (!attemptId || !ACTIVE_PROVISION_STATES.has(provision.status)) return void 0;
|
|
4476
4698
|
const controller = new AbortController();
|
|
@@ -4533,7 +4755,7 @@ function DingtalkSettingsTab({ rpcCall }) {
|
|
|
4533
4755
|
timer = null;
|
|
4534
4756
|
};
|
|
4535
4757
|
}, [announce, invoke, loadStatus, provision?.attemptId, provision?.pollIntervalMs, provision?.status]);
|
|
4536
|
-
const setBotBusy =
|
|
4758
|
+
const setBotBusy = React11.useCallback((botId, operation) => {
|
|
4537
4759
|
if (!mountedRef.current) return;
|
|
4538
4760
|
setBusyByBot((current) => {
|
|
4539
4761
|
const next = { ...current };
|
|
@@ -4542,7 +4764,7 @@ function DingtalkSettingsTab({ rpcCall }) {
|
|
|
4542
4764
|
return next;
|
|
4543
4765
|
});
|
|
4544
4766
|
}, []);
|
|
4545
|
-
const runBotAction =
|
|
4767
|
+
const runBotAction = React11.useCallback(async ({ account, operation, endpoint, payload, success }) => {
|
|
4546
4768
|
if (!mountedRef.current) return void 0;
|
|
4547
4769
|
const snapshotVersion = workspaceFence.beginMutation();
|
|
4548
4770
|
setBotBusy(account.botId, operation);
|
|
@@ -4563,7 +4785,8 @@ function DingtalkSettingsTab({ rpcCall }) {
|
|
|
4563
4785
|
totals: snapshot.totals,
|
|
4564
4786
|
revision: snapshot.revision,
|
|
4565
4787
|
error: null,
|
|
4566
|
-
agentPresetCatalog: snapshot.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG
|
|
4788
|
+
agentPresetCatalog: snapshot.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG,
|
|
4789
|
+
modelCatalog: snapshot.modelCatalog ?? EMPTY_MODEL_CATALOG
|
|
4567
4790
|
});
|
|
4568
4791
|
discardStaleFeedback(snapshot);
|
|
4569
4792
|
}
|
|
@@ -4597,7 +4820,7 @@ function DingtalkSettingsTab({ rpcCall }) {
|
|
|
4597
4820
|
if (mountedRef.current) setBotBusy(account.botId, null);
|
|
4598
4821
|
}
|
|
4599
4822
|
}, [announce, discardStaleFeedback, invoke, loadStatus, setBotBusy, workspaceFence]);
|
|
4600
|
-
const reconnect =
|
|
4823
|
+
const reconnect = React11.useCallback((account) => runBotAction({
|
|
4601
4824
|
account,
|
|
4602
4825
|
operation: "reconnect",
|
|
4603
4826
|
endpoint: DINGTALK_ENDPOINTS.reconnectBot,
|
|
@@ -4608,7 +4831,7 @@ function DingtalkSettingsTab({ rpcCall }) {
|
|
|
4608
4831
|
return connectionTestFeedback(snapshot.testMessage) ?? "\u9489\u9489\u8FDE\u63A5\u68C0\u67E5\u5B8C\u6210\u3002";
|
|
4609
4832
|
}
|
|
4610
4833
|
}), [runBotAction]);
|
|
4611
|
-
const saveWorkspace =
|
|
4834
|
+
const saveWorkspace = React11.useCallback(async (account, workspace) => {
|
|
4612
4835
|
const workspaceVersion = workspaceFence.beginMutation();
|
|
4613
4836
|
setBotBusy(account.botId, "workspace");
|
|
4614
4837
|
try {
|
|
@@ -4623,7 +4846,8 @@ function DingtalkSettingsTab({ rpcCall }) {
|
|
|
4623
4846
|
totals: snapshot.totals,
|
|
4624
4847
|
revision: snapshot.revision,
|
|
4625
4848
|
error: null,
|
|
4626
|
-
agentPresetCatalog: snapshot.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG
|
|
4849
|
+
agentPresetCatalog: snapshot.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG,
|
|
4850
|
+
modelCatalog: snapshot.modelCatalog ?? EMPTY_MODEL_CATALOG
|
|
4627
4851
|
});
|
|
4628
4852
|
discardStaleFeedback(snapshot);
|
|
4629
4853
|
}
|
|
@@ -4633,7 +4857,7 @@ function DingtalkSettingsTab({ rpcCall }) {
|
|
|
4633
4857
|
if (mountedRef.current) setBotBusy(account.botId, null);
|
|
4634
4858
|
}
|
|
4635
4859
|
}, [discardStaleFeedback, invoke, loadStatus, setBotBusy, workspaceFence]);
|
|
4636
|
-
const saveBotSetting =
|
|
4860
|
+
const saveBotSetting = React11.useCallback(async (account, operation, endpoint, payload) => {
|
|
4637
4861
|
const snapshotVersion = workspaceFence.beginMutation();
|
|
4638
4862
|
setBotBusy(account.botId, operation);
|
|
4639
4863
|
try {
|
|
@@ -4648,7 +4872,8 @@ function DingtalkSettingsTab({ rpcCall }) {
|
|
|
4648
4872
|
totals: snapshot.totals,
|
|
4649
4873
|
revision: snapshot.revision,
|
|
4650
4874
|
error: null,
|
|
4651
|
-
agentPresetCatalog: snapshot.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG
|
|
4875
|
+
agentPresetCatalog: snapshot.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG,
|
|
4876
|
+
modelCatalog: snapshot.modelCatalog ?? EMPTY_MODEL_CATALOG
|
|
4652
4877
|
});
|
|
4653
4878
|
discardStaleFeedback(snapshot);
|
|
4654
4879
|
}
|
|
@@ -4658,7 +4883,7 @@ function DingtalkSettingsTab({ rpcCall }) {
|
|
|
4658
4883
|
if (mountedRef.current) setBotBusy(account.botId, null);
|
|
4659
4884
|
}
|
|
4660
4885
|
}, [discardStaleFeedback, invoke, loadStatus, setBotBusy, workspaceFence]);
|
|
4661
|
-
const remove =
|
|
4886
|
+
const remove = React11.useCallback(async (account) => {
|
|
4662
4887
|
const snapshot = await runBotAction({
|
|
4663
4888
|
account,
|
|
4664
4889
|
operation: "delete",
|
|
@@ -4712,7 +4937,9 @@ function DingtalkSettingsTab({ rpcCall }) {
|
|
|
4712
4937
|
setCredentialError(null);
|
|
4713
4938
|
}
|
|
4714
4939
|
}) : null;
|
|
4715
|
-
return h2(
|
|
4940
|
+
return h2(ModelCatalogContext.Provider, {
|
|
4941
|
+
value: model.modelCatalog ?? EMPTY_MODEL_CATALOG
|
|
4942
|
+
}, h2(AgentPresetCatalogContext.Provider, {
|
|
4716
4943
|
value: model.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG
|
|
4717
4944
|
}, h2(
|
|
4718
4945
|
"section",
|
|
@@ -4742,7 +4969,7 @@ function DingtalkSettingsTab({ rpcCall }) {
|
|
|
4742
4969
|
h2(Button, { onClick: () => void loadStatus() }, "\u91CD\u65B0\u8BFB\u53D6")
|
|
4743
4970
|
)
|
|
4744
4971
|
) : h2(
|
|
4745
|
-
|
|
4972
|
+
React11.Fragment,
|
|
4746
4973
|
null,
|
|
4747
4974
|
credentialView,
|
|
4748
4975
|
provisionView,
|
|
@@ -4754,6 +4981,12 @@ function DingtalkSettingsTab({ rpcCall }) {
|
|
|
4754
4981
|
removeTarget,
|
|
4755
4982
|
onReconnect: (account) => void reconnect(account),
|
|
4756
4983
|
onWorkspaceSave: saveWorkspace,
|
|
4984
|
+
onModelSave: (account, selectedModel) => saveBotSetting(
|
|
4985
|
+
account,
|
|
4986
|
+
"model",
|
|
4987
|
+
DINGTALK_ENDPOINTS.setModel,
|
|
4988
|
+
{ model: selectedModel }
|
|
4989
|
+
),
|
|
4757
4990
|
onAgentPresetSave: (account, agentPreset) => saveBotSetting(
|
|
4758
4991
|
account,
|
|
4759
4992
|
"preset",
|
|
@@ -4771,7 +5004,7 @@ function DingtalkSettingsTab({ rpcCall }) {
|
|
|
4771
5004
|
onCancelRemove: () => setRemoveTarget(null)
|
|
4772
5005
|
}) : null
|
|
4773
5006
|
)
|
|
4774
|
-
));
|
|
5007
|
+
)));
|
|
4775
5008
|
}
|
|
4776
5009
|
|
|
4777
5010
|
// plugin-src/client/channels/shared/token-api.js
|
|
@@ -4797,6 +5030,7 @@ var TOKEN_BOT_ENDPOINTS = Object.freeze({
|
|
|
4797
5030
|
reconnectBot: "bot.reconnect",
|
|
4798
5031
|
deleteBot: "bot.delete",
|
|
4799
5032
|
setWorkspace: "bot.workspace.set",
|
|
5033
|
+
setModel: SET_MODEL_ENDPOINT,
|
|
4800
5034
|
setAgentPreset: SET_AGENT_PRESET_ENDPOINT,
|
|
4801
5035
|
setContextEnhancement: "bot.context-enhancement.set",
|
|
4802
5036
|
setAccessPolicy: "bot.access-policy.set"
|
|
@@ -4825,6 +5059,7 @@ function createTokenChannelApi(channel4, connectionSummary, {
|
|
|
4825
5059
|
connected,
|
|
4826
5060
|
state: connected ? "connected" : state,
|
|
4827
5061
|
workspace: text2(value.workspace, "", 4096),
|
|
5062
|
+
model: normalizeModelSelection(value.model),
|
|
4828
5063
|
agentPreset: normalizeAgentPresetId(value.agentPreset),
|
|
4829
5064
|
contextEnhancement: normalizeContextEnhancementConfig(value.contextEnhancement),
|
|
4830
5065
|
...Object.hasOwn(value, "accessPolicy") ? { accessPolicy: normalizeAccessPolicy(value.accessPolicy) } : {},
|
|
@@ -4858,7 +5093,8 @@ function createTokenChannelApi(channel4, connectionSummary, {
|
|
|
4858
5093
|
revision: Number.isSafeInteger(source.revision) ? source.revision : 0,
|
|
4859
5094
|
bots,
|
|
4860
5095
|
totals: { configured: bots.length, connected: bots.filter((bot) => bot.connected).length },
|
|
4861
|
-
agentPresetCatalog: normalizeAgentPresetCatalog(source.agentPresetCatalog)
|
|
5096
|
+
agentPresetCatalog: normalizeAgentPresetCatalog(source.agentPresetCatalog),
|
|
5097
|
+
modelCatalog: normalizeModelCatalog(source.modelCatalog)
|
|
4862
5098
|
};
|
|
4863
5099
|
};
|
|
4864
5100
|
const presentError13 = (error) => ({
|
|
@@ -4877,8 +5113,8 @@ var normalizeSnapshot2 = api.normalizeSnapshot;
|
|
|
4877
5113
|
var presentError2 = api.presentError;
|
|
4878
5114
|
|
|
4879
5115
|
// plugin-src/client/channels/shared/token-channel.js
|
|
4880
|
-
var
|
|
4881
|
-
var Button3 =
|
|
5116
|
+
var React12 = __toESM(require("react"), 1);
|
|
5117
|
+
var Button3 = React12.forwardRef(function Button4({ children, kind = "secondary", className = "", ...props }, ref) {
|
|
4882
5118
|
return h2("button", {
|
|
4883
5119
|
...props,
|
|
4884
5120
|
ref,
|
|
@@ -4930,7 +5166,7 @@ function createTokenChannelSettings(definition) {
|
|
|
4930
5166
|
AccountSettings = null,
|
|
4931
5167
|
accountSettingsEndpoint = null
|
|
4932
5168
|
} = definition;
|
|
4933
|
-
function AccountCard5({ account, busy, testNotice, removing, onReconnect, onWorkspaceSave, onAgentPresetSave, onContextEnhancementSave, onAccountSettingsSave, onRequestRemove, onConfirmRemove, onCancelRemove }) {
|
|
5169
|
+
function AccountCard5({ account, busy, testNotice, removing, onReconnect, onWorkspaceSave, onModelSave, onAgentPresetSave, onContextEnhancementSave, onAccountSettingsSave, onRequestRemove, onConfirmRemove, onCancelRemove }) {
|
|
4934
5170
|
const state = busy === "reconnect" ? "connecting" : account.state;
|
|
4935
5171
|
const tone = account.connected ? "success" : state === "error" ? "error" : "warning";
|
|
4936
5172
|
const stateLabel2 = account.connected ? "\u8FD0\u884C\u6B63\u5E38" : state === "connecting" ? "\u6B63\u5728\u8FDE\u63A5" : "\u8FDE\u63A5\u672A\u5C31\u7EEA";
|
|
@@ -4985,6 +5221,11 @@ function createTokenChannelSettings(definition) {
|
|
|
4985
5221
|
disabled: Boolean(busy),
|
|
4986
5222
|
onSave: onWorkspaceSave
|
|
4987
5223
|
}),
|
|
5224
|
+
h2(ModelEditor, {
|
|
5225
|
+
model: account.model,
|
|
5226
|
+
disabled: Boolean(busy),
|
|
5227
|
+
onSave: onModelSave
|
|
5228
|
+
}),
|
|
4988
5229
|
h2(AgentPresetEditor, {
|
|
4989
5230
|
agentPreset: account.agentPreset,
|
|
4990
5231
|
disabled: Boolean(busy),
|
|
@@ -5052,22 +5293,23 @@ function createTokenChannelSettings(definition) {
|
|
|
5052
5293
|
);
|
|
5053
5294
|
}
|
|
5054
5295
|
function SettingsTab({ rpcCall }) {
|
|
5055
|
-
const [model, setModel] =
|
|
5296
|
+
const [model, setModel] = React12.useState({
|
|
5056
5297
|
phase: "loading",
|
|
5057
5298
|
bots: [],
|
|
5058
5299
|
totals: { configured: 0, connected: 0 },
|
|
5059
5300
|
error: null,
|
|
5060
|
-
agentPresetCatalog: EMPTY_AGENT_PRESET_CATALOG
|
|
5301
|
+
agentPresetCatalog: EMPTY_AGENT_PRESET_CATALOG,
|
|
5302
|
+
modelCatalog: EMPTY_MODEL_CATALOG
|
|
5061
5303
|
});
|
|
5062
|
-
const [credentialOpen, setCredentialOpen] =
|
|
5063
|
-
const [credentialError, setCredentialError] =
|
|
5064
|
-
const [busy, setBusy] =
|
|
5065
|
-
const [busyByBot, setBusyByBot] =
|
|
5066
|
-
const [testNoticeByBot, setTestNoticeByBot] =
|
|
5067
|
-
const [removeTarget, setRemoveTarget] =
|
|
5068
|
-
const mounted =
|
|
5304
|
+
const [credentialOpen, setCredentialOpen] = React12.useState(false);
|
|
5305
|
+
const [credentialError, setCredentialError] = React12.useState(null);
|
|
5306
|
+
const [busy, setBusy] = React12.useState(false);
|
|
5307
|
+
const [busyByBot, setBusyByBot] = React12.useState({});
|
|
5308
|
+
const [testNoticeByBot, setTestNoticeByBot] = React12.useState({});
|
|
5309
|
+
const [removeTarget, setRemoveTarget] = React12.useState(null);
|
|
5310
|
+
const mounted = React12.useRef(true);
|
|
5069
5311
|
const workspaceFence = useWorkspaceSnapshotFence();
|
|
5070
|
-
|
|
5312
|
+
React12.useEffect(() => {
|
|
5071
5313
|
const disposeDingtalk = installDingtalkStyles();
|
|
5072
5314
|
const disposeChannel = installStyles();
|
|
5073
5315
|
mounted.current = true;
|
|
@@ -5077,11 +5319,11 @@ function createTokenChannelSettings(definition) {
|
|
|
5077
5319
|
disposeDingtalk();
|
|
5078
5320
|
};
|
|
5079
5321
|
}, []);
|
|
5080
|
-
const invoke =
|
|
5322
|
+
const invoke = React12.useCallback(async (endpoint, payload = {}, signal) => {
|
|
5081
5323
|
if (typeof rpcCall !== "function") throw new TypeError(`${channel4} \u8BBE\u7F6E\u9875\u7F3A\u5C11 RPC \u8FDE\u63A5`);
|
|
5082
5324
|
return api4.unwrapRpcResult(await rpcCall(endpoint, payload, signal));
|
|
5083
5325
|
}, [rpcCall]);
|
|
5084
|
-
const loadStatus =
|
|
5326
|
+
const loadStatus = React12.useCallback(async ({ signal, silent = false } = {}) => {
|
|
5085
5327
|
const workspaceVersion = workspaceFence.beginStatus();
|
|
5086
5328
|
if (workspaceVersion === null) return;
|
|
5087
5329
|
if (!silent && mounted.current) setModel((current) => ({ ...current, phase: "loading", error: null }));
|
|
@@ -5093,7 +5335,8 @@ function createTokenChannelSettings(definition) {
|
|
|
5093
5335
|
bots: snapshot.bots,
|
|
5094
5336
|
totals: snapshot.totals,
|
|
5095
5337
|
error: null,
|
|
5096
|
-
agentPresetCatalog: snapshot.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG
|
|
5338
|
+
agentPresetCatalog: snapshot.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG,
|
|
5339
|
+
modelCatalog: snapshot.modelCatalog ?? EMPTY_MODEL_CATALOG
|
|
5097
5340
|
});
|
|
5098
5341
|
} catch (error) {
|
|
5099
5342
|
if (error?.name !== "AbortError" && mounted.current && !signal?.aborted && workspaceFence.canCommitStatus(workspaceVersion)) {
|
|
@@ -5105,12 +5348,12 @@ function createTokenChannelSettings(definition) {
|
|
|
5105
5348
|
}
|
|
5106
5349
|
}
|
|
5107
5350
|
}, [invoke, workspaceFence]);
|
|
5108
|
-
|
|
5351
|
+
React12.useEffect(() => {
|
|
5109
5352
|
const controller = new AbortController();
|
|
5110
5353
|
void loadStatus({ signal: controller.signal });
|
|
5111
5354
|
return () => controller.abort();
|
|
5112
5355
|
}, [loadStatus]);
|
|
5113
|
-
|
|
5356
|
+
React12.useEffect(() => {
|
|
5114
5357
|
if (model.phase !== "ready") return void 0;
|
|
5115
5358
|
const controller = new AbortController();
|
|
5116
5359
|
const timer = window.setInterval(
|
|
@@ -5122,7 +5365,7 @@ function createTokenChannelSettings(definition) {
|
|
|
5122
5365
|
window.clearInterval(timer);
|
|
5123
5366
|
};
|
|
5124
5367
|
}, [loadStatus, model.phase]);
|
|
5125
|
-
const bindCredentials =
|
|
5368
|
+
const bindCredentials = React12.useCallback(async (values) => {
|
|
5126
5369
|
const snapshotVersion = workspaceFence.beginMutation();
|
|
5127
5370
|
setBusy(true);
|
|
5128
5371
|
setCredentialError(null);
|
|
@@ -5138,7 +5381,8 @@ function createTokenChannelSettings(definition) {
|
|
|
5138
5381
|
bots: snapshot.bots,
|
|
5139
5382
|
totals: snapshot.totals,
|
|
5140
5383
|
error: null,
|
|
5141
|
-
agentPresetCatalog: snapshot.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG
|
|
5384
|
+
agentPresetCatalog: snapshot.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG,
|
|
5385
|
+
modelCatalog: snapshot.modelCatalog ?? EMPTY_MODEL_CATALOG
|
|
5142
5386
|
});
|
|
5143
5387
|
}
|
|
5144
5388
|
setCredentialOpen(false);
|
|
@@ -5150,7 +5394,7 @@ function createTokenChannelSettings(definition) {
|
|
|
5150
5394
|
if (mounted.current) setBusy(false);
|
|
5151
5395
|
}
|
|
5152
5396
|
}, [invoke, loadStatus, workspaceFence]);
|
|
5153
|
-
const botAction =
|
|
5397
|
+
const botAction = React12.useCallback(async (account, operation, endpoint, payload) => {
|
|
5154
5398
|
const snapshotVersion = workspaceFence.beginMutation();
|
|
5155
5399
|
setBusyByBot((current) => ({ ...current, [account.botId]: operation }));
|
|
5156
5400
|
try {
|
|
@@ -5162,7 +5406,8 @@ function createTokenChannelSettings(definition) {
|
|
|
5162
5406
|
bots: snapshot.bots,
|
|
5163
5407
|
totals: snapshot.totals,
|
|
5164
5408
|
error: null,
|
|
5165
|
-
agentPresetCatalog: snapshot.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG
|
|
5409
|
+
agentPresetCatalog: snapshot.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG,
|
|
5410
|
+
modelCatalog: snapshot.modelCatalog ?? EMPTY_MODEL_CATALOG
|
|
5166
5411
|
});
|
|
5167
5412
|
}
|
|
5168
5413
|
if (mounted.current && operation === "reconnect") {
|
|
@@ -5214,6 +5459,12 @@ function createTokenChannelSettings(definition) {
|
|
|
5214
5459
|
endpoints.setWorkspace,
|
|
5215
5460
|
{ botId: account.botId, workspace }
|
|
5216
5461
|
),
|
|
5462
|
+
onModelSave: (selectedModel) => botAction(
|
|
5463
|
+
account,
|
|
5464
|
+
"model",
|
|
5465
|
+
endpoints.setModel,
|
|
5466
|
+
{ botId: account.botId, model: selectedModel }
|
|
5467
|
+
),
|
|
5217
5468
|
onAgentPresetSave: (agentPreset) => botAction(
|
|
5218
5469
|
account,
|
|
5219
5470
|
"preset",
|
|
@@ -5243,7 +5494,9 @@ function createTokenChannelSettings(definition) {
|
|
|
5243
5494
|
}
|
|
5244
5495
|
}))))
|
|
5245
5496
|
) : null;
|
|
5246
|
-
return h2(
|
|
5497
|
+
return h2(ModelCatalogContext.Provider, {
|
|
5498
|
+
value: model.modelCatalog ?? EMPTY_MODEL_CATALOG
|
|
5499
|
+
}, h2(AgentPresetCatalogContext.Provider, {
|
|
5247
5500
|
value: model.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG
|
|
5248
5501
|
}, h2(
|
|
5249
5502
|
"section",
|
|
@@ -5293,7 +5546,7 @@ function createTokenChannelSettings(definition) {
|
|
|
5293
5546
|
h2(Button3, { onClick: () => void loadStatus() }, "\u91CD\u65B0\u8BFB\u53D6")
|
|
5294
5547
|
)
|
|
5295
5548
|
) : h2(
|
|
5296
|
-
|
|
5549
|
+
React12.Fragment,
|
|
5297
5550
|
null,
|
|
5298
5551
|
credentialOpen ? CredentialPanel ? h2(CredentialPanel, {
|
|
5299
5552
|
busy,
|
|
@@ -5349,7 +5602,7 @@ function createTokenChannelSettings(definition) {
|
|
|
5349
5602
|
) : null,
|
|
5350
5603
|
botList
|
|
5351
5604
|
)
|
|
5352
|
-
));
|
|
5605
|
+
)));
|
|
5353
5606
|
}
|
|
5354
5607
|
return { SettingsTab, AccountCard: AccountCard5 };
|
|
5355
5608
|
}
|
|
@@ -5394,7 +5647,7 @@ var DiscordSettingsTab = channel.SettingsTab;
|
|
|
5394
5647
|
var DiscordAccountCard = channel.AccountCard;
|
|
5395
5648
|
|
|
5396
5649
|
// plugin-src/client/channels/feishu/index.js
|
|
5397
|
-
var
|
|
5650
|
+
var React14 = __toESM(require("react"), 1);
|
|
5398
5651
|
|
|
5399
5652
|
// plugin-src/client/channels/feishu/api.js
|
|
5400
5653
|
var FEISHU_RPC_CHANNEL = "/feishu";
|
|
@@ -5410,6 +5663,7 @@ var FEISHU_ENDPOINTS = Object.freeze({
|
|
|
5410
5663
|
disconnectBot: "bot.disconnect",
|
|
5411
5664
|
deleteBot: "bot.delete",
|
|
5412
5665
|
setWorkspace: "bot.workspace.set",
|
|
5666
|
+
setModel: SET_MODEL_ENDPOINT,
|
|
5413
5667
|
setAgentPreset: "bot.preset.set",
|
|
5414
5668
|
setContextEnhancement: "bot.context-enhancement.set",
|
|
5415
5669
|
setAccessPolicy: "bot.access-policy.set",
|
|
@@ -5561,6 +5815,7 @@ function normalizeBotConnection(value, fallbackBotId) {
|
|
|
5561
5815
|
connected,
|
|
5562
5816
|
configured: value.configured !== false,
|
|
5563
5817
|
workspace: optionalString2(value.workspace)?.slice(0, 4096) ?? "",
|
|
5818
|
+
model: normalizeModelSelection(value.model),
|
|
5564
5819
|
agentPreset: normalizeAgentPresetId(value.agentPreset),
|
|
5565
5820
|
contextEnhancement: normalizeContextEnhancementConfig(value.contextEnhancement),
|
|
5566
5821
|
...Object.hasOwn(value, "accessPolicy") ? { accessPolicy: normalizeAccessPolicy(value.accessPolicy) } : {},
|
|
@@ -5610,7 +5865,8 @@ function normalizeBotsSnapshot(value) {
|
|
|
5610
5865
|
totals: { configured, connected },
|
|
5611
5866
|
provisioning: value.provisioning ? normalizeProvisioning2(value.provisioning) : void 0,
|
|
5612
5867
|
error: normalizeError2(value.error),
|
|
5613
|
-
agentPresetCatalog: normalizeAgentPresetCatalog(value.agentPresetCatalog)
|
|
5868
|
+
agentPresetCatalog: normalizeAgentPresetCatalog(value.agentPresetCatalog),
|
|
5869
|
+
modelCatalog: normalizeModelCatalog(value.modelCatalog)
|
|
5614
5870
|
};
|
|
5615
5871
|
}
|
|
5616
5872
|
function normalizeConnectionSnapshot(value) {
|
|
@@ -5660,7 +5916,7 @@ function formatRemaining2(milliseconds) {
|
|
|
5660
5916
|
}
|
|
5661
5917
|
|
|
5662
5918
|
// plugin-src/client/lifecycle.js
|
|
5663
|
-
var
|
|
5919
|
+
var React13 = __toESM(require("react"), 1);
|
|
5664
5920
|
function createPollScheduler({ setTimeoutFn, clearTimeoutFn }) {
|
|
5665
5921
|
let disposed = false;
|
|
5666
5922
|
let timer;
|
|
@@ -5722,8 +5978,8 @@ function createAnimationFrameScheduler({ requestFrame, cancelFrame }) {
|
|
|
5722
5978
|
};
|
|
5723
5979
|
}
|
|
5724
5980
|
function useAnimationFrameScheduler() {
|
|
5725
|
-
const schedulerRef =
|
|
5726
|
-
|
|
5981
|
+
const schedulerRef = React13.useRef(null);
|
|
5982
|
+
React13.useEffect(() => {
|
|
5727
5983
|
const scheduler = createAnimationFrameScheduler({
|
|
5728
5984
|
requestFrame: (callback) => window.requestAnimationFrame(callback),
|
|
5729
5985
|
cancelFrame: (frame) => window.cancelAnimationFrame(frame)
|
|
@@ -5734,7 +5990,7 @@ function useAnimationFrameScheduler() {
|
|
|
5734
5990
|
if (schedulerRef.current === scheduler) schedulerRef.current = null;
|
|
5735
5991
|
};
|
|
5736
5992
|
}, []);
|
|
5737
|
-
return
|
|
5993
|
+
return React13.useCallback(
|
|
5738
5994
|
(callback, key) => schedulerRef.current?.schedule(callback, key) ?? false,
|
|
5739
5995
|
[]
|
|
5740
5996
|
);
|
|
@@ -5809,7 +6065,7 @@ function QrIcon({ size = 58 }) {
|
|
|
5809
6065
|
fill: "currentColor"
|
|
5810
6066
|
}));
|
|
5811
6067
|
}
|
|
5812
|
-
var Button5 =
|
|
6068
|
+
var Button5 = React14.forwardRef(function Button6({ children, kind = "secondary", size, icon, className = "", ...props }, ref) {
|
|
5813
6069
|
return h2("button", {
|
|
5814
6070
|
...props,
|
|
5815
6071
|
ref,
|
|
@@ -5926,7 +6182,7 @@ function safeQrSource2(value) {
|
|
|
5926
6182
|
return /^data:image\/(?:png|webp|svg\+xml)(?:;charset=[^;,]+)?;base64,/i.test(value) ? value : void 0;
|
|
5927
6183
|
}
|
|
5928
6184
|
function QrPane({ provision, now, onRefresh, onCancel, busy }) {
|
|
5929
|
-
const [imageFailed, setImageFailed] =
|
|
6185
|
+
const [imageFailed, setImageFailed] = React14.useState(false);
|
|
5930
6186
|
const qrSource = safeQrSource2(provision.qrCodeDataUrl);
|
|
5931
6187
|
const href = safeVerificationHref(provision.verificationUrl);
|
|
5932
6188
|
const remaining = Math.max(0, provision.expiresAt - now);
|
|
@@ -5935,7 +6191,7 @@ function QrPane({ provision, now, onRefresh, onCancel, busy }) {
|
|
|
5935
6191
|
const repairing = isCallbackRepair(provision);
|
|
5936
6192
|
const grantingGroupMessages = isGroupMessagePermission(provision);
|
|
5937
6193
|
const botName = provision.botName ?? "\u6B64\u673A\u5668\u4EBA";
|
|
5938
|
-
|
|
6194
|
+
React14.useEffect(() => setImageFailed(false), [qrSource]);
|
|
5939
6195
|
return h2(
|
|
5940
6196
|
"div",
|
|
5941
6197
|
{ className: "bxf-card bxf-provisionCard dim-surfaceCard" },
|
|
@@ -6098,11 +6354,11 @@ function connectionTestNotice2(value) {
|
|
|
6098
6354
|
return value?.testMessage ? "\u8FDE\u63A5\u68C0\u67E5\u5B8C\u6210\uFF0C\u4F46\u6D4B\u8BD5\u6D88\u606F\u53D1\u9001\u5931\u8D25\u3002" : null;
|
|
6099
6355
|
}
|
|
6100
6356
|
function RemoveConfirmation2({ bot, busy, onConfirm, onCancel }) {
|
|
6101
|
-
const cancelRef =
|
|
6357
|
+
const cancelRef = React14.useRef(null);
|
|
6102
6358
|
const idPart = bot.botId.replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
6103
6359
|
const titleId = `bxf-remove-title-${idPart}`;
|
|
6104
6360
|
const descriptionId = `bxf-remove-description-${idPart}`;
|
|
6105
|
-
|
|
6361
|
+
React14.useEffect(() => cancelRef.current?.focus(), []);
|
|
6106
6362
|
return h2(
|
|
6107
6363
|
"div",
|
|
6108
6364
|
{
|
|
@@ -6135,146 +6391,6 @@ function RemoveConfirmation2({ bot, busy, onConfirm, onCancel }) {
|
|
|
6135
6391
|
)
|
|
6136
6392
|
);
|
|
6137
6393
|
}
|
|
6138
|
-
function GroupResponseModeEditor({
|
|
6139
|
-
value,
|
|
6140
|
-
permissionGranted = false,
|
|
6141
|
-
disabled = false,
|
|
6142
|
-
authorizationDisabled = false,
|
|
6143
|
-
onSave,
|
|
6144
|
-
onAuthorize
|
|
6145
|
-
}) {
|
|
6146
|
-
const current = normalizeGroupResponseMode(value);
|
|
6147
|
-
const [saving, setSaving] = React13.useState(false);
|
|
6148
|
-
const [authorizing, setAuthorizing] = React13.useState(false);
|
|
6149
|
-
const [error, setError] = React13.useState(null);
|
|
6150
|
-
const change = async (event) => {
|
|
6151
|
-
const next = normalizeGroupResponseMode(event.target.value);
|
|
6152
|
-
if (next === current || saving || disabled) return;
|
|
6153
|
-
setSaving(true);
|
|
6154
|
-
setError(null);
|
|
6155
|
-
try {
|
|
6156
|
-
await onSave?.(next);
|
|
6157
|
-
} catch (cause) {
|
|
6158
|
-
setError(cause?.message ?? "\u7FA4\u804A\u54CD\u5E94\u65B9\u5F0F\u4FEE\u6539\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5\u3002");
|
|
6159
|
-
} finally {
|
|
6160
|
-
setSaving(false);
|
|
6161
|
-
}
|
|
6162
|
-
};
|
|
6163
|
-
const authorize = async () => {
|
|
6164
|
-
if (current !== "all" || saving || authorizing || disabled || authorizationDisabled) return;
|
|
6165
|
-
setAuthorizing(true);
|
|
6166
|
-
setError(null);
|
|
6167
|
-
try {
|
|
6168
|
-
await onAuthorize?.();
|
|
6169
|
-
} catch (cause) {
|
|
6170
|
-
setError(cause?.message ?? "\u7FA4\u6D88\u606F\u6743\u9650\u6388\u6743\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5\u3002");
|
|
6171
|
-
} finally {
|
|
6172
|
-
setAuthorizing(false);
|
|
6173
|
-
}
|
|
6174
|
-
};
|
|
6175
|
-
return h2(
|
|
6176
|
-
"div",
|
|
6177
|
-
{ className: "bxf-responseMode dim-responseMode" },
|
|
6178
|
-
h2(
|
|
6179
|
-
"div",
|
|
6180
|
-
{ className: "bxf-responseModeHeader dim-responseModeHeader" },
|
|
6181
|
-
h2("span", null, "\u7FA4\u804A\u54CD\u5E94\u65B9\u5F0F"),
|
|
6182
|
-
saving || authorizing ? h2(
|
|
6183
|
-
"span",
|
|
6184
|
-
{ className: "bxf-responseModeStatus dim-responseModeStatus" },
|
|
6185
|
-
saving ? "\u4FDD\u5B58\u4E2D\u2026" : "\u6B63\u5728\u51C6\u5907\u6388\u6743\u2026"
|
|
6186
|
-
) : null
|
|
6187
|
-
),
|
|
6188
|
-
h2(
|
|
6189
|
-
"select",
|
|
6190
|
-
{
|
|
6191
|
-
className: "bxf-responseModeSelect dim-responseModeSelect",
|
|
6192
|
-
value: current,
|
|
6193
|
-
disabled: disabled || saving,
|
|
6194
|
-
"aria-label": "\u7FA4\u804A\u54CD\u5E94\u65B9\u5F0F",
|
|
6195
|
-
onChange: (event) => {
|
|
6196
|
-
void change(event);
|
|
6197
|
-
}
|
|
6198
|
-
},
|
|
6199
|
-
h2("option", { value: "mention" }, "\u4EC5\u5728 @\u673A\u5668\u4EBA\u65F6\u54CD\u5E94\uFF08\u63A8\u8350\uFF09"),
|
|
6200
|
-
h2("option", { value: "all" }, "\u54CD\u5E94\u6240\u6709\u7FA4\u6D88\u606F")
|
|
6201
|
-
),
|
|
6202
|
-
h2(
|
|
6203
|
-
"small",
|
|
6204
|
-
{ className: "bxf-responseModeHelp dim-responseModeHelp" },
|
|
6205
|
-
current === "mention" ? permissionGranted ? "\u79C1\u804A\u59CB\u7EC8\u54CD\u5E94\uFF1B\u7FA4\u804A\u4EC5\u5904\u7406\u660E\u786E @\u5F53\u524D\u673A\u5668\u4EBA\u7684\u6D88\u606F\u3002\u7FA4\u6D88\u606F\u6743\u9650\u5DF2\u5F00\u901A\uFF0C\u518D\u6B21\u5207\u6362\u65E0\u9700\u6388\u6743\u3002" : "\u79C1\u804A\u59CB\u7EC8\u54CD\u5E94\uFF1B\u7FA4\u804A\u4EC5\u5904\u7406\u660E\u786E @\u5F53\u524D\u673A\u5668\u4EBA\u7684\u6D88\u606F\u3002\u9009\u62E9\u5168\u90E8\u6D88\u606F\u540E\u4F1A\u6253\u5F00\u98DE\u4E66\u5B98\u65B9\u6388\u6743\u6D41\u7A0B\u3002" : permissionGranted ? "\u5DF2\u5F00\u901A\u201C\u83B7\u53D6\u7FA4\u7EC4\u4E2D\u6240\u6709\u6D88\u606F\u201D\u6743\u9650\uFF08im:message.group_msg\uFF09\uFF1B\u673A\u5668\u4EBA\u4F1A\u5904\u7406\u7FA4\u804A\u4E2D\u7684\u6240\u6709\u53EF\u89C1\u6D88\u606F\u3002" : "\u5C1A\u672A\u786E\u8BA4\u201C\u83B7\u53D6\u7FA4\u7EC4\u4E2D\u6240\u6709\u6D88\u606F\u201D\u6743\u9650\uFF0C\u8BF7\u5B8C\u6210\u98DE\u4E66\u6388\u6743\u3002"
|
|
6206
|
-
),
|
|
6207
|
-
current === "all" ? h2(
|
|
6208
|
-
"div",
|
|
6209
|
-
{ className: "bxf-responseModePermissionAction dim-responseModePermissionAction" },
|
|
6210
|
-
h2(Button5, {
|
|
6211
|
-
className: "bxf-responseModePermissionButton",
|
|
6212
|
-
size: "small",
|
|
6213
|
-
disabled: disabled || authorizationDisabled || saving || authorizing,
|
|
6214
|
-
"aria-busy": authorizing ? "true" : void 0,
|
|
6215
|
-
"aria-label": permissionGranted ? "\u91CD\u65B0\u6388\u6743\u7FA4\u6D88\u606F\u6743\u9650" : "\u6388\u6743\u7FA4\u6D88\u606F\u6743\u9650",
|
|
6216
|
-
onClick: () => {
|
|
6217
|
-
void authorize();
|
|
6218
|
-
}
|
|
6219
|
-
}, authorizing ? "\u6B63\u5728\u51C6\u5907\u2026" : permissionGranted ? "\u91CD\u65B0\u6388\u6743" : "\u53BB\u6388\u6743")
|
|
6220
|
-
) : null,
|
|
6221
|
-
error ? h2("p", {
|
|
6222
|
-
className: "bxf-responseModeError dim-responseModeError",
|
|
6223
|
-
role: "alert"
|
|
6224
|
-
}, error) : null
|
|
6225
|
-
);
|
|
6226
|
-
}
|
|
6227
|
-
function GroupTopicReplyEditor({ value = false, disabled = false, onSave }) {
|
|
6228
|
-
const current = value === true ? "on" : "off";
|
|
6229
|
-
const [saving, setSaving] = React13.useState(false);
|
|
6230
|
-
const [error, setError] = React13.useState(null);
|
|
6231
|
-
const change = async (event) => {
|
|
6232
|
-
const next = event.target.value === "on";
|
|
6233
|
-
if ((next ? "on" : "off") === current || saving || disabled) return;
|
|
6234
|
-
setSaving(true);
|
|
6235
|
-
setError(null);
|
|
6236
|
-
try {
|
|
6237
|
-
await onSave?.(next);
|
|
6238
|
-
} catch (cause) {
|
|
6239
|
-
setError(cause?.message ?? "\u7FA4\u804A\u4EE5\u8BDD\u9898\u65B9\u5F0F\u56DE\u590D\u8BBE\u7F6E\u4FDD\u5B58\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5\u3002");
|
|
6240
|
-
} finally {
|
|
6241
|
-
setSaving(false);
|
|
6242
|
-
}
|
|
6243
|
-
};
|
|
6244
|
-
return h2(
|
|
6245
|
-
"div",
|
|
6246
|
-
{ className: "bxf-responseMode dim-responseMode" },
|
|
6247
|
-
h2(
|
|
6248
|
-
"div",
|
|
6249
|
-
{ className: "bxf-responseModeHeader dim-responseModeHeader" },
|
|
6250
|
-
h2("span", null, "\u7FA4\u804A\u4EE5\u8BDD\u9898\u65B9\u5F0F\u56DE\u590D"),
|
|
6251
|
-
saving ? h2("span", { className: "bxf-responseModeStatus dim-responseModeStatus" }, "\u4FDD\u5B58\u4E2D\u2026") : null
|
|
6252
|
-
),
|
|
6253
|
-
h2(
|
|
6254
|
-
"select",
|
|
6255
|
-
{
|
|
6256
|
-
className: "bxf-responseModeSelect dim-responseModeSelect",
|
|
6257
|
-
value: current,
|
|
6258
|
-
disabled: disabled || saving,
|
|
6259
|
-
"aria-label": "\u7FA4\u804A\u4EE5\u8BDD\u9898\u65B9\u5F0F\u56DE\u590D",
|
|
6260
|
-
onChange: (event) => {
|
|
6261
|
-
void change(event);
|
|
6262
|
-
}
|
|
6263
|
-
},
|
|
6264
|
-
h2("option", { value: "off" }, "\u5173\u95ED\uFF08\u7FA4\u5185\u76F4\u63A5\u56DE\u590D\uFF09"),
|
|
6265
|
-
h2("option", { value: "on" }, "\u5F00\u542F\uFF08\u81EA\u52A8\u5F00\u542F\u72EC\u7ACB\u98DE\u4E66\u8BDD\u9898\uFF09")
|
|
6266
|
-
),
|
|
6267
|
-
h2(
|
|
6268
|
-
"small",
|
|
6269
|
-
{ className: "bxf-responseModeHelp dim-responseModeHelp" },
|
|
6270
|
-
"\u5F00\u542F\u540E\uFF0C\u7FA4\u804A\u4E2D\u5411\u673A\u5668\u4EBA\u63D0\u95EE\u4F1A\u81EA\u52A8\u5F00\u542F\u72EC\u7ACB\u98DE\u4E66\u8BDD\u9898\uFF0C\u56DE\u590D\u843D\u5728\u8BDD\u9898\u5185\uFF1B\u6BCF\u4E2A\u8BDD\u9898\u662F dsh \u4F1A\u8BDD\u5217\u8868\u91CC\u4E00\u6761\u72EC\u7ACB\u4F1A\u8BDD\uFF0C\u4E0A\u4E0B\u6587\u4E92\u4E0D\u4E32\u3002\u79C1\u804A\u4E0D\u53D7\u5F71\u54CD\u3002"
|
|
6271
|
-
),
|
|
6272
|
-
error ? h2("p", {
|
|
6273
|
-
className: "bxf-responseModeError dim-responseModeError",
|
|
6274
|
-
role: "alert"
|
|
6275
|
-
}, error) : null
|
|
6276
|
-
);
|
|
6277
|
-
}
|
|
6278
6394
|
function BotCard({
|
|
6279
6395
|
connection,
|
|
6280
6396
|
busy,
|
|
@@ -6287,11 +6403,9 @@ function BotCard({
|
|
|
6287
6403
|
onReconnect,
|
|
6288
6404
|
onRepairCallback,
|
|
6289
6405
|
onWorkspaceSave,
|
|
6406
|
+
onModelSave,
|
|
6290
6407
|
onAgentPresetSave,
|
|
6291
6408
|
onContextEnhancementSave,
|
|
6292
|
-
onGroupResponseModeSave,
|
|
6293
|
-
onGroupTopicReplySave,
|
|
6294
|
-
onGroupMessagePermissionAuthorize,
|
|
6295
6409
|
onRequestRemove,
|
|
6296
6410
|
onConfirmRemove,
|
|
6297
6411
|
onCancelRemove,
|
|
@@ -6299,7 +6413,7 @@ function BotCard({
|
|
|
6299
6413
|
removeButtonRef
|
|
6300
6414
|
}) {
|
|
6301
6415
|
const { bot, health, state, connected } = connection;
|
|
6302
|
-
const repairTooltipId =
|
|
6416
|
+
const repairTooltipId = React14.useId();
|
|
6303
6417
|
const stateForDisplay = busy === "reconnect" ? "connecting" : state;
|
|
6304
6418
|
const tone = stateForDisplay === "connected" ? "success" : stateForDisplay === "connecting" ? "warning" : "error";
|
|
6305
6419
|
const summary2 = actionError?.message ?? connection.error?.message ?? (connected ? null : health.summary);
|
|
@@ -6351,7 +6465,12 @@ function BotCard({
|
|
|
6351
6465
|
botId: connection.botId,
|
|
6352
6466
|
botName: bot.name,
|
|
6353
6467
|
connected,
|
|
6354
|
-
accessPolicy: connection.accessPolicy
|
|
6468
|
+
accessPolicy: connection.accessPolicy,
|
|
6469
|
+
channelSettings: {
|
|
6470
|
+
groupResponseMode: connection.groupResponseMode,
|
|
6471
|
+
groupTopicReply: connection.groupTopicReply,
|
|
6472
|
+
groupMessagePermissionGranted: connection.groupMessagePermissionGranted
|
|
6473
|
+
}
|
|
6355
6474
|
})
|
|
6356
6475
|
)
|
|
6357
6476
|
),
|
|
@@ -6360,6 +6479,11 @@ function BotCard({
|
|
|
6360
6479
|
disabled: Boolean(busy),
|
|
6361
6480
|
onSave: onWorkspaceSave
|
|
6362
6481
|
}),
|
|
6482
|
+
h2(ModelEditor, {
|
|
6483
|
+
model: connection.model,
|
|
6484
|
+
disabled: Boolean(busy),
|
|
6485
|
+
onSave: onModelSave
|
|
6486
|
+
}),
|
|
6363
6487
|
h2(AgentPresetEditor, {
|
|
6364
6488
|
agentPreset: connection.agentPreset,
|
|
6365
6489
|
disabled: Boolean(busy),
|
|
@@ -6370,19 +6494,6 @@ function BotCard({
|
|
|
6370
6494
|
disabled: Boolean(busy),
|
|
6371
6495
|
onSave: onContextEnhancementSave
|
|
6372
6496
|
}),
|
|
6373
|
-
h2(GroupResponseModeEditor, {
|
|
6374
|
-
value: connection.groupResponseMode,
|
|
6375
|
-
permissionGranted: connection.groupMessagePermissionGranted,
|
|
6376
|
-
disabled: Boolean(busy),
|
|
6377
|
-
authorizationDisabled: repairDisabled,
|
|
6378
|
-
onSave: onGroupResponseModeSave,
|
|
6379
|
-
onAuthorize: onGroupMessagePermissionAuthorize
|
|
6380
|
-
}),
|
|
6381
|
-
h2(GroupTopicReplyEditor, {
|
|
6382
|
-
value: connection.groupTopicReply,
|
|
6383
|
-
disabled: Boolean(busy),
|
|
6384
|
-
onSave: onGroupTopicReplySave
|
|
6385
|
-
}),
|
|
6386
6497
|
provisionContent ? h2("section", {
|
|
6387
6498
|
className: "bxf-botProvision dim-botProvision",
|
|
6388
6499
|
"aria-label": `${bot.name}\u7684\u98DE\u4E66\u6388\u6743\u6D41\u7A0B`,
|
|
@@ -6489,11 +6600,9 @@ function BotList(props) {
|
|
|
6489
6600
|
onReconnect: () => props.onReconnect(bot),
|
|
6490
6601
|
onRepairCallback: () => props.onRepairCallback(bot),
|
|
6491
6602
|
onWorkspaceSave: (workspace) => props.onWorkspaceSave(bot, workspace),
|
|
6603
|
+
onModelSave: (model) => props.onModelSave(bot, model),
|
|
6492
6604
|
onAgentPresetSave: (agentPreset) => props.onAgentPresetSave(bot, agentPreset),
|
|
6493
6605
|
onContextEnhancementSave: (config) => props.onContextEnhancementSave(bot, config),
|
|
6494
|
-
onGroupResponseModeSave: (groupResponseMode) => props.onGroupResponseModeSave(bot, groupResponseMode),
|
|
6495
|
-
onGroupTopicReplySave: (groupTopicReply) => props.onGroupTopicReplySave(bot, groupTopicReply),
|
|
6496
|
-
onGroupMessagePermissionAuthorize: () => props.onGroupMessagePermissionAuthorize(bot),
|
|
6497
6606
|
onRequestRemove: () => props.onRequestRemove(bot),
|
|
6498
6607
|
onConfirmRemove: () => props.onConfirmRemove(bot),
|
|
6499
6608
|
onCancelRemove: props.onCancelRemove,
|
|
@@ -6552,11 +6661,12 @@ function mergeFeishuSnapshotState(current, snapshot, { restoreProvisioning = fal
|
|
|
6552
6661
|
provisioning,
|
|
6553
6662
|
pageError: null,
|
|
6554
6663
|
statusError: null,
|
|
6555
|
-
agentPresetCatalog: snapshot.agentPresetCatalog ?? current.agentPresetCatalog
|
|
6664
|
+
agentPresetCatalog: snapshot.agentPresetCatalog ?? current.agentPresetCatalog,
|
|
6665
|
+
modelCatalog: snapshot.modelCatalog ?? current.modelCatalog
|
|
6556
6666
|
};
|
|
6557
6667
|
}
|
|
6558
6668
|
function FeishuSettingsTab({ rpcCall }) {
|
|
6559
|
-
const [model, setModel] =
|
|
6669
|
+
const [model, setModel] = React14.useState({
|
|
6560
6670
|
phase: "loading",
|
|
6561
6671
|
revision: 0,
|
|
6562
6672
|
bots: [],
|
|
@@ -6564,43 +6674,44 @@ function FeishuSettingsTab({ rpcCall }) {
|
|
|
6564
6674
|
provisioning: null,
|
|
6565
6675
|
pageError: null,
|
|
6566
6676
|
statusError: null,
|
|
6567
|
-
agentPresetCatalog: EMPTY_AGENT_PRESET_CATALOG
|
|
6677
|
+
agentPresetCatalog: EMPTY_AGENT_PRESET_CATALOG,
|
|
6678
|
+
modelCatalog: EMPTY_MODEL_CATALOG
|
|
6568
6679
|
});
|
|
6569
|
-
const [pageBusy, setPageBusy] =
|
|
6570
|
-
const [provisionBusy, setProvisionBusy] =
|
|
6571
|
-
const [credentialOpen, setCredentialOpen] =
|
|
6572
|
-
const [credentialBusy, setCredentialBusy] =
|
|
6573
|
-
const [credentialError, setCredentialError] =
|
|
6574
|
-
const [busyByBot, setBusyByBot] =
|
|
6575
|
-
const [errorsByBot, setErrorsByBot] =
|
|
6576
|
-
const [testNoticesByBot, setTestNoticesByBot] =
|
|
6577
|
-
const [removeTargetId, setRemoveTargetId] =
|
|
6578
|
-
const [announcement, setAnnouncement] =
|
|
6579
|
-
const [now, setNow] =
|
|
6580
|
-
const [focusBotId, setFocusBotId] =
|
|
6581
|
-
const cardRefs =
|
|
6582
|
-
const removeButtonRefs =
|
|
6583
|
-
const targetedProvisionRef =
|
|
6584
|
-
const addButtonRef =
|
|
6585
|
-
const mountedRef =
|
|
6680
|
+
const [pageBusy, setPageBusy] = React14.useState(false);
|
|
6681
|
+
const [provisionBusy, setProvisionBusy] = React14.useState(false);
|
|
6682
|
+
const [credentialOpen, setCredentialOpen] = React14.useState(false);
|
|
6683
|
+
const [credentialBusy, setCredentialBusy] = React14.useState(false);
|
|
6684
|
+
const [credentialError, setCredentialError] = React14.useState(null);
|
|
6685
|
+
const [busyByBot, setBusyByBot] = React14.useState({});
|
|
6686
|
+
const [errorsByBot, setErrorsByBot] = React14.useState({});
|
|
6687
|
+
const [testNoticesByBot, setTestNoticesByBot] = React14.useState({});
|
|
6688
|
+
const [removeTargetId, setRemoveTargetId] = React14.useState(null);
|
|
6689
|
+
const [announcement, setAnnouncement] = React14.useState("");
|
|
6690
|
+
const [now, setNow] = React14.useState(() => Date.now());
|
|
6691
|
+
const [focusBotId, setFocusBotId] = React14.useState(null);
|
|
6692
|
+
const cardRefs = React14.useRef(/* @__PURE__ */ new Map());
|
|
6693
|
+
const removeButtonRefs = React14.useRef(/* @__PURE__ */ new Map());
|
|
6694
|
+
const targetedProvisionRef = React14.useRef(null);
|
|
6695
|
+
const addButtonRef = React14.useRef(null);
|
|
6696
|
+
const mountedRef = React14.useRef(true);
|
|
6586
6697
|
const workspaceFence = useWorkspaceSnapshotFence();
|
|
6587
6698
|
const scheduleAnimationFrame = useAnimationFrameScheduler();
|
|
6588
|
-
|
|
6699
|
+
React14.useEffect(() => {
|
|
6589
6700
|
mountedRef.current = true;
|
|
6590
6701
|
return () => {
|
|
6591
6702
|
mountedRef.current = false;
|
|
6592
6703
|
};
|
|
6593
6704
|
}, []);
|
|
6594
|
-
const announce =
|
|
6705
|
+
const announce = React14.useCallback((message) => {
|
|
6595
6706
|
setAnnouncement("");
|
|
6596
6707
|
scheduleAnimationFrame(() => {
|
|
6597
6708
|
if (message) setAnnouncement(message);
|
|
6598
6709
|
}, "announcement");
|
|
6599
6710
|
}, [scheduleAnimationFrame]);
|
|
6600
|
-
const invoke =
|
|
6711
|
+
const invoke = React14.useCallback(async (endpoint, payload = {}, signal) => {
|
|
6601
6712
|
return unwrapRpcResult3(await rpcCall(endpoint, payload, signal));
|
|
6602
6713
|
}, [rpcCall]);
|
|
6603
|
-
const mergeSnapshot =
|
|
6714
|
+
const mergeSnapshot = React14.useCallback((snapshot, { restoreProvisioning = false } = {}) => {
|
|
6604
6715
|
const now2 = Date.now();
|
|
6605
6716
|
setModel((current) => mergeFeishuSnapshotState(
|
|
6606
6717
|
current,
|
|
@@ -6608,7 +6719,7 @@ function FeishuSettingsTab({ rpcCall }) {
|
|
|
6608
6719
|
{ restoreProvisioning, now: now2 }
|
|
6609
6720
|
));
|
|
6610
6721
|
}, []);
|
|
6611
|
-
const loadStatus =
|
|
6722
|
+
const loadStatus = React14.useCallback(async ({ signal, silent = false, restoreProvisioning = false } = {}) => {
|
|
6612
6723
|
const workspaceVersion = workspaceFence.beginStatus();
|
|
6613
6724
|
if (workspaceVersion === null || !mountedRef.current) return void 0;
|
|
6614
6725
|
if (!silent) setPageBusy(true);
|
|
@@ -6626,12 +6737,12 @@ function FeishuSettingsTab({ rpcCall }) {
|
|
|
6626
6737
|
if (!silent && !signal?.aborted && mountedRef.current) setPageBusy(false);
|
|
6627
6738
|
}
|
|
6628
6739
|
}, [invoke, mergeSnapshot, workspaceFence]);
|
|
6629
|
-
|
|
6740
|
+
React14.useEffect(() => {
|
|
6630
6741
|
const controller = new AbortController();
|
|
6631
6742
|
void loadStatus({ signal: controller.signal, restoreProvisioning: true });
|
|
6632
6743
|
return () => controller.abort();
|
|
6633
6744
|
}, [loadStatus]);
|
|
6634
|
-
|
|
6745
|
+
React14.useEffect(() => {
|
|
6635
6746
|
if (model.phase !== "ready") return void 0;
|
|
6636
6747
|
const controller = new AbortController();
|
|
6637
6748
|
let inFlight = false;
|
|
@@ -6650,7 +6761,7 @@ function FeishuSettingsTab({ rpcCall }) {
|
|
|
6650
6761
|
window.clearInterval(timer);
|
|
6651
6762
|
};
|
|
6652
6763
|
}, [loadStatus, model.phase]);
|
|
6653
|
-
|
|
6764
|
+
React14.useEffect(() => {
|
|
6654
6765
|
if (!focusBotId) return;
|
|
6655
6766
|
const node = cardRefs.current.get(focusBotId);
|
|
6656
6767
|
if (!node) return;
|
|
@@ -6659,7 +6770,7 @@ function FeishuSettingsTab({ rpcCall }) {
|
|
|
6659
6770
|
setFocusBotId(null);
|
|
6660
6771
|
}, [focusBotId, model.bots]);
|
|
6661
6772
|
const targetedProvisionFocusKey = isTargetedAppUpdate2(model.provisioning) ? `${model.provisioning.botId}:${model.provisioning.attemptId ?? "preparing"}:${model.provisioning.phase}` : null;
|
|
6662
|
-
|
|
6773
|
+
React14.useEffect(() => {
|
|
6663
6774
|
if (!targetedProvisionFocusKey) return;
|
|
6664
6775
|
scheduleAnimationFrame(() => {
|
|
6665
6776
|
const node = targetedProvisionRef.current;
|
|
@@ -6668,7 +6779,7 @@ function FeishuSettingsTab({ rpcCall }) {
|
|
|
6668
6779
|
node.focus?.({ preventScroll: true });
|
|
6669
6780
|
}, "targeted-provision-focus");
|
|
6670
6781
|
}, [scheduleAnimationFrame, targetedProvisionFocusKey]);
|
|
6671
|
-
const startProvisioning =
|
|
6782
|
+
const startProvisioning = React14.useCallback(async ({
|
|
6672
6783
|
replace = false,
|
|
6673
6784
|
operation = FEISHU_REGISTRATION_OPERATIONS.PROVISION,
|
|
6674
6785
|
bot
|
|
@@ -6744,7 +6855,7 @@ function FeishuSettingsTab({ rpcCall }) {
|
|
|
6744
6855
|
model.provisioning?.botId,
|
|
6745
6856
|
model.provisioning?.botName
|
|
6746
6857
|
]);
|
|
6747
|
-
const bindCredentials =
|
|
6858
|
+
const bindCredentials = React14.useCallback(async ({ identity, secret }) => {
|
|
6748
6859
|
const snapshotVersion = workspaceFence.beginMutation();
|
|
6749
6860
|
setCredentialBusy(true);
|
|
6750
6861
|
setCredentialError(null);
|
|
@@ -6766,7 +6877,7 @@ function FeishuSettingsTab({ rpcCall }) {
|
|
|
6766
6877
|
setCredentialBusy(false);
|
|
6767
6878
|
}
|
|
6768
6879
|
}, [announce, invoke, loadStatus, mergeSnapshot, workspaceFence]);
|
|
6769
|
-
const cancelProvisioning =
|
|
6880
|
+
const cancelProvisioning = React14.useCallback(async () => {
|
|
6770
6881
|
const activeProvision = model.provisioning;
|
|
6771
6882
|
const attemptId = activeProvision?.attemptId;
|
|
6772
6883
|
const repairing = isCallbackRepair(activeProvision);
|
|
@@ -6831,7 +6942,7 @@ function FeishuSettingsTab({ rpcCall }) {
|
|
|
6831
6942
|
const countdownPhase = model.provisioning?.phase;
|
|
6832
6943
|
const countdownExpiresAt = model.provisioning?.expiresAt;
|
|
6833
6944
|
const countdownExpired = model.provisioning?.expired;
|
|
6834
|
-
|
|
6945
|
+
React14.useEffect(() => {
|
|
6835
6946
|
if (!countdownAttemptId || countdownPhase !== "qr" || countdownExpired) return void 0;
|
|
6836
6947
|
const tick = () => {
|
|
6837
6948
|
const timestamp7 = Date.now();
|
|
@@ -6844,7 +6955,7 @@ function FeishuSettingsTab({ rpcCall }) {
|
|
|
6844
6955
|
const timer = window.setInterval(tick, 1e3);
|
|
6845
6956
|
return () => window.clearInterval(timer);
|
|
6846
6957
|
}, [countdownAttemptId, countdownPhase, countdownExpiresAt, countdownExpired]);
|
|
6847
|
-
|
|
6958
|
+
React14.useEffect(() => {
|
|
6848
6959
|
const provision2 = model.provisioning;
|
|
6849
6960
|
if (!provision2 || !["qr", "connecting"].includes(provision2.phase) || !provision2.attemptId || provision2.expired) return void 0;
|
|
6850
6961
|
const controller = new AbortController();
|
|
@@ -6912,7 +7023,7 @@ function FeishuSettingsTab({ rpcCall }) {
|
|
|
6912
7023
|
window.clearTimeout(timer);
|
|
6913
7024
|
};
|
|
6914
7025
|
}, [announce, invoke, loadStatus, model.provisioning]);
|
|
6915
|
-
const setBotBusy =
|
|
7026
|
+
const setBotBusy = React14.useCallback((botId, value) => {
|
|
6916
7027
|
setBusyByBot((current) => {
|
|
6917
7028
|
const next = { ...current };
|
|
6918
7029
|
if (value) next[botId] = value;
|
|
@@ -6920,7 +7031,7 @@ function FeishuSettingsTab({ rpcCall }) {
|
|
|
6920
7031
|
return next;
|
|
6921
7032
|
});
|
|
6922
7033
|
}, []);
|
|
6923
|
-
const setBotError =
|
|
7034
|
+
const setBotError = React14.useCallback((botId, error) => {
|
|
6924
7035
|
setErrorsByBot((current) => {
|
|
6925
7036
|
const next = { ...current };
|
|
6926
7037
|
if (error) next[botId] = presentError3(error);
|
|
@@ -6928,7 +7039,7 @@ function FeishuSettingsTab({ rpcCall }) {
|
|
|
6928
7039
|
return next;
|
|
6929
7040
|
});
|
|
6930
7041
|
}, []);
|
|
6931
|
-
const repairCallback =
|
|
7042
|
+
const repairCallback = React14.useCallback((connection) => {
|
|
6932
7043
|
if (model.provisioning) return;
|
|
6933
7044
|
setRemoveTargetId(null);
|
|
6934
7045
|
setBotError(connection.botId, null);
|
|
@@ -6942,7 +7053,7 @@ function FeishuSettingsTab({ rpcCall }) {
|
|
|
6942
7053
|
bot: connection
|
|
6943
7054
|
});
|
|
6944
7055
|
}, [model.provisioning, setBotError, startProvisioning]);
|
|
6945
|
-
const reconnectOneBot =
|
|
7056
|
+
const reconnectOneBot = React14.useCallback(async (connection) => {
|
|
6946
7057
|
const { botId, bot } = connection;
|
|
6947
7058
|
const snapshotVersion = workspaceFence.beginMutation();
|
|
6948
7059
|
setBotBusy(botId, "reconnect");
|
|
@@ -6982,7 +7093,7 @@ function FeishuSettingsTab({ rpcCall }) {
|
|
|
6982
7093
|
setBotBusy(botId, null);
|
|
6983
7094
|
}
|
|
6984
7095
|
}, [announce, invoke, loadStatus, mergeSnapshot, setBotBusy, setBotError, workspaceFence]);
|
|
6985
|
-
const saveWorkspace =
|
|
7096
|
+
const saveWorkspace = React14.useCallback(async (connection, workspace) => {
|
|
6986
7097
|
const { botId } = connection;
|
|
6987
7098
|
const workspaceVersion = workspaceFence.beginMutation();
|
|
6988
7099
|
setBotBusy(botId, "workspace");
|
|
@@ -7001,7 +7112,7 @@ function FeishuSettingsTab({ rpcCall }) {
|
|
|
7001
7112
|
if (mountedRef.current) setBotBusy(botId, null);
|
|
7002
7113
|
}
|
|
7003
7114
|
}, [invoke, loadStatus, mergeSnapshot, setBotBusy, setBotError, workspaceFence]);
|
|
7004
|
-
const saveBotSetting =
|
|
7115
|
+
const saveBotSetting = React14.useCallback(async (connection, operation, endpoint, payload) => {
|
|
7005
7116
|
const { botId } = connection;
|
|
7006
7117
|
const snapshotVersion = workspaceFence.beginMutation();
|
|
7007
7118
|
setBotBusy(botId, operation);
|
|
@@ -7020,63 +7131,15 @@ function FeishuSettingsTab({ rpcCall }) {
|
|
|
7020
7131
|
if (mountedRef.current) setBotBusy(botId, null);
|
|
7021
7132
|
}
|
|
7022
7133
|
}, [invoke, loadStatus, mergeSnapshot, setBotBusy, setBotError, workspaceFence]);
|
|
7023
|
-
const
|
|
7024
|
-
const { botId } = connection;
|
|
7025
|
-
if (model.provisioning) {
|
|
7026
|
-
throw new Error("\u8BF7\u5148\u5B8C\u6210\u5F53\u524D\u98DE\u4E66\u6388\u6743\u64CD\u4F5C\uFF0C\u518D\u5F00\u901A\u7FA4\u6D88\u606F\u6743\u9650\u3002");
|
|
7027
|
-
}
|
|
7028
|
-
setRemoveTargetId(null);
|
|
7029
|
-
setBotError(botId, null);
|
|
7030
|
-
setTestNoticesByBot((current) => {
|
|
7031
|
-
const next = { ...current };
|
|
7032
|
-
delete next[botId];
|
|
7033
|
-
return next;
|
|
7034
|
-
});
|
|
7035
|
-
await startProvisioning({
|
|
7036
|
-
operation: GROUP_MESSAGE_PERMISSION_OPERATION,
|
|
7037
|
-
bot: connection
|
|
7038
|
-
});
|
|
7039
|
-
}, [model.provisioning, setBotError, startProvisioning]);
|
|
7040
|
-
const saveGroupResponseMode = React13.useCallback(async (connection, groupResponseMode) => {
|
|
7041
|
-
const { botId } = connection;
|
|
7042
|
-
if (groupResponseMode === "all" && connection.groupMessagePermissionGranted !== true) {
|
|
7043
|
-
await authorizeGroupMessages(connection);
|
|
7044
|
-
return;
|
|
7045
|
-
}
|
|
7046
|
-
const snapshotVersion = workspaceFence.beginMutation();
|
|
7047
|
-
setBotBusy(botId, "group-response-mode");
|
|
7048
|
-
setBotError(botId, null);
|
|
7049
|
-
try {
|
|
7050
|
-
const snapshot = normalizeBotsSnapshot(await invoke(
|
|
7051
|
-
FEISHU_ENDPOINTS.setGroupResponseMode,
|
|
7052
|
-
{ botId, groupResponseMode }
|
|
7053
|
-
));
|
|
7054
|
-
if (mountedRef.current && workspaceFence.canCommitMutation(snapshotVersion)) {
|
|
7055
|
-
mergeSnapshot(snapshot);
|
|
7056
|
-
}
|
|
7057
|
-
} finally {
|
|
7058
|
-
const shouldRefresh = workspaceFence.endMutation();
|
|
7059
|
-
if (shouldRefresh && mountedRef.current) void loadStatus({ silent: true });
|
|
7060
|
-
if (mountedRef.current) setBotBusy(botId, null);
|
|
7061
|
-
}
|
|
7062
|
-
}, [
|
|
7063
|
-
invoke,
|
|
7064
|
-
authorizeGroupMessages,
|
|
7065
|
-
loadStatus,
|
|
7066
|
-
mergeSnapshot,
|
|
7067
|
-
setBotBusy,
|
|
7068
|
-
setBotError,
|
|
7069
|
-
workspaceFence
|
|
7070
|
-
]);
|
|
7071
|
-
const requestRemove = React13.useCallback((connection) => {
|
|
7134
|
+
const requestRemove = React14.useCallback((connection) => {
|
|
7072
7135
|
setRemoveTargetId(connection.botId);
|
|
7073
7136
|
}, []);
|
|
7074
|
-
const cancelRemove =
|
|
7137
|
+
const cancelRemove = React14.useCallback(() => {
|
|
7075
7138
|
const botId = removeTargetId;
|
|
7076
7139
|
setRemoveTargetId(null);
|
|
7077
7140
|
scheduleAnimationFrame(() => removeButtonRefs.current.get(botId)?.focus(), "focus");
|
|
7078
7141
|
}, [removeTargetId, scheduleAnimationFrame]);
|
|
7079
|
-
const confirmRemove =
|
|
7142
|
+
const confirmRemove = React14.useCallback(async (connection) => {
|
|
7080
7143
|
const { botId, bot } = connection;
|
|
7081
7144
|
const snapshotVersion = workspaceFence.beginMutation();
|
|
7082
7145
|
setBotBusy(botId, "delete");
|
|
@@ -7162,15 +7225,17 @@ function FeishuSettingsTab({ rpcCall }) {
|
|
|
7162
7225
|
setCredentialError(null);
|
|
7163
7226
|
}
|
|
7164
7227
|
}) : null;
|
|
7165
|
-
const setCardRef =
|
|
7228
|
+
const setCardRef = React14.useCallback((botId, node) => {
|
|
7166
7229
|
if (node) cardRefs.current.set(botId, node);
|
|
7167
7230
|
else cardRefs.current.delete(botId);
|
|
7168
7231
|
}, []);
|
|
7169
|
-
const setRemoveButtonRef =
|
|
7232
|
+
const setRemoveButtonRef = React14.useCallback((botId, node) => {
|
|
7170
7233
|
if (node) removeButtonRefs.current.set(botId, node);
|
|
7171
7234
|
else removeButtonRefs.current.delete(botId);
|
|
7172
7235
|
}, []);
|
|
7173
|
-
return h2(
|
|
7236
|
+
return h2(ModelCatalogContext.Provider, {
|
|
7237
|
+
value: model.modelCatalog ?? EMPTY_MODEL_CATALOG
|
|
7238
|
+
}, h2(AgentPresetCatalogContext.Provider, {
|
|
7174
7239
|
value: model.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG
|
|
7175
7240
|
}, h2(
|
|
7176
7241
|
"section",
|
|
@@ -7205,7 +7270,7 @@ function FeishuSettingsTab({ rpcCall }) {
|
|
|
7205
7270
|
onRetry: () => void loadStatus(),
|
|
7206
7271
|
busy: pageBusy
|
|
7207
7272
|
}) : h2(
|
|
7208
|
-
|
|
7273
|
+
React14.Fragment,
|
|
7209
7274
|
null,
|
|
7210
7275
|
credentialContent,
|
|
7211
7276
|
targetedProvisioning ? null : provisionContent,
|
|
@@ -7222,6 +7287,12 @@ function FeishuSettingsTab({ rpcCall }) {
|
|
|
7222
7287
|
onReconnect: (bot) => void reconnectOneBot(bot),
|
|
7223
7288
|
onRepairCallback: repairCallback,
|
|
7224
7289
|
onWorkspaceSave: saveWorkspace,
|
|
7290
|
+
onModelSave: (connection, selectedModel) => saveBotSetting(
|
|
7291
|
+
connection,
|
|
7292
|
+
"model",
|
|
7293
|
+
FEISHU_ENDPOINTS.setModel,
|
|
7294
|
+
{ model: selectedModel }
|
|
7295
|
+
),
|
|
7225
7296
|
onAgentPresetSave: (connection, agentPreset) => saveBotSetting(
|
|
7226
7297
|
connection,
|
|
7227
7298
|
"preset",
|
|
@@ -7234,14 +7305,6 @@ function FeishuSettingsTab({ rpcCall }) {
|
|
|
7234
7305
|
FEISHU_ENDPOINTS.setContextEnhancement,
|
|
7235
7306
|
{ config }
|
|
7236
7307
|
),
|
|
7237
|
-
onGroupResponseModeSave: saveGroupResponseMode,
|
|
7238
|
-
onGroupTopicReplySave: (connection, groupTopicReply) => saveBotSetting(
|
|
7239
|
-
connection,
|
|
7240
|
-
"group-topic-reply",
|
|
7241
|
-
FEISHU_ENDPOINTS.setGroupTopicReply,
|
|
7242
|
-
{ groupTopicReply }
|
|
7243
|
-
),
|
|
7244
|
-
onGroupMessagePermissionAuthorize: authorizeGroupMessages,
|
|
7245
7308
|
onRequestRemove: requestRemove,
|
|
7246
7309
|
onConfirmRemove: (bot) => void confirmRemove(bot),
|
|
7247
7310
|
onCancelRemove: cancelRemove,
|
|
@@ -7249,7 +7312,7 @@ function FeishuSettingsTab({ rpcCall }) {
|
|
|
7249
7312
|
setRemoveButtonRef
|
|
7250
7313
|
}) : null
|
|
7251
7314
|
)
|
|
7252
|
-
));
|
|
7315
|
+
)));
|
|
7253
7316
|
}
|
|
7254
7317
|
|
|
7255
7318
|
// plugin-src/client/channels/feishu/styles.js
|
|
@@ -7835,6 +7898,7 @@ var QQ_ENDPOINTS = Object.freeze({
|
|
|
7835
7898
|
reconnectBot: "bot.reconnect",
|
|
7836
7899
|
deleteBot: "bot.delete",
|
|
7837
7900
|
setWorkspace: "bot.workspace.set",
|
|
7901
|
+
setModel: SET_MODEL_ENDPOINT,
|
|
7838
7902
|
setAgentPreset: SET_AGENT_PRESET_ENDPOINT,
|
|
7839
7903
|
setContextEnhancement: "bot.context-enhancement.set",
|
|
7840
7904
|
setAccessPolicy: "bot.access-policy.set"
|
|
@@ -7901,6 +7965,7 @@ function normalizeBot3(value) {
|
|
|
7901
7965
|
connected,
|
|
7902
7966
|
state: connected ? "connected" : state,
|
|
7903
7967
|
workspace: text3(value.workspace, "", 4096),
|
|
7968
|
+
model: normalizeModelSelection(value.model),
|
|
7904
7969
|
agentPreset: normalizeAgentPresetId(value.agentPreset),
|
|
7905
7970
|
contextEnhancement: normalizeContextEnhancementConfig(value.contextEnhancement),
|
|
7906
7971
|
...Object.hasOwn(value, "accessPolicy") ? { accessPolicy: normalizeAccessPolicy(value.accessPolicy) } : {},
|
|
@@ -7939,6 +8004,7 @@ function normalizeSnapshot3(value) {
|
|
|
7939
8004
|
totals: { configured: bots.length, connected: bots.filter((bot) => bot.connected).length },
|
|
7940
8005
|
provisioning: source.provisioning ? normalizeProvisioning3(source.provisioning) : null,
|
|
7941
8006
|
agentPresetCatalog: normalizeAgentPresetCatalog(source.agentPresetCatalog),
|
|
8007
|
+
modelCatalog: normalizeModelCatalog(source.modelCatalog),
|
|
7942
8008
|
...testMessage ? { testMessage } : {}
|
|
7943
8009
|
};
|
|
7944
8010
|
}
|
|
@@ -7961,7 +8027,7 @@ function formatRemaining3(milliseconds) {
|
|
|
7961
8027
|
}
|
|
7962
8028
|
|
|
7963
8029
|
// plugin-src/client/channels/qq/index.js
|
|
7964
|
-
var
|
|
8030
|
+
var React15 = __toESM(require("react"), 1);
|
|
7965
8031
|
|
|
7966
8032
|
// plugin-src/client/channels/qq/styles.js
|
|
7967
8033
|
var QQ_STYLE_ID = "xmanrui-dsh-im-qq-settings";
|
|
@@ -7986,7 +8052,7 @@ function installQqStyles() {
|
|
|
7986
8052
|
|
|
7987
8053
|
// plugin-src/client/channels/qq/index.js
|
|
7988
8054
|
var ACTIVE_STATES = /* @__PURE__ */ new Set(["pending", "refreshing", "connecting"]);
|
|
7989
|
-
var Button7 =
|
|
8055
|
+
var Button7 = React15.forwardRef(function Button8({ children, kind = "secondary", className = "", ...props }, ref) {
|
|
7990
8056
|
return h2("button", {
|
|
7991
8057
|
...props,
|
|
7992
8058
|
ref,
|
|
@@ -8200,6 +8266,7 @@ function AccountCard2({
|
|
|
8200
8266
|
removing,
|
|
8201
8267
|
onReconnect,
|
|
8202
8268
|
onWorkspaceSave,
|
|
8269
|
+
onModelSave,
|
|
8203
8270
|
onAgentPresetSave,
|
|
8204
8271
|
onContextEnhancementSave,
|
|
8205
8272
|
onRequestRemove,
|
|
@@ -8254,6 +8321,11 @@ function AccountCard2({
|
|
|
8254
8321
|
disabled: Boolean(busy),
|
|
8255
8322
|
onSave: onWorkspaceSave
|
|
8256
8323
|
}),
|
|
8324
|
+
h2(ModelEditor, {
|
|
8325
|
+
model: account.model,
|
|
8326
|
+
disabled: Boolean(busy),
|
|
8327
|
+
onSave: onModelSave
|
|
8328
|
+
}),
|
|
8257
8329
|
h2(AgentPresetEditor, {
|
|
8258
8330
|
agentPreset: account.agentPreset,
|
|
8259
8331
|
disabled: Boolean(busy),
|
|
@@ -8298,25 +8370,26 @@ function AccountCard2({
|
|
|
8298
8370
|
);
|
|
8299
8371
|
}
|
|
8300
8372
|
function QqSettingsTab({ rpcCall }) {
|
|
8301
|
-
const [model, setModel] =
|
|
8373
|
+
const [model, setModel] = React15.useState({
|
|
8302
8374
|
phase: "loading",
|
|
8303
8375
|
bots: [],
|
|
8304
8376
|
totals: { configured: 0, connected: 0 },
|
|
8305
8377
|
error: null,
|
|
8306
|
-
agentPresetCatalog: EMPTY_AGENT_PRESET_CATALOG
|
|
8378
|
+
agentPresetCatalog: EMPTY_AGENT_PRESET_CATALOG,
|
|
8379
|
+
modelCatalog: EMPTY_MODEL_CATALOG
|
|
8307
8380
|
});
|
|
8308
|
-
const [provision, setProvision] =
|
|
8309
|
-
const [busy, setBusy] =
|
|
8310
|
-
const [busyByBot, setBusyByBot] =
|
|
8311
|
-
const [feedbackByBot, setFeedbackByBot] =
|
|
8312
|
-
const [removeTarget, setRemoveTarget] =
|
|
8313
|
-
const [credentialOpen, setCredentialOpen] =
|
|
8314
|
-
const [credentialError, setCredentialError] =
|
|
8315
|
-
const [now, setNow] =
|
|
8316
|
-
const mounted =
|
|
8381
|
+
const [provision, setProvision] = React15.useState(null);
|
|
8382
|
+
const [busy, setBusy] = React15.useState(false);
|
|
8383
|
+
const [busyByBot, setBusyByBot] = React15.useState({});
|
|
8384
|
+
const [feedbackByBot, setFeedbackByBot] = React15.useState({});
|
|
8385
|
+
const [removeTarget, setRemoveTarget] = React15.useState(null);
|
|
8386
|
+
const [credentialOpen, setCredentialOpen] = React15.useState(false);
|
|
8387
|
+
const [credentialError, setCredentialError] = React15.useState(null);
|
|
8388
|
+
const [now, setNow] = React15.useState(Date.now());
|
|
8389
|
+
const mounted = React15.useRef(true);
|
|
8317
8390
|
const workspaceFence = useWorkspaceSnapshotFence();
|
|
8318
|
-
const addButtonRef =
|
|
8319
|
-
|
|
8391
|
+
const addButtonRef = React15.useRef(null);
|
|
8392
|
+
React15.useEffect(() => {
|
|
8320
8393
|
const disposeDingtalk = installDingtalkStyles();
|
|
8321
8394
|
const disposeQq = installQqStyles();
|
|
8322
8395
|
mounted.current = true;
|
|
@@ -8326,11 +8399,11 @@ function QqSettingsTab({ rpcCall }) {
|
|
|
8326
8399
|
disposeDingtalk();
|
|
8327
8400
|
};
|
|
8328
8401
|
}, []);
|
|
8329
|
-
const invoke =
|
|
8402
|
+
const invoke = React15.useCallback(async (endpoint, payload = {}, signal) => {
|
|
8330
8403
|
if (typeof rpcCall !== "function") throw new TypeError("QQ \u8BBE\u7F6E\u9875\u7F3A\u5C11 RPC \u8FDE\u63A5");
|
|
8331
8404
|
return unwrapRpcResult4(await rpcCall(endpoint, payload, signal));
|
|
8332
8405
|
}, [rpcCall]);
|
|
8333
|
-
const loadStatus =
|
|
8406
|
+
const loadStatus = React15.useCallback(async ({ signal, silent = false, restore = false } = {}) => {
|
|
8334
8407
|
const workspaceVersion = workspaceFence.beginStatus();
|
|
8335
8408
|
if (workspaceVersion === null) return void 0;
|
|
8336
8409
|
if (!silent && mounted.current) setModel((current) => ({ ...current, phase: "loading", error: null }));
|
|
@@ -8342,7 +8415,8 @@ function QqSettingsTab({ rpcCall }) {
|
|
|
8342
8415
|
bots: snapshot.bots,
|
|
8343
8416
|
totals: snapshot.totals,
|
|
8344
8417
|
error: null,
|
|
8345
|
-
agentPresetCatalog: snapshot.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG
|
|
8418
|
+
agentPresetCatalog: snapshot.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG,
|
|
8419
|
+
modelCatalog: snapshot.modelCatalog ?? EMPTY_MODEL_CATALOG
|
|
8346
8420
|
});
|
|
8347
8421
|
if (restore && snapshot.provisioning) setProvision({
|
|
8348
8422
|
...snapshot.provisioning,
|
|
@@ -8356,12 +8430,12 @@ function QqSettingsTab({ rpcCall }) {
|
|
|
8356
8430
|
return void 0;
|
|
8357
8431
|
}
|
|
8358
8432
|
}, [invoke, workspaceFence]);
|
|
8359
|
-
|
|
8433
|
+
React15.useEffect(() => {
|
|
8360
8434
|
const controller = new AbortController();
|
|
8361
8435
|
void loadStatus({ signal: controller.signal, restore: true });
|
|
8362
8436
|
return () => controller.abort();
|
|
8363
8437
|
}, [loadStatus]);
|
|
8364
|
-
|
|
8438
|
+
React15.useEffect(() => {
|
|
8365
8439
|
if (model.phase !== "ready") return void 0;
|
|
8366
8440
|
const controller = new AbortController();
|
|
8367
8441
|
const timer = window.setInterval(() => void loadStatus({ signal: controller.signal, silent: true }), 15e3);
|
|
@@ -8370,12 +8444,12 @@ function QqSettingsTab({ rpcCall }) {
|
|
|
8370
8444
|
window.clearInterval(timer);
|
|
8371
8445
|
};
|
|
8372
8446
|
}, [loadStatus, model.phase]);
|
|
8373
|
-
|
|
8447
|
+
React15.useEffect(() => {
|
|
8374
8448
|
if (!provision || !ACTIVE_STATES.has(provision.status)) return void 0;
|
|
8375
8449
|
const timer = window.setInterval(() => mounted.current && setNow(Date.now()), 1e3);
|
|
8376
8450
|
return () => window.clearInterval(timer);
|
|
8377
8451
|
}, [provision?.attemptId, provision?.status]);
|
|
8378
|
-
const startProvisioning =
|
|
8452
|
+
const startProvisioning = React15.useCallback(async (replace = false) => {
|
|
8379
8453
|
setCredentialOpen(false);
|
|
8380
8454
|
setCredentialError(null);
|
|
8381
8455
|
setBusy(true);
|
|
@@ -8393,7 +8467,7 @@ function QqSettingsTab({ rpcCall }) {
|
|
|
8393
8467
|
if (mounted.current) setBusy(false);
|
|
8394
8468
|
}
|
|
8395
8469
|
}, [invoke, provision?.attemptId]);
|
|
8396
|
-
const bindCredentials =
|
|
8470
|
+
const bindCredentials = React15.useCallback(async ({ identity, secret }) => {
|
|
8397
8471
|
const snapshotVersion = workspaceFence.beginMutation();
|
|
8398
8472
|
setBusy(true);
|
|
8399
8473
|
setCredentialError(null);
|
|
@@ -8409,7 +8483,8 @@ function QqSettingsTab({ rpcCall }) {
|
|
|
8409
8483
|
bots: snapshot.bots,
|
|
8410
8484
|
totals: snapshot.totals,
|
|
8411
8485
|
error: null,
|
|
8412
|
-
agentPresetCatalog: snapshot.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG
|
|
8486
|
+
agentPresetCatalog: snapshot.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG,
|
|
8487
|
+
modelCatalog: snapshot.modelCatalog ?? EMPTY_MODEL_CATALOG
|
|
8413
8488
|
});
|
|
8414
8489
|
}
|
|
8415
8490
|
setCredentialOpen(false);
|
|
@@ -8421,7 +8496,7 @@ function QqSettingsTab({ rpcCall }) {
|
|
|
8421
8496
|
if (mounted.current) setBusy(false);
|
|
8422
8497
|
}
|
|
8423
8498
|
}, [invoke, loadStatus, workspaceFence]);
|
|
8424
|
-
const closeProvision =
|
|
8499
|
+
const closeProvision = React15.useCallback(async () => {
|
|
8425
8500
|
setBusy(true);
|
|
8426
8501
|
try {
|
|
8427
8502
|
if (provision?.attemptId && ACTIVE_STATES.has(provision.status)) {
|
|
@@ -8432,7 +8507,7 @@ function QqSettingsTab({ rpcCall }) {
|
|
|
8432
8507
|
if (mounted.current) setBusy(false);
|
|
8433
8508
|
}
|
|
8434
8509
|
}, [invoke, provision?.attemptId, provision?.status]);
|
|
8435
|
-
|
|
8510
|
+
React15.useEffect(() => {
|
|
8436
8511
|
const attemptId = provision?.attemptId;
|
|
8437
8512
|
if (!attemptId || !ACTIVE_STATES.has(provision.status)) return void 0;
|
|
8438
8513
|
const controller = new AbortController();
|
|
@@ -8462,7 +8537,7 @@ function QqSettingsTab({ rpcCall }) {
|
|
|
8462
8537
|
window.clearTimeout(timer);
|
|
8463
8538
|
};
|
|
8464
8539
|
}, [invoke, loadStatus, provision?.attemptId, provision?.pollIntervalMs, provision?.status]);
|
|
8465
|
-
const botAction =
|
|
8540
|
+
const botAction = React15.useCallback(async (account, operation, endpoint, payload) => {
|
|
8466
8541
|
const snapshotVersion = workspaceFence.beginMutation();
|
|
8467
8542
|
setBusyByBot((current) => ({ ...current, [account.botId]: operation }));
|
|
8468
8543
|
try {
|
|
@@ -8473,7 +8548,8 @@ function QqSettingsTab({ rpcCall }) {
|
|
|
8473
8548
|
bots: snapshot.bots,
|
|
8474
8549
|
totals: snapshot.totals,
|
|
8475
8550
|
error: null,
|
|
8476
|
-
agentPresetCatalog: snapshot.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG
|
|
8551
|
+
agentPresetCatalog: snapshot.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG,
|
|
8552
|
+
modelCatalog: snapshot.modelCatalog ?? EMPTY_MODEL_CATALOG
|
|
8477
8553
|
});
|
|
8478
8554
|
}
|
|
8479
8555
|
return snapshot;
|
|
@@ -8487,7 +8563,7 @@ function QqSettingsTab({ rpcCall }) {
|
|
|
8487
8563
|
});
|
|
8488
8564
|
}
|
|
8489
8565
|
}, [invoke, loadStatus, workspaceFence]);
|
|
8490
|
-
const reconnect =
|
|
8566
|
+
const reconnect = React15.useCallback(async (account) => {
|
|
8491
8567
|
setFeedbackByBot((current) => {
|
|
8492
8568
|
const next = { ...current };
|
|
8493
8569
|
delete next[account.botId];
|
|
@@ -8550,6 +8626,12 @@ function QqSettingsTab({ rpcCall }) {
|
|
|
8550
8626
|
QQ_ENDPOINTS.setWorkspace,
|
|
8551
8627
|
{ botId: account.botId, workspace }
|
|
8552
8628
|
),
|
|
8629
|
+
onModelSave: (selectedModel) => botAction(
|
|
8630
|
+
account,
|
|
8631
|
+
"model",
|
|
8632
|
+
QQ_ENDPOINTS.setModel,
|
|
8633
|
+
{ botId: account.botId, model: selectedModel }
|
|
8634
|
+
),
|
|
8553
8635
|
onAgentPresetSave: (agentPreset) => botAction(
|
|
8554
8636
|
account,
|
|
8555
8637
|
"preset",
|
|
@@ -8584,7 +8666,9 @@ function QqSettingsTab({ rpcCall }) {
|
|
|
8584
8666
|
setCredentialError(null);
|
|
8585
8667
|
}
|
|
8586
8668
|
}) : null;
|
|
8587
|
-
return h2(
|
|
8669
|
+
return h2(ModelCatalogContext.Provider, {
|
|
8670
|
+
value: model.modelCatalog ?? EMPTY_MODEL_CATALOG
|
|
8671
|
+
}, h2(AgentPresetCatalogContext.Provider, {
|
|
8588
8672
|
value: model.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG
|
|
8589
8673
|
}, h2(
|
|
8590
8674
|
"section",
|
|
@@ -8602,14 +8686,14 @@ function QqSettingsTab({ rpcCall }) {
|
|
|
8602
8686
|
addButtonRef
|
|
8603
8687
|
}),
|
|
8604
8688
|
model.phase === "loading" ? h2(LoadingView3) : model.phase === "error" ? h2("div", { className: "ddt-card dim-surfaceCard" }, h2("div", { className: "ddt-inlineError dim-inlineError" }, h2("h3", null, "\u65E0\u6CD5\u8BFB\u53D6 QQ \u673A\u5668\u4EBA\u72B6\u6001"), h2("p", null, model.error?.message), h2(Button7, { onClick: () => void loadStatus() }, "\u91CD\u65B0\u8BFB\u53D6"))) : h2(
|
|
8605
|
-
|
|
8689
|
+
React15.Fragment,
|
|
8606
8690
|
null,
|
|
8607
8691
|
credentialView,
|
|
8608
8692
|
provisionView,
|
|
8609
8693
|
model.bots.length === 0 && !provision && !credentialOpen ? h2(EmptyView3, { busy, onStart: () => void startProvisioning() }) : null,
|
|
8610
8694
|
botList
|
|
8611
8695
|
)
|
|
8612
|
-
));
|
|
8696
|
+
)));
|
|
8613
8697
|
}
|
|
8614
8698
|
|
|
8615
8699
|
// src/channels/office/protocol.mjs
|
|
@@ -8691,7 +8775,7 @@ function normalizeOfficeStatus(value) {
|
|
|
8691
8775
|
}
|
|
8692
8776
|
|
|
8693
8777
|
// plugin-src/client/channels/office/index.js
|
|
8694
|
-
var
|
|
8778
|
+
var React16 = __toESM(require("react"), 1);
|
|
8695
8779
|
function Button9({ children, kind = "secondary", ...props }) {
|
|
8696
8780
|
return h2("button", { ...props, type: "button", className: "ddt-button", "data-kind": kind }, children);
|
|
8697
8781
|
}
|
|
@@ -8720,12 +8804,12 @@ function stateLabel(model) {
|
|
|
8720
8804
|
return "\u5DF2\u914D\u7F6E";
|
|
8721
8805
|
}
|
|
8722
8806
|
function OfficeSettingsTab({ rpcCall, initialStatus }) {
|
|
8723
|
-
const [model, setModel] =
|
|
8724
|
-
const [phase, setPhase] =
|
|
8725
|
-
const [busy, setBusy] =
|
|
8726
|
-
const [error, setError] =
|
|
8727
|
-
const [notice, setNotice] =
|
|
8728
|
-
const [form, setForm] =
|
|
8807
|
+
const [model, setModel] = React16.useState(normalizeOfficeStatus(initialStatus));
|
|
8808
|
+
const [phase, setPhase] = React16.useState(initialStatus === void 0 ? "loading" : "ready");
|
|
8809
|
+
const [busy, setBusy] = React16.useState("");
|
|
8810
|
+
const [error, setError] = React16.useState("");
|
|
8811
|
+
const [notice, setNotice] = React16.useState("");
|
|
8812
|
+
const [form, setForm] = React16.useState({
|
|
8729
8813
|
baseUrl: "",
|
|
8730
8814
|
deviceId: "local-harness",
|
|
8731
8815
|
deviceToken: "",
|
|
@@ -8734,11 +8818,11 @@ function OfficeSettingsTab({ rpcCall, initialStatus }) {
|
|
|
8734
8818
|
workspaces: "",
|
|
8735
8819
|
instructionPresets: ""
|
|
8736
8820
|
});
|
|
8737
|
-
const invoke =
|
|
8821
|
+
const invoke = React16.useCallback(async (endpoint, payload = {}) => {
|
|
8738
8822
|
if (typeof rpcCall !== "function") throw new Error("AI Office \u8BBE\u7F6E\u9875\u7F3A\u5C11 RPC \u8FDE\u63A5");
|
|
8739
8823
|
return unwrapOfficeRpc(await rpcCall(endpoint, payload));
|
|
8740
8824
|
}, [rpcCall]);
|
|
8741
|
-
const adopt =
|
|
8825
|
+
const adopt = React16.useCallback((value) => {
|
|
8742
8826
|
const next = normalizeOfficeStatus(value?.snapshot ?? value);
|
|
8743
8827
|
setModel(next);
|
|
8744
8828
|
if (next.config) setForm((current) => ({
|
|
@@ -8753,7 +8837,7 @@ function OfficeSettingsTab({ rpcCall, initialStatus }) {
|
|
|
8753
8837
|
}));
|
|
8754
8838
|
return next;
|
|
8755
8839
|
}, []);
|
|
8756
|
-
const load =
|
|
8840
|
+
const load = React16.useCallback(async () => {
|
|
8757
8841
|
try {
|
|
8758
8842
|
adopt(await invoke(OFFICE_RPC_ENDPOINTS.status));
|
|
8759
8843
|
setPhase("ready");
|
|
@@ -8763,7 +8847,7 @@ function OfficeSettingsTab({ rpcCall, initialStatus }) {
|
|
|
8763
8847
|
setError(caught.message);
|
|
8764
8848
|
}
|
|
8765
8849
|
}, [adopt, invoke]);
|
|
8766
|
-
|
|
8850
|
+
React16.useEffect(() => {
|
|
8767
8851
|
void load();
|
|
8768
8852
|
}, [load]);
|
|
8769
8853
|
const run = async (name2, operation) => {
|
|
@@ -8780,7 +8864,7 @@ function OfficeSettingsTab({ rpcCall, initialStatus }) {
|
|
|
8780
8864
|
setBusy("");
|
|
8781
8865
|
}
|
|
8782
8866
|
};
|
|
8783
|
-
const hooks =
|
|
8867
|
+
const hooks = React16.useMemo(() => {
|
|
8784
8868
|
try {
|
|
8785
8869
|
return officeHookUrls(form.baseUrl);
|
|
8786
8870
|
} catch {
|
|
@@ -8965,7 +9049,7 @@ var normalizeSnapshot4 = api2.normalizeSnapshot;
|
|
|
8965
9049
|
var presentError5 = api2.presentError;
|
|
8966
9050
|
|
|
8967
9051
|
// plugin-src/client/channels/slack/index.js
|
|
8968
|
-
var
|
|
9052
|
+
var React17 = __toESM(require("react"), 1);
|
|
8969
9053
|
|
|
8970
9054
|
// src/channels/slack/manifest.mjs
|
|
8971
9055
|
var SLACK_APP_MANIFEST_YAML = `_metadata:
|
|
@@ -9043,10 +9127,10 @@ function installSlackStyles() {
|
|
|
9043
9127
|
|
|
9044
9128
|
// plugin-src/client/channels/slack/index.js
|
|
9045
9129
|
function SlackCredentialPanel({ busy, error, onSubmit, onCancel }) {
|
|
9046
|
-
const [botToken, setBotToken] =
|
|
9047
|
-
const [appToken, setAppToken] =
|
|
9048
|
-
const [copied, setCopied] =
|
|
9049
|
-
const headingId =
|
|
9130
|
+
const [botToken, setBotToken] = React17.useState("");
|
|
9131
|
+
const [appToken, setAppToken] = React17.useState("");
|
|
9132
|
+
const [copied, setCopied] = React17.useState(false);
|
|
9133
|
+
const headingId = React17.useId();
|
|
9050
9134
|
const copyManifest = async () => {
|
|
9051
9135
|
try {
|
|
9052
9136
|
await navigator.clipboard.writeText(SLACK_APP_MANIFEST_YAML);
|
|
@@ -9241,6 +9325,7 @@ var WECOM_ENDPOINTS = Object.freeze({
|
|
|
9241
9325
|
reconnectBot: "bot.reconnect",
|
|
9242
9326
|
deleteBot: "bot.delete",
|
|
9243
9327
|
setWorkspace: "bot.workspace.set",
|
|
9328
|
+
setModel: SET_MODEL_ENDPOINT,
|
|
9244
9329
|
setAgentPreset: SET_AGENT_PRESET_ENDPOINT,
|
|
9245
9330
|
setContextEnhancement: "bot.context-enhancement.set",
|
|
9246
9331
|
setAccessPolicy: "bot.access-policy.set"
|
|
@@ -9313,6 +9398,7 @@ function normalizeBot4(value) {
|
|
|
9313
9398
|
connected,
|
|
9314
9399
|
state: connected ? "connected" : state,
|
|
9315
9400
|
workspace: text4(value.workspace, "", 4096),
|
|
9401
|
+
model: normalizeModelSelection(value.model),
|
|
9316
9402
|
agentPreset: normalizeAgentPresetId(value.agentPreset),
|
|
9317
9403
|
contextEnhancement: normalizeContextEnhancementConfig(value.contextEnhancement),
|
|
9318
9404
|
...Object.hasOwn(value, "accessPolicy") ? { accessPolicy: normalizeAccessPolicy(value.accessPolicy) } : {},
|
|
@@ -9341,7 +9427,8 @@ function normalizeSnapshot6(value) {
|
|
|
9341
9427
|
totals: { configured: bots.length, connected: bots.filter((bot) => bot.connected).length },
|
|
9342
9428
|
provisioning: source.provisioning ? normalizeProvisioning4(source.provisioning) : null,
|
|
9343
9429
|
testMessage: normalizeTestMessage3(source.testMessage),
|
|
9344
|
-
agentPresetCatalog: normalizeAgentPresetCatalog(source.agentPresetCatalog)
|
|
9430
|
+
agentPresetCatalog: normalizeAgentPresetCatalog(source.agentPresetCatalog),
|
|
9431
|
+
modelCatalog: normalizeModelCatalog(source.modelCatalog)
|
|
9345
9432
|
};
|
|
9346
9433
|
}
|
|
9347
9434
|
function presentError7(error) {
|
|
@@ -9356,7 +9443,7 @@ function formatRemaining4(milliseconds) {
|
|
|
9356
9443
|
}
|
|
9357
9444
|
|
|
9358
9445
|
// plugin-src/client/channels/wecom/index.js
|
|
9359
|
-
var
|
|
9446
|
+
var React18 = __toESM(require("react"), 1);
|
|
9360
9447
|
|
|
9361
9448
|
// plugin-src/client/channels/wecom/styles.js
|
|
9362
9449
|
var WECOM_STYLE_ID = "xmanrui-dsh-im-wecom-settings";
|
|
@@ -9381,7 +9468,7 @@ function installWecomStyles() {
|
|
|
9381
9468
|
|
|
9382
9469
|
// plugin-src/client/channels/wecom/index.js
|
|
9383
9470
|
var ACTIVE_STATES2 = /* @__PURE__ */ new Set(["pending", "refreshing", "connecting"]);
|
|
9384
|
-
var Button10 =
|
|
9471
|
+
var Button10 = React18.forwardRef(function Button11({ children, kind = "secondary", className = "", ...props }, ref) {
|
|
9385
9472
|
return h2("button", {
|
|
9386
9473
|
...props,
|
|
9387
9474
|
ref,
|
|
@@ -9595,6 +9682,7 @@ function AccountCard3({
|
|
|
9595
9682
|
removing,
|
|
9596
9683
|
onReconnect,
|
|
9597
9684
|
onWorkspaceSave,
|
|
9685
|
+
onModelSave,
|
|
9598
9686
|
onAgentPresetSave,
|
|
9599
9687
|
onContextEnhancementSave,
|
|
9600
9688
|
onRequestRemove,
|
|
@@ -9649,6 +9737,11 @@ function AccountCard3({
|
|
|
9649
9737
|
disabled: Boolean(busy),
|
|
9650
9738
|
onSave: onWorkspaceSave
|
|
9651
9739
|
}),
|
|
9740
|
+
h2(ModelEditor, {
|
|
9741
|
+
model: account.model,
|
|
9742
|
+
disabled: Boolean(busy),
|
|
9743
|
+
onSave: onModelSave
|
|
9744
|
+
}),
|
|
9652
9745
|
h2(AgentPresetEditor, {
|
|
9653
9746
|
agentPreset: account.agentPreset,
|
|
9654
9747
|
disabled: Boolean(busy),
|
|
@@ -9693,27 +9786,28 @@ function AccountCard3({
|
|
|
9693
9786
|
);
|
|
9694
9787
|
}
|
|
9695
9788
|
function WecomSettingsTab({ rpcCall }) {
|
|
9696
|
-
const [model, setModel] =
|
|
9789
|
+
const [model, setModel] = React18.useState({
|
|
9697
9790
|
phase: "loading",
|
|
9698
9791
|
bots: [],
|
|
9699
9792
|
totals: { configured: 0, connected: 0 },
|
|
9700
9793
|
error: null,
|
|
9701
|
-
agentPresetCatalog: EMPTY_AGENT_PRESET_CATALOG
|
|
9794
|
+
agentPresetCatalog: EMPTY_AGENT_PRESET_CATALOG,
|
|
9795
|
+
modelCatalog: EMPTY_MODEL_CATALOG
|
|
9702
9796
|
});
|
|
9703
|
-
const [provision, setProvision] =
|
|
9704
|
-
const [busy, setBusy] =
|
|
9705
|
-
const [busyByBot, setBusyByBot] =
|
|
9706
|
-
const [feedbackByBot, setFeedbackByBot] =
|
|
9707
|
-
const [removeTarget, setRemoveTarget] =
|
|
9708
|
-
const [credentialOpen, setCredentialOpen] =
|
|
9709
|
-
const [credentialError, setCredentialError] =
|
|
9710
|
-
const [notice, setNotice] =
|
|
9711
|
-
const [now, setNow] =
|
|
9712
|
-
const mounted =
|
|
9797
|
+
const [provision, setProvision] = React18.useState(null);
|
|
9798
|
+
const [busy, setBusy] = React18.useState(false);
|
|
9799
|
+
const [busyByBot, setBusyByBot] = React18.useState({});
|
|
9800
|
+
const [feedbackByBot, setFeedbackByBot] = React18.useState({});
|
|
9801
|
+
const [removeTarget, setRemoveTarget] = React18.useState(null);
|
|
9802
|
+
const [credentialOpen, setCredentialOpen] = React18.useState(false);
|
|
9803
|
+
const [credentialError, setCredentialError] = React18.useState(null);
|
|
9804
|
+
const [notice, setNotice] = React18.useState("");
|
|
9805
|
+
const [now, setNow] = React18.useState(Date.now());
|
|
9806
|
+
const mounted = React18.useRef(true);
|
|
9713
9807
|
const workspaceFence = useWorkspaceSnapshotFence();
|
|
9714
|
-
const addButtonRef =
|
|
9715
|
-
const noticeFrameRef =
|
|
9716
|
-
const announce =
|
|
9808
|
+
const addButtonRef = React18.useRef(null);
|
|
9809
|
+
const noticeFrameRef = React18.useRef(null);
|
|
9810
|
+
const announce = React18.useCallback((message) => {
|
|
9717
9811
|
if (!mounted.current) return;
|
|
9718
9812
|
if (noticeFrameRef.current !== null) {
|
|
9719
9813
|
window.cancelAnimationFrame(noticeFrameRef.current);
|
|
@@ -9727,7 +9821,7 @@ function WecomSettingsTab({ rpcCall }) {
|
|
|
9727
9821
|
});
|
|
9728
9822
|
}
|
|
9729
9823
|
}, []);
|
|
9730
|
-
|
|
9824
|
+
React18.useEffect(() => {
|
|
9731
9825
|
const disposeDingtalk = installDingtalkStyles();
|
|
9732
9826
|
const disposeWecom = installWecomStyles();
|
|
9733
9827
|
mounted.current = true;
|
|
@@ -9741,11 +9835,11 @@ function WecomSettingsTab({ rpcCall }) {
|
|
|
9741
9835
|
disposeDingtalk();
|
|
9742
9836
|
};
|
|
9743
9837
|
}, []);
|
|
9744
|
-
const invoke =
|
|
9838
|
+
const invoke = React18.useCallback(async (endpoint, payload = {}, signal) => {
|
|
9745
9839
|
if (typeof rpcCall !== "function") throw new TypeError("\u4F01\u4E1A\u5FAE\u4FE1\u8BBE\u7F6E\u9875\u7F3A\u5C11 RPC \u8FDE\u63A5");
|
|
9746
9840
|
return unwrapRpcResult7(await rpcCall(endpoint, payload, signal));
|
|
9747
9841
|
}, [rpcCall]);
|
|
9748
|
-
const loadStatus =
|
|
9842
|
+
const loadStatus = React18.useCallback(async ({ signal, silent = false, restore = false } = {}) => {
|
|
9749
9843
|
const workspaceVersion = workspaceFence.beginStatus();
|
|
9750
9844
|
if (workspaceVersion === null) return void 0;
|
|
9751
9845
|
if (!silent && mounted.current) setModel((current) => ({ ...current, phase: "loading", error: null }));
|
|
@@ -9757,7 +9851,8 @@ function WecomSettingsTab({ rpcCall }) {
|
|
|
9757
9851
|
bots: snapshot.bots,
|
|
9758
9852
|
totals: snapshot.totals,
|
|
9759
9853
|
error: null,
|
|
9760
|
-
agentPresetCatalog: snapshot.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG
|
|
9854
|
+
agentPresetCatalog: snapshot.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG,
|
|
9855
|
+
modelCatalog: snapshot.modelCatalog ?? EMPTY_MODEL_CATALOG
|
|
9761
9856
|
});
|
|
9762
9857
|
if (restore && snapshot.provisioning) setProvision({
|
|
9763
9858
|
...snapshot.provisioning,
|
|
@@ -9771,12 +9866,12 @@ function WecomSettingsTab({ rpcCall }) {
|
|
|
9771
9866
|
return void 0;
|
|
9772
9867
|
}
|
|
9773
9868
|
}, [invoke, workspaceFence]);
|
|
9774
|
-
|
|
9869
|
+
React18.useEffect(() => {
|
|
9775
9870
|
const controller = new AbortController();
|
|
9776
9871
|
void loadStatus({ signal: controller.signal, restore: true });
|
|
9777
9872
|
return () => controller.abort();
|
|
9778
9873
|
}, [loadStatus]);
|
|
9779
|
-
|
|
9874
|
+
React18.useEffect(() => {
|
|
9780
9875
|
if (model.phase !== "ready") return void 0;
|
|
9781
9876
|
const controller = new AbortController();
|
|
9782
9877
|
const timer = window.setInterval(() => void loadStatus({ signal: controller.signal, silent: true }), 15e3);
|
|
@@ -9785,12 +9880,12 @@ function WecomSettingsTab({ rpcCall }) {
|
|
|
9785
9880
|
window.clearInterval(timer);
|
|
9786
9881
|
};
|
|
9787
9882
|
}, [loadStatus, model.phase]);
|
|
9788
|
-
|
|
9883
|
+
React18.useEffect(() => {
|
|
9789
9884
|
if (!provision || !ACTIVE_STATES2.has(provision.status)) return void 0;
|
|
9790
9885
|
const timer = window.setInterval(() => mounted.current && setNow(Date.now()), 1e3);
|
|
9791
9886
|
return () => window.clearInterval(timer);
|
|
9792
9887
|
}, [provision?.attemptId, provision?.status]);
|
|
9793
|
-
const startProvisioning =
|
|
9888
|
+
const startProvisioning = React18.useCallback(async (replace = false) => {
|
|
9794
9889
|
setCredentialOpen(false);
|
|
9795
9890
|
setCredentialError(null);
|
|
9796
9891
|
setBusy(true);
|
|
@@ -9808,7 +9903,7 @@ function WecomSettingsTab({ rpcCall }) {
|
|
|
9808
9903
|
if (mounted.current) setBusy(false);
|
|
9809
9904
|
}
|
|
9810
9905
|
}, [invoke, provision?.attemptId]);
|
|
9811
|
-
const bindCredentials =
|
|
9906
|
+
const bindCredentials = React18.useCallback(async ({ identity, secret }) => {
|
|
9812
9907
|
const snapshotVersion = workspaceFence.beginMutation();
|
|
9813
9908
|
setBusy(true);
|
|
9814
9909
|
setCredentialError(null);
|
|
@@ -9824,7 +9919,8 @@ function WecomSettingsTab({ rpcCall }) {
|
|
|
9824
9919
|
bots: snapshot.bots,
|
|
9825
9920
|
totals: snapshot.totals,
|
|
9826
9921
|
error: null,
|
|
9827
|
-
agentPresetCatalog: snapshot.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG
|
|
9922
|
+
agentPresetCatalog: snapshot.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG,
|
|
9923
|
+
modelCatalog: snapshot.modelCatalog ?? EMPTY_MODEL_CATALOG
|
|
9828
9924
|
});
|
|
9829
9925
|
}
|
|
9830
9926
|
setCredentialOpen(false);
|
|
@@ -9836,7 +9932,7 @@ function WecomSettingsTab({ rpcCall }) {
|
|
|
9836
9932
|
if (mounted.current) setBusy(false);
|
|
9837
9933
|
}
|
|
9838
9934
|
}, [invoke, loadStatus, workspaceFence]);
|
|
9839
|
-
const closeProvision =
|
|
9935
|
+
const closeProvision = React18.useCallback(async () => {
|
|
9840
9936
|
setBusy(true);
|
|
9841
9937
|
try {
|
|
9842
9938
|
if (provision?.attemptId && ACTIVE_STATES2.has(provision.status)) {
|
|
@@ -9847,7 +9943,7 @@ function WecomSettingsTab({ rpcCall }) {
|
|
|
9847
9943
|
if (mounted.current) setBusy(false);
|
|
9848
9944
|
}
|
|
9849
9945
|
}, [invoke, provision?.attemptId, provision?.status]);
|
|
9850
|
-
|
|
9946
|
+
React18.useEffect(() => {
|
|
9851
9947
|
const attemptId = provision?.attemptId;
|
|
9852
9948
|
if (!attemptId || !ACTIVE_STATES2.has(provision.status)) return void 0;
|
|
9853
9949
|
const controller = new AbortController();
|
|
@@ -9877,7 +9973,7 @@ function WecomSettingsTab({ rpcCall }) {
|
|
|
9877
9973
|
window.clearTimeout(timer);
|
|
9878
9974
|
};
|
|
9879
9975
|
}, [invoke, loadStatus, provision?.attemptId, provision?.pollIntervalMs, provision?.status]);
|
|
9880
|
-
const botAction =
|
|
9976
|
+
const botAction = React18.useCallback(async (account, operation, endpoint, payload) => {
|
|
9881
9977
|
const snapshotVersion = workspaceFence.beginMutation();
|
|
9882
9978
|
setBusyByBot((current) => ({ ...current, [account.botId]: operation }));
|
|
9883
9979
|
try {
|
|
@@ -9888,7 +9984,8 @@ function WecomSettingsTab({ rpcCall }) {
|
|
|
9888
9984
|
bots: snapshot.bots,
|
|
9889
9985
|
totals: snapshot.totals,
|
|
9890
9986
|
error: null,
|
|
9891
|
-
agentPresetCatalog: snapshot.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG
|
|
9987
|
+
agentPresetCatalog: snapshot.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG,
|
|
9988
|
+
modelCatalog: snapshot.modelCatalog ?? EMPTY_MODEL_CATALOG
|
|
9892
9989
|
});
|
|
9893
9990
|
}
|
|
9894
9991
|
return snapshot;
|
|
@@ -9902,7 +9999,7 @@ function WecomSettingsTab({ rpcCall }) {
|
|
|
9902
9999
|
});
|
|
9903
10000
|
}
|
|
9904
10001
|
}, [invoke, loadStatus, workspaceFence]);
|
|
9905
|
-
const reconnect =
|
|
10002
|
+
const reconnect = React18.useCallback(async (account) => {
|
|
9906
10003
|
setFeedbackByBot((current) => {
|
|
9907
10004
|
const next = { ...current };
|
|
9908
10005
|
delete next[account.botId];
|
|
@@ -9976,6 +10073,12 @@ function WecomSettingsTab({ rpcCall }) {
|
|
|
9976
10073
|
WECOM_ENDPOINTS.setWorkspace,
|
|
9977
10074
|
{ botId: account.botId, workspace }
|
|
9978
10075
|
),
|
|
10076
|
+
onModelSave: (selectedModel) => botAction(
|
|
10077
|
+
account,
|
|
10078
|
+
"model",
|
|
10079
|
+
WECOM_ENDPOINTS.setModel,
|
|
10080
|
+
{ botId: account.botId, model: selectedModel }
|
|
10081
|
+
),
|
|
9979
10082
|
onAgentPresetSave: (agentPreset) => botAction(
|
|
9980
10083
|
account,
|
|
9981
10084
|
"preset",
|
|
@@ -10010,7 +10113,9 @@ function WecomSettingsTab({ rpcCall }) {
|
|
|
10010
10113
|
setCredentialError(null);
|
|
10011
10114
|
}
|
|
10012
10115
|
}) : null;
|
|
10013
|
-
return h2(
|
|
10116
|
+
return h2(ModelCatalogContext.Provider, {
|
|
10117
|
+
value: model.modelCatalog ?? EMPTY_MODEL_CATALOG
|
|
10118
|
+
}, h2(AgentPresetCatalogContext.Provider, {
|
|
10014
10119
|
value: model.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG
|
|
10015
10120
|
}, h2(
|
|
10016
10121
|
"section",
|
|
@@ -10029,18 +10134,18 @@ function WecomSettingsTab({ rpcCall }) {
|
|
|
10029
10134
|
}),
|
|
10030
10135
|
h2("div", { className: "ddt-visuallyHidden", role: "status", "aria-live": "polite" }, notice),
|
|
10031
10136
|
model.phase === "loading" ? h2(LoadingView4) : model.phase === "error" ? h2("div", { className: "ddt-card dim-surfaceCard" }, h2("div", { className: "ddt-inlineError dim-inlineError" }, h2("h3", null, "\u65E0\u6CD5\u8BFB\u53D6\u4F01\u4E1A\u5FAE\u4FE1\u673A\u5668\u4EBA\u72B6\u6001"), h2("p", null, model.error?.message), h2(Button10, { onClick: () => void loadStatus() }, "\u91CD\u65B0\u8BFB\u53D6"))) : h2(
|
|
10032
|
-
|
|
10137
|
+
React18.Fragment,
|
|
10033
10138
|
null,
|
|
10034
10139
|
credentialView,
|
|
10035
10140
|
provisionView,
|
|
10036
10141
|
model.bots.length === 0 && !provision && !credentialOpen ? h2(EmptyView4, { busy, onStart: () => void startProvisioning() }) : null,
|
|
10037
10142
|
botList
|
|
10038
10143
|
)
|
|
10039
|
-
));
|
|
10144
|
+
)));
|
|
10040
10145
|
}
|
|
10041
10146
|
|
|
10042
10147
|
// plugin-src/client/channels/weixin/index.js
|
|
10043
|
-
var
|
|
10148
|
+
var React19 = __toESM(require("react"), 1);
|
|
10044
10149
|
|
|
10045
10150
|
// plugin-src/client/channels/weixin/api.js
|
|
10046
10151
|
var WEIXIN_RPC_CHANNEL = "/weixin";
|
|
@@ -10053,6 +10158,7 @@ var WEIXIN_ENDPOINTS = Object.freeze({
|
|
|
10053
10158
|
reconnectBot: "bot.reconnect",
|
|
10054
10159
|
deleteBot: "bot.delete",
|
|
10055
10160
|
setWorkspace: "bot.workspace.set",
|
|
10161
|
+
setModel: SET_MODEL_ENDPOINT,
|
|
10056
10162
|
setAgentPreset: SET_AGENT_PRESET_ENDPOINT,
|
|
10057
10163
|
setContextEnhancement: "bot.context-enhancement.set",
|
|
10058
10164
|
setAccessPolicy: "bot.access-policy.set"
|
|
@@ -10145,6 +10251,7 @@ function normalizeBot5(value) {
|
|
|
10145
10251
|
connected,
|
|
10146
10252
|
configured: value.configured === true,
|
|
10147
10253
|
workspace: string(value.workspace).slice(0, 4096),
|
|
10254
|
+
model: normalizeModelSelection(value.model),
|
|
10148
10255
|
agentPreset: normalizeAgentPresetId(value.agentPreset),
|
|
10149
10256
|
contextEnhancement: normalizeContextEnhancementConfig(value.contextEnhancement),
|
|
10150
10257
|
...Object.hasOwn(value, "accessPolicy") ? { accessPolicy: normalizeAccessPolicy(value.accessPolicy) } : {},
|
|
@@ -10184,7 +10291,8 @@ function normalizeSnapshot7(value) {
|
|
|
10184
10291
|
},
|
|
10185
10292
|
provisioning: value.provisioning ? normalizeProvisioning5(value.provisioning) : null,
|
|
10186
10293
|
testMessage: normalizeTestMessage4(value.testMessage),
|
|
10187
|
-
agentPresetCatalog: normalizeAgentPresetCatalog(value.agentPresetCatalog)
|
|
10294
|
+
agentPresetCatalog: normalizeAgentPresetCatalog(value.agentPresetCatalog),
|
|
10295
|
+
modelCatalog: normalizeModelCatalog(value.modelCatalog)
|
|
10188
10296
|
};
|
|
10189
10297
|
}
|
|
10190
10298
|
function presentError8(error) {
|
|
@@ -10199,7 +10307,7 @@ function formatRemaining5(milliseconds) {
|
|
|
10199
10307
|
}
|
|
10200
10308
|
|
|
10201
10309
|
// plugin-src/client/channels/weixin/index.js
|
|
10202
|
-
var Button12 =
|
|
10310
|
+
var Button12 = React19.forwardRef(function Button13({ children, kind = "secondary", className = "", ...props }, ref) {
|
|
10203
10311
|
return h2("button", {
|
|
10204
10312
|
...props,
|
|
10205
10313
|
ref,
|
|
@@ -10272,14 +10380,14 @@ function EmptyView5({ onStart, busy }) {
|
|
|
10272
10380
|
);
|
|
10273
10381
|
}
|
|
10274
10382
|
function QrPanel4({ provision, now, busy, onRefresh, onCancel }) {
|
|
10275
|
-
const [imageFailed, setImageFailed] =
|
|
10383
|
+
const [imageFailed, setImageFailed] = React19.useState(false);
|
|
10276
10384
|
const source = safeQrSource5(provision.qrCodeDataUrl);
|
|
10277
10385
|
const href = safeVerificationUrl(provision.verificationUrl);
|
|
10278
10386
|
const remaining = Math.max(0, provision.expiresAt - now);
|
|
10279
10387
|
const expired = remaining === 0 || provision.status === "expired";
|
|
10280
10388
|
const duration = Math.max(1, provision.durationMs ?? 5 * 6e4);
|
|
10281
10389
|
const progress = Math.round(Math.min(1, remaining / duration) * 100);
|
|
10282
|
-
|
|
10390
|
+
React19.useEffect(() => setImageFailed(false), [source]);
|
|
10283
10391
|
return h2(
|
|
10284
10392
|
"div",
|
|
10285
10393
|
{ className: "dxw-card dim-surfaceCard" },
|
|
@@ -10346,9 +10454,9 @@ function QrPanel4({ provision, now, busy, onRefresh, onCancel }) {
|
|
|
10346
10454
|
);
|
|
10347
10455
|
}
|
|
10348
10456
|
function VerificationPanel({ provision, busy, onSubmit, onCancel }) {
|
|
10349
|
-
const [code, setCode] =
|
|
10457
|
+
const [code, setCode] = React19.useState("");
|
|
10350
10458
|
const valid = /^\d{4,8}$/.test(code);
|
|
10351
|
-
|
|
10459
|
+
React19.useEffect(() => setCode(""), [provision.attemptId]);
|
|
10352
10460
|
return h2(
|
|
10353
10461
|
"div",
|
|
10354
10462
|
{ className: "dxw-card dim-surfaceCard" },
|
|
@@ -10446,6 +10554,7 @@ function AccountCard4({
|
|
|
10446
10554
|
removing,
|
|
10447
10555
|
onReconnect,
|
|
10448
10556
|
onWorkspaceSave,
|
|
10557
|
+
onModelSave,
|
|
10449
10558
|
onAgentPresetSave,
|
|
10450
10559
|
onContextEnhancementSave,
|
|
10451
10560
|
onRequestRemove,
|
|
@@ -10495,6 +10604,11 @@ function AccountCard4({
|
|
|
10495
10604
|
disabled: Boolean(busy),
|
|
10496
10605
|
onSave: onWorkspaceSave
|
|
10497
10606
|
}),
|
|
10607
|
+
h2(ModelEditor, {
|
|
10608
|
+
model: account.model,
|
|
10609
|
+
disabled: Boolean(busy),
|
|
10610
|
+
onSave: onModelSave
|
|
10611
|
+
}),
|
|
10498
10612
|
h2(AgentPresetEditor, {
|
|
10499
10613
|
agentPreset: account.agentPreset,
|
|
10500
10614
|
disabled: Boolean(busy),
|
|
@@ -10572,6 +10686,7 @@ function AccountList2(props) {
|
|
|
10572
10686
|
removing: props.removeTarget === account.botId,
|
|
10573
10687
|
onReconnect: () => props.onReconnect(account),
|
|
10574
10688
|
onWorkspaceSave: (workspace) => props.onWorkspaceSave(account, workspace),
|
|
10689
|
+
onModelSave: (model) => props.onModelSave(account, model),
|
|
10575
10690
|
onAgentPresetSave: (agentPreset) => props.onAgentPresetSave(account, agentPreset),
|
|
10576
10691
|
onContextEnhancementSave: (config) => props.onContextEnhancementSave(account, config),
|
|
10577
10692
|
onRequestRemove: () => props.onRequestRemove(account),
|
|
@@ -10592,41 +10707,42 @@ function mergeWeixinProvisioningSnapshot(current, incoming, { restoreProvisionin
|
|
|
10592
10707
|
};
|
|
10593
10708
|
}
|
|
10594
10709
|
function WeixinSettingsTab({ rpcCall }) {
|
|
10595
|
-
const [model, setModel] =
|
|
10710
|
+
const [model, setModel] = React19.useState({
|
|
10596
10711
|
phase: "loading",
|
|
10597
10712
|
bots: [],
|
|
10598
10713
|
totals: EMPTY_TOTALS3,
|
|
10599
10714
|
revision: 0,
|
|
10600
10715
|
error: null,
|
|
10601
|
-
agentPresetCatalog: EMPTY_AGENT_PRESET_CATALOG
|
|
10716
|
+
agentPresetCatalog: EMPTY_AGENT_PRESET_CATALOG,
|
|
10717
|
+
modelCatalog: EMPTY_MODEL_CATALOG
|
|
10602
10718
|
});
|
|
10603
|
-
const [provision, setProvision] =
|
|
10604
|
-
const [busy, setBusy] =
|
|
10605
|
-
const [busyByBot, setBusyByBot] =
|
|
10606
|
-
const [feedbackByBot, setFeedbackByBot] =
|
|
10607
|
-
const [removeTarget, setRemoveTarget] =
|
|
10608
|
-
const [notice, setNotice] =
|
|
10609
|
-
const [now, setNow] =
|
|
10610
|
-
const addButtonRef =
|
|
10611
|
-
const mountedRef =
|
|
10719
|
+
const [provision, setProvision] = React19.useState(null);
|
|
10720
|
+
const [busy, setBusy] = React19.useState(false);
|
|
10721
|
+
const [busyByBot, setBusyByBot] = React19.useState({});
|
|
10722
|
+
const [feedbackByBot, setFeedbackByBot] = React19.useState({});
|
|
10723
|
+
const [removeTarget, setRemoveTarget] = React19.useState(null);
|
|
10724
|
+
const [notice, setNotice] = React19.useState("");
|
|
10725
|
+
const [now, setNow] = React19.useState(() => Date.now());
|
|
10726
|
+
const addButtonRef = React19.useRef(null);
|
|
10727
|
+
const mountedRef = React19.useRef(true);
|
|
10612
10728
|
const workspaceFence = useWorkspaceSnapshotFence();
|
|
10613
10729
|
const scheduleAnimationFrame = useAnimationFrameScheduler();
|
|
10614
|
-
|
|
10730
|
+
React19.useEffect(() => {
|
|
10615
10731
|
mountedRef.current = true;
|
|
10616
10732
|
return () => {
|
|
10617
10733
|
mountedRef.current = false;
|
|
10618
10734
|
};
|
|
10619
10735
|
}, []);
|
|
10620
|
-
const announce =
|
|
10736
|
+
const announce = React19.useCallback((value) => {
|
|
10621
10737
|
setNotice("");
|
|
10622
10738
|
scheduleAnimationFrame(() => {
|
|
10623
10739
|
if (value) setNotice(value);
|
|
10624
10740
|
}, "announcement");
|
|
10625
10741
|
}, [scheduleAnimationFrame]);
|
|
10626
|
-
const invoke =
|
|
10742
|
+
const invoke = React19.useCallback(async (endpoint, payload = {}, signal) => {
|
|
10627
10743
|
return unwrapRpcResult8(await rpcCall(endpoint, payload, signal));
|
|
10628
10744
|
}, [rpcCall]);
|
|
10629
|
-
const loadStatus =
|
|
10745
|
+
const loadStatus = React19.useCallback(async ({
|
|
10630
10746
|
signal,
|
|
10631
10747
|
silent = false,
|
|
10632
10748
|
restoreProvisioning = false
|
|
@@ -10643,7 +10759,8 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
10643
10759
|
totals: snapshot.totals,
|
|
10644
10760
|
revision: snapshot.revision,
|
|
10645
10761
|
error: null,
|
|
10646
|
-
agentPresetCatalog: snapshot.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG
|
|
10762
|
+
agentPresetCatalog: snapshot.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG,
|
|
10763
|
+
modelCatalog: snapshot.modelCatalog ?? EMPTY_MODEL_CATALOG
|
|
10647
10764
|
});
|
|
10648
10765
|
if (snapshot.provisioning) {
|
|
10649
10766
|
setProvision((current) => mergeWeixinProvisioningSnapshot(
|
|
@@ -10663,12 +10780,12 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
10663
10780
|
return void 0;
|
|
10664
10781
|
}
|
|
10665
10782
|
}, [invoke, workspaceFence]);
|
|
10666
|
-
|
|
10783
|
+
React19.useEffect(() => {
|
|
10667
10784
|
const controller = new AbortController();
|
|
10668
10785
|
void loadStatus({ signal: controller.signal, restoreProvisioning: true });
|
|
10669
10786
|
return () => controller.abort();
|
|
10670
10787
|
}, [loadStatus]);
|
|
10671
|
-
|
|
10788
|
+
React19.useEffect(() => {
|
|
10672
10789
|
if (model.phase !== "ready") return void 0;
|
|
10673
10790
|
const controller = new AbortController();
|
|
10674
10791
|
let running = false;
|
|
@@ -10687,12 +10804,12 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
10687
10804
|
window.clearInterval(timer);
|
|
10688
10805
|
};
|
|
10689
10806
|
}, [loadStatus, model.phase]);
|
|
10690
|
-
|
|
10807
|
+
React19.useEffect(() => {
|
|
10691
10808
|
if (!provision || !["pending", "scanned"].includes(provision.status)) return void 0;
|
|
10692
10809
|
const timer = window.setInterval(() => setNow(Date.now()), 1e3);
|
|
10693
10810
|
return () => window.clearInterval(timer);
|
|
10694
10811
|
}, [provision?.attemptId, provision?.status]);
|
|
10695
|
-
const startProvisioning =
|
|
10812
|
+
const startProvisioning = React19.useCallback(async ({ replace = false } = {}) => {
|
|
10696
10813
|
setBusy(true);
|
|
10697
10814
|
try {
|
|
10698
10815
|
if (replace && provision?.attemptId) {
|
|
@@ -10713,7 +10830,7 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
10713
10830
|
setBusy(false);
|
|
10714
10831
|
}
|
|
10715
10832
|
}, [announce, invoke, provision?.attemptId]);
|
|
10716
|
-
const cancelProvisioning =
|
|
10833
|
+
const cancelProvisioning = React19.useCallback(async () => {
|
|
10717
10834
|
setBusy(true);
|
|
10718
10835
|
try {
|
|
10719
10836
|
if (provision?.attemptId && !["failed", "expired", "cancelled"].includes(provision.status)) {
|
|
@@ -10728,7 +10845,7 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
10728
10845
|
setBusy(false);
|
|
10729
10846
|
}
|
|
10730
10847
|
}, [announce, invoke, provision?.attemptId, provision?.status, scheduleAnimationFrame]);
|
|
10731
|
-
const submitVerification =
|
|
10848
|
+
const submitVerification = React19.useCallback(async (verifyCode) => {
|
|
10732
10849
|
if (!provision?.attemptId) return;
|
|
10733
10850
|
setBusy(true);
|
|
10734
10851
|
try {
|
|
@@ -10744,7 +10861,7 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
10744
10861
|
setBusy(false);
|
|
10745
10862
|
}
|
|
10746
10863
|
}, [announce, invoke, provision?.attemptId]);
|
|
10747
|
-
|
|
10864
|
+
React19.useEffect(() => {
|
|
10748
10865
|
const attemptId = provision?.attemptId;
|
|
10749
10866
|
if (!attemptId || !["pending", "scanned", "connecting"].includes(provision.status)) return void 0;
|
|
10750
10867
|
const controller = new AbortController();
|
|
@@ -10792,7 +10909,7 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
10792
10909
|
controller.abort();
|
|
10793
10910
|
};
|
|
10794
10911
|
}, [announce, invoke, loadStatus, provision?.attemptId, provision?.status, provision?.pollIntervalMs]);
|
|
10795
|
-
const setBotBusy =
|
|
10912
|
+
const setBotBusy = React19.useCallback((botId, value) => {
|
|
10796
10913
|
setBusyByBot((current) => {
|
|
10797
10914
|
const next = { ...current };
|
|
10798
10915
|
if (value) next[botId] = value;
|
|
@@ -10800,7 +10917,7 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
10800
10917
|
return next;
|
|
10801
10918
|
});
|
|
10802
10919
|
}, []);
|
|
10803
|
-
const reconnect =
|
|
10920
|
+
const reconnect = React19.useCallback(async (account) => {
|
|
10804
10921
|
const snapshotVersion = workspaceFence.beginMutation();
|
|
10805
10922
|
setBotBusy(account.botId, "reconnect");
|
|
10806
10923
|
setFeedbackByBot((current) => {
|
|
@@ -10819,7 +10936,8 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
10819
10936
|
bots: snapshot.bots,
|
|
10820
10937
|
totals: snapshot.totals,
|
|
10821
10938
|
revision: snapshot.revision,
|
|
10822
|
-
agentPresetCatalog: snapshot.agentPresetCatalog ?? current.agentPresetCatalog
|
|
10939
|
+
agentPresetCatalog: snapshot.agentPresetCatalog ?? current.agentPresetCatalog,
|
|
10940
|
+
modelCatalog: snapshot.modelCatalog ?? current.modelCatalog
|
|
10823
10941
|
}));
|
|
10824
10942
|
}
|
|
10825
10943
|
const refreshed = snapshot.bots.find((bot) => bot.botId === account.botId);
|
|
@@ -10851,7 +10969,7 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
10851
10969
|
setBotBusy(account.botId, null);
|
|
10852
10970
|
}
|
|
10853
10971
|
}, [announce, invoke, loadStatus, setBotBusy, workspaceFence]);
|
|
10854
|
-
const saveWorkspace =
|
|
10972
|
+
const saveWorkspace = React19.useCallback(async (account, workspace) => {
|
|
10855
10973
|
const workspaceVersion = workspaceFence.beginMutation();
|
|
10856
10974
|
setBotBusy(account.botId, "workspace");
|
|
10857
10975
|
try {
|
|
@@ -10866,7 +10984,8 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
10866
10984
|
totals: snapshot.totals,
|
|
10867
10985
|
revision: snapshot.revision,
|
|
10868
10986
|
error: null,
|
|
10869
|
-
agentPresetCatalog: snapshot.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG
|
|
10987
|
+
agentPresetCatalog: snapshot.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG,
|
|
10988
|
+
modelCatalog: snapshot.modelCatalog ?? EMPTY_MODEL_CATALOG
|
|
10870
10989
|
});
|
|
10871
10990
|
}
|
|
10872
10991
|
} finally {
|
|
@@ -10875,7 +10994,7 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
10875
10994
|
if (mountedRef.current) setBotBusy(account.botId, null);
|
|
10876
10995
|
}
|
|
10877
10996
|
}, [invoke, loadStatus, setBotBusy, workspaceFence]);
|
|
10878
|
-
const saveBotSetting =
|
|
10997
|
+
const saveBotSetting = React19.useCallback(async (account, operation, endpoint, payload) => {
|
|
10879
10998
|
const snapshotVersion = workspaceFence.beginMutation();
|
|
10880
10999
|
setBotBusy(account.botId, operation);
|
|
10881
11000
|
try {
|
|
@@ -10890,7 +11009,8 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
10890
11009
|
totals: snapshot.totals,
|
|
10891
11010
|
revision: snapshot.revision,
|
|
10892
11011
|
error: null,
|
|
10893
|
-
agentPresetCatalog: snapshot.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG
|
|
11012
|
+
agentPresetCatalog: snapshot.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG,
|
|
11013
|
+
modelCatalog: snapshot.modelCatalog ?? EMPTY_MODEL_CATALOG
|
|
10894
11014
|
});
|
|
10895
11015
|
}
|
|
10896
11016
|
} finally {
|
|
@@ -10899,7 +11019,7 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
10899
11019
|
if (mountedRef.current) setBotBusy(account.botId, null);
|
|
10900
11020
|
}
|
|
10901
11021
|
}, [invoke, loadStatus, setBotBusy, workspaceFence]);
|
|
10902
|
-
const remove =
|
|
11022
|
+
const remove = React19.useCallback(async (account) => {
|
|
10903
11023
|
const snapshotVersion = workspaceFence.beginMutation();
|
|
10904
11024
|
setBotBusy(account.botId, "delete");
|
|
10905
11025
|
try {
|
|
@@ -10913,7 +11033,8 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
10913
11033
|
bots: snapshot.bots,
|
|
10914
11034
|
totals: snapshot.totals,
|
|
10915
11035
|
revision: snapshot.revision,
|
|
10916
|
-
agentPresetCatalog: snapshot.agentPresetCatalog ?? current.agentPresetCatalog
|
|
11036
|
+
agentPresetCatalog: snapshot.agentPresetCatalog ?? current.agentPresetCatalog,
|
|
11037
|
+
modelCatalog: snapshot.modelCatalog ?? current.modelCatalog
|
|
10917
11038
|
}));
|
|
10918
11039
|
}
|
|
10919
11040
|
setRemoveTarget(null);
|
|
@@ -10958,7 +11079,9 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
10958
11079
|
onClose: () => void cancelProvisioning()
|
|
10959
11080
|
});
|
|
10960
11081
|
}
|
|
10961
|
-
return h2(
|
|
11082
|
+
return h2(ModelCatalogContext.Provider, {
|
|
11083
|
+
value: model.modelCatalog ?? EMPTY_MODEL_CATALOG
|
|
11084
|
+
}, h2(AgentPresetCatalogContext.Provider, {
|
|
10962
11085
|
value: model.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG
|
|
10963
11086
|
}, h2(
|
|
10964
11087
|
"section",
|
|
@@ -10983,7 +11106,7 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
10983
11106
|
h2(Button12, { onClick: () => void loadStatus() }, "\u91CD\u65B0\u8BFB\u53D6")
|
|
10984
11107
|
)
|
|
10985
11108
|
) : h2(
|
|
10986
|
-
|
|
11109
|
+
React19.Fragment,
|
|
10987
11110
|
null,
|
|
10988
11111
|
provisionView,
|
|
10989
11112
|
model.bots.length === 0 && !provision ? h2(EmptyView5, { onStart: () => void startProvisioning(), busy }) : null,
|
|
@@ -10994,6 +11117,12 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
10994
11117
|
removeTarget,
|
|
10995
11118
|
onReconnect: (account) => void reconnect(account),
|
|
10996
11119
|
onWorkspaceSave: saveWorkspace,
|
|
11120
|
+
onModelSave: (account, selectedModel) => saveBotSetting(
|
|
11121
|
+
account,
|
|
11122
|
+
"model",
|
|
11123
|
+
WEIXIN_ENDPOINTS.setModel,
|
|
11124
|
+
{ model: selectedModel }
|
|
11125
|
+
),
|
|
10997
11126
|
onAgentPresetSave: (account, agentPreset) => saveBotSetting(
|
|
10998
11127
|
account,
|
|
10999
11128
|
"preset",
|
|
@@ -11011,7 +11140,7 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
11011
11140
|
onCancelRemove: () => setRemoveTarget(null)
|
|
11012
11141
|
}) : null
|
|
11013
11142
|
)
|
|
11014
|
-
));
|
|
11143
|
+
)));
|
|
11015
11144
|
}
|
|
11016
11145
|
|
|
11017
11146
|
// plugin-src/client/channels/weixin/styles.js
|
|
@@ -11142,6 +11271,7 @@ var WHATSAPP_ENDPOINTS = Object.freeze({
|
|
|
11142
11271
|
deleteBot: "bot.delete",
|
|
11143
11272
|
setAccessPolicy: "bot.access-policy.set",
|
|
11144
11273
|
setWorkspace: "bot.workspace.set",
|
|
11274
|
+
setModel: SET_MODEL_ENDPOINT,
|
|
11145
11275
|
setAgentPreset: SET_AGENT_PRESET_ENDPOINT,
|
|
11146
11276
|
setContextEnhancement: "bot.context-enhancement.set"
|
|
11147
11277
|
});
|
|
@@ -11208,6 +11338,7 @@ function normalizeBot6(value) {
|
|
|
11208
11338
|
connected,
|
|
11209
11339
|
state: connected ? "connected" : state,
|
|
11210
11340
|
workspace: text5(value.workspace, "", 4096),
|
|
11341
|
+
model: normalizeModelSelection(value.model),
|
|
11211
11342
|
agentPreset: normalizeAgentPresetId(value.agentPreset),
|
|
11212
11343
|
contextEnhancement: normalizeContextEnhancementConfig(value.contextEnhancement),
|
|
11213
11344
|
...Object.hasOwn(value, "accessPolicy") ? { accessPolicy: normalizeAccessPolicy(value.accessPolicy) } : {},
|
|
@@ -11237,7 +11368,8 @@ function normalizeSnapshot8(value) {
|
|
|
11237
11368
|
bots,
|
|
11238
11369
|
totals: { configured: bots.length, connected: bots.filter((bot) => bot.connected).length },
|
|
11239
11370
|
provisioning: source.provisioning ? normalizeProvisioning6(source.provisioning) : null,
|
|
11240
|
-
agentPresetCatalog: normalizeAgentPresetCatalog(source.agentPresetCatalog)
|
|
11371
|
+
agentPresetCatalog: normalizeAgentPresetCatalog(source.agentPresetCatalog),
|
|
11372
|
+
modelCatalog: normalizeModelCatalog(source.modelCatalog)
|
|
11241
11373
|
};
|
|
11242
11374
|
}
|
|
11243
11375
|
function presentError9(error) {
|
|
@@ -11252,7 +11384,7 @@ function formatRemaining6(milliseconds) {
|
|
|
11252
11384
|
}
|
|
11253
11385
|
|
|
11254
11386
|
// plugin-src/client/channels/whatsapp/index.js
|
|
11255
|
-
var
|
|
11387
|
+
var React20 = __toESM(require("react"), 1);
|
|
11256
11388
|
|
|
11257
11389
|
// plugin-src/client/channels/whatsapp/styles.js
|
|
11258
11390
|
var WHATSAPP_STYLE_ID = "xmanrui-dsh-im-whatsapp-settings";
|
|
@@ -11277,7 +11409,7 @@ function installWhatsappStyles() {
|
|
|
11277
11409
|
|
|
11278
11410
|
// plugin-src/client/channels/whatsapp/index.js
|
|
11279
11411
|
var ACTIVE_STATES3 = /* @__PURE__ */ new Set(["pending", "connecting"]);
|
|
11280
|
-
var Button14 =
|
|
11412
|
+
var Button14 = React20.forwardRef(function Button15({ children, kind = "secondary", className = "", ...props }, ref) {
|
|
11281
11413
|
return h2("button", {
|
|
11282
11414
|
...props,
|
|
11283
11415
|
ref,
|
|
@@ -11499,6 +11631,7 @@ function WhatsappAccountCard({
|
|
|
11499
11631
|
removing,
|
|
11500
11632
|
onReconnect,
|
|
11501
11633
|
onWorkspaceSave,
|
|
11634
|
+
onModelSave,
|
|
11502
11635
|
onAgentPresetSave,
|
|
11503
11636
|
onContextEnhancementSave,
|
|
11504
11637
|
onRequestRemove,
|
|
@@ -11557,6 +11690,11 @@ function WhatsappAccountCard({
|
|
|
11557
11690
|
disabled: Boolean(busy),
|
|
11558
11691
|
onSave: onWorkspaceSave
|
|
11559
11692
|
}),
|
|
11693
|
+
h2(ModelEditor, {
|
|
11694
|
+
model: account.model,
|
|
11695
|
+
disabled: Boolean(busy),
|
|
11696
|
+
onSave: onModelSave
|
|
11697
|
+
}),
|
|
11560
11698
|
h2(AgentPresetEditor, {
|
|
11561
11699
|
agentPreset: account.agentPreset,
|
|
11562
11700
|
disabled: Boolean(busy),
|
|
@@ -11609,23 +11747,24 @@ function WhatsappAccountCard({
|
|
|
11609
11747
|
);
|
|
11610
11748
|
}
|
|
11611
11749
|
function WhatsappSettingsTab({ rpcCall }) {
|
|
11612
|
-
const [model, setModel] =
|
|
11750
|
+
const [model, setModel] = React20.useState({
|
|
11613
11751
|
phase: "loading",
|
|
11614
11752
|
bots: [],
|
|
11615
11753
|
totals: { configured: 0, connected: 0 },
|
|
11616
11754
|
error: null,
|
|
11617
|
-
agentPresetCatalog: EMPTY_AGENT_PRESET_CATALOG
|
|
11755
|
+
agentPresetCatalog: EMPTY_AGENT_PRESET_CATALOG,
|
|
11756
|
+
modelCatalog: EMPTY_MODEL_CATALOG
|
|
11618
11757
|
});
|
|
11619
|
-
const [provision, setProvision] =
|
|
11620
|
-
const [busy, setBusy] =
|
|
11621
|
-
const [busyByBot, setBusyByBot] =
|
|
11622
|
-
const [testNoticeByBot, setTestNoticeByBot] =
|
|
11623
|
-
const [removeTarget, setRemoveTarget] =
|
|
11624
|
-
const [now, setNow] =
|
|
11625
|
-
const mounted =
|
|
11758
|
+
const [provision, setProvision] = React20.useState(null);
|
|
11759
|
+
const [busy, setBusy] = React20.useState(false);
|
|
11760
|
+
const [busyByBot, setBusyByBot] = React20.useState({});
|
|
11761
|
+
const [testNoticeByBot, setTestNoticeByBot] = React20.useState({});
|
|
11762
|
+
const [removeTarget, setRemoveTarget] = React20.useState(null);
|
|
11763
|
+
const [now, setNow] = React20.useState(Date.now());
|
|
11764
|
+
const mounted = React20.useRef(true);
|
|
11626
11765
|
const workspaceFence = useWorkspaceSnapshotFence();
|
|
11627
|
-
const addButtonRef =
|
|
11628
|
-
|
|
11766
|
+
const addButtonRef = React20.useRef(null);
|
|
11767
|
+
React20.useEffect(() => {
|
|
11629
11768
|
const disposeDingtalk = installDingtalkStyles();
|
|
11630
11769
|
const disposeWhatsapp = installWhatsappStyles();
|
|
11631
11770
|
mounted.current = true;
|
|
@@ -11635,11 +11774,11 @@ function WhatsappSettingsTab({ rpcCall }) {
|
|
|
11635
11774
|
disposeDingtalk();
|
|
11636
11775
|
};
|
|
11637
11776
|
}, []);
|
|
11638
|
-
const invoke =
|
|
11777
|
+
const invoke = React20.useCallback(async (endpoint, payload = {}, signal) => {
|
|
11639
11778
|
if (typeof rpcCall !== "function") throw new TypeError("WhatsApp \u8BBE\u7F6E\u9875\u7F3A\u5C11 RPC \u8FDE\u63A5");
|
|
11640
11779
|
return unwrapRpcResult9(await rpcCall(endpoint, payload, signal));
|
|
11641
11780
|
}, [rpcCall]);
|
|
11642
|
-
const loadStatus =
|
|
11781
|
+
const loadStatus = React20.useCallback(async ({ signal, silent = false, restore = false } = {}) => {
|
|
11643
11782
|
const workspaceVersion = workspaceFence.beginStatus();
|
|
11644
11783
|
if (workspaceVersion === null) return void 0;
|
|
11645
11784
|
if (!silent && mounted.current) setModel((current) => ({ ...current, phase: "loading", error: null }));
|
|
@@ -11651,7 +11790,8 @@ function WhatsappSettingsTab({ rpcCall }) {
|
|
|
11651
11790
|
bots: snapshot.bots,
|
|
11652
11791
|
totals: snapshot.totals,
|
|
11653
11792
|
error: null,
|
|
11654
|
-
agentPresetCatalog: snapshot.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG
|
|
11793
|
+
agentPresetCatalog: snapshot.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG,
|
|
11794
|
+
modelCatalog: snapshot.modelCatalog ?? EMPTY_MODEL_CATALOG
|
|
11655
11795
|
});
|
|
11656
11796
|
if (restore && snapshot.provisioning) setProvision({
|
|
11657
11797
|
...snapshot.provisioning,
|
|
@@ -11669,12 +11809,12 @@ function WhatsappSettingsTab({ rpcCall }) {
|
|
|
11669
11809
|
return void 0;
|
|
11670
11810
|
}
|
|
11671
11811
|
}, [invoke, workspaceFence]);
|
|
11672
|
-
|
|
11812
|
+
React20.useEffect(() => {
|
|
11673
11813
|
const controller = new AbortController();
|
|
11674
11814
|
void loadStatus({ signal: controller.signal, restore: true });
|
|
11675
11815
|
return () => controller.abort();
|
|
11676
11816
|
}, [loadStatus]);
|
|
11677
|
-
|
|
11817
|
+
React20.useEffect(() => {
|
|
11678
11818
|
if (model.phase !== "ready") return void 0;
|
|
11679
11819
|
const controller = new AbortController();
|
|
11680
11820
|
const timer = window.setInterval(
|
|
@@ -11686,12 +11826,12 @@ function WhatsappSettingsTab({ rpcCall }) {
|
|
|
11686
11826
|
window.clearInterval(timer);
|
|
11687
11827
|
};
|
|
11688
11828
|
}, [loadStatus, model.phase]);
|
|
11689
|
-
|
|
11829
|
+
React20.useEffect(() => {
|
|
11690
11830
|
if (!provision || !ACTIVE_STATES3.has(provision.status)) return void 0;
|
|
11691
11831
|
const timer = window.setInterval(() => mounted.current && setNow(Date.now()), 1e3);
|
|
11692
11832
|
return () => window.clearInterval(timer);
|
|
11693
11833
|
}, [provision?.attemptId, provision?.status]);
|
|
11694
|
-
const startProvisioning =
|
|
11834
|
+
const startProvisioning = React20.useCallback(async (replace = false) => {
|
|
11695
11835
|
setBusy(true);
|
|
11696
11836
|
try {
|
|
11697
11837
|
if (replace && provision?.attemptId) {
|
|
@@ -11709,7 +11849,7 @@ function WhatsappSettingsTab({ rpcCall }) {
|
|
|
11709
11849
|
if (mounted.current) setBusy(false);
|
|
11710
11850
|
}
|
|
11711
11851
|
}, [invoke, provision?.attemptId]);
|
|
11712
|
-
const closeProvision =
|
|
11852
|
+
const closeProvision = React20.useCallback(async () => {
|
|
11713
11853
|
setBusy(true);
|
|
11714
11854
|
try {
|
|
11715
11855
|
if (provision?.attemptId && ACTIVE_STATES3.has(provision.status)) {
|
|
@@ -11720,7 +11860,7 @@ function WhatsappSettingsTab({ rpcCall }) {
|
|
|
11720
11860
|
if (mounted.current) setBusy(false);
|
|
11721
11861
|
}
|
|
11722
11862
|
}, [invoke, provision?.attemptId, provision?.status]);
|
|
11723
|
-
|
|
11863
|
+
React20.useEffect(() => {
|
|
11724
11864
|
const attemptId = provision?.attemptId;
|
|
11725
11865
|
if (!attemptId || !ACTIVE_STATES3.has(provision.status)) return void 0;
|
|
11726
11866
|
const controller = new AbortController();
|
|
@@ -11761,7 +11901,7 @@ function WhatsappSettingsTab({ rpcCall }) {
|
|
|
11761
11901
|
if (timer) window.clearTimeout(timer);
|
|
11762
11902
|
};
|
|
11763
11903
|
}, [invoke, loadStatus, provision?.attemptId, provision?.status]);
|
|
11764
|
-
const botAction =
|
|
11904
|
+
const botAction = React20.useCallback(async (account, operation, endpoint, payload) => {
|
|
11765
11905
|
const snapshotVersion = workspaceFence.beginMutation();
|
|
11766
11906
|
setBusyByBot((current) => ({ ...current, [account.botId]: operation }));
|
|
11767
11907
|
if (operation === "reconnect") {
|
|
@@ -11780,7 +11920,8 @@ function WhatsappSettingsTab({ rpcCall }) {
|
|
|
11780
11920
|
bots: snapshot.bots,
|
|
11781
11921
|
totals: snapshot.totals,
|
|
11782
11922
|
error: null,
|
|
11783
|
-
agentPresetCatalog: snapshot.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG
|
|
11923
|
+
agentPresetCatalog: snapshot.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG,
|
|
11924
|
+
modelCatalog: snapshot.modelCatalog ?? EMPTY_MODEL_CATALOG
|
|
11784
11925
|
});
|
|
11785
11926
|
if (operation === "reconnect") {
|
|
11786
11927
|
setTestNoticeByBot((current) => ({
|
|
@@ -11832,6 +11973,12 @@ function WhatsappSettingsTab({ rpcCall }) {
|
|
|
11832
11973
|
WHATSAPP_ENDPOINTS.setWorkspace,
|
|
11833
11974
|
{ botId: account.botId, workspace }
|
|
11834
11975
|
),
|
|
11976
|
+
onModelSave: (selectedModel) => botAction(
|
|
11977
|
+
account,
|
|
11978
|
+
"model",
|
|
11979
|
+
WHATSAPP_ENDPOINTS.setModel,
|
|
11980
|
+
{ botId: account.botId, model: selectedModel }
|
|
11981
|
+
),
|
|
11835
11982
|
onAgentPresetSave: (agentPreset) => botAction(
|
|
11836
11983
|
account,
|
|
11837
11984
|
"preset",
|
|
@@ -11855,7 +12002,9 @@ function WhatsappSettingsTab({ rpcCall }) {
|
|
|
11855
12002
|
}
|
|
11856
12003
|
}))))
|
|
11857
12004
|
) : null;
|
|
11858
|
-
return h2(
|
|
12005
|
+
return h2(ModelCatalogContext.Provider, {
|
|
12006
|
+
value: model.modelCatalog ?? EMPTY_MODEL_CATALOG
|
|
12007
|
+
}, h2(AgentPresetCatalogContext.Provider, {
|
|
11859
12008
|
value: model.agentPresetCatalog ?? EMPTY_AGENT_PRESET_CATALOG
|
|
11860
12009
|
}, h2(
|
|
11861
12010
|
"section",
|
|
@@ -11880,7 +12029,7 @@ function WhatsappSettingsTab({ rpcCall }) {
|
|
|
11880
12029
|
h2(Button14, { onClick: () => void loadStatus() }, "\u91CD\u65B0\u8BFB\u53D6")
|
|
11881
12030
|
)
|
|
11882
12031
|
) : h2(
|
|
11883
|
-
|
|
12032
|
+
React20.Fragment,
|
|
11884
12033
|
null,
|
|
11885
12034
|
provision?.status === "pending" ? h2(QrPanel5, {
|
|
11886
12035
|
provision,
|
|
@@ -11896,14 +12045,14 @@ function WhatsappSettingsTab({ rpcCall }) {
|
|
|
11896
12045
|
}) : model.bots.length === 0 ? h2(EmptyView6, { busy, onStart: () => void startProvisioning(false) }) : null,
|
|
11897
12046
|
botList
|
|
11898
12047
|
)
|
|
11899
|
-
));
|
|
12048
|
+
)));
|
|
11900
12049
|
}
|
|
11901
12050
|
|
|
11902
12051
|
// plugin-src/client/delivery-settings.js
|
|
11903
|
-
var
|
|
12052
|
+
var React23 = __toESM(require("react"), 1);
|
|
11904
12053
|
|
|
11905
12054
|
// plugin-src/client/access-policy-settings.js
|
|
11906
|
-
var
|
|
12055
|
+
var React21 = __toESM(require("react"), 1);
|
|
11907
12056
|
var ACCESS_POLICY_ENDPOINT = "bot.access-policy.set";
|
|
11908
12057
|
var ACCESS_CHANNEL_DEFINITIONS = Object.freeze({
|
|
11909
12058
|
weixin: Object.freeze({
|
|
@@ -12005,8 +12154,8 @@ function ScenePolicyEditor({
|
|
|
12005
12154
|
unsupported = false,
|
|
12006
12155
|
onChange
|
|
12007
12156
|
}) {
|
|
12008
|
-
const ownerHelpId =
|
|
12009
|
-
const emptyAllowlistHelpId =
|
|
12157
|
+
const ownerHelpId = React21.useId();
|
|
12158
|
+
const emptyAllowlistHelpId = React21.useId();
|
|
12010
12159
|
const allowlist = policy.mode === "allowlist";
|
|
12011
12160
|
const collectionKey = allowlist ? "users" : "commandPermissionOverrides";
|
|
12012
12161
|
const branchKey = allowlist ? "allowlist" : "open";
|
|
@@ -12058,7 +12207,7 @@ function ScenePolicyEditor({
|
|
|
12058
12207
|
h2("strong", null, "\u5F53\u524D\u6E20\u9053\u4E0D\u652F\u6301\u7FA4\u804A"),
|
|
12059
12208
|
h2("p", null, "\u6B64\u533A\u57DF\u65E0\u9700\u914D\u7F6E\uFF0C\u4FDD\u5B58\u79C1\u804A\u8BBE\u7F6E\u65F6\u4F1A\u4FDD\u7559\u73B0\u6709\u7FA4\u804A\u7B56\u7565\u3002")
|
|
12060
12209
|
) : h2(
|
|
12061
|
-
|
|
12210
|
+
React21.Fragment,
|
|
12062
12211
|
null,
|
|
12063
12212
|
h2(
|
|
12064
12213
|
"div",
|
|
@@ -12199,16 +12348,16 @@ function AccessPolicySettingsPage({ channel: channel4, account, rpcCall, onSaved
|
|
|
12199
12348
|
const definition = ACCESS_CHANNEL_DEFINITIONS[channel4];
|
|
12200
12349
|
const initialPolicy = normalizeAccessPolicy(account?.accessPolicy);
|
|
12201
12350
|
const initialKey = JSON.stringify(initialPolicy);
|
|
12202
|
-
const [draft, setDraft] =
|
|
12351
|
+
const [draft, setDraft] = React21.useState(() => clonePolicy(
|
|
12203
12352
|
initialPolicy ?? DEFAULT_ACCESS_POLICY
|
|
12204
12353
|
));
|
|
12205
|
-
const [saving, setSaving] =
|
|
12206
|
-
const [feedback, setFeedback] =
|
|
12207
|
-
|
|
12354
|
+
const [saving, setSaving] = React21.useState(false);
|
|
12355
|
+
const [feedback, setFeedback] = React21.useState(null);
|
|
12356
|
+
React21.useEffect(() => {
|
|
12208
12357
|
const next = normalizeAccessPolicy(account?.accessPolicy);
|
|
12209
12358
|
setDraft(clonePolicy(next ?? DEFAULT_ACCESS_POLICY));
|
|
12210
12359
|
}, [account?.botId, initialKey]);
|
|
12211
|
-
|
|
12360
|
+
React21.useEffect(() => {
|
|
12212
12361
|
setFeedback(null);
|
|
12213
12362
|
}, [account?.botId]);
|
|
12214
12363
|
if (!definition) {
|
|
@@ -12298,80 +12447,682 @@ function AccessPolicySettingsPage({ channel: channel4, account, rpcCall, onSaved
|
|
|
12298
12447
|
);
|
|
12299
12448
|
}
|
|
12300
12449
|
|
|
12301
|
-
// plugin-src/client/
|
|
12302
|
-
var
|
|
12303
|
-
var
|
|
12304
|
-
|
|
12305
|
-
|
|
12306
|
-
|
|
12307
|
-
|
|
12308
|
-
|
|
12309
|
-
|
|
12310
|
-
|
|
12311
|
-
|
|
12312
|
-
|
|
12313
|
-
|
|
12314
|
-
|
|
12315
|
-
|
|
12316
|
-
|
|
12317
|
-
|
|
12318
|
-
|
|
12319
|
-
|
|
12320
|
-
|
|
12321
|
-
|
|
12322
|
-
|
|
12323
|
-
|
|
12324
|
-
|
|
12325
|
-
|
|
12326
|
-
|
|
12327
|
-
|
|
12328
|
-
|
|
12329
|
-
|
|
12330
|
-
|
|
12331
|
-
|
|
12332
|
-
|
|
12333
|
-
|
|
12334
|
-
|
|
12335
|
-
|
|
12336
|
-
|
|
12337
|
-
|
|
12338
|
-
|
|
12339
|
-
|
|
12340
|
-
|
|
12341
|
-
|
|
12342
|
-
|
|
12343
|
-
|
|
12344
|
-
|
|
12345
|
-
|
|
12346
|
-
|
|
12347
|
-
|
|
12348
|
-
|
|
12349
|
-
|
|
12350
|
-
|
|
12351
|
-
|
|
12352
|
-
|
|
12353
|
-
|
|
12354
|
-
|
|
12355
|
-
|
|
12356
|
-
|
|
12357
|
-
|
|
12358
|
-
|
|
12359
|
-
|
|
12360
|
-
|
|
12361
|
-
|
|
12362
|
-
|
|
12363
|
-
|
|
12364
|
-
|
|
12365
|
-
|
|
12366
|
-
|
|
12367
|
-
|
|
12368
|
-
|
|
12369
|
-
|
|
12370
|
-
|
|
12371
|
-
|
|
12372
|
-
|
|
12373
|
-
|
|
12374
|
-
|
|
12450
|
+
// plugin-src/client/channels/feishu/group-settings.js
|
|
12451
|
+
var React22 = __toESM(require("react"), 1);
|
|
12452
|
+
var GROUP_MESSAGE_PERMISSION_OPERATION2 = FEISHU_REGISTRATION_OPERATIONS.GROUP_MESSAGE_PERMISSION;
|
|
12453
|
+
function SettingsButton({ children, kind = "secondary", className = "", ...props }) {
|
|
12454
|
+
return h2("button", {
|
|
12455
|
+
...props,
|
|
12456
|
+
type: "button",
|
|
12457
|
+
className: `dim-deliveryButton ${className}`.trim(),
|
|
12458
|
+
"data-kind": kind
|
|
12459
|
+
}, children);
|
|
12460
|
+
}
|
|
12461
|
+
function groupSettingsFrom(value) {
|
|
12462
|
+
return {
|
|
12463
|
+
groupResponseMode: normalizeGroupResponseMode(value?.groupResponseMode),
|
|
12464
|
+
groupTopicReply: value?.groupTopicReply === true,
|
|
12465
|
+
groupMessagePermissionGranted: value?.groupMessagePermissionGranted === true
|
|
12466
|
+
};
|
|
12467
|
+
}
|
|
12468
|
+
function targetBotFromSnapshot(value, botId) {
|
|
12469
|
+
const snapshot = normalizeBotsSnapshot(value);
|
|
12470
|
+
const bot = snapshot.bots.find((entry) => entry.botId === botId);
|
|
12471
|
+
if (!bot) throw new Error("\u98DE\u4E66\u670D\u52A1\u6CA1\u6709\u8FD4\u56DE\u5F53\u524D\u673A\u5668\u4EBA\u7684\u8BBE\u7F6E");
|
|
12472
|
+
return { snapshot, bot };
|
|
12473
|
+
}
|
|
12474
|
+
function safeVerificationHref2(value) {
|
|
12475
|
+
if (!value) return void 0;
|
|
12476
|
+
try {
|
|
12477
|
+
const url = new URL(value);
|
|
12478
|
+
return url.protocol === "https:" && [
|
|
12479
|
+
"accounts.feishu.cn",
|
|
12480
|
+
"accounts.larksuite.com",
|
|
12481
|
+
"open.feishu.cn",
|
|
12482
|
+
"open.larksuite.com"
|
|
12483
|
+
].includes(url.hostname) && !url.port && !url.username && !url.password ? url.toString() : void 0;
|
|
12484
|
+
} catch {
|
|
12485
|
+
return void 0;
|
|
12486
|
+
}
|
|
12487
|
+
}
|
|
12488
|
+
function safeQrSource7(value) {
|
|
12489
|
+
if (!value) return void 0;
|
|
12490
|
+
return /^data:image\/(?:png|webp|svg\+xml)(?:;charset=[^;,]+)?;base64,/i.test(value) ? value : void 0;
|
|
12491
|
+
}
|
|
12492
|
+
function QrPlaceholder() {
|
|
12493
|
+
return h2("svg", {
|
|
12494
|
+
viewBox: "0 0 24 24",
|
|
12495
|
+
width: 50,
|
|
12496
|
+
height: 50,
|
|
12497
|
+
fill: "currentColor",
|
|
12498
|
+
"aria-hidden": "true"
|
|
12499
|
+
}, h2("path", {
|
|
12500
|
+
d: "M3 3h7v7H3V3Zm2 2v3h3V5H5Zm9-2h7v7h-7V3Zm2 2v3h3V5h-3ZM3 14h7v7H3v-7Zm2 2v3h3v-3H5Zm9-2h3v3h-3v-3Zm4 0h3v7h-3v-3h-2v3h-2v-5h4v-2Z"
|
|
12501
|
+
}));
|
|
12502
|
+
}
|
|
12503
|
+
function GroupResponseModeEditor({
|
|
12504
|
+
value,
|
|
12505
|
+
permissionGranted = false,
|
|
12506
|
+
disabled = false,
|
|
12507
|
+
authorizationDisabled = false,
|
|
12508
|
+
onSave,
|
|
12509
|
+
onAuthorize
|
|
12510
|
+
}) {
|
|
12511
|
+
const current = normalizeGroupResponseMode(value);
|
|
12512
|
+
const [saving, setSaving] = React22.useState(false);
|
|
12513
|
+
const [authorizing, setAuthorizing] = React22.useState(false);
|
|
12514
|
+
const [error, setError] = React22.useState(null);
|
|
12515
|
+
const change = async (event) => {
|
|
12516
|
+
const next = normalizeGroupResponseMode(event.target.value);
|
|
12517
|
+
if (next === current || saving || disabled) return;
|
|
12518
|
+
setSaving(true);
|
|
12519
|
+
setError(null);
|
|
12520
|
+
try {
|
|
12521
|
+
await onSave?.(next);
|
|
12522
|
+
} catch (cause) {
|
|
12523
|
+
setError(cause?.message ?? "\u7FA4\u804A\u54CD\u5E94\u65B9\u5F0F\u4FEE\u6539\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5\u3002");
|
|
12524
|
+
} finally {
|
|
12525
|
+
setSaving(false);
|
|
12526
|
+
}
|
|
12527
|
+
};
|
|
12528
|
+
const authorize = async () => {
|
|
12529
|
+
if (current !== "all" || saving || authorizing || disabled || authorizationDisabled) return;
|
|
12530
|
+
setAuthorizing(true);
|
|
12531
|
+
setError(null);
|
|
12532
|
+
try {
|
|
12533
|
+
await onAuthorize?.();
|
|
12534
|
+
} catch (cause) {
|
|
12535
|
+
setError(cause?.message ?? "\u7FA4\u6D88\u606F\u6743\u9650\u6388\u6743\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5\u3002");
|
|
12536
|
+
} finally {
|
|
12537
|
+
setAuthorizing(false);
|
|
12538
|
+
}
|
|
12539
|
+
};
|
|
12540
|
+
return h2(
|
|
12541
|
+
"section",
|
|
12542
|
+
{
|
|
12543
|
+
className: "dim-feishuGroupControl",
|
|
12544
|
+
"aria-labelledby": "dim-feishu-group-response-title"
|
|
12545
|
+
},
|
|
12546
|
+
h2(
|
|
12547
|
+
"div",
|
|
12548
|
+
{ className: "dim-feishuGroupControlHeader" },
|
|
12549
|
+
h2("h3", { id: "dim-feishu-group-response-title" }, "\u7FA4\u804A\u54CD\u5E94\u65B9\u5F0F"),
|
|
12550
|
+
saving || authorizing ? h2(
|
|
12551
|
+
"span",
|
|
12552
|
+
{ className: "dim-feishuGroupControlStatus", role: "status" },
|
|
12553
|
+
saving ? "\u4FDD\u5B58\u4E2D\u2026" : "\u6B63\u5728\u51C6\u5907\u6388\u6743\u2026"
|
|
12554
|
+
) : null
|
|
12555
|
+
),
|
|
12556
|
+
h2(
|
|
12557
|
+
"select",
|
|
12558
|
+
{
|
|
12559
|
+
className: "dim-feishuGroupSelect",
|
|
12560
|
+
value: current,
|
|
12561
|
+
disabled: disabled || saving,
|
|
12562
|
+
"aria-label": "\u7FA4\u804A\u54CD\u5E94\u65B9\u5F0F",
|
|
12563
|
+
onChange: (event) => {
|
|
12564
|
+
void change(event);
|
|
12565
|
+
}
|
|
12566
|
+
},
|
|
12567
|
+
h2("option", { value: "mention" }, "\u4EC5\u5728 @\u673A\u5668\u4EBA\u65F6\u54CD\u5E94\uFF08\u63A8\u8350\uFF09"),
|
|
12568
|
+
h2("option", { value: "all" }, "\u54CD\u5E94\u6240\u6709\u7FA4\u6D88\u606F")
|
|
12569
|
+
),
|
|
12570
|
+
h2(
|
|
12571
|
+
"p",
|
|
12572
|
+
{ className: "dim-feishuGroupHelp" },
|
|
12573
|
+
current === "mention" ? permissionGranted ? "\u79C1\u804A\u59CB\u7EC8\u54CD\u5E94\uFF1B\u7FA4\u804A\u4EC5\u5904\u7406\u660E\u786E @\u5F53\u524D\u673A\u5668\u4EBA\u7684\u6D88\u606F\u3002\u7FA4\u6D88\u606F\u6743\u9650\u5DF2\u5F00\u901A\uFF0C\u518D\u6B21\u5207\u6362\u65E0\u9700\u6388\u6743\u3002" : "\u79C1\u804A\u59CB\u7EC8\u54CD\u5E94\uFF1B\u7FA4\u804A\u4EC5\u5904\u7406\u660E\u786E @\u5F53\u524D\u673A\u5668\u4EBA\u7684\u6D88\u606F\u3002\u9009\u62E9\u5168\u90E8\u6D88\u606F\u540E\u4F1A\u6253\u5F00\u98DE\u4E66\u5B98\u65B9\u6388\u6743\u6D41\u7A0B\u3002" : permissionGranted ? "\u5DF2\u5F00\u901A\u201C\u83B7\u53D6\u7FA4\u7EC4\u4E2D\u6240\u6709\u6D88\u606F\u201D\u6743\u9650\uFF08im:message.group_msg\uFF09\uFF1B\u673A\u5668\u4EBA\u4F1A\u5904\u7406\u7FA4\u804A\u4E2D\u7684\u6240\u6709\u53EF\u89C1\u6D88\u606F\u3002" : "\u5C1A\u672A\u786E\u8BA4\u201C\u83B7\u53D6\u7FA4\u7EC4\u4E2D\u6240\u6709\u6D88\u606F\u201D\u6743\u9650\uFF0C\u8BF7\u5B8C\u6210\u98DE\u4E66\u6388\u6743\u3002"
|
|
12574
|
+
),
|
|
12575
|
+
current === "all" ? h2(
|
|
12576
|
+
"div",
|
|
12577
|
+
{ className: "dim-feishuGroupPermissionAction" },
|
|
12578
|
+
h2(SettingsButton, {
|
|
12579
|
+
disabled: disabled || authorizationDisabled || saving || authorizing,
|
|
12580
|
+
"aria-busy": authorizing ? "true" : void 0,
|
|
12581
|
+
"aria-label": permissionGranted ? "\u91CD\u65B0\u6388\u6743\u7FA4\u6D88\u606F\u6743\u9650" : "\u6388\u6743\u7FA4\u6D88\u606F\u6743\u9650",
|
|
12582
|
+
onClick: () => {
|
|
12583
|
+
void authorize();
|
|
12584
|
+
}
|
|
12585
|
+
}, authorizing ? "\u6B63\u5728\u51C6\u5907\u2026" : permissionGranted ? "\u91CD\u65B0\u6388\u6743" : "\u53BB\u6388\u6743")
|
|
12586
|
+
) : null,
|
|
12587
|
+
error ? h2("p", {
|
|
12588
|
+
className: "dim-feishuGroupError",
|
|
12589
|
+
role: "alert"
|
|
12590
|
+
}, error) : null
|
|
12591
|
+
);
|
|
12592
|
+
}
|
|
12593
|
+
function GroupTopicReplyEditor({ value = false, disabled = false, onSave }) {
|
|
12594
|
+
const current = value === true ? "on" : "off";
|
|
12595
|
+
const [saving, setSaving] = React22.useState(false);
|
|
12596
|
+
const [error, setError] = React22.useState(null);
|
|
12597
|
+
const change = async (event) => {
|
|
12598
|
+
const next = event.target.value === "on";
|
|
12599
|
+
if ((next ? "on" : "off") === current || saving || disabled) return;
|
|
12600
|
+
setSaving(true);
|
|
12601
|
+
setError(null);
|
|
12602
|
+
try {
|
|
12603
|
+
await onSave?.(next);
|
|
12604
|
+
} catch (cause) {
|
|
12605
|
+
setError(cause?.message ?? "\u7FA4\u804A\u4EE5\u8BDD\u9898\u65B9\u5F0F\u56DE\u590D\u8BBE\u7F6E\u4FDD\u5B58\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5\u3002");
|
|
12606
|
+
} finally {
|
|
12607
|
+
setSaving(false);
|
|
12608
|
+
}
|
|
12609
|
+
};
|
|
12610
|
+
return h2(
|
|
12611
|
+
"section",
|
|
12612
|
+
{
|
|
12613
|
+
className: "dim-feishuGroupControl",
|
|
12614
|
+
"aria-labelledby": "dim-feishu-group-topic-title"
|
|
12615
|
+
},
|
|
12616
|
+
h2(
|
|
12617
|
+
"div",
|
|
12618
|
+
{ className: "dim-feishuGroupControlHeader" },
|
|
12619
|
+
h2("h3", { id: "dim-feishu-group-topic-title" }, "\u7FA4\u804A\u4EE5\u8BDD\u9898\u65B9\u5F0F\u56DE\u590D"),
|
|
12620
|
+
saving ? h2("span", { className: "dim-feishuGroupControlStatus", role: "status" }, "\u4FDD\u5B58\u4E2D\u2026") : null
|
|
12621
|
+
),
|
|
12622
|
+
h2(
|
|
12623
|
+
"select",
|
|
12624
|
+
{
|
|
12625
|
+
className: "dim-feishuGroupSelect",
|
|
12626
|
+
value: current,
|
|
12627
|
+
disabled: disabled || saving,
|
|
12628
|
+
"aria-label": "\u7FA4\u804A\u4EE5\u8BDD\u9898\u65B9\u5F0F\u56DE\u590D",
|
|
12629
|
+
onChange: (event) => {
|
|
12630
|
+
void change(event);
|
|
12631
|
+
}
|
|
12632
|
+
},
|
|
12633
|
+
h2("option", { value: "off" }, "\u5173\u95ED\uFF08\u7FA4\u5185\u76F4\u63A5\u56DE\u590D\uFF09"),
|
|
12634
|
+
h2("option", { value: "on" }, "\u5F00\u542F\uFF08\u81EA\u52A8\u5F00\u542F\u72EC\u7ACB\u98DE\u4E66\u8BDD\u9898\uFF09")
|
|
12635
|
+
),
|
|
12636
|
+
h2(
|
|
12637
|
+
"p",
|
|
12638
|
+
{ className: "dim-feishuGroupHelp" },
|
|
12639
|
+
"\u5F00\u542F\u540E\uFF0C\u7FA4\u804A\u4E2D\u5411\u673A\u5668\u4EBA\u63D0\u95EE\u4F1A\u81EA\u52A8\u5F00\u542F\u72EC\u7ACB\u98DE\u4E66\u8BDD\u9898\uFF0C\u56DE\u590D\u843D\u5728\u8BDD\u9898\u5185\uFF1B\u6BCF\u4E2A\u8BDD\u9898\u662F dsh \u4F1A\u8BDD\u5217\u8868\u91CC\u4E00\u6761\u72EC\u7ACB\u4F1A\u8BDD\uFF0C\u4E0A\u4E0B\u6587\u4E92\u4E0D\u4E32\u3002\u79C1\u804A\u4E0D\u53D7\u5F71\u54CD\u3002"
|
|
12640
|
+
),
|
|
12641
|
+
error ? h2("p", {
|
|
12642
|
+
className: "dim-feishuGroupError",
|
|
12643
|
+
role: "alert"
|
|
12644
|
+
}, error) : null
|
|
12645
|
+
);
|
|
12646
|
+
}
|
|
12647
|
+
function PermissionFlow({ provision, now, busy, botName, onRetry, onCancel, onClose }) {
|
|
12648
|
+
if (!provision) return null;
|
|
12649
|
+
const phase = provision.phase;
|
|
12650
|
+
const error = provision.error;
|
|
12651
|
+
if (phase === "creating" || phase === "connecting") {
|
|
12652
|
+
return h2(
|
|
12653
|
+
"section",
|
|
12654
|
+
{
|
|
12655
|
+
className: "dim-feishuGroupAuthorization dim-feishuGroupAuthorizationState",
|
|
12656
|
+
"aria-live": "polite",
|
|
12657
|
+
"aria-busy": "true"
|
|
12658
|
+
},
|
|
12659
|
+
h2("span", { className: "dim-feishuGroupSpinner", "aria-hidden": "true" }),
|
|
12660
|
+
h2(
|
|
12661
|
+
"div",
|
|
12662
|
+
null,
|
|
12663
|
+
h2("h3", null, phase === "creating" ? "\u6B63\u5728\u51C6\u5907\u6743\u9650\u6388\u6743\u4E8C\u7EF4\u7801" : "\u5DF2\u786E\u8BA4\uFF0C\u6B63\u5728\u542F\u7528\u5168\u90E8\u6D88\u606F\u6A21\u5F0F"),
|
|
12664
|
+
h2("p", null, phase === "creating" ? "\u6B63\u5728\u4E3A\u73B0\u6709\u98DE\u4E66\u5E94\u7528\u7533\u8BF7\u7FA4\u6D88\u606F\u6743\u9650\u4E8C\u7EF4\u7801\uFF0C\u8BF7\u7A0D\u5019\u3002" : "\u6743\u9650\u914D\u7F6E\u5DF2\u63D0\u4EA4\uFF0C\u6B63\u5728\u4FDD\u5B58\u8BBE\u7F6E\u5E76\u91CD\u8FDE\u6B64\u673A\u5668\u4EBA\uFF1B\u6B64\u9636\u6BB5\u65E0\u6CD5\u53D6\u6D88\uFF0C\u5176\u4ED6\u673A\u5668\u4EBA\u4E0D\u4F1A\u4E2D\u65AD\u3002")
|
|
12665
|
+
)
|
|
12666
|
+
);
|
|
12667
|
+
}
|
|
12668
|
+
if (phase === "error") {
|
|
12669
|
+
return h2(
|
|
12670
|
+
"section",
|
|
12671
|
+
{
|
|
12672
|
+
className: "dim-feishuGroupAuthorization dim-feishuGroupAuthorizationError",
|
|
12673
|
+
role: "alert"
|
|
12674
|
+
},
|
|
12675
|
+
h2(
|
|
12676
|
+
"div",
|
|
12677
|
+
null,
|
|
12678
|
+
h2("h3", null, "\u7FA4\u6D88\u606F\u6743\u9650\u6CA1\u6709\u5F00\u901A\u5B8C\u6210"),
|
|
12679
|
+
h2("p", null, error?.message ?? "\u7FA4\u6D88\u606F\u6743\u9650\u6388\u6743\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5\u3002"),
|
|
12680
|
+
error?.code ? h2("code", null, error.code) : null
|
|
12681
|
+
),
|
|
12682
|
+
h2(
|
|
12683
|
+
"div",
|
|
12684
|
+
{ className: "dim-feishuGroupAuthorizationActions" },
|
|
12685
|
+
h2(
|
|
12686
|
+
SettingsButton,
|
|
12687
|
+
{ kind: "primary", onClick: onRetry, disabled: busy },
|
|
12688
|
+
busy ? "\u6B63\u5728\u51C6\u5907\u2026" : "\u91CD\u65B0\u751F\u6210\u4E8C\u7EF4\u7801"
|
|
12689
|
+
),
|
|
12690
|
+
h2(SettingsButton, { onClick: onClose, disabled: busy }, "\u5173\u95ED")
|
|
12691
|
+
)
|
|
12692
|
+
);
|
|
12693
|
+
}
|
|
12694
|
+
const qrSource = safeQrSource7(provision.qrCodeDataUrl);
|
|
12695
|
+
const href = safeVerificationHref2(provision.verificationUrl);
|
|
12696
|
+
const remaining = Math.max(0, (provision.expiresAt ?? now) - now);
|
|
12697
|
+
const expired = provision.expired === true || remaining === 0;
|
|
12698
|
+
const progress = Math.min(1, remaining / Math.max(1, provision.durationMs ?? remaining));
|
|
12699
|
+
return h2(
|
|
12700
|
+
"section",
|
|
12701
|
+
{
|
|
12702
|
+
className: "dim-feishuGroupAuthorization",
|
|
12703
|
+
"aria-label": `${botName}\u7684\u98DE\u4E66\u6388\u6743\u6D41\u7A0B`
|
|
12704
|
+
},
|
|
12705
|
+
h2(
|
|
12706
|
+
"div",
|
|
12707
|
+
{ className: "dim-feishuGroupQrColumn" },
|
|
12708
|
+
h2(
|
|
12709
|
+
"div",
|
|
12710
|
+
{ className: "dim-feishuGroupQrFrame" },
|
|
12711
|
+
qrSource ? h2("img", {
|
|
12712
|
+
src: qrSource,
|
|
12713
|
+
alt: `\u7528\u4E8E\u4E3A${botName}\u5F00\u901A\u7FA4\u6D88\u606F\u6743\u9650\u7684\u4E00\u6B21\u6027\u6388\u6743\u4E8C\u7EF4\u7801`
|
|
12714
|
+
}) : h2(
|
|
12715
|
+
"div",
|
|
12716
|
+
{ className: "dim-feishuGroupQrFallback" },
|
|
12717
|
+
h2(QrPlaceholder),
|
|
12718
|
+
h2("span", null, "\u4E8C\u7EF4\u7801\u672A\u5C31\u7EEA\uFF0C\u8BF7\u6253\u5F00\u6388\u6743\u94FE\u63A5")
|
|
12719
|
+
),
|
|
12720
|
+
expired ? h2(
|
|
12721
|
+
"div",
|
|
12722
|
+
{ className: "dim-feishuGroupQrExpired", role: "status" },
|
|
12723
|
+
h2("span", null, "\u4E8C\u7EF4\u7801\u5DF2\u5931\u6548"),
|
|
12724
|
+
h2("small", null, "\u8BF7\u5237\u65B0\u540E\u91CD\u65B0\u626B\u7801")
|
|
12725
|
+
) : null
|
|
12726
|
+
),
|
|
12727
|
+
h2(
|
|
12728
|
+
"div",
|
|
12729
|
+
{
|
|
12730
|
+
className: "dim-feishuGroupCountdown",
|
|
12731
|
+
"aria-label": expired ? "\u4E8C\u7EF4\u7801\u5DF2\u5931\u6548" : `\u4E8C\u7EF4\u7801\u5269\u4F59 ${formatRemaining2(remaining)}`
|
|
12732
|
+
},
|
|
12733
|
+
h2("span", null, expired ? "\u7B49\u5F85\u5237\u65B0" : "\u4E8C\u7EF4\u7801\u6709\u6548\u65F6\u95F4"),
|
|
12734
|
+
h2("strong", null, formatRemaining2(remaining)),
|
|
12735
|
+
h2(
|
|
12736
|
+
"span",
|
|
12737
|
+
{ className: "dim-feishuGroupProgress", "aria-hidden": "true" },
|
|
12738
|
+
h2("span", { style: { width: `${Math.round(progress * 100)}%` } })
|
|
12739
|
+
)
|
|
12740
|
+
)
|
|
12741
|
+
),
|
|
12742
|
+
h2(
|
|
12743
|
+
"div",
|
|
12744
|
+
{ className: "dim-feishuGroupAuthorizationCopy" },
|
|
12745
|
+
h2(
|
|
12746
|
+
"span",
|
|
12747
|
+
{ className: "dim-feishuGroupAuthorizationEyebrow" },
|
|
12748
|
+
`\u6B63\u5728\u4E3A\u300C${botName}\u300D\u5F00\u901A\u7FA4\u6D88\u606F\u6743\u9650`
|
|
12749
|
+
),
|
|
12750
|
+
h2("h3", null, expired ? "\u5237\u65B0\u4E8C\u7EF4\u7801\u540E\u7EE7\u7EED" : "\u4F7F\u7528\u98DE\u4E66\u786E\u8BA4\u7FA4\u6D88\u606F\u6743\u9650"),
|
|
12751
|
+
h2(
|
|
12752
|
+
"p",
|
|
12753
|
+
null,
|
|
12754
|
+
"\u626B\u7801\u4F1A\u66F4\u65B0\u73B0\u6709\u98DE\u4E66\u5E94\u7528\uFF0C\u53EA\u589E\u91CF\u5F00\u901A\u201C\u83B7\u53D6\u7FA4\u7EC4\u4E2D\u6240\u6709\u6D88\u606F\u201D\u6743\u9650\uFF1B\u4E0D\u4F1A\u521B\u5EFA\u65B0\u5E94\u7528\u3002\u786E\u8BA4\u540E\u4F1A\u81EA\u52A8\u542F\u7528\u201C\u54CD\u5E94\u6240\u6709\u7FA4\u6D88\u606F\u201D\uFF0C\u5176\u4ED6\u673A\u5668\u4EBA\u4E0D\u53D7\u5F71\u54CD\u3002"
|
|
12755
|
+
),
|
|
12756
|
+
h2(
|
|
12757
|
+
"ol",
|
|
12758
|
+
null,
|
|
12759
|
+
h2("li", null, "\u6253\u5F00\u98DE\u4E66\u79FB\u52A8\u7AEF\uFF0C\u4F7F\u7528\u626B\u4E00\u626B\u8BFB\u53D6\u4E8C\u7EF4\u7801"),
|
|
12760
|
+
h2("li", null, "\u6838\u5BF9\u73B0\u6709\u5E94\u7528\uFF0C\u5E76\u786E\u8BA4\u201C\u83B7\u53D6\u7FA4\u7EC4\u4E2D\u6240\u6709\u6D88\u606F\u201D\u6743\u9650"),
|
|
12761
|
+
h2("li", null, "\u4FDD\u6301\u672C\u9875\u6253\u5F00\uFF0C\u7B49\u5F85\u6743\u9650\u751F\u6548\u5E76\u81EA\u52A8\u5207\u6362\u54CD\u5E94\u65B9\u5F0F")
|
|
12762
|
+
),
|
|
12763
|
+
h2(
|
|
12764
|
+
"div",
|
|
12765
|
+
{ className: "dim-feishuGroupAuthorizationActions" },
|
|
12766
|
+
expired ? h2(
|
|
12767
|
+
SettingsButton,
|
|
12768
|
+
{ kind: "primary", onClick: onRetry, disabled: busy },
|
|
12769
|
+
busy ? "\u5237\u65B0\u4E2D\u2026" : "\u5237\u65B0\u4E8C\u7EF4\u7801"
|
|
12770
|
+
) : href ? h2("a", {
|
|
12771
|
+
className: "dim-deliveryButton dim-feishuGroupAuthorizationLink",
|
|
12772
|
+
href,
|
|
12773
|
+
target: "_blank",
|
|
12774
|
+
rel: "noopener noreferrer"
|
|
12775
|
+
}, "\u5728\u98DE\u4E66\u4E2D\u6253\u5F00") : null,
|
|
12776
|
+
!expired ? h2(SettingsButton, { onClick: onRetry, disabled: busy }, "\u6362\u4E00\u4E2A\u4E8C\u7EF4\u7801") : null,
|
|
12777
|
+
h2(SettingsButton, { onClick: onCancel, disabled: busy }, "\u53D6\u6D88\u6388\u6743")
|
|
12778
|
+
)
|
|
12779
|
+
)
|
|
12780
|
+
);
|
|
12781
|
+
}
|
|
12782
|
+
function FeishuGroupSettingsPage({ account, rpcCall }) {
|
|
12783
|
+
const [settings, setSettings] = React22.useState(() => groupSettingsFrom(account));
|
|
12784
|
+
const [refreshing, setRefreshing] = React22.useState(false);
|
|
12785
|
+
const [refreshError, setRefreshError] = React22.useState(null);
|
|
12786
|
+
const [provision, setProvision] = React22.useState(null);
|
|
12787
|
+
const [provisionBusy, setProvisionBusy] = React22.useState(false);
|
|
12788
|
+
const [now, setNow] = React22.useState(() => Date.now());
|
|
12789
|
+
const mounted = React22.useRef(true);
|
|
12790
|
+
React22.useEffect(() => {
|
|
12791
|
+
setSettings(groupSettingsFrom(account));
|
|
12792
|
+
}, [
|
|
12793
|
+
account.botId,
|
|
12794
|
+
account.groupResponseMode,
|
|
12795
|
+
account.groupTopicReply,
|
|
12796
|
+
account.groupMessagePermissionGranted
|
|
12797
|
+
]);
|
|
12798
|
+
React22.useEffect(() => {
|
|
12799
|
+
mounted.current = true;
|
|
12800
|
+
return () => {
|
|
12801
|
+
mounted.current = false;
|
|
12802
|
+
};
|
|
12803
|
+
}, []);
|
|
12804
|
+
const invoke = React22.useCallback(async (endpoint, payload = {}, signal) => {
|
|
12805
|
+
if (typeof rpcCall !== "function") throw new Error("\u98DE\u4E66\u7FA4\u804A\u8BBE\u7F6E\u6682\u4E0D\u53EF\u7528\u3002");
|
|
12806
|
+
return unwrapRpcResult3(await rpcCall(endpoint, payload, signal));
|
|
12807
|
+
}, [rpcCall]);
|
|
12808
|
+
const applySnapshot = React22.useCallback((value) => {
|
|
12809
|
+
const result = targetBotFromSnapshot(value, account.botId);
|
|
12810
|
+
if (mounted.current) setSettings(groupSettingsFrom(result.bot));
|
|
12811
|
+
return result;
|
|
12812
|
+
}, [account.botId]);
|
|
12813
|
+
const loadSettings = React22.useCallback(async ({ signal, restoreProvisioning = false } = {}) => {
|
|
12814
|
+
setRefreshing(true);
|
|
12815
|
+
setRefreshError(null);
|
|
12816
|
+
try {
|
|
12817
|
+
const value = await invoke(FEISHU_ENDPOINTS.status, {}, signal);
|
|
12818
|
+
if (signal?.aborted || !mounted.current) return void 0;
|
|
12819
|
+
const result = applySnapshot(value);
|
|
12820
|
+
if (restoreProvisioning) {
|
|
12821
|
+
const active = result.snapshot.provisioning;
|
|
12822
|
+
if (active?.operation === GROUP_MESSAGE_PERMISSION_OPERATION2 && active.botId === account.botId) {
|
|
12823
|
+
const timestamp7 = Date.now();
|
|
12824
|
+
setNow(timestamp7);
|
|
12825
|
+
setProvision({
|
|
12826
|
+
phase: active.submitted ? "connecting" : "qr",
|
|
12827
|
+
...active,
|
|
12828
|
+
durationMs: Math.max(1, active.expiresAt - timestamp7),
|
|
12829
|
+
expired: !active.submitted && active.expiresAt <= timestamp7
|
|
12830
|
+
});
|
|
12831
|
+
}
|
|
12832
|
+
}
|
|
12833
|
+
return result.bot;
|
|
12834
|
+
} catch (cause) {
|
|
12835
|
+
if (signal?.aborted || cause?.name === "AbortError" || !mounted.current) return void 0;
|
|
12836
|
+
setRefreshError(presentError3(cause));
|
|
12837
|
+
return void 0;
|
|
12838
|
+
} finally {
|
|
12839
|
+
if (!signal?.aborted && mounted.current) setRefreshing(false);
|
|
12840
|
+
}
|
|
12841
|
+
}, [account.botId, applySnapshot, invoke]);
|
|
12842
|
+
React22.useEffect(() => {
|
|
12843
|
+
const controller = new AbortController();
|
|
12844
|
+
void loadSettings({ signal: controller.signal, restoreProvisioning: true });
|
|
12845
|
+
return () => controller.abort();
|
|
12846
|
+
}, [loadSettings]);
|
|
12847
|
+
const saveSetting = React22.useCallback(async (endpoint, payload) => {
|
|
12848
|
+
const value = await invoke(endpoint, { botId: account.botId, ...payload });
|
|
12849
|
+
applySnapshot(value);
|
|
12850
|
+
}, [account.botId, applySnapshot, invoke]);
|
|
12851
|
+
const startAuthorization = React22.useCallback(async ({ replace = false } = {}) => {
|
|
12852
|
+
if (provisionBusy) return;
|
|
12853
|
+
const previousAttemptId = provision?.attemptId;
|
|
12854
|
+
setProvisionBusy(true);
|
|
12855
|
+
setProvision({ phase: "creating", operation: GROUP_MESSAGE_PERMISSION_OPERATION2, botId: account.botId });
|
|
12856
|
+
try {
|
|
12857
|
+
if (replace && previousAttemptId) {
|
|
12858
|
+
try {
|
|
12859
|
+
await invoke(FEISHU_ENDPOINTS.cancelProvisioning, { attemptId: previousAttemptId });
|
|
12860
|
+
} catch {
|
|
12861
|
+
}
|
|
12862
|
+
}
|
|
12863
|
+
const normalized = normalizeProvisioning2(await invoke(
|
|
12864
|
+
FEISHU_ENDPOINTS.beginGroupMessagePermission,
|
|
12865
|
+
{ botId: account.botId }
|
|
12866
|
+
));
|
|
12867
|
+
if (normalized.operation !== GROUP_MESSAGE_PERMISSION_OPERATION2 || normalized.botId !== account.botId) {
|
|
12868
|
+
throw new Error("\u98DE\u4E66\u670D\u52A1\u8FD4\u56DE\u4E86\u4E0D\u5339\u914D\u7684\u7FA4\u6D88\u606F\u6743\u9650\u4E8C\u7EF4\u7801");
|
|
12869
|
+
}
|
|
12870
|
+
const timestamp7 = Date.now();
|
|
12871
|
+
if (!mounted.current) return;
|
|
12872
|
+
setNow(timestamp7);
|
|
12873
|
+
setProvision({
|
|
12874
|
+
phase: normalized.submitted ? "connecting" : "qr",
|
|
12875
|
+
...normalized,
|
|
12876
|
+
durationMs: Math.max(1, normalized.expiresAt - timestamp7),
|
|
12877
|
+
expired: false
|
|
12878
|
+
});
|
|
12879
|
+
} catch (cause) {
|
|
12880
|
+
if (!mounted.current) return;
|
|
12881
|
+
setProvision({
|
|
12882
|
+
phase: "error",
|
|
12883
|
+
operation: GROUP_MESSAGE_PERMISSION_OPERATION2,
|
|
12884
|
+
botId: account.botId,
|
|
12885
|
+
...previousAttemptId ? { attemptId: previousAttemptId } : {},
|
|
12886
|
+
error: presentError3(cause)
|
|
12887
|
+
});
|
|
12888
|
+
} finally {
|
|
12889
|
+
if (mounted.current) setProvisionBusy(false);
|
|
12890
|
+
}
|
|
12891
|
+
}, [account.botId, invoke, provision?.attemptId, provisionBusy]);
|
|
12892
|
+
const finishAuthorization = React22.useCallback(async (signal) => {
|
|
12893
|
+
const bot = await loadSettings({ signal, restoreProvisioning: false });
|
|
12894
|
+
if (signal?.aborted || !mounted.current) return;
|
|
12895
|
+
if (!bot) throw new Error("\u7FA4\u6D88\u606F\u6743\u9650\u5DF2\u66F4\u65B0\uFF0C\u4F46\u6682\u65F6\u65E0\u6CD5\u786E\u8BA4\u673A\u5668\u4EBA\u8FDE\u63A5\u72B6\u6001");
|
|
12896
|
+
setProvision(null);
|
|
12897
|
+
}, [loadSettings]);
|
|
12898
|
+
React22.useEffect(() => {
|
|
12899
|
+
if (!provision?.attemptId || !["qr", "connecting"].includes(provision.phase) || provision.expired) return void 0;
|
|
12900
|
+
const timerHost = globalThis.window ?? globalThis;
|
|
12901
|
+
const controller = new AbortController();
|
|
12902
|
+
const timer = timerHost.setTimeout(async () => {
|
|
12903
|
+
try {
|
|
12904
|
+
const result = normalizePollResult(await invoke(
|
|
12905
|
+
FEISHU_ENDPOINTS.pollProvisioning,
|
|
12906
|
+
{ attemptId: provision.attemptId },
|
|
12907
|
+
controller.signal
|
|
12908
|
+
));
|
|
12909
|
+
if (result.operation !== GROUP_MESSAGE_PERMISSION_OPERATION2 || result.botId !== account.botId) {
|
|
12910
|
+
throw new Error("\u98DE\u4E66\u670D\u52A1\u8FD4\u56DE\u4E86\u4E0D\u5339\u914D\u7684\u6CE8\u518C\u8FDB\u5EA6");
|
|
12911
|
+
}
|
|
12912
|
+
if (result.status === "connected") {
|
|
12913
|
+
await finishAuthorization(controller.signal);
|
|
12914
|
+
return;
|
|
12915
|
+
}
|
|
12916
|
+
if (result.status === "failed") {
|
|
12917
|
+
const error = new Error(result.message ?? "\u98DE\u4E66\u7FA4\u6D88\u606F\u6743\u9650\u5F00\u901A\u5931\u8D25");
|
|
12918
|
+
error.code = "FEISHU_PROVISION_FAILED";
|
|
12919
|
+
throw error;
|
|
12920
|
+
}
|
|
12921
|
+
if (result.status === "expired") {
|
|
12922
|
+
if (mounted.current) setProvision((current) => current?.attemptId === provision.attemptId ? { ...current, phase: "qr", expired: true } : current);
|
|
12923
|
+
return;
|
|
12924
|
+
}
|
|
12925
|
+
if (mounted.current) {
|
|
12926
|
+
setProvision((current) => current?.attemptId === provision.attemptId ? {
|
|
12927
|
+
...current,
|
|
12928
|
+
...result.provisioning ?? {},
|
|
12929
|
+
phase: ["scanned", "connecting"].includes(result.status) ? "connecting" : "qr"
|
|
12930
|
+
} : current);
|
|
12931
|
+
}
|
|
12932
|
+
} catch (cause) {
|
|
12933
|
+
if (controller.signal.aborted || cause?.name === "AbortError" || !mounted.current) return;
|
|
12934
|
+
setProvision((current) => current?.attemptId === provision.attemptId ? { ...current, phase: "error", error: presentError3(cause) } : current);
|
|
12935
|
+
}
|
|
12936
|
+
}, provision.pollIntervalMs ?? 1800);
|
|
12937
|
+
return () => {
|
|
12938
|
+
controller.abort();
|
|
12939
|
+
timerHost.clearTimeout(timer);
|
|
12940
|
+
};
|
|
12941
|
+
}, [account.botId, finishAuthorization, invoke, provision]);
|
|
12942
|
+
React22.useEffect(() => {
|
|
12943
|
+
if (!provision?.attemptId || provision.phase !== "qr" || provision.expired) return void 0;
|
|
12944
|
+
const timerHost = globalThis.window ?? globalThis;
|
|
12945
|
+
const tick = () => {
|
|
12946
|
+
const timestamp7 = Date.now();
|
|
12947
|
+
setNow(timestamp7);
|
|
12948
|
+
if (timestamp7 >= provision.expiresAt) {
|
|
12949
|
+
setProvision((current) => current?.attemptId === provision.attemptId ? { ...current, expired: true } : current);
|
|
12950
|
+
}
|
|
12951
|
+
};
|
|
12952
|
+
tick();
|
|
12953
|
+
const timer = timerHost.setInterval(tick, 1e3);
|
|
12954
|
+
return () => timerHost.clearInterval(timer);
|
|
12955
|
+
}, [provision?.attemptId, provision?.expired, provision?.expiresAt, provision?.phase]);
|
|
12956
|
+
const cancelAuthorization = React22.useCallback(async () => {
|
|
12957
|
+
if (!provision?.attemptId || provisionBusy) {
|
|
12958
|
+
setProvision(null);
|
|
12959
|
+
return;
|
|
12960
|
+
}
|
|
12961
|
+
setProvisionBusy(true);
|
|
12962
|
+
try {
|
|
12963
|
+
const result = normalizePollResult(await invoke(
|
|
12964
|
+
FEISHU_ENDPOINTS.cancelProvisioning,
|
|
12965
|
+
{ attemptId: provision.attemptId }
|
|
12966
|
+
));
|
|
12967
|
+
if (result.operation !== GROUP_MESSAGE_PERMISSION_OPERATION2 || result.botId !== account.botId) {
|
|
12968
|
+
throw new Error("\u98DE\u4E66\u670D\u52A1\u8FD4\u56DE\u4E86\u4E0D\u5339\u914D\u7684\u6CE8\u518C\u8FDB\u5EA6");
|
|
12969
|
+
}
|
|
12970
|
+
if (result.status === "connecting") {
|
|
12971
|
+
setProvision((current) => ({ ...current, phase: "connecting", submitted: true }));
|
|
12972
|
+
return;
|
|
12973
|
+
}
|
|
12974
|
+
if (result.status === "connected") {
|
|
12975
|
+
await finishAuthorization();
|
|
12976
|
+
return;
|
|
12977
|
+
}
|
|
12978
|
+
setProvision(null);
|
|
12979
|
+
await loadSettings({ restoreProvisioning: false });
|
|
12980
|
+
} catch (cause) {
|
|
12981
|
+
if (mounted.current) {
|
|
12982
|
+
setProvision((current) => ({ ...current, phase: "error", error: presentError3(cause) }));
|
|
12983
|
+
}
|
|
12984
|
+
} finally {
|
|
12985
|
+
if (mounted.current) setProvisionBusy(false);
|
|
12986
|
+
}
|
|
12987
|
+
}, [account.botId, finishAuthorization, invoke, loadSettings, provision, provisionBusy]);
|
|
12988
|
+
const disabled = refreshing || Boolean(provision);
|
|
12989
|
+
return h2(
|
|
12990
|
+
"section",
|
|
12991
|
+
{
|
|
12992
|
+
className: "dim-feishuGroupSettings",
|
|
12993
|
+
"aria-label": "\u7FA4\u804A\u8BBE\u7F6E"
|
|
12994
|
+
},
|
|
12995
|
+
refreshError ? h2("p", {
|
|
12996
|
+
className: "dim-feishuGroupRefreshError",
|
|
12997
|
+
role: "alert"
|
|
12998
|
+
}, refreshError.message) : null,
|
|
12999
|
+
h2(
|
|
13000
|
+
"div",
|
|
13001
|
+
{ className: "dim-feishuGroupControls" },
|
|
13002
|
+
h2(GroupResponseModeEditor, {
|
|
13003
|
+
value: settings.groupResponseMode,
|
|
13004
|
+
permissionGranted: settings.groupMessagePermissionGranted,
|
|
13005
|
+
disabled,
|
|
13006
|
+
authorizationDisabled: provisionBusy,
|
|
13007
|
+
onSave: async (groupResponseMode) => {
|
|
13008
|
+
if (groupResponseMode === "all" && !settings.groupMessagePermissionGranted) {
|
|
13009
|
+
await startAuthorization();
|
|
13010
|
+
return;
|
|
13011
|
+
}
|
|
13012
|
+
await saveSetting(FEISHU_ENDPOINTS.setGroupResponseMode, { groupResponseMode });
|
|
13013
|
+
},
|
|
13014
|
+
onAuthorize: () => startAuthorization()
|
|
13015
|
+
}),
|
|
13016
|
+
h2(GroupTopicReplyEditor, {
|
|
13017
|
+
value: settings.groupTopicReply,
|
|
13018
|
+
disabled,
|
|
13019
|
+
onSave: (groupTopicReply) => saveSetting(
|
|
13020
|
+
FEISHU_ENDPOINTS.setGroupTopicReply,
|
|
13021
|
+
{ groupTopicReply }
|
|
13022
|
+
)
|
|
13023
|
+
})
|
|
13024
|
+
),
|
|
13025
|
+
h2(PermissionFlow, {
|
|
13026
|
+
provision,
|
|
13027
|
+
now,
|
|
13028
|
+
busy: provisionBusy,
|
|
13029
|
+
botName: account.botName || "\u5F53\u524D\u673A\u5668\u4EBA",
|
|
13030
|
+
onRetry: () => {
|
|
13031
|
+
void startAuthorization({ replace: true });
|
|
13032
|
+
},
|
|
13033
|
+
onCancel: () => {
|
|
13034
|
+
void cancelAuthorization();
|
|
13035
|
+
},
|
|
13036
|
+
onClose: () => {
|
|
13037
|
+
setProvision(null);
|
|
13038
|
+
void loadSettings({ restoreProvisioning: true });
|
|
13039
|
+
}
|
|
13040
|
+
})
|
|
13041
|
+
);
|
|
13042
|
+
}
|
|
13043
|
+
|
|
13044
|
+
// plugin-src/client/delivery-settings.js
|
|
13045
|
+
var DELIVERY_RPC_CHANNEL = "/dsh-im-delivery";
|
|
13046
|
+
var DELIVERY_DOCS_URL = Object.freeze({
|
|
13047
|
+
zh: "https://github.com/xmanrui/dsh-im/blob/main/PROACTIVE_DELIVERY.md",
|
|
13048
|
+
en: "https://github.com/xmanrui/dsh-im/blob/main/PROACTIVE_DELIVERY.en.md"
|
|
13049
|
+
});
|
|
13050
|
+
var DELIVERY_ENDPOINTS = Object.freeze({
|
|
13051
|
+
list: "target.list",
|
|
13052
|
+
listSuggestions: "target.suggestion.list",
|
|
13053
|
+
create: "target.create",
|
|
13054
|
+
update: "target.update",
|
|
13055
|
+
delete: "target.delete",
|
|
13056
|
+
sessionSync: "target.session-sync.set",
|
|
13057
|
+
test: "target.test"
|
|
13058
|
+
});
|
|
13059
|
+
var BOT_SETTINGS_TABS = Object.freeze([
|
|
13060
|
+
Object.freeze({ id: "delivery", label: "\u6295\u9012\u8BBE\u7F6E" }),
|
|
13061
|
+
Object.freeze({ id: "access", label: "\u8BBF\u95EE\u8BBE\u7F6E" })
|
|
13062
|
+
]);
|
|
13063
|
+
var FEISHU_BOT_SETTINGS_TABS = Object.freeze([
|
|
13064
|
+
...BOT_SETTINGS_TABS,
|
|
13065
|
+
Object.freeze({ id: "group", label: "\u7FA4\u804A" })
|
|
13066
|
+
]);
|
|
13067
|
+
function botSettingsTabsForChannel(channel4) {
|
|
13068
|
+
return channel4 === "feishu" ? FEISHU_BOT_SETTINGS_TABS : BOT_SETTINGS_TABS;
|
|
13069
|
+
}
|
|
13070
|
+
var CHANNEL_DEFINITIONS = Object.freeze({
|
|
13071
|
+
weixin: {
|
|
13072
|
+
label: "\u5FAE\u4FE1",
|
|
13073
|
+
kinds: [{ value: "user", label: "\u7528\u6237" }],
|
|
13074
|
+
fields: { user: [{ key: "toUserId", label: "\u5FAE\u4FE1\u7528\u6237 ID", placeholder: "\u586B\u5199\u63A5\u6536\u6D88\u606F\u7684\u7528\u6237 ID" }] }
|
|
13075
|
+
},
|
|
13076
|
+
feishu: {
|
|
13077
|
+
label: "\u98DE\u4E66",
|
|
13078
|
+
kinds: [{ value: "user", label: "\u79C1\u804A" }, { value: "group", label: "\u7FA4\u804A" }],
|
|
13079
|
+
fields: {
|
|
13080
|
+
user: [{ key: "openId", label: "Open ID", placeholder: "ou_xxx" }],
|
|
13081
|
+
group: [{ key: "chatId", label: "\u7FA4 Chat ID", placeholder: "oc_xxx" }]
|
|
13082
|
+
}
|
|
13083
|
+
},
|
|
13084
|
+
dingtalk: {
|
|
13085
|
+
label: "\u9489\u9489",
|
|
13086
|
+
kinds: [{ value: "user", label: "\u7528\u6237" }, { value: "group", label: "\u7FA4\u804A" }],
|
|
13087
|
+
fields: {
|
|
13088
|
+
user: [{ key: "userId", label: "\u7528\u6237 ID", placeholder: "\u586B\u5199\u9489\u9489\u7528\u6237 ID" }],
|
|
13089
|
+
group: [{ key: "openConversationId", label: "\u7FA4 Open Conversation ID", placeholder: "cidxxx" }]
|
|
13090
|
+
}
|
|
13091
|
+
},
|
|
13092
|
+
wecom: {
|
|
13093
|
+
label: "\u4F01\u4E1A\u5FAE\u4FE1",
|
|
13094
|
+
kinds: [{ value: "user", label: "\u79C1\u804A" }, { value: "group", label: "\u7FA4\u804A" }],
|
|
13095
|
+
fields: {
|
|
13096
|
+
user: [{ key: "chatId", label: "\u7528\u6237 ID", placeholder: "\u586B\u5199\u4F01\u4E1A\u5FAE\u4FE1\u7528\u6237 ID" }],
|
|
13097
|
+
group: [{ key: "chatId", label: "\u7FA4 Chat ID", placeholder: "\u586B\u5199\u7FA4 chatid" }]
|
|
13098
|
+
}
|
|
13099
|
+
},
|
|
13100
|
+
qq: {
|
|
13101
|
+
label: "QQ",
|
|
13102
|
+
kinds: [{ value: "user", label: "\u5355\u804A" }, { value: "group", label: "\u7FA4\u804A" }],
|
|
13103
|
+
fields: {
|
|
13104
|
+
user: [{ key: "userOpenId", label: "\u7528\u6237 Open ID", placeholder: "\u586B\u5199 user_openid" }],
|
|
13105
|
+
group: [{ key: "groupOpenId", label: "\u7FA4 Open ID", placeholder: "\u586B\u5199 group_openid" }]
|
|
13106
|
+
}
|
|
13107
|
+
},
|
|
13108
|
+
slack: {
|
|
13109
|
+
label: "Slack",
|
|
13110
|
+
kinds: [{ value: "conversation", label: "\u4F1A\u8BDD" }, { value: "thread", label: "\u7EBF\u7A0B" }],
|
|
13111
|
+
fields: {
|
|
13112
|
+
conversation: [{ key: "channelId", label: "Channel ID", placeholder: "C0123456789" }],
|
|
13113
|
+
thread: [
|
|
13114
|
+
{ key: "channelId", label: "Channel ID", placeholder: "C0123456789" },
|
|
13115
|
+
{ key: "threadTs", label: "Thread \u65F6\u95F4\u6233", placeholder: "1712345678.123456" }
|
|
13116
|
+
]
|
|
13117
|
+
}
|
|
13118
|
+
},
|
|
13119
|
+
telegram: {
|
|
13120
|
+
label: "Telegram",
|
|
13121
|
+
kinds: [{ value: "chat", label: "\u804A\u5929" }, { value: "topic", label: "\u8BDD\u9898" }],
|
|
13122
|
+
fields: {
|
|
13123
|
+
chat: [{ key: "chatId", label: "Chat ID", placeholder: "-1001234567890", inputMode: "numeric" }],
|
|
13124
|
+
topic: [
|
|
13125
|
+
{ key: "chatId", label: "Chat ID", placeholder: "-1001234567890", inputMode: "numeric" },
|
|
12375
13126
|
{ key: "messageThreadId", label: "Topic ID", placeholder: "123", inputMode: "numeric", integer: true }
|
|
12376
13127
|
]
|
|
12377
13128
|
}
|
|
@@ -12511,13 +13262,13 @@ function TargetForm({
|
|
|
12511
13262
|
}) {
|
|
12512
13263
|
const editing = mode === "edit";
|
|
12513
13264
|
const initialKind = initialValue?.kind && definition.fields[initialValue.kind] ? initialValue.kind : definition.kinds[0].value;
|
|
12514
|
-
const [targetId, setTargetId] =
|
|
12515
|
-
const [name2, setName] =
|
|
12516
|
-
const [kind, setKind] =
|
|
12517
|
-
const [route, setRoute] =
|
|
12518
|
-
const [error, setError] =
|
|
12519
|
-
const [testing, setTesting] =
|
|
12520
|
-
const [testState, setTestState] =
|
|
13265
|
+
const [targetId, setTargetId] = React23.useState(initialValue?.targetId ?? "");
|
|
13266
|
+
const [name2, setName] = React23.useState(initialValue?.name ?? "");
|
|
13267
|
+
const [kind, setKind] = React23.useState(initialKind);
|
|
13268
|
+
const [route, setRoute] = React23.useState(initialValue?.route ?? {});
|
|
13269
|
+
const [error, setError] = React23.useState(null);
|
|
13270
|
+
const [testing, setTesting] = React23.useState(false);
|
|
13271
|
+
const [testState, setTestState] = React23.useState(null);
|
|
12521
13272
|
const currentTarget = () => {
|
|
12522
13273
|
const normalizedRoute = Object.fromEntries(fieldsFor(definition, kind).map((field) => {
|
|
12523
13274
|
const raw = String(route[field.key] ?? "").trim();
|
|
@@ -12563,7 +13314,7 @@ function TargetForm({
|
|
|
12563
13314
|
"div",
|
|
12564
13315
|
{ className: "dim-targetFormHeading" },
|
|
12565
13316
|
h2("h3", null, editing ? "\u7F16\u8F91\u6295\u9012\u76EE\u6807" : "\u65B0\u5EFA\u6295\u9012\u76EE\u6807"),
|
|
12566
|
-
editing ? null : h2("p", null, source === "suggestion" ? "\u5DF2\u4ECE\u4F1A\u8BDD\u81EA\u52A8\u586B\u5165\u76EE\u6807\u4FE1\u606F\uFF1B\u786E\u8BA4\u540E\u518D\u4FDD\u5B58\u3002" : "\u8BF7\u624B\u52A8\u586B\u5199\u4ECE\u5BF9\u5E94\u5E73\u53F0\u53D6\u5F97\u7684\u539F\u751F\u6807\u8BC6\u3002")
|
|
13317
|
+
editing ? initialValue?.sessionSync?.enabled ? h2("p", null, "\u4FEE\u6539\u63A5\u6536\u4F4D\u7F6E\u4F1A\u5173\u95ED\u4F1A\u8BDD\u53CC\u5411\u540C\u6B65\u3002") : null : h2("p", null, source === "suggestion" ? "\u5DF2\u4ECE\u4F1A\u8BDD\u81EA\u52A8\u586B\u5165\u76EE\u6807\u4FE1\u606F\uFF1B\u786E\u8BA4\u540E\u518D\u4FDD\u5B58\u3002" : "\u8BF7\u624B\u52A8\u586B\u5199\u4ECE\u5BF9\u5E94\u5E73\u53F0\u53D6\u5F97\u7684\u539F\u751F\u6807\u8BC6\u3002")
|
|
12567
13318
|
),
|
|
12568
13319
|
h2(
|
|
12569
13320
|
"div",
|
|
@@ -12734,7 +13485,7 @@ function TargetSuggestionPicker({
|
|
|
12734
13485
|
suggestions.map((suggestion, index) => {
|
|
12735
13486
|
const identity = routeIdentity(definition, suggestion);
|
|
12736
13487
|
const added = configured.has(identity);
|
|
12737
|
-
return
|
|
13488
|
+
return React23.createElement("option", {
|
|
12738
13489
|
key: suggestion.id ?? suggestion.suggestionId ?? `${identity}:${index}`,
|
|
12739
13490
|
value: String(index),
|
|
12740
13491
|
disabled: added
|
|
@@ -12751,10 +13502,13 @@ function TargetSuggestionPicker({
|
|
|
12751
13502
|
);
|
|
12752
13503
|
}
|
|
12753
13504
|
function TargetRow({ definition, target, botId, connected, rpcCall, onChanged, onEdit }) {
|
|
12754
|
-
const [action, setAction] =
|
|
12755
|
-
const [testState, setTestState] =
|
|
12756
|
-
const [
|
|
12757
|
-
const [
|
|
13505
|
+
const [action, setAction] = React23.useState(null);
|
|
13506
|
+
const [testState, setTestState] = React23.useState(null);
|
|
13507
|
+
const [syncFeedback, setSyncFeedback] = React23.useState(null);
|
|
13508
|
+
const [copyState, setCopyState] = React23.useState(null);
|
|
13509
|
+
const [confirmDelete, setConfirmDelete] = React23.useState(false);
|
|
13510
|
+
const sessionSync = target.sessionSync ?? { enabled: false, state: "unavailable" };
|
|
13511
|
+
const syncDescription = sessionSync.state === "active" ? "\u81EA\u52A8\u8DDF\u968F\u8BE5\u79C1\u804A\u7684\u5F53\u524D\u4F1A\u8BDD" : sessionSync.state === "waiting" ? "\u7B49\u5F85\u8BE5\u79C1\u804A\u5EFA\u7ACB\u65B0\u4F1A\u8BDD" : sessionSync.state === "unavailable" ? "\u4EC5\u652F\u6301\u5DF2\u7ECF\u804A\u8FC7\u3001\u5DF2\u5EFA\u7ACB\u5F53\u524D\u4F1A\u8BDD\u4E14\u4F7F\u7528\u5F53\u524D Host Harness \u7684\u79C1\u804A\u76EE\u6807" : "\u5173\u95ED\u65F6\u4E0D\u53D1\u9001 DSH \u4F1A\u8BDD\u6D88\u606F";
|
|
12758
13512
|
const testTarget = async () => {
|
|
12759
13513
|
setAction("test");
|
|
12760
13514
|
setTestState(null);
|
|
@@ -12787,6 +13541,25 @@ function TargetRow({ definition, target, botId, connected, rpcCall, onChanged, o
|
|
|
12787
13541
|
setConfirmDelete(false);
|
|
12788
13542
|
}
|
|
12789
13543
|
};
|
|
13544
|
+
const setSessionSync = async (enabled) => {
|
|
13545
|
+
setAction("sync");
|
|
13546
|
+
setSyncFeedback(null);
|
|
13547
|
+
try {
|
|
13548
|
+
await rpcCall(DELIVERY_ENDPOINTS.sessionSync, {
|
|
13549
|
+
botId,
|
|
13550
|
+
targetId: target.targetId,
|
|
13551
|
+
enabled
|
|
13552
|
+
});
|
|
13553
|
+
await onChanged();
|
|
13554
|
+
} catch (error) {
|
|
13555
|
+
setSyncFeedback({
|
|
13556
|
+
tone: "error",
|
|
13557
|
+
message: error?.code === "session-sync-unavailable" ? "\u4F1A\u8BDD\u540C\u6B65\u4EC5\u652F\u6301\u5DF2\u7ECF\u804A\u8FC7\u3001\u5DF2\u5EFA\u7ACB\u5F53\u524D\u4F1A\u8BDD\u4E14\u4F7F\u7528\u5F53\u524D Host Harness \u7684\u79C1\u804A\u76EE\u6807\u3002" : presentError10(error, "\u4F1A\u8BDD\u540C\u6B65\u8BBE\u7F6E\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002")
|
|
13558
|
+
});
|
|
13559
|
+
} finally {
|
|
13560
|
+
setAction(null);
|
|
13561
|
+
}
|
|
13562
|
+
};
|
|
12790
13563
|
return h2(
|
|
12791
13564
|
"li",
|
|
12792
13565
|
{ className: "dim-targetRow", "data-target-id": target.targetId },
|
|
@@ -12796,7 +13569,7 @@ function TargetRow({ definition, target, botId, connected, rpcCall, onChanged, o
|
|
|
12796
13569
|
h2(
|
|
12797
13570
|
"div",
|
|
12798
13571
|
{ className: "dim-targetTitle" },
|
|
12799
|
-
|
|
13572
|
+
React23.createElement("strong", null, target.name || target.targetId),
|
|
12800
13573
|
h2("span", null, kindLabel(definition, target.kind))
|
|
12801
13574
|
),
|
|
12802
13575
|
h2("code", null, `targetId: ${target.targetId}`)
|
|
@@ -12818,7 +13591,29 @@ function TargetRow({ definition, target, botId, connected, rpcCall, onChanged, o
|
|
|
12818
13591
|
disabled: Boolean(action)
|
|
12819
13592
|
}, "\u5220\u9664")
|
|
12820
13593
|
),
|
|
13594
|
+
h2(
|
|
13595
|
+
"label",
|
|
13596
|
+
{ className: "dim-targetSessionSync" },
|
|
13597
|
+
h2(
|
|
13598
|
+
"span",
|
|
13599
|
+
{ className: "dim-targetSessionSyncCopy" },
|
|
13600
|
+
h2("strong", null, "\u4F1A\u8BDD\u53CC\u5411\u540C\u6B65"),
|
|
13601
|
+
h2("small", null, syncDescription)
|
|
13602
|
+
),
|
|
13603
|
+
h2("input", {
|
|
13604
|
+
type: "checkbox",
|
|
13605
|
+
checked: sessionSync.enabled === true,
|
|
13606
|
+
disabled: Boolean(action) || sessionSync.enabled !== true && sessionSync.state === "unavailable",
|
|
13607
|
+
onChange: (event) => void setSessionSync(event.target.checked),
|
|
13608
|
+
"aria-label": "\u4F1A\u8BDD\u53CC\u5411\u540C\u6B65"
|
|
13609
|
+
})
|
|
13610
|
+
),
|
|
12821
13611
|
copyState ? h2("p", { className: "dim-targetFeedback", role: "status" }, copyState) : null,
|
|
13612
|
+
syncFeedback ? h2("p", {
|
|
13613
|
+
className: "dim-targetFeedback",
|
|
13614
|
+
"data-tone": syncFeedback.tone,
|
|
13615
|
+
role: "alert"
|
|
13616
|
+
}, syncFeedback.message) : null,
|
|
12822
13617
|
testState ? h2("p", {
|
|
12823
13618
|
className: "dim-targetFeedback",
|
|
12824
13619
|
"data-tone": testState.tone,
|
|
@@ -12833,7 +13628,8 @@ function TargetRow({ definition, target, botId, connected, rpcCall, onChanged, o
|
|
|
12833
13628
|
null,
|
|
12834
13629
|
"\u5220\u9664 ",
|
|
12835
13630
|
h2("code", null, target.targetId),
|
|
12836
|
-
"\uFF1F\u4F7F\u7528\u8FD9\u4E2A targetId \u7684\u5916\u90E8\u8C03\u7528\u5C06\u8FD4\u56DE unknown-target\u3002"
|
|
13631
|
+
"\uFF1F\u4F7F\u7528\u8FD9\u4E2A targetId \u7684\u5916\u90E8\u8C03\u7528\u5C06\u8FD4\u56DE unknown-target\u3002",
|
|
13632
|
+
sessionSync.enabled ? " \u4F1A\u8BDD\u540C\u6B65\u8BBE\u7F6E\u4E5F\u4F1A\u4E00\u5E76\u5220\u9664\u3002" : null
|
|
12837
13633
|
),
|
|
12838
13634
|
h2(
|
|
12839
13635
|
"div",
|
|
@@ -12859,26 +13655,26 @@ function DeliveryTargetSettingsPage({
|
|
|
12859
13655
|
onBack
|
|
12860
13656
|
}) {
|
|
12861
13657
|
const definition = CHANNEL_DEFINITIONS[channel4];
|
|
12862
|
-
const [activeTabId, setActiveTabId] =
|
|
12863
|
-
const [phase, setPhase] =
|
|
12864
|
-
const [targets, setTargets] =
|
|
12865
|
-
const [suggestionPhase, setSuggestionPhase] =
|
|
12866
|
-
const [suggestions, setSuggestions] =
|
|
12867
|
-
const [suggestionError, setSuggestionError] =
|
|
12868
|
-
const [error, setError] =
|
|
12869
|
-
const [editor, setEditor] =
|
|
12870
|
-
const [saving, setSaving] =
|
|
12871
|
-
const [botCopyState, setBotCopyState] =
|
|
12872
|
-
const [accessPolicy, setAccessPolicy] =
|
|
12873
|
-
const mounted =
|
|
12874
|
-
|
|
13658
|
+
const [activeTabId, setActiveTabId] = React23.useState(BOT_SETTINGS_TABS[0].id);
|
|
13659
|
+
const [phase, setPhase] = React23.useState("loading");
|
|
13660
|
+
const [targets, setTargets] = React23.useState([]);
|
|
13661
|
+
const [suggestionPhase, setSuggestionPhase] = React23.useState("idle");
|
|
13662
|
+
const [suggestions, setSuggestions] = React23.useState([]);
|
|
13663
|
+
const [suggestionError, setSuggestionError] = React23.useState(null);
|
|
13664
|
+
const [error, setError] = React23.useState(null);
|
|
13665
|
+
const [editor, setEditor] = React23.useState(null);
|
|
13666
|
+
const [saving, setSaving] = React23.useState(false);
|
|
13667
|
+
const [botCopyState, setBotCopyState] = React23.useState(null);
|
|
13668
|
+
const [accessPolicy, setAccessPolicy] = React23.useState(account.accessPolicy);
|
|
13669
|
+
const mounted = React23.useRef(true);
|
|
13670
|
+
React23.useEffect(() => {
|
|
12875
13671
|
setAccessPolicy(account.accessPolicy);
|
|
12876
13672
|
}, [account.botId, account.accessPolicy]);
|
|
12877
|
-
const invoke =
|
|
13673
|
+
const invoke = React23.useCallback(async (endpoint, payload = {}, signal) => {
|
|
12878
13674
|
if (typeof rpcCall !== "function") throw new Error("\u6295\u9012\u76EE\u6807\u8BBE\u7F6E\u6682\u4E0D\u53EF\u7528\u3002");
|
|
12879
13675
|
return unwrapRpcResult11(await rpcCall(endpoint, payload, signal));
|
|
12880
13676
|
}, [rpcCall]);
|
|
12881
|
-
const loadTargets =
|
|
13677
|
+
const loadTargets = React23.useCallback(async ({ signal, silent = false } = {}) => {
|
|
12882
13678
|
if (!silent) setPhase("loading");
|
|
12883
13679
|
setError(null);
|
|
12884
13680
|
try {
|
|
@@ -12892,7 +13688,7 @@ function DeliveryTargetSettingsPage({
|
|
|
12892
13688
|
setPhase("error");
|
|
12893
13689
|
}
|
|
12894
13690
|
}, [account.botId, invoke]);
|
|
12895
|
-
const loadSuggestions =
|
|
13691
|
+
const loadSuggestions = React23.useCallback(async () => {
|
|
12896
13692
|
setSuggestionPhase("loading");
|
|
12897
13693
|
setSuggestionError(null);
|
|
12898
13694
|
try {
|
|
@@ -12906,7 +13702,7 @@ function DeliveryTargetSettingsPage({
|
|
|
12906
13702
|
setSuggestionPhase("error");
|
|
12907
13703
|
}
|
|
12908
13704
|
}, [account.botId, definition, invoke]);
|
|
12909
|
-
|
|
13705
|
+
React23.useEffect(() => {
|
|
12910
13706
|
mounted.current = true;
|
|
12911
13707
|
const controller = new AbortController();
|
|
12912
13708
|
void loadTargets({ signal: controller.signal });
|
|
@@ -12977,7 +13773,8 @@ function DeliveryTargetSettingsPage({
|
|
|
12977
13773
|
setBotCopyState(presentError10(caught, "\u590D\u5236\u5931\u8D25\u3002"));
|
|
12978
13774
|
}
|
|
12979
13775
|
};
|
|
12980
|
-
const
|
|
13776
|
+
const settingsTabs = botSettingsTabsForChannel(channel4);
|
|
13777
|
+
const activeTab = settingsTabs.find((tab) => tab.id === activeTabId) ?? settingsTabs[0];
|
|
12981
13778
|
const activeTabDomId = `dim-bot-settings-${activeTab.id}-tab`;
|
|
12982
13779
|
const activePanelId = `dim-bot-settings-${activeTab.id}-panel`;
|
|
12983
13780
|
return h2(
|
|
@@ -12998,7 +13795,7 @@ function DeliveryTargetSettingsPage({
|
|
|
12998
13795
|
className: "dim-botSettingsTabs",
|
|
12999
13796
|
role: "tablist",
|
|
13000
13797
|
"aria-label": "\u673A\u5668\u4EBA\u8BBE\u7F6E\u9875\u7B7E"
|
|
13001
|
-
},
|
|
13798
|
+
}, settingsTabs.map((tab) => h2("button", {
|
|
13002
13799
|
key: tab.id,
|
|
13003
13800
|
id: `dim-bot-settings-${tab.id}-tab`,
|
|
13004
13801
|
type: "button",
|
|
@@ -13023,8 +13820,11 @@ function DeliveryTargetSettingsPage({
|
|
|
13023
13820
|
account: { ...account, accessPolicy },
|
|
13024
13821
|
rpcCall: accessRpcCall,
|
|
13025
13822
|
onSaved: setAccessPolicy
|
|
13823
|
+
}) : activeTab.id === "group" && channel4 === "feishu" ? h2(FeishuGroupSettingsPage, {
|
|
13824
|
+
account,
|
|
13825
|
+
rpcCall: accessRpcCall
|
|
13026
13826
|
}) : h2(
|
|
13027
|
-
|
|
13827
|
+
React23.Fragment,
|
|
13028
13828
|
null,
|
|
13029
13829
|
h2(
|
|
13030
13830
|
"section",
|
|
@@ -13135,7 +13935,7 @@ function DeliveryTargetSettingsPage({
|
|
|
13135
13935
|
}
|
|
13136
13936
|
|
|
13137
13937
|
// plugin-src/client/global-settings.js
|
|
13138
|
-
var
|
|
13938
|
+
var React24 = __toESM(require("react"), 1);
|
|
13139
13939
|
|
|
13140
13940
|
// src/channels/shared/inbound-ttl.mjs
|
|
13141
13941
|
var DEFAULT_INBOUND_TTL_HOURS = 168;
|
|
@@ -13197,29 +13997,29 @@ function GlobalButton({ children, kind = "secondary", className = "", ...props }
|
|
|
13197
13997
|
}, children);
|
|
13198
13998
|
}
|
|
13199
13999
|
function GlobalSettingsPanel({ rpcCall }) {
|
|
13200
|
-
const [phase, setPhase] =
|
|
13201
|
-
const [loadError, setLoadError] =
|
|
13202
|
-
const [ttlInput, setTtlInput] =
|
|
13203
|
-
const [savedTtl, setSavedTtl] =
|
|
13204
|
-
const [ttlError, setTtlError] =
|
|
13205
|
-
const [saveError, setSaveError] =
|
|
13206
|
-
const [saveSucceeded, setSaveSucceeded] =
|
|
13207
|
-
const [isSaving, setIsSaving] =
|
|
13208
|
-
const [sweepConfirming, setSweepConfirming] =
|
|
13209
|
-
const [sweeping, setSweeping] =
|
|
13210
|
-
const ttlErrorId =
|
|
13211
|
-
const ttlHintsId =
|
|
13212
|
-
const sweepTriggerId =
|
|
13213
|
-
const sweepConfirmId =
|
|
13214
|
-
const sweepConfirmTextId =
|
|
13215
|
-
const sweepConfirmButtonId =
|
|
13216
|
-
const mounted =
|
|
13217
|
-
const saving =
|
|
13218
|
-
const invoke =
|
|
14000
|
+
const [phase, setPhase] = React24.useState("loading");
|
|
14001
|
+
const [loadError, setLoadError] = React24.useState(null);
|
|
14002
|
+
const [ttlInput, setTtlInput] = React24.useState("");
|
|
14003
|
+
const [savedTtl, setSavedTtl] = React24.useState(null);
|
|
14004
|
+
const [ttlError, setTtlError] = React24.useState(false);
|
|
14005
|
+
const [saveError, setSaveError] = React24.useState(null);
|
|
14006
|
+
const [saveSucceeded, setSaveSucceeded] = React24.useState(false);
|
|
14007
|
+
const [isSaving, setIsSaving] = React24.useState(false);
|
|
14008
|
+
const [sweepConfirming, setSweepConfirming] = React24.useState(false);
|
|
14009
|
+
const [sweeping, setSweeping] = React24.useState(false);
|
|
14010
|
+
const ttlErrorId = React24.useId();
|
|
14011
|
+
const ttlHintsId = React24.useId();
|
|
14012
|
+
const sweepTriggerId = React24.useId();
|
|
14013
|
+
const sweepConfirmId = React24.useId();
|
|
14014
|
+
const sweepConfirmTextId = React24.useId();
|
|
14015
|
+
const sweepConfirmButtonId = React24.useId();
|
|
14016
|
+
const mounted = React24.useRef(true);
|
|
14017
|
+
const saving = React24.useRef(false);
|
|
14018
|
+
const invoke = React24.useCallback(async (endpoint, payload = {}, signal) => {
|
|
13219
14019
|
if (typeof rpcCall !== "function") throw new Error("\u901A\u7528\u8BBE\u7F6E\u6682\u4E0D\u53EF\u7528\u3002");
|
|
13220
14020
|
return unwrapRpcResult12(await rpcCall(endpoint, payload, signal));
|
|
13221
14021
|
}, [rpcCall]);
|
|
13222
|
-
const loadSettings =
|
|
14022
|
+
const loadSettings = React24.useCallback(async ({ signal } = {}) => {
|
|
13223
14023
|
setPhase("loading");
|
|
13224
14024
|
setLoadError(null);
|
|
13225
14025
|
try {
|
|
@@ -13243,7 +14043,7 @@ function GlobalSettingsPanel({ rpcCall }) {
|
|
|
13243
14043
|
setPhase("error");
|
|
13244
14044
|
}
|
|
13245
14045
|
}, [invoke]);
|
|
13246
|
-
|
|
14046
|
+
React24.useEffect(() => {
|
|
13247
14047
|
mounted.current = true;
|
|
13248
14048
|
const controller = new AbortController();
|
|
13249
14049
|
void loadSettings({ signal: controller.signal });
|
|
@@ -13252,7 +14052,7 @@ function GlobalSettingsPanel({ rpcCall }) {
|
|
|
13252
14052
|
controller.abort();
|
|
13253
14053
|
};
|
|
13254
14054
|
}, [loadSettings]);
|
|
13255
|
-
|
|
14055
|
+
React24.useEffect(() => {
|
|
13256
14056
|
if (!sweepConfirming) return;
|
|
13257
14057
|
globalThis.document?.getElementById(sweepConfirmButtonId)?.focus();
|
|
13258
14058
|
}, [sweepConfirmButtonId, sweepConfirming]);
|
|
@@ -13950,6 +14750,45 @@ var CSS11 = String.raw`
|
|
|
13950
14750
|
.dim-botSettingsTab[aria-selected="true"]::after { background: var(--dsw-alias-state-business-primary, #3370ff); transform: scaleX(1); }
|
|
13951
14751
|
.dim-botSettingsTab:focus-visible { outline: 2px solid var(--dsw-alias-state-business-primary, #3370ff); outline-offset: -2px; border-radius: 5px; }
|
|
13952
14752
|
.dim-botSettingsTabPanel { min-width: 0; display: grid; gap: 14px; padding-top: 14px; }
|
|
14753
|
+
.dim-feishuGroupSettings { min-width: 0; display: grid; gap: 14px; }
|
|
14754
|
+
.dim-feishuGroupControls { min-width: 0; display: grid; gap: 12px; }
|
|
14755
|
+
.dim-feishuGroupControl { min-width: 0; display: grid; grid-template-columns: minmax(0, 1fr); gap: 10px; padding: 16px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 12px; background: var(--dsw-alias-bg-layer-3, #fff); }
|
|
14756
|
+
.dim-feishuGroupControlHeader { min-width: 0; display: flex; align-items: center; justify-content: space-between; gap: 12px; }
|
|
14757
|
+
.dim-feishuGroupControlHeader h3 { min-width: 0; margin: 0; color: var(--dsw-alias-label-primary, #1f2329); font-size: 14px; line-height: 21px; font-weight: 650; }
|
|
14758
|
+
.dim-feishuGroupControlStatus { flex: none; color: var(--dsw-alias-label-tertiary, #8f959e); font-size: 11px; line-height: 17px; }
|
|
14759
|
+
.dim-feishuGroupSelect { min-width: 0; width: 100%; height: 38px; padding: 0 34px 0 11px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 8px; color: var(--dsw-alias-label-primary, #1f2329); background: var(--dsw-alias-bg-layer-1, #fff); font: inherit; font-size: 13px; line-height: 38px; cursor: pointer; transition: border-color .15s ease, box-shadow .15s ease; }
|
|
14760
|
+
.dim-feishuGroupSelect:hover:not(:disabled) { border-color: color-mix(in srgb, var(--dsw-alias-state-business-primary, #3370ff) 42%, var(--dsw-alias-border-l2, #dfe1e5)); }
|
|
14761
|
+
.dim-feishuGroupSelect:focus-visible { outline: none; border-color: var(--dsw-alias-state-business-primary, #3370ff); box-shadow: 0 0 0 2px color-mix(in srgb, var(--dsw-alias-state-business-primary, #3370ff) 15%, transparent); }
|
|
14762
|
+
.dim-feishuGroupSelect:disabled { cursor: not-allowed; opacity: .55; }
|
|
14763
|
+
.dim-feishuGroupHelp { margin: -2px 0 0; color: var(--dsw-alias-label-tertiary, #8f959e); font-size: 12px; line-height: 19px; }
|
|
14764
|
+
.dim-feishuGroupPermissionAction { display: flex; justify-content: flex-start; }
|
|
14765
|
+
.dim-feishuGroupPermissionAction .dim-deliveryButton { color: var(--dsw-alias-state-business-primary, #3370ff); border-color: color-mix(in srgb, var(--dsw-alias-state-business-primary, #3370ff) 30%, var(--dsw-alias-border-l2, #dfe1e5)); }
|
|
14766
|
+
.dim-feishuGroupError, .dim-feishuGroupRefreshError { margin: 0; padding: 9px 11px; border-radius: 8px; font-size: 12px; line-height: 18px; }
|
|
14767
|
+
.dim-feishuGroupError, .dim-feishuGroupRefreshError { color: var(--dsw-alias-state-error-primary, #d54941); background: color-mix(in srgb, var(--dsw-alias-state-error-primary, #d54941) 7%, var(--dsw-alias-bg-layer-1, #fff)); }
|
|
14768
|
+
.dim-feishuGroupAuthorization { min-width: 0; display: grid; grid-template-columns: 184px minmax(0, 1fr); align-items: start; gap: 24px; padding: 18px; border: 1px solid color-mix(in srgb, var(--dsw-alias-state-business-primary, #3370ff) 30%, var(--dsw-alias-border-l2, #dfe1e5)); border-radius: 12px; background: color-mix(in srgb, var(--dsw-alias-state-business-primary, #3370ff) 2.5%, var(--dsw-alias-bg-layer-3, #fff)); }
|
|
14769
|
+
.dim-feishuGroupAuthorizationState { min-height: 126px; grid-template-columns: 32px minmax(0, 1fr); align-items: center; }
|
|
14770
|
+
.dim-feishuGroupAuthorizationState h3, .dim-feishuGroupAuthorizationError h3, .dim-feishuGroupAuthorizationCopy h3 { margin: 0; color: var(--dsw-alias-label-primary, #1f2329); font-size: 16px; line-height: 24px; font-weight: 650; }
|
|
14771
|
+
.dim-feishuGroupAuthorizationState p, .dim-feishuGroupAuthorizationError p, .dim-feishuGroupAuthorizationCopy > p { margin: 5px 0 0; color: var(--dsw-alias-label-secondary, #646a73); font-size: 12px; line-height: 19px; }
|
|
14772
|
+
.dim-feishuGroupSpinner { width: 24px; height: 24px; border: 3px solid var(--dsw-alias-border-l2, #dfe1e5); border-top-color: var(--dsw-alias-state-business-primary, #3370ff); border-radius: 50%; animation: dim-spin .8s linear infinite; }
|
|
14773
|
+
.dim-feishuGroupAuthorizationError { grid-template-columns: minmax(0, 1fr) max-content; align-items: center; border-color: color-mix(in srgb, var(--dsw-alias-state-error-primary, #d54941) 28%, var(--dsw-alias-border-l2, #dfe1e5)); background: color-mix(in srgb, var(--dsw-alias-state-error-primary, #d54941) 4%, var(--dsw-alias-bg-layer-3, #fff)); }
|
|
14774
|
+
.dim-feishuGroupAuthorizationError code { display: inline-block; margin-top: 6px; color: var(--dsw-alias-label-tertiary, #8f959e); font: 11px/17px ui-monospace, SFMono-Regular, Menlo, monospace; }
|
|
14775
|
+
.dim-feishuGroupQrColumn { min-width: 0; }
|
|
14776
|
+
.dim-feishuGroupQrFrame { position: relative; width: 176px; height: 176px; display: grid; place-items: center; padding: 10px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 11px; background: #fff; box-shadow: 0 6px 18px rgb(31 35 41 / 7%); }
|
|
14777
|
+
.dim-feishuGroupQrFrame img { width: 100%; height: 100%; display: block; object-fit: contain; }
|
|
14778
|
+
.dim-feishuGroupQrFallback { width: 100%; height: 100%; display: grid; place-content: center; justify-items: center; gap: 7px; border-radius: 7px; color: var(--dsw-alias-state-business-primary, #3370ff); background: #f7f9ff; text-align: center; }
|
|
14779
|
+
.dim-feishuGroupQrFallback span { color: var(--dsw-alias-label-secondary, #646a73); font-size: 11px; line-height: 17px; }
|
|
14780
|
+
.dim-feishuGroupQrExpired { position: absolute; inset: 10px; display: grid; place-content: center; gap: 2px; border-radius: 8px; color: var(--dsw-alias-label-primary, #1f2329); background: rgb(255 255 255 / 94%); backdrop-filter: blur(3px); text-align: center; }
|
|
14781
|
+
.dim-feishuGroupQrExpired span { font-size: 13px; line-height: 20px; font-weight: 650; }
|
|
14782
|
+
.dim-feishuGroupQrExpired small { color: var(--dsw-alias-label-secondary, #646a73); font-size: 11px; line-height: 17px; }
|
|
14783
|
+
.dim-feishuGroupCountdown { width: 176px; display: grid; grid-template-columns: minmax(0, 1fr) max-content; gap: 5px 10px; margin-top: 9px; color: var(--dsw-alias-label-tertiary, #8f959e); font-size: 11px; line-height: 17px; font-variant-numeric: tabular-nums; }
|
|
14784
|
+
.dim-feishuGroupCountdown strong { color: var(--dsw-alias-label-secondary, #646a73); font-weight: 600; }
|
|
14785
|
+
.dim-feishuGroupProgress { grid-column: 1 / -1; height: 3px; overflow: hidden; border-radius: 99px; background: var(--dsw-alias-bg-module-platform, #f2f3f5); }
|
|
14786
|
+
.dim-feishuGroupProgress > span { display: block; height: 100%; border-radius: inherit; background: var(--dsw-alias-state-business-primary, #3370ff); transition: width 1s linear; }
|
|
14787
|
+
.dim-feishuGroupAuthorizationCopy { min-width: 0; }
|
|
14788
|
+
.dim-feishuGroupAuthorizationEyebrow { display: block; margin-bottom: 7px; color: var(--dsw-alias-label-secondary, #646a73); font-size: 11px; line-height: 17px; font-weight: 600; }
|
|
14789
|
+
.dim-feishuGroupAuthorizationCopy ol { display: grid; gap: 6px; margin: 13px 0 0; padding-left: 18px; color: var(--dsw-alias-label-secondary, #646a73); font-size: 11px; line-height: 18px; }
|
|
14790
|
+
.dim-feishuGroupAuthorizationActions { display: flex; align-items: center; justify-content: flex-start; flex-wrap: wrap; gap: 8px; margin-top: 14px; }
|
|
14791
|
+
.dim-feishuGroupAuthorizationLink { text-decoration: none; }
|
|
13953
14792
|
.dim-deliveryDocsLink { min-height: 30px; flex: none; display: inline-flex; align-items: center; gap: 4px; padding: 5px 8px; border-radius: 7px; color: var(--dsw-alias-state-business-primary, #3370ff); font-size: 12px; line-height: 18px; text-decoration: none; white-space: nowrap; }
|
|
13954
14793
|
.dim-deliveryDocsLink:hover { background: color-mix(in srgb, var(--dsw-alias-state-business-primary, #3370ff) 8%, transparent); }
|
|
13955
14794
|
.dim-deliveryDocsLink:focus-visible { outline: 2px solid var(--dsw-alias-state-business-primary, #3370ff); outline-offset: 2px; }
|
|
@@ -13979,6 +14818,12 @@ var CSS11 = String.raw`
|
|
|
13979
14818
|
.dim-targetTitle span { flex: none; padding: 1px 6px; border-radius: 5px; color: var(--dsw-alias-state-business-primary, #3370ff); background: color-mix(in srgb, var(--dsw-alias-state-business-primary, #3370ff) 9%, transparent); font-size: 10px; line-height: 16px; }
|
|
13980
14819
|
.dim-targetSummary code { display: block; overflow: hidden; margin-top: 3px; color: var(--dsw-alias-label-secondary, #646a73); font: 11px/17px ui-monospace, SFMono-Regular, Menlo, monospace; text-overflow: ellipsis; white-space: nowrap; }
|
|
13981
14820
|
.dim-targetActions { display: flex; align-items: center; justify-content: flex-end; gap: 6px; flex-wrap: wrap; }
|
|
14821
|
+
.dim-targetSessionSync { grid-column: 1 / -1; min-width: 0; display: flex; align-items: center; justify-content: space-between; gap: 12px; padding-top: 9px; border-top: 1px solid var(--dsw-alias-border-l1, #eef0f3); cursor: pointer; }
|
|
14822
|
+
.dim-targetSessionSyncCopy { min-width: 0; display: grid; gap: 1px; }
|
|
14823
|
+
.dim-targetSessionSyncCopy strong { color: var(--dsw-alias-label-primary, #1f2329); font-size: 12px; line-height: 18px; font-weight: 600; }
|
|
14824
|
+
.dim-targetSessionSyncCopy small { color: var(--dsw-alias-label-secondary, #646a73); font-size: 11px; line-height: 17px; }
|
|
14825
|
+
.dim-targetSessionSync input { width: 16px; height: 16px; flex: none; margin: 0; accent-color: var(--dsw-alias-state-business-primary, #3370ff); }
|
|
14826
|
+
.dim-targetSessionSync:has(input:disabled) { cursor: default; }
|
|
13982
14827
|
.dim-targetFeedback { grid-column: 1 / -1; margin: 0; color: var(--dsw-alias-label-secondary, #646a73); font-size: 11px; line-height: 17px; }
|
|
13983
14828
|
.dim-targetFeedback[data-tone="success"] { color: var(--dsw-alias-state-success-primary, #20a162); }
|
|
13984
14829
|
.dim-targetFeedback[data-tone="error"], .dim-targetFormError { color: var(--dsw-alias-state-error-primary, #d54941); }
|
|
@@ -14102,6 +14947,10 @@ var CSS11 = String.raw`
|
|
|
14102
14947
|
.dim-accessControls { grid-template-columns: minmax(0, 1fr); }
|
|
14103
14948
|
.dim-accessUserRow { grid-template-columns: minmax(0, 1fr); }
|
|
14104
14949
|
.dim-accessDeleteUser { justify-self: start; }
|
|
14950
|
+
.dim-feishuGroupAuthorization { grid-template-columns: minmax(0, 1fr); justify-items: center; }
|
|
14951
|
+
.dim-feishuGroupAuthorizationCopy { width: 100%; }
|
|
14952
|
+
.dim-feishuGroupAuthorizationState { grid-template-columns: 32px minmax(0, 1fr); justify-items: stretch; }
|
|
14953
|
+
.dim-feishuGroupAuthorizationError { justify-items: stretch; }
|
|
14105
14954
|
}
|
|
14106
14955
|
@media (max-width: 840px) {
|
|
14107
14956
|
.dim-title { align-items: flex-start; }
|
|
@@ -14131,6 +14980,7 @@ var CSS11 = String.raw`
|
|
|
14131
14980
|
.dim-deliveryBotId > span { grid-column: 1 / -1; }
|
|
14132
14981
|
.dim-targetActions .dim-deliveryButton { flex: 1 1 auto; }
|
|
14133
14982
|
.dim-accessActions .dim-deliveryButton { width: 100%; }
|
|
14983
|
+
.dim-feishuGroupAuthorizationActions .dim-deliveryButton { flex: 1 1 auto; }
|
|
14134
14984
|
.dim-directoryPickerBackdrop { padding: 10px; }
|
|
14135
14985
|
.dim-directoryPicker { height: calc(100vh - 20px); min-height: 0; border-radius: 14px; }
|
|
14136
14986
|
.dim-directoryPickerHeader { padding: 18px 17px 14px; }
|
|
@@ -14160,7 +15010,7 @@ function installImStyles() {
|
|
|
14160
15010
|
}
|
|
14161
15011
|
|
|
14162
15012
|
// plugin-src/client/update-panel.js
|
|
14163
|
-
var
|
|
15013
|
+
var React25 = __toESM(require("react"), 1);
|
|
14164
15014
|
var import_react_dom3 = require("react-dom");
|
|
14165
15015
|
var import_valid = __toESM(require_valid(), 1);
|
|
14166
15016
|
var import_rcompare = __toESM(require_rcompare(), 1);
|
|
@@ -14250,11 +15100,11 @@ function manualUpdateCommand(snapshot) {
|
|
|
14250
15100
|
return `dsh plugin --profile ${profileArgument} add -w @xmanrui/dsh-im@${version}`;
|
|
14251
15101
|
}
|
|
14252
15102
|
function ManualUpdateCommand({ command, disabled, sourceInstall, desktop }) {
|
|
14253
|
-
const [copyState, setCopyState] =
|
|
14254
|
-
const commandRef =
|
|
14255
|
-
const mounted =
|
|
14256
|
-
const copying =
|
|
14257
|
-
|
|
15103
|
+
const [copyState, setCopyState] = React25.useState("idle");
|
|
15104
|
+
const commandRef = React25.useRef(null);
|
|
15105
|
+
const mounted = React25.useRef(false);
|
|
15106
|
+
const copying = React25.useRef(false);
|
|
15107
|
+
React25.useEffect(() => {
|
|
14258
15108
|
mounted.current = true;
|
|
14259
15109
|
return () => {
|
|
14260
15110
|
mounted.current = false;
|
|
@@ -14286,7 +15136,7 @@ function ManualUpdateCommand({ command, disabled, sourceInstall, desktop }) {
|
|
|
14286
15136
|
{ className: "dim-updateManual", "aria-label": "\u624B\u5DE5\u66F4\u65B0" },
|
|
14287
15137
|
h2("h4", { className: "dim-updateManualHeading" }, "\u624B\u5DE5\u66F4\u65B0"),
|
|
14288
15138
|
command ? h2(
|
|
14289
|
-
|
|
15139
|
+
React25.Fragment,
|
|
14290
15140
|
null,
|
|
14291
15141
|
h2("p", { className: "dim-updateManualHint" }, "\u81EA\u52A8\u66F4\u65B0\u5931\u8D25\u53EF\u4EE5\u4F7F\u7528\u547D\u4EE4\u66F4\u65B0\uFF1A"),
|
|
14292
15142
|
h2(
|
|
@@ -14322,7 +15172,7 @@ function ManualUpdateCommand({ command, disabled, sourceInstall, desktop }) {
|
|
|
14322
15172
|
"aria-hidden": "true",
|
|
14323
15173
|
focusable: "false"
|
|
14324
15174
|
}, copyState === "copied" ? h2("path", { d: "m4 10 4 4 8-8" }) : h2(
|
|
14325
|
-
|
|
15175
|
+
React25.Fragment,
|
|
14326
15176
|
null,
|
|
14327
15177
|
h2("rect", { x: 7, y: 7, width: 10, height: 11, rx: 1.5 }),
|
|
14328
15178
|
h2("path", { d: "M5 13H3.5A1.5 1.5 0 0 1 2 11.5v-8A1.5 1.5 0 0 1 3.5 2h8A1.5 1.5 0 0 1 13 3.5V5" })
|
|
@@ -14347,10 +15197,10 @@ function ManualUpdateCommand({ command, disabled, sourceInstall, desktop }) {
|
|
|
14347
15197
|
);
|
|
14348
15198
|
}
|
|
14349
15199
|
function UpdateDialog({ children, onClose }) {
|
|
14350
|
-
const dialogRef =
|
|
14351
|
-
const titleId =
|
|
14352
|
-
const descriptionId =
|
|
14353
|
-
|
|
15200
|
+
const dialogRef = React25.useRef(null);
|
|
15201
|
+
const titleId = React25.useId();
|
|
15202
|
+
const descriptionId = React25.useId();
|
|
15203
|
+
React25.useEffect(() => {
|
|
14354
15204
|
const previous = globalThis.document?.activeElement;
|
|
14355
15205
|
dialogRef.current?.focus?.();
|
|
14356
15206
|
return () => {
|
|
@@ -14408,19 +15258,19 @@ function UpdateDialog({ children, onClose }) {
|
|
|
14408
15258
|
return typeof document !== "undefined" && document.body ? (0, import_react_dom3.createPortal)(content, document.body) : content;
|
|
14409
15259
|
}
|
|
14410
15260
|
function UpdatePanel({ rpcCall, clientVersion, onStatus }) {
|
|
14411
|
-
const [snapshot, setSnapshot] =
|
|
14412
|
-
const [action, setAction] =
|
|
14413
|
-
const [error, setError] =
|
|
14414
|
-
const [open, setOpen] =
|
|
14415
|
-
const [uncertainInstall, setUncertainInstall] =
|
|
14416
|
-
const mounted =
|
|
14417
|
-
const busy =
|
|
14418
|
-
const readController =
|
|
14419
|
-
const pollReadController =
|
|
14420
|
-
const installRequest =
|
|
14421
|
-
const onStatusRef =
|
|
15261
|
+
const [snapshot, setSnapshot] = React25.useState(null);
|
|
15262
|
+
const [action, setAction] = React25.useState("status");
|
|
15263
|
+
const [error, setError] = React25.useState(null);
|
|
15264
|
+
const [open, setOpen] = React25.useState(false);
|
|
15265
|
+
const [uncertainInstall, setUncertainInstall] = React25.useState(false);
|
|
15266
|
+
const mounted = React25.useRef(false);
|
|
15267
|
+
const busy = React25.useRef(false);
|
|
15268
|
+
const readController = React25.useRef(null);
|
|
15269
|
+
const pollReadController = React25.useRef(null);
|
|
15270
|
+
const installRequest = React25.useRef(null);
|
|
15271
|
+
const onStatusRef = React25.useRef(onStatus);
|
|
14422
15272
|
onStatusRef.current = onStatus;
|
|
14423
|
-
const accept =
|
|
15273
|
+
const accept = React25.useCallback((next) => {
|
|
14424
15274
|
setSnapshot(next);
|
|
14425
15275
|
onStatusRef.current?.(next);
|
|
14426
15276
|
}, []);
|
|
@@ -14429,7 +15279,7 @@ function UpdatePanel({ rpcCall, clientVersion, onStatus }) {
|
|
|
14429
15279
|
setUncertainInstall(false);
|
|
14430
15280
|
accept(next);
|
|
14431
15281
|
};
|
|
14432
|
-
const invoke =
|
|
15282
|
+
const invoke = React25.useCallback(async (endpoint, payload = {}, signal) => {
|
|
14433
15283
|
if (typeof rpcCall !== "function") {
|
|
14434
15284
|
const unavailable = new Error("\u5F53\u524D Host \u4E0D\u652F\u6301\u66F4\u65B0\u63A5\u53E3\uFF0C\u8BF7\u5148\u624B\u52A8\u66F4\u65B0\u63D2\u4EF6\u5E76\u91CD\u542F\u3002");
|
|
14435
15285
|
unavailable.code = "update-unavailable";
|
|
@@ -14437,7 +15287,7 @@ function UpdatePanel({ rpcCall, clientVersion, onStatus }) {
|
|
|
14437
15287
|
}
|
|
14438
15288
|
return unwrapSnapshot(await rpcCall(endpoint, payload, signal));
|
|
14439
15289
|
}, [rpcCall]);
|
|
14440
|
-
|
|
15290
|
+
React25.useEffect(() => {
|
|
14441
15291
|
mounted.current = true;
|
|
14442
15292
|
busy.current = true;
|
|
14443
15293
|
const controller = new AbortController();
|
|
@@ -14460,7 +15310,7 @@ function UpdatePanel({ rpcCall, clientVersion, onStatus }) {
|
|
|
14460
15310
|
const activeJob = ACTIVE_STATES4.has(snapshot?.job?.state);
|
|
14461
15311
|
const restartRequired = snapshot?.job?.state === "restart-required" || snapshot?.blockedReason === "pending-restart";
|
|
14462
15312
|
const shouldPoll = activeJob || uncertainInstall;
|
|
14463
|
-
|
|
15313
|
+
React25.useEffect(() => {
|
|
14464
15314
|
if (!shouldPoll) return void 0;
|
|
14465
15315
|
let controller;
|
|
14466
15316
|
const scheduler = createPollScheduler({
|
|
@@ -14558,7 +15408,7 @@ function UpdatePanel({ rpcCall, clientVersion, onStatus }) {
|
|
|
14558
15408
|
const manualCommand = manualUpdateCommand(snapshot);
|
|
14559
15409
|
const buttonLabel = action === "checking" ? "\u68C0\u67E5\u4E2D\u2026" : action === "starting" || activeJob ? "\u6B63\u5728\u66F4\u65B0\u2026" : restartRequired ? "\u5F85\u624B\u52A8\u91CD\u542F" : snapshot?.canInstall ? "\u66F4\u65B0\u81F3" : "\u68C0\u67E5\u66F4\u65B0";
|
|
14560
15410
|
return h2(
|
|
14561
|
-
|
|
15411
|
+
React25.Fragment,
|
|
14562
15412
|
null,
|
|
14563
15413
|
h2("button", {
|
|
14564
15414
|
type: "button",
|
|
@@ -14583,13 +15433,13 @@ function UpdatePanel({ rpcCall, clientVersion, onStatus }) {
|
|
|
14583
15433
|
h2("dt", null, "\u8FD0\u884C\u7248\u672C"),
|
|
14584
15434
|
h2("dd", null, `v${snapshot?.runningVersion ?? clientVersion}`),
|
|
14585
15435
|
snapshot?.installedVersion && snapshot.installedVersion !== snapshot.runningVersion ? h2(
|
|
14586
|
-
|
|
15436
|
+
React25.Fragment,
|
|
14587
15437
|
null,
|
|
14588
15438
|
h2("dt", null, "\u5DF2\u5B89\u88C5\u7248\u672C"),
|
|
14589
15439
|
h2("dd", null, `v${snapshot.installedVersion}`)
|
|
14590
15440
|
) : null,
|
|
14591
15441
|
targetVersion ? h2(
|
|
14592
|
-
|
|
15442
|
+
React25.Fragment,
|
|
14593
15443
|
null,
|
|
14594
15444
|
h2("dt", null, "\u76EE\u6807\u7248\u672C"),
|
|
14595
15445
|
h2("dd", null, `v${targetVersion}`)
|
|
@@ -14794,23 +15644,23 @@ function IMSettingsTab({
|
|
|
14794
15644
|
browserLocation = globalThis.location,
|
|
14795
15645
|
navigateToRecoveryUrl = replacePageLocation
|
|
14796
15646
|
}) {
|
|
14797
|
-
const [selected, setSelected] =
|
|
14798
|
-
const [loopbackRecovery, setLoopbackRecovery] =
|
|
14799
|
-
const [runningVersion, setRunningVersion] =
|
|
14800
|
-
const [deliverySettings, setDeliverySettings] =
|
|
14801
|
-
const githubTooltipId =
|
|
14802
|
-
const generalSettingsTooltipId =
|
|
15647
|
+
const [selected, setSelected] = React26.useState("weixin");
|
|
15648
|
+
const [loopbackRecovery, setLoopbackRecovery] = React26.useState(null);
|
|
15649
|
+
const [runningVersion, setRunningVersion] = React26.useState(IM_PLUGIN_VERSION);
|
|
15650
|
+
const [deliverySettings, setDeliverySettings] = React26.useState(null);
|
|
15651
|
+
const githubTooltipId = React26.useId();
|
|
15652
|
+
const generalSettingsTooltipId = React26.useId();
|
|
14803
15653
|
const globalSettingsSelected = selected === GLOBAL_SETTINGS_TAB_ID;
|
|
14804
15654
|
const active = CHANNELS.find((channel4) => channel4.id === selected) ?? CHANNELS[0];
|
|
14805
15655
|
const activeTabId = globalSettingsSelected ? "dim-general-settings-trigger" : `dim-tab-${active.id}`;
|
|
14806
15656
|
const activePanelId = globalSettingsSelected ? `dim-panel-${GLOBAL_SETTINGS_TAB_ID}` : `dim-panel-${active.id}`;
|
|
14807
|
-
const reportLoopbackRecovery =
|
|
15657
|
+
const reportLoopbackRecovery = React26.useCallback((recovery) => {
|
|
14808
15658
|
setLoopbackRecovery((current) => current?.url === recovery.url ? current : recovery);
|
|
14809
15659
|
}, []);
|
|
14810
|
-
const reportUpdateStatus =
|
|
15660
|
+
const reportUpdateStatus = React26.useCallback((snapshot) => {
|
|
14811
15661
|
setRunningVersion(snapshot.runningVersion);
|
|
14812
15662
|
}, []);
|
|
14813
|
-
const rpcCalls =
|
|
15663
|
+
const rpcCalls = React26.useMemo(() => createLoopbackAwareRpcCalls({
|
|
14814
15664
|
dingtalkRpcCall,
|
|
14815
15665
|
discordRpcCall,
|
|
14816
15666
|
feishuRpcCall,
|
|
@@ -14844,7 +15694,7 @@ function IMSettingsTab({
|
|
|
14844
15694
|
weixinRpcCall,
|
|
14845
15695
|
whatsappRpcCall
|
|
14846
15696
|
]);
|
|
14847
|
-
const botSettingsContext =
|
|
15697
|
+
const botSettingsContext = React26.useMemo(() => Object.freeze({
|
|
14848
15698
|
openBotSettings: setDeliverySettings
|
|
14849
15699
|
}), []);
|
|
14850
15700
|
return h2(
|