@eddyskywalker/dsh-chatgpt-subscription 0.48.4 → 0.49.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/CHANGELOG.md +10 -0
- package/lib/client.js +2381 -179
- package/lib/client.js.map +1 -1
- package/lib/index.js +829 -29
- package/lib/types/client/index.d.ts +2 -0
- package/lib/types/client/index.d.ts.map +1 -1
- package/lib/types/client/kimi-code/KimiCodeSection.d.ts.map +1 -1
- package/lib/types/client/kimi-code/locales.d.ts +14 -2
- package/lib/types/client/kimi-code/locales.d.ts.map +1 -1
- package/lib/types/client/locales-ru/kimi-code.d.ts.map +1 -1
- package/lib/types/client/subagent/SubagentCard.d.ts +35 -0
- package/lib/types/client/subagent/SubagentCard.d.ts.map +1 -0
- package/lib/types/client/subagent/index.d.ts +28 -0
- package/lib/types/client/subagent/index.d.ts.map +1 -0
- package/lib/types/client/subagent/locales.d.ts +172 -0
- package/lib/types/client/subagent/locales.d.ts.map +1 -0
- package/lib/types/client/subagent/styles.d.ts +20 -0
- package/lib/types/client/subagent/styles.d.ts.map +1 -0
- package/lib/types/client/subagent/subagent-card-controller.d.ts +329 -0
- package/lib/types/client/subagent/subagent-card-controller.d.ts.map +1 -0
- package/lib/types/compat.d.ts +1 -1
- package/lib/types/host/common/request-images.d.ts +66 -0
- package/lib/types/host/common/request-images.d.ts.map +1 -1
- package/lib/types/host/kimi-code/adapter.d.ts.map +1 -1
- package/lib/types/host/kimi-code/mapper.d.ts +53 -3
- package/lib/types/host/kimi-code/mapper.d.ts.map +1 -1
- package/lib/types/host/kimi-code/routes.d.ts.map +1 -1
- package/lib/types/host/kimi-code/session-cache-state.d.ts +14 -0
- package/lib/types/host/kimi-code/session-cache-state.d.ts.map +1 -1
- package/lib/types/host/kimi-code/types.d.ts +29 -4
- package/lib/types/host/kimi-code/types.d.ts.map +1 -1
- package/lib/types/host/preferences.d.ts.map +1 -1
- package/lib/types/host/routes.d.ts.map +1 -1
- package/lib/types/host/subagent-model-authorization.d.ts +130 -2
- package/lib/types/host/subagent-model-authorization.d.ts.map +1 -1
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/shared/contracts.d.ts +28 -0
- package/lib/types/shared/contracts.d.ts.map +1 -1
- package/lib/types/shared/kimi-code-contracts.d.ts +10 -1
- package/lib/types/shared/kimi-code-contracts.d.ts.map +1 -1
- package/lib/types/shared/preferences.d.ts +52 -1
- package/lib/types/shared/preferences.d.ts.map +1 -1
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -3108,7 +3108,7 @@ window.__ModuleLoader__.load({
|
|
|
3108
3108
|
//#endregion
|
|
3109
3109
|
//#region src/client/antigravity/locales.ts
|
|
3110
3110
|
const NS_ANTIGRAVITY = "dsh-antigravity";
|
|
3111
|
-
const zh$
|
|
3111
|
+
const zh$14 = {
|
|
3112
3112
|
...accountPoolZh,
|
|
3113
3113
|
title: "Antigravity",
|
|
3114
3114
|
pageDesc: "登录 Google Antigravity / Cloud Code Assist,并查看当前账号的共享额度。",
|
|
@@ -3186,7 +3186,7 @@ window.__ModuleLoader__.load({
|
|
|
3186
3186
|
loginFailed: "登录失败",
|
|
3187
3187
|
tokens: "tokens"
|
|
3188
3188
|
};
|
|
3189
|
-
const en$
|
|
3189
|
+
const en$14 = {
|
|
3190
3190
|
...accountPoolEn,
|
|
3191
3191
|
title: "Antigravity",
|
|
3192
3192
|
pageDesc: "Sign in to Google Antigravity / Cloud Code Assist and view shared quotas.",
|
|
@@ -3264,11 +3264,11 @@ window.__ModuleLoader__.load({
|
|
|
3264
3264
|
loginFailed: "Login failed",
|
|
3265
3265
|
tokens: "tokens"
|
|
3266
3266
|
};
|
|
3267
|
-
const dictionaries$
|
|
3268
|
-
zh: zh$
|
|
3269
|
-
"zh-CN": zh$
|
|
3270
|
-
en: en$
|
|
3271
|
-
"en-US": en$
|
|
3267
|
+
const dictionaries$14 = {
|
|
3268
|
+
zh: zh$14,
|
|
3269
|
+
"zh-CN": zh$14,
|
|
3270
|
+
en: en$14,
|
|
3271
|
+
"en-US": en$14
|
|
3272
3272
|
};
|
|
3273
3273
|
//#endregion
|
|
3274
3274
|
//#region src/client/common/line-locale.ts
|
|
@@ -3380,7 +3380,7 @@ window.__ModuleLoader__.load({
|
|
|
3380
3380
|
const [savingModel, setSavingModel] = (0, react.useState)(null);
|
|
3381
3381
|
/** Follow-up poll owed while the host refreshes the quota behind an answer. */
|
|
3382
3382
|
const quotaFollowUp = (0, react.useRef)(null);
|
|
3383
|
-
const t = useLineDict(NS_ANTIGRAVITY, zh$
|
|
3383
|
+
const t = useLineDict(NS_ANTIGRAVITY, zh$14);
|
|
3384
3384
|
const notifyChange = (0, react.useCallback)(() => {
|
|
3385
3385
|
onModelChange?.();
|
|
3386
3386
|
loadModelDirectory?.();
|
|
@@ -3937,7 +3937,7 @@ window.__ModuleLoader__.load({
|
|
|
3937
3937
|
//#endregion
|
|
3938
3938
|
//#region src/client/command-code/locales.ts
|
|
3939
3939
|
const NS_COMMAND_CODE = "dsh-command-code";
|
|
3940
|
-
const zh$
|
|
3940
|
+
const zh$13 = {
|
|
3941
3941
|
...accountPoolZh,
|
|
3942
3942
|
title: "Command Code",
|
|
3943
3943
|
pageDesc: "登录 Command Code,管理可用模型、上下文窗口与额度。",
|
|
@@ -4005,7 +4005,7 @@ window.__ModuleLoader__.load({
|
|
|
4005
4005
|
loginFailed: "登录失败",
|
|
4006
4006
|
tokens: "tokens"
|
|
4007
4007
|
};
|
|
4008
|
-
const en$
|
|
4008
|
+
const en$13 = {
|
|
4009
4009
|
...accountPoolEn,
|
|
4010
4010
|
title: "Command Code",
|
|
4011
4011
|
pageDesc: "Sign in to Command Code and manage models, context windows, and quota.",
|
|
@@ -4073,11 +4073,11 @@ window.__ModuleLoader__.load({
|
|
|
4073
4073
|
loginFailed: "Sign-in failed",
|
|
4074
4074
|
tokens: "tokens"
|
|
4075
4075
|
};
|
|
4076
|
-
const dictionaries$
|
|
4077
|
-
zh: zh$
|
|
4078
|
-
"zh-CN": zh$
|
|
4079
|
-
en: en$
|
|
4080
|
-
"en-US": en$
|
|
4076
|
+
const dictionaries$13 = {
|
|
4077
|
+
zh: zh$13,
|
|
4078
|
+
"zh-CN": zh$13,
|
|
4079
|
+
en: en$13,
|
|
4080
|
+
"en-US": en$13
|
|
4081
4081
|
};
|
|
4082
4082
|
//#endregion
|
|
4083
4083
|
//#region src/client/command-code/CommandCodeSection.tsx
|
|
@@ -4118,7 +4118,7 @@ window.__ModuleLoader__.load({
|
|
|
4118
4118
|
const [apiKey, setApiKey] = (0, react.useState)("");
|
|
4119
4119
|
/** Follow-up poll owed while the host refreshes the quota behind an answer. */
|
|
4120
4120
|
const quotaFollowUp = (0, react.useRef)(null);
|
|
4121
|
-
const t = useLineDict(NS_COMMAND_CODE, zh$
|
|
4121
|
+
const t = useLineDict(NS_COMMAND_CODE, zh$13);
|
|
4122
4122
|
const notifyChange = (0, react.useCallback)(() => {
|
|
4123
4123
|
onModelChange?.();
|
|
4124
4124
|
loadModelDirectory?.();
|
|
@@ -4879,7 +4879,7 @@ window.__ModuleLoader__.load({
|
|
|
4879
4879
|
//#endregion
|
|
4880
4880
|
//#region src/client/kimi-code/locales.ts
|
|
4881
4881
|
const NS_KIMI_CODE = "dsh-kimi-code";
|
|
4882
|
-
const zh$
|
|
4882
|
+
const zh$12 = {
|
|
4883
4883
|
...accountPoolZh,
|
|
4884
4884
|
title: "Kimi Code",
|
|
4885
4885
|
pageDesc: "登录 Kimi Code 订阅,管理模型、思考档位、上下文窗口与额度。",
|
|
@@ -4989,6 +4989,10 @@ window.__ModuleLoader__.load({
|
|
|
4989
4989
|
cacheDriftTools: "工具列表已变化(缓存失效)",
|
|
4990
4990
|
cacheDriftCacheKey: "缓存键已变化(会话切换)",
|
|
4991
4991
|
cacheDriftColdKey: "未发送缓存键(无法命中)",
|
|
4992
|
+
cacheDriftImageOffload: "旧图片超预算淘汰(缓存重建)",
|
|
4993
|
+
cacheImageBudgetLabel: "请求图片预算",
|
|
4994
|
+
cacheImageBudgetValue: "本轮 {used} / 上限 {budget}(低水位 {low})",
|
|
4995
|
+
cacheImageBudgetDropped: "本轮 {used} / 上限 {budget}(已粘性淘汰 {dropped} 张)",
|
|
4992
4996
|
preserveThinking: "保留思考 (Preserved Thinking)",
|
|
4993
4997
|
preserveOn: "已开启(官方默认):跨轮保留 reasoning_content,多轮工具调用更连贯,但思考 token 也计入输出。",
|
|
4994
4998
|
preserveOff: "已关闭:不要求服务回传推理内容。可设置 DSH_KIMI_CODE_PRESERVE_THINKING=0 关闭。",
|
|
@@ -5046,7 +5050,7 @@ window.__ModuleLoader__.load({
|
|
|
5046
5050
|
compactionRouteNoImage: "该模型不接受图片:摘要里的截图会被替换为占位文本。",
|
|
5047
5051
|
compactionRouteEmpty: "没有可用的线路——先登录任意一条线路再回来设置。"
|
|
5048
5052
|
};
|
|
5049
|
-
const en$
|
|
5053
|
+
const en$12 = {
|
|
5050
5054
|
...accountPoolEn,
|
|
5051
5055
|
title: "Kimi Code",
|
|
5052
5056
|
pageDesc: "Sign in to the Kimi Code subscription and manage models, thinking level, context windows, and quota.",
|
|
@@ -5156,6 +5160,10 @@ window.__ModuleLoader__.load({
|
|
|
5156
5160
|
cacheDriftTools: "Tool list changed (cache invalidated)",
|
|
5157
5161
|
cacheDriftCacheKey: "Cache key changed (session switch)",
|
|
5158
5162
|
cacheDriftColdKey: "No cache key sent (cannot hit)",
|
|
5163
|
+
cacheDriftImageOffload: "Older images offloaded for budget (cache rebuilt)",
|
|
5164
|
+
cacheImageBudgetLabel: "Request image budget",
|
|
5165
|
+
cacheImageBudgetValue: "{used} this turn / {budget} cap ({low} low-water)",
|
|
5166
|
+
cacheImageBudgetDropped: "{used} this turn / {budget} cap ({dropped} sticky-offloaded)",
|
|
5159
5167
|
preserveThinking: "Preserved Thinking",
|
|
5160
5168
|
preserveOn: "On (the official default): reasoning_content is retained across turns, which keeps multi-step tool use coherent — its tokens are billed as output.",
|
|
5161
5169
|
preserveOff: "Off: the service is not asked to return reasoning. Set DSH_KIMI_CODE_PRESERVE_THINKING=0 to disable.",
|
|
@@ -5213,11 +5221,11 @@ window.__ModuleLoader__.load({
|
|
|
5213
5221
|
compactionRouteNoImage: "This model takes no images: screenshots become placeholder text in the summary.",
|
|
5214
5222
|
compactionRouteEmpty: "No route is available — sign in to one first."
|
|
5215
5223
|
};
|
|
5216
|
-
const dictionaries$
|
|
5217
|
-
zh: zh$
|
|
5218
|
-
"zh-CN": zh$
|
|
5219
|
-
en: en$
|
|
5220
|
-
"en-US": en$
|
|
5224
|
+
const dictionaries$12 = {
|
|
5225
|
+
zh: zh$12,
|
|
5226
|
+
"zh-CN": zh$12,
|
|
5227
|
+
en: en$12,
|
|
5228
|
+
"en-US": en$12
|
|
5221
5229
|
};
|
|
5222
5230
|
//#endregion
|
|
5223
5231
|
//#region src/shared/kimi-code-contracts.ts
|
|
@@ -5329,7 +5337,7 @@ window.__ModuleLoader__.load({
|
|
|
5329
5337
|
return `${value}x`;
|
|
5330
5338
|
}
|
|
5331
5339
|
function KimiModelCapabilities({ models }) {
|
|
5332
|
-
const t = useLineDict(NS_KIMI_CODE, zh$
|
|
5340
|
+
const t = useLineDict(NS_KIMI_CODE, zh$12);
|
|
5333
5341
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5334
5342
|
className: "dsha-cap-table",
|
|
5335
5343
|
children: [
|
|
@@ -5742,6 +5750,20 @@ window.__ModuleLoader__.load({
|
|
|
5742
5750
|
function tokenCount(value, t) {
|
|
5743
5751
|
return typeof value === "number" && Number.isFinite(value) ? value.toLocaleString() : t.unknownMetric;
|
|
5744
5752
|
}
|
|
5753
|
+
/**
|
|
5754
|
+
* One byte count as the card prints it.
|
|
5755
|
+
*
|
|
5756
|
+
* The image budget is a byte budget, so a raw number would be unreadable: the
|
|
5757
|
+
* cap sits in the megabytes while a single image can be in the kilobytes.
|
|
5758
|
+
* A value the card cannot read prints as "0 B" rather than "NaN B" — an
|
|
5759
|
+
* absent measurement is not a measurement of zero bytes.
|
|
5760
|
+
*/
|
|
5761
|
+
function formatByteSize(bytes) {
|
|
5762
|
+
if (!Number.isFinite(bytes) || bytes <= 0) return "0 B";
|
|
5763
|
+
if (bytes >= 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(bytes % (1024 * 1024) === 0 ? 0 : 2)} MB`;
|
|
5764
|
+
if (bytes >= 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
5765
|
+
return `${Math.round(bytes)} B`;
|
|
5766
|
+
}
|
|
5745
5767
|
/** Human label for the last request's prefix-drift cause. */
|
|
5746
5768
|
function driftLabel(cause, t) {
|
|
5747
5769
|
switch (cause) {
|
|
@@ -5751,6 +5773,7 @@ window.__ModuleLoader__.load({
|
|
|
5751
5773
|
case "tools": return t.cacheDriftTools;
|
|
5752
5774
|
case "cache-key": return t.cacheDriftCacheKey;
|
|
5753
5775
|
case "cold-key": return t.cacheDriftColdKey;
|
|
5776
|
+
case "image-offload": return t.cacheDriftImageOffload;
|
|
5754
5777
|
default: return String(cause);
|
|
5755
5778
|
}
|
|
5756
5779
|
}
|
|
@@ -5768,7 +5791,7 @@ window.__ModuleLoader__.load({
|
|
|
5768
5791
|
const [compactionPreferences, setCompactionPreferences] = (0, react.useState)(null);
|
|
5769
5792
|
/** Follow-up poll owed while the host refreshes the quota behind an answer. */
|
|
5770
5793
|
const quotaFollowUp = (0, react.useRef)(null);
|
|
5771
|
-
const t = useLineDict(NS_KIMI_CODE, zh$
|
|
5794
|
+
const t = useLineDict(NS_KIMI_CODE, zh$12);
|
|
5772
5795
|
const notifyChange = (0, react.useCallback)(() => {
|
|
5773
5796
|
onModelChange?.();
|
|
5774
5797
|
loadModelDirectory?.();
|
|
@@ -6324,6 +6347,16 @@ window.__ModuleLoader__.load({
|
|
|
6324
6347
|
className: "dsha-value",
|
|
6325
6348
|
children: (status.cache.warmup.warmup ? t.cacheWarmupWarming : t.cacheWarmupSettled).replace("{hits}", String(status.cache.warmup.consecutiveHits)).replace("{required}", String(status.cache.warmup.requiredHits)).replace("{chars}", status.cache.warmup.maxChars.toLocaleString())
|
|
6326
6349
|
})]
|
|
6350
|
+
}),
|
|
6351
|
+
status.cache.imageBudget !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6352
|
+
className: "dsha-row",
|
|
6353
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6354
|
+
className: "dsha-label",
|
|
6355
|
+
children: t.cacheImageBudgetLabel
|
|
6356
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6357
|
+
className: "dsha-value",
|
|
6358
|
+
children: (status.cache.imageBudget.droppedImages > 0 ? t.cacheImageBudgetDropped : t.cacheImageBudgetValue).replace("{used}", formatByteSize(status.cache.imageBudget.requestImageBytes)).replace("{budget}", formatByteSize(status.cache.imageBudget.budgetBytes)).replace("{low}", formatByteSize(status.cache.imageBudget.lowBudgetBytes)).replace("{dropped}", String(status.cache.imageBudget.droppedImages))
|
|
6359
|
+
})]
|
|
6327
6360
|
})
|
|
6328
6361
|
]
|
|
6329
6362
|
})
|
|
@@ -6538,7 +6571,7 @@ window.__ModuleLoader__.load({
|
|
|
6538
6571
|
//#endregion
|
|
6539
6572
|
//#region src/client/minimax-code/locales.ts
|
|
6540
6573
|
const NS_MINIMAX_CODE = "dsh-minimax-code";
|
|
6541
|
-
const zh$
|
|
6574
|
+
const zh$11 = {
|
|
6542
6575
|
...accountPoolZh,
|
|
6543
6576
|
title: "MiniMax Code",
|
|
6544
6577
|
pageDesc: "登录 MiniMax Code 编程订阅(设备码 OAuth),复用本机 MiniMax Code 的登录态,管理账号、连接与模型。",
|
|
@@ -6736,7 +6769,7 @@ window.__ModuleLoader__.load({
|
|
|
6736
6769
|
videoHistoryEncrypted: "已由系统凭据后端加密",
|
|
6737
6770
|
videoHistoryPlain: "本机没有可用的凭据后端,记录为明文"
|
|
6738
6771
|
};
|
|
6739
|
-
const en$
|
|
6772
|
+
const en$11 = {
|
|
6740
6773
|
...accountPoolEn,
|
|
6741
6774
|
title: "MiniMax Code",
|
|
6742
6775
|
pageDesc: "Sign in to the MiniMax Code coding subscription (device-code OAuth) and reuse the local MiniMax Code sign-in to manage the account, connection, and models.",
|
|
@@ -6934,11 +6967,11 @@ window.__ModuleLoader__.load({
|
|
|
6934
6967
|
videoHistoryEncrypted: "Encrypted by the platform credential backend",
|
|
6935
6968
|
videoHistoryPlain: "No credential backend on this host; stored as plain text"
|
|
6936
6969
|
};
|
|
6937
|
-
const dictionaries$
|
|
6938
|
-
zh: zh$
|
|
6939
|
-
"zh-CN": zh$
|
|
6940
|
-
en: en$
|
|
6941
|
-
"en-US": en$
|
|
6970
|
+
const dictionaries$11 = {
|
|
6971
|
+
zh: zh$11,
|
|
6972
|
+
"zh-CN": zh$11,
|
|
6973
|
+
en: en$11,
|
|
6974
|
+
"en-US": en$11
|
|
6942
6975
|
};
|
|
6943
6976
|
//#endregion
|
|
6944
6977
|
//#region src/client/minimax-code/useMinimaxCodeSection.ts
|
|
@@ -6952,7 +6985,7 @@ window.__ModuleLoader__.load({
|
|
|
6952
6985
|
* rather than inferred from the JSX.
|
|
6953
6986
|
*/
|
|
6954
6987
|
/** The card's own dictionary; stable identity keeps effect dependencies intact. */
|
|
6955
|
-
const fallbackTranslate$5 = (key) => zh$
|
|
6988
|
+
const fallbackTranslate$5 = (key) => zh$11[key];
|
|
6956
6989
|
/**
|
|
6957
6990
|
* The shared pool card's labels, resolved through this card's dictionary.
|
|
6958
6991
|
*
|
|
@@ -9010,7 +9043,7 @@ window.__ModuleLoader__.load({
|
|
|
9010
9043
|
* 键名重合的会被渲染成 ChatGPT 的措辞,不重合的会把键名本身打印出来)。
|
|
9011
9044
|
*/
|
|
9012
9045
|
const NS_GLM_CODING_PLAN = "dsh-glm-coding-plan";
|
|
9013
|
-
const zh$
|
|
9046
|
+
const zh$10 = {
|
|
9014
9047
|
...accountPoolZh,
|
|
9015
9048
|
title: "GLM(ZCode 账号)",
|
|
9016
9049
|
pageDesc: "用 ZCode 账号授权接入 GLM Coding Plan(国区 bigmodel.cn / 国际区 z.ai),管理账号池、套餐额度与模型勾选。两个区域的凭据各自独立,池内可以同时存在两区账号。",
|
|
@@ -9104,7 +9137,7 @@ window.__ModuleLoader__.load({
|
|
|
9104
9137
|
quotaAllowanceUnknown: "未判定",
|
|
9105
9138
|
quotaAllowanceHint: "登录时探活认定的额度来源。「免费体验额度」指新用户注册后自动获得、首次使用起 5 天内每天 800 万 token 的体验额度。"
|
|
9106
9139
|
};
|
|
9107
|
-
const en$
|
|
9140
|
+
const en$10 = {
|
|
9108
9141
|
...accountPoolEn,
|
|
9109
9142
|
title: "GLM (ZCode account)",
|
|
9110
9143
|
pageDesc: "Sign in with a ZCode account to reach GLM Coding Plan (China bigmodel.cn / International z.ai), and manage the account pool, plan quota and model selection. The two regions hold independent credentials, so a pool can carry accounts from both.",
|
|
@@ -9198,11 +9231,11 @@ window.__ModuleLoader__.load({
|
|
|
9198
9231
|
quotaAllowanceUnknown: "Undetermined",
|
|
9199
9232
|
quotaAllowanceHint: "The allowance source established by the sign-in probe. “Free trial allowance” means 8M tokens per day for 5 days from first use, granted automatically to new accounts."
|
|
9200
9233
|
};
|
|
9201
|
-
const dictionaries$
|
|
9202
|
-
zh: zh$
|
|
9203
|
-
"zh-CN": zh$
|
|
9204
|
-
en: en$
|
|
9205
|
-
"en-US": en$
|
|
9234
|
+
const dictionaries$10 = {
|
|
9235
|
+
zh: zh$10,
|
|
9236
|
+
"zh-CN": zh$10,
|
|
9237
|
+
en: en$10,
|
|
9238
|
+
"en-US": en$10
|
|
9206
9239
|
};
|
|
9207
9240
|
/** 一个配额窗口的键到「窗口长度(分钟)」的映射。 */
|
|
9208
9241
|
const QUOTA_WINDOW_MINUTES$1 = {
|
|
@@ -9283,7 +9316,7 @@ window.__ModuleLoader__.load({
|
|
|
9283
9316
|
/** 登录状态机的轮询节奏。真实超时与间隔由 host 拥有,卡片只是跟随。 */
|
|
9284
9317
|
const LOGIN_POLL_INTERVAL_MS$2 = 2e3;
|
|
9285
9318
|
/** 本卡片的字典;身份稳定,依赖它的 effect 才不会每次渲染重建。 */
|
|
9286
|
-
const fallbackTranslate$4 = (key) => zh$
|
|
9319
|
+
const fallbackTranslate$4 = (key) => zh$10[key];
|
|
9287
9320
|
/**
|
|
9288
9321
|
* 共享账号池卡片需要的标签集,按本卡片的字典逐键查出来。
|
|
9289
9322
|
*
|
|
@@ -9709,7 +9742,7 @@ window.__ModuleLoader__.load({
|
|
|
9709
9742
|
const { status, loading, busy, error, connection, adoptResult, pasteValue, region, pasteOpen, contextDrafts, savingModel } = state;
|
|
9710
9743
|
const { accounts, models, contextModels, overrideCount, login, quota, authenticated, poolLabels } = derived;
|
|
9711
9744
|
const { setRegion, login: startLogin, cancelLogin, submitPaste, setPasteValue, togglePaste, adopt, clearAdoptResult, accountAction, setStrategy, toggleModel, setAllModels, saveContextWindow, resetContextWindow, resetAllContextWindows, updateContextDraft, refreshQuota, refreshCatalog, testConnection } = actions;
|
|
9712
|
-
const t = useLineDict(NS_GLM_CODING_PLAN, zh$
|
|
9745
|
+
const t = useLineDict(NS_GLM_CODING_PLAN, zh$10);
|
|
9713
9746
|
if (loading) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
9714
9747
|
className: "dsha-page",
|
|
9715
9748
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
@@ -10174,7 +10207,7 @@ window.__ModuleLoader__.load({
|
|
|
10174
10207
|
* provider — the same reason every sibling line has one.
|
|
10175
10208
|
*/
|
|
10176
10209
|
const NS_CLAUDE = "dsh-claude";
|
|
10177
|
-
const zh$
|
|
10210
|
+
const zh$9 = {
|
|
10178
10211
|
...accountPoolZh,
|
|
10179
10212
|
title: "Claude(订阅)",
|
|
10180
10213
|
pageDesc: "登录 Claude Pro/Max 订阅,管理模型、思考档位、上下文窗口与额度。",
|
|
@@ -10291,7 +10324,7 @@ window.__ModuleLoader__.load({
|
|
|
10291
10324
|
copy: "复制",
|
|
10292
10325
|
copied: "已复制"
|
|
10293
10326
|
};
|
|
10294
|
-
const en$
|
|
10327
|
+
const en$9 = {
|
|
10295
10328
|
...accountPoolEn,
|
|
10296
10329
|
title: "Claude (subscription)",
|
|
10297
10330
|
pageDesc: "Sign in to a Claude Pro/Max subscription and manage models, thinking levels, context windows and quota.",
|
|
@@ -10408,11 +10441,11 @@ window.__ModuleLoader__.load({
|
|
|
10408
10441
|
copy: "Copy",
|
|
10409
10442
|
copied: "Copied"
|
|
10410
10443
|
};
|
|
10411
|
-
const dictionaries$
|
|
10412
|
-
zh: zh$
|
|
10413
|
-
"zh-CN": zh$
|
|
10414
|
-
en: en$
|
|
10415
|
-
"en-US": en$
|
|
10444
|
+
const dictionaries$9 = {
|
|
10445
|
+
zh: zh$9,
|
|
10446
|
+
"zh-CN": zh$9,
|
|
10447
|
+
en: en$9,
|
|
10448
|
+
"en-US": en$9
|
|
10416
10449
|
};
|
|
10417
10450
|
//#endregion
|
|
10418
10451
|
//#region src/client/claude/useClaudeSection.ts
|
|
@@ -10446,7 +10479,7 @@ window.__ModuleLoader__.load({
|
|
|
10446
10479
|
const [connection, setConnection] = (0, react.useState)(null);
|
|
10447
10480
|
/** Follow-up poll owed while the host refreshes the quota behind an answer. */
|
|
10448
10481
|
const quotaFollowUp = (0, react.useRef)(null);
|
|
10449
|
-
const t = useLineDict(NS_CLAUDE, zh$
|
|
10482
|
+
const t = useLineDict(NS_CLAUDE, zh$9);
|
|
10450
10483
|
const notifyChange = (0, react.useCallback)(() => {
|
|
10451
10484
|
onModelChange?.();
|
|
10452
10485
|
loadModelDirectory?.();
|
|
@@ -10893,11 +10926,11 @@ window.__ModuleLoader__.load({
|
|
|
10893
10926
|
* out here would hide a choice the host would accept and a catalog may expose.
|
|
10894
10927
|
*/
|
|
10895
10928
|
const EFFORT_LABELS$2 = {
|
|
10896
|
-
low: zh$
|
|
10897
|
-
medium: zh$
|
|
10898
|
-
high: zh$
|
|
10899
|
-
xhigh: zh$
|
|
10900
|
-
max: zh$
|
|
10929
|
+
low: zh$9.effortLow,
|
|
10930
|
+
medium: zh$9.effortMedium,
|
|
10931
|
+
high: zh$9.effortHigh,
|
|
10932
|
+
xhigh: zh$9.effortXHigh,
|
|
10933
|
+
max: zh$9.effortMax
|
|
10901
10934
|
};
|
|
10902
10935
|
/** One-line capability summary shown as a model pill's hover title. */
|
|
10903
10936
|
function modelFacts(model, t) {
|
|
@@ -10918,7 +10951,7 @@ window.__ModuleLoader__.load({
|
|
|
10918
10951
|
const { status, loading, busy, error, flow, connection, pasteValue, contextDrafts, savingModel } = state;
|
|
10919
10952
|
const { accounts, hasAdopted, contextModels, overrideCount, quota, windows, poolLabels } = derived;
|
|
10920
10953
|
const { login, cancelLogin, submitPaste, adopt, stopImporting, accountAction, setStrategy, relogin, refreshQuota, refreshCatalog, testConnection, toggleModel, setAllModels, updateEffort, updateCacheTtl, saveContextWindow, resetContextWindow, resetAllContextWindows, updateContextDraft, setPasteValue } = actions;
|
|
10921
|
-
const t = useLineDict(NS_CLAUDE, zh$
|
|
10954
|
+
const t = useLineDict(NS_CLAUDE, zh$9);
|
|
10922
10955
|
if (loading) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
10923
10956
|
className: "dsha-page",
|
|
10924
10957
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
@@ -11509,7 +11542,7 @@ window.__ModuleLoader__.load({
|
|
|
11509
11542
|
//#endregion
|
|
11510
11543
|
//#region src/client/ollama/locales.ts
|
|
11511
11544
|
const NS_OLLAMA = "dsh-ollama";
|
|
11512
|
-
const zh$
|
|
11545
|
+
const zh$8 = {
|
|
11513
11546
|
...accountPoolZh,
|
|
11514
11547
|
relogin: "更换 Key",
|
|
11515
11548
|
needsRelogin: "Key 已失效",
|
|
@@ -11561,7 +11594,7 @@ window.__ModuleLoader__.load({
|
|
|
11561
11594
|
usageNone: "尚无请求",
|
|
11562
11595
|
usageHint: "按 Ollama 每次响应自带的 token 计数本地累加。"
|
|
11563
11596
|
};
|
|
11564
|
-
const en$
|
|
11597
|
+
const en$8 = {
|
|
11565
11598
|
...accountPoolEn,
|
|
11566
11599
|
relogin: "Replace Key",
|
|
11567
11600
|
needsRelogin: "Key rejected",
|
|
@@ -11613,11 +11646,11 @@ window.__ModuleLoader__.load({
|
|
|
11613
11646
|
usageNone: "No requests yet",
|
|
11614
11647
|
usageHint: "Summed locally from the token counts Ollama returns on each response."
|
|
11615
11648
|
};
|
|
11616
|
-
const dictionaries$
|
|
11617
|
-
zh: zh$
|
|
11618
|
-
"zh-CN": zh$
|
|
11619
|
-
en: en$
|
|
11620
|
-
"en-US": en$
|
|
11649
|
+
const dictionaries$8 = {
|
|
11650
|
+
zh: zh$8,
|
|
11651
|
+
"zh-CN": zh$8,
|
|
11652
|
+
en: en$8,
|
|
11653
|
+
"en-US": en$8
|
|
11621
11654
|
};
|
|
11622
11655
|
//#endregion
|
|
11623
11656
|
//#region src/client/ollama/OllamaSection.tsx
|
|
@@ -11743,7 +11776,7 @@ window.__ModuleLoader__.load({
|
|
|
11743
11776
|
const setEffort = (0, react.useCallback)((value) => {
|
|
11744
11777
|
run("effort", () => API$5.setDefaultReasoningEffort(value === "" ? null : value));
|
|
11745
11778
|
}, [run]);
|
|
11746
|
-
const t = useLineDict(NS_OLLAMA, zh$
|
|
11779
|
+
const t = useLineDict(NS_OLLAMA, zh$8);
|
|
11747
11780
|
const pool = status?.pool;
|
|
11748
11781
|
const models = status?.models ?? [];
|
|
11749
11782
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [
|
|
@@ -11858,7 +11891,7 @@ window.__ModuleLoader__.load({
|
|
|
11858
11891
|
className: "dsha-btn",
|
|
11859
11892
|
disabled: busy !== null,
|
|
11860
11893
|
onClick: () => setShowKeyForm(false),
|
|
11861
|
-
children: zh$
|
|
11894
|
+
children: zh$8.deleteAccount
|
|
11862
11895
|
})]
|
|
11863
11896
|
})
|
|
11864
11897
|
]
|
|
@@ -11978,7 +12011,7 @@ window.__ModuleLoader__.load({
|
|
|
11978
12011
|
* 键名重合的会被渲染成 ChatGPT 的措辞,不重合的会把键名本身打印出来)。
|
|
11979
12012
|
*/
|
|
11980
12013
|
const NS_STEP_CODE = "dsh-step-code";
|
|
11981
|
-
const zh$
|
|
12014
|
+
const zh$7 = {
|
|
11982
12015
|
...accountPoolZh,
|
|
11983
12016
|
title: "Step Code(Step Plan 订阅)",
|
|
11984
12017
|
pageDesc: "用 StepFun 的 Step Plan 订阅(国区 api.stepfun.com / 国际区 api.stepfun.ai)或开放平台 API Key 接入,管理账号池、套餐额度、缓存用量与模型勾选。区域是凭据的属性,两区凭据互不通用,因此号池里可以同时存在两区账号。",
|
|
@@ -12147,7 +12180,7 @@ window.__ModuleLoader__.load({
|
|
|
12147
12180
|
cacheEmpty: "本进程还没有任何请求回报过用量,跑一次对话后再看。",
|
|
12148
12181
|
cacheHitRatioUnavailable: "—"
|
|
12149
12182
|
};
|
|
12150
|
-
const en$
|
|
12183
|
+
const en$7 = {
|
|
12151
12184
|
...accountPoolEn,
|
|
12152
12185
|
title: "Step Code (Step Plan subscription)",
|
|
12153
12186
|
pageDesc: "Reach StepFun with a Step Plan subscription (China api.stepfun.com / international api.stepfun.ai) or an open-platform API key, and manage the account pool, plan quota, cache usage and model selection. A region is a property of the credential and the two never share, so a pool can carry accounts from both.",
|
|
@@ -12314,11 +12347,11 @@ window.__ModuleLoader__.load({
|
|
|
12314
12347
|
cacheEmpty: "No request on this machine has reported usage yet — run a conversation and look again.",
|
|
12315
12348
|
cacheHitRatioUnavailable: "—"
|
|
12316
12349
|
};
|
|
12317
|
-
const dictionaries$
|
|
12318
|
-
zh: zh$
|
|
12319
|
-
"zh-CN": zh$
|
|
12320
|
-
en: en$
|
|
12321
|
-
"en-US": en$
|
|
12350
|
+
const dictionaries$7 = {
|
|
12351
|
+
zh: zh$7,
|
|
12352
|
+
"zh-CN": zh$7,
|
|
12353
|
+
en: en$7,
|
|
12354
|
+
"en-US": en$7
|
|
12322
12355
|
};
|
|
12323
12356
|
/** 一个额度窗口的键到「窗口长度(分钟)」的映射。窗口名由共享组件按长度本地化。 */
|
|
12324
12357
|
const QUOTA_WINDOW_MINUTES = {
|
|
@@ -12436,7 +12469,7 @@ window.__ModuleLoader__.load({
|
|
|
12436
12469
|
/** 登录状态机的轮询节奏。真实超时与间隔由 host 拥有,卡片只是跟随。 */
|
|
12437
12470
|
const LOGIN_POLL_INTERVAL_MS$1 = 2e3;
|
|
12438
12471
|
/** 本卡片的字典;身份稳定,依赖它的 effect 才不会每次渲染重建。 */
|
|
12439
|
-
const fallbackTranslate$3 = (key) => zh$
|
|
12472
|
+
const fallbackTranslate$3 = (key) => zh$7[key];
|
|
12440
12473
|
/**
|
|
12441
12474
|
* 共享账号池卡片需要的标签集,按本卡片的字典逐键查出来。
|
|
12442
12475
|
*
|
|
@@ -13122,7 +13155,7 @@ window.__ModuleLoader__.load({
|
|
|
13122
13155
|
const { status, loading, busy, error, connection, adoptResult, pasteValue, profile, pasteOpen, contextDrafts, savingModel, quotaAccount, quotaPassword, quotaToken } = state;
|
|
13123
13156
|
const { accounts, models, contextModels, overrideCount, login, quota, authenticated, poolLabels, cache, cacheHitRatio: hitRatio, quotaCredential } = derived;
|
|
13124
13157
|
const { setProfile, login: startLogin, cancelLogin, submitPaste, setPasteValue, togglePaste, adopt, clearAdoptResult, accountAction, setStrategy, toggleModel, setAllModels, saveContextWindow, resetContextWindow, resetAllContextWindows, updateContextDraft, setDefaultReasoningEffort, setCacheRequestParams, refreshQuota, refreshCatalog, testConnection, setQuotaAccount, setQuotaPassword, setQuotaToken, submitQuotaPassword, submitQuotaToken, clearQuotaCredential } = actions;
|
|
13125
|
-
const t = useLineDict(NS_STEP_CODE, zh$
|
|
13158
|
+
const t = useLineDict(NS_STEP_CODE, zh$7);
|
|
13126
13159
|
if (loading) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
13127
13160
|
className: "dsha-page",
|
|
13128
13161
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
@@ -14038,7 +14071,7 @@ window.__ModuleLoader__.load({
|
|
|
14038
14071
|
//#endregion
|
|
14039
14072
|
//#region src/client/cline-pass/locales.ts
|
|
14040
14073
|
const NS_CLINE_PASS = "dsh-cline-pass";
|
|
14041
|
-
const zh$
|
|
14074
|
+
const zh$6 = {
|
|
14042
14075
|
...accountPoolZh,
|
|
14043
14076
|
relogin: "重新登录",
|
|
14044
14077
|
needsRelogin: "登录已失效",
|
|
@@ -14201,7 +14234,7 @@ window.__ModuleLoader__.load({
|
|
|
14201
14234
|
limitRoute: "模型路由按 provider id 抢占:若已有其他插件占用 cline-pass,本卡仍可配置,但请求由对方服务。",
|
|
14202
14235
|
limitQuota: "额度窗口来自网关的 usage-limits 接口;接口失败时卡片保留上一次读数并显示原因。"
|
|
14203
14236
|
};
|
|
14204
|
-
const en$
|
|
14237
|
+
const en$6 = {
|
|
14205
14238
|
...accountPoolEn,
|
|
14206
14239
|
relogin: "Sign in again",
|
|
14207
14240
|
needsRelogin: "Sign-in expired",
|
|
@@ -14364,11 +14397,11 @@ window.__ModuleLoader__.load({
|
|
|
14364
14397
|
limitRoute: "The route is claimed by provider id: if another plugin already serves cline-pass, this card still configures the line but that provider answers the requests.",
|
|
14365
14398
|
limitQuota: "Quota windows come from the gateway usage-limits endpoint; when it fails the card keeps the previous reading and says why."
|
|
14366
14399
|
};
|
|
14367
|
-
const dictionaries$
|
|
14368
|
-
zh: zh$
|
|
14369
|
-
"zh-CN": zh$
|
|
14370
|
-
en: en$
|
|
14371
|
-
"en-US": en$
|
|
14400
|
+
const dictionaries$6 = {
|
|
14401
|
+
zh: zh$6,
|
|
14402
|
+
"zh-CN": zh$6,
|
|
14403
|
+
en: en$6,
|
|
14404
|
+
"en-US": en$6
|
|
14372
14405
|
};
|
|
14373
14406
|
//#endregion
|
|
14374
14407
|
//#region src/client/cline-pass/ClinePassSection.tsx
|
|
@@ -14495,10 +14528,10 @@ window.__ModuleLoader__.load({
|
|
|
14495
14528
|
API$4.loginStatus(flow.id).then((next) => {
|
|
14496
14529
|
setLoginFlow(next);
|
|
14497
14530
|
if (next.status === "complete") {
|
|
14498
|
-
setNotice(zh$
|
|
14531
|
+
setNotice(zh$6.loginComplete.replace("{account}", next.accountAlias === "" ? "Cline Pass" : next.accountAlias));
|
|
14499
14532
|
setShowKeyForm(false);
|
|
14500
14533
|
loadStatus();
|
|
14501
|
-
} else if (next.status === "failed") setError(zh$
|
|
14534
|
+
} else if (next.status === "failed") setError(zh$6.loginFailed.replace("{detail}", next.error));
|
|
14502
14535
|
}).catch((cause) => setError(detail$1(cause)));
|
|
14503
14536
|
}, Math.max(2, flow.intervalSeconds) * 1e3);
|
|
14504
14537
|
return () => window.clearInterval(timer);
|
|
@@ -14572,7 +14605,7 @@ window.__ModuleLoader__.load({
|
|
|
14572
14605
|
apiKey: trimmed,
|
|
14573
14606
|
...keyBaseURL.trim() === "" ? {} : { baseURL: keyBaseURL.trim() }
|
|
14574
14607
|
}).then((result) => {
|
|
14575
|
-
setNotice(result.authorized ? zh$
|
|
14608
|
+
setNotice(result.authorized ? zh$6.keyTestOk.replace("{ms}", String(Math.round(result.ms))) : zh$6.keyTestFailed.replace("{detail}", result.error));
|
|
14576
14609
|
}).catch((cause) => setError(detail$1(cause))).finally(() => setBusy(null));
|
|
14577
14610
|
}, [key, keyBaseURL]);
|
|
14578
14611
|
const testStored = (0, react.useCallback)((accountId) => {
|
|
@@ -14580,7 +14613,7 @@ window.__ModuleLoader__.load({
|
|
|
14580
14613
|
setError(null);
|
|
14581
14614
|
setNotice(null);
|
|
14582
14615
|
API$4.testKey({ accountId }).then((result) => {
|
|
14583
|
-
setNotice(result.authorized ? zh$
|
|
14616
|
+
setNotice(result.authorized ? zh$6.keyTestOk.replace("{ms}", String(Math.round(result.ms))) : zh$6.keyTestFailed.replace("{detail}", result.error));
|
|
14584
14617
|
}).catch((cause) => setError(detail$1(cause))).finally(() => setBusy(null));
|
|
14585
14618
|
}, []);
|
|
14586
14619
|
const enabledModels = (0, react.useMemo)(() => (status?.models ?? []).filter((model) => model.enabled), [status]);
|
|
@@ -14606,7 +14639,7 @@ window.__ModuleLoader__.load({
|
|
|
14606
14639
|
if (model === void 0) return;
|
|
14607
14640
|
const parsed = parsePositiveCapacity$1(drafts[id] ?? formatCapacity$1(model.contextWindow));
|
|
14608
14641
|
if (parsed === null) {
|
|
14609
|
-
setError(zh$
|
|
14642
|
+
setError(zh$6.error.replace("{detail}", zh$6.defaultContextWindow));
|
|
14610
14643
|
return;
|
|
14611
14644
|
}
|
|
14612
14645
|
run("ctx:" + id, () => API$4.setContextWindow(id, parsed));
|
|
@@ -14628,7 +14661,7 @@ window.__ModuleLoader__.load({
|
|
|
14628
14661
|
}, [run, status]);
|
|
14629
14662
|
const resetAllContext = (0, react.useCallback)(() => {
|
|
14630
14663
|
if (status === null) return;
|
|
14631
|
-
if (typeof window !== "undefined" && !window.confirm(zh$
|
|
14664
|
+
if (typeof window !== "undefined" && !window.confirm(zh$6.contextResetAll)) return;
|
|
14632
14665
|
const overridden = status.models.filter((model) => model.contextWindowOverride !== void 0);
|
|
14633
14666
|
run("ctx-all", async () => {
|
|
14634
14667
|
let next = status;
|
|
@@ -14669,7 +14702,7 @@ window.__ModuleLoader__.load({
|
|
|
14669
14702
|
const refreshUsage = (0, react.useCallback)(() => {
|
|
14670
14703
|
run("usage", async () => {
|
|
14671
14704
|
const outcome = await API$4.readUsage();
|
|
14672
|
-
setNotice(outcome.usage.accounts.some((account) => account.ok) ? "" : zh$
|
|
14705
|
+
setNotice(outcome.usage.accounts.some((account) => account.ok) ? "" : zh$6.usageEmpty);
|
|
14673
14706
|
return outcome.status;
|
|
14674
14707
|
});
|
|
14675
14708
|
}, [run]);
|
|
@@ -14689,7 +14722,7 @@ window.__ModuleLoader__.load({
|
|
|
14689
14722
|
};
|
|
14690
14723
|
const invalid = Object.entries(numbers).find(([, value]) => !Number.isSafeInteger(value) || value < 0);
|
|
14691
14724
|
if (invalid !== void 0) {
|
|
14692
|
-
setError(zh$
|
|
14725
|
+
setError(zh$6.error.replace("{detail}", invalid[0]));
|
|
14693
14726
|
return;
|
|
14694
14727
|
}
|
|
14695
14728
|
setBusy("settings");
|
|
@@ -14701,7 +14734,7 @@ window.__ModuleLoader__.load({
|
|
|
14701
14734
|
}).then((next) => {
|
|
14702
14735
|
applyStatus(next);
|
|
14703
14736
|
setSettingsForm(settingsFormOf$1(next));
|
|
14704
|
-
setNotice(zh$
|
|
14737
|
+
setNotice(zh$6.saved);
|
|
14705
14738
|
}).catch((cause) => setError(detail$1(cause))).finally(() => setBusy(null));
|
|
14706
14739
|
}, [settingsForm, applyStatus]);
|
|
14707
14740
|
const toggleTools = (0, react.useCallback)(() => {
|
|
@@ -14712,10 +14745,10 @@ window.__ModuleLoader__.load({
|
|
|
14712
14745
|
API$4.updateSettings({ exposeTools: value }).then((next) => {
|
|
14713
14746
|
applyStatus(next);
|
|
14714
14747
|
setSettingsForm(settingsFormOf$1(next));
|
|
14715
|
-
setNotice(zh$
|
|
14748
|
+
setNotice(zh$6.restartRequired);
|
|
14716
14749
|
}).catch((cause) => setError(detail$1(cause))).finally(() => setBusy(null));
|
|
14717
14750
|
}, [status, applyStatus]);
|
|
14718
|
-
const t = useLineDict(NS_CLINE_PASS, zh$
|
|
14751
|
+
const t = useLineDict(NS_CLINE_PASS, zh$6);
|
|
14719
14752
|
const errorPrefix = t.error.split("{detail}")[0] ?? "";
|
|
14720
14753
|
const pool = status?.pool;
|
|
14721
14754
|
const accounts = (0, react.useMemo)(() => {
|
|
@@ -15912,7 +15945,7 @@ window.__ModuleLoader__.load({
|
|
|
15912
15945
|
* 'settings.section' 上的那张座位(那张座绑定的是 ChatGPT 的键集)。
|
|
15913
15946
|
*/
|
|
15914
15947
|
const NS_QODER = "dsh-qoder";
|
|
15915
|
-
const zh$
|
|
15948
|
+
const zh$5 = {
|
|
15916
15949
|
modelRowEfforts: "档位 {list}",
|
|
15917
15950
|
modelRowNoEfforts: "无档位",
|
|
15918
15951
|
modelRowOutput: "输出 {cap}",
|
|
@@ -16036,8 +16069,8 @@ window.__ModuleLoader__.load({
|
|
|
16036
16069
|
quotaWindow: "额度窗口"
|
|
16037
16070
|
};
|
|
16038
16071
|
/** 两套字典。 */
|
|
16039
|
-
const dictionaries$
|
|
16040
|
-
zh: zh$
|
|
16072
|
+
const dictionaries$5 = {
|
|
16073
|
+
zh: zh$5,
|
|
16041
16074
|
en: {
|
|
16042
16075
|
modelRowEfforts: "efforts {list}",
|
|
16043
16076
|
modelRowNoEfforts: "no efforts",
|
|
@@ -16238,7 +16271,7 @@ window.__ModuleLoader__.load({
|
|
|
16238
16271
|
/** 登录状态机的轮询节奏。真实超时与间隔由 host 拥有,卡片只是跟随。 */
|
|
16239
16272
|
const LOGIN_POLL_INTERVAL_MS = 2e3;
|
|
16240
16273
|
/** 本卡片的字典;身份稳定,依赖它的 effect 才不会每次渲染重建。 */
|
|
16241
|
-
const fallbackTranslate$2 = (key) => zh$
|
|
16274
|
+
const fallbackTranslate$2 = (key) => zh$5[key];
|
|
16242
16275
|
/**
|
|
16243
16276
|
* 共享账号池卡片需要的标签集,按本卡片的字典逐键查出来。
|
|
16244
16277
|
*
|
|
@@ -16804,7 +16837,7 @@ window.__ModuleLoader__.load({
|
|
|
16804
16837
|
* `defaultMaxTokens`),客户端不按模型名推断任何一项。与 OpenDesign 卡同一写法:
|
|
16805
16838
|
* 数据一行,散文进折叠区。
|
|
16806
16839
|
*/
|
|
16807
|
-
function qoderModelRowHint(model, t = zh$
|
|
16840
|
+
function qoderModelRowHint(model, t = zh$5) {
|
|
16808
16841
|
return `${formatTokenCount(model.contextWindow)} · ${model.supportsImages ? "text+image" : "text"} · ${model.reasoningEfforts.length === 0 ? t.modelRowNoEfforts : t.modelRowEfforts.replace("{list}", model.reasoningEfforts.join("/"))} · ${t.modelRowOutput.replace("{cap}", formatTokenCount(model.defaultMaxTokens))}`;
|
|
16809
16842
|
}
|
|
16810
16843
|
function QoderSection({ onModelChange } = {}) {
|
|
@@ -16812,7 +16845,7 @@ window.__ModuleLoader__.load({
|
|
|
16812
16845
|
const { status, loading, busy, error, connection, adoptResult, pasteValue, region, pasteOpen, contextDrafts, savingModel } = state;
|
|
16813
16846
|
const { accounts, models, contextModels, overrideCount, login, quota, authenticated, poolLabels, cache, cacheHitRatio: hitRatio } = derived;
|
|
16814
16847
|
const { setRegion, login: startLogin, cancelLogin, submitPaste, setPasteValue, togglePaste, adopt, clearAdoptResult, accountAction, setStrategy, toggleModel, setAllModels, saveContextWindow, resetContextWindow, resetAllContextWindows, updateContextDraft, setDefaultReasoningEffort, refreshQuota, refreshCatalog, testConnection } = actions;
|
|
16815
|
-
const t = useLineDict(NS_QODER, zh$
|
|
16848
|
+
const t = useLineDict(NS_QODER, zh$5);
|
|
16816
16849
|
if (loading) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
16817
16850
|
className: "dsha-page",
|
|
16818
16851
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
@@ -17407,7 +17440,7 @@ window.__ModuleLoader__.load({
|
|
|
17407
17440
|
//#endregion
|
|
17408
17441
|
//#region src/client/opendesign/locales.ts
|
|
17409
17442
|
const NS_OPENDESIGN = "dsh-opendesign";
|
|
17410
|
-
const zh$
|
|
17443
|
+
const zh$4 = {
|
|
17411
17444
|
...accountPoolZh,
|
|
17412
17445
|
relogin: "重新登录",
|
|
17413
17446
|
needsRelogin: "登录已失效",
|
|
@@ -17515,7 +17548,7 @@ window.__ModuleLoader__.load({
|
|
|
17515
17548
|
limitRoute: "模型路由按 provider id 抢占:若已有其他插件占用 opendesign,本卡仍可配置,但请求由对方服务。",
|
|
17516
17549
|
limitQuota: "套餐与额度读取只覆盖浏览器授权登录的账号;粘贴的 API Key 没有控制 Key,请在 OpenDesign Cloud 控制台查看用量。"
|
|
17517
17550
|
};
|
|
17518
|
-
const en$
|
|
17551
|
+
const en$4 = {
|
|
17519
17552
|
...accountPoolEn,
|
|
17520
17553
|
relogin: "Add again",
|
|
17521
17554
|
needsRelogin: "Key invalid",
|
|
@@ -17623,11 +17656,11 @@ window.__ModuleLoader__.load({
|
|
|
17623
17656
|
limitRoute: "The route is claimed by provider id: if another plugin already serves opendesign, this card still configures the line but that provider answers the requests.",
|
|
17624
17657
|
limitQuota: "Plan and credit reads cover browser-signed-in accounts only; a pasted API key has no control key, so see usage in the OpenDesign Cloud console."
|
|
17625
17658
|
};
|
|
17626
|
-
const dictionaries$
|
|
17627
|
-
zh: zh$
|
|
17628
|
-
"zh-CN": zh$
|
|
17629
|
-
en: en$
|
|
17630
|
-
"en-US": en$
|
|
17659
|
+
const dictionaries$4 = {
|
|
17660
|
+
zh: zh$4,
|
|
17661
|
+
"zh-CN": zh$4,
|
|
17662
|
+
en: en$4,
|
|
17663
|
+
"en-US": en$4
|
|
17631
17664
|
};
|
|
17632
17665
|
//#endregion
|
|
17633
17666
|
//#region src/client/opendesign/OpenDesignSection.tsx
|
|
@@ -17922,7 +17955,7 @@ window.__ModuleLoader__.load({
|
|
|
17922
17955
|
try {
|
|
17923
17956
|
const outcome = await API$3.readUsage();
|
|
17924
17957
|
setStatus(outcome.status);
|
|
17925
|
-
if (!silent) setNotice(outcome.usage.accounts.some((account) => account.ok) ? "" : zh$
|
|
17958
|
+
if (!silent) setNotice(outcome.usage.accounts.some((account) => account.ok) ? "" : zh$4.usageEmpty);
|
|
17926
17959
|
} catch (cause) {
|
|
17927
17960
|
if (!silent) setError(detail(cause));
|
|
17928
17961
|
}
|
|
@@ -17959,10 +17992,10 @@ window.__ModuleLoader__.load({
|
|
|
17959
17992
|
API$3.loginStatus(flow.id).then((next) => {
|
|
17960
17993
|
setLoginFlow(next);
|
|
17961
17994
|
if (next.status === "complete") {
|
|
17962
|
-
setNotice(zh$
|
|
17995
|
+
setNotice(zh$4.loginComplete.replace("{account}", next.accountAlias === "" ? "OpenDesign" : next.accountAlias));
|
|
17963
17996
|
setShowKeyForm(false);
|
|
17964
17997
|
reload();
|
|
17965
|
-
} else if (next.status === "failed") setError(zh$
|
|
17998
|
+
} else if (next.status === "failed") setError(zh$4.loginFailed.replace("{detail}", next.error));
|
|
17966
17999
|
}).catch((cause) => setError(detail(cause)));
|
|
17967
18000
|
}, Math.max(2, flow.intervalSeconds) * 1e3);
|
|
17968
18001
|
return () => window.clearInterval(timer);
|
|
@@ -18008,7 +18041,7 @@ window.__ModuleLoader__.load({
|
|
|
18008
18041
|
const refreshUsage = (0, react.useCallback)(() => {
|
|
18009
18042
|
run("usage", async () => {
|
|
18010
18043
|
const outcome = await API$3.readUsage();
|
|
18011
|
-
setNotice(outcome.usage.accounts.some((account) => account.ok) ? "" : zh$
|
|
18044
|
+
setNotice(outcome.usage.accounts.some((account) => account.ok) ? "" : zh$4.usageEmpty);
|
|
18012
18045
|
return outcome.status;
|
|
18013
18046
|
});
|
|
18014
18047
|
}, [run]);
|
|
@@ -18043,7 +18076,7 @@ window.__ModuleLoader__.load({
|
|
|
18043
18076
|
apiKey: trimmed,
|
|
18044
18077
|
...keyBaseURL.trim() === "" ? {} : { baseURL: keyBaseURL.trim() }
|
|
18045
18078
|
}).then((result) => {
|
|
18046
|
-
setNotice(result.authorized ? zh$
|
|
18079
|
+
setNotice(result.authorized ? zh$4.keyTestOk.replace("{ms}", String(Math.round(result.ms))).replace("{count}", String(result.modelCount)) : zh$4.keyTestFailed.replace("{detail}", result.error));
|
|
18047
18080
|
}).catch((cause) => setError(detail(cause))).finally(() => setBusy(null));
|
|
18048
18081
|
}, [key, keyBaseURL]);
|
|
18049
18082
|
const testStored = (0, react.useCallback)((accountId) => {
|
|
@@ -18051,7 +18084,7 @@ window.__ModuleLoader__.load({
|
|
|
18051
18084
|
setError(null);
|
|
18052
18085
|
setNotice(null);
|
|
18053
18086
|
API$3.testKey({ accountId }).then((result) => {
|
|
18054
|
-
setNotice(result.authorized ? zh$
|
|
18087
|
+
setNotice(result.authorized ? zh$4.keyTestOk.replace("{ms}", String(Math.round(result.ms))).replace("{count}", String(result.modelCount)) : zh$4.keyTestFailed.replace("{detail}", result.error));
|
|
18055
18088
|
}).catch((cause) => setError(detail(cause))).finally(() => setBusy(null));
|
|
18056
18089
|
}, []);
|
|
18057
18090
|
const enabledModels = (0, react.useMemo)(() => (status?.models ?? []).filter((model) => model.enabled), [status]);
|
|
@@ -18077,7 +18110,7 @@ window.__ModuleLoader__.load({
|
|
|
18077
18110
|
if (model === void 0) return;
|
|
18078
18111
|
const parsed = parsePositiveCapacity$1(drafts[id] ?? formatCapacity$1(model.contextWindow));
|
|
18079
18112
|
if (parsed === null) {
|
|
18080
|
-
setError(zh$
|
|
18113
|
+
setError(zh$4.error.replace("{detail}", zh$4.defaultContextWindow));
|
|
18081
18114
|
return;
|
|
18082
18115
|
}
|
|
18083
18116
|
run("ctx:" + id, () => API$3.setContextWindow(id, parsed));
|
|
@@ -18099,7 +18132,7 @@ window.__ModuleLoader__.load({
|
|
|
18099
18132
|
}, [run, status]);
|
|
18100
18133
|
const resetAllContext = (0, react.useCallback)(() => {
|
|
18101
18134
|
if (status === null) return;
|
|
18102
|
-
if (typeof window !== "undefined" && !window.confirm(zh$
|
|
18135
|
+
if (typeof window !== "undefined" && !window.confirm(zh$4.contextResetAll)) return;
|
|
18103
18136
|
const overridden = status.models.filter((model) => model.contextWindowOverride !== void 0);
|
|
18104
18137
|
run("ctx-all", async () => {
|
|
18105
18138
|
let next = status;
|
|
@@ -18115,7 +18148,7 @@ window.__ModuleLoader__.load({
|
|
|
18115
18148
|
const refreshCatalog = (0, react.useCallback)(() => {
|
|
18116
18149
|
run("catalog", async () => {
|
|
18117
18150
|
const outcome = await API$3.refreshCatalog();
|
|
18118
|
-
setNotice(zh$
|
|
18151
|
+
setNotice(zh$4.catalogSyncedNote.replace("{count}", String(outcome.status.catalogCount)));
|
|
18119
18152
|
return outcome.status;
|
|
18120
18153
|
});
|
|
18121
18154
|
}, [run]);
|
|
@@ -18129,7 +18162,7 @@ window.__ModuleLoader__.load({
|
|
|
18129
18162
|
};
|
|
18130
18163
|
const invalid = Object.entries(numbers).find(([, value]) => !Number.isSafeInteger(value) || value < 0);
|
|
18131
18164
|
if (invalid !== void 0) {
|
|
18132
|
-
setError(zh$
|
|
18165
|
+
setError(zh$4.error.replace("{detail}", invalid[0]));
|
|
18133
18166
|
return;
|
|
18134
18167
|
}
|
|
18135
18168
|
setBusy("settings");
|
|
@@ -18140,10 +18173,10 @@ window.__ModuleLoader__.load({
|
|
|
18140
18173
|
}).then((next) => {
|
|
18141
18174
|
applyStatus(next);
|
|
18142
18175
|
setSettingsForm(settingsFormOf(next));
|
|
18143
|
-
setNotice(zh$
|
|
18176
|
+
setNotice(zh$4.saved);
|
|
18144
18177
|
}).catch((cause) => setError(detail(cause))).finally(() => setBusy(null));
|
|
18145
18178
|
}, [settingsForm, applyStatus]);
|
|
18146
|
-
const t = useLineDict(NS_OPENDESIGN, zh$
|
|
18179
|
+
const t = useLineDict(NS_OPENDESIGN, zh$4);
|
|
18147
18180
|
const errorPrefix = t.error.split("{detail}")[0] ?? "";
|
|
18148
18181
|
const pool = status?.pool;
|
|
18149
18182
|
const accounts = pool?.accounts ?? [];
|
|
@@ -18660,7 +18693,7 @@ window.__ModuleLoader__.load({
|
|
|
18660
18693
|
* control that renders it instead.
|
|
18661
18694
|
*/
|
|
18662
18695
|
const NS_WORKBUDDY = "dsh-workbuddy";
|
|
18663
|
-
const zh$
|
|
18696
|
+
const zh$3 = {
|
|
18664
18697
|
title: "WorkBuddy",
|
|
18665
18698
|
pageDesc: "复用本机 CodeBuddy 桌面端登录态,管理 WorkBuddy(CodeBuddy 订阅)模型、上下文窗口与额度。",
|
|
18666
18699
|
account: "账号",
|
|
@@ -18786,7 +18819,7 @@ window.__ModuleLoader__.load({
|
|
|
18786
18819
|
modelCooldownActive: "模型限流中",
|
|
18787
18820
|
notRoutable: "当前不可路由"
|
|
18788
18821
|
};
|
|
18789
|
-
const en$
|
|
18822
|
+
const en$3 = {
|
|
18790
18823
|
title: "WorkBuddy",
|
|
18791
18824
|
pageDesc: "Reuse the local CodeBuddy desktop sign-in to manage WorkBuddy (CodeBuddy subscription) models, context windows, and quota.",
|
|
18792
18825
|
account: "Account",
|
|
@@ -18912,11 +18945,11 @@ window.__ModuleLoader__.load({
|
|
|
18912
18945
|
modelCooldownActive: "Model parked",
|
|
18913
18946
|
notRoutable: "Not routable right now"
|
|
18914
18947
|
};
|
|
18915
|
-
const dictionaries$
|
|
18916
|
-
zh: zh$
|
|
18917
|
-
"zh-CN": zh$
|
|
18918
|
-
en: en$
|
|
18919
|
-
"en-US": en$
|
|
18948
|
+
const dictionaries$3 = {
|
|
18949
|
+
zh: zh$3,
|
|
18950
|
+
"zh-CN": zh$3,
|
|
18951
|
+
en: en$3,
|
|
18952
|
+
"en-US": en$3
|
|
18920
18953
|
};
|
|
18921
18954
|
//#endregion
|
|
18922
18955
|
//#region src/client/workbuddy/useWorkBuddySection.ts
|
|
@@ -19014,7 +19047,7 @@ window.__ModuleLoader__.load({
|
|
|
19014
19047
|
const quotaFollowUp = (0, react.useRef)(null);
|
|
19015
19048
|
const [contextDrafts, setContextDrafts] = (0, react.useState)({});
|
|
19016
19049
|
const [savingModel, setSavingModel] = (0, react.useState)(null);
|
|
19017
|
-
const t = useLineDict(NS_WORKBUDDY, zh$
|
|
19050
|
+
const t = useLineDict(NS_WORKBUDDY, zh$3);
|
|
19018
19051
|
const notifyChange = (0, react.useCallback)(() => {
|
|
19019
19052
|
onModelChange?.();
|
|
19020
19053
|
loadModelDirectory?.();
|
|
@@ -19648,7 +19681,7 @@ window.__ModuleLoader__.load({
|
|
|
19648
19681
|
const timer = window.setInterval(() => setNow(Date.now()), 1e3);
|
|
19649
19682
|
return () => window.clearInterval(timer);
|
|
19650
19683
|
}, [pausedUntil]);
|
|
19651
|
-
const t = useLineDict(NS_WORKBUDDY, zh$
|
|
19684
|
+
const t = useLineDict(NS_WORKBUDDY, zh$3);
|
|
19652
19685
|
const poolState = poolStateLines(pool, t, now);
|
|
19653
19686
|
const storageLine = poolStorageLine(pool?.storage, t);
|
|
19654
19687
|
const storageUnavailable = pool?.storage === void 0 ? null : poolStorageUnavailableLabel(pool.storage, t);
|
|
@@ -20864,7 +20897,7 @@ window.__ModuleLoader__.load({
|
|
|
20864
20897
|
//#endregion
|
|
20865
20898
|
//#region src/client/locales.ts
|
|
20866
20899
|
const NS = "dsh-chatgpt-subscription";
|
|
20867
|
-
const dictionaries$
|
|
20900
|
+
const dictionaries$2 = {
|
|
20868
20901
|
zh: {
|
|
20869
20902
|
...accountPoolZh,
|
|
20870
20903
|
title: "ChatGPT",
|
|
@@ -21277,7 +21310,7 @@ window.__ModuleLoader__.load({
|
|
|
21277
21310
|
* 不另起一套点号命名——同一份 index.tsx 里两种命名风格会让「这条键属于哪张表」
|
|
21278
21311
|
* 变成要靠记忆的事。
|
|
21279
21312
|
*/
|
|
21280
|
-
const zh = {
|
|
21313
|
+
const zh$1 = {
|
|
21281
21314
|
/** 设置页导航里的那一格,也是侧栏页签的标题。 */
|
|
21282
21315
|
navTitle: "进展更新",
|
|
21283
21316
|
progressTitle: "进展更新",
|
|
@@ -21321,7 +21354,7 @@ window.__ModuleLoader__.load({
|
|
|
21321
21354
|
settingsSaveFailed: "保存失败,请稍后再试"
|
|
21322
21355
|
};
|
|
21323
21356
|
/** 英文对照,键集与 zh 完全一致。 */
|
|
21324
|
-
const en = {
|
|
21357
|
+
const en$1 = {
|
|
21325
21358
|
navTitle: "Progress updates",
|
|
21326
21359
|
progressTitle: "Progress updates",
|
|
21327
21360
|
progressGuideNote: "Every step the agent reports, collected here",
|
|
@@ -21363,11 +21396,11 @@ window.__ModuleLoader__.load({
|
|
|
21363
21396
|
settingsSaveFailed: "Could not save. Try again in a moment."
|
|
21364
21397
|
};
|
|
21365
21398
|
/** 与其余线路同形的字典包(四个内置语言 id 都指向那两份)。 */
|
|
21366
|
-
const dictionaries = {
|
|
21367
|
-
zh,
|
|
21368
|
-
"zh-CN": zh,
|
|
21369
|
-
en,
|
|
21370
|
-
"en-US": en
|
|
21399
|
+
const dictionaries$1 = {
|
|
21400
|
+
zh: zh$1,
|
|
21401
|
+
"zh-CN": zh$1,
|
|
21402
|
+
en: en$1,
|
|
21403
|
+
"en-US": en$1
|
|
21371
21404
|
};
|
|
21372
21405
|
//#endregion
|
|
21373
21406
|
//#region src/client/locales-ru/account-pool.ts
|
|
@@ -22260,6 +22293,10 @@ window.__ModuleLoader__.load({
|
|
|
22260
22293
|
cacheDriftTools: "Список инструментов изменился (кеш сброшен)",
|
|
22261
22294
|
cacheDriftCacheKey: "Ключ кеша изменился (переключение сессии)",
|
|
22262
22295
|
cacheDriftColdKey: "Ключ кеша не отправлен (попадание невозможно)",
|
|
22296
|
+
cacheDriftImageOffload: "Старые изображения выгружены по бюджету (кеш пересобран)",
|
|
22297
|
+
cacheImageBudgetLabel: "Бюджет изображений запроса",
|
|
22298
|
+
cacheImageBudgetValue: "{used} за ход / лимит {budget} (нижний порог {low})",
|
|
22299
|
+
cacheImageBudgetDropped: "{used} за ход / лимит {budget} (выгружено: {dropped})",
|
|
22263
22300
|
preserveThinking: "Сохранение рассуждений (Preserved Thinking)",
|
|
22264
22301
|
preserveOn: "Включено (официальное значение по умолчанию): reasoning_content сохраняется между ходами, многошаговые вызовы инструментов идут связнее, но токены рассуждений входят в вывод.",
|
|
22265
22302
|
preserveOff: "Выключено: сервис не просят возвращать рассуждения. Отключается через DSH_KIMI_CODE_PRESERVE_THINKING=0.",
|
|
@@ -24249,7 +24286,7 @@ window.__ModuleLoader__.load({
|
|
|
24249
24286
|
//#region src/client/minimax-code/MinimaxVideoDocumentBody.tsx
|
|
24250
24287
|
/** 兜底翻译:只在没有 locale 座位时用到。 */
|
|
24251
24288
|
function translate$1(key) {
|
|
24252
|
-
return zh$
|
|
24289
|
+
return zh$11[key] ?? key;
|
|
24253
24290
|
}
|
|
24254
24291
|
/**
|
|
24255
24292
|
* 一个文件地址里的会话与路径。
|
|
@@ -24385,7 +24422,7 @@ window.__ModuleLoader__.load({
|
|
|
24385
24422
|
*/
|
|
24386
24423
|
/** 兜底翻译:只在没有 locale 座位时用到,走同一份 zh 字典。 */
|
|
24387
24424
|
function translate(key) {
|
|
24388
|
-
return zh$
|
|
24425
|
+
return zh$11[key] ?? key;
|
|
24389
24426
|
}
|
|
24390
24427
|
/**
|
|
24391
24428
|
* 一张视频工具卡片。
|
|
@@ -24841,7 +24878,7 @@ window.__ModuleLoader__.load({
|
|
|
24841
24878
|
* 没有快照、没有窗口、或全部窗口都没有百分比时返回 null,即**不渲染胶囊**:
|
|
24842
24879
|
* 契约允许 quota 为 null,装一个占位数字比不显示更像坏了。
|
|
24843
24880
|
*/
|
|
24844
|
-
function selectBadgeFacts$3(status, lookup = (key) => zh$
|
|
24881
|
+
function selectBadgeFacts$3(status, lookup = (key) => zh$10[key]) {
|
|
24845
24882
|
const measured = (status?.quota?.windows ?? []).filter((window) => typeof window.usedPercent === "number" && Number.isFinite(window.usedPercent));
|
|
24846
24883
|
if (measured.length === 0) return null;
|
|
24847
24884
|
const tightest = measured.reduce((best, window) => {
|
|
@@ -24933,7 +24970,7 @@ window.__ModuleLoader__.load({
|
|
|
24933
24970
|
*
|
|
24934
24971
|
* 没有快照、没有窗口、或全部窗口都没有百分比时返回 null(见文件头)。
|
|
24935
24972
|
*/
|
|
24936
|
-
function selectBadgeFacts$2(status, lookup = (key) => zh$
|
|
24973
|
+
function selectBadgeFacts$2(status, lookup = (key) => zh$7[key]) {
|
|
24937
24974
|
const quota = status?.quota;
|
|
24938
24975
|
if (quota === null || quota === void 0) return null;
|
|
24939
24976
|
if (quota.kind !== "windowed") return null;
|
|
@@ -25082,7 +25119,7 @@ window.__ModuleLoader__.load({
|
|
|
25082
25119
|
directory: props.directory,
|
|
25083
25120
|
loadModelDirectory: props.loadModelDirectory,
|
|
25084
25121
|
providerId: "cline-pass",
|
|
25085
|
-
label: zh$
|
|
25122
|
+
label: zh$6.composerLabel,
|
|
25086
25123
|
readStatus: (refresh) => API$1.status(refresh),
|
|
25087
25124
|
selectFacts: selectClinePassFacts
|
|
25088
25125
|
});
|
|
@@ -25178,7 +25215,7 @@ window.__ModuleLoader__.load({
|
|
|
25178
25215
|
* 另外那只可能还剩一大半。所以这里不平均、不取最小剩余,而是取最大已用比例。
|
|
25179
25216
|
* 没有快照、没有桶、或全部桶都没有总额时返回 null(见文件头)。
|
|
25180
25217
|
*/
|
|
25181
|
-
function selectBadgeFacts$1(status, lookup = (key) => zh$
|
|
25218
|
+
function selectBadgeFacts$1(status, lookup = (key) => zh$5[key]) {
|
|
25182
25219
|
const quota = status?.quota;
|
|
25183
25220
|
if (quota === null || quota === void 0) return null;
|
|
25184
25221
|
const measurable = quota.buckets.filter((bucket) => bucket.total !== null && bucket.total > 0 && bucket.used !== null);
|
|
@@ -25188,7 +25225,7 @@ window.__ModuleLoader__.load({
|
|
|
25188
25225
|
const remaining = Math.round((1 - used) * 100);
|
|
25189
25226
|
const unit = tightest.unit !== null && tightest.unit !== "" ? " " + tightest.unit : "";
|
|
25190
25227
|
const bucketLabel = quotaBucketText(tightest.kind, {
|
|
25191
|
-
...zh$
|
|
25228
|
+
...zh$5,
|
|
25192
25229
|
quotaBucketPersonal: lookup("quotaBucketPersonal"),
|
|
25193
25230
|
quotaBucketAddOn: lookup("quotaBucketAddOn"),
|
|
25194
25231
|
quotaBucketOrg: lookup("quotaBucketOrg")
|
|
@@ -25299,7 +25336,7 @@ window.__ModuleLoader__.load({
|
|
|
25299
25336
|
directory: props.directory,
|
|
25300
25337
|
loadModelDirectory: props.loadModelDirectory,
|
|
25301
25338
|
providerId: "opendesign",
|
|
25302
|
-
label: zh$
|
|
25339
|
+
label: zh$4.composerLabel,
|
|
25303
25340
|
readStatus: () => API.status(),
|
|
25304
25341
|
selectFacts: selectOpenDesignFacts
|
|
25305
25342
|
});
|
|
@@ -25320,9 +25357,9 @@ window.__ModuleLoader__.load({
|
|
|
25320
25357
|
* is not), and one decimal is what keeps "1.5 小时" from reading as "2 小时".
|
|
25321
25358
|
*/
|
|
25322
25359
|
function planWindowName(seconds) {
|
|
25323
|
-
if (seconds >= 86400 && seconds % 86400 === 0) return zh$
|
|
25324
|
-
if (seconds >= 3600) return zh$
|
|
25325
|
-
return zh$
|
|
25360
|
+
if (seconds >= 86400 && seconds % 86400 === 0) return zh$4.usageWindowDays.replace("{count}", String(seconds / 86400));
|
|
25361
|
+
if (seconds >= 3600) return zh$4.usageWindowHours.replace("{count}", formatDecimal(seconds / 3600));
|
|
25362
|
+
return zh$4.usageWindowMinutes.replace("{count}", formatDecimal(seconds / 60));
|
|
25326
25363
|
}
|
|
25327
25364
|
/** What a window still has, from the grant and the remainder it states. */
|
|
25328
25365
|
function windowRemaining(limitCredits, remainingCredits) {
|
|
@@ -25355,7 +25392,7 @@ window.__ModuleLoader__.load({
|
|
|
25355
25392
|
const primaryId = status.pool.activeAccountId ?? status.pool.accounts.find((account) => account.isPrimary)?.id;
|
|
25356
25393
|
const reading = readings.find((account) => account.accountId === primaryId) ?? readings[0];
|
|
25357
25394
|
const amount = reading.balanceUsd;
|
|
25358
|
-
const readAt = zh$
|
|
25395
|
+
const readAt = zh$4.usageReadAt.replace("{time}", new Date(reading.fetchedAt).toLocaleTimeString());
|
|
25359
25396
|
const windows = planWindows(reading.codingPlan);
|
|
25360
25397
|
if (windows.length === 0) return {
|
|
25361
25398
|
text: `$${amount}`,
|
|
@@ -25364,8 +25401,8 @@ window.__ModuleLoader__.load({
|
|
|
25364
25401
|
};
|
|
25365
25402
|
const narrowest = windows[0];
|
|
25366
25403
|
return {
|
|
25367
|
-
text: zh$
|
|
25368
|
-
tooltip: `${reading.alias} · ${windows.map((window) => `${window.name} ${zh$
|
|
25404
|
+
text: zh$4.usageWindowRemaining.replace("{remaining}", formatDecimal(narrowest.remaining)),
|
|
25405
|
+
tooltip: `${reading.alias} · ${windows.map((window) => `${window.name} ${zh$4.usageWindowRemaining.replace("{remaining}", formatDecimal(window.remaining))}`).join(" · ")} · ${readAt}`,
|
|
25369
25406
|
level: quotaLevel(narrowest.remaining),
|
|
25370
25407
|
percent: narrowest.remaining
|
|
25371
25408
|
};
|
|
@@ -27194,7 +27231,7 @@ window.__ModuleLoader__.load({
|
|
|
27194
27231
|
}
|
|
27195
27232
|
/** 兜底翻译:只在没有 locale 服务时用到(测试、以及菜单渲染早于字典注册)。 */
|
|
27196
27233
|
function fallbackTranslate$1(key, params) {
|
|
27197
|
-
const template = zh$
|
|
27234
|
+
const template = zh$11[key] ?? key;
|
|
27198
27235
|
if (params === void 0) return template;
|
|
27199
27236
|
return template.replace(/\{(\w+)\}/g, (_match, name) => String(params[name] ?? ""));
|
|
27200
27237
|
}
|
|
@@ -54405,7 +54442,7 @@ window.__ModuleLoader__.load({
|
|
|
54405
54442
|
* @returns 该键的文案;缺键时回退为键本身。
|
|
54406
54443
|
*/
|
|
54407
54444
|
function fallbackTranslate(key, params) {
|
|
54408
|
-
return interpolate(zh[key] ?? key, params);
|
|
54445
|
+
return interpolate(zh$1[key] ?? key, params);
|
|
54409
54446
|
}
|
|
54410
54447
|
/**
|
|
54411
54448
|
* 把 `{name}` 占位符换成实参。
|
|
@@ -54566,7 +54603,7 @@ window.__ModuleLoader__.load({
|
|
|
54566
54603
|
* 先按当前语言的字典取值(没有 `t` 时才用兜底字典),再统一做一次替换。
|
|
54567
54604
|
*/
|
|
54568
54605
|
const translate = (key, params) => {
|
|
54569
|
-
return interpolate(t === void 0 ? zh[key] ?? key : t(key), params);
|
|
54606
|
+
return interpolate(t === void 0 ? zh$1[key] ?? key : t(key), params);
|
|
54570
54607
|
};
|
|
54571
54608
|
const latestId = updates.length > 0 ? updates[updates.length - 1].id : void 0;
|
|
54572
54609
|
/**
|
|
@@ -55672,7 +55709,7 @@ window.__ModuleLoader__.load({
|
|
|
55672
55709
|
* @param name - 服务名。
|
|
55673
55710
|
* @returns 服务实例或 undefined。
|
|
55674
55711
|
*/
|
|
55675
|
-
function serviceOf$
|
|
55712
|
+
function serviceOf$2(ctx, name) {
|
|
55676
55713
|
try {
|
|
55677
55714
|
return ctx.get(name);
|
|
55678
55715
|
} catch {
|
|
@@ -55684,7 +55721,7 @@ window.__ModuleLoader__.load({
|
|
|
55684
55721
|
* @param value - 任意服务值。
|
|
55685
55722
|
* @returns 是否具备 get / describe 两个成员。
|
|
55686
55723
|
*/
|
|
55687
|
-
function isConfigForms(value) {
|
|
55724
|
+
function isConfigForms$1(value) {
|
|
55688
55725
|
if (typeof value !== "object" || value === null) return false;
|
|
55689
55726
|
const face = value;
|
|
55690
55727
|
return typeof face.get === "function" && typeof face.describe === "function";
|
|
@@ -55711,8 +55748,8 @@ window.__ModuleLoader__.load({
|
|
|
55711
55748
|
* @returns 表单通道,或 undefined(这个部署没有设置服务)。
|
|
55712
55749
|
*/
|
|
55713
55750
|
function createProgressSettingsForm(ctx) {
|
|
55714
|
-
const forms = serviceOf$
|
|
55715
|
-
if (!isConfigForms(forms)) return void 0;
|
|
55751
|
+
const forms = serviceOf$2(ctx, "configForms");
|
|
55752
|
+
if (!isConfigForms$1(forms)) return void 0;
|
|
55716
55753
|
const listeners = /* @__PURE__ */ new Set();
|
|
55717
55754
|
let boundId;
|
|
55718
55755
|
let bound;
|
|
@@ -55824,7 +55861,7 @@ window.__ModuleLoader__.load({
|
|
|
55824
55861
|
* @param name - 服务名。
|
|
55825
55862
|
* @returns 服务实例或 undefined。
|
|
55826
55863
|
*/
|
|
55827
|
-
function serviceOf(ctx, name) {
|
|
55864
|
+
function serviceOf$1(ctx, name) {
|
|
55828
55865
|
try {
|
|
55829
55866
|
return ctx.get(name);
|
|
55830
55867
|
} catch {
|
|
@@ -55849,7 +55886,7 @@ window.__ModuleLoader__.load({
|
|
|
55849
55886
|
explicit(PANEL_TAB_KIND);
|
|
55850
55887
|
return;
|
|
55851
55888
|
}
|
|
55852
|
-
const sidebarRight = serviceOf(ctx, "sidebarRight");
|
|
55889
|
+
const sidebarRight = serviceOf$1(ctx, "sidebarRight");
|
|
55853
55890
|
if (typeof sidebarRight?.openTab !== "function") return;
|
|
55854
55891
|
sidebarRight.openTab(PANEL_TAB_KIND);
|
|
55855
55892
|
};
|
|
@@ -55953,7 +55990,7 @@ window.__ModuleLoader__.load({
|
|
|
55953
55990
|
const direct = scope.sidebarRightTabs;
|
|
55954
55991
|
if (direct !== void 0) return direct;
|
|
55955
55992
|
} catch {}
|
|
55956
|
-
return serviceOf(scope, "sidebarRightTabs");
|
|
55993
|
+
return serviceOf$1(scope, "sidebarRightTabs");
|
|
55957
55994
|
};
|
|
55958
55995
|
/**
|
|
55959
55996
|
* 阶段一:声明页签**类型**。
|
|
@@ -55974,7 +56011,7 @@ window.__ModuleLoader__.load({
|
|
|
55974
56011
|
try {
|
|
55975
56012
|
return ctx.locale.bind(NS_PROGRESS_UPDATES)("progressTitle");
|
|
55976
56013
|
} catch {
|
|
55977
|
-
return zh.progressTitle;
|
|
56014
|
+
return zh$1.progressTitle;
|
|
55978
56015
|
}
|
|
55979
56016
|
},
|
|
55980
56017
|
guide: [{
|
|
@@ -55984,14 +56021,14 @@ window.__ModuleLoader__.load({
|
|
|
55984
56021
|
try {
|
|
55985
56022
|
return ctx.locale.bind(NS_PROGRESS_UPDATES)("progressTitle");
|
|
55986
56023
|
} catch {
|
|
55987
|
-
return zh.progressTitle;
|
|
56024
|
+
return zh$1.progressTitle;
|
|
55988
56025
|
}
|
|
55989
56026
|
},
|
|
55990
56027
|
description: () => {
|
|
55991
56028
|
try {
|
|
55992
56029
|
return ctx.locale.bind(NS_PROGRESS_UPDATES)("progressGuideNote");
|
|
55993
56030
|
} catch {
|
|
55994
|
-
return zh.progressGuideNote;
|
|
56031
|
+
return zh$1.progressGuideNote;
|
|
55995
56032
|
}
|
|
55996
56033
|
},
|
|
55997
56034
|
icon: ProgressUpdatesArtwork
|
|
@@ -56069,7 +56106,7 @@ window.__ModuleLoader__.load({
|
|
|
56069
56106
|
try {
|
|
56070
56107
|
return ctx.locale.bind(NS_PROGRESS_UPDATES)("navTitle");
|
|
56071
56108
|
} catch {
|
|
56072
|
-
return zh.navTitle;
|
|
56109
|
+
return zh$1.navTitle;
|
|
56073
56110
|
}
|
|
56074
56111
|
},
|
|
56075
56112
|
locale: NS_PROGRESS_UPDATES,
|
|
@@ -56115,7 +56152,7 @@ window.__ModuleLoader__.load({
|
|
|
56115
56152
|
* 单独一支分支。写死的只有开关滑块投影与品牌方块淡染这类"结构色"。
|
|
56116
56153
|
*/
|
|
56117
56154
|
/** 这张表的 `data-plugin-css` 子名。 */
|
|
56118
|
-
const STYLE_NAME = "progress-updates";
|
|
56155
|
+
const STYLE_NAME$1 = "progress-updates";
|
|
56119
56156
|
/** 设置卡片与面板的样式全文。 */
|
|
56120
56157
|
const CSS = `
|
|
56121
56158
|
.dsh-progress-overview{display:flex;flex-direction:column;min-width:0}
|
|
@@ -56152,7 +56189,7 @@ window.__ModuleLoader__.load({
|
|
|
56152
56189
|
* @returns 空操作释放函数(与邻居同形)。
|
|
56153
56190
|
*/
|
|
56154
56191
|
function installProgressUpdatesStyles() {
|
|
56155
|
-
return installPluginStyle(STYLE_NAME, CSS);
|
|
56192
|
+
return installPluginStyle(STYLE_NAME$1, CSS);
|
|
56156
56193
|
}
|
|
56157
56194
|
//#endregion
|
|
56158
56195
|
//#region src/client/workbuddy/WorkBuddyComposerQuota.tsx
|
|
@@ -56218,7 +56255,7 @@ window.__ModuleLoader__.load({
|
|
|
56218
56255
|
providerId: "workbuddy-subscription",
|
|
56219
56256
|
readStatus: (refresh) => refresh ? api.post("/quota") : api.get("/status"),
|
|
56220
56257
|
selectFacts: selectBadgeFacts,
|
|
56221
|
-
label: useLineDict(NS_WORKBUDDY, zh$
|
|
56258
|
+
label: useLineDict(NS_WORKBUDDY, zh$3).composerLabel
|
|
56222
56259
|
});
|
|
56223
56260
|
}
|
|
56224
56261
|
//#endregion
|
|
@@ -56282,6 +56319,2165 @@ window.__ModuleLoader__.load({
|
|
|
56282
56319
|
`, STYLE_ID);
|
|
56283
56320
|
}
|
|
56284
56321
|
//#endregion
|
|
56322
|
+
//#region src/client/subagent/subagent-card-controller.ts
|
|
56323
|
+
/**
|
|
56324
|
+
* 「子智能体」设置卡片的**状态与动作**。
|
|
56325
|
+
*
|
|
56326
|
+
* ## 这张卡替换了宿主的同名卡
|
|
56327
|
+
*
|
|
56328
|
+
* 宿主自带 `@deepseek-ai/dsh-client-ui-settings-subagent` 在 `plugins.item` 上以
|
|
56329
|
+
* `id: 'subagent'`、默认 priority 注册。本插件以同一个 id、`priority: -10` 再注册
|
|
56330
|
+
* 一次——槽位的遮蔽规则是「同一个 cell 上 priority 最低的那一条渲染」,于是打开
|
|
56331
|
+
* 「插件 → 子智能体」看到的是这张卡,而不是两张并排。
|
|
56332
|
+
*
|
|
56333
|
+
* ## 三份存储,一次保存
|
|
56334
|
+
*
|
|
56335
|
+
* | 来源 | 内容 | 通道 |
|
|
56336
|
+
* | --- | --- | --- |
|
|
56337
|
+
* | `subagent` 命名空间 | `maxDepth` / `maxActiveSubagents` | `ctx.configForms` |
|
|
56338
|
+
* | `subagent-model-selection-settings` 命名空间 | `enabled` / `allowedModels` | `ctx.configForms` |
|
|
56339
|
+
* | 本插件偏好文档 | 全局默认列表 + 每个主代理模型的专属列表 | `POST /preferences/update` |
|
|
56340
|
+
*
|
|
56341
|
+
* @module @eddyskywalker/dsh-chatgpt-subscription/client/subagent/subagent-card-controller
|
|
56342
|
+
*/
|
|
56343
|
+
/** 宿主侧「运行限制」的命名空间。 */
|
|
56344
|
+
const SUBAGENT_LIMITS_NS = "subagent";
|
|
56345
|
+
/** 宿主侧「模型选择」的命名空间。 */
|
|
56346
|
+
const SUBAGENT_MODEL_SELECTION_NS = "subagent-model-selection-settings";
|
|
56347
|
+
/** 主代理模型下拉里代表「全局默认」的取值。 */
|
|
56348
|
+
const GLOBAL_TARGET = "default";
|
|
56349
|
+
/** 浏览器侧本地备份键(当宿主进程尚未重启加载新版 /preferences/update 时兜底)。 */
|
|
56350
|
+
const LOCAL_STORAGE_KEY = "dsh-chatgpt-subscription:subagent-model-preferences";
|
|
56351
|
+
/** 一条路由的不透明键。 */
|
|
56352
|
+
function routeKey(route) {
|
|
56353
|
+
return `${route.provider}/${route.model}`;
|
|
56354
|
+
}
|
|
56355
|
+
/** 过滤并克隆非空合法路由。 */
|
|
56356
|
+
function cloneRoutes(routes) {
|
|
56357
|
+
const out = [];
|
|
56358
|
+
const seen = /* @__PURE__ */ new Set();
|
|
56359
|
+
for (const route of routes) {
|
|
56360
|
+
if (typeof route?.provider !== "string" || typeof route?.model !== "string") continue;
|
|
56361
|
+
const provider = route.provider.trim();
|
|
56362
|
+
const model = route.model.trim();
|
|
56363
|
+
if (provider.length === 0 || model.length === 0) continue;
|
|
56364
|
+
if (provider === "undefined" || model === "undefined") continue;
|
|
56365
|
+
const key = `${provider}/${model}`;
|
|
56366
|
+
if (seen.has(key)) continue;
|
|
56367
|
+
seen.add(key);
|
|
56368
|
+
out.push({
|
|
56369
|
+
provider,
|
|
56370
|
+
model
|
|
56371
|
+
});
|
|
56372
|
+
}
|
|
56373
|
+
return out;
|
|
56374
|
+
}
|
|
56375
|
+
function sameRouteSet(left, right) {
|
|
56376
|
+
if (left.length !== right.length) return false;
|
|
56377
|
+
const keys = new Set(right.map(routeKey));
|
|
56378
|
+
return left.every((route) => keys.has(routeKey(route)));
|
|
56379
|
+
}
|
|
56380
|
+
function sameOverrides(left, right) {
|
|
56381
|
+
const leftKeys = Object.keys(left).sort();
|
|
56382
|
+
const rightKeys = Object.keys(right).sort();
|
|
56383
|
+
if (leftKeys.length !== rightKeys.length) return false;
|
|
56384
|
+
return leftKeys.every((key, index) => key === rightKeys[index] && sameRouteSet(left[key] ?? [], right[key] ?? []));
|
|
56385
|
+
}
|
|
56386
|
+
/** 最小快照 store:`useSyncExternalStore` 要求引用在两次变更之间稳定。 */
|
|
56387
|
+
function createStore(initial) {
|
|
56388
|
+
let snapshot = initial;
|
|
56389
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
56390
|
+
return {
|
|
56391
|
+
getSnapshot: () => snapshot,
|
|
56392
|
+
subscribe: (listener) => {
|
|
56393
|
+
listeners.add(listener);
|
|
56394
|
+
return () => {
|
|
56395
|
+
listeners.delete(listener);
|
|
56396
|
+
};
|
|
56397
|
+
},
|
|
56398
|
+
setState: (next) => {
|
|
56399
|
+
snapshot = next;
|
|
56400
|
+
for (const listener of [...listeners]) listener();
|
|
56401
|
+
}
|
|
56402
|
+
};
|
|
56403
|
+
}
|
|
56404
|
+
/** 未绑定表单时的空快照。 */
|
|
56405
|
+
const EMPTY_SNAPSHOT = Object.freeze({
|
|
56406
|
+
status: "unavailable",
|
|
56407
|
+
value: void 0,
|
|
56408
|
+
base: void 0,
|
|
56409
|
+
user: void 0,
|
|
56410
|
+
revision: void 0,
|
|
56411
|
+
writable: false
|
|
56412
|
+
});
|
|
56413
|
+
/** 空表单(服务缺席时用它顶替,让所有读取都成立)。 */
|
|
56414
|
+
const NO_SCOPE = {
|
|
56415
|
+
getSnapshot: () => EMPTY_SNAPSHOT,
|
|
56416
|
+
subscribe: () => () => {}
|
|
56417
|
+
};
|
|
56418
|
+
/**
|
|
56419
|
+
* 归一化模型目录分组:兼容宿主的 `{ id, name, models }` 与测试替身的 `{ provider, providerName, models }`。
|
|
56420
|
+
*/
|
|
56421
|
+
function normalizeCatalogGroups(rawGroups) {
|
|
56422
|
+
const groups = [];
|
|
56423
|
+
for (const entry of rawGroups) {
|
|
56424
|
+
if (typeof entry !== "object" || entry === null) continue;
|
|
56425
|
+
const rec = entry;
|
|
56426
|
+
const provider = typeof rec["provider"] === "string" && rec["provider"].trim().length > 0 ? rec["provider"].trim() : typeof rec["id"] === "string" && rec["id"].trim().length > 0 ? rec["id"].trim() : "";
|
|
56427
|
+
if (provider.length === 0) continue;
|
|
56428
|
+
const providerName = typeof rec["providerName"] === "string" && rec["providerName"].trim().length > 0 ? rec["providerName"].trim() : typeof rec["name"] === "string" && rec["name"].trim().length > 0 ? rec["name"].trim() : provider;
|
|
56429
|
+
const rawModels = Array.isArray(rec["models"]) ? rec["models"] : [];
|
|
56430
|
+
const models = [];
|
|
56431
|
+
for (const rawModel of rawModels) {
|
|
56432
|
+
if (typeof rawModel !== "object" || rawModel === null) continue;
|
|
56433
|
+
const mRec = rawModel;
|
|
56434
|
+
const id = typeof mRec["id"] === "string" && mRec["id"].trim().length > 0 ? mRec["id"].trim() : typeof mRec["model"] === "string" && mRec["model"].trim().length > 0 ? mRec["model"].trim() : "";
|
|
56435
|
+
if (id.length === 0) continue;
|
|
56436
|
+
const name = typeof mRec["name"] === "string" && mRec["name"].trim().length > 0 ? mRec["name"].trim() : typeof mRec["modelName"] === "string" && mRec["modelName"].trim().length > 0 ? mRec["modelName"].trim() : id;
|
|
56437
|
+
models.push({
|
|
56438
|
+
id,
|
|
56439
|
+
name
|
|
56440
|
+
});
|
|
56441
|
+
}
|
|
56442
|
+
groups.push({
|
|
56443
|
+
provider,
|
|
56444
|
+
providerName,
|
|
56445
|
+
models
|
|
56446
|
+
});
|
|
56447
|
+
}
|
|
56448
|
+
return groups;
|
|
56449
|
+
}
|
|
56450
|
+
function readLocalBackup() {
|
|
56451
|
+
try {
|
|
56452
|
+
if (typeof localStorage === "undefined") return void 0;
|
|
56453
|
+
const raw = localStorage.getItem(LOCAL_STORAGE_KEY);
|
|
56454
|
+
if (!raw) return void 0;
|
|
56455
|
+
const parsed = JSON.parse(raw);
|
|
56456
|
+
if (typeof parsed !== "object" || parsed === null) return void 0;
|
|
56457
|
+
return {
|
|
56458
|
+
subagentDefaultModels: Array.isArray(parsed.subagentDefaultModels) ? cloneRoutes(parsed.subagentDefaultModels) : [],
|
|
56459
|
+
subagentModelsByMainModel: parsed.subagentModelsByMainModel ?? {}
|
|
56460
|
+
};
|
|
56461
|
+
} catch {
|
|
56462
|
+
return;
|
|
56463
|
+
}
|
|
56464
|
+
}
|
|
56465
|
+
function writeLocalBackup(patch) {
|
|
56466
|
+
try {
|
|
56467
|
+
if (typeof localStorage === "undefined") return;
|
|
56468
|
+
const prev = readLocalBackup();
|
|
56469
|
+
const mergedOverrides = { ...prev?.subagentModelsByMainModel ?? {} };
|
|
56470
|
+
for (const [k, v] of Object.entries(patch.subagentModelsByMainModel ?? {})) if (v === null || !Array.isArray(v) || v.length === 0) delete mergedOverrides[k];
|
|
56471
|
+
else mergedOverrides[k] = cloneRoutes(v);
|
|
56472
|
+
localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify({
|
|
56473
|
+
subagentDefaultModels: Array.isArray(patch.subagentDefaultModels) ? cloneRoutes(patch.subagentDefaultModels) : prev?.subagentDefaultModels ?? [],
|
|
56474
|
+
subagentModelsByMainModel: mergedOverrides
|
|
56475
|
+
}));
|
|
56476
|
+
} catch {}
|
|
56477
|
+
}
|
|
56478
|
+
/**
|
|
56479
|
+
* 读本插件偏好里的子代理模型两项。
|
|
56480
|
+
* @returns 偏好切片;读取失败时 undefined(卡片照常可用,只是从空列表起步)。
|
|
56481
|
+
*/
|
|
56482
|
+
async function readSubagentPreferences() {
|
|
56483
|
+
const local = readLocalBackup();
|
|
56484
|
+
try {
|
|
56485
|
+
const response = await fetch(`${ROUTE_PREFIX}/status`, { credentials: "same-origin" });
|
|
56486
|
+
if (!response.ok) return local;
|
|
56487
|
+
const preferences = (await response.json())?.value?.preferences;
|
|
56488
|
+
if (preferences === void 0 || preferences === null) return local;
|
|
56489
|
+
const serverDefaults = Array.isArray(preferences.subagentDefaultModels) ? cloneRoutes(preferences.subagentDefaultModels) : [];
|
|
56490
|
+
const serverByMain = preferences.subagentModelsByMainModel ?? {};
|
|
56491
|
+
if (serverDefaults.length === 0 && Object.keys(serverByMain).length === 0 && local !== void 0) return local;
|
|
56492
|
+
return {
|
|
56493
|
+
subagentDefaultModels: serverDefaults,
|
|
56494
|
+
subagentModelsByMainModel: serverByMain
|
|
56495
|
+
};
|
|
56496
|
+
} catch {
|
|
56497
|
+
return local;
|
|
56498
|
+
}
|
|
56499
|
+
}
|
|
56500
|
+
/**
|
|
56501
|
+
* 写本插件偏好里的子代理模型两项。
|
|
56502
|
+
* @param patch - 要写入的两项。
|
|
56503
|
+
*/
|
|
56504
|
+
async function writeSubagentPreferences(patch) {
|
|
56505
|
+
writeLocalBackup(patch);
|
|
56506
|
+
const response = await fetch(`${ROUTE_PREFIX}/preferences/update`, {
|
|
56507
|
+
method: "POST",
|
|
56508
|
+
credentials: "same-origin",
|
|
56509
|
+
headers: { "content-type": "application/json" },
|
|
56510
|
+
body: JSON.stringify(patch)
|
|
56511
|
+
});
|
|
56512
|
+
const envelope = await response.json().catch(() => void 0);
|
|
56513
|
+
if (!response.ok || envelope?.ok === false) throw new Error(envelope?.error?.message ?? "The deployment rejected the subagent model preferences.");
|
|
56514
|
+
}
|
|
56515
|
+
/**
|
|
56516
|
+
* 读宿主模型目录。
|
|
56517
|
+
*
|
|
56518
|
+
* `remote.session.modelCatalog()` 返回 `{ ok: true, value: { groups: ModelProviderGroup[], failures } }`,
|
|
56519
|
+
* 其中每个 `group` 是 `{ id: string, name: string, models: Array<{ id: string, name: string }> }`。
|
|
56520
|
+
* @param ctx - 浏览器根上下文(只用 `get`)。
|
|
56521
|
+
* @returns 分组,或失败。
|
|
56522
|
+
*/
|
|
56523
|
+
async function readSubagentCatalog(ctx) {
|
|
56524
|
+
try {
|
|
56525
|
+
const session = (ctx?.get?.("remote"))?.session;
|
|
56526
|
+
const call = session?.modelCatalog;
|
|
56527
|
+
if (typeof call === "function" && session !== void 0) {
|
|
56528
|
+
const answer = await call.call(session);
|
|
56529
|
+
if (answer?.ok === true && Array.isArray(answer.value?.groups)) return {
|
|
56530
|
+
ok: true,
|
|
56531
|
+
groups: normalizeCatalogGroups(answer.value.groups),
|
|
56532
|
+
partial: (answer.value.failures?.length ?? 0) > 0
|
|
56533
|
+
};
|
|
56534
|
+
return {
|
|
56535
|
+
ok: false,
|
|
56536
|
+
groups: []
|
|
56537
|
+
};
|
|
56538
|
+
}
|
|
56539
|
+
} catch {
|
|
56540
|
+
return {
|
|
56541
|
+
ok: false,
|
|
56542
|
+
groups: []
|
|
56543
|
+
};
|
|
56544
|
+
}
|
|
56545
|
+
return {
|
|
56546
|
+
ok: false,
|
|
56547
|
+
groups: []
|
|
56548
|
+
};
|
|
56549
|
+
}
|
|
56550
|
+
/** 数字限制字段的解析规则。 */
|
|
56551
|
+
function parseLimit(text, minimum) {
|
|
56552
|
+
const trimmed = text.trim();
|
|
56553
|
+
if (!/^[0-9]+$/.test(trimmed)) return void 0;
|
|
56554
|
+
const value = Number(trimmed);
|
|
56555
|
+
return Number.isSafeInteger(value) && value >= minimum && !Object.is(value, -0) ? value : void 0;
|
|
56556
|
+
}
|
|
56557
|
+
/** 取表单快照里的一个数字字段(缺失时用兜底值)。 */
|
|
56558
|
+
function readNumber(value, field, fallback) {
|
|
56559
|
+
if (typeof value !== "object" || value === null) return fallback;
|
|
56560
|
+
const raw = value[field];
|
|
56561
|
+
return typeof raw === "number" && Number.isSafeInteger(raw) ? raw : fallback;
|
|
56562
|
+
}
|
|
56563
|
+
/** 用户层是否已经覆盖了某个字段(存在性即覆盖,与值无关)。 */
|
|
56564
|
+
function userHas(user, field) {
|
|
56565
|
+
return typeof user === "object" && user !== null && field in user;
|
|
56566
|
+
}
|
|
56567
|
+
/**
|
|
56568
|
+
* 子智能体设置卡片的状态机。
|
|
56569
|
+
*/
|
|
56570
|
+
var SubagentSettingsController = class {
|
|
56571
|
+
limits;
|
|
56572
|
+
modelSelection;
|
|
56573
|
+
loadCatalog;
|
|
56574
|
+
loadPreferences;
|
|
56575
|
+
savePreferences;
|
|
56576
|
+
store = createStore(void 0);
|
|
56577
|
+
unsubscribes = [];
|
|
56578
|
+
preferences;
|
|
56579
|
+
preferencesStatus = "idle";
|
|
56580
|
+
catalogGroups = [];
|
|
56581
|
+
catalogPartial = false;
|
|
56582
|
+
catalogStatus = "idle";
|
|
56583
|
+
draftDepth;
|
|
56584
|
+
draftDepthCleared = false;
|
|
56585
|
+
draftActive;
|
|
56586
|
+
draftActiveCleared = false;
|
|
56587
|
+
draftEnabled;
|
|
56588
|
+
draftDefault;
|
|
56589
|
+
draftOverrides;
|
|
56590
|
+
draftRevision;
|
|
56591
|
+
activeTarget = GLOBAL_TARGET;
|
|
56592
|
+
saving = false;
|
|
56593
|
+
failed = false;
|
|
56594
|
+
disposed = false;
|
|
56595
|
+
catalogGeneration = 0;
|
|
56596
|
+
saveGeneration = 0;
|
|
56597
|
+
/**
|
|
56598
|
+
* @param options - 表单通道与三条外部依赖;全部可省,省略时卡片是只读的。
|
|
56599
|
+
*/
|
|
56600
|
+
constructor(options = {}) {
|
|
56601
|
+
this.limits = options.limits ?? NO_SCOPE;
|
|
56602
|
+
this.modelSelection = options.modelSelection ?? NO_SCOPE;
|
|
56603
|
+
this.loadCatalog = options.loadCatalog ?? (() => Promise.resolve({
|
|
56604
|
+
ok: false,
|
|
56605
|
+
groups: []
|
|
56606
|
+
}));
|
|
56607
|
+
this.loadPreferences = options.loadPreferences ?? (() => Promise.resolve(void 0));
|
|
56608
|
+
this.savePreferences = options.savePreferences ?? (() => Promise.resolve());
|
|
56609
|
+
this.unsubscribes.push(this.limits.subscribe(() => {
|
|
56610
|
+
this.publish();
|
|
56611
|
+
}));
|
|
56612
|
+
this.unsubscribes.push(this.modelSelection.subscribe(() => {
|
|
56613
|
+
this.publish();
|
|
56614
|
+
}));
|
|
56615
|
+
this.publish();
|
|
56616
|
+
this.hydrate();
|
|
56617
|
+
}
|
|
56618
|
+
/** 停掉订阅与迟到的保存/目录答复。 */
|
|
56619
|
+
dispose() {
|
|
56620
|
+
this.disposed = true;
|
|
56621
|
+
this.saveGeneration += 1;
|
|
56622
|
+
this.catalogGeneration += 1;
|
|
56623
|
+
for (const off of this.unsubscribes.splice(0)) try {
|
|
56624
|
+
off();
|
|
56625
|
+
} catch {}
|
|
56626
|
+
}
|
|
56627
|
+
/** 刷新模型目录(当适配器或设置文档在其他位置变更时调用)。 */
|
|
56628
|
+
refreshCatalog() {
|
|
56629
|
+
if (this.disposed) return;
|
|
56630
|
+
this.loadCatalogOnce();
|
|
56631
|
+
}
|
|
56632
|
+
/** 重连后重置连接态与目录。 */
|
|
56633
|
+
resetConnection() {
|
|
56634
|
+
if (this.disposed) return;
|
|
56635
|
+
this.saveGeneration += 1;
|
|
56636
|
+
this.saving = false;
|
|
56637
|
+
this.clearDraft();
|
|
56638
|
+
this.catalogGroups = [];
|
|
56639
|
+
this.hydrate();
|
|
56640
|
+
}
|
|
56641
|
+
/**
|
|
56642
|
+
* 组装注入给渲染器的座位。
|
|
56643
|
+
* @returns 快照与全部动作。
|
|
56644
|
+
*/
|
|
56645
|
+
inject() {
|
|
56646
|
+
return {
|
|
56647
|
+
store: this.store,
|
|
56648
|
+
editLimit: (field, text) => {
|
|
56649
|
+
this.editLimit(field, text);
|
|
56650
|
+
},
|
|
56651
|
+
resetLimit: (field) => {
|
|
56652
|
+
this.resetLimit(field);
|
|
56653
|
+
},
|
|
56654
|
+
toggleEnabled: () => {
|
|
56655
|
+
this.toggleEnabled();
|
|
56656
|
+
},
|
|
56657
|
+
toggleModel: (key) => {
|
|
56658
|
+
this.toggleModel(key);
|
|
56659
|
+
},
|
|
56660
|
+
setActiveTarget: (target) => {
|
|
56661
|
+
this.setActiveTarget(target);
|
|
56662
|
+
},
|
|
56663
|
+
resetActiveTarget: () => {
|
|
56664
|
+
this.resetActiveTarget();
|
|
56665
|
+
},
|
|
56666
|
+
retryCatalog: () => {
|
|
56667
|
+
this.loadCatalogOnce();
|
|
56668
|
+
},
|
|
56669
|
+
save: () => {
|
|
56670
|
+
this.save();
|
|
56671
|
+
},
|
|
56672
|
+
discard: () => {
|
|
56673
|
+
this.discard();
|
|
56674
|
+
}
|
|
56675
|
+
};
|
|
56676
|
+
}
|
|
56677
|
+
/** 首屏:并行读偏好与目录。 */
|
|
56678
|
+
async hydrate() {
|
|
56679
|
+
this.preferencesStatus = "loading";
|
|
56680
|
+
this.publish();
|
|
56681
|
+
const [preferences] = await Promise.all([this.loadPreferences(), this.loadCatalogOnce()]);
|
|
56682
|
+
if (this.disposed) return;
|
|
56683
|
+
if (preferences === void 0) this.preferencesStatus = "error";
|
|
56684
|
+
else {
|
|
56685
|
+
this.preferences = preferences;
|
|
56686
|
+
this.preferencesStatus = "ready";
|
|
56687
|
+
}
|
|
56688
|
+
this.publish();
|
|
56689
|
+
}
|
|
56690
|
+
/** 拉一次目录(`refreshCatalog` 与「重试」共用)。 */
|
|
56691
|
+
async loadCatalogOnce() {
|
|
56692
|
+
if (this.disposed) return;
|
|
56693
|
+
this.catalogGeneration += 1;
|
|
56694
|
+
const generation = this.catalogGeneration;
|
|
56695
|
+
this.catalogStatus = "loading";
|
|
56696
|
+
this.catalogPartial = false;
|
|
56697
|
+
this.publish();
|
|
56698
|
+
const answer = await this.loadCatalog();
|
|
56699
|
+
if (this.disposed || generation !== this.catalogGeneration) return;
|
|
56700
|
+
if (answer.ok) {
|
|
56701
|
+
this.catalogGroups = normalizeCatalogGroups(answer.groups);
|
|
56702
|
+
this.catalogPartial = answer.partial === true;
|
|
56703
|
+
this.catalogStatus = "ready";
|
|
56704
|
+
} else {
|
|
56705
|
+
this.catalogGroups = [];
|
|
56706
|
+
this.catalogStatus = "error";
|
|
56707
|
+
}
|
|
56708
|
+
this.publish();
|
|
56709
|
+
}
|
|
56710
|
+
currentEnabled() {
|
|
56711
|
+
return this.modelSelection.getSnapshot().value?.enabled === true;
|
|
56712
|
+
}
|
|
56713
|
+
/**
|
|
56714
|
+
* 全局默认列表。
|
|
56715
|
+
*
|
|
56716
|
+
* 向后兼容种子:偏好文档里还没有这份列表(老版本、或从未保存过)时,把宿主
|
|
56717
|
+
* `allowedModels` 当作初始默认。
|
|
56718
|
+
*/
|
|
56719
|
+
currentDefault() {
|
|
56720
|
+
const stored = this.preferences?.subagentDefaultModels;
|
|
56721
|
+
if (Array.isArray(stored) && stored.length > 0) return cloneRoutes(stored);
|
|
56722
|
+
const allowed = this.modelSelection.getSnapshot().value?.allowedModels;
|
|
56723
|
+
if (Array.isArray(allowed) && allowed.length > 0) return cloneRoutes(allowed);
|
|
56724
|
+
return [];
|
|
56725
|
+
}
|
|
56726
|
+
/** 每个主代理模型的专属列表(丢弃空数组与非法项)。 */
|
|
56727
|
+
currentOverrides() {
|
|
56728
|
+
const raw = this.preferences?.subagentModelsByMainModel;
|
|
56729
|
+
const out = {};
|
|
56730
|
+
if (raw === void 0 || raw === null) return out;
|
|
56731
|
+
for (const [key, value] of Object.entries(raw)) {
|
|
56732
|
+
if (!Array.isArray(value)) continue;
|
|
56733
|
+
const cloned = cloneRoutes(value);
|
|
56734
|
+
if (cloned.length === 0) continue;
|
|
56735
|
+
out[key] = cloned;
|
|
56736
|
+
}
|
|
56737
|
+
return out;
|
|
56738
|
+
}
|
|
56739
|
+
enabled() {
|
|
56740
|
+
return this.draftEnabled ?? this.currentEnabled();
|
|
56741
|
+
}
|
|
56742
|
+
defaultRoutes() {
|
|
56743
|
+
return cloneRoutes(this.draftDefault ?? this.currentDefault());
|
|
56744
|
+
}
|
|
56745
|
+
overrides() {
|
|
56746
|
+
const source = this.draftOverrides ?? this.currentOverrides();
|
|
56747
|
+
const out = {};
|
|
56748
|
+
for (const [key, value] of Object.entries(source)) out[key] = cloneRoutes(value);
|
|
56749
|
+
return out;
|
|
56750
|
+
}
|
|
56751
|
+
/** 当前目标生效的列表(专属列表优先,否则回落到全局默认)。 */
|
|
56752
|
+
activeRoutes() {
|
|
56753
|
+
if (this.activeTarget === "default") return this.defaultRoutes();
|
|
56754
|
+
const own = this.overrides()[this.activeTarget];
|
|
56755
|
+
return own === void 0 ? this.defaultRoutes() : cloneRoutes(own);
|
|
56756
|
+
}
|
|
56757
|
+
ensureDraft() {
|
|
56758
|
+
if (this.draftDefault !== void 0) return;
|
|
56759
|
+
this.draftEnabled = this.currentEnabled();
|
|
56760
|
+
this.draftDefault = this.currentDefault();
|
|
56761
|
+
this.draftOverrides = this.currentOverrides();
|
|
56762
|
+
this.draftRevision = this.modelSelection.getSnapshot().revision;
|
|
56763
|
+
}
|
|
56764
|
+
clearDraft() {
|
|
56765
|
+
this.draftDepth = void 0;
|
|
56766
|
+
this.draftDepthCleared = false;
|
|
56767
|
+
this.draftActive = void 0;
|
|
56768
|
+
this.draftActiveCleared = false;
|
|
56769
|
+
this.draftEnabled = void 0;
|
|
56770
|
+
this.draftDefault = void 0;
|
|
56771
|
+
this.draftOverrides = void 0;
|
|
56772
|
+
this.draftRevision = void 0;
|
|
56773
|
+
this.failed = false;
|
|
56774
|
+
}
|
|
56775
|
+
editLimit(field, text) {
|
|
56776
|
+
if (this.saving) return;
|
|
56777
|
+
if (field === "maxDepth") {
|
|
56778
|
+
this.draftDepth = text;
|
|
56779
|
+
this.draftDepthCleared = text.trim() === "";
|
|
56780
|
+
} else {
|
|
56781
|
+
this.draftActive = text;
|
|
56782
|
+
this.draftActiveCleared = text.trim() === "";
|
|
56783
|
+
}
|
|
56784
|
+
this.failed = false;
|
|
56785
|
+
this.publish();
|
|
56786
|
+
}
|
|
56787
|
+
resetLimit(field) {
|
|
56788
|
+
if (this.saving) return;
|
|
56789
|
+
const base = this.limits.getSnapshot().base;
|
|
56790
|
+
const fallback = field === "maxDepth" ? readNumber(base, "maxDepth", 1) : readNumber(base, "maxActiveSubagents", 8);
|
|
56791
|
+
if (field === "maxDepth") {
|
|
56792
|
+
this.draftDepth = String(fallback);
|
|
56793
|
+
this.draftDepthCleared = true;
|
|
56794
|
+
} else {
|
|
56795
|
+
this.draftActive = String(fallback);
|
|
56796
|
+
this.draftActiveCleared = true;
|
|
56797
|
+
}
|
|
56798
|
+
this.failed = false;
|
|
56799
|
+
this.publish();
|
|
56800
|
+
}
|
|
56801
|
+
toggleEnabled() {
|
|
56802
|
+
const snapshot = this.modelSelection.getSnapshot();
|
|
56803
|
+
if (this.saving || snapshot.status !== "ready" || !snapshot.writable) return;
|
|
56804
|
+
this.ensureDraft();
|
|
56805
|
+
this.draftEnabled = !this.enabled();
|
|
56806
|
+
this.failed = false;
|
|
56807
|
+
if (this.draftEnabled && this.catalogStatus === "idle") this.loadCatalogOnce();
|
|
56808
|
+
this.publish();
|
|
56809
|
+
}
|
|
56810
|
+
/**
|
|
56811
|
+
* 切换一条路由在当前目标下的勾选态。
|
|
56812
|
+
*/
|
|
56813
|
+
toggleModel(key) {
|
|
56814
|
+
if (this.saving || !this.enabled()) return;
|
|
56815
|
+
if (this.modelSelection.getSnapshot().status !== "ready") return;
|
|
56816
|
+
const route = this.candidates().find((candidate) => candidate.key === key);
|
|
56817
|
+
if (route === void 0) return;
|
|
56818
|
+
if (!route.provider || !route.model || route.provider === "undefined" || route.model === "undefined") return;
|
|
56819
|
+
this.ensureDraft();
|
|
56820
|
+
const overrides = this.draftOverrides ?? this.currentOverrides();
|
|
56821
|
+
if (this.activeTarget === "default") {
|
|
56822
|
+
const next = new Map((this.draftDefault ?? this.currentDefault()).map((item) => [routeKey(item), item]));
|
|
56823
|
+
if (next.has(key)) next.delete(key);
|
|
56824
|
+
else next.set(key, {
|
|
56825
|
+
provider: route.provider,
|
|
56826
|
+
model: route.model
|
|
56827
|
+
});
|
|
56828
|
+
this.draftDefault = [...next.values()];
|
|
56829
|
+
} else {
|
|
56830
|
+
const base = overrides[this.activeTarget] ?? this.defaultRoutes();
|
|
56831
|
+
const next = new Map(base.map((item) => [routeKey(item), item]));
|
|
56832
|
+
if (next.has(key)) next.delete(key);
|
|
56833
|
+
else next.set(key, {
|
|
56834
|
+
provider: route.provider,
|
|
56835
|
+
model: route.model
|
|
56836
|
+
});
|
|
56837
|
+
overrides[this.activeTarget] = [...next.values()];
|
|
56838
|
+
this.draftOverrides = overrides;
|
|
56839
|
+
}
|
|
56840
|
+
this.failed = false;
|
|
56841
|
+
this.publish();
|
|
56842
|
+
}
|
|
56843
|
+
setActiveTarget(target) {
|
|
56844
|
+
if (this.saving) return;
|
|
56845
|
+
this.activeTarget = target === "" ? GLOBAL_TARGET : target;
|
|
56846
|
+
this.publish();
|
|
56847
|
+
}
|
|
56848
|
+
/** 让当前目标恢复「跟随全局默认」:删掉它的专属列表。 */
|
|
56849
|
+
resetActiveTarget() {
|
|
56850
|
+
if (this.saving || this.activeTarget === "default") return;
|
|
56851
|
+
this.ensureDraft();
|
|
56852
|
+
const overrides = this.draftOverrides ?? this.currentOverrides();
|
|
56853
|
+
delete overrides[this.activeTarget];
|
|
56854
|
+
this.draftOverrides = overrides;
|
|
56855
|
+
this.failed = false;
|
|
56856
|
+
this.publish();
|
|
56857
|
+
}
|
|
56858
|
+
discard() {
|
|
56859
|
+
if (this.saving) return;
|
|
56860
|
+
this.clearDraft();
|
|
56861
|
+
this.publish();
|
|
56862
|
+
}
|
|
56863
|
+
/** 当前目标的候选行:目录 ∪ 已保存 ∪ 草稿里出现的每一条。 */
|
|
56864
|
+
candidates() {
|
|
56865
|
+
const selected = new Set(this.activeRoutes().map(routeKey));
|
|
56866
|
+
const retained = /* @__PURE__ */ new Map();
|
|
56867
|
+
for (const route of this.activeRoutes()) retained.set(routeKey(route), route);
|
|
56868
|
+
for (const route of this.currentDefault()) retained.set(routeKey(route), route);
|
|
56869
|
+
for (const list of Object.values(this.overrides())) for (const route of list) retained.set(routeKey(route), route);
|
|
56870
|
+
const rows = [];
|
|
56871
|
+
for (const group of this.catalogGroups) {
|
|
56872
|
+
if (!group.provider || group.provider === "undefined") continue;
|
|
56873
|
+
for (const model of group.models) {
|
|
56874
|
+
if (!model.id || model.id === "undefined") continue;
|
|
56875
|
+
const key = `${group.provider}/${model.id}`;
|
|
56876
|
+
retained.delete(key);
|
|
56877
|
+
rows.push({
|
|
56878
|
+
provider: group.provider,
|
|
56879
|
+
model: model.id,
|
|
56880
|
+
key,
|
|
56881
|
+
providerName: group.providerName,
|
|
56882
|
+
modelName: model.name,
|
|
56883
|
+
available: true,
|
|
56884
|
+
selected: selected.has(key)
|
|
56885
|
+
});
|
|
56886
|
+
}
|
|
56887
|
+
}
|
|
56888
|
+
for (const [key, route] of retained) {
|
|
56889
|
+
if (!route.provider || !route.model || route.provider === "undefined" || route.model === "undefined") continue;
|
|
56890
|
+
rows.push({
|
|
56891
|
+
provider: route.provider,
|
|
56892
|
+
model: route.model,
|
|
56893
|
+
key,
|
|
56894
|
+
providerName: route.provider,
|
|
56895
|
+
modelName: route.model,
|
|
56896
|
+
available: false,
|
|
56897
|
+
selected: selected.has(key)
|
|
56898
|
+
});
|
|
56899
|
+
}
|
|
56900
|
+
return rows;
|
|
56901
|
+
}
|
|
56902
|
+
/** 主代理模型下拉的分组(目录分组 + 已保存但不可用的孤儿)。 */
|
|
56903
|
+
mainModelGroups() {
|
|
56904
|
+
const overrides = this.overrides();
|
|
56905
|
+
const groups = [];
|
|
56906
|
+
for (const group of this.catalogGroups) {
|
|
56907
|
+
if (!group.provider || group.provider === "undefined") continue;
|
|
56908
|
+
const models = group.models.filter((model) => Boolean(model.id) && model.id !== "undefined").map((model) => {
|
|
56909
|
+
const key = `${group.provider}/${model.id}`;
|
|
56910
|
+
return {
|
|
56911
|
+
key,
|
|
56912
|
+
model: model.id,
|
|
56913
|
+
modelName: model.name,
|
|
56914
|
+
overridden: overrides[key] !== void 0
|
|
56915
|
+
};
|
|
56916
|
+
});
|
|
56917
|
+
if (models.length > 0) groups.push({
|
|
56918
|
+
provider: group.provider,
|
|
56919
|
+
providerName: group.providerName,
|
|
56920
|
+
models
|
|
56921
|
+
});
|
|
56922
|
+
}
|
|
56923
|
+
return groups;
|
|
56924
|
+
}
|
|
56925
|
+
/** 已保存但目录不公布的主代理模型键(下拉里单列一组)。 */
|
|
56926
|
+
orphanMainModels() {
|
|
56927
|
+
const known = /* @__PURE__ */ new Set();
|
|
56928
|
+
for (const group of this.catalogGroups) for (const model of group.models) known.add(`${group.provider}/${model.id}`);
|
|
56929
|
+
return Object.keys(this.overrides()).filter((key) => !known.has(key));
|
|
56930
|
+
}
|
|
56931
|
+
/**
|
|
56932
|
+
* 一次保存三份存储。
|
|
56933
|
+
*/
|
|
56934
|
+
async save() {
|
|
56935
|
+
const state = this.store.getSnapshot();
|
|
56936
|
+
if (this.disposed || this.saving || !state.available || !state.writable || !state.dirty || state.invalid) return;
|
|
56937
|
+
const desiredEnabled = this.enabled();
|
|
56938
|
+
const desiredDefault = this.defaultRoutes();
|
|
56939
|
+
const desiredOverrides = this.overrides();
|
|
56940
|
+
const generation = this.saveGeneration;
|
|
56941
|
+
this.saving = true;
|
|
56942
|
+
this.failed = false;
|
|
56943
|
+
this.publish();
|
|
56944
|
+
try {
|
|
56945
|
+
const initial = this.currentOverrides();
|
|
56946
|
+
const patch = {};
|
|
56947
|
+
for (const key of /* @__PURE__ */ new Set([...Object.keys(initial), ...Object.keys(desiredOverrides)])) {
|
|
56948
|
+
const list = desiredOverrides[key];
|
|
56949
|
+
patch[key] = list !== void 0 && list.length > 0 ? cloneRoutes(list) : null;
|
|
56950
|
+
}
|
|
56951
|
+
await this.savePreferences({
|
|
56952
|
+
subagentDefaultModels: cloneRoutes(desiredDefault),
|
|
56953
|
+
subagentModelsByMainModel: patch
|
|
56954
|
+
});
|
|
56955
|
+
if (this.disposed || generation !== this.saveGeneration) return;
|
|
56956
|
+
const nextOverrides = {};
|
|
56957
|
+
for (const [k, v] of Object.entries(desiredOverrides)) if (v.length > 0) nextOverrides[k] = cloneRoutes(v);
|
|
56958
|
+
this.preferences = {
|
|
56959
|
+
subagentDefaultModels: cloneRoutes(desiredDefault),
|
|
56960
|
+
subagentModelsByMainModel: nextOverrides
|
|
56961
|
+
};
|
|
56962
|
+
this.preferencesStatus = "ready";
|
|
56963
|
+
const union = /* @__PURE__ */ new Map();
|
|
56964
|
+
for (const route of desiredDefault) union.set(routeKey(route), {
|
|
56965
|
+
provider: route.provider,
|
|
56966
|
+
model: route.model
|
|
56967
|
+
});
|
|
56968
|
+
for (const list of Object.values(desiredOverrides)) for (const route of list) union.set(routeKey(route), {
|
|
56969
|
+
provider: route.provider,
|
|
56970
|
+
model: route.model
|
|
56971
|
+
});
|
|
56972
|
+
const unionRoutes = [...union.values()];
|
|
56973
|
+
const scope = this.modelSelection;
|
|
56974
|
+
const modelSnapshot = scope.getSnapshot();
|
|
56975
|
+
if ((this.currentEnabled() !== desiredEnabled || !sameRouteSet(modelSnapshot.value?.allowedModels ?? [], unionRoutes)) && modelSnapshot.status === "ready") {
|
|
56976
|
+
const ops = [{
|
|
56977
|
+
op: "set",
|
|
56978
|
+
path: ["enabled"],
|
|
56979
|
+
value: desiredEnabled
|
|
56980
|
+
}, {
|
|
56981
|
+
op: "set",
|
|
56982
|
+
path: ["allowedModels"],
|
|
56983
|
+
value: unionRoutes
|
|
56984
|
+
}];
|
|
56985
|
+
if (typeof scope.mutate === "function") {
|
|
56986
|
+
if (await scope.mutate(ops, modelSnapshot.revision ?? this.draftRevision) === false) throw new Error("The deployment rejected the subagent model selection settings.");
|
|
56987
|
+
} else if (typeof scope.set === "function") {
|
|
56988
|
+
const ok1 = await scope.set("enabled", desiredEnabled);
|
|
56989
|
+
const ok2 = await scope.set("allowedModels", unionRoutes);
|
|
56990
|
+
if (ok1 === false || ok2 === false) throw new Error("The deployment rejected the subagent model selection settings.");
|
|
56991
|
+
}
|
|
56992
|
+
}
|
|
56993
|
+
if (state.maxDepth.invalid || state.maxActiveSubagents.invalid) throw new Error("invalid limits");
|
|
56994
|
+
const limitsSnapshot = this.limits.getSnapshot();
|
|
56995
|
+
const limitsOps = [];
|
|
56996
|
+
if (this.draftDepthCleared) {
|
|
56997
|
+
if (userHas(limitsSnapshot.user, "maxDepth")) limitsOps.push({
|
|
56998
|
+
op: "unset",
|
|
56999
|
+
path: ["maxDepth"]
|
|
57000
|
+
});
|
|
57001
|
+
} else if (this.draftDepth !== void 0) {
|
|
57002
|
+
const nextDepth = parseLimit(this.draftDepth, 0);
|
|
57003
|
+
if (nextDepth !== void 0 && nextDepth !== readNumber(limitsSnapshot.value, "maxDepth", nextDepth)) limitsOps.push({
|
|
57004
|
+
op: "set",
|
|
57005
|
+
path: ["maxDepth"],
|
|
57006
|
+
value: nextDepth
|
|
57007
|
+
});
|
|
57008
|
+
}
|
|
57009
|
+
if (this.draftActiveCleared) {
|
|
57010
|
+
if (userHas(limitsSnapshot.user, "maxActiveSubagents")) limitsOps.push({
|
|
57011
|
+
op: "unset",
|
|
57012
|
+
path: ["maxActiveSubagents"]
|
|
57013
|
+
});
|
|
57014
|
+
} else if (this.draftActive !== void 0) {
|
|
57015
|
+
const nextActive = parseLimit(this.draftActive, 1);
|
|
57016
|
+
if (nextActive !== void 0 && nextActive !== readNumber(limitsSnapshot.value, "maxActiveSubagents", nextActive)) limitsOps.push({
|
|
57017
|
+
op: "set",
|
|
57018
|
+
path: ["maxActiveSubagents"],
|
|
57019
|
+
value: nextActive
|
|
57020
|
+
});
|
|
57021
|
+
}
|
|
57022
|
+
if (limitsOps.length > 0 && limitsSnapshot.status === "ready") {
|
|
57023
|
+
if (typeof this.limits.mutate === "function") {
|
|
57024
|
+
if (await this.limits.mutate(limitsOps, limitsSnapshot.revision) === false) throw new Error("The deployment rejected the subagent limits.");
|
|
57025
|
+
} else if (typeof this.limits.set === "function") {
|
|
57026
|
+
for (const op of limitsOps) if (op.op === "set") await this.limits.set(op.path[0], op.value);
|
|
57027
|
+
}
|
|
57028
|
+
}
|
|
57029
|
+
if (this.disposed || generation !== this.saveGeneration) return;
|
|
57030
|
+
this.saving = false;
|
|
57031
|
+
this.clearDraft();
|
|
57032
|
+
this.publish();
|
|
57033
|
+
} catch {
|
|
57034
|
+
if (this.disposed || generation !== this.saveGeneration) return;
|
|
57035
|
+
this.saving = false;
|
|
57036
|
+
this.failed = true;
|
|
57037
|
+
this.publish();
|
|
57038
|
+
}
|
|
57039
|
+
}
|
|
57040
|
+
limitField(field, minimum, fallback) {
|
|
57041
|
+
const snapshot = this.limits.getSnapshot();
|
|
57042
|
+
const base = readNumber(snapshot.base, field, readNumber(snapshot.value, field, fallback));
|
|
57043
|
+
const current = readNumber(snapshot.value, field, fallback);
|
|
57044
|
+
const draft = field === "maxDepth" ? this.draftDepth : this.draftActive;
|
|
57045
|
+
const cleared = field === "maxDepth" ? this.draftDepthCleared : this.draftActiveCleared;
|
|
57046
|
+
const text = cleared ? String(base) : draft ?? String(current);
|
|
57047
|
+
const persistedOverridden = userHas(snapshot.user, field) || base !== current;
|
|
57048
|
+
const overridden = cleared ? false : draft !== void 0 ? text.trim() !== "" && text.trim() !== String(base) : persistedOverridden;
|
|
57049
|
+
const invalid = cleared ? false : parseLimit(text, minimum) === void 0;
|
|
57050
|
+
return {
|
|
57051
|
+
value: text,
|
|
57052
|
+
base: String(base),
|
|
57053
|
+
overridden,
|
|
57054
|
+
invalid
|
|
57055
|
+
};
|
|
57056
|
+
}
|
|
57057
|
+
projection() {
|
|
57058
|
+
const limitsSnapshot = this.limits.getSnapshot();
|
|
57059
|
+
const modelSnapshot = this.modelSelection.getSnapshot();
|
|
57060
|
+
const limitsAvailable = limitsSnapshot.status === "ready";
|
|
57061
|
+
const modelsAvailable = modelSnapshot.status === "ready";
|
|
57062
|
+
const maxDepth = this.limitField("maxDepth", 0, 1);
|
|
57063
|
+
const maxActive = this.limitField("maxActiveSubagents", 1, 8);
|
|
57064
|
+
const enabled = this.enabled();
|
|
57065
|
+
const desiredDefault = this.defaultRoutes();
|
|
57066
|
+
const desiredOverrides = this.overrides();
|
|
57067
|
+
const currentOverrides = this.currentOverrides();
|
|
57068
|
+
const currentDefault = this.currentDefault();
|
|
57069
|
+
const union = /* @__PURE__ */ new Map();
|
|
57070
|
+
for (const route of desiredDefault) union.set(routeKey(route), route);
|
|
57071
|
+
for (const list of Object.values(desiredOverrides)) for (const route of list) union.set(routeKey(route), route);
|
|
57072
|
+
const hostAllowed = cloneRoutes(modelSnapshot.value?.allowedModels ?? []);
|
|
57073
|
+
const modelsDirty = this.currentEnabled() !== enabled || !sameRouteSet(currentDefault, desiredDefault) || !sameOverrides(currentOverrides, desiredOverrides) || this.draftDefault !== void 0 && !sameRouteSet(hostAllowed, [...union.values()]);
|
|
57074
|
+
const depthPersistedOverridden = userHas(limitsSnapshot.user, "maxDepth");
|
|
57075
|
+
const activePersistedOverridden = userHas(limitsSnapshot.user, "maxActiveSubagents");
|
|
57076
|
+
const depthDirty = this.draftDepthCleared ? depthPersistedOverridden : this.draftDepth !== void 0 && maxDepth.value !== String(readNumber(limitsSnapshot.value, "maxDepth", 1));
|
|
57077
|
+
const activeDirty = this.draftActiveCleared ? activePersistedOverridden : this.draftActive !== void 0 && maxActive.value !== String(readNumber(limitsSnapshot.value, "maxActiveSubagents", 8));
|
|
57078
|
+
const limitsDirty = depthDirty || activeDirty;
|
|
57079
|
+
const emptyOverride = Object.values(desiredOverrides).some((list) => list.length === 0);
|
|
57080
|
+
const invalid = maxDepth.invalid || maxActive.invalid || enabled && (desiredDefault.length === 0 || emptyOverride);
|
|
57081
|
+
const activeOverridden = this.activeTarget !== "default" && desiredOverrides[this.activeTarget] !== void 0;
|
|
57082
|
+
return {
|
|
57083
|
+
available: limitsAvailable || modelsAvailable,
|
|
57084
|
+
writable: (limitsAvailable ? limitsSnapshot.writable : true) && (modelsAvailable ? modelSnapshot.writable : true),
|
|
57085
|
+
dirty: limitsDirty || modelsDirty,
|
|
57086
|
+
invalid,
|
|
57087
|
+
saving: this.saving,
|
|
57088
|
+
failed: this.failed,
|
|
57089
|
+
maxDepth,
|
|
57090
|
+
maxActiveSubagents: maxActive,
|
|
57091
|
+
enabled,
|
|
57092
|
+
activeTarget: this.activeTarget,
|
|
57093
|
+
defaultCount: desiredDefault.length,
|
|
57094
|
+
overridesByMainModel: desiredOverrides,
|
|
57095
|
+
mainModelGroups: this.mainModelGroups(),
|
|
57096
|
+
orphanMainModels: this.orphanMainModels(),
|
|
57097
|
+
catalogStatus: this.catalogStatus,
|
|
57098
|
+
catalogPartial: this.catalogPartial,
|
|
57099
|
+
candidates: this.candidates(),
|
|
57100
|
+
activeTargetOverridden: activeOverridden,
|
|
57101
|
+
activeTargetCount: this.activeRoutes().length,
|
|
57102
|
+
preferencesStatus: this.preferencesStatus
|
|
57103
|
+
};
|
|
57104
|
+
}
|
|
57105
|
+
publish() {
|
|
57106
|
+
if (this.disposed) return;
|
|
57107
|
+
this.store.setState(this.projection());
|
|
57108
|
+
}
|
|
57109
|
+
};
|
|
57110
|
+
//#endregion
|
|
57111
|
+
//#region src/client/subagent/SubagentCard.tsx
|
|
57112
|
+
/**
|
|
57113
|
+
* 「子智能体」设置卡片:运行限制 + 模型选择(全局默认 + 按主代理模型覆盖)。
|
|
57114
|
+
*
|
|
57115
|
+
* 1:1 还原 DSH 官方 `@deepseek-ai/dsh-client-ui-settings-subagent` 的 DOM 层次与样式:
|
|
57116
|
+
* - 运行限制:双列响应式网格,标题旁带 `?` 帮助按钮(展开显示深度说明表格),全宽数字输入框;
|
|
57117
|
+
* - 模型选择:官方胶囊开关、主代理模型切换栏、以及带滚动条(max-height: 280px)和提供方分隔线的子智能体模型勾选框;
|
|
57118
|
+
* - 保存栏:左对齐保存按钮,卸载页面时自动丢弃未保存草稿。
|
|
57119
|
+
*
|
|
57120
|
+
* @module @eddyskywalker/dsh-chatgpt-subscription/client/subagent/SubagentCard
|
|
57121
|
+
*/
|
|
57122
|
+
/** 把 {count} 占位符换成一个数。 */
|
|
57123
|
+
function withCount(template, count) {
|
|
57124
|
+
return template.replace("{count}", String(count));
|
|
57125
|
+
}
|
|
57126
|
+
/** 与官方 IconInfoOutlineRegular 一致的 12px 信息圆圈图标。 */
|
|
57127
|
+
function InfoIcon() {
|
|
57128
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
|
|
57129
|
+
width: "12",
|
|
57130
|
+
height: "12",
|
|
57131
|
+
viewBox: "0 0 16 16",
|
|
57132
|
+
fill: "none",
|
|
57133
|
+
"aria-hidden": "true",
|
|
57134
|
+
children: [
|
|
57135
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("circle", {
|
|
57136
|
+
cx: "8",
|
|
57137
|
+
cy: "8",
|
|
57138
|
+
r: "6.25",
|
|
57139
|
+
stroke: "currentColor",
|
|
57140
|
+
strokeWidth: "1.3"
|
|
57141
|
+
}),
|
|
57142
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
57143
|
+
d: "M8 7.2V11",
|
|
57144
|
+
stroke: "currentColor",
|
|
57145
|
+
strokeWidth: "1.3",
|
|
57146
|
+
strokeLinecap: "round"
|
|
57147
|
+
}),
|
|
57148
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("circle", {
|
|
57149
|
+
cx: "8",
|
|
57150
|
+
cy: "4.9",
|
|
57151
|
+
r: "0.75",
|
|
57152
|
+
fill: "currentColor"
|
|
57153
|
+
})
|
|
57154
|
+
]
|
|
57155
|
+
});
|
|
57156
|
+
}
|
|
57157
|
+
/** 一行模型勾选项(1:1 复刻官方 SubagentModelSelectionFields 的 renderCandidate)。 */
|
|
57158
|
+
function ModelRow(props) {
|
|
57159
|
+
const { candidate } = props;
|
|
57160
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
57161
|
+
className: "dsh-subagent-model",
|
|
57162
|
+
"data-dsh-part": "subagent-model",
|
|
57163
|
+
children: [
|
|
57164
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
57165
|
+
type: "checkbox",
|
|
57166
|
+
checked: candidate.selected,
|
|
57167
|
+
disabled: props.disabled,
|
|
57168
|
+
"aria-label": candidate.providerName + " " + candidate.modelName,
|
|
57169
|
+
onChange: () => {
|
|
57170
|
+
props.onToggle(candidate.key);
|
|
57171
|
+
}
|
|
57172
|
+
}),
|
|
57173
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
57174
|
+
className: "dsh-subagent-model-name",
|
|
57175
|
+
children: candidate.modelName
|
|
57176
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
57177
|
+
className: "dsh-subagent-model-route",
|
|
57178
|
+
children: candidate.providerName + " · " + candidate.provider + "/" + candidate.model
|
|
57179
|
+
})] }),
|
|
57180
|
+
candidate.available ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
57181
|
+
className: "dsh-subagent-model-unavailable",
|
|
57182
|
+
children: props.unavailableLabel
|
|
57183
|
+
})
|
|
57184
|
+
]
|
|
57185
|
+
});
|
|
57186
|
+
}
|
|
57187
|
+
/** 1:1 复刻官方 SettingsValueField:标签 + 帮助按钮 + 已覆盖徽标/恢复默认 + 全宽输入框。 */
|
|
57188
|
+
function LimitField(props) {
|
|
57189
|
+
const [helpOpen, setHelpOpen] = (0, react.useState)(false);
|
|
57190
|
+
const helpId = props.id + "-help";
|
|
57191
|
+
const messageId = props.id + "-message";
|
|
57192
|
+
const description = [props.invalid ? messageId : "", helpOpen ? helpId : ""].filter(Boolean).join(" ");
|
|
57193
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
57194
|
+
className: "dsh-subagent-field",
|
|
57195
|
+
"data-dsh-part": props.id,
|
|
57196
|
+
children: [
|
|
57197
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
57198
|
+
className: "dsh-subagent-field-head",
|
|
57199
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
57200
|
+
className: "dsh-subagent-label-group",
|
|
57201
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
57202
|
+
className: "dsh-subagent-label",
|
|
57203
|
+
htmlFor: props.id,
|
|
57204
|
+
children: props.label
|
|
57205
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
57206
|
+
type: "button",
|
|
57207
|
+
className: "dsh-subagent-help-btn",
|
|
57208
|
+
"aria-label": props.helpLabel,
|
|
57209
|
+
"aria-expanded": helpOpen,
|
|
57210
|
+
"aria-controls": helpId,
|
|
57211
|
+
onClick: () => {
|
|
57212
|
+
setHelpOpen(!helpOpen);
|
|
57213
|
+
},
|
|
57214
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(InfoIcon, {})
|
|
57215
|
+
})]
|
|
57216
|
+
}), props.overridden ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
57217
|
+
className: "dsh-subagent-badges",
|
|
57218
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
57219
|
+
className: "dsh-subagent-override-tag",
|
|
57220
|
+
children: props.overriddenLabel
|
|
57221
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
57222
|
+
type: "button",
|
|
57223
|
+
className: "dsh-subagent-reset-link",
|
|
57224
|
+
"data-dsh-part": props.id + "-reset",
|
|
57225
|
+
disabled: props.disabled,
|
|
57226
|
+
onClick: props.onReset,
|
|
57227
|
+
children: props.resetLabel
|
|
57228
|
+
})]
|
|
57229
|
+
}) : null]
|
|
57230
|
+
}),
|
|
57231
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
57232
|
+
id: props.id,
|
|
57233
|
+
type: "text",
|
|
57234
|
+
inputMode: "numeric",
|
|
57235
|
+
className: "dsh-subagent-input",
|
|
57236
|
+
"aria-label": props.label,
|
|
57237
|
+
"aria-describedby": description || void 0,
|
|
57238
|
+
...props.invalid ? { "aria-invalid": true } : {},
|
|
57239
|
+
value: props.value,
|
|
57240
|
+
disabled: props.disabled,
|
|
57241
|
+
onChange: (event) => {
|
|
57242
|
+
props.onEdit(event.target.value);
|
|
57243
|
+
}
|
|
57244
|
+
}),
|
|
57245
|
+
props.invalid ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
57246
|
+
id: messageId,
|
|
57247
|
+
className: "dsh-subagent-invalid",
|
|
57248
|
+
role: "alert",
|
|
57249
|
+
children: props.invalidLabel
|
|
57250
|
+
}) : null,
|
|
57251
|
+
helpOpen ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
57252
|
+
id: helpId,
|
|
57253
|
+
className: "dsh-subagent-help-box",
|
|
57254
|
+
role: "region",
|
|
57255
|
+
"aria-label": props.helpLabel,
|
|
57256
|
+
children: props.helpContent
|
|
57257
|
+
}) : null
|
|
57258
|
+
]
|
|
57259
|
+
});
|
|
57260
|
+
}
|
|
57261
|
+
/**
|
|
57262
|
+
* 渲染子智能体设置。
|
|
57263
|
+
* @param props - 框架座位、t,以及注入的快照与动作。
|
|
57264
|
+
* @returns summary 时是一句简介,page 时是整张表单。
|
|
57265
|
+
*/
|
|
57266
|
+
function SubagentCard(props) {
|
|
57267
|
+
const { t } = props;
|
|
57268
|
+
const state = (0, react.useSyncExternalStore)(props.store.subscribe, props.store.getSnapshot, props.store.getSnapshot);
|
|
57269
|
+
const headingId = (0, react.useId)();
|
|
57270
|
+
const discardRef = (0, react.useRef)(props.discard);
|
|
57271
|
+
discardRef.current = props.discard;
|
|
57272
|
+
(0, react.useEffect)(() => () => {
|
|
57273
|
+
if (props.view === "page") discardRef.current();
|
|
57274
|
+
}, [props.view]);
|
|
57275
|
+
if (props.view === "summary") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: t("subagentDescription") });
|
|
57276
|
+
if (!state.available) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
57277
|
+
className: "dsh-subagent-unavailable-notice",
|
|
57278
|
+
role: "status",
|
|
57279
|
+
children: t("unavailable")
|
|
57280
|
+
});
|
|
57281
|
+
const disabled = !state.writable || state.saving;
|
|
57282
|
+
const groups = /* @__PURE__ */ new Map();
|
|
57283
|
+
const unavailable = [];
|
|
57284
|
+
for (const candidate of state.candidates) {
|
|
57285
|
+
if (!candidate.available) {
|
|
57286
|
+
unavailable.push(candidate);
|
|
57287
|
+
continue;
|
|
57288
|
+
}
|
|
57289
|
+
const group = groups.get(candidate.provider);
|
|
57290
|
+
if (group === void 0) groups.set(candidate.provider, {
|
|
57291
|
+
providerName: candidate.providerName,
|
|
57292
|
+
rows: [candidate]
|
|
57293
|
+
});
|
|
57294
|
+
else group.rows.push(candidate);
|
|
57295
|
+
}
|
|
57296
|
+
/** 主代理模型的显示名:目录里有就用目录的,没有就用键本身。 */
|
|
57297
|
+
const mainModelName = (key) => {
|
|
57298
|
+
for (const group of state.mainModelGroups) for (const model of group.models) if (model.key === key) return model.modelName;
|
|
57299
|
+
return key;
|
|
57300
|
+
};
|
|
57301
|
+
const activeModelKey = state.activeTarget;
|
|
57302
|
+
const overrideKeys = Object.keys(state.overridesByMainModel);
|
|
57303
|
+
const limitsHeadingId = headingId + "-limits";
|
|
57304
|
+
const modelsHeadingId = headingId + "-models";
|
|
57305
|
+
const mainModelId = headingId + "-main-model";
|
|
57306
|
+
const blocked = !state.dirty || state.invalid || state.saving || !state.writable;
|
|
57307
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
57308
|
+
className: "dsh-subagent-form",
|
|
57309
|
+
"data-dsh-plugin": "subagent",
|
|
57310
|
+
"data-dsh-part": "subagent-form",
|
|
57311
|
+
children: [
|
|
57312
|
+
!state.writable ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
57313
|
+
className: "dsh-subagent-readonly-notice",
|
|
57314
|
+
role: "status",
|
|
57315
|
+
children: t("readOnly")
|
|
57316
|
+
}) : null,
|
|
57317
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
57318
|
+
className: "dsh-subagent-section",
|
|
57319
|
+
"aria-labelledby": limitsHeadingId,
|
|
57320
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
|
|
57321
|
+
className: "dsh-subagent-heading",
|
|
57322
|
+
id: limitsHeadingId,
|
|
57323
|
+
children: t("subagentLimitsTitle")
|
|
57324
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
57325
|
+
className: "dsh-subagent-limits-grid",
|
|
57326
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
57327
|
+
className: "dsh-subagent-limit-cell",
|
|
57328
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LimitField, {
|
|
57329
|
+
id: "plugin-config-subagent-depth",
|
|
57330
|
+
label: t("subagentMaxDepth"),
|
|
57331
|
+
helpLabel: t("subagentDepthHelpLabel"),
|
|
57332
|
+
helpContent: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
57333
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: t("subagentDepthHelp") }),
|
|
57334
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("table", {
|
|
57335
|
+
className: "dsh-subagent-depth-table",
|
|
57336
|
+
"aria-label": t("subagentDepthHelpLabel"),
|
|
57337
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tbody", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
|
|
57338
|
+
scope: "row",
|
|
57339
|
+
children: 0
|
|
57340
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", { children: t("subagentDepthZero") })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
|
|
57341
|
+
scope: "row",
|
|
57342
|
+
children: 1
|
|
57343
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", { children: t("subagentDepthOne") })] })] })
|
|
57344
|
+
}),
|
|
57345
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: t("subagentDepthOverride") })
|
|
57346
|
+
] }),
|
|
57347
|
+
value: state.maxDepth.value,
|
|
57348
|
+
overridden: state.maxDepth.overridden,
|
|
57349
|
+
overriddenLabel: t("overridden"),
|
|
57350
|
+
resetLabel: t("reset"),
|
|
57351
|
+
invalidLabel: t("subagentDepthInvalid"),
|
|
57352
|
+
invalid: state.maxDepth.invalid,
|
|
57353
|
+
disabled,
|
|
57354
|
+
onEdit: (text) => {
|
|
57355
|
+
props.editLimit("maxDepth", text);
|
|
57356
|
+
},
|
|
57357
|
+
onReset: () => {
|
|
57358
|
+
props.resetLimit("maxDepth");
|
|
57359
|
+
}
|
|
57360
|
+
})
|
|
57361
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
57362
|
+
className: "dsh-subagent-limit-cell",
|
|
57363
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LimitField, {
|
|
57364
|
+
id: "plugin-config-subagent-capacity",
|
|
57365
|
+
label: t("subagentMaxActive"),
|
|
57366
|
+
helpLabel: t("subagentCapacityHelpLabel"),
|
|
57367
|
+
helpContent: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: t("subagentCapacityHelp") }),
|
|
57368
|
+
value: state.maxActiveSubagents.value,
|
|
57369
|
+
overridden: state.maxActiveSubagents.overridden,
|
|
57370
|
+
overriddenLabel: t("overridden"),
|
|
57371
|
+
resetLabel: t("reset"),
|
|
57372
|
+
invalidLabel: t("subagentCapacityInvalid"),
|
|
57373
|
+
invalid: state.maxActiveSubagents.invalid,
|
|
57374
|
+
disabled,
|
|
57375
|
+
onEdit: (text) => {
|
|
57376
|
+
props.editLimit("maxActiveSubagents", text);
|
|
57377
|
+
},
|
|
57378
|
+
onReset: () => {
|
|
57379
|
+
props.resetLimit("maxActiveSubagents");
|
|
57380
|
+
}
|
|
57381
|
+
})
|
|
57382
|
+
})]
|
|
57383
|
+
})]
|
|
57384
|
+
}),
|
|
57385
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
57386
|
+
className: "dsh-subagent-section",
|
|
57387
|
+
"aria-labelledby": modelsHeadingId,
|
|
57388
|
+
children: [
|
|
57389
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
|
|
57390
|
+
className: "dsh-subagent-heading",
|
|
57391
|
+
id: modelsHeadingId,
|
|
57392
|
+
children: t("subagentModelSelectionTitle")
|
|
57393
|
+
}),
|
|
57394
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
57395
|
+
className: "dsh-subagent-permission",
|
|
57396
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
57397
|
+
className: "dsh-subagent-toggle-row",
|
|
57398
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
57399
|
+
className: "dsh-subagent-toggle-label",
|
|
57400
|
+
children: t("subagentModelSelectionToggle")
|
|
57401
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
57402
|
+
type: "button",
|
|
57403
|
+
role: "switch",
|
|
57404
|
+
"aria-checked": state.enabled,
|
|
57405
|
+
"aria-label": t("subagentModelSelectionToggle"),
|
|
57406
|
+
className: "dsh-subagent-switch",
|
|
57407
|
+
"data-dsh-part": "subagent-enabled-switch",
|
|
57408
|
+
disabled,
|
|
57409
|
+
onClick: () => {
|
|
57410
|
+
props.toggleEnabled();
|
|
57411
|
+
},
|
|
57412
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: "dsh-subagent-switch-thumb" })
|
|
57413
|
+
})]
|
|
57414
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
57415
|
+
className: "dsh-subagent-hint",
|
|
57416
|
+
children: t(state.enabled ? "subagentModelSelectionChoose" : "subagentModelSelectionOff")
|
|
57417
|
+
})]
|
|
57418
|
+
}),
|
|
57419
|
+
state.enabled ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
57420
|
+
className: "dsh-subagent-selection",
|
|
57421
|
+
"data-dsh-part": "subagent-target",
|
|
57422
|
+
children: [
|
|
57423
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
57424
|
+
className: "dsh-subagent-target-bar",
|
|
57425
|
+
children: [
|
|
57426
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
57427
|
+
className: "dsh-subagent-target-header",
|
|
57428
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
57429
|
+
className: "dsh-subagent-target-label",
|
|
57430
|
+
htmlFor: mainModelId,
|
|
57431
|
+
children: t("subagentMainModelLabel")
|
|
57432
|
+
}), activeModelKey !== "default" && state.activeTargetOverridden ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
57433
|
+
type: "button",
|
|
57434
|
+
className: "dsh-subagent-reset",
|
|
57435
|
+
"data-dsh-part": "subagent-reset-to-global",
|
|
57436
|
+
disabled,
|
|
57437
|
+
onClick: () => {
|
|
57438
|
+
props.resetActiveTarget();
|
|
57439
|
+
},
|
|
57440
|
+
children: t("subagentResetToGlobal")
|
|
57441
|
+
}) : null]
|
|
57442
|
+
}),
|
|
57443
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
57444
|
+
id: mainModelId,
|
|
57445
|
+
className: "dsh-subagent-select",
|
|
57446
|
+
"data-dsh-part": "subagent-main-model",
|
|
57447
|
+
"aria-label": t("subagentMainModelLabel"),
|
|
57448
|
+
value: activeModelKey,
|
|
57449
|
+
disabled,
|
|
57450
|
+
onChange: (event) => {
|
|
57451
|
+
props.setActiveTarget(event.target.value);
|
|
57452
|
+
},
|
|
57453
|
+
children: [
|
|
57454
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
57455
|
+
value: GLOBAL_TARGET,
|
|
57456
|
+
children: t("subagentMainModelGlobalOption")
|
|
57457
|
+
}),
|
|
57458
|
+
state.mainModelGroups.map((group) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("optgroup", {
|
|
57459
|
+
label: group.providerName,
|
|
57460
|
+
children: group.models.map((model) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
57461
|
+
value: model.key,
|
|
57462
|
+
children: model.modelName + " · " + model.key + (model.overridden ? t("subagentOverrideBadge") : "")
|
|
57463
|
+
}, model.key))
|
|
57464
|
+
}, group.provider)),
|
|
57465
|
+
state.orphanMainModels.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("optgroup", {
|
|
57466
|
+
label: t("subagentModelSelectionUnavailableGroup"),
|
|
57467
|
+
children: state.orphanMainModels.map((key) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
57468
|
+
value: key,
|
|
57469
|
+
children: mainModelName(key) + " · " + key + t("subagentOverrideBadge")
|
|
57470
|
+
}, key))
|
|
57471
|
+
}) : null
|
|
57472
|
+
]
|
|
57473
|
+
}),
|
|
57474
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
57475
|
+
className: "dsh-subagent-chips",
|
|
57476
|
+
"data-dsh-part": "subagent-chips",
|
|
57477
|
+
"aria-label": t("subagentMainModelQuickSwitch"),
|
|
57478
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
57479
|
+
type: "button",
|
|
57480
|
+
className: "dsh-subagent-chip",
|
|
57481
|
+
"data-dsh-part": "subagent-chip-global",
|
|
57482
|
+
"aria-pressed": activeModelKey === GLOBAL_TARGET,
|
|
57483
|
+
disabled,
|
|
57484
|
+
onClick: () => {
|
|
57485
|
+
props.setActiveTarget(GLOBAL_TARGET);
|
|
57486
|
+
},
|
|
57487
|
+
children: withCount(t("subagentChipGlobal"), state.defaultCount)
|
|
57488
|
+
}), overrideKeys.map((key) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
57489
|
+
type: "button",
|
|
57490
|
+
className: "dsh-subagent-chip",
|
|
57491
|
+
"data-dsh-part": "subagent-chip-override",
|
|
57492
|
+
"aria-pressed": activeModelKey === key,
|
|
57493
|
+
disabled,
|
|
57494
|
+
onClick: () => {
|
|
57495
|
+
props.setActiveTarget(key);
|
|
57496
|
+
},
|
|
57497
|
+
children: mainModelName(key) + " (" + String(state.overridesByMainModel[key]?.length ?? 0) + ")"
|
|
57498
|
+
}, key))]
|
|
57499
|
+
}),
|
|
57500
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
57501
|
+
className: "dsh-subagent-status",
|
|
57502
|
+
"data-dsh-part": "subagent-target-status",
|
|
57503
|
+
children: activeModelKey === "default" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
57504
|
+
className: "dsh-subagent-hint",
|
|
57505
|
+
children: t("subagentTargetGlobalHint")
|
|
57506
|
+
}) : state.activeTargetOverridden ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
57507
|
+
className: "dsh-subagent-hint",
|
|
57508
|
+
children: withCount(t("subagentTargetOverrideStatus"), state.activeTargetCount)
|
|
57509
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
57510
|
+
className: "dsh-subagent-hint",
|
|
57511
|
+
children: t("subagentTargetFollowGlobalStatus")
|
|
57512
|
+
})
|
|
57513
|
+
})
|
|
57514
|
+
]
|
|
57515
|
+
}),
|
|
57516
|
+
state.catalogStatus === "loading" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
57517
|
+
className: "dsh-subagent-notice",
|
|
57518
|
+
role: "status",
|
|
57519
|
+
children: t("subagentModelSelectionLoading")
|
|
57520
|
+
}) : null,
|
|
57521
|
+
state.catalogStatus === "error" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
57522
|
+
className: "dsh-subagent-catalog-error",
|
|
57523
|
+
role: "alert",
|
|
57524
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("subagentModelSelectionLoadFailed") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
57525
|
+
type: "button",
|
|
57526
|
+
"data-dsh-part": "subagent-retry-catalog",
|
|
57527
|
+
disabled: state.saving,
|
|
57528
|
+
onClick: () => {
|
|
57529
|
+
props.retryCatalog();
|
|
57530
|
+
},
|
|
57531
|
+
children: t("subagentModelSelectionRetry")
|
|
57532
|
+
})]
|
|
57533
|
+
}) : null,
|
|
57534
|
+
state.catalogPartial ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
57535
|
+
className: "dsh-subagent-notice",
|
|
57536
|
+
children: t("subagentModelSelectionPartial")
|
|
57537
|
+
}) : null,
|
|
57538
|
+
state.candidates.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("fieldset", {
|
|
57539
|
+
className: "dsh-subagent-models",
|
|
57540
|
+
children: [
|
|
57541
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("legend", { children: t("subagentModelSelectionAllowed") }),
|
|
57542
|
+
[...groups].map(([provider, group]) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
57543
|
+
className: "dsh-subagent-group",
|
|
57544
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
57545
|
+
className: "dsh-subagent-group-name",
|
|
57546
|
+
children: group.providerName
|
|
57547
|
+
}), group.rows.map((candidate) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ModelRow, {
|
|
57548
|
+
candidate,
|
|
57549
|
+
disabled,
|
|
57550
|
+
unavailableLabel: t("subagentModelSelectionUnavailable"),
|
|
57551
|
+
onToggle: (key) => {
|
|
57552
|
+
props.toggleModel(key);
|
|
57553
|
+
}
|
|
57554
|
+
}, candidate.key))]
|
|
57555
|
+
}, provider)),
|
|
57556
|
+
unavailable.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
57557
|
+
className: "dsh-subagent-group",
|
|
57558
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
57559
|
+
className: "dsh-subagent-group-name",
|
|
57560
|
+
children: t("subagentModelSelectionUnavailableGroup")
|
|
57561
|
+
}), unavailable.map((candidate) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ModelRow, {
|
|
57562
|
+
candidate,
|
|
57563
|
+
disabled,
|
|
57564
|
+
unavailableLabel: t("subagentModelSelectionUnavailable"),
|
|
57565
|
+
onToggle: (key) => {
|
|
57566
|
+
props.toggleModel(key);
|
|
57567
|
+
}
|
|
57568
|
+
}, candidate.key))]
|
|
57569
|
+
}) : null
|
|
57570
|
+
]
|
|
57571
|
+
}) : state.catalogStatus === "ready" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
57572
|
+
className: "dsh-subagent-notice",
|
|
57573
|
+
children: t("subagentModelSelectionEmpty")
|
|
57574
|
+
}) : null,
|
|
57575
|
+
state.invalid ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
57576
|
+
className: "dsh-subagent-invalid",
|
|
57577
|
+
role: "alert",
|
|
57578
|
+
children: t("subagentModelPerTargetRequired")
|
|
57579
|
+
}) : null
|
|
57580
|
+
]
|
|
57581
|
+
}) : null
|
|
57582
|
+
]
|
|
57583
|
+
}),
|
|
57584
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
57585
|
+
className: "dsh-subagent-footer",
|
|
57586
|
+
"data-dsh-part": "subagent-footer",
|
|
57587
|
+
children: [
|
|
57588
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
57589
|
+
type: "button",
|
|
57590
|
+
className: "dsh-subagent-save",
|
|
57591
|
+
"data-dsh-part": "subagent-save",
|
|
57592
|
+
disabled: blocked,
|
|
57593
|
+
onClick: () => {
|
|
57594
|
+
props.save();
|
|
57595
|
+
},
|
|
57596
|
+
children: state.saving ? t("saving") : t("save")
|
|
57597
|
+
}),
|
|
57598
|
+
state.dirty ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
57599
|
+
type: "button",
|
|
57600
|
+
className: "dsh-subagent-discard",
|
|
57601
|
+
"data-dsh-part": "subagent-discard",
|
|
57602
|
+
disabled: state.saving,
|
|
57603
|
+
onClick: () => {
|
|
57604
|
+
props.discard();
|
|
57605
|
+
},
|
|
57606
|
+
children: t("discard")
|
|
57607
|
+
}) : null,
|
|
57608
|
+
state.failed ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
57609
|
+
className: "dsh-subagent-failed",
|
|
57610
|
+
role: "alert",
|
|
57611
|
+
children: t("saveFailed")
|
|
57612
|
+
}) : null
|
|
57613
|
+
]
|
|
57614
|
+
})
|
|
57615
|
+
]
|
|
57616
|
+
});
|
|
57617
|
+
}
|
|
57618
|
+
//#endregion
|
|
57619
|
+
//#region src/client/subagent/locales.ts
|
|
57620
|
+
/**
|
|
57621
|
+
* 「子智能体」设置卡片的文案与命名空间。
|
|
57622
|
+
*
|
|
57623
|
+
* ## 为什么这里另起一个命名空间
|
|
57624
|
+
*
|
|
57625
|
+
* 宿主自带的子智能体设置页有自己的 `settings.subagent` 命名空间,而本卡是
|
|
57626
|
+
* **替换**它(同 id、更低 priority 遮蔽),不是与它并存。文案表因此归本插件所有:
|
|
57627
|
+
* 键名沿用本插件其余线路的扁平驼峰(`hubTitle`、`settingsEnabledName` 那一套),
|
|
57628
|
+
* 不引入宿主的点号风格。
|
|
57629
|
+
*
|
|
57630
|
+
* ## 键集是契约
|
|
57631
|
+
*
|
|
57632
|
+
* `SubagentLocaleKey` 由中文表反推,英文表用 `Record<SubagentLocaleKey, string>`
|
|
57633
|
+
* 钉死——少一条键编译期就报,而不是等到界面上渲染出键名本身。
|
|
57634
|
+
*/
|
|
57635
|
+
/** 本卡片在 locale 服务里的命名空间。 */
|
|
57636
|
+
const NS_SUBAGENT = "dsh-subagent-settings";
|
|
57637
|
+
/** 中文文案(键集的唯一定义处)。 */
|
|
57638
|
+
const zh = {
|
|
57639
|
+
overridden: "已覆盖",
|
|
57640
|
+
reset: "恢复默认",
|
|
57641
|
+
readOnly: "本部署的设置为只读。",
|
|
57642
|
+
unavailable: "该插件当前未加载,暂时无法配置。",
|
|
57643
|
+
save: "保存",
|
|
57644
|
+
saving: "保存中…",
|
|
57645
|
+
saveFailed: "本部署没有接受这些值,已保留供你修改。",
|
|
57646
|
+
discard: "放弃修改",
|
|
57647
|
+
subagentTitle: "子智能体",
|
|
57648
|
+
subagentDescription: "设置子智能体的递归层级、数量和模型。",
|
|
57649
|
+
subagentLimitsTitle: "运行限制",
|
|
57650
|
+
subagentMaxDepth: "最大递归深度",
|
|
57651
|
+
subagentDepthHelpLabel: "最大递归深度说明",
|
|
57652
|
+
subagentDepthHelp: "限制 Agent 创建子智能体的递归层级。",
|
|
57653
|
+
subagentDepthZero: "禁用子智能体",
|
|
57654
|
+
subagentDepthOne: "仅允许主 Agent 创建子智能体",
|
|
57655
|
+
subagentDepthOverride: "如果某个工具单独设置了最大递归深度,以该工具的设置为准。",
|
|
57656
|
+
subagentMaxActive: "子智能体并行数量上限",
|
|
57657
|
+
subagentCapacityHelpLabel: "子智能体并行数量上限说明",
|
|
57658
|
+
subagentCapacityHelp: "同一主 Agent 下,所有递归层级同时存活的子智能体总数,主 Agent 不计入。达到上限时,新的启动请求会被拒绝。",
|
|
57659
|
+
subagentDepthInvalid: "请输入不小于 0 的整数。",
|
|
57660
|
+
subagentCapacityInvalid: "请输入不小于 1 的整数。",
|
|
57661
|
+
subagentModelSelectionTitle: "模型选择",
|
|
57662
|
+
subagentModelSelectionToggle: "允许 Agent 为子智能体选择模型",
|
|
57663
|
+
subagentModelSelectionChoose: "开启后,Agent 可以从下方授权模型中,为每个子智能体选择提供方、模型和推理强度。仅影响新会话。",
|
|
57664
|
+
subagentModelSelectionAllowed: "Agent 可选择的模型",
|
|
57665
|
+
subagentModelSelectionLoading: "正在加载模型…",
|
|
57666
|
+
subagentModelSelectionLoadFailed: "无法加载模型。",
|
|
57667
|
+
subagentModelSelectionRetry: "重试",
|
|
57668
|
+
subagentModelSelectionPartial: "部分模型提供方暂时无法加载;已保存的选择仍可移除。",
|
|
57669
|
+
subagentModelSelectionUnavailable: "当前不可用",
|
|
57670
|
+
subagentModelSelectionUnavailableGroup: "已保存但当前不可用",
|
|
57671
|
+
subagentModelSelectionEmpty: "当前没有模型提供方公布模型。",
|
|
57672
|
+
subagentModelSelectionRequired: "保存前请至少选择一个模型。",
|
|
57673
|
+
subagentModelSelectionOff: "关闭后,子智能体使用配置的默认模型或继承父 Agent 的模型;已选模型会保留。",
|
|
57674
|
+
subagentMainModelLabel: "主代理模型配置栏",
|
|
57675
|
+
subagentMainModelGlobalOption: "全局默认(未单独配置的主代理使用)",
|
|
57676
|
+
subagentMainModelQuickSwitch: "快捷切换",
|
|
57677
|
+
subagentChipGlobal: "全局默认 ({count})",
|
|
57678
|
+
subagentTargetGlobalHint: "正在编辑全局默认子代理模型列表;未单独配置专属列表的主代理将使用此列表。",
|
|
57679
|
+
subagentTargetOverrideStatus: "已为该主代理单独配置 {count} 个子代理模型",
|
|
57680
|
+
subagentTargetFollowGlobalStatus: "当前跟随全局默认列表(勾选或取消下方模型即可为该主代理创建专属列表)",
|
|
57681
|
+
subagentResetToGlobal: "恢复跟随全局默认",
|
|
57682
|
+
subagentOverrideBadge: "(已覆盖)",
|
|
57683
|
+
subagentPreferencesLoadFailed: "无法读取已保存的子代理模型偏好;保存时将以当前界面为准。",
|
|
57684
|
+
subagentModelPerTargetRequired: "保存前请至少选择一个模型(或点击「恢复跟随全局默认」)。"
|
|
57685
|
+
};
|
|
57686
|
+
/** 英文对照,键集与中文完全一致。 */
|
|
57687
|
+
const en = {
|
|
57688
|
+
overridden: "Overridden",
|
|
57689
|
+
reset: "Reset to default",
|
|
57690
|
+
readOnly: "This deployment stores settings read-only.",
|
|
57691
|
+
unavailable: "This plugin is not loaded, so it cannot be configured right now.",
|
|
57692
|
+
save: "Save",
|
|
57693
|
+
saving: "Saving…",
|
|
57694
|
+
saveFailed: "The deployment did not accept these values; they were left for you to correct.",
|
|
57695
|
+
discard: "Discard changes",
|
|
57696
|
+
subagentTitle: "Subagent",
|
|
57697
|
+
subagentDescription: "Set Subagent recursion depth, count, and models.",
|
|
57698
|
+
subagentLimitsTitle: "Limits",
|
|
57699
|
+
subagentMaxDepth: "Maximum recursion depth",
|
|
57700
|
+
subagentDepthHelpLabel: "About maximum recursion depth",
|
|
57701
|
+
subagentDepthHelp: "Limits how many levels of Subagents an Agent can create.",
|
|
57702
|
+
subagentDepthZero: "Disable Subagents",
|
|
57703
|
+
subagentDepthOne: "Only the main Agent can create Subagents",
|
|
57704
|
+
subagentDepthOverride: "If a tool defines its own maximum recursion depth, that setting takes precedence.",
|
|
57705
|
+
subagentMaxActive: "Subagent parallelism limit",
|
|
57706
|
+
subagentCapacityHelpLabel: "About the Subagent parallelism limit",
|
|
57707
|
+
subagentCapacityHelp: "Total live Subagents under the same main Agent, across all recursion levels. The main Agent is excluded. New start requests are rejected when the limit is reached.",
|
|
57708
|
+
subagentDepthInvalid: "Enter a whole number of 0 or more.",
|
|
57709
|
+
subagentCapacityInvalid: "Enter a whole number of 1 or more.",
|
|
57710
|
+
subagentModelSelectionTitle: "Model selection",
|
|
57711
|
+
subagentModelSelectionToggle: "Allow agents to choose models for Subagents",
|
|
57712
|
+
subagentModelSelectionChoose: "When enabled, agents can choose a provider, model, and reasoning effort for each Subagent from the authorized models below. Applies only to new sessions.",
|
|
57713
|
+
subagentModelSelectionAllowed: "Models agents may choose",
|
|
57714
|
+
subagentModelSelectionLoading: "Loading models…",
|
|
57715
|
+
subagentModelSelectionLoadFailed: "Models could not be loaded.",
|
|
57716
|
+
subagentModelSelectionRetry: "Retry",
|
|
57717
|
+
subagentModelSelectionPartial: "Some model providers could not be loaded; saved choices remain removable.",
|
|
57718
|
+
subagentModelSelectionUnavailable: "Currently unavailable",
|
|
57719
|
+
subagentModelSelectionUnavailableGroup: "Saved but currently unavailable",
|
|
57720
|
+
subagentModelSelectionEmpty: "No model provider currently advertises a model.",
|
|
57721
|
+
subagentModelSelectionRequired: "Select at least one model before saving.",
|
|
57722
|
+
subagentModelSelectionOff: "Subagents use configured defaults or inherit the parent agent's model. Saved model choices are retained.",
|
|
57723
|
+
subagentMainModelLabel: "Main agent model",
|
|
57724
|
+
subagentMainModelGlobalOption: "Global default (used by main agents without their own list)",
|
|
57725
|
+
subagentMainModelQuickSwitch: "Quick switch",
|
|
57726
|
+
subagentChipGlobal: "Global default ({count})",
|
|
57727
|
+
subagentTargetGlobalHint: "Editing the global default subagent model list; main agents without their own list use it.",
|
|
57728
|
+
subagentTargetOverrideStatus: "This main agent has {count} dedicated subagent models",
|
|
57729
|
+
subagentTargetFollowGlobalStatus: "Currently following the global default list (tick or untick a model below to create a dedicated list for this main agent)",
|
|
57730
|
+
subagentResetToGlobal: "Follow the global default again",
|
|
57731
|
+
subagentOverrideBadge: " (overridden)",
|
|
57732
|
+
subagentPreferencesLoadFailed: "Saved subagent model preferences could not be read; saving will use what this page shows.",
|
|
57733
|
+
subagentModelPerTargetRequired: "Select at least one model before saving (or choose \"Follow the global default again\")."
|
|
57734
|
+
};
|
|
57735
|
+
/** 与其余线路同形的字典包(四个内置语言 id 都指向那两份)。 */
|
|
57736
|
+
const dictionaries = {
|
|
57737
|
+
zh,
|
|
57738
|
+
"zh-CN": zh,
|
|
57739
|
+
en,
|
|
57740
|
+
"en-US": en
|
|
57741
|
+
};
|
|
57742
|
+
//#endregion
|
|
57743
|
+
//#region src/client/subagent/index.ts
|
|
57744
|
+
/** 本卡在插件页里的槽位 id;与宿主同名,这是遮蔽的前提。 */
|
|
57745
|
+
const SUBAGENT_SLOT_ID = "subagent";
|
|
57746
|
+
function serviceOf(ctx, name) {
|
|
57747
|
+
try {
|
|
57748
|
+
return ctx.get?.(name);
|
|
57749
|
+
} catch {
|
|
57750
|
+
return;
|
|
57751
|
+
}
|
|
57752
|
+
}
|
|
57753
|
+
function isConfigForms(value) {
|
|
57754
|
+
if (typeof value !== "object" || value === null) return false;
|
|
57755
|
+
return typeof value.get === "function";
|
|
57756
|
+
}
|
|
57757
|
+
/**
|
|
57758
|
+
* 为 `ctx.slots.entries('plugins.item')` 安装按 `id` 的 cell 去重视图,
|
|
57759
|
+
* 避免 `configLedgerSource` 读原始账本时把被遮蔽的同 id 卡片也列出来。
|
|
57760
|
+
*/
|
|
57761
|
+
function installPluginsItemLedgerDedup(slots) {
|
|
57762
|
+
if (typeof slots !== "object" || slots === null) return () => {};
|
|
57763
|
+
const target = slots;
|
|
57764
|
+
if (typeof target.entries !== "function") return () => {};
|
|
57765
|
+
const originalEntries = target.entries;
|
|
57766
|
+
let holder = target;
|
|
57767
|
+
let descriptor = Object.getOwnPropertyDescriptor(holder, "entries");
|
|
57768
|
+
while (descriptor === void 0) {
|
|
57769
|
+
const proto = Object.getPrototypeOf(holder);
|
|
57770
|
+
if (proto === null) break;
|
|
57771
|
+
holder = proto;
|
|
57772
|
+
descriptor = Object.getOwnPropertyDescriptor(holder, "entries");
|
|
57773
|
+
}
|
|
57774
|
+
if (descriptor !== void 0 && !descriptor.configurable && !descriptor.writable) return () => {};
|
|
57775
|
+
let cachedRaw;
|
|
57776
|
+
let cachedDeduped = [];
|
|
57777
|
+
const wrapped = function(key) {
|
|
57778
|
+
const raw = originalEntries.call(this ?? slots, key);
|
|
57779
|
+
if (key !== "plugins.item" || !Array.isArray(raw) || raw.length <= 1) return raw;
|
|
57780
|
+
if (raw === cachedRaw) return cachedDeduped;
|
|
57781
|
+
const seenIds = /* @__PURE__ */ new Set();
|
|
57782
|
+
const deduped = [];
|
|
57783
|
+
for (const entry of raw) {
|
|
57784
|
+
const id = entry?.options?.id;
|
|
57785
|
+
if (typeof id === "string" && id.length > 0) {
|
|
57786
|
+
if (seenIds.has(id)) continue;
|
|
57787
|
+
seenIds.add(id);
|
|
57788
|
+
}
|
|
57789
|
+
deduped.push(entry);
|
|
57790
|
+
}
|
|
57791
|
+
deduped.sort((a, b) => (a.options?.order ?? 0) - (b.options?.order ?? 0));
|
|
57792
|
+
cachedRaw = raw;
|
|
57793
|
+
cachedDeduped = deduped;
|
|
57794
|
+
return cachedDeduped;
|
|
57795
|
+
};
|
|
57796
|
+
try {
|
|
57797
|
+
Object.defineProperty(target, "entries", {
|
|
57798
|
+
value: wrapped,
|
|
57799
|
+
configurable: true,
|
|
57800
|
+
writable: true
|
|
57801
|
+
});
|
|
57802
|
+
} catch {
|
|
57803
|
+
return () => {};
|
|
57804
|
+
}
|
|
57805
|
+
return () => {
|
|
57806
|
+
try {
|
|
57807
|
+
if (target.entries === wrapped) {
|
|
57808
|
+
delete target.entries;
|
|
57809
|
+
if (target.entries !== originalEntries) Object.defineProperty(target, "entries", {
|
|
57810
|
+
value: originalEntries,
|
|
57811
|
+
configurable: true,
|
|
57812
|
+
writable: true
|
|
57813
|
+
});
|
|
57814
|
+
}
|
|
57815
|
+
} catch {}
|
|
57816
|
+
};
|
|
57817
|
+
}
|
|
57818
|
+
/**
|
|
57819
|
+
* 把本卡注册进插件页。
|
|
57820
|
+
*/
|
|
57821
|
+
function installSubagentSettingsCard(ctx) {
|
|
57822
|
+
const forms = serviceOf(ctx, "configForms");
|
|
57823
|
+
if (!isConfigForms(forms)) return () => {};
|
|
57824
|
+
const controller = new SubagentSettingsController({
|
|
57825
|
+
limits: forms.get(SUBAGENT_LIMITS_NS),
|
|
57826
|
+
modelSelection: forms.get(SUBAGENT_MODEL_SELECTION_NS),
|
|
57827
|
+
loadCatalog: () => readSubagentCatalog(ctx),
|
|
57828
|
+
loadPreferences: readSubagentPreferences,
|
|
57829
|
+
savePreferences: writeSubagentPreferences
|
|
57830
|
+
});
|
|
57831
|
+
ctx.effect(() => () => {
|
|
57832
|
+
controller.dispose();
|
|
57833
|
+
}, "dsh-subagent-settings: form subscriptions");
|
|
57834
|
+
const remote = serviceOf(ctx, "remote");
|
|
57835
|
+
if (typeof remote?.$on === "function") {
|
|
57836
|
+
const $on = remote.$on.bind(remote);
|
|
57837
|
+
ctx.effect(() => $on("llm/adapters-updated", () => {
|
|
57838
|
+
controller.refreshCatalog();
|
|
57839
|
+
}), "dsh-subagent-settings: adapter invalidations");
|
|
57840
|
+
ctx.effect(() => $on("settings/document-updated", () => {
|
|
57841
|
+
controller.refreshCatalog();
|
|
57842
|
+
}), "dsh-subagent-settings: settings invalidations");
|
|
57843
|
+
}
|
|
57844
|
+
const on = ctx.on;
|
|
57845
|
+
if (typeof on === "function") ctx.effect(() => on.call(ctx, "connection/reset", () => {
|
|
57846
|
+
controller.resetConnection();
|
|
57847
|
+
}), "dsh-subagent-settings: connection reset");
|
|
57848
|
+
const face = controller.inject();
|
|
57849
|
+
const register = () => {
|
|
57850
|
+
try {
|
|
57851
|
+
const restoreEntries = installPluginsItemLedgerDedup(ctx.slots);
|
|
57852
|
+
const disposeInject = ctx.slots.inject("plugins.item", () => {
|
|
57853
|
+
try {
|
|
57854
|
+
return ctx.slots.register({
|
|
57855
|
+
name: "plugins.item",
|
|
57856
|
+
id: SUBAGENT_SLOT_ID,
|
|
57857
|
+
order: 10,
|
|
57858
|
+
priority: -10,
|
|
57859
|
+
label: () => {
|
|
57860
|
+
try {
|
|
57861
|
+
return ctx.locale.bind(NS_SUBAGENT)("subagentTitle");
|
|
57862
|
+
} catch {
|
|
57863
|
+
return "子智能体";
|
|
57864
|
+
}
|
|
57865
|
+
},
|
|
57866
|
+
locale: NS_SUBAGENT,
|
|
57867
|
+
inject: () => face
|
|
57868
|
+
}, SubagentCard);
|
|
57869
|
+
} catch {
|
|
57870
|
+
return () => {};
|
|
57871
|
+
}
|
|
57872
|
+
});
|
|
57873
|
+
return () => {
|
|
57874
|
+
disposeInject();
|
|
57875
|
+
restoreEntries();
|
|
57876
|
+
};
|
|
57877
|
+
} catch {
|
|
57878
|
+
return () => {};
|
|
57879
|
+
}
|
|
57880
|
+
};
|
|
57881
|
+
if (typeof forms.whileServed === "function") try {
|
|
57882
|
+
return forms.whileServed([SUBAGENT_LIMITS_NS, SUBAGENT_MODEL_SELECTION_NS], () => register());
|
|
57883
|
+
} catch {}
|
|
57884
|
+
return register();
|
|
57885
|
+
}
|
|
57886
|
+
//#endregion
|
|
57887
|
+
//#region src/client/subagent/styles.ts
|
|
57888
|
+
/**
|
|
57889
|
+
* 「子智能体」设置卡片的样式表。
|
|
57890
|
+
*
|
|
57891
|
+
* 1:1 对齐 DSH 官方 `ui-settings-subagent` 与 `ui-primitives` 的 CSS 规则与变量:
|
|
57892
|
+
* - `.dsh-subagent-section` / `.dsh-subagent-heading` 对应 `SubagentCard.module.css`
|
|
57893
|
+
* - `.dsh-subagent-limits-grid` / `.dsh-subagent-field` / `.dsh-subagent-input` 对应 `SubagentLimitsFields.module.css` + `fields.module.css`
|
|
57894
|
+
* - `.dsh-subagent-switch` 对应 `Switch.module.css`
|
|
57895
|
+
* - `.dsh-subagent-models` / `.dsh-subagent-group` / `.dsh-subagent-model` 对应 `SubagentModelSelectionFields.module.css`
|
|
57896
|
+
* - `.dsh-subagent-footer` / `.dsh-subagent-save` 对应 `SettingsForm.module.css`
|
|
57897
|
+
*/
|
|
57898
|
+
/** 这张表的 `data-plugin-css` 子名。 */
|
|
57899
|
+
const STYLE_NAME = "subagent";
|
|
57900
|
+
/** 卡片与表单的样式全文。 */
|
|
57901
|
+
const SUBAGENT_CSS = `
|
|
57902
|
+
.dsh-subagent-form {
|
|
57903
|
+
display: flex;
|
|
57904
|
+
flex-direction: column;
|
|
57905
|
+
min-width: 0;
|
|
57906
|
+
}
|
|
57907
|
+
|
|
57908
|
+
.dsh-subagent-readonly-notice,
|
|
57909
|
+
.dsh-subagent-unavailable-notice {
|
|
57910
|
+
margin: 0 0 12px;
|
|
57911
|
+
font-size: 12px;
|
|
57912
|
+
line-height: 1.5;
|
|
57913
|
+
color: var(--dsw-alias-label-tertiary);
|
|
57914
|
+
}
|
|
57915
|
+
|
|
57916
|
+
.dsh-subagent-section {
|
|
57917
|
+
min-width: 0;
|
|
57918
|
+
padding: 16px 0;
|
|
57919
|
+
}
|
|
57920
|
+
|
|
57921
|
+
.dsh-subagent-heading {
|
|
57922
|
+
margin: 0;
|
|
57923
|
+
font-size: 13px;
|
|
57924
|
+
font-weight: 600;
|
|
57925
|
+
line-height: 1.5;
|
|
57926
|
+
color: var(--dsw-alias-label-primary);
|
|
57927
|
+
}
|
|
57928
|
+
|
|
57929
|
+
.dsh-subagent-limits-grid {
|
|
57930
|
+
display: grid;
|
|
57931
|
+
grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr));
|
|
57932
|
+
gap: 16px;
|
|
57933
|
+
}
|
|
57934
|
+
|
|
57935
|
+
.dsh-subagent-limit-cell {
|
|
57936
|
+
min-width: 0;
|
|
57937
|
+
}
|
|
57938
|
+
|
|
57939
|
+
.dsh-subagent-field {
|
|
57940
|
+
display: flex;
|
|
57941
|
+
flex-direction: column;
|
|
57942
|
+
gap: 6px;
|
|
57943
|
+
padding: 12px 0;
|
|
57944
|
+
min-width: 0;
|
|
57945
|
+
}
|
|
57946
|
+
|
|
57947
|
+
.dsh-subagent-field-head {
|
|
57948
|
+
display: flex;
|
|
57949
|
+
align-items: center;
|
|
57950
|
+
gap: 8px;
|
|
57951
|
+
}
|
|
57952
|
+
|
|
57953
|
+
.dsh-subagent-label-group {
|
|
57954
|
+
display: flex;
|
|
57955
|
+
align-items: center;
|
|
57956
|
+
gap: 4px;
|
|
57957
|
+
flex: 1;
|
|
57958
|
+
min-width: 0;
|
|
57959
|
+
}
|
|
57960
|
+
|
|
57961
|
+
.dsh-subagent-label {
|
|
57962
|
+
flex: 0 1 auto;
|
|
57963
|
+
min-width: 0;
|
|
57964
|
+
font-size: 13px;
|
|
57965
|
+
font-weight: 500;
|
|
57966
|
+
line-height: 1.5;
|
|
57967
|
+
color: var(--dsw-alias-label-primary);
|
|
57968
|
+
}
|
|
57969
|
+
|
|
57970
|
+
.dsh-subagent-help-btn {
|
|
57971
|
+
display: inline-flex;
|
|
57972
|
+
align-items: center;
|
|
57973
|
+
justify-content: center;
|
|
57974
|
+
flex: none;
|
|
57975
|
+
width: 24px;
|
|
57976
|
+
height: 24px;
|
|
57977
|
+
padding: 0;
|
|
57978
|
+
border: 0;
|
|
57979
|
+
border-radius: var(--dsw-radius-sm, 6px);
|
|
57980
|
+
background: none;
|
|
57981
|
+
color: var(--dsw-alias-label-tertiary);
|
|
57982
|
+
cursor: pointer;
|
|
57983
|
+
}
|
|
57984
|
+
|
|
57985
|
+
.dsh-subagent-help-btn[aria-expanded='true'] {
|
|
57986
|
+
background: var(--dsw-alias-bg-layer-4);
|
|
57987
|
+
color: var(--dsw-alias-label-secondary);
|
|
57988
|
+
}
|
|
57989
|
+
|
|
57990
|
+
@media (hover: hover) {
|
|
57991
|
+
.dsh-subagent-help-btn:hover {
|
|
57992
|
+
background: var(--dsw-alias-bg-layer-4);
|
|
57993
|
+
color: var(--dsw-alias-label-secondary);
|
|
57994
|
+
}
|
|
57995
|
+
}
|
|
57996
|
+
|
|
57997
|
+
.dsh-subagent-help-box {
|
|
57998
|
+
padding: 10px 0 0;
|
|
57999
|
+
font-size: 12px;
|
|
58000
|
+
line-height: 1.6;
|
|
58001
|
+
color: var(--dsw-alias-label-secondary);
|
|
58002
|
+
}
|
|
58003
|
+
|
|
58004
|
+
.dsh-subagent-help-box > p {
|
|
58005
|
+
margin: 0;
|
|
58006
|
+
}
|
|
58007
|
+
|
|
58008
|
+
.dsh-subagent-help-box > p + p {
|
|
58009
|
+
margin-top: 8px;
|
|
58010
|
+
}
|
|
58011
|
+
|
|
58012
|
+
.dsh-subagent-depth-table {
|
|
58013
|
+
width: 100%;
|
|
58014
|
+
margin: 8px 0;
|
|
58015
|
+
border-collapse: collapse;
|
|
58016
|
+
border-block: 0.5px solid var(--dsw-alias-border-l2);
|
|
58017
|
+
font: inherit;
|
|
58018
|
+
text-align: left;
|
|
58019
|
+
}
|
|
58020
|
+
|
|
58021
|
+
.dsh-subagent-depth-table th,
|
|
58022
|
+
.dsh-subagent-depth-table td {
|
|
58023
|
+
padding: 6px 0;
|
|
58024
|
+
vertical-align: top;
|
|
58025
|
+
}
|
|
58026
|
+
|
|
58027
|
+
.dsh-subagent-depth-table th {
|
|
58028
|
+
width: 24px;
|
|
58029
|
+
padding-right: 8px;
|
|
58030
|
+
font-weight: 500;
|
|
58031
|
+
font-variant-numeric: tabular-nums;
|
|
58032
|
+
color: var(--dsw-alias-label-primary);
|
|
58033
|
+
}
|
|
58034
|
+
|
|
58035
|
+
.dsh-subagent-depth-table tr + tr {
|
|
58036
|
+
border-top: 0.5px solid var(--dsw-alias-border-l2);
|
|
58037
|
+
}
|
|
58038
|
+
|
|
58039
|
+
.dsh-subagent-badges {
|
|
58040
|
+
display: inline-flex;
|
|
58041
|
+
align-items: center;
|
|
58042
|
+
gap: 8px;
|
|
58043
|
+
}
|
|
58044
|
+
|
|
58045
|
+
.dsh-subagent-override-tag {
|
|
58046
|
+
display: inline-flex;
|
|
58047
|
+
align-items: center;
|
|
58048
|
+
padding: 1px 6px;
|
|
58049
|
+
border-radius: var(--dsw-radius-sm, 6px);
|
|
58050
|
+
background: var(--dsw-alias-bg-layer-4);
|
|
58051
|
+
font-size: 11px;
|
|
58052
|
+
line-height: 1.4;
|
|
58053
|
+
color: var(--dsw-alias-label-secondary);
|
|
58054
|
+
}
|
|
58055
|
+
|
|
58056
|
+
.dsh-subagent-reset-link {
|
|
58057
|
+
border: none;
|
|
58058
|
+
background: none;
|
|
58059
|
+
padding: 0;
|
|
58060
|
+
font: inherit;
|
|
58061
|
+
font-size: 12px;
|
|
58062
|
+
line-height: 1.5;
|
|
58063
|
+
color: var(--dsw-alias-label-secondary);
|
|
58064
|
+
cursor: pointer;
|
|
58065
|
+
}
|
|
58066
|
+
|
|
58067
|
+
@media (hover: hover) {
|
|
58068
|
+
.dsh-subagent-reset-link:hover:not(:disabled) {
|
|
58069
|
+
color: var(--dsw-alias-label-primary);
|
|
58070
|
+
}
|
|
58071
|
+
}
|
|
58072
|
+
|
|
58073
|
+
.dsh-subagent-reset-link:disabled {
|
|
58074
|
+
cursor: default;
|
|
58075
|
+
opacity: 0.5;
|
|
58076
|
+
}
|
|
58077
|
+
|
|
58078
|
+
.dsh-subagent-input {
|
|
58079
|
+
height: 34px;
|
|
58080
|
+
padding: 0 12px;
|
|
58081
|
+
border: 0.5px solid var(--dsw-alias-border-l4);
|
|
58082
|
+
border-radius: var(--dsw-radius-md, 8px);
|
|
58083
|
+
background: var(--dsw-alias-bg-layer-3);
|
|
58084
|
+
font: inherit;
|
|
58085
|
+
font-size: 13px;
|
|
58086
|
+
line-height: 1.5;
|
|
58087
|
+
font-variant-numeric: tabular-nums;
|
|
58088
|
+
color: var(--dsw-alias-label-primary);
|
|
58089
|
+
min-width: 0;
|
|
58090
|
+
box-sizing: border-box;
|
|
58091
|
+
}
|
|
58092
|
+
|
|
58093
|
+
.dsh-subagent-input:focus-visible {
|
|
58094
|
+
outline: none;
|
|
58095
|
+
border-color: var(--dsw-alias-state-business-primary);
|
|
58096
|
+
}
|
|
58097
|
+
|
|
58098
|
+
.dsh-subagent-input:disabled {
|
|
58099
|
+
color: var(--dsw-alias-label-tertiary);
|
|
58100
|
+
cursor: default;
|
|
58101
|
+
}
|
|
58102
|
+
|
|
58103
|
+
.dsh-subagent-input[aria-invalid='true'] {
|
|
58104
|
+
border-color: var(--dsw-alias-state-error-primary);
|
|
58105
|
+
}
|
|
58106
|
+
|
|
58107
|
+
.dsh-subagent-permission {
|
|
58108
|
+
display: grid;
|
|
58109
|
+
gap: 6px;
|
|
58110
|
+
padding: 12px 0;
|
|
58111
|
+
}
|
|
58112
|
+
|
|
58113
|
+
.dsh-subagent-toggle-row {
|
|
58114
|
+
display: flex;
|
|
58115
|
+
align-items: flex-start;
|
|
58116
|
+
justify-content: space-between;
|
|
58117
|
+
gap: 16px;
|
|
58118
|
+
font-size: 13px;
|
|
58119
|
+
line-height: 1.5;
|
|
58120
|
+
color: var(--dsw-alias-label-primary);
|
|
58121
|
+
}
|
|
58122
|
+
|
|
58123
|
+
.dsh-subagent-toggle-label {
|
|
58124
|
+
flex: 1;
|
|
58125
|
+
min-width: 0;
|
|
58126
|
+
}
|
|
58127
|
+
|
|
58128
|
+
.dsh-subagent-switch {
|
|
58129
|
+
box-sizing: border-box;
|
|
58130
|
+
position: relative;
|
|
58131
|
+
flex: 0 0 auto;
|
|
58132
|
+
width: 36px;
|
|
58133
|
+
height: 20px;
|
|
58134
|
+
padding: 2px;
|
|
58135
|
+
border: 0;
|
|
58136
|
+
border-radius: 999px;
|
|
58137
|
+
background: var(--dsw-alias-border-l3);
|
|
58138
|
+
cursor: pointer;
|
|
58139
|
+
}
|
|
58140
|
+
|
|
58141
|
+
.dsh-subagent-switch[aria-checked='true'] {
|
|
58142
|
+
background: var(--dsw-alias-brand-primary, #e06c3b);
|
|
58143
|
+
}
|
|
58144
|
+
|
|
58145
|
+
.dsh-subagent-switch:disabled {
|
|
58146
|
+
cursor: default;
|
|
58147
|
+
opacity: 0.5;
|
|
58148
|
+
}
|
|
58149
|
+
|
|
58150
|
+
.dsh-subagent-switch:focus-visible {
|
|
58151
|
+
outline: var(--dsw-focus-ring-width, 2px) solid var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));
|
|
58152
|
+
outline-offset: 2px;
|
|
58153
|
+
}
|
|
58154
|
+
|
|
58155
|
+
.dsh-subagent-switch-thumb {
|
|
58156
|
+
display: block;
|
|
58157
|
+
width: 16px;
|
|
58158
|
+
height: 16px;
|
|
58159
|
+
border-radius: 50%;
|
|
58160
|
+
background: var(--dsw-alias-label-primary-foreground, #fff);
|
|
58161
|
+
transition: transform 120ms ease;
|
|
58162
|
+
}
|
|
58163
|
+
|
|
58164
|
+
.dsh-subagent-switch[aria-checked='false'] .dsh-subagent-switch-thumb {
|
|
58165
|
+
background: var(--dsw-alias-switch-thumb, #fff);
|
|
58166
|
+
}
|
|
58167
|
+
|
|
58168
|
+
.dsh-subagent-switch[aria-checked='true'] .dsh-subagent-switch-thumb {
|
|
58169
|
+
transform: translateX(16px);
|
|
58170
|
+
}
|
|
58171
|
+
|
|
58172
|
+
.dsh-subagent-selection {
|
|
58173
|
+
display: grid;
|
|
58174
|
+
gap: 12px;
|
|
58175
|
+
min-width: 0;
|
|
58176
|
+
}
|
|
58177
|
+
|
|
58178
|
+
.dsh-subagent-target-bar {
|
|
58179
|
+
display: grid;
|
|
58180
|
+
gap: 8px;
|
|
58181
|
+
padding: 12px;
|
|
58182
|
+
border: 0.5px solid var(--dsw-alias-border-l4);
|
|
58183
|
+
border-radius: var(--dsw-radius-lg, 10px);
|
|
58184
|
+
background: var(--dsw-alias-bg-layer-2, transparent);
|
|
58185
|
+
min-width: 0;
|
|
58186
|
+
}
|
|
58187
|
+
|
|
58188
|
+
.dsh-subagent-target-header {
|
|
58189
|
+
display: flex;
|
|
58190
|
+
align-items: center;
|
|
58191
|
+
justify-content: space-between;
|
|
58192
|
+
gap: 8px;
|
|
58193
|
+
min-width: 0;
|
|
58194
|
+
}
|
|
58195
|
+
|
|
58196
|
+
.dsh-subagent-target-label {
|
|
58197
|
+
font-size: 12px;
|
|
58198
|
+
font-weight: 500;
|
|
58199
|
+
line-height: 1.5;
|
|
58200
|
+
color: var(--dsw-alias-label-secondary);
|
|
58201
|
+
}
|
|
58202
|
+
|
|
58203
|
+
.dsh-subagent-select {
|
|
58204
|
+
height: 34px;
|
|
58205
|
+
width: 100%;
|
|
58206
|
+
padding: 0 10px;
|
|
58207
|
+
border: 0.5px solid var(--dsw-alias-border-l4);
|
|
58208
|
+
border-radius: var(--dsw-radius-md, 8px);
|
|
58209
|
+
background: var(--dsw-alias-bg-layer-3);
|
|
58210
|
+
color: var(--dsw-alias-label-primary);
|
|
58211
|
+
font: inherit;
|
|
58212
|
+
font-size: 13px;
|
|
58213
|
+
line-height: 1.5;
|
|
58214
|
+
box-sizing: border-box;
|
|
58215
|
+
cursor: pointer;
|
|
58216
|
+
}
|
|
58217
|
+
|
|
58218
|
+
.dsh-subagent-select option,
|
|
58219
|
+
.dsh-subagent-select optgroup {
|
|
58220
|
+
background: var(--dsw-alias-bg-layer-3, #1e1e1e);
|
|
58221
|
+
color: var(--dsw-alias-label-primary, #e5e5e5);
|
|
58222
|
+
}
|
|
58223
|
+
|
|
58224
|
+
.dsh-subagent-select:focus-visible {
|
|
58225
|
+
outline: none;
|
|
58226
|
+
border-color: var(--dsw-alias-state-business-primary);
|
|
58227
|
+
}
|
|
58228
|
+
|
|
58229
|
+
.dsh-subagent-select:disabled {
|
|
58230
|
+
color: var(--dsw-alias-label-tertiary);
|
|
58231
|
+
cursor: default;
|
|
58232
|
+
}
|
|
58233
|
+
|
|
58234
|
+
.dsh-subagent-chips {
|
|
58235
|
+
display: flex;
|
|
58236
|
+
flex-wrap: wrap;
|
|
58237
|
+
align-items: center;
|
|
58238
|
+
gap: 6px;
|
|
58239
|
+
min-width: 0;
|
|
58240
|
+
}
|
|
58241
|
+
|
|
58242
|
+
.dsh-subagent-chip {
|
|
58243
|
+
padding: 3px 10px;
|
|
58244
|
+
border: 0.5px solid var(--dsw-alias-border-l3);
|
|
58245
|
+
border-radius: 999px;
|
|
58246
|
+
background: var(--dsw-alias-bg-layer-3);
|
|
58247
|
+
color: var(--dsw-alias-label-secondary);
|
|
58248
|
+
font: inherit;
|
|
58249
|
+
font-size: 12px;
|
|
58250
|
+
line-height: 1.4;
|
|
58251
|
+
cursor: pointer;
|
|
58252
|
+
}
|
|
58253
|
+
|
|
58254
|
+
.dsh-subagent-chip[aria-pressed='true'] {
|
|
58255
|
+
border-color: var(--dsw-alias-brand-primary, #e06c3b);
|
|
58256
|
+
background: color-mix(in srgb, var(--dsw-alias-brand-primary, #e06c3b) 15%, transparent);
|
|
58257
|
+
color: var(--dsw-alias-label-primary);
|
|
58258
|
+
font-weight: 500;
|
|
58259
|
+
}
|
|
58260
|
+
|
|
58261
|
+
.dsh-subagent-chip:disabled {
|
|
58262
|
+
cursor: default;
|
|
58263
|
+
opacity: 0.5;
|
|
58264
|
+
}
|
|
58265
|
+
|
|
58266
|
+
.dsh-subagent-status {
|
|
58267
|
+
display: flex;
|
|
58268
|
+
flex-wrap: wrap;
|
|
58269
|
+
align-items: center;
|
|
58270
|
+
justify-content: space-between;
|
|
58271
|
+
gap: 8px;
|
|
58272
|
+
min-width: 0;
|
|
58273
|
+
}
|
|
58274
|
+
|
|
58275
|
+
.dsh-subagent-reset {
|
|
58276
|
+
padding: 3px 10px;
|
|
58277
|
+
border: 0.5px solid var(--dsw-alias-border-l4);
|
|
58278
|
+
border-radius: var(--dsw-radius-md, 8px);
|
|
58279
|
+
background: var(--dsw-alias-bg-layer-3);
|
|
58280
|
+
color: var(--dsw-alias-label-secondary);
|
|
58281
|
+
font: inherit;
|
|
58282
|
+
font-size: 12px;
|
|
58283
|
+
line-height: 1.4;
|
|
58284
|
+
cursor: pointer;
|
|
58285
|
+
}
|
|
58286
|
+
|
|
58287
|
+
@media (hover: hover) {
|
|
58288
|
+
.dsh-subagent-reset:hover:not(:disabled) {
|
|
58289
|
+
background: var(--dsw-alias-bg-layer-4);
|
|
58290
|
+
color: var(--dsw-alias-label-primary);
|
|
58291
|
+
}
|
|
58292
|
+
}
|
|
58293
|
+
|
|
58294
|
+
.dsh-subagent-reset:disabled {
|
|
58295
|
+
cursor: default;
|
|
58296
|
+
opacity: 0.5;
|
|
58297
|
+
}
|
|
58298
|
+
|
|
58299
|
+
.dsh-subagent-hint,
|
|
58300
|
+
.dsh-subagent-notice,
|
|
58301
|
+
.dsh-subagent-invalid {
|
|
58302
|
+
margin: 0;
|
|
58303
|
+
font-size: 12px;
|
|
58304
|
+
line-height: 1.5;
|
|
58305
|
+
}
|
|
58306
|
+
|
|
58307
|
+
.dsh-subagent-hint,
|
|
58308
|
+
.dsh-subagent-notice {
|
|
58309
|
+
color: var(--dsw-alias-label-tertiary);
|
|
58310
|
+
}
|
|
58311
|
+
|
|
58312
|
+
.dsh-subagent-invalid {
|
|
58313
|
+
color: var(--dsw-alias-state-error-primary, #e5534b);
|
|
58314
|
+
}
|
|
58315
|
+
|
|
58316
|
+
.dsh-subagent-catalog-error {
|
|
58317
|
+
display: flex;
|
|
58318
|
+
align-items: center;
|
|
58319
|
+
justify-content: space-between;
|
|
58320
|
+
gap: 12px;
|
|
58321
|
+
font-size: 12px;
|
|
58322
|
+
color: var(--dsw-alias-state-error-primary, #e5534b);
|
|
58323
|
+
}
|
|
58324
|
+
|
|
58325
|
+
.dsh-subagent-catalog-error button {
|
|
58326
|
+
border: 0;
|
|
58327
|
+
padding: 0;
|
|
58328
|
+
background: transparent;
|
|
58329
|
+
color: var(--dsw-alias-brand-primary, #e06c3b);
|
|
58330
|
+
font: inherit;
|
|
58331
|
+
cursor: pointer;
|
|
58332
|
+
}
|
|
58333
|
+
|
|
58334
|
+
.dsh-subagent-models {
|
|
58335
|
+
display: grid;
|
|
58336
|
+
align-content: start;
|
|
58337
|
+
gap: 6px;
|
|
58338
|
+
min-width: 0;
|
|
58339
|
+
min-height: 180px;
|
|
58340
|
+
max-height: clamp(220px, calc(100dvh - 620px), 440px);
|
|
58341
|
+
resize: vertical;
|
|
58342
|
+
margin: 0;
|
|
58343
|
+
padding: 10px;
|
|
58344
|
+
overflow: auto;
|
|
58345
|
+
border: 0.5px solid var(--dsw-alias-border-l4);
|
|
58346
|
+
border-radius: var(--dsw-radius-lg, 10px);
|
|
58347
|
+
}
|
|
58348
|
+
|
|
58349
|
+
.dsh-subagent-models > legend {
|
|
58350
|
+
padding: 0 4px;
|
|
58351
|
+
font-size: 12px;
|
|
58352
|
+
color: var(--dsw-alias-label-secondary);
|
|
58353
|
+
}
|
|
58354
|
+
|
|
58355
|
+
.dsh-subagent-group {
|
|
58356
|
+
display: grid;
|
|
58357
|
+
gap: 6px;
|
|
58358
|
+
min-width: 0;
|
|
58359
|
+
}
|
|
58360
|
+
|
|
58361
|
+
.dsh-subagent-group + .dsh-subagent-group {
|
|
58362
|
+
margin-top: 4px;
|
|
58363
|
+
padding-top: 10px;
|
|
58364
|
+
border-top: 0.5px solid var(--dsw-alias-border-l3);
|
|
58365
|
+
}
|
|
58366
|
+
|
|
58367
|
+
.dsh-subagent-group-name {
|
|
58368
|
+
padding: 0 6px;
|
|
58369
|
+
font-size: 11px;
|
|
58370
|
+
font-weight: 500;
|
|
58371
|
+
color: var(--dsw-alias-label-tertiary);
|
|
58372
|
+
}
|
|
58373
|
+
|
|
58374
|
+
.dsh-subagent-model {
|
|
58375
|
+
display: grid;
|
|
58376
|
+
grid-template-columns: auto minmax(0, 1fr) auto;
|
|
58377
|
+
align-items: center;
|
|
58378
|
+
gap: 8px;
|
|
58379
|
+
min-width: 0;
|
|
58380
|
+
padding: 6px;
|
|
58381
|
+
border-radius: var(--dsw-radius-md, 8px);
|
|
58382
|
+
cursor: pointer;
|
|
58383
|
+
}
|
|
58384
|
+
|
|
58385
|
+
@media (hover: hover) {
|
|
58386
|
+
.dsh-subagent-model:hover {
|
|
58387
|
+
background: var(--dsw-alias-bg-layer-4);
|
|
58388
|
+
}
|
|
58389
|
+
}
|
|
58390
|
+
|
|
58391
|
+
.dsh-subagent-model-name,
|
|
58392
|
+
.dsh-subagent-model-route {
|
|
58393
|
+
display: block;
|
|
58394
|
+
overflow: hidden;
|
|
58395
|
+
text-overflow: ellipsis;
|
|
58396
|
+
white-space: nowrap;
|
|
58397
|
+
}
|
|
58398
|
+
|
|
58399
|
+
.dsh-subagent-model-name {
|
|
58400
|
+
font-size: 13px;
|
|
58401
|
+
color: var(--dsw-alias-label-primary);
|
|
58402
|
+
}
|
|
58403
|
+
|
|
58404
|
+
.dsh-subagent-model-route {
|
|
58405
|
+
margin-top: 2px;
|
|
58406
|
+
font-size: 11px;
|
|
58407
|
+
color: var(--dsw-alias-label-tertiary);
|
|
58408
|
+
}
|
|
58409
|
+
|
|
58410
|
+
.dsh-subagent-model-unavailable {
|
|
58411
|
+
font-size: 11px;
|
|
58412
|
+
color: var(--dsw-alias-label-tertiary);
|
|
58413
|
+
white-space: nowrap;
|
|
58414
|
+
}
|
|
58415
|
+
|
|
58416
|
+
.dsh-subagent-footer {
|
|
58417
|
+
display: flex;
|
|
58418
|
+
align-items: center;
|
|
58419
|
+
gap: 8px;
|
|
58420
|
+
padding-top: 16px;
|
|
58421
|
+
}
|
|
58422
|
+
|
|
58423
|
+
.dsh-subagent-save {
|
|
58424
|
+
appearance: none;
|
|
58425
|
+
border: 1px solid transparent;
|
|
58426
|
+
border-radius: var(--dsw-radius-md, 8px);
|
|
58427
|
+
padding: 5px 14px;
|
|
58428
|
+
font: inherit;
|
|
58429
|
+
font-size: 13px;
|
|
58430
|
+
line-height: 1.5;
|
|
58431
|
+
cursor: pointer;
|
|
58432
|
+
background: var(--dsw-alias-label-primary);
|
|
58433
|
+
color: var(--dsw-alias-bg-layer-3);
|
|
58434
|
+
}
|
|
58435
|
+
|
|
58436
|
+
.dsh-subagent-save:disabled {
|
|
58437
|
+
opacity: 0.4;
|
|
58438
|
+
cursor: default;
|
|
58439
|
+
}
|
|
58440
|
+
|
|
58441
|
+
.dsh-subagent-save:focus-visible {
|
|
58442
|
+
outline: var(--dsw-focus-ring-width, 2px) solid var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));
|
|
58443
|
+
outline-offset: 1px;
|
|
58444
|
+
}
|
|
58445
|
+
|
|
58446
|
+
.dsh-subagent-discard {
|
|
58447
|
+
appearance: none;
|
|
58448
|
+
border: 0.5px solid var(--dsw-alias-border-l4);
|
|
58449
|
+
border-radius: var(--dsw-radius-md, 8px);
|
|
58450
|
+
padding: 5px 12px;
|
|
58451
|
+
font: inherit;
|
|
58452
|
+
font-size: 13px;
|
|
58453
|
+
line-height: 1.5;
|
|
58454
|
+
cursor: pointer;
|
|
58455
|
+
background: transparent;
|
|
58456
|
+
color: var(--dsw-alias-label-secondary);
|
|
58457
|
+
}
|
|
58458
|
+
|
|
58459
|
+
.dsh-subagent-discard:disabled {
|
|
58460
|
+
opacity: 0.4;
|
|
58461
|
+
cursor: default;
|
|
58462
|
+
}
|
|
58463
|
+
|
|
58464
|
+
.dsh-subagent-failed {
|
|
58465
|
+
flex: 1;
|
|
58466
|
+
min-width: 0;
|
|
58467
|
+
margin: 0;
|
|
58468
|
+
font-size: 12px;
|
|
58469
|
+
line-height: 1.5;
|
|
58470
|
+
color: var(--dsw-alias-label-error, var(--dsw-alias-state-error-primary, #e5534b));
|
|
58471
|
+
}
|
|
58472
|
+
`;
|
|
58473
|
+
/**
|
|
58474
|
+
* 安装本卡片的样式表。
|
|
58475
|
+
* @returns 卸载函数(样式表由文档持有,这里不做删除)。
|
|
58476
|
+
*/
|
|
58477
|
+
function installSubagentStyles() {
|
|
58478
|
+
return installPluginStyle(STYLE_NAME, SUBAGENT_CSS);
|
|
58479
|
+
}
|
|
58480
|
+
//#endregion
|
|
56285
58481
|
//#region src/client/index.tsx
|
|
56286
58482
|
const inject = [
|
|
56287
58483
|
"slots",
|
|
@@ -56295,70 +58491,75 @@ window.__ModuleLoader__.load({
|
|
|
56295
58491
|
function apply(ctx) {
|
|
56296
58492
|
installLineLocale(ctx.locale);
|
|
56297
58493
|
installRussianLocale(ctx);
|
|
56298
|
-
ctx.effect(() => ctx.locale.register(NS, dictionaries$
|
|
58494
|
+
ctx.effect(() => ctx.locale.register(NS, dictionaries$2), "dsh-chatgpt-subscription: dictionaries");
|
|
56299
58495
|
ctx.effect(() => installStyles(), "dsh-chatgpt-subscription: styles");
|
|
56300
58496
|
ctx.effect(() => {
|
|
56301
58497
|
installHubStyles();
|
|
56302
58498
|
installModelChecklistStyles();
|
|
56303
58499
|
return () => {};
|
|
56304
58500
|
}, "dsh-chatgpt-subscription: hub styles");
|
|
56305
|
-
ctx.effect(() => ctx.locale.register(NS_ANTIGRAVITY, dictionaries$
|
|
58501
|
+
ctx.effect(() => ctx.locale.register(NS_ANTIGRAVITY, dictionaries$14), "dsh-antigravity: dictionaries");
|
|
56306
58502
|
ctx.effect(() => {
|
|
56307
58503
|
installAntigravityStyles();
|
|
56308
58504
|
return () => {};
|
|
56309
58505
|
}, "dsh-antigravity: styles");
|
|
56310
|
-
ctx.effect(() => ctx.locale.register(NS_CLAUDE, dictionaries$
|
|
58506
|
+
ctx.effect(() => ctx.locale.register(NS_CLAUDE, dictionaries$9), "dsh-claude: dictionaries");
|
|
56311
58507
|
ctx.effect(() => {
|
|
56312
58508
|
installClaudeStyles();
|
|
56313
58509
|
return () => {};
|
|
56314
58510
|
}, "dsh-claude: styles");
|
|
56315
|
-
ctx.effect(() => ctx.locale.register(NS_COMMAND_CODE, dictionaries$
|
|
56316
|
-
ctx.effect(() => ctx.locale.register(NS_KIMI_CODE, dictionaries$
|
|
58511
|
+
ctx.effect(() => ctx.locale.register(NS_COMMAND_CODE, dictionaries$13), "dsh-command-code: dictionaries");
|
|
58512
|
+
ctx.effect(() => ctx.locale.register(NS_KIMI_CODE, dictionaries$12), "dsh-kimi-code: dictionaries");
|
|
56317
58513
|
ctx.effect(() => {
|
|
56318
58514
|
installKimiCodeStyles();
|
|
56319
58515
|
return () => {};
|
|
56320
58516
|
}, "dsh-kimi-code: styles");
|
|
56321
|
-
ctx.effect(() => ctx.locale.register(NS_MINIMAX_CODE, dictionaries$
|
|
58517
|
+
ctx.effect(() => ctx.locale.register(NS_MINIMAX_CODE, dictionaries$11), "dsh-minimax-code: dictionaries");
|
|
56322
58518
|
ctx.effect(() => {
|
|
56323
58519
|
installMinimaxCodeStyles();
|
|
56324
58520
|
return () => {};
|
|
56325
58521
|
}, "dsh-minimax-code: styles");
|
|
56326
|
-
ctx.effect(() => ctx.locale.register(NS_GLM_CODING_PLAN, dictionaries$
|
|
58522
|
+
ctx.effect(() => ctx.locale.register(NS_GLM_CODING_PLAN, dictionaries$10), "dsh-glm-coding-plan: dictionaries");
|
|
56327
58523
|
ctx.effect(() => {
|
|
56328
58524
|
installGlmCodingPlanStyles();
|
|
56329
58525
|
return () => {};
|
|
56330
58526
|
}, "dsh-glm-coding-plan: styles");
|
|
56331
|
-
ctx.effect(() => ctx.locale.register(NS_OLLAMA, dictionaries$
|
|
56332
|
-
ctx.effect(() => ctx.locale.register(NS_PROGRESS_UPDATES, dictionaries), "dsh-progress-updates: dictionaries");
|
|
58527
|
+
ctx.effect(() => ctx.locale.register(NS_OLLAMA, dictionaries$8), "dsh-ollama: dictionaries");
|
|
58528
|
+
ctx.effect(() => ctx.locale.register(NS_PROGRESS_UPDATES, dictionaries$1), "dsh-progress-updates: dictionaries");
|
|
56333
58529
|
ctx.effect(() => {
|
|
56334
58530
|
installProgressUpdatesStyles();
|
|
56335
58531
|
return () => {};
|
|
56336
58532
|
}, "dsh-progress-updates: styles");
|
|
56337
|
-
ctx.effect(() => ctx.locale.register(NS_STEP_CODE, dictionaries$
|
|
58533
|
+
ctx.effect(() => ctx.locale.register(NS_STEP_CODE, dictionaries$7), "dsh-step-code: dictionaries");
|
|
56338
58534
|
ctx.effect(() => {
|
|
56339
58535
|
installStepCodeStyles();
|
|
56340
58536
|
return () => {};
|
|
56341
58537
|
}, "dsh-step-code: styles");
|
|
56342
|
-
ctx.effect(() => ctx.locale.register(NS_CLINE_PASS, dictionaries$
|
|
58538
|
+
ctx.effect(() => ctx.locale.register(NS_CLINE_PASS, dictionaries$6), "dsh-cline-pass: dictionaries");
|
|
56343
58539
|
ctx.effect(() => {
|
|
56344
58540
|
installClinePassStyles();
|
|
56345
58541
|
return () => {};
|
|
56346
58542
|
}, "dsh-cline-pass: styles");
|
|
56347
|
-
ctx.effect(() => ctx.locale.register(NS_QODER, dictionaries$
|
|
58543
|
+
ctx.effect(() => ctx.locale.register(NS_QODER, dictionaries$5), "dsh-qoder: dictionaries");
|
|
56348
58544
|
ctx.effect(() => {
|
|
56349
58545
|
installQoderStyles();
|
|
56350
58546
|
return () => {};
|
|
56351
58547
|
}, "dsh-qoder: styles");
|
|
56352
|
-
ctx.effect(() => ctx.locale.register(NS_OPENDESIGN, dictionaries$
|
|
58548
|
+
ctx.effect(() => ctx.locale.register(NS_OPENDESIGN, dictionaries$4), "dsh-opendesign: dictionaries");
|
|
56353
58549
|
ctx.effect(() => {
|
|
56354
58550
|
installOpenDesignStyles();
|
|
56355
58551
|
return () => {};
|
|
56356
58552
|
}, "dsh-opendesign: styles");
|
|
56357
|
-
ctx.effect(() => ctx.locale.register(NS_WORKBUDDY, dictionaries$
|
|
58553
|
+
ctx.effect(() => ctx.locale.register(NS_WORKBUDDY, dictionaries$3), "dsh-workbuddy: dictionaries");
|
|
56358
58554
|
ctx.effect(() => {
|
|
56359
58555
|
installWorkBuddyStyles();
|
|
56360
58556
|
return () => {};
|
|
56361
58557
|
}, "dsh-workbuddy: styles");
|
|
58558
|
+
ctx.effect(() => ctx.locale.register(NS_SUBAGENT, dictionaries), "dsh-subagent-settings: dictionaries");
|
|
58559
|
+
ctx.effect(() => {
|
|
58560
|
+
installSubagentStyles();
|
|
58561
|
+
return () => {};
|
|
58562
|
+
}, "dsh-subagent-settings: styles");
|
|
56362
58563
|
ctx.effect(() => {
|
|
56363
58564
|
installPoolStyles();
|
|
56364
58565
|
return () => {};
|
|
@@ -56491,6 +58692,7 @@ window.__ModuleLoader__.load({
|
|
|
56491
58692
|
})
|
|
56492
58693
|
}, MinimaxVideoToolView));
|
|
56493
58694
|
installVideoDocumentPreview(ctx);
|
|
58695
|
+
installSubagentSettingsCard(ctx);
|
|
56494
58696
|
installProgressUpdatesClient(ctx);
|
|
56495
58697
|
ctx.effect(() => installVideoCommand(ctx), "dsh-minimax-code: /video command");
|
|
56496
58698
|
const VideoCommandHost = createVideoCommandHost(ctx);
|