@eddyskywalker/dsh-chatgpt-subscription 0.8.0-alpha.1 → 0.8.2
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 +48 -0
- package/README.md +65 -0
- package/lib/client.js +2051 -456
- package/lib/client.js.map +1 -1
- package/lib/index.js +4762 -1711
- package/lib/types/client/CodexSubscriptionSection.d.ts.map +1 -1
- package/lib/types/client/ProviderHubSection.d.ts.map +1 -1
- package/lib/types/client/antigravity/AntigravitySection.d.ts.map +1 -1
- package/lib/types/client/antigravity/locales.d.ts +14 -2
- package/lib/types/client/antigravity/locales.d.ts.map +1 -1
- package/lib/types/client/antigravity/styles.d.ts.map +1 -1
- package/lib/types/client/command-code/CommandCodeSection.d.ts.map +1 -1
- package/lib/types/client/command-code/locales.d.ts +14 -2
- package/lib/types/client/command-code/locales.d.ts.map +1 -1
- package/lib/types/client/index.d.ts +1 -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/kimi-code/styles.d.ts.map +1 -1
- package/lib/types/client/locales.d.ts +13 -5
- package/lib/types/client/locales.d.ts.map +1 -1
- package/lib/types/client/workbuddy/WorkBuddySection.d.ts.map +1 -1
- package/lib/types/client/workbuddy/locales.d.ts +84 -0
- package/lib/types/client/workbuddy/locales.d.ts.map +1 -1
- package/lib/types/client/zhipu/ZhipuComposerQuota.d.ts +26 -0
- package/lib/types/client/zhipu/ZhipuComposerQuota.d.ts.map +1 -0
- package/lib/types/client/zhipu/ZhipuSection.d.ts +11 -0
- package/lib/types/client/zhipu/ZhipuSection.d.ts.map +1 -0
- package/lib/types/client/zhipu/locales.d.ts +275 -0
- package/lib/types/client/zhipu/locales.d.ts.map +1 -0
- package/lib/types/client/zhipu/styles.d.ts +12 -0
- package/lib/types/client/zhipu/styles.d.ts.map +1 -0
- package/lib/types/host/antigravity/token-store.d.ts +5 -2
- package/lib/types/host/antigravity/token-store.d.ts.map +1 -1
- package/lib/types/host/command-code/routes.d.ts.map +1 -1
- package/lib/types/host/command-code/token-store.d.ts +5 -2
- package/lib/types/host/command-code/token-store.d.ts.map +1 -1
- package/lib/types/host/common/context-window-overrides.d.ts +12 -0
- package/lib/types/host/common/context-window-overrides.d.ts.map +1 -0
- package/lib/types/host/kimi-code/routes.d.ts.map +1 -1
- package/lib/types/host/kimi-code/token-store.d.ts +5 -2
- package/lib/types/host/kimi-code/token-store.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/workbuddy/checkin.d.ts +134 -0
- package/lib/types/host/workbuddy/checkin.d.ts.map +1 -0
- package/lib/types/host/workbuddy/routes.d.ts +3 -0
- package/lib/types/host/workbuddy/routes.d.ts.map +1 -1
- package/lib/types/host/workbuddy/token-store.d.ts +29 -3
- package/lib/types/host/workbuddy/token-store.d.ts.map +1 -1
- package/lib/types/host/zhipu/account-pool.d.ts +43 -0
- package/lib/types/host/zhipu/account-pool.d.ts.map +1 -0
- package/lib/types/host/zhipu/adapter.d.ts +93 -0
- package/lib/types/host/zhipu/adapter.d.ts.map +1 -0
- package/lib/types/host/zhipu/client.d.ts +153 -0
- package/lib/types/host/zhipu/client.d.ts.map +1 -0
- package/lib/types/host/zhipu/mapper.d.ts +111 -0
- package/lib/types/host/zhipu/mapper.d.ts.map +1 -0
- package/lib/types/host/zhipu/model-catalog.d.ts +73 -0
- package/lib/types/host/zhipu/model-catalog.d.ts.map +1 -0
- package/lib/types/host/zhipu/routes.d.ts +33 -0
- package/lib/types/host/zhipu/routes.d.ts.map +1 -0
- package/lib/types/host/zhipu/token-store.d.ts +112 -0
- package/lib/types/host/zhipu/token-store.d.ts.map +1 -0
- package/lib/types/host/zhipu/types.d.ts +125 -0
- package/lib/types/host/zhipu/types.d.ts.map +1 -0
- package/lib/types/index.d.ts +8 -0
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/shared/antigravity-contracts.d.ts +2 -1
- package/lib/types/shared/antigravity-contracts.d.ts.map +1 -1
- package/lib/types/shared/command-code-contracts.d.ts +2 -1
- package/lib/types/shared/command-code-contracts.d.ts.map +1 -1
- package/lib/types/shared/contracts.d.ts +5 -9
- package/lib/types/shared/contracts.d.ts.map +1 -1
- package/lib/types/shared/kimi-code-contracts.d.ts +2 -1
- package/lib/types/shared/kimi-code-contracts.d.ts.map +1 -1
- package/lib/types/shared/model-catalog.d.ts +6 -4
- package/lib/types/shared/model-catalog.d.ts.map +1 -1
- package/lib/types/shared/preferences.d.ts.map +1 -1
- package/lib/types/shared/workbuddy-contracts.d.ts +42 -1
- package/lib/types/shared/workbuddy-contracts.d.ts.map +1 -1
- package/lib/types/shared/zhipu-contracts.d.ts +156 -0
- package/lib/types/shared/zhipu-contracts.d.ts.map +1 -0
- package/package.json +31 -31
package/lib/client.js
CHANGED
|
@@ -56,7 +56,7 @@ window.__ModuleLoader__.load({
|
|
|
56
56
|
//#endregion
|
|
57
57
|
//#region src/client/CodexComposerQuota.tsx
|
|
58
58
|
function CodexComposerQuota({ api, directory, loadModelDirectory, t }) {
|
|
59
|
-
const modelState = useStore$
|
|
59
|
+
const modelState = useStore$5(directory);
|
|
60
60
|
const [status, setStatus] = (0, react.useState)(null);
|
|
61
61
|
const [loading, setLoading] = (0, react.useState)(false);
|
|
62
62
|
const mountedRef = (0, react.useRef)(false);
|
|
@@ -103,7 +103,7 @@ window.__ModuleLoader__.load({
|
|
|
103
103
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("quickQuotaLabel") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: quota === null ? loading ? t("quickQuotaLoading") : "—" : formatPercent$1(quota.remainingPercent) })]
|
|
104
104
|
});
|
|
105
105
|
}
|
|
106
|
-
function useStore$
|
|
106
|
+
function useStore$5(store) {
|
|
107
107
|
return (0, react.useSyncExternalStore)((listener) => store.subscribe(listener), () => store.getSnapshot(), () => store.getSnapshot());
|
|
108
108
|
}
|
|
109
109
|
function formatPercent$1(value) {
|
|
@@ -179,7 +179,7 @@ window.__ModuleLoader__.load({
|
|
|
179
179
|
});
|
|
180
180
|
}
|
|
181
181
|
function promptFromBlock(block) {
|
|
182
|
-
const raw = "kind" in block ? block.call?.argsRaw : block
|
|
182
|
+
const raw = "kind" in block ? block.call?.argsRaw : dispatchedArgsRaw(block);
|
|
183
183
|
if (typeof raw !== "string" || raw.trim() === "") return null;
|
|
184
184
|
try {
|
|
185
185
|
const value = JSON.parse(raw);
|
|
@@ -188,6 +188,16 @@ window.__ModuleLoader__.load({
|
|
|
188
188
|
return null;
|
|
189
189
|
}
|
|
190
190
|
}
|
|
191
|
+
/**
|
|
192
|
+
* Arguments of a dispatched call that has no result yet.
|
|
193
|
+
*
|
|
194
|
+
* Harness 0.1.7-rc.1 dispatches a view as soon as its call starts *preparing*,
|
|
195
|
+
* before the arguments exist, so the preparing shape carries no `argsRaw` at
|
|
196
|
+
* all. Older generations only ever sent the dispatched shape.
|
|
197
|
+
*/
|
|
198
|
+
function dispatchedArgsRaw(block) {
|
|
199
|
+
return "argsRaw" in block ? block.argsRaw : void 0;
|
|
200
|
+
}
|
|
191
201
|
function imageBlocks(blocks) {
|
|
192
202
|
const result = [];
|
|
193
203
|
for (const block of blocks) {
|
|
@@ -316,14 +326,11 @@ window.__ModuleLoader__.load({
|
|
|
316
326
|
"gpt-5.6-luna"
|
|
317
327
|
];
|
|
318
328
|
const DEFAULT_CODEX_MODEL = CODEX_MODEL_CATALOG[0];
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
"gpt-5.6-terra",
|
|
325
|
-
"gpt-5.6-luna"
|
|
326
|
-
];
|
|
329
|
+
/**
|
|
330
|
+
* Upper bound for one model's context window override. The Codex subscription
|
|
331
|
+
* caps the whole GPT-6 family at 872K and everything older at 1M, so a model's
|
|
332
|
+
* catalog default is where the number starts, not where it has to stay.
|
|
333
|
+
*/
|
|
327
334
|
function contextWindowLimitForModel(model) {
|
|
328
335
|
return resolveCodexCatalogEntry(model).reasoningProfile === "gpt-6" ? GPT_6_MAX_CONTEXT_WINDOW : GPT_56_MAX_CONTEXT_WINDOW;
|
|
329
336
|
}
|
|
@@ -837,6 +844,22 @@ window.__ModuleLoader__.load({
|
|
|
837
844
|
[model]: String(parsed)
|
|
838
845
|
}));
|
|
839
846
|
};
|
|
847
|
+
/** Drop one model's override; the row falls back to the catalog value. */
|
|
848
|
+
const resetContextWindow = async (model) => {
|
|
849
|
+
await updatePreferences({ contextWindowOverrides: { [model]: null } });
|
|
850
|
+
setContextDrafts((drafts) => ({
|
|
851
|
+
...drafts,
|
|
852
|
+
[model]: formatCapacity$5(resolveCodexCatalogEntry(model).contextWindow)
|
|
853
|
+
}));
|
|
854
|
+
};
|
|
855
|
+
/** Clear every stored override, including models the picker no longer shows. */
|
|
856
|
+
const resetAllContextWindows = async () => {
|
|
857
|
+
const models = Object.keys(status?.preferences.contextWindowOverrides ?? {});
|
|
858
|
+
if (models.length === 0) return;
|
|
859
|
+
if (!window.confirm(t("contextWindowResetAllConfirm"))) return;
|
|
860
|
+
await updatePreferences({ contextWindowOverrides: Object.fromEntries(models.map((model) => [model, null])) });
|
|
861
|
+
setContextDrafts({});
|
|
862
|
+
};
|
|
840
863
|
const updateCustomProxyUrl = async () => {
|
|
841
864
|
const draft = customProxyDraft?.trim();
|
|
842
865
|
await updatePreferences({ customProxyUrl: draft ? draft : null });
|
|
@@ -925,6 +948,8 @@ window.__ModuleLoader__.load({
|
|
|
925
948
|
const storage = status?.storage;
|
|
926
949
|
const login = status?.login;
|
|
927
950
|
const visibleModelIds = preferences?.visibleModelIds ?? DEFAULT_VISIBLE_CODEX_MODEL_IDS;
|
|
951
|
+
const contextModels = CODEX_MODEL_CATALOG.filter((entry) => visibleModelIds.some((id) => id === entry.id));
|
|
952
|
+
const overrideCount = Object.keys(preferences?.contextWindowOverrides ?? {}).length;
|
|
928
953
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
929
954
|
className: "dsha-page",
|
|
930
955
|
"aria-labelledby": "dsh-codex-title",
|
|
@@ -1038,7 +1063,7 @@ window.__ModuleLoader__.load({
|
|
|
1038
1063
|
}),
|
|
1039
1064
|
connection !== null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(InfoRow, {
|
|
1040
1065
|
label: t("latency"),
|
|
1041
|
-
value: `${connection.latencyMs} ms · ${formatDate$
|
|
1066
|
+
value: `${connection.latencyMs} ms · ${formatDate$4(connection.checkedAt)}`
|
|
1042
1067
|
}) : null,
|
|
1043
1068
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1044
1069
|
className: "dsha-muted dsha-models-hint",
|
|
@@ -1289,58 +1314,83 @@ window.__ModuleLoader__.load({
|
|
|
1289
1314
|
}),
|
|
1290
1315
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1291
1316
|
className: "dsha-context-settings",
|
|
1292
|
-
children: [
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1317
|
+
children: [
|
|
1318
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t("contextWindows") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1319
|
+
className: "dsha-muted",
|
|
1320
|
+
children: t("contextWindowsHint")
|
|
1321
|
+
})] }),
|
|
1322
|
+
contextModels.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1323
|
+
className: "dsha-muted",
|
|
1324
|
+
children: t("contextWindowsNoneEnabled")
|
|
1325
|
+
}) : null,
|
|
1326
|
+
contextModels.map((entry) => {
|
|
1327
|
+
const model = entry.id;
|
|
1328
|
+
const fallback = preferences?.contextWindowOverrides?.[model] ?? entry.contextWindow;
|
|
1329
|
+
const draft = contextDrafts[model];
|
|
1330
|
+
const parsedDraft = draft === void 0 ? fallback : parseCapacity(draft, contextWindowLimitForModel(model));
|
|
1331
|
+
const dirty = draft !== void 0 && parsedDraft !== fallback;
|
|
1332
|
+
const overridden = preferences?.contextWindowOverrides?.[model] !== void 0;
|
|
1333
|
+
const inputId = `dsh-codex-context-${model}`;
|
|
1334
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1335
|
+
className: "dsha-context-row",
|
|
1336
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
1337
|
+
htmlFor: inputId,
|
|
1338
|
+
children: entry.name
|
|
1339
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1340
|
+
className: "dsha-capacity-control",
|
|
1341
|
+
children: [
|
|
1342
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
1343
|
+
id: inputId,
|
|
1344
|
+
type: "text",
|
|
1345
|
+
inputMode: "numeric",
|
|
1346
|
+
value: draft ?? formatCapacity$5(fallback),
|
|
1347
|
+
disabled: busy !== null,
|
|
1348
|
+
"aria-label": entry.name + " " + t("contextWindow"),
|
|
1349
|
+
onChange: (event) => {
|
|
1350
|
+
const value = event.currentTarget.value;
|
|
1351
|
+
setContextDrafts((drafts) => ({
|
|
1352
|
+
...drafts,
|
|
1353
|
+
[model]: value
|
|
1354
|
+
}));
|
|
1355
|
+
},
|
|
1356
|
+
onKeyDown: (event) => {
|
|
1357
|
+
if (event.key !== "Enter" || !dirty) return;
|
|
1358
|
+
event.preventDefault();
|
|
1359
|
+
updateContextWindow(model);
|
|
1360
|
+
}
|
|
1361
|
+
}),
|
|
1362
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: t("tokens") }),
|
|
1363
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1364
|
+
className: "dsha-context-save",
|
|
1365
|
+
type: "button",
|
|
1366
|
+
"data-model": model,
|
|
1367
|
+
"aria-label": entry.name + " " + t("saveContextWindow"),
|
|
1368
|
+
disabled: busy !== null || !dirty,
|
|
1369
|
+
onClick: () => void updateContextWindow(model),
|
|
1370
|
+
children: t("save")
|
|
1371
|
+
}),
|
|
1372
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1373
|
+
className: "dsha-context-save dsha-context-reset",
|
|
1374
|
+
type: "button",
|
|
1375
|
+
"data-reset-model": model,
|
|
1376
|
+
"aria-label": entry.name + " " + t("contextWindowReset"),
|
|
1377
|
+
disabled: busy !== null || !overridden,
|
|
1378
|
+
onClick: () => void resetContextWindow(model),
|
|
1379
|
+
children: t("contextWindowReset")
|
|
1380
|
+
})
|
|
1381
|
+
]
|
|
1382
|
+
})]
|
|
1383
|
+
}, model);
|
|
1384
|
+
}),
|
|
1385
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1386
|
+
className: "dsha-actions",
|
|
1387
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
|
|
1388
|
+
disabled: busy !== null || overrideCount === 0,
|
|
1389
|
+
onClick: resetAllContextWindows,
|
|
1390
|
+
children: t("contextWindowResetAll")
|
|
1391
|
+
})
|
|
1392
|
+
})
|
|
1393
|
+
]
|
|
1344
1394
|
}),
|
|
1345
1395
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
1346
1396
|
className: "dsh-codex-check",
|
|
@@ -1425,7 +1475,7 @@ window.__ModuleLoader__.load({
|
|
|
1425
1475
|
children: [
|
|
1426
1476
|
t("updated"),
|
|
1427
1477
|
": ",
|
|
1428
|
-
formatDate$
|
|
1478
|
+
formatDate$4(quota.fetchedAt)
|
|
1429
1479
|
]
|
|
1430
1480
|
}) : null
|
|
1431
1481
|
]
|
|
@@ -1517,7 +1567,7 @@ window.__ModuleLoader__.load({
|
|
|
1517
1567
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("small", { children: [
|
|
1518
1568
|
t("resetCreditExpires"),
|
|
1519
1569
|
": ",
|
|
1520
|
-
resetCredits.expiresAt == null ? t("unknown") : formatReset$
|
|
1570
|
+
resetCredits.expiresAt == null ? t("unknown") : formatReset$4(resetCredits.expiresAt)
|
|
1521
1571
|
] })
|
|
1522
1572
|
]
|
|
1523
1573
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
|
|
@@ -1550,7 +1600,7 @@ window.__ModuleLoader__.load({
|
|
|
1550
1600
|
}),
|
|
1551
1601
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1552
1602
|
className: "dsh-codex-meter-meta",
|
|
1553
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: percent >= 100 ? `${t("exhausted")} · ${formatPercent(remaining)} ${t("remaining")}` : `${formatPercent(percent)} ${t("used")} · ${formatPercent(remaining)} ${t("remaining")}` }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: window?.resetsAt == null ? "—" : `${t("resets")}: ${formatReset$
|
|
1603
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: percent >= 100 ? `${t("exhausted")} · ${formatPercent(remaining)} ${t("remaining")}` : `${formatPercent(percent)} ${t("used")} · ${formatPercent(remaining)} ${t("remaining")}` }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: window?.resetsAt == null ? "—" : `${t("resets")}: ${formatReset$4(window.resetsAt)}` })]
|
|
1554
1604
|
})
|
|
1555
1605
|
]
|
|
1556
1606
|
});
|
|
@@ -1576,7 +1626,7 @@ window.__ModuleLoader__.load({
|
|
|
1576
1626
|
return `${value} ${t("limitWindow")}`;
|
|
1577
1627
|
}
|
|
1578
1628
|
}
|
|
1579
|
-
function parsePositiveCapacity$
|
|
1629
|
+
function parsePositiveCapacity$5(value) {
|
|
1580
1630
|
const matched = value.trim().toLowerCase().replace(/[,_\s]/g, "").match(/^(\d+(?:\.\d+)?)(k|m)?$/);
|
|
1581
1631
|
if (matched === null) return null;
|
|
1582
1632
|
const multiplier = matched[2] === "m" ? 1e6 : matched[2] === "k" ? 1e3 : 1;
|
|
@@ -1584,10 +1634,10 @@ window.__ModuleLoader__.load({
|
|
|
1584
1634
|
return Number.isSafeInteger(parsed) && parsed >= 1 ? parsed : null;
|
|
1585
1635
|
}
|
|
1586
1636
|
function parseCapacity(value, maxContextWindow = GPT_56_MAX_CONTEXT_WINDOW) {
|
|
1587
|
-
const parsed = parsePositiveCapacity$
|
|
1637
|
+
const parsed = parsePositiveCapacity$5(value);
|
|
1588
1638
|
return parsed !== null && parsed <= maxContextWindow ? parsed : null;
|
|
1589
1639
|
}
|
|
1590
|
-
function formatCapacity$
|
|
1640
|
+
function formatCapacity$5(value) {
|
|
1591
1641
|
if (value % 1e3 === 0) return `${value / 1e3}K`;
|
|
1592
1642
|
return String(value);
|
|
1593
1643
|
}
|
|
@@ -1604,11 +1654,11 @@ window.__ModuleLoader__.load({
|
|
|
1604
1654
|
limit.remainingPercent !== null && limit.remainingPercent !== void 0 ? `${formatPercent(limit.remainingPercent)} ${t("remaining")}` : null,
|
|
1605
1655
|
limit.limit !== null && limit.limit !== void 0 ? `${t("limit")}: ${limit.limit}` : null,
|
|
1606
1656
|
limit.used !== null && limit.used !== void 0 ? `${t("used")}: ${limit.used}` : null,
|
|
1607
|
-
limit.resetsAt !== null && limit.resetsAt !== void 0 ? `${t("resets")}: ${formatReset$
|
|
1657
|
+
limit.resetsAt !== null && limit.resetsAt !== void 0 ? `${t("resets")}: ${formatReset$4(limit.resetsAt)}` : null
|
|
1608
1658
|
].filter((part) => part !== null);
|
|
1609
1659
|
return parts.length > 0 ? parts.join(" · ") : t("unknown");
|
|
1610
1660
|
}
|
|
1611
|
-
function formatDate$
|
|
1661
|
+
function formatDate$4(seconds) {
|
|
1612
1662
|
if (seconds === void 0 || seconds === null || typeof seconds !== "number" || !Number.isFinite(seconds) || seconds <= 0) return "—";
|
|
1613
1663
|
const ms = seconds > 1e10 ? seconds : seconds * 1e3;
|
|
1614
1664
|
try {
|
|
@@ -1620,10 +1670,10 @@ window.__ModuleLoader__.load({
|
|
|
1620
1670
|
return "—";
|
|
1621
1671
|
}
|
|
1622
1672
|
}
|
|
1623
|
-
function formatReset$
|
|
1673
|
+
function formatReset$4(seconds) {
|
|
1624
1674
|
if (seconds === void 0 || seconds === null || typeof seconds !== "number" || !Number.isFinite(seconds) || seconds <= 0) return "—";
|
|
1625
1675
|
const ms = seconds > 1e10 ? seconds : seconds * 1e3;
|
|
1626
|
-
const absolute = formatDate$
|
|
1676
|
+
const absolute = formatDate$4(seconds);
|
|
1627
1677
|
const diff = ms - Date.now();
|
|
1628
1678
|
const abs = Math.abs(diff);
|
|
1629
1679
|
const [amount, unit] = abs >= 864e5 ? [Math.round(diff / 864e5), "day"] : abs >= 36e5 ? [Math.round(diff / 36e5), "hour"] : [Math.round(diff / 6e4), "minute"];
|
|
@@ -1639,7 +1689,7 @@ window.__ModuleLoader__.load({
|
|
|
1639
1689
|
//#endregion
|
|
1640
1690
|
//#region src/client/antigravity/locales.ts
|
|
1641
1691
|
const NS_ANTIGRAVITY = "dsh-antigravity";
|
|
1642
|
-
const zh$
|
|
1692
|
+
const zh$5 = {
|
|
1643
1693
|
...accountPoolZh,
|
|
1644
1694
|
title: "Antigravity",
|
|
1645
1695
|
pageDesc: "登录 Google Antigravity / Cloud Code Assist,并查看当前账号的共享额度。",
|
|
@@ -1685,6 +1735,10 @@ window.__ModuleLoader__.load({
|
|
|
1685
1735
|
defaultEffortAuto: "使用 Provider 默认值",
|
|
1686
1736
|
contextWindowSection: "模型上下文窗口",
|
|
1687
1737
|
contextWindowHint: "默认按模型标准;可选应用最高容量,该值用于 DSH 的压缩与溢出判断,可输入 1M、512K、200K 等容量。",
|
|
1738
|
+
contextWindowReset: "恢复默认",
|
|
1739
|
+
contextWindowResetAll: "全部恢复默认",
|
|
1740
|
+
contextWindowResetAllConfirm: "确定把已改过的模型上下文窗口全部恢复为默认值吗?",
|
|
1741
|
+
contextWindowNoneEnabled: "还没有勾选任何模型。在上方勾选后,这里会出现该模型的上下文窗口设置。",
|
|
1688
1742
|
save: "保存",
|
|
1689
1743
|
saved: "已保存",
|
|
1690
1744
|
saving: "保存中...",
|
|
@@ -1705,7 +1759,7 @@ window.__ModuleLoader__.load({
|
|
|
1705
1759
|
loginFailed: "登录失败",
|
|
1706
1760
|
tokens: "tokens"
|
|
1707
1761
|
};
|
|
1708
|
-
const en$
|
|
1762
|
+
const en$5 = {
|
|
1709
1763
|
...accountPoolEn,
|
|
1710
1764
|
title: "Antigravity",
|
|
1711
1765
|
pageDesc: "Sign in to Google Antigravity / Cloud Code Assist and view shared quotas.",
|
|
@@ -1751,6 +1805,10 @@ window.__ModuleLoader__.load({
|
|
|
1751
1805
|
defaultEffortAuto: "Use Provider default",
|
|
1752
1806
|
contextWindowSection: "Model Context Window",
|
|
1753
1807
|
contextWindowHint: "Defaults to model specification; configure custom capacity used by DSH for compaction and overflow judgments (e.g., 1M, 512K, 200K).",
|
|
1808
|
+
contextWindowReset: "Restore default",
|
|
1809
|
+
contextWindowResetAll: "Restore all defaults",
|
|
1810
|
+
contextWindowResetAllConfirm: "Restore every changed model context window to its default?",
|
|
1811
|
+
contextWindowNoneEnabled: "No model is checked yet. Check one above and its context window setting appears here.",
|
|
1754
1812
|
save: "Save",
|
|
1755
1813
|
saved: "Saved",
|
|
1756
1814
|
saving: "Saving...",
|
|
@@ -1771,17 +1829,17 @@ window.__ModuleLoader__.load({
|
|
|
1771
1829
|
loginFailed: "Login failed",
|
|
1772
1830
|
tokens: "tokens"
|
|
1773
1831
|
};
|
|
1774
|
-
const dictionaries$
|
|
1775
|
-
zh: zh$
|
|
1776
|
-
"zh-CN": zh$
|
|
1777
|
-
en: en$
|
|
1778
|
-
"en-US": en$
|
|
1832
|
+
const dictionaries$5 = {
|
|
1833
|
+
zh: zh$5,
|
|
1834
|
+
"zh-CN": zh$5,
|
|
1835
|
+
en: en$5,
|
|
1836
|
+
"en-US": en$5
|
|
1779
1837
|
};
|
|
1780
1838
|
//#endregion
|
|
1781
1839
|
//#region src/client/antigravity/AntigravitySection.tsx
|
|
1782
|
-
const API$
|
|
1783
|
-
async function fetchApi$
|
|
1784
|
-
const res = await fetch(`${API$
|
|
1840
|
+
const API$9 = "/antigravity/api";
|
|
1841
|
+
async function fetchApi$9(path, options) {
|
|
1842
|
+
const res = await fetch(`${API$9}${path}`, {
|
|
1785
1843
|
...options,
|
|
1786
1844
|
headers: {
|
|
1787
1845
|
"Content-Type": "application/json",
|
|
@@ -1792,18 +1850,28 @@ window.__ModuleLoader__.load({
|
|
|
1792
1850
|
if (!res.ok || !json.ok) throw new Error(json.error || `HTTP ${res.status}`);
|
|
1793
1851
|
return json.value;
|
|
1794
1852
|
}
|
|
1795
|
-
function parsePositiveCapacity$
|
|
1853
|
+
function parsePositiveCapacity$4(value) {
|
|
1796
1854
|
const matched = value.trim().toLowerCase().replace(/[,_\s]/g, "").match(/^(\d+(?:\.\d+)?)(k|m)?$/);
|
|
1797
1855
|
if (matched === null) return null;
|
|
1798
1856
|
const multiplier = matched[2] === "m" ? 1e6 : matched[2] === "k" ? 1e3 : 1;
|
|
1799
1857
|
const parsed = Number(matched[1]) * multiplier;
|
|
1800
1858
|
return Number.isSafeInteger(parsed) && parsed >= 1 ? parsed : null;
|
|
1801
1859
|
}
|
|
1802
|
-
function formatCapacity$
|
|
1860
|
+
function formatCapacity$4(value) {
|
|
1803
1861
|
if (value >= 1e6 && value % 1e5 === 0) return `${value / 1e6}M`;
|
|
1804
1862
|
if (value % 1e3 === 0) return `${value / 1e3}K`;
|
|
1805
1863
|
return String(value);
|
|
1806
1864
|
}
|
|
1865
|
+
/**
|
|
1866
|
+
* Seed one draft per model from a status payload. Also run after a model
|
|
1867
|
+
* toggle: a model that was just enabled has no draft yet, and the context
|
|
1868
|
+
* window section only renders enabled models.
|
|
1869
|
+
*/
|
|
1870
|
+
function contextDraftsFor$4(status) {
|
|
1871
|
+
const drafts = {};
|
|
1872
|
+
for (const model of status.models) drafts[model.id] = formatCapacity$4(status.contextWindowOverrides[model.id] || model.defaultContextWindow);
|
|
1873
|
+
return drafts;
|
|
1874
|
+
}
|
|
1807
1875
|
function formatResetTime(resetTime) {
|
|
1808
1876
|
if (!resetTime) return "";
|
|
1809
1877
|
const diff = new Date(resetTime).getTime() - Date.now();
|
|
@@ -1815,7 +1883,7 @@ window.__ModuleLoader__.load({
|
|
|
1815
1883
|
if (hours > 0) return `${hours}h ${mins % 60}m`;
|
|
1816
1884
|
return `${mins}m`;
|
|
1817
1885
|
}
|
|
1818
|
-
function formatDate$
|
|
1886
|
+
function formatDate$3(ms) {
|
|
1819
1887
|
if (!ms || ms <= 0) return "—";
|
|
1820
1888
|
try {
|
|
1821
1889
|
return new Intl.DateTimeFormat(void 0, {
|
|
@@ -1835,7 +1903,7 @@ window.__ModuleLoader__.load({
|
|
|
1835
1903
|
const [loginProgress, setLoginProgress] = (0, react.useState)(null);
|
|
1836
1904
|
const [contextDrafts, setContextDrafts] = (0, react.useState)({});
|
|
1837
1905
|
const [savingModel, setSavingModel] = (0, react.useState)(null);
|
|
1838
|
-
const t = zh$
|
|
1906
|
+
const t = zh$5;
|
|
1839
1907
|
const notifyChange = (0, react.useCallback)(() => {
|
|
1840
1908
|
onModelChange?.();
|
|
1841
1909
|
loadModelDirectory?.();
|
|
@@ -1846,14 +1914,9 @@ window.__ModuleLoader__.load({
|
|
|
1846
1914
|
setValidationUrl(null);
|
|
1847
1915
|
}
|
|
1848
1916
|
try {
|
|
1849
|
-
const data = await fetchApi$
|
|
1917
|
+
const data = await fetchApi$9("/status");
|
|
1850
1918
|
setStatus(data);
|
|
1851
|
-
|
|
1852
|
-
for (const m of data.models) {
|
|
1853
|
-
const val = data.contextWindowOverrides[m.id] || m.defaultContextWindow;
|
|
1854
|
-
drafts[m.id] = formatCapacity$3(val);
|
|
1855
|
-
}
|
|
1856
|
-
setContextDrafts(drafts);
|
|
1919
|
+
setContextDrafts(contextDraftsFor$4(data));
|
|
1857
1920
|
} catch (err) {
|
|
1858
1921
|
if (!quiet) setError(err instanceof Error ? err.message : String(err));
|
|
1859
1922
|
} finally {
|
|
@@ -1878,11 +1941,11 @@ window.__ModuleLoader__.load({
|
|
|
1878
1941
|
setError(null);
|
|
1879
1942
|
setValidationUrl(null);
|
|
1880
1943
|
setLoginProgress(null);
|
|
1881
|
-
const flow = await fetchApi$
|
|
1944
|
+
const flow = await fetchApi$9("/login", { method: "POST" });
|
|
1882
1945
|
if (flow.authUrl) window.open(flow.authUrl, "_blank");
|
|
1883
1946
|
const pollTimer = setInterval(async () => {
|
|
1884
1947
|
try {
|
|
1885
|
-
const pollStatus = await fetchApi$
|
|
1948
|
+
const pollStatus = await fetchApi$9("/login/status");
|
|
1886
1949
|
if (pollStatus.progress) setLoginProgress(pollStatus.progress);
|
|
1887
1950
|
if (pollStatus.status === "complete") {
|
|
1888
1951
|
clearInterval(pollTimer);
|
|
@@ -1914,7 +1977,7 @@ window.__ModuleLoader__.load({
|
|
|
1914
1977
|
try {
|
|
1915
1978
|
setBusy("quota");
|
|
1916
1979
|
setError(null);
|
|
1917
|
-
const updated = await fetchApi$
|
|
1980
|
+
const updated = await fetchApi$9("/quota", { method: "POST" });
|
|
1918
1981
|
setStatus(updated);
|
|
1919
1982
|
} catch (err) {
|
|
1920
1983
|
setError(err instanceof Error ? err.message : String(err));
|
|
@@ -1926,7 +1989,7 @@ window.__ModuleLoader__.load({
|
|
|
1926
1989
|
try {
|
|
1927
1990
|
setBusy(`primary-${accountId}`);
|
|
1928
1991
|
setError(null);
|
|
1929
|
-
const updated = await fetchApi$
|
|
1992
|
+
const updated = await fetchApi$9("/accounts", {
|
|
1930
1993
|
method: "POST",
|
|
1931
1994
|
body: JSON.stringify({
|
|
1932
1995
|
action: "set-primary",
|
|
@@ -1945,7 +2008,7 @@ window.__ModuleLoader__.load({
|
|
|
1945
2008
|
try {
|
|
1946
2009
|
setBusy(`delete-${accountId}`);
|
|
1947
2010
|
setError(null);
|
|
1948
|
-
const updated = await fetchApi$
|
|
2011
|
+
const updated = await fetchApi$9("/accounts", {
|
|
1949
2012
|
method: "POST",
|
|
1950
2013
|
body: JSON.stringify({
|
|
1951
2014
|
action: "delete",
|
|
@@ -1964,7 +2027,7 @@ window.__ModuleLoader__.load({
|
|
|
1964
2027
|
try {
|
|
1965
2028
|
setBusy(`cooldown-${accountId}`);
|
|
1966
2029
|
setError(null);
|
|
1967
|
-
const updated = await fetchApi$
|
|
2030
|
+
const updated = await fetchApi$9("/accounts", {
|
|
1968
2031
|
method: "POST",
|
|
1969
2032
|
body: JSON.stringify({
|
|
1970
2033
|
action: "clear-cooldown",
|
|
@@ -1982,7 +2045,7 @@ window.__ModuleLoader__.load({
|
|
|
1982
2045
|
try {
|
|
1983
2046
|
setBusy("strategy");
|
|
1984
2047
|
setError(null);
|
|
1985
|
-
const updated = await fetchApi$
|
|
2048
|
+
const updated = await fetchApi$9("/accounts", {
|
|
1986
2049
|
method: "POST",
|
|
1987
2050
|
body: JSON.stringify({
|
|
1988
2051
|
action: "strategy",
|
|
@@ -2002,7 +2065,7 @@ window.__ModuleLoader__.load({
|
|
|
2002
2065
|
enabled
|
|
2003
2066
|
} : prev);
|
|
2004
2067
|
try {
|
|
2005
|
-
const updated = await fetchApi$
|
|
2068
|
+
const updated = await fetchApi$9("/settings", {
|
|
2006
2069
|
method: "POST",
|
|
2007
2070
|
body: JSON.stringify({ enabled })
|
|
2008
2071
|
});
|
|
@@ -2018,11 +2081,12 @@ window.__ModuleLoader__.load({
|
|
|
2018
2081
|
const currentEnabled = status.models.filter((m) => m.enabled).map((m) => m.id);
|
|
2019
2082
|
const nextEnabled = checked ? [.../* @__PURE__ */ new Set([...currentEnabled, modelId])] : currentEnabled.filter((id) => id !== modelId);
|
|
2020
2083
|
try {
|
|
2021
|
-
const updated = await fetchApi$
|
|
2084
|
+
const updated = await fetchApi$9("/models", {
|
|
2022
2085
|
method: "POST",
|
|
2023
2086
|
body: JSON.stringify({ enabledModelIds: nextEnabled })
|
|
2024
2087
|
});
|
|
2025
2088
|
setStatus(updated);
|
|
2089
|
+
setContextDrafts(contextDraftsFor$4(updated));
|
|
2026
2090
|
notifyChange();
|
|
2027
2091
|
} catch (err) {
|
|
2028
2092
|
setError(err instanceof Error ? err.message : String(err));
|
|
@@ -2032,11 +2096,12 @@ window.__ModuleLoader__.load({
|
|
|
2032
2096
|
if (!status) return;
|
|
2033
2097
|
const nextEnabled = selectAll ? status.models.map((m) => m.id) : [];
|
|
2034
2098
|
try {
|
|
2035
|
-
const updated = await fetchApi$
|
|
2099
|
+
const updated = await fetchApi$9("/models", {
|
|
2036
2100
|
method: "POST",
|
|
2037
2101
|
body: JSON.stringify({ enabledModelIds: nextEnabled })
|
|
2038
2102
|
});
|
|
2039
2103
|
setStatus(updated);
|
|
2104
|
+
setContextDrafts(contextDraftsFor$4(updated));
|
|
2040
2105
|
notifyChange();
|
|
2041
2106
|
} catch (err) {
|
|
2042
2107
|
setError(err instanceof Error ? err.message : String(err));
|
|
@@ -2044,7 +2109,7 @@ window.__ModuleLoader__.load({
|
|
|
2044
2109
|
};
|
|
2045
2110
|
const handleUpdateEffort = async (effort) => {
|
|
2046
2111
|
try {
|
|
2047
|
-
const updated = await fetchApi$
|
|
2112
|
+
const updated = await fetchApi$9("/settings", {
|
|
2048
2113
|
method: "POST",
|
|
2049
2114
|
body: JSON.stringify({ defaultReasoningEffort: effort })
|
|
2050
2115
|
});
|
|
@@ -2056,7 +2121,7 @@ window.__ModuleLoader__.load({
|
|
|
2056
2121
|
};
|
|
2057
2122
|
const handleSaveContextWindow = async (modelId) => {
|
|
2058
2123
|
const raw = contextDrafts[modelId] || "";
|
|
2059
|
-
const parsed = parsePositiveCapacity$
|
|
2124
|
+
const parsed = parsePositiveCapacity$4(raw);
|
|
2060
2125
|
if (parsed === null) {
|
|
2061
2126
|
setError(`无效的上下文容量值: ${raw}`);
|
|
2062
2127
|
return;
|
|
@@ -2064,14 +2129,14 @@ window.__ModuleLoader__.load({
|
|
|
2064
2129
|
try {
|
|
2065
2130
|
setSavingModel(modelId);
|
|
2066
2131
|
setError(null);
|
|
2067
|
-
const updated = await fetchApi$
|
|
2132
|
+
const updated = await fetchApi$9("/settings", {
|
|
2068
2133
|
method: "POST",
|
|
2069
2134
|
body: JSON.stringify({ contextWindowOverrides: { [modelId]: parsed } })
|
|
2070
2135
|
});
|
|
2071
2136
|
setStatus(updated);
|
|
2072
2137
|
setContextDrafts((prev) => ({
|
|
2073
2138
|
...prev,
|
|
2074
|
-
[modelId]: formatCapacity$
|
|
2139
|
+
[modelId]: formatCapacity$4(parsed)
|
|
2075
2140
|
}));
|
|
2076
2141
|
notifyChange();
|
|
2077
2142
|
} catch (err) {
|
|
@@ -2080,6 +2145,53 @@ window.__ModuleLoader__.load({
|
|
|
2080
2145
|
setSavingModel(null);
|
|
2081
2146
|
}
|
|
2082
2147
|
};
|
|
2148
|
+
/** Clear one override; the row falls back to the catalog length. */
|
|
2149
|
+
const handleResetContextWindow = async (modelId) => {
|
|
2150
|
+
try {
|
|
2151
|
+
setSavingModel(modelId);
|
|
2152
|
+
setError(null);
|
|
2153
|
+
const updated = await fetchApi$9("/settings", {
|
|
2154
|
+
method: "POST",
|
|
2155
|
+
body: JSON.stringify({ contextWindowOverrides: { [modelId]: null } })
|
|
2156
|
+
});
|
|
2157
|
+
setStatus(updated);
|
|
2158
|
+
setContextDrafts((prev) => {
|
|
2159
|
+
const model = updated.models.find((candidate) => candidate.id === modelId);
|
|
2160
|
+
return model === void 0 ? prev : {
|
|
2161
|
+
...prev,
|
|
2162
|
+
[modelId]: formatCapacity$4(model.defaultContextWindow)
|
|
2163
|
+
};
|
|
2164
|
+
});
|
|
2165
|
+
notifyChange();
|
|
2166
|
+
} catch (err) {
|
|
2167
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
2168
|
+
} finally {
|
|
2169
|
+
setSavingModel(null);
|
|
2170
|
+
}
|
|
2171
|
+
};
|
|
2172
|
+
/** Clear every stored override, including models the picker no longer shows. */
|
|
2173
|
+
const handleResetAllContextWindows = async () => {
|
|
2174
|
+
const models = Object.keys(status?.contextWindowOverrides ?? {});
|
|
2175
|
+
if (models.length === 0) return;
|
|
2176
|
+
if (typeof window !== "undefined" && !window.confirm(t.contextWindowResetAllConfirm)) return;
|
|
2177
|
+
try {
|
|
2178
|
+
setBusy("context");
|
|
2179
|
+
setError(null);
|
|
2180
|
+
const updated = await fetchApi$9("/settings", {
|
|
2181
|
+
method: "POST",
|
|
2182
|
+
body: JSON.stringify({ contextWindowOverrides: Object.fromEntries(models.map((model) => [model, null])) })
|
|
2183
|
+
});
|
|
2184
|
+
setStatus(updated);
|
|
2185
|
+
setContextDrafts(contextDraftsFor$4(updated));
|
|
2186
|
+
notifyChange();
|
|
2187
|
+
} catch (err) {
|
|
2188
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
2189
|
+
} finally {
|
|
2190
|
+
setBusy(null);
|
|
2191
|
+
}
|
|
2192
|
+
};
|
|
2193
|
+
const contextModels = status?.models.filter((model) => model.enabled) ?? [];
|
|
2194
|
+
const overrideCount = Object.keys(status?.contextWindowOverrides ?? {}).length;
|
|
2083
2195
|
if (loading) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2084
2196
|
className: "dsha-page",
|
|
2085
2197
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
@@ -2119,12 +2231,12 @@ window.__ModuleLoader__.load({
|
|
|
2119
2231
|
account.expiresAt && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
|
|
2120
2232
|
t.expires,
|
|
2121
2233
|
": ",
|
|
2122
|
-
formatDate$
|
|
2234
|
+
formatDate$3(account.expiresAt)
|
|
2123
2235
|
] }),
|
|
2124
2236
|
account.lastUsedAt && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
|
|
2125
2237
|
t.lastUsed,
|
|
2126
2238
|
": ",
|
|
2127
|
-
formatDate$
|
|
2239
|
+
formatDate$3(account.lastUsedAt)
|
|
2128
2240
|
] })
|
|
2129
2241
|
] })
|
|
2130
2242
|
}),
|
|
@@ -2256,35 +2368,58 @@ window.__ModuleLoader__.load({
|
|
|
2256
2368
|
className: "dsha-muted",
|
|
2257
2369
|
children: t.contextWindowHint
|
|
2258
2370
|
}),
|
|
2259
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
2371
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2260
2372
|
className: "dsha-context-settings",
|
|
2261
|
-
children:
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2373
|
+
children: [
|
|
2374
|
+
contextModels.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2375
|
+
className: "dsha-muted",
|
|
2376
|
+
children: t.contextWindowNoneEnabled
|
|
2377
|
+
}),
|
|
2378
|
+
contextModels.map((model) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2379
|
+
className: "dsha-context-row",
|
|
2380
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: model.name }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2381
|
+
className: "dsha-capacity-control",
|
|
2382
|
+
children: [
|
|
2383
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
2384
|
+
type: "text",
|
|
2385
|
+
value: contextDrafts[model.id] ?? "",
|
|
2386
|
+
onChange: (e) => setContextDrafts({
|
|
2387
|
+
...contextDrafts,
|
|
2388
|
+
[model.id]: e.target.value
|
|
2389
|
+
}),
|
|
2390
|
+
onKeyDown: (e) => {
|
|
2391
|
+
if (e.key === "Enter") handleSaveContextWindow(model.id);
|
|
2392
|
+
}
|
|
2272
2393
|
}),
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2394
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: t.tokens }),
|
|
2395
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2396
|
+
type: "button",
|
|
2397
|
+
className: "dsha-context-save",
|
|
2398
|
+
disabled: savingModel === model.id,
|
|
2399
|
+
onClick: () => void handleSaveContextWindow(model.id),
|
|
2400
|
+
children: savingModel === model.id ? t.saving : t.save
|
|
2401
|
+
}),
|
|
2402
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2403
|
+
type: "button",
|
|
2404
|
+
className: "dsha-context-save dsha-context-reset",
|
|
2405
|
+
"aria-label": `${model.name} ${t.contextWindowReset}`,
|
|
2406
|
+
disabled: savingModel === model.id || status?.contextWindowOverrides[model.id] === void 0,
|
|
2407
|
+
onClick: () => void handleResetContextWindow(model.id),
|
|
2408
|
+
children: t.contextWindowReset
|
|
2409
|
+
})
|
|
2410
|
+
]
|
|
2411
|
+
})]
|
|
2412
|
+
}, model.id)),
|
|
2413
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2414
|
+
className: "dsha-actions",
|
|
2415
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2416
|
+
className: "dsha-btn",
|
|
2417
|
+
disabled: busy !== null || overrideCount === 0,
|
|
2418
|
+
onClick: () => void handleResetAllContextWindows(),
|
|
2419
|
+
children: t.contextWindowResetAll
|
|
2420
|
+
})
|
|
2421
|
+
})
|
|
2422
|
+
]
|
|
2288
2423
|
})
|
|
2289
2424
|
]
|
|
2290
2425
|
}),
|
|
@@ -2380,7 +2515,7 @@ window.__ModuleLoader__.load({
|
|
|
2380
2515
|
//#endregion
|
|
2381
2516
|
//#region src/client/command-code/locales.ts
|
|
2382
2517
|
const NS_COMMAND_CODE = "dsh-command-code";
|
|
2383
|
-
const zh$
|
|
2518
|
+
const zh$4 = {
|
|
2384
2519
|
...accountPoolZh,
|
|
2385
2520
|
title: "Command Code",
|
|
2386
2521
|
pageDesc: "登录 Command Code,管理可用模型、上下文窗口与额度。",
|
|
@@ -2433,6 +2568,10 @@ window.__ModuleLoader__.load({
|
|
|
2433
2568
|
defaultEffortAuto: "使用 Provider 默认值",
|
|
2434
2569
|
contextWindowSection: "模型上下文窗口",
|
|
2435
2570
|
contextWindowHint: "默认取 Command Code 模型目录的 context length;可覆盖为自定义容量,该值用于 DSH 的压缩与溢出判断,可输入 1M、512K、200K 等容量。",
|
|
2571
|
+
contextWindowReset: "恢复默认",
|
|
2572
|
+
contextWindowResetAll: "全部恢复默认",
|
|
2573
|
+
contextWindowResetAllConfirm: "确定把已改过的模型上下文窗口全部恢复为默认值吗?",
|
|
2574
|
+
contextWindowNoneEnabled: "还没有勾选任何模型。在上方勾选后,这里会出现该模型的上下文窗口设置。",
|
|
2436
2575
|
save: "保存",
|
|
2437
2576
|
saved: "已保存",
|
|
2438
2577
|
saving: "保存中...",
|
|
@@ -2448,7 +2587,7 @@ window.__ModuleLoader__.load({
|
|
|
2448
2587
|
loginFailed: "登录失败",
|
|
2449
2588
|
tokens: "tokens"
|
|
2450
2589
|
};
|
|
2451
|
-
const en$
|
|
2590
|
+
const en$4 = {
|
|
2452
2591
|
...accountPoolEn,
|
|
2453
2592
|
title: "Command Code",
|
|
2454
2593
|
pageDesc: "Sign in to Command Code and manage models, context windows, and quota.",
|
|
@@ -2501,6 +2640,10 @@ window.__ModuleLoader__.load({
|
|
|
2501
2640
|
defaultEffortAuto: "Use provider default",
|
|
2502
2641
|
contextWindowSection: "Model context window",
|
|
2503
2642
|
contextWindowHint: "Defaults to the context length in the Command Code catalog; override it with the capacity DSH should use for compaction and overflow decisions (e.g., 1M, 512K, 200K).",
|
|
2643
|
+
contextWindowReset: "Restore default",
|
|
2644
|
+
contextWindowResetAll: "Restore all defaults",
|
|
2645
|
+
contextWindowResetAllConfirm: "Restore every changed model context window to its default?",
|
|
2646
|
+
contextWindowNoneEnabled: "No model is checked yet. Check one above and its context window setting appears here.",
|
|
2504
2647
|
save: "Save",
|
|
2505
2648
|
saved: "Saved",
|
|
2506
2649
|
saving: "Saving...",
|
|
@@ -2516,11 +2659,11 @@ window.__ModuleLoader__.load({
|
|
|
2516
2659
|
loginFailed: "Sign-in failed",
|
|
2517
2660
|
tokens: "tokens"
|
|
2518
2661
|
};
|
|
2519
|
-
const dictionaries$
|
|
2520
|
-
zh: zh$
|
|
2521
|
-
"zh-CN": zh$
|
|
2522
|
-
en: en$
|
|
2523
|
-
"en-US": en$
|
|
2662
|
+
const dictionaries$4 = {
|
|
2663
|
+
zh: zh$4,
|
|
2664
|
+
"zh-CN": zh$4,
|
|
2665
|
+
en: en$4,
|
|
2666
|
+
"en-US": en$4
|
|
2524
2667
|
};
|
|
2525
2668
|
//#endregion
|
|
2526
2669
|
//#region src/client/command-code/CommandCodeSection.tsx
|
|
@@ -2528,7 +2671,7 @@ window.__ModuleLoader__.load({
|
|
|
2528
2671
|
* Display label per reasoning level. The locale dictionary only accepts flat
|
|
2529
2672
|
* string values, so this nested table lives with the control that renders it.
|
|
2530
2673
|
*/
|
|
2531
|
-
const EFFORT_LABELS$
|
|
2674
|
+
const EFFORT_LABELS$2 = {
|
|
2532
2675
|
minimal: "Minimal",
|
|
2533
2676
|
low: "Low",
|
|
2534
2677
|
medium: "Medium",
|
|
@@ -2536,9 +2679,9 @@ window.__ModuleLoader__.load({
|
|
|
2536
2679
|
xhigh: "X-High",
|
|
2537
2680
|
max: "Max"
|
|
2538
2681
|
};
|
|
2539
|
-
const API$
|
|
2540
|
-
async function fetchApi$
|
|
2541
|
-
const res = await fetch(`${API$
|
|
2682
|
+
const API$8 = "/command-code/api";
|
|
2683
|
+
async function fetchApi$8(path, options) {
|
|
2684
|
+
const res = await fetch(`${API$8}${path}`, {
|
|
2542
2685
|
...options,
|
|
2543
2686
|
headers: {
|
|
2544
2687
|
"Content-Type": "application/json",
|
|
@@ -2550,19 +2693,29 @@ window.__ModuleLoader__.load({
|
|
|
2550
2693
|
return json.value;
|
|
2551
2694
|
}
|
|
2552
2695
|
/** Parse "1M", "512K", "200000" into a positive integer token count. */
|
|
2553
|
-
function parsePositiveCapacity$
|
|
2696
|
+
function parsePositiveCapacity$3(value) {
|
|
2554
2697
|
const matched = value.trim().toLowerCase().replace(/[,_\s]/g, "").match(/^(\d+(?:\.\d+)?)(k|m)?$/);
|
|
2555
2698
|
if (matched === null) return null;
|
|
2556
2699
|
const multiplier = matched[2] === "m" ? 1e6 : matched[2] === "k" ? 1e3 : 1;
|
|
2557
2700
|
const parsed = Number(matched[1]) * multiplier;
|
|
2558
2701
|
return Number.isSafeInteger(parsed) && parsed >= 1 ? parsed : null;
|
|
2559
2702
|
}
|
|
2560
|
-
function formatCapacity$
|
|
2703
|
+
function formatCapacity$3(value) {
|
|
2561
2704
|
if (value >= 1e6 && value % 1e5 === 0) return `${value / 1e6}M`;
|
|
2562
2705
|
if (value >= 1e3 && value % 1e3 === 0) return `${value / 1e3}K`;
|
|
2563
2706
|
return String(value);
|
|
2564
2707
|
}
|
|
2565
|
-
|
|
2708
|
+
/**
|
|
2709
|
+
* Seed one draft per model from a status payload. Also run after a model
|
|
2710
|
+
* toggle: a model that was just enabled has no draft yet, and the context
|
|
2711
|
+
* window section only renders enabled models.
|
|
2712
|
+
*/
|
|
2713
|
+
function contextDraftsFor$3(status) {
|
|
2714
|
+
const drafts = {};
|
|
2715
|
+
for (const model of status.models) drafts[model.id] = formatCapacity$3(status.contextWindowOverrides[model.id] || model.defaultContextWindow);
|
|
2716
|
+
return drafts;
|
|
2717
|
+
}
|
|
2718
|
+
function formatReset$3(resetsAt) {
|
|
2566
2719
|
if (resetsAt === void 0 || resetsAt === null || resetsAt <= 0) return "";
|
|
2567
2720
|
const diff = resetsAt - Date.now();
|
|
2568
2721
|
if (diff <= 0) return "now";
|
|
@@ -2582,7 +2735,7 @@ window.__ModuleLoader__.load({
|
|
|
2582
2735
|
const [contextDrafts, setContextDrafts] = (0, react.useState)({});
|
|
2583
2736
|
const [savingModel, setSavingModel] = (0, react.useState)(null);
|
|
2584
2737
|
const [apiKey, setApiKey] = (0, react.useState)("");
|
|
2585
|
-
const t = zh$
|
|
2738
|
+
const t = zh$4;
|
|
2586
2739
|
const notifyChange = (0, react.useCallback)(() => {
|
|
2587
2740
|
onModelChange?.();
|
|
2588
2741
|
loadModelDirectory?.();
|
|
@@ -2590,11 +2743,9 @@ window.__ModuleLoader__.load({
|
|
|
2590
2743
|
const loadStatus = (0, react.useCallback)(async (quiet = false) => {
|
|
2591
2744
|
if (!quiet) setError(null);
|
|
2592
2745
|
try {
|
|
2593
|
-
const data = await fetchApi$
|
|
2746
|
+
const data = await fetchApi$8("/status");
|
|
2594
2747
|
setStatus(data);
|
|
2595
|
-
|
|
2596
|
-
for (const model of data.models) drafts[model.id] = formatCapacity$2(data.contextWindowOverrides[model.id] || model.defaultContextWindow);
|
|
2597
|
-
setContextDrafts(drafts);
|
|
2748
|
+
setContextDrafts(contextDraftsFor$3(data));
|
|
2598
2749
|
} catch (err) {
|
|
2599
2750
|
if (!quiet) setError(err instanceof Error ? err.message : String(err));
|
|
2600
2751
|
} finally {
|
|
@@ -2618,12 +2769,12 @@ window.__ModuleLoader__.load({
|
|
|
2618
2769
|
setBusy("login");
|
|
2619
2770
|
setError(null);
|
|
2620
2771
|
setLoginProgress(null);
|
|
2621
|
-
const flow = await fetchApi$
|
|
2772
|
+
const flow = await fetchApi$8("/login", { method: "POST" });
|
|
2622
2773
|
if (flow.authUrl) window.open(flow.authUrl, "_blank");
|
|
2623
2774
|
const pollTimer = window.setInterval(() => {
|
|
2624
2775
|
(async () => {
|
|
2625
2776
|
try {
|
|
2626
|
-
const poll = await fetchApi$
|
|
2777
|
+
const poll = await fetchApi$8("/login/status");
|
|
2627
2778
|
if (poll.progress) setLoginProgress(poll.progress);
|
|
2628
2779
|
if (poll.status === "complete") {
|
|
2629
2780
|
window.clearInterval(pollTimer);
|
|
@@ -2655,7 +2806,7 @@ window.__ModuleLoader__.load({
|
|
|
2655
2806
|
try {
|
|
2656
2807
|
setBusy("apikey");
|
|
2657
2808
|
setError(null);
|
|
2658
|
-
const updated = await fetchApi$
|
|
2809
|
+
const updated = await fetchApi$8("/login/apikey", {
|
|
2659
2810
|
method: "POST",
|
|
2660
2811
|
body: JSON.stringify({ apiKey })
|
|
2661
2812
|
});
|
|
@@ -2673,7 +2824,7 @@ window.__ModuleLoader__.load({
|
|
|
2673
2824
|
try {
|
|
2674
2825
|
setBusy(`${action}-${accountId}`);
|
|
2675
2826
|
setError(null);
|
|
2676
|
-
const updated = await fetchApi$
|
|
2827
|
+
const updated = await fetchApi$8("/accounts", {
|
|
2677
2828
|
method: "POST",
|
|
2678
2829
|
body: JSON.stringify({
|
|
2679
2830
|
action,
|
|
@@ -2692,7 +2843,7 @@ window.__ModuleLoader__.load({
|
|
|
2692
2843
|
try {
|
|
2693
2844
|
setBusy("strategy");
|
|
2694
2845
|
setError(null);
|
|
2695
|
-
const updated = await fetchApi$
|
|
2846
|
+
const updated = await fetchApi$8("/accounts", {
|
|
2696
2847
|
method: "POST",
|
|
2697
2848
|
body: JSON.stringify({
|
|
2698
2849
|
action: "strategy",
|
|
@@ -2715,7 +2866,7 @@ window.__ModuleLoader__.load({
|
|
|
2715
2866
|
const handleRelogin = (accountId) => {
|
|
2716
2867
|
(async () => {
|
|
2717
2868
|
try {
|
|
2718
|
-
const updated = await fetchApi$
|
|
2869
|
+
const updated = await fetchApi$8("/accounts", {
|
|
2719
2870
|
method: "POST",
|
|
2720
2871
|
body: JSON.stringify({
|
|
2721
2872
|
action: "relogin",
|
|
@@ -2734,7 +2885,7 @@ window.__ModuleLoader__.load({
|
|
|
2734
2885
|
try {
|
|
2735
2886
|
setBusy("quota");
|
|
2736
2887
|
setError(null);
|
|
2737
|
-
const updated = await fetchApi$
|
|
2888
|
+
const updated = await fetchApi$8("/quota", { method: "POST" });
|
|
2738
2889
|
setStatus(updated);
|
|
2739
2890
|
} catch (err) {
|
|
2740
2891
|
setError(err instanceof Error ? err.message : String(err));
|
|
@@ -2746,11 +2897,9 @@ window.__ModuleLoader__.load({
|
|
|
2746
2897
|
try {
|
|
2747
2898
|
setBusy("catalog");
|
|
2748
2899
|
setError(null);
|
|
2749
|
-
const updated = await fetchApi$
|
|
2900
|
+
const updated = await fetchApi$8("/catalog/refresh", { method: "POST" });
|
|
2750
2901
|
setStatus(updated);
|
|
2751
|
-
|
|
2752
|
-
for (const model of updated.models) drafts[model.id] = formatCapacity$2(updated.contextWindowOverrides[model.id] || model.defaultContextWindow);
|
|
2753
|
-
setContextDrafts(drafts);
|
|
2902
|
+
setContextDrafts(contextDraftsFor$3(updated));
|
|
2754
2903
|
notifyChange();
|
|
2755
2904
|
} catch (err) {
|
|
2756
2905
|
setError(err instanceof Error ? err.message : String(err));
|
|
@@ -2762,7 +2911,7 @@ window.__ModuleLoader__.load({
|
|
|
2762
2911
|
try {
|
|
2763
2912
|
setBusy("connection");
|
|
2764
2913
|
setError(null);
|
|
2765
|
-
await fetchApi$
|
|
2914
|
+
await fetchApi$8("/connection/test", { method: "POST" });
|
|
2766
2915
|
await loadStatus(true);
|
|
2767
2916
|
} catch (err) {
|
|
2768
2917
|
setError(err instanceof Error ? err.message : String(err));
|
|
@@ -2772,11 +2921,12 @@ window.__ModuleLoader__.load({
|
|
|
2772
2921
|
};
|
|
2773
2922
|
const applyEnabled = async (enabledModelIds) => {
|
|
2774
2923
|
try {
|
|
2775
|
-
const updated = await fetchApi$
|
|
2924
|
+
const updated = await fetchApi$8("/models", {
|
|
2776
2925
|
method: "POST",
|
|
2777
2926
|
body: JSON.stringify({ enabledModelIds })
|
|
2778
2927
|
});
|
|
2779
2928
|
setStatus(updated);
|
|
2929
|
+
setContextDrafts(contextDraftsFor$3(updated));
|
|
2780
2930
|
notifyChange();
|
|
2781
2931
|
} catch (err) {
|
|
2782
2932
|
setError(err instanceof Error ? err.message : String(err));
|
|
@@ -2788,7 +2938,7 @@ window.__ModuleLoader__.load({
|
|
|
2788
2938
|
enabled
|
|
2789
2939
|
} : prev);
|
|
2790
2940
|
try {
|
|
2791
|
-
const updated = await fetchApi$
|
|
2941
|
+
const updated = await fetchApi$8("/settings", {
|
|
2792
2942
|
method: "POST",
|
|
2793
2943
|
body: JSON.stringify({ enabled })
|
|
2794
2944
|
});
|
|
@@ -2811,7 +2961,7 @@ window.__ModuleLoader__.load({
|
|
|
2811
2961
|
};
|
|
2812
2962
|
const handleUpdateEffort = async (effort) => {
|
|
2813
2963
|
try {
|
|
2814
|
-
const updated = await fetchApi$
|
|
2964
|
+
const updated = await fetchApi$8("/settings", {
|
|
2815
2965
|
method: "POST",
|
|
2816
2966
|
body: JSON.stringify({ defaultReasoningEffort: effort })
|
|
2817
2967
|
});
|
|
@@ -2823,7 +2973,7 @@ window.__ModuleLoader__.load({
|
|
|
2823
2973
|
};
|
|
2824
2974
|
const handleSaveContextWindow = async (modelId) => {
|
|
2825
2975
|
const raw = contextDrafts[modelId] || "";
|
|
2826
|
-
const parsed = parsePositiveCapacity$
|
|
2976
|
+
const parsed = parsePositiveCapacity$3(raw);
|
|
2827
2977
|
if (parsed === null) {
|
|
2828
2978
|
setError(`Invalid context capacity: ${raw}`);
|
|
2829
2979
|
return;
|
|
@@ -2831,14 +2981,14 @@ window.__ModuleLoader__.load({
|
|
|
2831
2981
|
try {
|
|
2832
2982
|
setSavingModel(modelId);
|
|
2833
2983
|
setError(null);
|
|
2834
|
-
const updated = await fetchApi$
|
|
2984
|
+
const updated = await fetchApi$8("/settings", {
|
|
2835
2985
|
method: "POST",
|
|
2836
2986
|
body: JSON.stringify({ contextWindowOverrides: { [modelId]: parsed } })
|
|
2837
2987
|
});
|
|
2838
2988
|
setStatus(updated);
|
|
2839
2989
|
setContextDrafts((prev) => ({
|
|
2840
2990
|
...prev,
|
|
2841
|
-
[modelId]: formatCapacity$
|
|
2991
|
+
[modelId]: formatCapacity$3(parsed)
|
|
2842
2992
|
}));
|
|
2843
2993
|
notifyChange();
|
|
2844
2994
|
} catch (err) {
|
|
@@ -2847,6 +2997,53 @@ window.__ModuleLoader__.load({
|
|
|
2847
2997
|
setSavingModel(null);
|
|
2848
2998
|
}
|
|
2849
2999
|
};
|
|
3000
|
+
/** Clear one override; the row falls back to the catalog length. */
|
|
3001
|
+
const handleResetContextWindow = async (modelId) => {
|
|
3002
|
+
try {
|
|
3003
|
+
setSavingModel(modelId);
|
|
3004
|
+
setError(null);
|
|
3005
|
+
const updated = await fetchApi$8("/settings", {
|
|
3006
|
+
method: "POST",
|
|
3007
|
+
body: JSON.stringify({ contextWindowOverrides: { [modelId]: null } })
|
|
3008
|
+
});
|
|
3009
|
+
setStatus(updated);
|
|
3010
|
+
setContextDrafts((prev) => {
|
|
3011
|
+
const model = updated.models.find((candidate) => candidate.id === modelId);
|
|
3012
|
+
return model === void 0 ? prev : {
|
|
3013
|
+
...prev,
|
|
3014
|
+
[modelId]: formatCapacity$3(model.defaultContextWindow)
|
|
3015
|
+
};
|
|
3016
|
+
});
|
|
3017
|
+
notifyChange();
|
|
3018
|
+
} catch (err) {
|
|
3019
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
3020
|
+
} finally {
|
|
3021
|
+
setSavingModel(null);
|
|
3022
|
+
}
|
|
3023
|
+
};
|
|
3024
|
+
/** Clear every stored override, including models the picker no longer shows. */
|
|
3025
|
+
const handleResetAllContextWindows = async () => {
|
|
3026
|
+
const models = Object.keys(status?.contextWindowOverrides ?? {});
|
|
3027
|
+
if (models.length === 0) return;
|
|
3028
|
+
if (typeof window !== "undefined" && !window.confirm(t.contextWindowResetAllConfirm)) return;
|
|
3029
|
+
try {
|
|
3030
|
+
setBusy("context");
|
|
3031
|
+
setError(null);
|
|
3032
|
+
const updated = await fetchApi$8("/settings", {
|
|
3033
|
+
method: "POST",
|
|
3034
|
+
body: JSON.stringify({ contextWindowOverrides: Object.fromEntries(models.map((model) => [model, null])) })
|
|
3035
|
+
});
|
|
3036
|
+
setStatus(updated);
|
|
3037
|
+
setContextDrafts(contextDraftsFor$3(updated));
|
|
3038
|
+
notifyChange();
|
|
3039
|
+
} catch (err) {
|
|
3040
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
3041
|
+
} finally {
|
|
3042
|
+
setBusy(null);
|
|
3043
|
+
}
|
|
3044
|
+
};
|
|
3045
|
+
const contextModels = status?.models.filter((model) => model.enabled) ?? [];
|
|
3046
|
+
const overrideCount = Object.keys(status?.contextWindowOverrides ?? {}).length;
|
|
2850
3047
|
if (loading) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2851
3048
|
className: "dsha-page",
|
|
2852
3049
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
@@ -3034,7 +3231,7 @@ window.__ModuleLoader__.load({
|
|
|
3034
3231
|
children: t.defaultEffortAuto
|
|
3035
3232
|
}), COMMAND_CODE_REASONING_EFFORTS.map((effort) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
3036
3233
|
value: effort,
|
|
3037
|
-
children: EFFORT_LABELS$
|
|
3234
|
+
children: EFFORT_LABELS$2[effort]
|
|
3038
3235
|
}, effort))]
|
|
3039
3236
|
})]
|
|
3040
3237
|
})]
|
|
@@ -3050,39 +3247,62 @@ window.__ModuleLoader__.load({
|
|
|
3050
3247
|
className: "dsha-muted",
|
|
3051
3248
|
children: t.contextWindowHint
|
|
3052
3249
|
}),
|
|
3053
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
3250
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3054
3251
|
className: "dsha-context-settings",
|
|
3055
|
-
children:
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
className: "dsha-
|
|
3062
|
-
children: [
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
|
|
3252
|
+
children: [
|
|
3253
|
+
contextModels.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
3254
|
+
className: "dsha-muted",
|
|
3255
|
+
children: t.contextWindowNoneEnabled
|
|
3256
|
+
}),
|
|
3257
|
+
contextModels.map((model) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3258
|
+
className: "dsha-context-row",
|
|
3259
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3260
|
+
title: model.id,
|
|
3261
|
+
children: model.name
|
|
3262
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3263
|
+
className: "dsha-capacity-control",
|
|
3264
|
+
children: [
|
|
3265
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
3266
|
+
type: "text",
|
|
3267
|
+
"aria-label": `${model.name} context window`,
|
|
3268
|
+
value: contextDrafts[model.id] ?? "",
|
|
3269
|
+
onChange: (event) => setContextDrafts({
|
|
3270
|
+
...contextDrafts,
|
|
3271
|
+
[model.id]: event.currentTarget.value
|
|
3272
|
+
}),
|
|
3273
|
+
onKeyDown: (event) => {
|
|
3274
|
+
if (event.key === "Enter") handleSaveContextWindow(model.id);
|
|
3275
|
+
}
|
|
3070
3276
|
}),
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
|
|
3082
|
-
|
|
3083
|
-
|
|
3084
|
-
|
|
3085
|
-
|
|
3277
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: t.tokens }),
|
|
3278
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
3279
|
+
type: "button",
|
|
3280
|
+
className: "dsha-context-save",
|
|
3281
|
+
disabled: savingModel === model.id,
|
|
3282
|
+
onClick: () => void handleSaveContextWindow(model.id),
|
|
3283
|
+
children: savingModel === model.id ? t.saving : t.save
|
|
3284
|
+
}),
|
|
3285
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
3286
|
+
type: "button",
|
|
3287
|
+
className: "dsha-context-save dsha-context-reset",
|
|
3288
|
+
"aria-label": `${model.name} ${t.contextWindowReset}`,
|
|
3289
|
+
disabled: savingModel === model.id || status?.contextWindowOverrides[model.id] === void 0,
|
|
3290
|
+
onClick: () => void handleResetContextWindow(model.id),
|
|
3291
|
+
children: t.contextWindowReset
|
|
3292
|
+
})
|
|
3293
|
+
]
|
|
3294
|
+
})]
|
|
3295
|
+
}, model.id)),
|
|
3296
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3297
|
+
className: "dsha-actions",
|
|
3298
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
3299
|
+
className: "dsha-btn",
|
|
3300
|
+
disabled: busy !== null || overrideCount === 0,
|
|
3301
|
+
onClick: () => void handleResetAllContextWindows(),
|
|
3302
|
+
children: t.contextWindowResetAll
|
|
3303
|
+
})
|
|
3304
|
+
})
|
|
3305
|
+
]
|
|
3086
3306
|
})
|
|
3087
3307
|
]
|
|
3088
3308
|
}),
|
|
@@ -3128,7 +3348,7 @@ window.__ModuleLoader__.load({
|
|
|
3128
3348
|
}),
|
|
3129
3349
|
window.resetsAt !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3130
3350
|
className: "dsha-meter-meta",
|
|
3131
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: ["Reset: ", formatReset$
|
|
3351
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: ["Reset: ", formatReset$3(window.resetsAt)] })
|
|
3132
3352
|
})
|
|
3133
3353
|
]
|
|
3134
3354
|
}, window.id)),
|
|
@@ -3153,7 +3373,7 @@ window.__ModuleLoader__.load({
|
|
|
3153
3373
|
meter.used ?? "—",
|
|
3154
3374
|
" / ",
|
|
3155
3375
|
meter.limit ?? "—"
|
|
3156
|
-
] }), meter.resetsAt !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: ["Reset: ", formatReset$
|
|
3376
|
+
] }), meter.resetsAt !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: ["Reset: ", formatReset$3(meter.resetsAt)] })]
|
|
3157
3377
|
}) : meter.description !== null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3158
3378
|
className: "dsha-meter-meta",
|
|
3159
3379
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: meter.description })
|
|
@@ -3192,7 +3412,7 @@ window.__ModuleLoader__.load({
|
|
|
3192
3412
|
//#endregion
|
|
3193
3413
|
//#region src/client/kimi-code/locales.ts
|
|
3194
3414
|
const NS_KIMI_CODE = "dsh-kimi-code";
|
|
3195
|
-
const zh$
|
|
3415
|
+
const zh$3 = {
|
|
3196
3416
|
...accountPoolZh,
|
|
3197
3417
|
title: "Kimi Code",
|
|
3198
3418
|
pageDesc: "登录 Kimi Code 订阅,管理模型、思考档位、上下文窗口与额度。",
|
|
@@ -3272,6 +3492,10 @@ window.__ModuleLoader__.load({
|
|
|
3272
3492
|
contextWindowSection: "模型上下文窗口",
|
|
3273
3493
|
contextWindowHint: "默认取模型目录的上下文长度。k3 的 1M 上下文需要 Allegretto 及以上套餐,因此默认按 256K 计算;如已升级可在此覆盖为 1M。",
|
|
3274
3494
|
contextWindowPlan: "完整上下文需要 {plan} 套餐",
|
|
3495
|
+
contextWindowReset: "恢复默认",
|
|
3496
|
+
contextWindowResetAll: "全部恢复默认",
|
|
3497
|
+
contextWindowResetAllConfirm: "确定把已改过的模型上下文窗口全部恢复为默认值吗?",
|
|
3498
|
+
contextWindowNoneEnabled: "还没有勾选任何模型。在上方勾选后,这里会出现该模型的上下文窗口设置。",
|
|
3275
3499
|
save: "保存",
|
|
3276
3500
|
saved: "已保存",
|
|
3277
3501
|
saving: "保存中...",
|
|
@@ -3312,7 +3536,7 @@ window.__ModuleLoader__.load({
|
|
|
3312
3536
|
requests: "次请求",
|
|
3313
3537
|
tokens: "tokens"
|
|
3314
3538
|
};
|
|
3315
|
-
const en$
|
|
3539
|
+
const en$3 = {
|
|
3316
3540
|
...accountPoolEn,
|
|
3317
3541
|
title: "Kimi Code",
|
|
3318
3542
|
pageDesc: "Sign in to the Kimi Code subscription and manage models, thinking level, context windows, and quota.",
|
|
@@ -3392,6 +3616,10 @@ window.__ModuleLoader__.load({
|
|
|
3392
3616
|
contextWindowSection: "Model context window",
|
|
3393
3617
|
contextWindowHint: "Defaults to the catalog context length. k3 reaches 1M only on Allegretto and above, so it defaults to 256K; raise the override here after upgrading.",
|
|
3394
3618
|
contextWindowPlan: "Full context requires the {plan} plan",
|
|
3619
|
+
contextWindowReset: "Restore default",
|
|
3620
|
+
contextWindowResetAll: "Restore all defaults",
|
|
3621
|
+
contextWindowResetAllConfirm: "Restore every changed model context window to its default?",
|
|
3622
|
+
contextWindowNoneEnabled: "No model is checked yet. Check one above and its context window setting appears here.",
|
|
3395
3623
|
save: "Save",
|
|
3396
3624
|
saved: "Saved",
|
|
3397
3625
|
saving: "Saving...",
|
|
@@ -3432,11 +3660,11 @@ window.__ModuleLoader__.load({
|
|
|
3432
3660
|
requests: "requests",
|
|
3433
3661
|
tokens: "tokens"
|
|
3434
3662
|
};
|
|
3435
|
-
const dictionaries$
|
|
3436
|
-
zh: zh$
|
|
3437
|
-
"zh-CN": zh$
|
|
3438
|
-
en: en$
|
|
3439
|
-
"en-US": en$
|
|
3663
|
+
const dictionaries$3 = {
|
|
3664
|
+
zh: zh$3,
|
|
3665
|
+
"zh-CN": zh$3,
|
|
3666
|
+
en: en$3,
|
|
3667
|
+
"en-US": en$3
|
|
3440
3668
|
};
|
|
3441
3669
|
//#endregion
|
|
3442
3670
|
//#region src/client/kimi-code/KimiModelCapabilities.tsx
|
|
@@ -3449,7 +3677,7 @@ window.__ModuleLoader__.load({
|
|
|
3449
3677
|
* Capabilities are now short tags in their own columns, with the per-model
|
|
3450
3678
|
* detail kept in a hover title.
|
|
3451
3679
|
*/
|
|
3452
|
-
const t = zh$
|
|
3680
|
+
const t = zh$3;
|
|
3453
3681
|
function KimiModelCapabilities({ models }) {
|
|
3454
3682
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3455
3683
|
className: "dsha-cap-table",
|
|
@@ -3493,9 +3721,9 @@ window.__ModuleLoader__.load({
|
|
|
3493
3721
|
}
|
|
3494
3722
|
//#endregion
|
|
3495
3723
|
//#region src/client/kimi-code/KimiCodeSection.tsx
|
|
3496
|
-
const API$
|
|
3497
|
-
async function fetchApi$
|
|
3498
|
-
const res = await fetch(`${API$
|
|
3724
|
+
const API$7 = "/kimi-code/api";
|
|
3725
|
+
async function fetchApi$7(path, options) {
|
|
3726
|
+
const res = await fetch(`${API$7}${path}`, {
|
|
3499
3727
|
...options,
|
|
3500
3728
|
headers: {
|
|
3501
3729
|
"Content-Type": "application/json",
|
|
@@ -3507,19 +3735,29 @@ window.__ModuleLoader__.load({
|
|
|
3507
3735
|
return json.value;
|
|
3508
3736
|
}
|
|
3509
3737
|
/** Parse "1M", "512K", "200000" into a positive integer token count. */
|
|
3510
|
-
function parsePositiveCapacity$
|
|
3738
|
+
function parsePositiveCapacity$2(value) {
|
|
3511
3739
|
const matched = value.trim().toLowerCase().replace(/[,_\s]/g, "").match(/^(\d+(?:\.\d+)?)(k|m)?$/);
|
|
3512
3740
|
if (matched === null) return null;
|
|
3513
3741
|
const multiplier = matched[2] === "m" ? 1e6 : matched[2] === "k" ? 1e3 : 1;
|
|
3514
3742
|
const parsed = Number(matched[1]) * multiplier;
|
|
3515
3743
|
return Number.isSafeInteger(parsed) && parsed >= 1 ? parsed : null;
|
|
3516
3744
|
}
|
|
3517
|
-
function formatCapacity$
|
|
3745
|
+
function formatCapacity$2(value) {
|
|
3518
3746
|
if (value >= 1e6 && value % 1e5 === 0) return `${value / 1e6}M`;
|
|
3519
3747
|
if (value >= 1e3 && value % 1e3 === 0) return `${value / 1e3}K`;
|
|
3520
3748
|
return String(value);
|
|
3521
3749
|
}
|
|
3522
|
-
|
|
3750
|
+
/**
|
|
3751
|
+
* Seed one draft per model from a status payload. Also run after a model
|
|
3752
|
+
* toggle: a model that was just enabled has no draft yet, and the context
|
|
3753
|
+
* window section only renders enabled models.
|
|
3754
|
+
*/
|
|
3755
|
+
function contextDraftsFor$2(status) {
|
|
3756
|
+
const drafts = {};
|
|
3757
|
+
for (const model of status.models) drafts[model.id] = formatCapacity$2(status.contextWindowOverrides[model.id] || model.defaultContextWindow);
|
|
3758
|
+
return drafts;
|
|
3759
|
+
}
|
|
3760
|
+
function formatDate$2(ms) {
|
|
3523
3761
|
if (ms === void 0 || ms === null || ms <= 0) return "—";
|
|
3524
3762
|
try {
|
|
3525
3763
|
return new Intl.DateTimeFormat(void 0, {
|
|
@@ -3530,7 +3768,7 @@ window.__ModuleLoader__.load({
|
|
|
3530
3768
|
return "—";
|
|
3531
3769
|
}
|
|
3532
3770
|
}
|
|
3533
|
-
function formatReset$
|
|
3771
|
+
function formatReset$2(resetsAt) {
|
|
3534
3772
|
if (resetsAt === void 0 || resetsAt === null || resetsAt <= 0) return "";
|
|
3535
3773
|
const diff = resetsAt - Date.now();
|
|
3536
3774
|
if (diff <= 0) return "now";
|
|
@@ -3555,10 +3793,10 @@ window.__ModuleLoader__.load({
|
|
|
3555
3793
|
}
|
|
3556
3794
|
}
|
|
3557
3795
|
const EFFORT_LABEL = {
|
|
3558
|
-
low: zh$
|
|
3559
|
-
high: zh$
|
|
3560
|
-
max: zh$
|
|
3561
|
-
none: zh$
|
|
3796
|
+
low: zh$3.effortLow,
|
|
3797
|
+
high: zh$3.effortHigh,
|
|
3798
|
+
max: zh$3.effortMax,
|
|
3799
|
+
none: zh$3.effortNone
|
|
3562
3800
|
};
|
|
3563
3801
|
/** Human label for the last request's prefix-drift cause. */
|
|
3564
3802
|
function driftLabel(cause, t) {
|
|
@@ -3582,7 +3820,7 @@ window.__ModuleLoader__.load({
|
|
|
3582
3820
|
const [savingModel, setSavingModel] = (0, react.useState)(null);
|
|
3583
3821
|
const [copied, setCopied] = (0, react.useState)(false);
|
|
3584
3822
|
const [connectionNotice, setConnectionNotice] = (0, react.useState)(null);
|
|
3585
|
-
const t = zh$
|
|
3823
|
+
const t = zh$3;
|
|
3586
3824
|
const notifyChange = (0, react.useCallback)(() => {
|
|
3587
3825
|
onModelChange?.();
|
|
3588
3826
|
loadModelDirectory?.();
|
|
@@ -3590,11 +3828,9 @@ window.__ModuleLoader__.load({
|
|
|
3590
3828
|
const loadStatus = (0, react.useCallback)(async (quiet = false) => {
|
|
3591
3829
|
if (!quiet) setError(null);
|
|
3592
3830
|
try {
|
|
3593
|
-
const data = await fetchApi$
|
|
3831
|
+
const data = await fetchApi$7("/status");
|
|
3594
3832
|
setStatus(data);
|
|
3595
|
-
|
|
3596
|
-
for (const model of data.models) drafts[model.id] = formatCapacity$1(data.contextWindowOverrides[model.id] || model.defaultContextWindow);
|
|
3597
|
-
setContextDrafts(drafts);
|
|
3833
|
+
setContextDrafts(contextDraftsFor$2(data));
|
|
3598
3834
|
} catch (err) {
|
|
3599
3835
|
if (!quiet) setError(err instanceof Error ? err.message : String(err));
|
|
3600
3836
|
} finally {
|
|
@@ -3618,7 +3854,7 @@ window.__ModuleLoader__.load({
|
|
|
3618
3854
|
const timer = window.setInterval(() => {
|
|
3619
3855
|
(async () => {
|
|
3620
3856
|
try {
|
|
3621
|
-
const poll = await fetchApi$
|
|
3857
|
+
const poll = await fetchApi$7("/login/status");
|
|
3622
3858
|
setFlow(poll);
|
|
3623
3859
|
if (poll.status === "complete") {
|
|
3624
3860
|
await loadStatus();
|
|
@@ -3639,7 +3875,7 @@ window.__ModuleLoader__.load({
|
|
|
3639
3875
|
setBusy("login");
|
|
3640
3876
|
setError(null);
|
|
3641
3877
|
setCopied(false);
|
|
3642
|
-
const next = await fetchApi$
|
|
3878
|
+
const next = await fetchApi$7("/login", {
|
|
3643
3879
|
method: "POST",
|
|
3644
3880
|
body: JSON.stringify({})
|
|
3645
3881
|
});
|
|
@@ -3652,7 +3888,7 @@ window.__ModuleLoader__.load({
|
|
|
3652
3888
|
};
|
|
3653
3889
|
const handleCancelLogin = async () => {
|
|
3654
3890
|
try {
|
|
3655
|
-
await fetchApi$
|
|
3891
|
+
await fetchApi$7("/login/cancel", { method: "POST" });
|
|
3656
3892
|
setFlow({ status: "idle" });
|
|
3657
3893
|
} catch (err) {
|
|
3658
3894
|
setError(err instanceof Error ? err.message : String(err));
|
|
@@ -3672,7 +3908,7 @@ window.__ModuleLoader__.load({
|
|
|
3672
3908
|
try {
|
|
3673
3909
|
setBusy(`${action}-${accountId}`);
|
|
3674
3910
|
setError(null);
|
|
3675
|
-
const updated = await fetchApi$
|
|
3911
|
+
const updated = await fetchApi$7("/accounts", {
|
|
3676
3912
|
method: "POST",
|
|
3677
3913
|
body: JSON.stringify({
|
|
3678
3914
|
action,
|
|
@@ -3692,7 +3928,7 @@ window.__ModuleLoader__.load({
|
|
|
3692
3928
|
try {
|
|
3693
3929
|
setBusy("strategy");
|
|
3694
3930
|
setError(null);
|
|
3695
|
-
const updated = await fetchApi$
|
|
3931
|
+
const updated = await fetchApi$7("/accounts", {
|
|
3696
3932
|
method: "POST",
|
|
3697
3933
|
body: JSON.stringify({
|
|
3698
3934
|
action: "strategy",
|
|
@@ -3715,7 +3951,7 @@ window.__ModuleLoader__.load({
|
|
|
3715
3951
|
const handleRelogin = (accountId) => {
|
|
3716
3952
|
(async () => {
|
|
3717
3953
|
try {
|
|
3718
|
-
const updated = await fetchApi$
|
|
3954
|
+
const updated = await fetchApi$7("/accounts", {
|
|
3719
3955
|
method: "POST",
|
|
3720
3956
|
body: JSON.stringify({
|
|
3721
3957
|
action: "relogin",
|
|
@@ -3734,7 +3970,7 @@ window.__ModuleLoader__.load({
|
|
|
3734
3970
|
try {
|
|
3735
3971
|
setBusy("quota");
|
|
3736
3972
|
setError(null);
|
|
3737
|
-
const updated = await fetchApi$
|
|
3973
|
+
const updated = await fetchApi$7("/quota", { method: "POST" });
|
|
3738
3974
|
setStatus(updated);
|
|
3739
3975
|
} catch (err) {
|
|
3740
3976
|
setError(err instanceof Error ? err.message : String(err));
|
|
@@ -3747,11 +3983,9 @@ window.__ModuleLoader__.load({
|
|
|
3747
3983
|
try {
|
|
3748
3984
|
setBusy("catalog");
|
|
3749
3985
|
setError(null);
|
|
3750
|
-
const updated = await fetchApi$
|
|
3986
|
+
const updated = await fetchApi$7("/catalog/refresh", { method: "POST" });
|
|
3751
3987
|
setStatus(updated);
|
|
3752
|
-
|
|
3753
|
-
for (const model of updated.models) drafts[model.id] = formatCapacity$1(updated.contextWindowOverrides[model.id] || model.defaultContextWindow);
|
|
3754
|
-
setContextDrafts(drafts);
|
|
3988
|
+
setContextDrafts(contextDraftsFor$2(updated));
|
|
3755
3989
|
notifyChange();
|
|
3756
3990
|
} catch (err) {
|
|
3757
3991
|
setError(err instanceof Error ? err.message : String(err));
|
|
@@ -3764,7 +3998,7 @@ window.__ModuleLoader__.load({
|
|
|
3764
3998
|
setBusy("connection");
|
|
3765
3999
|
setError(null);
|
|
3766
4000
|
setConnectionNotice(null);
|
|
3767
|
-
const result = await fetchApi$
|
|
4001
|
+
const result = await fetchApi$7("/connection/test", { method: "POST" });
|
|
3768
4002
|
setConnectionNotice(result.connected ? `${t.testSuccess} · ${result.latencyMs} ms` : t.testFailed);
|
|
3769
4003
|
await loadStatus(true);
|
|
3770
4004
|
} catch (err) {
|
|
@@ -3775,11 +4009,12 @@ window.__ModuleLoader__.load({
|
|
|
3775
4009
|
};
|
|
3776
4010
|
const applyEnabled = async (enabledModelIds) => {
|
|
3777
4011
|
try {
|
|
3778
|
-
const updated = await fetchApi$
|
|
4012
|
+
const updated = await fetchApi$7("/models", {
|
|
3779
4013
|
method: "POST",
|
|
3780
4014
|
body: JSON.stringify({ enabledModelIds })
|
|
3781
4015
|
});
|
|
3782
4016
|
setStatus(updated);
|
|
4017
|
+
setContextDrafts(contextDraftsFor$2(updated));
|
|
3783
4018
|
notifyChange();
|
|
3784
4019
|
} catch (err) {
|
|
3785
4020
|
setError(err instanceof Error ? err.message : String(err));
|
|
@@ -3791,7 +4026,7 @@ window.__ModuleLoader__.load({
|
|
|
3791
4026
|
enabled
|
|
3792
4027
|
} : prev);
|
|
3793
4028
|
try {
|
|
3794
|
-
const updated = await fetchApi$
|
|
4029
|
+
const updated = await fetchApi$7("/settings", {
|
|
3795
4030
|
method: "POST",
|
|
3796
4031
|
body: JSON.stringify({ enabled })
|
|
3797
4032
|
});
|
|
@@ -3814,7 +4049,7 @@ window.__ModuleLoader__.load({
|
|
|
3814
4049
|
};
|
|
3815
4050
|
const handleUpdateEffort = async (effort) => {
|
|
3816
4051
|
try {
|
|
3817
|
-
const updated = await fetchApi$
|
|
4052
|
+
const updated = await fetchApi$7("/settings", {
|
|
3818
4053
|
method: "POST",
|
|
3819
4054
|
body: JSON.stringify({ defaultReasoningEffort: effort })
|
|
3820
4055
|
});
|
|
@@ -3826,7 +4061,7 @@ window.__ModuleLoader__.load({
|
|
|
3826
4061
|
};
|
|
3827
4062
|
const handleSaveContextWindow = async (modelId) => {
|
|
3828
4063
|
const raw = contextDrafts[modelId] || "";
|
|
3829
|
-
const parsed = parsePositiveCapacity$
|
|
4064
|
+
const parsed = parsePositiveCapacity$2(raw);
|
|
3830
4065
|
if (parsed === null) {
|
|
3831
4066
|
setError(`Invalid context capacity: ${raw}`);
|
|
3832
4067
|
return;
|
|
@@ -3834,14 +4069,14 @@ window.__ModuleLoader__.load({
|
|
|
3834
4069
|
try {
|
|
3835
4070
|
setSavingModel(modelId);
|
|
3836
4071
|
setError(null);
|
|
3837
|
-
const updated = await fetchApi$
|
|
4072
|
+
const updated = await fetchApi$7("/settings", {
|
|
3838
4073
|
method: "POST",
|
|
3839
4074
|
body: JSON.stringify({ contextWindowOverrides: { [modelId]: parsed } })
|
|
3840
4075
|
});
|
|
3841
4076
|
setStatus(updated);
|
|
3842
4077
|
setContextDrafts((prev) => ({
|
|
3843
4078
|
...prev,
|
|
3844
|
-
[modelId]: formatCapacity$
|
|
4079
|
+
[modelId]: formatCapacity$2(parsed)
|
|
3845
4080
|
}));
|
|
3846
4081
|
notifyChange();
|
|
3847
4082
|
} catch (err) {
|
|
@@ -3850,6 +4085,53 @@ window.__ModuleLoader__.load({
|
|
|
3850
4085
|
setSavingModel(null);
|
|
3851
4086
|
}
|
|
3852
4087
|
};
|
|
4088
|
+
/** Clear one override; the row falls back to the catalog length. */
|
|
4089
|
+
const handleResetContextWindow = async (modelId) => {
|
|
4090
|
+
try {
|
|
4091
|
+
setSavingModel(modelId);
|
|
4092
|
+
setError(null);
|
|
4093
|
+
const updated = await fetchApi$7("/settings", {
|
|
4094
|
+
method: "POST",
|
|
4095
|
+
body: JSON.stringify({ contextWindowOverrides: { [modelId]: null } })
|
|
4096
|
+
});
|
|
4097
|
+
setStatus(updated);
|
|
4098
|
+
setContextDrafts((prev) => {
|
|
4099
|
+
const model = updated.models.find((candidate) => candidate.id === modelId);
|
|
4100
|
+
return model === void 0 ? prev : {
|
|
4101
|
+
...prev,
|
|
4102
|
+
[modelId]: formatCapacity$2(model.defaultContextWindow)
|
|
4103
|
+
};
|
|
4104
|
+
});
|
|
4105
|
+
notifyChange();
|
|
4106
|
+
} catch (err) {
|
|
4107
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
4108
|
+
} finally {
|
|
4109
|
+
setSavingModel(null);
|
|
4110
|
+
}
|
|
4111
|
+
};
|
|
4112
|
+
/** Clear every stored override, including models the picker no longer shows. */
|
|
4113
|
+
const handleResetAllContextWindows = async () => {
|
|
4114
|
+
const models = Object.keys(status?.contextWindowOverrides ?? {});
|
|
4115
|
+
if (models.length === 0) return;
|
|
4116
|
+
if (typeof window !== "undefined" && !window.confirm(t.contextWindowResetAllConfirm)) return;
|
|
4117
|
+
try {
|
|
4118
|
+
setBusy("context");
|
|
4119
|
+
setError(null);
|
|
4120
|
+
const updated = await fetchApi$7("/settings", {
|
|
4121
|
+
method: "POST",
|
|
4122
|
+
body: JSON.stringify({ contextWindowOverrides: Object.fromEntries(models.map((model) => [model, null])) })
|
|
4123
|
+
});
|
|
4124
|
+
setStatus(updated);
|
|
4125
|
+
setContextDrafts(contextDraftsFor$2(updated));
|
|
4126
|
+
notifyChange();
|
|
4127
|
+
} catch (err) {
|
|
4128
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
4129
|
+
} finally {
|
|
4130
|
+
setBusy(null);
|
|
4131
|
+
}
|
|
4132
|
+
};
|
|
4133
|
+
const contextModels = status?.models.filter((model) => model.enabled) ?? [];
|
|
4134
|
+
const overrideCount = Object.keys(status?.contextWindowOverrides ?? {}).length;
|
|
3853
4135
|
if (loading) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3854
4136
|
className: "dsha-page",
|
|
3855
4137
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
@@ -3928,7 +4210,7 @@ window.__ModuleLoader__.load({
|
|
|
3928
4210
|
children: t.codeExpires
|
|
3929
4211
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3930
4212
|
className: "dsha-value",
|
|
3931
|
-
children: formatDate$
|
|
4213
|
+
children: formatDate$2(flow?.expiresAt)
|
|
3932
4214
|
})]
|
|
3933
4215
|
}),
|
|
3934
4216
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -4196,42 +4478,65 @@ window.__ModuleLoader__.load({
|
|
|
4196
4478
|
className: "dsha-muted",
|
|
4197
4479
|
children: t.contextWindowHint
|
|
4198
4480
|
}),
|
|
4199
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
4481
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4200
4482
|
className: "dsha-context-settings",
|
|
4201
|
-
children:
|
|
4202
|
-
|
|
4203
|
-
|
|
4204
|
-
|
|
4205
|
-
|
|
4206
|
-
|
|
4207
|
-
|
|
4208
|
-
|
|
4209
|
-
|
|
4210
|
-
|
|
4211
|
-
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
|
|
4215
|
-
|
|
4216
|
-
|
|
4217
|
-
|
|
4218
|
-
|
|
4483
|
+
children: [
|
|
4484
|
+
contextModels.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
4485
|
+
className: "dsha-muted",
|
|
4486
|
+
children: t.contextWindowNoneEnabled
|
|
4487
|
+
}),
|
|
4488
|
+
contextModels.map((model) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4489
|
+
className: "dsha-context-row",
|
|
4490
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
4491
|
+
title: model.id,
|
|
4492
|
+
children: [model.name, model.defaultContextWindow < model.contextWindow && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4493
|
+
className: "dsha-model-meta",
|
|
4494
|
+
children: formatCapacity$2(model.contextWindow)
|
|
4495
|
+
})]
|
|
4496
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4497
|
+
className: "dsha-capacity-control",
|
|
4498
|
+
children: [
|
|
4499
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
4500
|
+
type: "text",
|
|
4501
|
+
"aria-label": `${model.name} context window`,
|
|
4502
|
+
value: contextDrafts[model.id] ?? "",
|
|
4503
|
+
onChange: (event) => setContextDrafts({
|
|
4504
|
+
...contextDrafts,
|
|
4505
|
+
[model.id]: event.currentTarget.value
|
|
4506
|
+
}),
|
|
4507
|
+
onKeyDown: (event) => {
|
|
4508
|
+
if (event.key === "Enter") handleSaveContextWindow(model.id);
|
|
4509
|
+
}
|
|
4219
4510
|
}),
|
|
4220
|
-
|
|
4221
|
-
|
|
4222
|
-
|
|
4223
|
-
|
|
4224
|
-
|
|
4225
|
-
|
|
4226
|
-
|
|
4227
|
-
|
|
4228
|
-
|
|
4229
|
-
|
|
4230
|
-
|
|
4231
|
-
|
|
4232
|
-
|
|
4233
|
-
|
|
4234
|
-
|
|
4511
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: t.tokens }),
|
|
4512
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
4513
|
+
type: "button",
|
|
4514
|
+
className: "dsha-context-save",
|
|
4515
|
+
disabled: savingModel === model.id,
|
|
4516
|
+
onClick: () => void handleSaveContextWindow(model.id),
|
|
4517
|
+
children: savingModel === model.id ? t.saving : t.save
|
|
4518
|
+
}),
|
|
4519
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
4520
|
+
type: "button",
|
|
4521
|
+
className: "dsha-context-save dsha-context-reset",
|
|
4522
|
+
"aria-label": `${model.name} ${t.contextWindowReset}`,
|
|
4523
|
+
disabled: savingModel === model.id || status?.contextWindowOverrides[model.id] === void 0,
|
|
4524
|
+
onClick: () => void handleResetContextWindow(model.id),
|
|
4525
|
+
children: t.contextWindowReset
|
|
4526
|
+
})
|
|
4527
|
+
]
|
|
4528
|
+
})]
|
|
4529
|
+
}, model.id)),
|
|
4530
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4531
|
+
className: "dsha-actions",
|
|
4532
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
4533
|
+
className: "dsha-btn",
|
|
4534
|
+
disabled: busy !== null || overrideCount === 0,
|
|
4535
|
+
onClick: () => void handleResetAllContextWindows(),
|
|
4536
|
+
children: t.contextWindowResetAll
|
|
4537
|
+
})
|
|
4538
|
+
})
|
|
4539
|
+
]
|
|
4235
4540
|
})
|
|
4236
4541
|
]
|
|
4237
4542
|
}),
|
|
@@ -4289,7 +4594,7 @@ window.__ModuleLoader__.load({
|
|
|
4289
4594
|
window.limit ?? "—",
|
|
4290
4595
|
" ",
|
|
4291
4596
|
t.requests
|
|
4292
|
-
] }), window.resetsAt !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t.resetAt.replace("{time}", formatReset$
|
|
4597
|
+
] }), window.resetsAt !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t.resetAt.replace("{time}", formatReset$2(window.resetsAt)) })]
|
|
4293
4598
|
})
|
|
4294
4599
|
]
|
|
4295
4600
|
}, window.id);
|
|
@@ -4341,7 +4646,7 @@ window.__ModuleLoader__.load({
|
|
|
4341
4646
|
//#endregion
|
|
4342
4647
|
//#region src/client/workbuddy/locales.ts
|
|
4343
4648
|
const NS_WORKBUDDY = "dsh-workbuddy";
|
|
4344
|
-
const zh$
|
|
4649
|
+
const zh$2 = {
|
|
4345
4650
|
title: "WorkBuddy",
|
|
4346
4651
|
pageDesc: "复用本机 CodeBuddy 桌面端登录态,管理 WorkBuddy(CodeBuddy 订阅)模型、上下文窗口与额度。",
|
|
4347
4652
|
account: "账号",
|
|
@@ -4404,6 +4709,10 @@ window.__ModuleLoader__.load({
|
|
|
4404
4709
|
defaultEffortKept: "已保存的档位不被当前任何模型支持,已保留但不会生效。",
|
|
4405
4710
|
contextWindowSection: "模型上下文窗口",
|
|
4406
4711
|
contextWindowHint: "默认值来自订阅网关的模型目录(每个模型的真实上下文上限);可覆盖为自定义容量,该值用于 DSH 的压缩与溢出判断,可输入 1M、512K、200K 等容量。",
|
|
4712
|
+
contextWindowReset: "恢复默认",
|
|
4713
|
+
contextWindowResetAll: "全部恢复默认",
|
|
4714
|
+
contextWindowResetAllConfirm: "确定把已改过的模型上下文窗口全部恢复为默认值吗?",
|
|
4715
|
+
contextWindowNoneEnabled: "还没有勾选任何模型。在上方勾选后,这里会出现该模型的上下文窗口设置。",
|
|
4407
4716
|
save: "保存",
|
|
4408
4717
|
saved: "已保存",
|
|
4409
4718
|
saving: "保存中...",
|
|
@@ -4419,9 +4728,19 @@ window.__ModuleLoader__.load({
|
|
|
4419
4728
|
updatedAt: "更新时间:{time}",
|
|
4420
4729
|
loading: "加载中...",
|
|
4421
4730
|
credits: "credits",
|
|
4422
|
-
composerLabel: "额度"
|
|
4731
|
+
composerLabel: "额度",
|
|
4732
|
+
dailyCheckin: "每日签到",
|
|
4733
|
+
checkinHint: "仅国区账号参与;DSH 启动时自动签到一次,运行期间每 10 分钟补检,进程关闭的当天不会签到。",
|
|
4734
|
+
checkinAuto: "自动签到",
|
|
4735
|
+
checkinToday: "今日已签 {done}/{total}",
|
|
4736
|
+
checkinSkipped: "{count} 个无签到活动",
|
|
4737
|
+
checkinFailed: "{count} 个失败",
|
|
4738
|
+
checkinLastRun: "上次运行:{time}",
|
|
4739
|
+
checkinNever: "尚未运行",
|
|
4740
|
+
checkinNow: "立即签到",
|
|
4741
|
+
checkinRunning: "签到中…"
|
|
4423
4742
|
};
|
|
4424
|
-
const en$
|
|
4743
|
+
const en$2 = {
|
|
4425
4744
|
title: "WorkBuddy",
|
|
4426
4745
|
pageDesc: "Reuse the local CodeBuddy desktop sign-in to manage WorkBuddy (CodeBuddy subscription) models, context windows, and quota.",
|
|
4427
4746
|
account: "Account",
|
|
@@ -4484,6 +4803,10 @@ window.__ModuleLoader__.load({
|
|
|
4484
4803
|
defaultEffortKept: "The saved level is not supported by any current model; it is kept but has no effect.",
|
|
4485
4804
|
contextWindowSection: "Model context window",
|
|
4486
4805
|
contextWindowHint: "Defaults come from the subscription gateway’s own catalog (each model’s real context cap); override one with the capacity DSH should use for compaction and overflow decisions (e.g., 1M, 512K, 200K).",
|
|
4806
|
+
contextWindowReset: "Restore default",
|
|
4807
|
+
contextWindowResetAll: "Restore all defaults",
|
|
4808
|
+
contextWindowResetAllConfirm: "Restore every changed model context window to its default?",
|
|
4809
|
+
contextWindowNoneEnabled: "No model is checked yet. Check one above and its context window setting appears here.",
|
|
4487
4810
|
save: "Save",
|
|
4488
4811
|
saved: "Saved",
|
|
4489
4812
|
saving: "Saving...",
|
|
@@ -4499,13 +4822,23 @@ window.__ModuleLoader__.load({
|
|
|
4499
4822
|
updatedAt: "Updated at: {time}",
|
|
4500
4823
|
loading: "Loading...",
|
|
4501
4824
|
credits: "credits",
|
|
4502
|
-
composerLabel: "Quota"
|
|
4825
|
+
composerLabel: "Quota",
|
|
4826
|
+
dailyCheckin: "Daily check-in",
|
|
4827
|
+
checkinHint: "CN-region accounts only. The host signs in once at startup and re-checks every 10 minutes while running; a day the process never runs is not signed.",
|
|
4828
|
+
checkinAuto: "Auto check-in",
|
|
4829
|
+
checkinToday: "Checked in today {done}/{total}",
|
|
4830
|
+
checkinSkipped: "{count} with no activity",
|
|
4831
|
+
checkinFailed: "{count} failed",
|
|
4832
|
+
checkinLastRun: "Last run: {time}",
|
|
4833
|
+
checkinNever: "Never run",
|
|
4834
|
+
checkinNow: "Check in now",
|
|
4835
|
+
checkinRunning: "Checking in…"
|
|
4503
4836
|
};
|
|
4504
|
-
const dictionaries$
|
|
4505
|
-
zh: zh$
|
|
4506
|
-
"zh-CN": zh$
|
|
4507
|
-
en: en$
|
|
4508
|
-
"en-US": en$
|
|
4837
|
+
const dictionaries$2 = {
|
|
4838
|
+
zh: zh$2,
|
|
4839
|
+
"zh-CN": zh$2,
|
|
4840
|
+
en: en$2,
|
|
4841
|
+
"en-US": en$2
|
|
4509
4842
|
};
|
|
4510
4843
|
//#endregion
|
|
4511
4844
|
//#region src/client/workbuddy/WorkBuddySection.tsx
|
|
@@ -4513,7 +4846,7 @@ window.__ModuleLoader__.load({
|
|
|
4513
4846
|
* Display label per reasoning level. The locale dictionary only accepts flat
|
|
4514
4847
|
* string values, so this nested table lives with the control that renders it.
|
|
4515
4848
|
*/
|
|
4516
|
-
const EFFORT_LABELS = {
|
|
4849
|
+
const EFFORT_LABELS$1 = {
|
|
4517
4850
|
minimal: "Minimal",
|
|
4518
4851
|
low: "Low",
|
|
4519
4852
|
medium: "Medium",
|
|
@@ -4521,7 +4854,7 @@ window.__ModuleLoader__.load({
|
|
|
4521
4854
|
xhigh: "X-High",
|
|
4522
4855
|
max: "Max"
|
|
4523
4856
|
};
|
|
4524
|
-
const API$
|
|
4857
|
+
const API$6 = "/workbuddy/api";
|
|
4525
4858
|
/**
|
|
4526
4859
|
* The shared card's label set.
|
|
4527
4860
|
*
|
|
@@ -4547,8 +4880,8 @@ window.__ModuleLoader__.load({
|
|
|
4547
4880
|
* process (a stale Host has no route to answer), so the error is reported as
|
|
4548
4881
|
* such instead of as a credential problem.
|
|
4549
4882
|
*/
|
|
4550
|
-
async function fetchApi$
|
|
4551
|
-
const res = await fetch(`${API$
|
|
4883
|
+
async function fetchApi$6(path, options) {
|
|
4884
|
+
const res = await fetch(`${API$6}${path}`, {
|
|
4552
4885
|
...options,
|
|
4553
4886
|
headers: {
|
|
4554
4887
|
"Content-Type": "application/json",
|
|
@@ -4567,19 +4900,29 @@ window.__ModuleLoader__.load({
|
|
|
4567
4900
|
return json.value;
|
|
4568
4901
|
}
|
|
4569
4902
|
/** Parse "1M", "512K", "200000" into a positive integer token count. */
|
|
4570
|
-
function parsePositiveCapacity(value) {
|
|
4903
|
+
function parsePositiveCapacity$1(value) {
|
|
4571
4904
|
const matched = value.trim().toLowerCase().replace(/[,_\s]/g, "").match(/^(\d+(?:\.\d+)?)(k|m)?$/);
|
|
4572
4905
|
if (matched === null) return null;
|
|
4573
4906
|
const multiplier = matched[2] === "m" ? 1e6 : matched[2] === "k" ? 1e3 : 1;
|
|
4574
4907
|
const parsed = Number(matched[1]) * multiplier;
|
|
4575
4908
|
return Number.isSafeInteger(parsed) && parsed >= 1 ? parsed : null;
|
|
4576
4909
|
}
|
|
4577
|
-
function formatCapacity(value) {
|
|
4910
|
+
function formatCapacity$1(value) {
|
|
4578
4911
|
if (value >= 1e6 && value % 1e5 === 0) return `${value / 1e6}M`;
|
|
4579
4912
|
if (value >= 1e3 && value % 1e3 === 0) return `${value / 1e3}K`;
|
|
4580
4913
|
return String(value);
|
|
4581
4914
|
}
|
|
4582
|
-
|
|
4915
|
+
/**
|
|
4916
|
+
* Seed one draft per model from a status payload. Also run after a model
|
|
4917
|
+
* toggle: a model that was just enabled has no draft yet, and the context
|
|
4918
|
+
* window section only renders enabled models.
|
|
4919
|
+
*/
|
|
4920
|
+
function contextDraftsFor$1(status) {
|
|
4921
|
+
const drafts = {};
|
|
4922
|
+
for (const model of status.models) drafts[model.id] = formatCapacity$1(status.contextWindowOverrides[model.id] || model.defaultContextWindow);
|
|
4923
|
+
return drafts;
|
|
4924
|
+
}
|
|
4925
|
+
function formatDate$1(ms) {
|
|
4583
4926
|
if (ms === void 0 || ms === null || ms <= 0) return "—";
|
|
4584
4927
|
try {
|
|
4585
4928
|
return new Intl.DateTimeFormat(void 0, {
|
|
@@ -4590,7 +4933,7 @@ window.__ModuleLoader__.load({
|
|
|
4590
4933
|
return "—";
|
|
4591
4934
|
}
|
|
4592
4935
|
}
|
|
4593
|
-
function formatReset(resetsAt) {
|
|
4936
|
+
function formatReset$1(resetsAt) {
|
|
4594
4937
|
if (resetsAt === void 0 || resetsAt === null || resetsAt <= 0) return "";
|
|
4595
4938
|
const diff = resetsAt - Date.now();
|
|
4596
4939
|
if (diff <= 0) return "now";
|
|
@@ -4667,7 +5010,7 @@ window.__ModuleLoader__.load({
|
|
|
4667
5010
|
const loginTimeoutRef = (0, react.useRef)(null);
|
|
4668
5011
|
const [contextDrafts, setContextDrafts] = (0, react.useState)({});
|
|
4669
5012
|
const [savingModel, setSavingModel] = (0, react.useState)(null);
|
|
4670
|
-
const t = zh$
|
|
5013
|
+
const t = zh$2;
|
|
4671
5014
|
const notifyChange = (0, react.useCallback)(() => {
|
|
4672
5015
|
onModelChange?.();
|
|
4673
5016
|
loadModelDirectory?.();
|
|
@@ -4679,12 +5022,10 @@ window.__ModuleLoader__.load({
|
|
|
4679
5022
|
const loadStatus = (0, react.useCallback)(async (quiet = false) => {
|
|
4680
5023
|
if (!quiet) setError(null);
|
|
4681
5024
|
try {
|
|
4682
|
-
const normalized = normalizeStatus(await fetchApi$
|
|
5025
|
+
const normalized = normalizeStatus(await fetchApi$6("/status"));
|
|
4683
5026
|
setStatus(normalized);
|
|
4684
5027
|
setStatusFailed(false);
|
|
4685
|
-
|
|
4686
|
-
for (const model of normalized.models) drafts[model.id] = formatCapacity(normalized.contextWindowOverrides[model.id] || model.defaultContextWindow);
|
|
4687
|
-
setContextDrafts(drafts);
|
|
5028
|
+
setContextDrafts(contextDraftsFor$1(normalized));
|
|
4688
5029
|
} catch (err) {
|
|
4689
5030
|
setStatusFailed(true);
|
|
4690
5031
|
if (!quiet) setError(err instanceof Error ? err.message : String(err));
|
|
@@ -4708,7 +5049,7 @@ window.__ModuleLoader__.load({
|
|
|
4708
5049
|
try {
|
|
4709
5050
|
setBusy("rescan");
|
|
4710
5051
|
setError(null);
|
|
4711
|
-
const updated = await fetchApi$
|
|
5052
|
+
const updated = await fetchApi$6("/rescan", { method: "POST" });
|
|
4712
5053
|
setStatus(normalizeStatus(updated));
|
|
4713
5054
|
notifyChange();
|
|
4714
5055
|
} catch (err) {
|
|
@@ -4722,7 +5063,7 @@ window.__ModuleLoader__.load({
|
|
|
4722
5063
|
setBusy(`login:${region}`);
|
|
4723
5064
|
setError(null);
|
|
4724
5065
|
setLoginProgress(t.loginWaiting);
|
|
4725
|
-
const flow = await fetchApi$
|
|
5066
|
+
const flow = await fetchApi$6("/accounts/login", {
|
|
4726
5067
|
method: "POST",
|
|
4727
5068
|
body: JSON.stringify({ region })
|
|
4728
5069
|
});
|
|
@@ -4732,7 +5073,7 @@ window.__ModuleLoader__.load({
|
|
|
4732
5073
|
const timer = window.setInterval(() => {
|
|
4733
5074
|
(async () => {
|
|
4734
5075
|
try {
|
|
4735
|
-
const poll = await fetchApi$
|
|
5076
|
+
const poll = await fetchApi$6("/accounts/login/status");
|
|
4736
5077
|
if (poll.progress) setLoginProgress(poll.progress);
|
|
4737
5078
|
if (poll.status === "complete") {
|
|
4738
5079
|
window.clearInterval(timer);
|
|
@@ -4741,7 +5082,7 @@ window.__ModuleLoader__.load({
|
|
|
4741
5082
|
loginTimeoutRef.current = null;
|
|
4742
5083
|
setBusy(null);
|
|
4743
5084
|
setLoginProgress(null);
|
|
4744
|
-
if (poll.accountId) await fetchApi$
|
|
5085
|
+
if (poll.accountId) await fetchApi$6("/settings", {
|
|
4745
5086
|
method: "POST",
|
|
4746
5087
|
body: JSON.stringify({ selectedAccountId: poll.accountId })
|
|
4747
5088
|
});
|
|
@@ -4781,7 +5122,7 @@ window.__ModuleLoader__.load({
|
|
|
4781
5122
|
try {
|
|
4782
5123
|
setBusy(`${action}:${accountId}`);
|
|
4783
5124
|
setError(null);
|
|
4784
|
-
const updated = await fetchApi$
|
|
5125
|
+
const updated = await fetchApi$6("/accounts/action", {
|
|
4785
5126
|
method: "POST",
|
|
4786
5127
|
body: JSON.stringify({
|
|
4787
5128
|
action,
|
|
@@ -4804,7 +5145,7 @@ window.__ModuleLoader__.load({
|
|
|
4804
5145
|
try {
|
|
4805
5146
|
setBusy("strategy");
|
|
4806
5147
|
setError(null);
|
|
4807
|
-
const updated = await fetchApi$
|
|
5148
|
+
const updated = await fetchApi$6("/accounts/strategy", {
|
|
4808
5149
|
method: "POST",
|
|
4809
5150
|
body: JSON.stringify({ strategy })
|
|
4810
5151
|
});
|
|
@@ -4819,7 +5160,7 @@ window.__ModuleLoader__.load({
|
|
|
4819
5160
|
try {
|
|
4820
5161
|
setBusy("connection");
|
|
4821
5162
|
setError(null);
|
|
4822
|
-
setConnection(await fetchApi$
|
|
5163
|
+
setConnection(await fetchApi$6("/connection/test", { method: "POST" }));
|
|
4823
5164
|
} catch (err) {
|
|
4824
5165
|
setError(err instanceof Error ? err.message : String(err));
|
|
4825
5166
|
} finally {
|
|
@@ -4830,7 +5171,7 @@ window.__ModuleLoader__.load({
|
|
|
4830
5171
|
try {
|
|
4831
5172
|
setBusy("quota");
|
|
4832
5173
|
setError(null);
|
|
4833
|
-
const updated = await fetchApi$
|
|
5174
|
+
const updated = await fetchApi$6("/quota", { method: "POST" });
|
|
4834
5175
|
setStatus(updated);
|
|
4835
5176
|
} catch (err) {
|
|
4836
5177
|
setError(err instanceof Error ? err.message : String(err));
|
|
@@ -4838,11 +5179,38 @@ window.__ModuleLoader__.load({
|
|
|
4838
5179
|
setBusy(null);
|
|
4839
5180
|
}
|
|
4840
5181
|
};
|
|
5182
|
+
const handleCheckinNow = async () => {
|
|
5183
|
+
try {
|
|
5184
|
+
setBusy("checkin");
|
|
5185
|
+
setError(null);
|
|
5186
|
+
const updated = await fetchApi$6("/checkin/now", { method: "POST" });
|
|
5187
|
+
setStatus(normalizeStatus(updated));
|
|
5188
|
+
} catch (err) {
|
|
5189
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
5190
|
+
} finally {
|
|
5191
|
+
setBusy(null);
|
|
5192
|
+
}
|
|
5193
|
+
};
|
|
5194
|
+
const handleCheckinPatch = async (checkin) => {
|
|
5195
|
+
try {
|
|
5196
|
+
setBusy("checkin");
|
|
5197
|
+
setError(null);
|
|
5198
|
+
const updated = await fetchApi$6("/settings", {
|
|
5199
|
+
method: "POST",
|
|
5200
|
+
body: JSON.stringify({ checkin })
|
|
5201
|
+
});
|
|
5202
|
+
setStatus(normalizeStatus(updated));
|
|
5203
|
+
} catch (err) {
|
|
5204
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
5205
|
+
} finally {
|
|
5206
|
+
setBusy(null);
|
|
5207
|
+
}
|
|
5208
|
+
};
|
|
4841
5209
|
const toggleEnabled = async (enabled) => {
|
|
4842
5210
|
try {
|
|
4843
5211
|
setBusy("enabled");
|
|
4844
5212
|
setError(null);
|
|
4845
|
-
const updated = await fetchApi$
|
|
5213
|
+
const updated = await fetchApi$6("/settings", {
|
|
4846
5214
|
method: "POST",
|
|
4847
5215
|
body: JSON.stringify({ enabled })
|
|
4848
5216
|
});
|
|
@@ -4861,11 +5229,12 @@ window.__ModuleLoader__.load({
|
|
|
4861
5229
|
try {
|
|
4862
5230
|
setBusy(`model:${modelId}`);
|
|
4863
5231
|
setError(null);
|
|
4864
|
-
const
|
|
5232
|
+
const normalized = normalizeStatus(await fetchApi$6("/settings", {
|
|
4865
5233
|
method: "POST",
|
|
4866
5234
|
body: JSON.stringify({ enabledModelIds: next })
|
|
4867
|
-
});
|
|
4868
|
-
setStatus(
|
|
5235
|
+
}));
|
|
5236
|
+
setStatus(normalized);
|
|
5237
|
+
setContextDrafts(contextDraftsFor$1(normalized));
|
|
4869
5238
|
notifyChange();
|
|
4870
5239
|
} catch (err) {
|
|
4871
5240
|
setError(err instanceof Error ? err.message : String(err));
|
|
@@ -4878,11 +5247,12 @@ window.__ModuleLoader__.load({
|
|
|
4878
5247
|
try {
|
|
4879
5248
|
setBusy("models-all");
|
|
4880
5249
|
setError(null);
|
|
4881
|
-
const
|
|
5250
|
+
const normalized = normalizeStatus(await fetchApi$6("/settings", {
|
|
4882
5251
|
method: "POST",
|
|
4883
5252
|
body: JSON.stringify({ enabledModelIds: enabled ? status.models.map((model) => model.id) : [] })
|
|
4884
|
-
});
|
|
4885
|
-
setStatus(
|
|
5253
|
+
}));
|
|
5254
|
+
setStatus(normalized);
|
|
5255
|
+
setContextDrafts(contextDraftsFor$1(normalized));
|
|
4886
5256
|
notifyChange();
|
|
4887
5257
|
} catch (err) {
|
|
4888
5258
|
setError(err instanceof Error ? err.message : String(err));
|
|
@@ -4894,7 +5264,7 @@ window.__ModuleLoader__.load({
|
|
|
4894
5264
|
try {
|
|
4895
5265
|
setBusy("effort");
|
|
4896
5266
|
setError(null);
|
|
4897
|
-
const updated = await fetchApi$
|
|
5267
|
+
const updated = await fetchApi$6("/settings", {
|
|
4898
5268
|
method: "POST",
|
|
4899
5269
|
body: JSON.stringify({ defaultReasoningEffort: effort })
|
|
4900
5270
|
});
|
|
@@ -4910,16 +5280,9 @@ window.__ModuleLoader__.load({
|
|
|
4910
5280
|
try {
|
|
4911
5281
|
setBusy("catalog");
|
|
4912
5282
|
setError(null);
|
|
4913
|
-
const
|
|
4914
|
-
const normalized = {
|
|
4915
|
-
...updated,
|
|
4916
|
-
models: Array.isArray(updated?.models) ? updated.models : [],
|
|
4917
|
-
contextWindowOverrides: updated?.contextWindowOverrides ?? {}
|
|
4918
|
-
};
|
|
5283
|
+
const normalized = normalizeStatus(await fetchApi$6("/catalog/refresh", { method: "POST" }));
|
|
4919
5284
|
setStatus(normalized);
|
|
4920
|
-
|
|
4921
|
-
for (const model of normalized.models) drafts[model.id] = formatCapacity(normalized.contextWindowOverrides[model.id] || model.defaultContextWindow);
|
|
4922
|
-
setContextDrafts(drafts);
|
|
5285
|
+
setContextDrafts(contextDraftsFor$1(normalized));
|
|
4923
5286
|
notifyChange();
|
|
4924
5287
|
} catch (err) {
|
|
4925
5288
|
setError(err instanceof Error ? err.message : String(err));
|
|
@@ -4929,7 +5292,7 @@ window.__ModuleLoader__.load({
|
|
|
4929
5292
|
};
|
|
4930
5293
|
const handleSaveContextWindow = async (modelId) => {
|
|
4931
5294
|
const raw = contextDrafts[modelId] || "";
|
|
4932
|
-
const parsed = parsePositiveCapacity(raw);
|
|
5295
|
+
const parsed = parsePositiveCapacity$1(raw);
|
|
4933
5296
|
if (parsed === null) {
|
|
4934
5297
|
setError(`Invalid context capacity: ${raw}`);
|
|
4935
5298
|
return;
|
|
@@ -4937,15 +5300,39 @@ window.__ModuleLoader__.load({
|
|
|
4937
5300
|
try {
|
|
4938
5301
|
setSavingModel(modelId);
|
|
4939
5302
|
setError(null);
|
|
4940
|
-
const updated = await fetchApi$
|
|
5303
|
+
const updated = await fetchApi$6("/settings", {
|
|
4941
5304
|
method: "POST",
|
|
4942
5305
|
body: JSON.stringify({ contextWindowOverrides: { [modelId]: parsed } })
|
|
4943
5306
|
});
|
|
4944
5307
|
setStatus(updated);
|
|
4945
5308
|
setContextDrafts((prev) => ({
|
|
4946
5309
|
...prev,
|
|
4947
|
-
[modelId]: formatCapacity(parsed)
|
|
5310
|
+
[modelId]: formatCapacity$1(parsed)
|
|
5311
|
+
}));
|
|
5312
|
+
notifyChange();
|
|
5313
|
+
} catch (err) {
|
|
5314
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
5315
|
+
} finally {
|
|
5316
|
+
setSavingModel(null);
|
|
5317
|
+
}
|
|
5318
|
+
};
|
|
5319
|
+
/** Clear one override; the row falls back to the catalog length. */
|
|
5320
|
+
const handleResetContextWindow = async (modelId) => {
|
|
5321
|
+
try {
|
|
5322
|
+
setSavingModel(modelId);
|
|
5323
|
+
setError(null);
|
|
5324
|
+
const updated = normalizeStatus(await fetchApi$6("/settings", {
|
|
5325
|
+
method: "POST",
|
|
5326
|
+
body: JSON.stringify({ contextWindowOverrides: { [modelId]: null } })
|
|
4948
5327
|
}));
|
|
5328
|
+
setStatus(updated);
|
|
5329
|
+
setContextDrafts((prev) => {
|
|
5330
|
+
const model = updated.models.find((candidate) => candidate.id === modelId);
|
|
5331
|
+
return model === void 0 ? prev : {
|
|
5332
|
+
...prev,
|
|
5333
|
+
[modelId]: formatCapacity$1(model.defaultContextWindow)
|
|
5334
|
+
};
|
|
5335
|
+
});
|
|
4949
5336
|
notifyChange();
|
|
4950
5337
|
} catch (err) {
|
|
4951
5338
|
setError(err instanceof Error ? err.message : String(err));
|
|
@@ -4953,6 +5340,29 @@ window.__ModuleLoader__.load({
|
|
|
4953
5340
|
setSavingModel(null);
|
|
4954
5341
|
}
|
|
4955
5342
|
};
|
|
5343
|
+
/** Clear every stored override, including models the picker no longer shows. */
|
|
5344
|
+
const handleResetAllContextWindows = async () => {
|
|
5345
|
+
const models = Object.keys(status?.contextWindowOverrides ?? {});
|
|
5346
|
+
if (models.length === 0) return;
|
|
5347
|
+
if (!window.confirm(t.contextWindowResetAllConfirm)) return;
|
|
5348
|
+
try {
|
|
5349
|
+
setBusy("context");
|
|
5350
|
+
setError(null);
|
|
5351
|
+
const updated = normalizeStatus(await fetchApi$6("/settings", {
|
|
5352
|
+
method: "POST",
|
|
5353
|
+
body: JSON.stringify({ contextWindowOverrides: Object.fromEntries(models.map((model) => [model, null])) })
|
|
5354
|
+
}));
|
|
5355
|
+
setStatus(updated);
|
|
5356
|
+
setContextDrafts(contextDraftsFor$1(updated));
|
|
5357
|
+
notifyChange();
|
|
5358
|
+
} catch (err) {
|
|
5359
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
5360
|
+
} finally {
|
|
5361
|
+
setBusy(null);
|
|
5362
|
+
}
|
|
5363
|
+
};
|
|
5364
|
+
const contextModels = status?.models.filter((model) => model.enabled) ?? [];
|
|
5365
|
+
const overrideCount = Object.keys(status?.contextWindowOverrides ?? {}).length;
|
|
4956
5366
|
if (loading) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4957
5367
|
className: "dsha-page",
|
|
4958
5368
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
@@ -5066,6 +5476,57 @@ window.__ModuleLoader__.load({
|
|
|
5066
5476
|
})
|
|
5067
5477
|
]
|
|
5068
5478
|
}),
|
|
5479
|
+
status?.checkin != null ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
5480
|
+
className: "dsha-group",
|
|
5481
|
+
children: [
|
|
5482
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5483
|
+
className: "dsha-grouphead",
|
|
5484
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t.dailyCheckin })
|
|
5485
|
+
}),
|
|
5486
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
5487
|
+
className: "dsha-muted",
|
|
5488
|
+
children: t.checkinHint
|
|
5489
|
+
}),
|
|
5490
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5491
|
+
className: "dsha-row",
|
|
5492
|
+
style: { marginBottom: 8 },
|
|
5493
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5494
|
+
className: "dsha-label",
|
|
5495
|
+
style: { fontWeight: 600 },
|
|
5496
|
+
children: t.checkinAuto
|
|
5497
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
5498
|
+
type: "checkbox",
|
|
5499
|
+
checked: status.checkin.enabled,
|
|
5500
|
+
disabled: busy !== null,
|
|
5501
|
+
onChange: (event) => void handleCheckinPatch({ enabled: event.currentTarget.checked })
|
|
5502
|
+
})]
|
|
5503
|
+
}),
|
|
5504
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5505
|
+
className: "dsha-row",
|
|
5506
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5507
|
+
className: "dsha-label",
|
|
5508
|
+
children: t.dailyCheckin
|
|
5509
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
5510
|
+
className: "dsha-value",
|
|
5511
|
+
children: [
|
|
5512
|
+
t.checkinToday.replace("{done}", String(status.checkin.doneToday)).replace("{total}", String(status.checkin.totalAccounts)),
|
|
5513
|
+
status.checkin.skippedToday > 0 ? ` · ${t.checkinSkipped.replace("{count}", String(status.checkin.skippedToday))}` : "",
|
|
5514
|
+
status.checkin.failedToday > 0 ? ` · ${t.checkinFailed.replace("{count}", String(status.checkin.failedToday))}` : "",
|
|
5515
|
+
` · ${status.checkin.lastRunAt === null ? t.checkinNever : t.checkinLastRun.replace("{time}", new Date(status.checkin.lastRunAt).toLocaleString())}`
|
|
5516
|
+
]
|
|
5517
|
+
})]
|
|
5518
|
+
}),
|
|
5519
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5520
|
+
className: "dsha-actions",
|
|
5521
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
5522
|
+
className: "dsha-btn",
|
|
5523
|
+
disabled: busy !== null,
|
|
5524
|
+
onClick: () => void handleCheckinNow(),
|
|
5525
|
+
children: busy === "checkin" ? t.checkinRunning : t.checkinNow
|
|
5526
|
+
})
|
|
5527
|
+
})
|
|
5528
|
+
]
|
|
5529
|
+
}) : null,
|
|
5069
5530
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
5070
5531
|
className: "dsha-group",
|
|
5071
5532
|
children: [
|
|
@@ -5145,7 +5606,7 @@ window.__ModuleLoader__.load({
|
|
|
5145
5606
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
5146
5607
|
title: [
|
|
5147
5608
|
model.id,
|
|
5148
|
-
formatCapacity(model.contextWindow),
|
|
5609
|
+
formatCapacity$1(model.contextWindow),
|
|
5149
5610
|
model.supportsImage ? t.imageSupport : t.textOnly,
|
|
5150
5611
|
...model.reasoningEfforts && model.reasoningEfforts.length > 0 ? [model.reasoningEfforts.join("/")] : []
|
|
5151
5612
|
].join(" · "),
|
|
@@ -5209,11 +5670,11 @@ window.__ModuleLoader__.load({
|
|
|
5209
5670
|
}),
|
|
5210
5671
|
strayEffort !== null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
5211
5672
|
value: strayEffort,
|
|
5212
|
-
children: `${EFFORT_LABELS[strayEffort]} (${t.effortUnsupported})`
|
|
5673
|
+
children: `${EFFORT_LABELS$1[strayEffort]} (${t.effortUnsupported})`
|
|
5213
5674
|
}) : null,
|
|
5214
5675
|
effortChoices.map((choice) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
5215
5676
|
value: choice.value,
|
|
5216
|
-
children: choice.models.length === allModels.length ? EFFORT_LABELS[choice.value] : `${EFFORT_LABELS[choice.value]} (${choice.models.length}/${allModels.length})`
|
|
5677
|
+
children: choice.models.length === allModels.length ? EFFORT_LABELS$1[choice.value] : `${EFFORT_LABELS$1[choice.value]} (${choice.models.length}/${allModels.length})`
|
|
5217
5678
|
}, choice.value))
|
|
5218
5679
|
]
|
|
5219
5680
|
})]
|
|
@@ -5235,39 +5696,988 @@ window.__ModuleLoader__.load({
|
|
|
5235
5696
|
className: "dsha-muted",
|
|
5236
5697
|
children: t.contextWindowHint
|
|
5237
5698
|
}),
|
|
5238
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
5699
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5700
|
+
className: "dsha-context-settings",
|
|
5701
|
+
children: [
|
|
5702
|
+
contextModels.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
5703
|
+
className: "dsha-muted",
|
|
5704
|
+
children: t.contextWindowNoneEnabled
|
|
5705
|
+
}),
|
|
5706
|
+
contextModels.map((model) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5707
|
+
className: "dsha-context-row",
|
|
5708
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5709
|
+
title: model.id,
|
|
5710
|
+
children: model.name
|
|
5711
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5712
|
+
className: "dsha-capacity-control",
|
|
5713
|
+
children: [
|
|
5714
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
5715
|
+
type: "text",
|
|
5716
|
+
"aria-label": `${model.name} context window`,
|
|
5717
|
+
value: contextDrafts[model.id] ?? "",
|
|
5718
|
+
onChange: (event) => setContextDrafts({
|
|
5719
|
+
...contextDrafts,
|
|
5720
|
+
[model.id]: event.currentTarget.value
|
|
5721
|
+
}),
|
|
5722
|
+
onKeyDown: (event) => {
|
|
5723
|
+
if (event.key === "Enter") handleSaveContextWindow(model.id);
|
|
5724
|
+
}
|
|
5725
|
+
}),
|
|
5726
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: "tokens" }),
|
|
5727
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
5728
|
+
type: "button",
|
|
5729
|
+
className: "dsha-context-save",
|
|
5730
|
+
disabled: savingModel === model.id,
|
|
5731
|
+
onClick: () => void handleSaveContextWindow(model.id),
|
|
5732
|
+
children: savingModel === model.id ? t.saving : t.save
|
|
5733
|
+
}),
|
|
5734
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
5735
|
+
type: "button",
|
|
5736
|
+
className: "dsha-context-save dsha-context-reset",
|
|
5737
|
+
"aria-label": `${model.name} ${t.contextWindowReset}`,
|
|
5738
|
+
disabled: savingModel === model.id || status?.contextWindowOverrides[model.id] === void 0,
|
|
5739
|
+
onClick: () => void handleResetContextWindow(model.id),
|
|
5740
|
+
children: t.contextWindowReset
|
|
5741
|
+
})
|
|
5742
|
+
]
|
|
5743
|
+
})]
|
|
5744
|
+
}, model.id)),
|
|
5745
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5746
|
+
className: "dsha-actions",
|
|
5747
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
5748
|
+
className: "dsha-btn",
|
|
5749
|
+
disabled: busy !== null || overrideCount === 0,
|
|
5750
|
+
onClick: () => void handleResetAllContextWindows(),
|
|
5751
|
+
children: t.contextWindowResetAll
|
|
5752
|
+
})
|
|
5753
|
+
})
|
|
5754
|
+
]
|
|
5755
|
+
})
|
|
5756
|
+
]
|
|
5757
|
+
}),
|
|
5758
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
5759
|
+
className: "dsha-group",
|
|
5760
|
+
children: [
|
|
5761
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5762
|
+
className: "dsha-grouphead",
|
|
5763
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t.quotaSection }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
5764
|
+
className: "dsha-btn",
|
|
5765
|
+
disabled: busy !== null || !authenticated,
|
|
5766
|
+
onClick: () => void handleRefreshQuota(),
|
|
5767
|
+
children: busy === "quota" ? t.refreshingQuota : t.refreshQuota
|
|
5768
|
+
})]
|
|
5769
|
+
}),
|
|
5770
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
5771
|
+
className: "dsha-muted",
|
|
5772
|
+
children: t.quotaDesc
|
|
5773
|
+
}),
|
|
5774
|
+
!authenticated ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5775
|
+
className: "dsha-empty",
|
|
5776
|
+
children: t.signedOut
|
|
5777
|
+
}) : quota === null || quota === void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5778
|
+
className: "dsha-empty",
|
|
5779
|
+
children: busy === "quota" ? t.refreshingQuota : t.quotaEmpty
|
|
5780
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5781
|
+
className: "dsha-quota-card",
|
|
5782
|
+
children: [
|
|
5783
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5784
|
+
className: "dsha-quota-title",
|
|
5785
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: quota.packageName || t.quotaPackage }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: quota.remainingCredits !== null ? `${quota.remainingCredits} ${t.credits}` : "—" })]
|
|
5786
|
+
}),
|
|
5787
|
+
quota.cycleUsedCredits !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5788
|
+
className: "dsha-row",
|
|
5789
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5790
|
+
className: "dsha-label",
|
|
5791
|
+
children: t.quotaCycle
|
|
5792
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
5793
|
+
className: "dsha-value",
|
|
5794
|
+
children: [
|
|
5795
|
+
quota.cycleUsedCredits,
|
|
5796
|
+
quota.cycleCredits !== null ? ` / ${quota.cycleCredits}` : "",
|
|
5797
|
+
` ${t.credits}`
|
|
5798
|
+
]
|
|
5799
|
+
})]
|
|
5800
|
+
}),
|
|
5801
|
+
quota.cycleEndsAt !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5802
|
+
className: "dsha-row",
|
|
5803
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5804
|
+
className: "dsha-label",
|
|
5805
|
+
children: t.quotaReset
|
|
5806
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
5807
|
+
className: "dsha-value",
|
|
5808
|
+
children: [formatDate$1(quota.cycleEndsAt), formatReset$1(quota.cycleEndsAt) ? ` · ${formatReset$1(quota.cycleEndsAt)}` : ""]
|
|
5809
|
+
})]
|
|
5810
|
+
}),
|
|
5811
|
+
quota.meters.map((meter) => {
|
|
5812
|
+
const remaining = meter.remainingFraction;
|
|
5813
|
+
const percent = remaining === null ? null : Math.round(remaining * 100);
|
|
5814
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5815
|
+
className: "dsha-meter-wrap",
|
|
5816
|
+
children: [
|
|
5817
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5818
|
+
className: "dsha-meter-label",
|
|
5819
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: meter.label }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: percent === null ? meter.limit ?? "—" : `${percent}% left` })]
|
|
5820
|
+
}),
|
|
5821
|
+
percent !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5822
|
+
className: "dsha-meter dsha-meter-green",
|
|
5823
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { style: { width: `${percent}%` } })
|
|
5824
|
+
}),
|
|
5825
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5826
|
+
className: "dsha-meter-meta",
|
|
5827
|
+
children: [meter.used !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
|
|
5828
|
+
meter.used,
|
|
5829
|
+
" / ",
|
|
5830
|
+
meter.limit ?? "—"
|
|
5831
|
+
] }), meter.resetsAt !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
|
|
5832
|
+
t.quotaReset,
|
|
5833
|
+
": ",
|
|
5834
|
+
formatReset$1(meter.resetsAt)
|
|
5835
|
+
] })]
|
|
5836
|
+
})
|
|
5837
|
+
]
|
|
5838
|
+
}, meter.id);
|
|
5839
|
+
}),
|
|
5840
|
+
quota.meters.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5841
|
+
className: "dsha-empty",
|
|
5842
|
+
children: t.quotaEmpty
|
|
5843
|
+
}),
|
|
5844
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5845
|
+
className: "dsha-timestamp",
|
|
5846
|
+
children: t.updatedAt.replace("{time}", new Date(quota.fetchedAt).toLocaleString())
|
|
5847
|
+
})
|
|
5848
|
+
]
|
|
5849
|
+
})
|
|
5850
|
+
]
|
|
5851
|
+
}),
|
|
5852
|
+
error && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5853
|
+
className: "dsha-error",
|
|
5854
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { children: error })
|
|
5855
|
+
})
|
|
5856
|
+
]
|
|
5857
|
+
});
|
|
5858
|
+
}
|
|
5859
|
+
//#endregion
|
|
5860
|
+
//#region src/shared/zhipu-contracts.ts
|
|
5861
|
+
/** Every level this route can name, in escalating order (the card's sort key). */
|
|
5862
|
+
const ZHIPU_REASONING_EFFORTS = [
|
|
5863
|
+
"low",
|
|
5864
|
+
"high",
|
|
5865
|
+
"max"
|
|
5866
|
+
];
|
|
5867
|
+
({
|
|
5868
|
+
none: 0,
|
|
5869
|
+
minimal: 1,
|
|
5870
|
+
low: 2,
|
|
5871
|
+
medium: 3,
|
|
5872
|
+
high: 4,
|
|
5873
|
+
xhigh: 5,
|
|
5874
|
+
max: 6
|
|
5875
|
+
}).high;
|
|
5876
|
+
//#endregion
|
|
5877
|
+
//#region src/client/zhipu/locales.ts
|
|
5878
|
+
const NS_ZHIPU = "dsh-zhipu";
|
|
5879
|
+
const zh$1 = {
|
|
5880
|
+
...accountPoolZh,
|
|
5881
|
+
title: "GLM(智谱 Coding Plan)",
|
|
5882
|
+
pageDesc: "添加智谱 / Z.ai 的 GLM Coding Plan API Key,管理可用模型、上下文窗口与额度。",
|
|
5883
|
+
account: "账号",
|
|
5884
|
+
signedIn: "已登录",
|
|
5885
|
+
signedOut: "未登录",
|
|
5886
|
+
region: "区域",
|
|
5887
|
+
regionIntl: "国际区 (api.z.ai)",
|
|
5888
|
+
regionCn: "国区 (open.bigmodel.cn)",
|
|
5889
|
+
keyHint: "Key 尾号",
|
|
5890
|
+
plan: "套餐",
|
|
5891
|
+
planUnknown: "—",
|
|
5892
|
+
renews: "续费于",
|
|
5893
|
+
authenticatedAt: "添加时间",
|
|
5894
|
+
storage: "凭据存储",
|
|
5895
|
+
storageNotice: "API Key 由 Host 保存于本地加密存储,不会进入浏览器。",
|
|
5896
|
+
signOut: "注销",
|
|
5897
|
+
addKeySection: "添加 API Key",
|
|
5898
|
+
addKeyHint: "在对应开放平台的「API Keys」页创建 Key 后粘贴到此处。它必须来自你订阅 Coding Plan 的那个平台:国区 Key 与国际区 Key 互不通用,开放平台(/api/paas/v4)的通用 Key 在订阅接口上会被拒绝。",
|
|
5899
|
+
keyPlaceholder: "粘贴 GLM Coding Plan API Key",
|
|
5900
|
+
keySave: "保存并验证",
|
|
5901
|
+
keySaving: "验证中...",
|
|
5902
|
+
keySaved: "已保存",
|
|
5903
|
+
connection: "连接",
|
|
5904
|
+
provider: "Provider",
|
|
5905
|
+
providerValue: "GLM(智谱 Coding Plan)· zhipu-coding-plan",
|
|
5906
|
+
connectionState: "连接状态",
|
|
5907
|
+
connected: "已连接",
|
|
5908
|
+
untested: "未测试",
|
|
5909
|
+
testConnection: "测试连接",
|
|
5910
|
+
testingConnection: "测试中...",
|
|
5911
|
+
routeOwned: "模型路由由本插件提供",
|
|
5912
|
+
routeConflict: "模型路由已被其他 Provider 占用:{detail}。请在 DSH 设置中移除重复的 Provider 配置后重试。",
|
|
5913
|
+
modelsSection: "模型",
|
|
5914
|
+
enableProvider: "启用此供应商",
|
|
5915
|
+
modelsHint: "勾选后模型才会出现在对话页的模型选择列表中;全部取消勾选或关闭上方开关可在列表中隐藏该供应商。",
|
|
5916
|
+
refreshCatalog: "刷新模型目录",
|
|
5917
|
+
refreshingCatalog: "刷新中...",
|
|
5918
|
+
selectAll: "全选",
|
|
5919
|
+
unselectAll: "全不选",
|
|
5920
|
+
effectiveWindow: "有效窗口",
|
|
5921
|
+
enhanced: "增强功能",
|
|
5922
|
+
defaultReasoningEffort: "默认思考深度",
|
|
5923
|
+
defaultReasoningEffortHint: "仅对声明了思考档位的模型生效。上游只接受 low / high / max,其余档位会收敛到最近的可用档位后发出(不支持的档位会直接报错)。",
|
|
5924
|
+
defaultEffortAuto: "使用 Provider 默认值",
|
|
5925
|
+
contextWindowSection: "模型上下文窗口",
|
|
5926
|
+
contextWindowHint: "默认取该模型官方声明的上下文窗口;可覆盖为自定义容量,该值用于 DSH 的压缩与溢出判断,可输入 1M、512K、200K 等容量。",
|
|
5927
|
+
contextWindowReset: "恢复默认",
|
|
5928
|
+
contextWindowResetAll: "全部恢复默认",
|
|
5929
|
+
contextWindowResetAllConfirm: "确定把已改过的模型上下文窗口全部恢复为默认值吗?",
|
|
5930
|
+
contextWindowNoneEnabled: "还没有勾选任何模型。在上方勾选后,这里会出现该模型的上下文窗口设置。",
|
|
5931
|
+
save: "保存",
|
|
5932
|
+
saved: "已保存",
|
|
5933
|
+
saving: "保存中...",
|
|
5934
|
+
quotaSection: "用量与配额",
|
|
5935
|
+
quotaDesc: "数据来自 GLM Coding Plan 的用量接口,页面可见时最多每 60 秒刷新一次。Coding Plan 同时受 5 小时额度与每周额度限制。",
|
|
5936
|
+
refreshQuota: "刷新用量",
|
|
5937
|
+
refreshingQuota: "刷新中...",
|
|
5938
|
+
quotaEmpty: "暂无配额数据,点击「刷新用量」重试。",
|
|
5939
|
+
quotaUnavailable: "该账号没有可用的配额数据(通常是套餐未生效,或 Key 不属于 Coding Plan)。",
|
|
5940
|
+
quotaError: "配额读取失败",
|
|
5941
|
+
updatedAt: "更新时间:{time}",
|
|
5942
|
+
loading: "加载中...",
|
|
5943
|
+
tokens: "tokens",
|
|
5944
|
+
left: "剩余",
|
|
5945
|
+
resetAt: "重置于",
|
|
5946
|
+
now: "即将重置"
|
|
5947
|
+
};
|
|
5948
|
+
const en$1 = {
|
|
5949
|
+
...accountPoolEn,
|
|
5950
|
+
title: "GLM (Zhipu Coding Plan)",
|
|
5951
|
+
pageDesc: "Add a GLM Coding Plan API key for Zhipu / Z.ai and manage models, context windows, and quota.",
|
|
5952
|
+
account: "Account",
|
|
5953
|
+
signedIn: "Signed in",
|
|
5954
|
+
signedOut: "Not signed in",
|
|
5955
|
+
region: "Region",
|
|
5956
|
+
regionIntl: "International (api.z.ai)",
|
|
5957
|
+
regionCn: "China (open.bigmodel.cn)",
|
|
5958
|
+
keyHint: "Key suffix",
|
|
5959
|
+
plan: "Plan",
|
|
5960
|
+
planUnknown: "—",
|
|
5961
|
+
renews: "renews",
|
|
5962
|
+
authenticatedAt: "Added at",
|
|
5963
|
+
storage: "Credential storage",
|
|
5964
|
+
storageNotice: "The API key is stored locally by the Host in encrypted storage and never reaches the browser.",
|
|
5965
|
+
signOut: "Sign out",
|
|
5966
|
+
addKeySection: "Add an API key",
|
|
5967
|
+
addKeyHint: "Create a key on the console’s API Keys page and paste it here. It must come from the platform your Coding Plan was bought on: China and international keys are not interchangeable, and a general open-platform key (/api/paas/v4) is rejected by the subscription surface.",
|
|
5968
|
+
keyPlaceholder: "Paste a GLM Coding Plan API key",
|
|
5969
|
+
keySave: "Save and verify",
|
|
5970
|
+
keySaving: "Verifying...",
|
|
5971
|
+
keySaved: "Saved",
|
|
5972
|
+
connection: "Connection",
|
|
5973
|
+
provider: "Provider",
|
|
5974
|
+
providerValue: "GLM (Zhipu Coding Plan) · zhipu-coding-plan",
|
|
5975
|
+
connectionState: "Connection state",
|
|
5976
|
+
connected: "Connected",
|
|
5977
|
+
untested: "Untested",
|
|
5978
|
+
testConnection: "Test connection",
|
|
5979
|
+
testingConnection: "Testing...",
|
|
5980
|
+
routeOwned: "This plugin serves the model route",
|
|
5981
|
+
routeConflict: "Another provider already owns the model route: {detail}. Remove the duplicate provider configuration in DSH settings and reload.",
|
|
5982
|
+
modelsSection: "Models",
|
|
5983
|
+
enableProvider: "Enable this provider",
|
|
5984
|
+
modelsHint: "Checked models appear in the DSH conversation model list; unchecking all or turning off the switch hides this provider.",
|
|
5985
|
+
refreshCatalog: "Refresh catalog",
|
|
5986
|
+
refreshingCatalog: "Refreshing...",
|
|
5987
|
+
selectAll: "Select all",
|
|
5988
|
+
unselectAll: "Deselect all",
|
|
5989
|
+
effectiveWindow: "Effective window",
|
|
5990
|
+
enhanced: "Enhanced features",
|
|
5991
|
+
defaultReasoningEffort: "Default reasoning effort",
|
|
5992
|
+
defaultReasoningEffortHint: "Applies only to models that declare a reasoning ladder. The provider accepts low / high / max; any other level is converged onto the nearest supported one before it is sent, because an unsupported level is rejected outright.",
|
|
5993
|
+
defaultEffortAuto: "Use provider default",
|
|
5994
|
+
contextWindowSection: "Model context window",
|
|
5995
|
+
contextWindowHint: "Defaults to the window the model itself declares; override it with the capacity DSH should use for compaction and overflow decisions (e.g., 1M, 512K, 200K).",
|
|
5996
|
+
contextWindowReset: "Restore default",
|
|
5997
|
+
contextWindowResetAll: "Restore all defaults",
|
|
5998
|
+
contextWindowResetAllConfirm: "Restore every changed model context window to its default?",
|
|
5999
|
+
contextWindowNoneEnabled: "No model is checked yet. Check one above and its context window setting appears here.",
|
|
6000
|
+
save: "Save",
|
|
6001
|
+
saved: "Saved",
|
|
6002
|
+
saving: "Saving...",
|
|
6003
|
+
quotaSection: "Usage & quota",
|
|
6004
|
+
quotaDesc: "Read from the GLM Coding Plan usage endpoints; refreshes at most once every 60 seconds while visible. A Coding Plan is bounded by both a 5-hour and a weekly allowance.",
|
|
6005
|
+
refreshQuota: "Refresh quota",
|
|
6006
|
+
refreshingQuota: "Refreshing...",
|
|
6007
|
+
quotaEmpty: "No quota data yet — use “Refresh quota” to retry.",
|
|
6008
|
+
quotaUnavailable: "This account reports no usable quota (usually an inactive plan, or a key that is not a Coding Plan key).",
|
|
6009
|
+
quotaError: "Quota lookup failed",
|
|
6010
|
+
updatedAt: "Updated at: {time}",
|
|
6011
|
+
loading: "Loading...",
|
|
6012
|
+
tokens: "tokens",
|
|
6013
|
+
left: "left",
|
|
6014
|
+
resetAt: "Resets at",
|
|
6015
|
+
now: "resetting now"
|
|
6016
|
+
};
|
|
6017
|
+
const dictionaries$1 = {
|
|
6018
|
+
zh: zh$1,
|
|
6019
|
+
"zh-CN": zh$1,
|
|
6020
|
+
en: en$1,
|
|
6021
|
+
"en-US": en$1
|
|
6022
|
+
};
|
|
6023
|
+
//#endregion
|
|
6024
|
+
//#region src/client/zhipu/ZhipuSection.tsx
|
|
6025
|
+
/**
|
|
6026
|
+
* Display label per reasoning level. The locale dictionary only accepts flat
|
|
6027
|
+
* string values, so this table lives with the control that renders it.
|
|
6028
|
+
*/
|
|
6029
|
+
const EFFORT_LABELS = {
|
|
6030
|
+
low: "Low",
|
|
6031
|
+
high: "High",
|
|
6032
|
+
max: "Max"
|
|
6033
|
+
};
|
|
6034
|
+
const API$5 = "/zhipu/api";
|
|
6035
|
+
async function fetchApi$5(path, options) {
|
|
6036
|
+
const res = await fetch(`${API$5}${path}`, {
|
|
6037
|
+
...options,
|
|
6038
|
+
headers: {
|
|
6039
|
+
"Content-Type": "application/json",
|
|
6040
|
+
...options?.headers
|
|
6041
|
+
}
|
|
6042
|
+
});
|
|
6043
|
+
const json = await res.json();
|
|
6044
|
+
if (!res.ok || !json.ok) throw new Error(json.error || `HTTP ${res.status}`);
|
|
6045
|
+
return json.value;
|
|
6046
|
+
}
|
|
6047
|
+
/** Parse "1M", "512K", "200000" into a positive integer token count. */
|
|
6048
|
+
function parsePositiveCapacity(value) {
|
|
6049
|
+
const matched = value.trim().toLowerCase().replace(/[,_\s]/g, "").match(/^(\d+(?:\.\d+)?)(k|m)?$/);
|
|
6050
|
+
if (matched === null) return null;
|
|
6051
|
+
const multiplier = matched[2] === "m" ? 1e6 : matched[2] === "k" ? 1e3 : 1;
|
|
6052
|
+
const parsed = Number(matched[1]) * multiplier;
|
|
6053
|
+
return Number.isSafeInteger(parsed) && parsed >= 1 ? parsed : null;
|
|
6054
|
+
}
|
|
6055
|
+
function formatCapacity(value) {
|
|
6056
|
+
if (value >= 1e6 && value % 1e5 === 0) return `${value / 1e6}M`;
|
|
6057
|
+
if (value >= 1e3 && value % 1e3 === 0) return `${value / 1e3}K`;
|
|
6058
|
+
return String(value);
|
|
6059
|
+
}
|
|
6060
|
+
/**
|
|
6061
|
+
* Seed one draft per model from a status payload. Also run after a model
|
|
6062
|
+
* toggle: a model that was just enabled has no draft yet, and the context
|
|
6063
|
+
* window section only renders enabled models.
|
|
6064
|
+
*/
|
|
6065
|
+
function contextDraftsFor(status) {
|
|
6066
|
+
const drafts = {};
|
|
6067
|
+
for (const model of status.models) drafts[model.id] = formatCapacity(status.contextWindowOverrides[model.id] || model.defaultContextWindow);
|
|
6068
|
+
return drafts;
|
|
6069
|
+
}
|
|
6070
|
+
function formatDate(ms) {
|
|
6071
|
+
if (ms === void 0 || ms === null || ms <= 0) return "—";
|
|
6072
|
+
try {
|
|
6073
|
+
return new Intl.DateTimeFormat(void 0, {
|
|
6074
|
+
dateStyle: "medium",
|
|
6075
|
+
timeStyle: "short"
|
|
6076
|
+
}).format(ms);
|
|
6077
|
+
} catch {
|
|
6078
|
+
return "—";
|
|
6079
|
+
}
|
|
6080
|
+
}
|
|
6081
|
+
function formatReset(resetsAt, nowLabel = "now") {
|
|
6082
|
+
if (resetsAt === void 0 || resetsAt === null || resetsAt <= 0) return "";
|
|
6083
|
+
const diff = resetsAt - Date.now();
|
|
6084
|
+
if (diff <= 0) return nowLabel;
|
|
6085
|
+
const mins = Math.floor(diff / 6e4);
|
|
6086
|
+
const hours = Math.floor(mins / 60);
|
|
6087
|
+
const days = Math.floor(hours / 24);
|
|
6088
|
+
if (days > 0) return `${days}d ${hours % 24}h`;
|
|
6089
|
+
if (hours > 0) return `${hours}h ${mins % 60}m`;
|
|
6090
|
+
return `${mins}m`;
|
|
6091
|
+
}
|
|
6092
|
+
function ZhipuSection({ onModelChange, loadModelDirectory }) {
|
|
6093
|
+
const [status, setStatus] = (0, react.useState)(null);
|
|
6094
|
+
const [loading, setLoading] = (0, react.useState)(true);
|
|
6095
|
+
const [busy, setBusy] = (0, react.useState)(null);
|
|
6096
|
+
const [error, setError] = (0, react.useState)(null);
|
|
6097
|
+
const [contextDrafts, setContextDrafts] = (0, react.useState)({});
|
|
6098
|
+
const [savingModel, setSavingModel] = (0, react.useState)(null);
|
|
6099
|
+
const [apiKey, setApiKey] = (0, react.useState)("");
|
|
6100
|
+
const [region, setRegion] = (0, react.useState)("intl");
|
|
6101
|
+
const t = zh$1;
|
|
6102
|
+
const notifyChange = (0, react.useCallback)(() => {
|
|
6103
|
+
onModelChange?.();
|
|
6104
|
+
loadModelDirectory?.();
|
|
6105
|
+
}, [onModelChange, loadModelDirectory]);
|
|
6106
|
+
const loadStatus = (0, react.useCallback)(async (quiet = false) => {
|
|
6107
|
+
if (!quiet) setError(null);
|
|
6108
|
+
try {
|
|
6109
|
+
const data = await fetchApi$5("/status");
|
|
6110
|
+
setStatus(data);
|
|
6111
|
+
setContextDrafts(contextDraftsFor(data));
|
|
6112
|
+
} catch (err) {
|
|
6113
|
+
if (!quiet) setError(err instanceof Error ? err.message : String(err));
|
|
6114
|
+
} finally {
|
|
6115
|
+
setLoading(false);
|
|
6116
|
+
}
|
|
6117
|
+
}, []);
|
|
6118
|
+
(0, react.useEffect)(() => {
|
|
6119
|
+
loadStatus();
|
|
6120
|
+
const refreshWhenVisible = () => {
|
|
6121
|
+
if (document.visibilityState === "visible") loadStatus(true);
|
|
6122
|
+
};
|
|
6123
|
+
document.addEventListener("visibilitychange", refreshWhenVisible);
|
|
6124
|
+
const timer = window.setInterval(refreshWhenVisible, 6e4);
|
|
6125
|
+
return () => {
|
|
6126
|
+
window.clearInterval(timer);
|
|
6127
|
+
document.removeEventListener("visibilitychange", refreshWhenVisible);
|
|
6128
|
+
};
|
|
6129
|
+
}, [loadStatus]);
|
|
6130
|
+
/**
|
|
6131
|
+
* Save one pasted key.
|
|
6132
|
+
*
|
|
6133
|
+
* The host verifies it against the deployment before persisting, so a key
|
|
6134
|
+
* from the wrong console fails here with a message naming the console it
|
|
6135
|
+
* belongs to rather than inside a conversation later.
|
|
6136
|
+
*/
|
|
6137
|
+
const handleAddKey = async () => {
|
|
6138
|
+
try {
|
|
6139
|
+
setBusy("apikey");
|
|
6140
|
+
setError(null);
|
|
6141
|
+
const updated = await fetchApi$5("/accounts/add", {
|
|
6142
|
+
method: "POST",
|
|
6143
|
+
body: JSON.stringify({
|
|
6144
|
+
apiKey,
|
|
6145
|
+
region
|
|
6146
|
+
})
|
|
6147
|
+
});
|
|
6148
|
+
setStatus(updated);
|
|
6149
|
+
setContextDrafts(contextDraftsFor(updated));
|
|
6150
|
+
setApiKey("");
|
|
6151
|
+
notifyChange();
|
|
6152
|
+
} catch (err) {
|
|
6153
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
6154
|
+
} finally {
|
|
6155
|
+
setBusy(null);
|
|
6156
|
+
}
|
|
6157
|
+
};
|
|
6158
|
+
/** One account-level action on the shared pool card. */
|
|
6159
|
+
const handleAccountAction = async (action, accountId) => {
|
|
6160
|
+
try {
|
|
6161
|
+
setBusy(`${action}-${accountId}`);
|
|
6162
|
+
setError(null);
|
|
6163
|
+
const updated = await fetchApi$5("/accounts/action", {
|
|
6164
|
+
method: "POST",
|
|
6165
|
+
body: JSON.stringify({
|
|
6166
|
+
action,
|
|
6167
|
+
accountId
|
|
6168
|
+
})
|
|
6169
|
+
});
|
|
6170
|
+
setStatus(updated);
|
|
6171
|
+
notifyChange();
|
|
6172
|
+
} catch (err) {
|
|
6173
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
6174
|
+
} finally {
|
|
6175
|
+
setBusy(null);
|
|
6176
|
+
}
|
|
6177
|
+
};
|
|
6178
|
+
const handleSetStrategy = async (strategy) => {
|
|
6179
|
+
try {
|
|
6180
|
+
setBusy("strategy");
|
|
6181
|
+
setError(null);
|
|
6182
|
+
const updated = await fetchApi$5("/accounts/action", {
|
|
6183
|
+
method: "POST",
|
|
6184
|
+
body: JSON.stringify({
|
|
6185
|
+
action: "strategy",
|
|
6186
|
+
strategy
|
|
6187
|
+
})
|
|
6188
|
+
});
|
|
6189
|
+
setStatus(updated);
|
|
6190
|
+
} catch (err) {
|
|
6191
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
6192
|
+
} finally {
|
|
6193
|
+
setBusy(null);
|
|
6194
|
+
}
|
|
6195
|
+
};
|
|
6196
|
+
const handleRefreshQuota = async () => {
|
|
6197
|
+
try {
|
|
6198
|
+
setBusy("quota");
|
|
6199
|
+
setError(null);
|
|
6200
|
+
const updated = await fetchApi$5("/quota", { method: "POST" });
|
|
6201
|
+
setStatus(updated);
|
|
6202
|
+
} catch (err) {
|
|
6203
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
6204
|
+
} finally {
|
|
6205
|
+
setBusy(null);
|
|
6206
|
+
}
|
|
6207
|
+
};
|
|
6208
|
+
const handleRefreshCatalog = async () => {
|
|
6209
|
+
try {
|
|
6210
|
+
setBusy("catalog");
|
|
6211
|
+
setError(null);
|
|
6212
|
+
const updated = await fetchApi$5("/catalog/refresh", { method: "POST" });
|
|
6213
|
+
setStatus(updated);
|
|
6214
|
+
setContextDrafts(contextDraftsFor(updated));
|
|
6215
|
+
notifyChange();
|
|
6216
|
+
} catch (err) {
|
|
6217
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
6218
|
+
} finally {
|
|
6219
|
+
setBusy(null);
|
|
6220
|
+
}
|
|
6221
|
+
};
|
|
6222
|
+
const handleTestConnection = async () => {
|
|
6223
|
+
try {
|
|
6224
|
+
setBusy("connection");
|
|
6225
|
+
setError(null);
|
|
6226
|
+
await fetchApi$5("/connection/test", { method: "POST" });
|
|
6227
|
+
await loadStatus(true);
|
|
6228
|
+
} catch (err) {
|
|
6229
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
6230
|
+
} finally {
|
|
6231
|
+
setBusy(null);
|
|
6232
|
+
}
|
|
6233
|
+
};
|
|
6234
|
+
const applyEnabled = async (enabledModelIds) => {
|
|
6235
|
+
try {
|
|
6236
|
+
const updated = await fetchApi$5("/models", {
|
|
6237
|
+
method: "POST",
|
|
6238
|
+
body: JSON.stringify({ enabledModelIds })
|
|
6239
|
+
});
|
|
6240
|
+
setStatus(updated);
|
|
6241
|
+
setContextDrafts(contextDraftsFor(updated));
|
|
6242
|
+
notifyChange();
|
|
6243
|
+
} catch (err) {
|
|
6244
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
6245
|
+
}
|
|
6246
|
+
};
|
|
6247
|
+
const toggleEnabled = async (enabled) => {
|
|
6248
|
+
setStatus((prev) => prev ? {
|
|
6249
|
+
...prev,
|
|
6250
|
+
enabled
|
|
6251
|
+
} : prev);
|
|
6252
|
+
try {
|
|
6253
|
+
const updated = await fetchApi$5("/settings", {
|
|
6254
|
+
method: "POST",
|
|
6255
|
+
body: JSON.stringify({ enabled })
|
|
6256
|
+
});
|
|
6257
|
+
setStatus(updated);
|
|
6258
|
+
notifyChange();
|
|
6259
|
+
} catch (err) {
|
|
6260
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
6261
|
+
loadStatus(true);
|
|
6262
|
+
}
|
|
6263
|
+
};
|
|
6264
|
+
const toggleModel = (modelId, checked) => {
|
|
6265
|
+
if (!status) return;
|
|
6266
|
+
const current = status.models.filter((model) => model.enabled).map((model) => model.id);
|
|
6267
|
+
const next = checked ? [.../* @__PURE__ */ new Set([...current, modelId])] : current.filter((id) => id !== modelId);
|
|
6268
|
+
applyEnabled(next);
|
|
6269
|
+
};
|
|
6270
|
+
const setAllModels = (selectAll) => {
|
|
6271
|
+
if (!status || status.models.length === 0) return;
|
|
6272
|
+
applyEnabled(selectAll ? status.models.map((model) => model.id) : []);
|
|
6273
|
+
};
|
|
6274
|
+
const handleUpdateEffort = async (effort) => {
|
|
6275
|
+
try {
|
|
6276
|
+
const updated = await fetchApi$5("/settings", {
|
|
6277
|
+
method: "POST",
|
|
6278
|
+
body: JSON.stringify({ defaultReasoningEffort: effort })
|
|
6279
|
+
});
|
|
6280
|
+
setStatus(updated);
|
|
6281
|
+
notifyChange();
|
|
6282
|
+
} catch (err) {
|
|
6283
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
6284
|
+
}
|
|
6285
|
+
};
|
|
6286
|
+
const handleSaveContextWindow = async (modelId) => {
|
|
6287
|
+
const raw = contextDrafts[modelId] || "";
|
|
6288
|
+
const parsed = parsePositiveCapacity(raw);
|
|
6289
|
+
if (parsed === null) {
|
|
6290
|
+
setError(`Invalid context capacity: ${raw}`);
|
|
6291
|
+
return;
|
|
6292
|
+
}
|
|
6293
|
+
try {
|
|
6294
|
+
setSavingModel(modelId);
|
|
6295
|
+
setError(null);
|
|
6296
|
+
const updated = await fetchApi$5("/settings", {
|
|
6297
|
+
method: "POST",
|
|
6298
|
+
body: JSON.stringify({ contextWindowOverrides: { [modelId]: parsed } })
|
|
6299
|
+
});
|
|
6300
|
+
setStatus(updated);
|
|
6301
|
+
setContextDrafts((prev) => ({
|
|
6302
|
+
...prev,
|
|
6303
|
+
[modelId]: formatCapacity(parsed)
|
|
6304
|
+
}));
|
|
6305
|
+
notifyChange();
|
|
6306
|
+
} catch (err) {
|
|
6307
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
6308
|
+
} finally {
|
|
6309
|
+
setSavingModel(null);
|
|
6310
|
+
}
|
|
6311
|
+
};
|
|
6312
|
+
/** Clear one override; the row falls back to the declared window. */
|
|
6313
|
+
const handleResetContextWindow = async (modelId) => {
|
|
6314
|
+
try {
|
|
6315
|
+
setSavingModel(modelId);
|
|
6316
|
+
setError(null);
|
|
6317
|
+
const updated = await fetchApi$5("/settings", {
|
|
6318
|
+
method: "POST",
|
|
6319
|
+
body: JSON.stringify({ contextWindowOverrides: { [modelId]: null } })
|
|
6320
|
+
});
|
|
6321
|
+
setStatus(updated);
|
|
6322
|
+
setContextDrafts((prev) => {
|
|
6323
|
+
const model = updated.models.find((candidate) => candidate.id === modelId);
|
|
6324
|
+
return model === void 0 ? prev : {
|
|
6325
|
+
...prev,
|
|
6326
|
+
[modelId]: formatCapacity(model.defaultContextWindow)
|
|
6327
|
+
};
|
|
6328
|
+
});
|
|
6329
|
+
notifyChange();
|
|
6330
|
+
} catch (err) {
|
|
6331
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
6332
|
+
} finally {
|
|
6333
|
+
setSavingModel(null);
|
|
6334
|
+
}
|
|
6335
|
+
};
|
|
6336
|
+
/** Clear every stored override, including models the picker no longer shows. */
|
|
6337
|
+
const handleResetAllContextWindows = async () => {
|
|
6338
|
+
const models = Object.keys(status?.contextWindowOverrides ?? {});
|
|
6339
|
+
if (models.length === 0) return;
|
|
6340
|
+
if (typeof window !== "undefined" && !window.confirm(t.contextWindowResetAllConfirm)) return;
|
|
6341
|
+
try {
|
|
6342
|
+
setBusy("context");
|
|
6343
|
+
setError(null);
|
|
6344
|
+
const updated = await fetchApi$5("/settings", {
|
|
6345
|
+
method: "POST",
|
|
6346
|
+
body: JSON.stringify({ contextWindowOverrides: Object.fromEntries(models.map((model) => [model, null])) })
|
|
6347
|
+
});
|
|
6348
|
+
setStatus(updated);
|
|
6349
|
+
setContextDrafts(contextDraftsFor(updated));
|
|
6350
|
+
notifyChange();
|
|
6351
|
+
} catch (err) {
|
|
6352
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
6353
|
+
} finally {
|
|
6354
|
+
setBusy(null);
|
|
6355
|
+
}
|
|
6356
|
+
};
|
|
6357
|
+
if (loading) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6358
|
+
className: "dsha-page",
|
|
6359
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6360
|
+
className: "dsha-empty",
|
|
6361
|
+
children: t.loading
|
|
6362
|
+
})
|
|
6363
|
+
});
|
|
6364
|
+
const contextModels = status?.models.filter((model) => model.enabled) ?? [];
|
|
6365
|
+
const overrideCount = Object.keys(status?.contextWindowOverrides ?? {}).length;
|
|
6366
|
+
const quota = status?.quota;
|
|
6367
|
+
const account = status?.account;
|
|
6368
|
+
const hasMeters = (quota?.meters.length ?? 0) > 0;
|
|
6369
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6370
|
+
className: "dsha-page",
|
|
6371
|
+
children: [
|
|
6372
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(AccountPoolSection, {
|
|
6373
|
+
accounts: status?.accounts ?? [],
|
|
6374
|
+
activeAccountId: status?.activeAccountId,
|
|
6375
|
+
rotationStrategy: status?.rotationStrategy ?? "sequential",
|
|
6376
|
+
busy,
|
|
6377
|
+
labels: t,
|
|
6378
|
+
onLogin: () => {
|
|
6379
|
+
document.querySelector(`.dsha-page input[type=password]`)?.focus();
|
|
6380
|
+
},
|
|
6381
|
+
onSetPrimary: (accountId) => void handleAccountAction("set-primary", accountId),
|
|
6382
|
+
onDelete: (accountId) => void handleAccountAction("delete", accountId),
|
|
6383
|
+
onClearCooldown: (accountId) => void handleAccountAction("clear-cooldown", accountId),
|
|
6384
|
+
onSetStrategy: (strategy) => void handleSetStrategy(strategy),
|
|
6385
|
+
storageValue: status?.storagePath || "—",
|
|
6386
|
+
renderDetails: (entry) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
6387
|
+
entry.keyHint && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
|
|
6388
|
+
t.keyHint,
|
|
6389
|
+
": ",
|
|
6390
|
+
entry.keyHint
|
|
6391
|
+
] }),
|
|
6392
|
+
entry.region && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
|
|
6393
|
+
t.region,
|
|
6394
|
+
": ",
|
|
6395
|
+
entry.region === "cn" ? t.regionCn : t.regionIntl
|
|
6396
|
+
] }),
|
|
6397
|
+
entry.planLabel && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
|
|
6398
|
+
t.plan,
|
|
6399
|
+
": ",
|
|
6400
|
+
entry.planLabel
|
|
6401
|
+
] })
|
|
6402
|
+
] }),
|
|
6403
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
6404
|
+
className: "dsha-muted",
|
|
6405
|
+
style: { paddingTop: 12 },
|
|
6406
|
+
children: t.addKeyHint
|
|
6407
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6408
|
+
className: "dsha-capacity-control dshzp-keyrow",
|
|
6409
|
+
children: [
|
|
6410
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
6411
|
+
className: "dsha-select",
|
|
6412
|
+
"aria-label": t.region,
|
|
6413
|
+
value: region,
|
|
6414
|
+
onChange: (event) => setRegion(event.currentTarget.value === "cn" ? "cn" : "intl"),
|
|
6415
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
6416
|
+
value: "intl",
|
|
6417
|
+
children: t.regionIntl
|
|
6418
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
6419
|
+
value: "cn",
|
|
6420
|
+
children: t.regionCn
|
|
6421
|
+
})]
|
|
6422
|
+
}),
|
|
6423
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
6424
|
+
type: "password",
|
|
6425
|
+
"aria-label": t.addKeySection,
|
|
6426
|
+
placeholder: t.keyPlaceholder,
|
|
6427
|
+
value: apiKey,
|
|
6428
|
+
onChange: (event) => setApiKey(event.currentTarget.value),
|
|
6429
|
+
onKeyDown: (event) => {
|
|
6430
|
+
if (event.key === "Enter" && apiKey.trim() !== "") handleAddKey();
|
|
6431
|
+
}
|
|
6432
|
+
}),
|
|
6433
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
6434
|
+
type: "button",
|
|
6435
|
+
className: "dsha-context-save",
|
|
6436
|
+
disabled: busy !== null || apiKey.trim() === "",
|
|
6437
|
+
onClick: () => void handleAddKey(),
|
|
6438
|
+
children: busy === "apikey" ? t.keySaving : t.keySave
|
|
6439
|
+
})
|
|
6440
|
+
]
|
|
6441
|
+
})]
|
|
6442
|
+
}),
|
|
6443
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
6444
|
+
className: "dsha-group",
|
|
6445
|
+
children: [
|
|
6446
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6447
|
+
className: "dsha-grouphead",
|
|
6448
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t.connection })
|
|
6449
|
+
}),
|
|
6450
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6451
|
+
className: "dsha-row",
|
|
6452
|
+
style: { marginBottom: 12 },
|
|
6453
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6454
|
+
className: "dsha-label",
|
|
6455
|
+
style: { fontWeight: 600 },
|
|
6456
|
+
children: t.enableProvider
|
|
6457
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
6458
|
+
type: "checkbox",
|
|
6459
|
+
checked: status?.enabled !== false,
|
|
6460
|
+
disabled: busy !== null,
|
|
6461
|
+
onChange: (e) => void toggleEnabled(e.currentTarget.checked)
|
|
6462
|
+
})]
|
|
6463
|
+
}),
|
|
6464
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6465
|
+
className: "dsha-row",
|
|
6466
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6467
|
+
className: "dsha-label",
|
|
6468
|
+
children: t.provider
|
|
6469
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6470
|
+
className: "dsha-value",
|
|
6471
|
+
children: t.providerValue
|
|
6472
|
+
})]
|
|
6473
|
+
}),
|
|
6474
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6475
|
+
className: "dsha-row",
|
|
6476
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6477
|
+
className: "dsha-label",
|
|
6478
|
+
children: t.connectionState
|
|
6479
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6480
|
+
className: "dsha-value",
|
|
6481
|
+
children: status?.authenticated ? t.connected : t.untested
|
|
6482
|
+
})]
|
|
6483
|
+
}),
|
|
6484
|
+
account && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6485
|
+
className: "dsha-row",
|
|
6486
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6487
|
+
className: "dsha-label",
|
|
6488
|
+
children: t.account
|
|
6489
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
6490
|
+
className: "dsha-value",
|
|
6491
|
+
children: [
|
|
6492
|
+
account.keyHint,
|
|
6493
|
+
" · ",
|
|
6494
|
+
account.region === "cn" ? t.regionCn : t.regionIntl
|
|
6495
|
+
]
|
|
6496
|
+
})]
|
|
6497
|
+
}),
|
|
6498
|
+
account?.planLabel && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6499
|
+
className: "dsha-row",
|
|
6500
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6501
|
+
className: "dsha-label",
|
|
6502
|
+
children: t.plan
|
|
6503
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6504
|
+
className: "dsha-value",
|
|
6505
|
+
children: account.planLabel
|
|
6506
|
+
})]
|
|
6507
|
+
}),
|
|
6508
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6509
|
+
className: "dsha-row",
|
|
6510
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6511
|
+
className: "dsha-label",
|
|
6512
|
+
children: t.storage
|
|
6513
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6514
|
+
className: "dsha-value",
|
|
6515
|
+
children: status?.storagePath ?? "—"
|
|
6516
|
+
})]
|
|
6517
|
+
}),
|
|
6518
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
6519
|
+
className: "dsha-notice",
|
|
6520
|
+
children: status?.serving === false && status.conflict ? t.routeConflict.replace("{detail}", status.conflict) : t.routeOwned
|
|
6521
|
+
}),
|
|
6522
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6523
|
+
className: "dsha-actions",
|
|
6524
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
6525
|
+
className: "dsha-btn",
|
|
6526
|
+
disabled: busy !== null || !status?.authenticated,
|
|
6527
|
+
onClick: () => void handleTestConnection(),
|
|
6528
|
+
children: busy === "connection" ? t.testingConnection : t.testConnection
|
|
6529
|
+
})
|
|
6530
|
+
})
|
|
6531
|
+
]
|
|
6532
|
+
}),
|
|
6533
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
6534
|
+
className: "dsha-group",
|
|
6535
|
+
children: [
|
|
6536
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6537
|
+
className: "dsha-grouphead",
|
|
6538
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t.modelsSection }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
6539
|
+
className: "dsha-btn",
|
|
6540
|
+
disabled: busy !== null,
|
|
6541
|
+
onClick: () => void handleRefreshCatalog(),
|
|
6542
|
+
children: busy === "catalog" ? t.refreshingCatalog : t.refreshCatalog
|
|
6543
|
+
})]
|
|
6544
|
+
}),
|
|
6545
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
6546
|
+
className: "dsha-muted dsha-models-hint",
|
|
6547
|
+
children: t.modelsHint
|
|
6548
|
+
}),
|
|
6549
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6550
|
+
className: "dsha-models",
|
|
6551
|
+
"aria-label": "GLM Coding Plan Models",
|
|
6552
|
+
children: status?.models.map((model) => {
|
|
6553
|
+
const capabilities = [
|
|
6554
|
+
model.supportsImage ? "image" : null,
|
|
6555
|
+
model.reasoningEfforts.length > 0 ? model.reasoningEfforts.join("/") : null,
|
|
6556
|
+
`${t.effectiveWindow} ${formatCapacity(model.contextWindow)}`
|
|
6557
|
+
].filter((part) => part !== null).join(" · ");
|
|
6558
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
6559
|
+
title: `${model.id} · ${capabilities}`,
|
|
6560
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
6561
|
+
type: "checkbox",
|
|
6562
|
+
checked: model.enabled,
|
|
6563
|
+
disabled: busy !== null,
|
|
6564
|
+
onChange: (event) => toggleModel(model.id, event.currentTarget.checked)
|
|
6565
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: model.name })]
|
|
6566
|
+
}, model.id);
|
|
6567
|
+
})
|
|
6568
|
+
}),
|
|
6569
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6570
|
+
className: "dsha-actions",
|
|
6571
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
6572
|
+
className: "dsha-btn",
|
|
6573
|
+
disabled: busy !== null,
|
|
6574
|
+
onClick: () => setAllModels(true),
|
|
6575
|
+
children: t.selectAll
|
|
6576
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
6577
|
+
className: "dsha-btn",
|
|
6578
|
+
disabled: busy !== null,
|
|
6579
|
+
onClick: () => setAllModels(false),
|
|
6580
|
+
children: t.unselectAll
|
|
6581
|
+
})]
|
|
6582
|
+
})
|
|
6583
|
+
]
|
|
6584
|
+
}),
|
|
6585
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
6586
|
+
className: "dsha-group",
|
|
6587
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6588
|
+
className: "dsha-grouphead",
|
|
6589
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t.enhanced })
|
|
6590
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6591
|
+
className: "dsha-pref-row",
|
|
6592
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t.defaultReasoningEffort }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
6593
|
+
className: "dsha-muted",
|
|
6594
|
+
children: t.defaultReasoningEffortHint
|
|
6595
|
+
})] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
6596
|
+
className: "dsha-select",
|
|
6597
|
+
"aria-label": t.defaultReasoningEffort,
|
|
6598
|
+
value: status?.defaultReasoningEffort ?? "",
|
|
6599
|
+
disabled: busy !== null,
|
|
6600
|
+
onChange: (event) => {
|
|
6601
|
+
const value = event.currentTarget.value;
|
|
6602
|
+
handleUpdateEffort(value === "" ? null : value);
|
|
6603
|
+
},
|
|
6604
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
6605
|
+
value: "",
|
|
6606
|
+
children: t.defaultEffortAuto
|
|
6607
|
+
}), ZHIPU_REASONING_EFFORTS.map((effort) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
6608
|
+
value: effort,
|
|
6609
|
+
children: EFFORT_LABELS[effort]
|
|
6610
|
+
}, effort))]
|
|
6611
|
+
})]
|
|
6612
|
+
})]
|
|
6613
|
+
}),
|
|
6614
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
6615
|
+
className: "dsha-group",
|
|
6616
|
+
children: [
|
|
6617
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6618
|
+
className: "dsha-grouphead",
|
|
6619
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t.contextWindowSection })
|
|
6620
|
+
}),
|
|
6621
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
6622
|
+
className: "dsha-muted",
|
|
6623
|
+
children: t.contextWindowHint
|
|
6624
|
+
}),
|
|
6625
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5239
6626
|
className: "dsha-context-settings",
|
|
5240
|
-
children:
|
|
5241
|
-
|
|
5242
|
-
|
|
5243
|
-
|
|
5244
|
-
|
|
5245
|
-
|
|
5246
|
-
className: "dsha-
|
|
5247
|
-
children: [
|
|
5248
|
-
|
|
5249
|
-
|
|
5250
|
-
|
|
5251
|
-
|
|
5252
|
-
|
|
5253
|
-
|
|
5254
|
-
|
|
6627
|
+
children: [
|
|
6628
|
+
contextModels.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
6629
|
+
className: "dsha-muted",
|
|
6630
|
+
children: t.contextWindowNoneEnabled
|
|
6631
|
+
}),
|
|
6632
|
+
contextModels.map((model) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6633
|
+
className: "dsha-context-row",
|
|
6634
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6635
|
+
title: model.id,
|
|
6636
|
+
children: model.name
|
|
6637
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6638
|
+
className: "dsha-capacity-control",
|
|
6639
|
+
children: [
|
|
6640
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
6641
|
+
type: "text",
|
|
6642
|
+
"aria-label": `${model.name} context window`,
|
|
6643
|
+
value: contextDrafts[model.id] ?? "",
|
|
6644
|
+
onChange: (event) => setContextDrafts({
|
|
6645
|
+
...contextDrafts,
|
|
6646
|
+
[model.id]: event.currentTarget.value
|
|
6647
|
+
}),
|
|
6648
|
+
onKeyDown: (event) => {
|
|
6649
|
+
if (event.key === "Enter") handleSaveContextWindow(model.id);
|
|
6650
|
+
}
|
|
5255
6651
|
}),
|
|
5256
|
-
|
|
5257
|
-
|
|
5258
|
-
|
|
5259
|
-
|
|
5260
|
-
|
|
5261
|
-
|
|
5262
|
-
|
|
5263
|
-
|
|
5264
|
-
|
|
5265
|
-
|
|
5266
|
-
|
|
5267
|
-
|
|
5268
|
-
|
|
5269
|
-
|
|
5270
|
-
|
|
6652
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: t.tokens }),
|
|
6653
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
6654
|
+
type: "button",
|
|
6655
|
+
className: "dsha-context-save",
|
|
6656
|
+
disabled: savingModel === model.id,
|
|
6657
|
+
onClick: () => void handleSaveContextWindow(model.id),
|
|
6658
|
+
children: savingModel === model.id ? t.saving : t.save
|
|
6659
|
+
}),
|
|
6660
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
6661
|
+
type: "button",
|
|
6662
|
+
className: "dsha-context-save dsha-context-reset",
|
|
6663
|
+
"aria-label": `${model.name} ${t.contextWindowReset}`,
|
|
6664
|
+
disabled: savingModel === model.id || status?.contextWindowOverrides[model.id] === void 0,
|
|
6665
|
+
onClick: () => void handleResetContextWindow(model.id),
|
|
6666
|
+
children: t.contextWindowReset
|
|
6667
|
+
})
|
|
6668
|
+
]
|
|
6669
|
+
})]
|
|
6670
|
+
}, model.id)),
|
|
6671
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6672
|
+
className: "dsha-actions",
|
|
6673
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
6674
|
+
className: "dsha-btn",
|
|
6675
|
+
disabled: busy !== null || overrideCount === 0,
|
|
6676
|
+
onClick: () => void handleResetAllContextWindows(),
|
|
6677
|
+
children: t.contextWindowResetAll
|
|
6678
|
+
})
|
|
6679
|
+
})
|
|
6680
|
+
]
|
|
5271
6681
|
})
|
|
5272
6682
|
]
|
|
5273
6683
|
}),
|
|
@@ -5278,7 +6688,7 @@ window.__ModuleLoader__.load({
|
|
|
5278
6688
|
className: "dsha-grouphead",
|
|
5279
6689
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t.quotaSection }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
5280
6690
|
className: "dsha-btn",
|
|
5281
|
-
disabled: busy !== null || !authenticated,
|
|
6691
|
+
disabled: busy !== null || !status?.authenticated,
|
|
5282
6692
|
onClick: () => void handleRefreshQuota(),
|
|
5283
6693
|
children: busy === "quota" ? t.refreshingQuota : t.refreshQuota
|
|
5284
6694
|
})]
|
|
@@ -5287,81 +6697,100 @@ window.__ModuleLoader__.load({
|
|
|
5287
6697
|
className: "dsha-muted",
|
|
5288
6698
|
children: t.quotaDesc
|
|
5289
6699
|
}),
|
|
5290
|
-
!authenticated ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6700
|
+
!status?.authenticated ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5291
6701
|
className: "dsha-empty",
|
|
5292
6702
|
children: t.signedOut
|
|
5293
6703
|
}) : quota === null || quota === void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5294
6704
|
className: "dsha-empty",
|
|
5295
|
-
children: busy === "quota" ? t.refreshingQuota : t.quotaEmpty
|
|
6705
|
+
children: busy === "quota" ? t.refreshingQuota : status.quotaError ?? t.quotaEmpty
|
|
5296
6706
|
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5297
6707
|
className: "dsha-quota-card",
|
|
5298
6708
|
children: [
|
|
5299
6709
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5300
6710
|
className: "dsha-quota-title",
|
|
5301
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: quota.
|
|
6711
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: quota.planName ?? t.quotaSection }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: quota.planLevel ?? t.planUnknown })]
|
|
5302
6712
|
}),
|
|
5303
|
-
quota.
|
|
5304
|
-
className: "dsha-
|
|
5305
|
-
children:
|
|
5306
|
-
|
|
5307
|
-
|
|
5308
|
-
|
|
5309
|
-
|
|
6713
|
+
quota.renewsAt !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6714
|
+
className: "dsha-meter-meta",
|
|
6715
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
|
|
6716
|
+
t.renews,
|
|
6717
|
+
": ",
|
|
6718
|
+
formatDate(quota.renewsAt)
|
|
6719
|
+
] })
|
|
6720
|
+
}),
|
|
6721
|
+
quota.windows.map((window) => {
|
|
6722
|
+
const percent = window.remainingFraction === null ? null : Math.round(window.remainingFraction * 100);
|
|
6723
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6724
|
+
className: "dsha-meter-wrap",
|
|
5310
6725
|
children: [
|
|
5311
|
-
|
|
5312
|
-
|
|
5313
|
-
|
|
6726
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6727
|
+
className: "dsha-meter-label",
|
|
6728
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: window.label }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: percent === null ? "—" : `${percent}% ${t.left}` })]
|
|
6729
|
+
}),
|
|
6730
|
+
percent !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6731
|
+
className: "dsha-meter dsha-meter-green",
|
|
6732
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { style: { width: `${Math.max(0, percent)}%` } })
|
|
6733
|
+
}),
|
|
6734
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6735
|
+
className: "dsha-meter-meta",
|
|
6736
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
|
|
6737
|
+
window.used ?? "—",
|
|
6738
|
+
" / ",
|
|
6739
|
+
window.limit ?? "—"
|
|
6740
|
+
] }), window.resetsAt !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
|
|
6741
|
+
t.resetAt,
|
|
6742
|
+
": ",
|
|
6743
|
+
formatReset(window.resetsAt, t.now)
|
|
6744
|
+
] })]
|
|
6745
|
+
})
|
|
5314
6746
|
]
|
|
5315
|
-
})
|
|
5316
|
-
}),
|
|
5317
|
-
quota.cycleEndsAt !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5318
|
-
className: "dsha-row",
|
|
5319
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5320
|
-
className: "dsha-label",
|
|
5321
|
-
children: t.quotaReset
|
|
5322
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
5323
|
-
className: "dsha-value",
|
|
5324
|
-
children: [formatDate(quota.cycleEndsAt), formatReset(quota.cycleEndsAt) ? ` · ${formatReset(quota.cycleEndsAt)}` : ""]
|
|
5325
|
-
})]
|
|
6747
|
+
}, window.id);
|
|
5326
6748
|
}),
|
|
5327
|
-
quota.meters.map((meter) => {
|
|
5328
|
-
const
|
|
5329
|
-
const percent = remaining === null ? null : Math.round(remaining * 100);
|
|
6749
|
+
quota.meters.filter((meter) => !quota.windows.some((window) => window.id === meter.id)).map((meter) => {
|
|
6750
|
+
const percent = meter.remainingFraction === null ? null : Math.round(meter.remainingFraction * 100);
|
|
5330
6751
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5331
6752
|
className: "dsha-meter-wrap",
|
|
5332
6753
|
children: [
|
|
5333
6754
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5334
6755
|
className: "dsha-meter-label",
|
|
5335
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: meter.label }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: percent === null ?
|
|
6756
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: meter.label }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: percent === null ? "—" : `${percent}% ${t.left}` })]
|
|
5336
6757
|
}),
|
|
5337
6758
|
percent !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5338
|
-
className: "dsha-meter dsha-meter-
|
|
5339
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { style: { width: `${percent}%` } })
|
|
6759
|
+
className: "dsha-meter dsha-meter-cyan",
|
|
6760
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { style: { width: `${Math.max(0, percent)}%` } })
|
|
5340
6761
|
}),
|
|
5341
6762
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5342
6763
|
className: "dsha-meter-meta",
|
|
5343
|
-
children: [
|
|
5344
|
-
meter.used,
|
|
6764
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
|
|
6765
|
+
meter.used ?? "—",
|
|
5345
6766
|
" / ",
|
|
5346
6767
|
meter.limit ?? "—"
|
|
5347
6768
|
] }), meter.resetsAt !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
|
|
5348
|
-
t.
|
|
6769
|
+
t.resetAt,
|
|
5349
6770
|
": ",
|
|
5350
|
-
formatReset(meter.resetsAt)
|
|
6771
|
+
formatReset(meter.resetsAt, t.now)
|
|
5351
6772
|
] })]
|
|
5352
6773
|
})
|
|
5353
6774
|
]
|
|
5354
6775
|
}, meter.id);
|
|
5355
6776
|
}),
|
|
5356
|
-
|
|
6777
|
+
!hasMeters && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5357
6778
|
className: "dsha-empty",
|
|
5358
|
-
children: t.
|
|
6779
|
+
children: t.quotaUnavailable
|
|
5359
6780
|
}),
|
|
5360
6781
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5361
6782
|
className: "dsha-timestamp",
|
|
5362
6783
|
children: t.updatedAt.replace("{time}", new Date(quota.fetchedAt).toLocaleString())
|
|
5363
6784
|
})
|
|
5364
6785
|
]
|
|
6786
|
+
}),
|
|
6787
|
+
status?.quotaError && quota !== null && quota !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
|
|
6788
|
+
className: "dsha-muted",
|
|
6789
|
+
children: [
|
|
6790
|
+
t.quotaError,
|
|
6791
|
+
": ",
|
|
6792
|
+
status.quotaError
|
|
6793
|
+
]
|
|
5365
6794
|
})
|
|
5366
6795
|
]
|
|
5367
6796
|
}),
|
|
@@ -5394,6 +6823,10 @@ window.__ModuleLoader__.load({
|
|
|
5394
6823
|
{
|
|
5395
6824
|
id: "workbuddy",
|
|
5396
6825
|
label: "WorkBuddy"
|
|
6826
|
+
},
|
|
6827
|
+
{
|
|
6828
|
+
id: "zhipu",
|
|
6829
|
+
label: "GLM"
|
|
5397
6830
|
}
|
|
5398
6831
|
];
|
|
5399
6832
|
/**
|
|
@@ -5452,7 +6885,8 @@ window.__ModuleLoader__.load({
|
|
|
5452
6885
|
active === "antigravity" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AntigravitySection, { onModelChange }) : null,
|
|
5453
6886
|
active === "command-code" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CommandCodeSection, { onModelChange }) : null,
|
|
5454
6887
|
active === "kimi-code" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(KimiCodeSection, { onModelChange }) : null,
|
|
5455
|
-
active === "workbuddy" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(WorkBuddySection, { onModelChange }) : null
|
|
6888
|
+
active === "workbuddy" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(WorkBuddySection, { onModelChange }) : null,
|
|
6889
|
+
active === "zhipu" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ZhipuSection, { onModelChange }) : null
|
|
5456
6890
|
]
|
|
5457
6891
|
})
|
|
5458
6892
|
]
|
|
@@ -5540,9 +6974,13 @@ window.__ModuleLoader__.load({
|
|
|
5540
6974
|
searchProviderCodex: "ChatGPT(代理隧道)",
|
|
5541
6975
|
providerDefault: "使用 Provider 默认值",
|
|
5542
6976
|
contextWindows: "模型上下文窗口",
|
|
5543
|
-
contextWindowsHint: "GPT-6
|
|
6977
|
+
contextWindowsHint: "只列出已勾选「可用模型」的条目。默认取模型目录值(GPT-6 系列 384K,最高 872K;其余最高 1M),该值用于 DSH 的压缩与溢出判断,可输入 872K、512K 等容量;改过的模型可单独或一键恢复默认。",
|
|
5544
6978
|
contextWindow: "上下文窗口",
|
|
5545
|
-
contextWindowInvalid: "上下文窗口必须是正整数,且不能超过模型上限(GPT-6 系列为 872K
|
|
6979
|
+
contextWindowInvalid: "上下文窗口必须是正整数,且不能超过模型上限(GPT-6 系列为 872K,其余为 1M);可使用 K 或 M 后缀。",
|
|
6980
|
+
contextWindowReset: "恢复默认",
|
|
6981
|
+
contextWindowResetAll: "全部恢复默认",
|
|
6982
|
+
contextWindowResetAllConfirm: "确定把已改过的模型上下文窗口全部恢复为默认值吗?",
|
|
6983
|
+
contextWindowsNoneEnabled: "还没有勾选任何模型。在上方「可用模型」里勾选后,这里会出现该模型的上下文窗口设置。",
|
|
5546
6984
|
saveContextWindow: "保存上下文窗口",
|
|
5547
6985
|
save: "保存",
|
|
5548
6986
|
tokens: "tokens",
|
|
@@ -5669,9 +7107,13 @@ window.__ModuleLoader__.load({
|
|
|
5669
7107
|
searchProviderCodex: "ChatGPT (Proxy tunnel)",
|
|
5670
7108
|
providerDefault: "Use provider default",
|
|
5671
7109
|
contextWindows: "Model context windows",
|
|
5672
|
-
contextWindowsHint: "
|
|
7110
|
+
contextWindowsHint: "Lists the models checked under Available models. Each starts at its catalog value (384K for the GPT-6 family, up to 872K; up to 1M otherwise); DSH uses it for compaction and overflow detection. Values such as 872K and 512K are accepted, and a changed model can be restored one by one or all at once.",
|
|
5673
7111
|
contextWindow: "Context window",
|
|
5674
|
-
contextWindowInvalid: "The context window must be a positive integer within the model limit (872K for the GPT-6 family, 1M
|
|
7112
|
+
contextWindowInvalid: "The context window must be a positive integer within the model limit (872K for the GPT-6 family, 1M otherwise). K and M suffixes are accepted.",
|
|
7113
|
+
contextWindowReset: "Restore default",
|
|
7114
|
+
contextWindowResetAll: "Restore all defaults",
|
|
7115
|
+
contextWindowResetAllConfirm: "Restore every changed model context window to its default?",
|
|
7116
|
+
contextWindowsNoneEnabled: "No model is checked yet. Check one under Available models above and its context window setting appears here.",
|
|
5675
7117
|
saveContextWindow: "Save context window",
|
|
5676
7118
|
save: "Save",
|
|
5677
7119
|
tokens: "tokens",
|
|
@@ -5723,7 +7165,7 @@ window.__ModuleLoader__.load({
|
|
|
5723
7165
|
};
|
|
5724
7166
|
//#endregion
|
|
5725
7167
|
//#region src/client/styles.ts
|
|
5726
|
-
const STYLE_ID$
|
|
7168
|
+
const STYLE_ID$4 = "@eddyskywalker/dsh-chatgpt-subscription/main";
|
|
5727
7169
|
const CSS = `
|
|
5728
7170
|
.dsh-codex-page{box-sizing:border-box;color:var(--dsw-alias-label-primary);display:flex;flex-direction:column;gap:20px;max-width:780px;min-width:0;padding:2px 0 30px}
|
|
5729
7171
|
.dsh-codex-page *{box-sizing:border-box}
|
|
@@ -5832,21 +7274,21 @@ window.__ModuleLoader__.load({
|
|
|
5832
7274
|
@media(prefers-reduced-motion:reduce){.dsh-codex-meter>span{transition:none}.dsh-codex-skeleton span{animation:none}}
|
|
5833
7275
|
`;
|
|
5834
7276
|
function installStyles() {
|
|
5835
|
-
if (document.querySelector(`style[data-plugin-css="${STYLE_ID$
|
|
7277
|
+
if (document.querySelector(`style[data-plugin-css="${STYLE_ID$4}"]`) !== null) return () => void 0;
|
|
5836
7278
|
const element = document.createElement("style");
|
|
5837
7279
|
element.dataset.plugin = "@eddyskywalker/dsh-chatgpt-subscription";
|
|
5838
|
-
element.dataset.pluginCss = STYLE_ID$
|
|
7280
|
+
element.dataset.pluginCss = STYLE_ID$4;
|
|
5839
7281
|
element.textContent = CSS;
|
|
5840
7282
|
document.head.appendChild(element);
|
|
5841
7283
|
return () => element.remove();
|
|
5842
7284
|
}
|
|
5843
7285
|
//#endregion
|
|
5844
7286
|
//#region src/client/antigravity/styles.ts
|
|
5845
|
-
const STYLE_ID$
|
|
7287
|
+
const STYLE_ID$3 = "dsh-antigravity-settings-style";
|
|
5846
7288
|
function installAntigravityStyles() {
|
|
5847
7289
|
if (typeof document === "undefined" || document.getElementById("dsh-antigravity-settings-style")) return;
|
|
5848
7290
|
const style = document.createElement("style");
|
|
5849
|
-
style.id = STYLE_ID$
|
|
7291
|
+
style.id = STYLE_ID$3;
|
|
5850
7292
|
style.textContent = `
|
|
5851
7293
|
.dsha-page{box-sizing:border-box;color:var(--dsw-alias-label-primary);display:flex;flex-direction:column;gap:20px;max-width:780px;min-width:0;padding:2px 0 30px}
|
|
5852
7294
|
.dsha-page *{box-sizing:border-box}
|
|
@@ -5884,6 +7326,8 @@ window.__ModuleLoader__.load({
|
|
|
5884
7326
|
.dsha-context-save{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-primary);cursor:pointer;font:inherit;font-size:12px;line-height:1;padding:8px 10px;white-space:nowrap}
|
|
5885
7327
|
.dsha-context-save:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}
|
|
5886
7328
|
.dsha-context-save:disabled{cursor:default;opacity:.45}
|
|
7329
|
+
.dsha-context-reset{color:var(--dsw-alias-label-secondary)}
|
|
7330
|
+
.dsha-context-reset:hover:not(:disabled){color:var(--dsw-alias-label-primary)}
|
|
5887
7331
|
.dsha-quota-card{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:8px;margin-top:12px;padding:12px}
|
|
5888
7332
|
.dsha-quota-title{align-items:center;display:flex;font-size:13px;gap:8px;justify-content:space-between;color:var(--dsw-alias-label-primary);font-weight:650}
|
|
5889
7333
|
.dsha-quota-title span{color:var(--dsw-alias-label-tertiary);font-size:11px;text-transform:uppercase}
|
|
@@ -5945,9 +7389,9 @@ window.__ModuleLoader__.load({
|
|
|
5945
7389
|
}
|
|
5946
7390
|
//#endregion
|
|
5947
7391
|
//#region src/client/antigravity/AntigravityComposerQuota.tsx
|
|
5948
|
-
const API$
|
|
5949
|
-
async function fetchApi$
|
|
5950
|
-
const res = await fetch(`${API$
|
|
7392
|
+
const API$4 = "/antigravity/api";
|
|
7393
|
+
async function fetchApi$4(path, options) {
|
|
7394
|
+
const res = await fetch(`${API$4}${path}`, {
|
|
5951
7395
|
...options,
|
|
5952
7396
|
headers: {
|
|
5953
7397
|
"Content-Type": "application/json",
|
|
@@ -5988,7 +7432,7 @@ window.__ModuleLoader__.load({
|
|
|
5988
7432
|
}
|
|
5989
7433
|
}
|
|
5990
7434
|
function AntigravityComposerQuota({ directory, loadModelDirectory }) {
|
|
5991
|
-
const modelState = useStore$
|
|
7435
|
+
const modelState = useStore$4(directory);
|
|
5992
7436
|
const [status, setStatus] = (0, react.useState)(null);
|
|
5993
7437
|
const [loading, setLoading] = (0, react.useState)(false);
|
|
5994
7438
|
const mountedRef = (0, react.useRef)(false);
|
|
@@ -6007,7 +7451,7 @@ window.__ModuleLoader__.load({
|
|
|
6007
7451
|
if (!mountedRef.current) return;
|
|
6008
7452
|
setLoading(true);
|
|
6009
7453
|
try {
|
|
6010
|
-
const data = refresh ? await fetchApi$
|
|
7454
|
+
const data = refresh ? await fetchApi$4("/quota", { method: "POST" }) : await fetchApi$4("/status");
|
|
6011
7455
|
if (mountedRef.current) setStatus(data);
|
|
6012
7456
|
} catch {} finally {
|
|
6013
7457
|
if (mountedRef.current) setLoading(false);
|
|
@@ -6045,14 +7489,14 @@ window.__ModuleLoader__.load({
|
|
|
6045
7489
|
})]
|
|
6046
7490
|
});
|
|
6047
7491
|
}
|
|
6048
|
-
function useStore$
|
|
7492
|
+
function useStore$4(store) {
|
|
6049
7493
|
return (0, react.useSyncExternalStore)((listener) => store.subscribe(listener), () => store.getSnapshot(), () => store.getSnapshot());
|
|
6050
7494
|
}
|
|
6051
7495
|
//#endregion
|
|
6052
7496
|
//#region src/client/command-code/CommandCodeComposerQuota.tsx
|
|
6053
|
-
const API$
|
|
6054
|
-
async function fetchApi$
|
|
6055
|
-
const res = await fetch(`${API$
|
|
7497
|
+
const API$3 = "/command-code/api";
|
|
7498
|
+
async function fetchApi$3(path, options) {
|
|
7499
|
+
const res = await fetch(`${API$3}${path}`, {
|
|
6056
7500
|
...options,
|
|
6057
7501
|
headers: {
|
|
6058
7502
|
"Content-Type": "application/json",
|
|
@@ -6069,7 +7513,7 @@ window.__ModuleLoader__.load({
|
|
|
6069
7513
|
* A bounded usage window is the number a user actually spends down, so it wins
|
|
6070
7514
|
* over a credit balance; the balance shows only when no window is reported.
|
|
6071
7515
|
*/
|
|
6072
|
-
function selectBadgeFacts$
|
|
7516
|
+
function selectBadgeFacts$3(status) {
|
|
6073
7517
|
const quota = status?.quota;
|
|
6074
7518
|
if (quota === null || quota === void 0) return {
|
|
6075
7519
|
text: "—",
|
|
@@ -6111,7 +7555,7 @@ window.__ModuleLoader__.load({
|
|
|
6111
7555
|
};
|
|
6112
7556
|
}
|
|
6113
7557
|
function CommandCodeComposerQuota({ directory, loadModelDirectory }) {
|
|
6114
|
-
const modelState = useStore$
|
|
7558
|
+
const modelState = useStore$3(directory);
|
|
6115
7559
|
const [status, setStatus] = (0, react.useState)(null);
|
|
6116
7560
|
const [loading, setLoading] = (0, react.useState)(false);
|
|
6117
7561
|
const mountedRef = (0, react.useRef)(false);
|
|
@@ -6129,7 +7573,7 @@ window.__ModuleLoader__.load({
|
|
|
6129
7573
|
if (!mountedRef.current) return;
|
|
6130
7574
|
setLoading(true);
|
|
6131
7575
|
try {
|
|
6132
|
-
const data = refresh ? await fetchApi$
|
|
7576
|
+
const data = refresh ? await fetchApi$3("/quota", { method: "POST" }) : await fetchApi$3("/status");
|
|
6133
7577
|
if (mountedRef.current) setStatus(data);
|
|
6134
7578
|
} catch {} finally {
|
|
6135
7579
|
if (mountedRef.current) setLoading(false);
|
|
@@ -6145,7 +7589,7 @@ window.__ModuleLoader__.load({
|
|
|
6145
7589
|
window.clearInterval(timer);
|
|
6146
7590
|
};
|
|
6147
7591
|
}, [fetchStatus, isCommandCode]);
|
|
6148
|
-
const facts = (0, react.useMemo)(() => selectBadgeFacts$
|
|
7592
|
+
const facts = (0, react.useMemo)(() => selectBadgeFacts$3(status), [status]);
|
|
6149
7593
|
if (!isCommandCode || !status?.authenticated || facts === null) return null;
|
|
6150
7594
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
6151
7595
|
className: "dsha-composer-quota",
|
|
@@ -6162,14 +7606,14 @@ window.__ModuleLoader__.load({
|
|
|
6162
7606
|
})]
|
|
6163
7607
|
});
|
|
6164
7608
|
}
|
|
6165
|
-
function useStore$
|
|
7609
|
+
function useStore$3(store) {
|
|
6166
7610
|
return (0, react.useSyncExternalStore)((listener) => store.subscribe(listener), () => store.getSnapshot(), () => store.getSnapshot());
|
|
6167
7611
|
}
|
|
6168
7612
|
//#endregion
|
|
6169
7613
|
//#region src/client/kimi-code/KimiCodeComposerQuota.tsx
|
|
6170
|
-
const API$
|
|
6171
|
-
async function fetchApi$
|
|
6172
|
-
const res = await fetch(`${API$
|
|
7614
|
+
const API$2 = "/kimi-code/api";
|
|
7615
|
+
async function fetchApi$2(path, options) {
|
|
7616
|
+
const res = await fetch(`${API$2}${path}`, {
|
|
6173
7617
|
...options,
|
|
6174
7618
|
headers: {
|
|
6175
7619
|
"Content-Type": "application/json",
|
|
@@ -6187,7 +7631,7 @@ window.__ModuleLoader__.load({
|
|
|
6187
7631
|
* blocks work soonest, so it wins over the longer pools; the 7-day allowance
|
|
6188
7632
|
* shows only when no 5-hour window is reported.
|
|
6189
7633
|
*/
|
|
6190
|
-
function selectBadgeFacts$
|
|
7634
|
+
function selectBadgeFacts$2(status) {
|
|
6191
7635
|
const quota = status?.quota;
|
|
6192
7636
|
if (quota === null || quota === void 0) return {
|
|
6193
7637
|
text: "—",
|
|
@@ -6219,7 +7663,7 @@ window.__ModuleLoader__.load({
|
|
|
6219
7663
|
};
|
|
6220
7664
|
}
|
|
6221
7665
|
function KimiCodeComposerQuota({ directory, loadModelDirectory }) {
|
|
6222
|
-
const modelState = useStore$
|
|
7666
|
+
const modelState = useStore$2(directory);
|
|
6223
7667
|
const [status, setStatus] = (0, react.useState)(null);
|
|
6224
7668
|
const [loading, setLoading] = (0, react.useState)(false);
|
|
6225
7669
|
const mountedRef = (0, react.useRef)(false);
|
|
@@ -6237,7 +7681,7 @@ window.__ModuleLoader__.load({
|
|
|
6237
7681
|
if (!mountedRef.current) return;
|
|
6238
7682
|
setLoading(true);
|
|
6239
7683
|
try {
|
|
6240
|
-
const data = refresh ? await fetchApi$
|
|
7684
|
+
const data = refresh ? await fetchApi$2("/quota", { method: "POST" }) : await fetchApi$2("/status");
|
|
6241
7685
|
if (mountedRef.current) setStatus(data);
|
|
6242
7686
|
} catch {} finally {
|
|
6243
7687
|
if (mountedRef.current) setLoading(false);
|
|
@@ -6253,7 +7697,7 @@ window.__ModuleLoader__.load({
|
|
|
6253
7697
|
window.clearInterval(timer);
|
|
6254
7698
|
};
|
|
6255
7699
|
}, [fetchStatus, isKimiCode]);
|
|
6256
|
-
const facts = (0, react.useMemo)(() => selectBadgeFacts$
|
|
7700
|
+
const facts = (0, react.useMemo)(() => selectBadgeFacts$2(status), [status]);
|
|
6257
7701
|
if (!isKimiCode || !status?.authenticated || facts === null) return null;
|
|
6258
7702
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
6259
7703
|
className: "dsha-composer-quota",
|
|
@@ -6270,12 +7714,12 @@ window.__ModuleLoader__.load({
|
|
|
6270
7714
|
})]
|
|
6271
7715
|
});
|
|
6272
7716
|
}
|
|
6273
|
-
function useStore$
|
|
7717
|
+
function useStore$2(store) {
|
|
6274
7718
|
return (0, react.useSyncExternalStore)((listener) => store.subscribe(listener), () => store.getSnapshot(), () => store.getSnapshot());
|
|
6275
7719
|
}
|
|
6276
7720
|
//#endregion
|
|
6277
7721
|
//#region src/client/kimi-code/styles.ts
|
|
6278
|
-
const STYLE_ID$
|
|
7722
|
+
const STYLE_ID$2 = "dsh-kimi-code-settings-style";
|
|
6279
7723
|
/**
|
|
6280
7724
|
* Node the base control styles come from.
|
|
6281
7725
|
*
|
|
@@ -6320,6 +7764,8 @@ window.__ModuleLoader__.load({
|
|
|
6320
7764
|
.dsha-context-save{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-primary);cursor:pointer;font:inherit;font-size:12px;line-height:1;padding:8px 10px;white-space:nowrap}
|
|
6321
7765
|
.dsha-context-save:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}
|
|
6322
7766
|
.dsha-context-save:disabled{cursor:default;opacity:.45}
|
|
7767
|
+
.dsha-context-reset{color:var(--dsw-alias-label-secondary)}
|
|
7768
|
+
.dsha-context-reset:hover:not(:disabled){color:var(--dsw-alias-label-primary)}
|
|
6323
7769
|
.dsha-quota-card{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:8px;margin-top:12px;padding:12px}
|
|
6324
7770
|
.dsha-quota-title{align-items:center;display:flex;font-size:13px;gap:8px;justify-content:space-between;color:var(--dsw-alias-label-primary);font-weight:650}
|
|
6325
7771
|
.dsha-quota-title span{color:var(--dsw-alias-label-tertiary);font-size:11px;text-transform:uppercase}
|
|
@@ -6365,15 +7811,15 @@ window.__ModuleLoader__.load({
|
|
|
6365
7811
|
function installKimiCodeStyles() {
|
|
6366
7812
|
if (typeof document === "undefined" || document.getElementById("dsh-kimi-code-settings-style")) return;
|
|
6367
7813
|
const style = document.createElement("style");
|
|
6368
|
-
style.id = STYLE_ID$
|
|
7814
|
+
style.id = STYLE_ID$2;
|
|
6369
7815
|
style.textContent = BASE;
|
|
6370
7816
|
document.head.appendChild(style);
|
|
6371
7817
|
}
|
|
6372
7818
|
//#endregion
|
|
6373
7819
|
//#region src/client/workbuddy/WorkBuddyComposerQuota.tsx
|
|
6374
|
-
const API = "/workbuddy/api";
|
|
6375
|
-
async function fetchApi(path, options) {
|
|
6376
|
-
const res = await fetch(`${API}${path}`, {
|
|
7820
|
+
const API$1 = "/workbuddy/api";
|
|
7821
|
+
async function fetchApi$1(path, options) {
|
|
7822
|
+
const res = await fetch(`${API$1}${path}`, {
|
|
6377
7823
|
...options,
|
|
6378
7824
|
headers: {
|
|
6379
7825
|
"Content-Type": "application/json",
|
|
@@ -6392,7 +7838,7 @@ window.__ModuleLoader__.load({
|
|
|
6392
7838
|
* payload reports both a cycle meter and a package meter, and the cycle meter
|
|
6393
7839
|
* is the one that actually resets, so it is preferred when both exist.
|
|
6394
7840
|
*/
|
|
6395
|
-
function selectBadgeFacts(status) {
|
|
7841
|
+
function selectBadgeFacts$1(status) {
|
|
6396
7842
|
const quota = status?.quota;
|
|
6397
7843
|
if (quota === null || quota === void 0) return {
|
|
6398
7844
|
text: "—",
|
|
@@ -6420,7 +7866,7 @@ window.__ModuleLoader__.load({
|
|
|
6420
7866
|
};
|
|
6421
7867
|
}
|
|
6422
7868
|
function WorkBuddyComposerQuota({ directory, loadModelDirectory }) {
|
|
6423
|
-
const modelState = useStore(directory);
|
|
7869
|
+
const modelState = useStore$1(directory);
|
|
6424
7870
|
const [status, setStatus] = (0, react.useState)(null);
|
|
6425
7871
|
const [loading, setLoading] = (0, react.useState)(false);
|
|
6426
7872
|
const mountedRef = (0, react.useRef)(false);
|
|
@@ -6438,7 +7884,7 @@ window.__ModuleLoader__.load({
|
|
|
6438
7884
|
if (!mountedRef.current) return;
|
|
6439
7885
|
setLoading(true);
|
|
6440
7886
|
try {
|
|
6441
|
-
const data = refresh ? await fetchApi("/quota", { method: "POST" }) : await fetchApi("/status");
|
|
7887
|
+
const data = refresh ? await fetchApi$1("/quota", { method: "POST" }) : await fetchApi$1("/status");
|
|
6442
7888
|
if (mountedRef.current) setStatus(data);
|
|
6443
7889
|
} catch {} finally {
|
|
6444
7890
|
if (mountedRef.current) setLoading(false);
|
|
@@ -6454,7 +7900,7 @@ window.__ModuleLoader__.load({
|
|
|
6454
7900
|
window.clearInterval(timer);
|
|
6455
7901
|
};
|
|
6456
7902
|
}, [fetchStatus, isWorkBuddy]);
|
|
6457
|
-
const facts = (0, react.useMemo)(() => selectBadgeFacts(status), [status]);
|
|
7903
|
+
const facts = (0, react.useMemo)(() => selectBadgeFacts$1(status), [status]);
|
|
6458
7904
|
if (!isWorkBuddy || !status?.authenticated || facts === null) return null;
|
|
6459
7905
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
6460
7906
|
className: "dsha-composer-quota",
|
|
@@ -6471,12 +7917,12 @@ window.__ModuleLoader__.load({
|
|
|
6471
7917
|
})]
|
|
6472
7918
|
});
|
|
6473
7919
|
}
|
|
6474
|
-
function useStore(store) {
|
|
7920
|
+
function useStore$1(store) {
|
|
6475
7921
|
return (0, react.useSyncExternalStore)((listener) => store.subscribe(listener), () => store.getSnapshot(), () => store.getSnapshot());
|
|
6476
7922
|
}
|
|
6477
7923
|
//#endregion
|
|
6478
7924
|
//#region src/client/workbuddy/styles.ts
|
|
6479
|
-
const STYLE_ID = "dsh-workbuddy-settings-style";
|
|
7925
|
+
const STYLE_ID$1 = "dsh-workbuddy-settings-style";
|
|
6480
7926
|
/**
|
|
6481
7927
|
* WorkBuddy-only additions to the shared settings design system.
|
|
6482
7928
|
*
|
|
@@ -6492,12 +7938,141 @@ window.__ModuleLoader__.load({
|
|
|
6492
7938
|
function installWorkBuddyStyles() {
|
|
6493
7939
|
if (typeof document === "undefined" || document.getElementById("dsh-workbuddy-settings-style")) return;
|
|
6494
7940
|
const style = document.createElement("style");
|
|
6495
|
-
style.id = STYLE_ID;
|
|
7941
|
+
style.id = STYLE_ID$1;
|
|
6496
7942
|
style.textContent = `
|
|
6497
7943
|
.dshwb-mono{font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:11px}
|
|
6498
7944
|
.dsha-account-add-actions{display:flex;flex-wrap:wrap;gap:8px}
|
|
6499
7945
|
.dsha-account-add-actions .dsha-btn{background:var(--dsw-alias-button-info-fill,#397ee8);border-color:transparent;color:var(--dsw-alias-button-info-label,#fff)}
|
|
6500
7946
|
.dsha-account-add-actions .dsha-btn:hover:not(:disabled){opacity:.9;background:var(--dsw-alias-button-info-fill,#397ee8)}
|
|
7947
|
+
`;
|
|
7948
|
+
document.head.append(style);
|
|
7949
|
+
}
|
|
7950
|
+
//#endregion
|
|
7951
|
+
//#region src/client/zhipu/ZhipuComposerQuota.tsx
|
|
7952
|
+
const API = "/zhipu/api";
|
|
7953
|
+
async function fetchApi(path, options) {
|
|
7954
|
+
const res = await fetch(`${API}${path}`, {
|
|
7955
|
+
...options,
|
|
7956
|
+
headers: {
|
|
7957
|
+
"Content-Type": "application/json",
|
|
7958
|
+
...options?.headers
|
|
7959
|
+
}
|
|
7960
|
+
});
|
|
7961
|
+
const json = await res.json();
|
|
7962
|
+
if (!res.ok || !json.ok) throw new Error(json.error || `HTTP ${res.status}`);
|
|
7963
|
+
return json.value;
|
|
7964
|
+
}
|
|
7965
|
+
/**
|
|
7966
|
+
* Pick the most meaningful number for the badge.
|
|
7967
|
+
*
|
|
7968
|
+
* A Coding Plan is bounded by two windows at once, and the one closer to
|
|
7969
|
+
* exhaustion is what the user needs to see: the 5-hour window can be spent
|
|
7970
|
+
* while the weekly one has room, and the reverse. So the tightest *remaining*
|
|
7971
|
+
* fraction wins, and its window names the tooltip.
|
|
7972
|
+
*/
|
|
7973
|
+
function selectBadgeFacts(status) {
|
|
7974
|
+
const quota = status?.quota;
|
|
7975
|
+
if (quota === null || quota === void 0) return {
|
|
7976
|
+
text: "—",
|
|
7977
|
+
tooltip: "GLM Coding Plan quota unavailable — click to refresh",
|
|
7978
|
+
level: "normal"
|
|
7979
|
+
};
|
|
7980
|
+
let tightest = null;
|
|
7981
|
+
for (const window of quota.windows) {
|
|
7982
|
+
if (window.remainingFraction === null) continue;
|
|
7983
|
+
if (tightest === null || window.remainingFraction < tightest.remaining) tightest = {
|
|
7984
|
+
label: window.label,
|
|
7985
|
+
remaining: window.remainingFraction
|
|
7986
|
+
};
|
|
7987
|
+
}
|
|
7988
|
+
if (tightest === null) return {
|
|
7989
|
+
text: "—",
|
|
7990
|
+
tooltip: "GLM Coding Plan quota unavailable — click to refresh",
|
|
7991
|
+
level: "normal"
|
|
7992
|
+
};
|
|
7993
|
+
const remaining = Math.round(tightest.remaining * 100);
|
|
7994
|
+
return {
|
|
7995
|
+
text: `${remaining}%`,
|
|
7996
|
+
tooltip: `[GLM Coding Plan] ${tightest.label}: ${remaining}% left`,
|
|
7997
|
+
level: remaining <= 5 ? "danger" : remaining <= 20 ? "warning" : "normal"
|
|
7998
|
+
};
|
|
7999
|
+
}
|
|
8000
|
+
function ZhipuComposerQuota({ directory, loadModelDirectory }) {
|
|
8001
|
+
const modelState = useStore(directory);
|
|
8002
|
+
const [status, setStatus] = (0, react.useState)(null);
|
|
8003
|
+
const [loading, setLoading] = (0, react.useState)(false);
|
|
8004
|
+
const mountedRef = (0, react.useRef)(false);
|
|
8005
|
+
const isZhipu = modelState.current?.provider === "zhipu-coding-plan";
|
|
8006
|
+
(0, react.useEffect)(() => {
|
|
8007
|
+
loadModelDirectory();
|
|
8008
|
+
}, [loadModelDirectory]);
|
|
8009
|
+
(0, react.useEffect)(() => {
|
|
8010
|
+
mountedRef.current = true;
|
|
8011
|
+
return () => {
|
|
8012
|
+
mountedRef.current = false;
|
|
8013
|
+
};
|
|
8014
|
+
}, []);
|
|
8015
|
+
const fetchStatus = (0, react.useCallback)(async (refresh = false) => {
|
|
8016
|
+
if (!mountedRef.current) return;
|
|
8017
|
+
setLoading(true);
|
|
8018
|
+
try {
|
|
8019
|
+
const data = refresh ? await fetchApi("/quota", { method: "POST" }) : await fetchApi("/status");
|
|
8020
|
+
if (mountedRef.current) setStatus(data);
|
|
8021
|
+
} catch {} finally {
|
|
8022
|
+
if (mountedRef.current) setLoading(false);
|
|
8023
|
+
}
|
|
8024
|
+
}, []);
|
|
8025
|
+
(0, react.useEffect)(() => {
|
|
8026
|
+
if (!isZhipu) return;
|
|
8027
|
+
fetchStatus(false);
|
|
8028
|
+
const timer = window.setInterval(() => {
|
|
8029
|
+
if (document.visibilityState === "visible") fetchStatus(false);
|
|
8030
|
+
}, 6e4);
|
|
8031
|
+
return () => {
|
|
8032
|
+
window.clearInterval(timer);
|
|
8033
|
+
};
|
|
8034
|
+
}, [fetchStatus, isZhipu]);
|
|
8035
|
+
const facts = (0, react.useMemo)(() => selectBadgeFacts(status), [status]);
|
|
8036
|
+
if (!isZhipu || !status?.authenticated || facts === null) return null;
|
|
8037
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
8038
|
+
className: "dsha-composer-quota",
|
|
8039
|
+
"data-level": facts.level,
|
|
8040
|
+
title: facts.tooltip,
|
|
8041
|
+
"aria-label": facts.tooltip,
|
|
8042
|
+
onClick: () => void fetchStatus(true),
|
|
8043
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
8044
|
+
className: "dsha-composer-quota-label",
|
|
8045
|
+
children: "额度"
|
|
8046
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", {
|
|
8047
|
+
className: "dsha-composer-quota-val",
|
|
8048
|
+
children: loading ? "…" : facts.text
|
|
8049
|
+
})]
|
|
8050
|
+
});
|
|
8051
|
+
}
|
|
8052
|
+
function useStore(store) {
|
|
8053
|
+
return (0, react.useSyncExternalStore)((listener) => store.subscribe(listener), () => store.getSnapshot(), () => store.getSnapshot());
|
|
8054
|
+
}
|
|
8055
|
+
//#endregion
|
|
8056
|
+
//#region src/client/zhipu/styles.ts
|
|
8057
|
+
const STYLE_ID = "dsh-zhipu-settings-style";
|
|
8058
|
+
/**
|
|
8059
|
+
* GLM Coding Plan additions to the shared settings design system.
|
|
8060
|
+
*
|
|
8061
|
+
* The base control styles (`.dsha-page`, `.dsha-group`, `.dsha-models`, the
|
|
8062
|
+
* account card, the meters, …) come from the stylesheets the sibling routes
|
|
8063
|
+
* install, in the same order the client installs them, so this file declares
|
|
8064
|
+
* only what stays unique to this card: the key-hint line and the region
|
|
8065
|
+
* selector that sits beside the key input.
|
|
8066
|
+
*/
|
|
8067
|
+
function installZhipuStyles() {
|
|
8068
|
+
if (typeof document === "undefined" || document.getElementById("dsh-zhipu-settings-style")) return;
|
|
8069
|
+
const style = document.createElement("style");
|
|
8070
|
+
style.id = STYLE_ID;
|
|
8071
|
+
style.textContent = `
|
|
8072
|
+
.dshzp-mono{font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:11px}
|
|
8073
|
+
.dshzp-keyrow{display:flex;flex-wrap:wrap;gap:8px;align-items:center}
|
|
8074
|
+
.dshzp-keyrow .dsha-select{min-width:190px}
|
|
8075
|
+
.dshzp-keyrow input[type=password]{flex:1 1 260px;min-width:200px}
|
|
6501
8076
|
`;
|
|
6502
8077
|
document.head.append(style);
|
|
6503
8078
|
}
|
|
@@ -6844,22 +8419,27 @@ window.__ModuleLoader__.load({
|
|
|
6844
8419
|
function apply(ctx) {
|
|
6845
8420
|
ctx.effect(() => ctx.locale.register(NS, dictionaries), "dsh-chatgpt-subscription: dictionaries");
|
|
6846
8421
|
ctx.effect(() => installStyles(), "dsh-chatgpt-subscription: styles");
|
|
6847
|
-
ctx.effect(() => ctx.locale.register(NS_ANTIGRAVITY, dictionaries$
|
|
8422
|
+
ctx.effect(() => ctx.locale.register(NS_ANTIGRAVITY, dictionaries$5), "dsh-antigravity: dictionaries");
|
|
6848
8423
|
ctx.effect(() => {
|
|
6849
8424
|
installAntigravityStyles();
|
|
6850
8425
|
return () => {};
|
|
6851
8426
|
}, "dsh-antigravity: styles");
|
|
6852
|
-
ctx.effect(() => ctx.locale.register(NS_COMMAND_CODE, dictionaries$
|
|
6853
|
-
ctx.effect(() => ctx.locale.register(NS_KIMI_CODE, dictionaries$
|
|
8427
|
+
ctx.effect(() => ctx.locale.register(NS_COMMAND_CODE, dictionaries$4), "dsh-command-code: dictionaries");
|
|
8428
|
+
ctx.effect(() => ctx.locale.register(NS_KIMI_CODE, dictionaries$3), "dsh-kimi-code: dictionaries");
|
|
6854
8429
|
ctx.effect(() => {
|
|
6855
8430
|
installKimiCodeStyles();
|
|
6856
8431
|
return () => {};
|
|
6857
8432
|
}, "dsh-kimi-code: styles");
|
|
6858
|
-
ctx.effect(() => ctx.locale.register(NS_WORKBUDDY, dictionaries$
|
|
8433
|
+
ctx.effect(() => ctx.locale.register(NS_WORKBUDDY, dictionaries$2), "dsh-workbuddy: dictionaries");
|
|
6859
8434
|
ctx.effect(() => {
|
|
6860
8435
|
installWorkBuddyStyles();
|
|
6861
8436
|
return () => {};
|
|
6862
8437
|
}, "dsh-workbuddy: styles");
|
|
8438
|
+
ctx.effect(() => ctx.locale.register(NS_ZHIPU, dictionaries$1), "dsh-zhipu: dictionaries");
|
|
8439
|
+
ctx.effect(() => {
|
|
8440
|
+
installZhipuStyles();
|
|
8441
|
+
return () => {};
|
|
8442
|
+
}, "dsh-zhipu: styles");
|
|
6863
8443
|
ctx.effect(() => {
|
|
6864
8444
|
installPoolStyles();
|
|
6865
8445
|
return () => {};
|
|
@@ -6962,6 +8542,21 @@ window.__ModuleLoader__.load({
|
|
|
6962
8542
|
};
|
|
6963
8543
|
}
|
|
6964
8544
|
}, WorkBuddyComposerQuota));
|
|
8545
|
+
ctx.slots.inject("conversation.input.right", () => ctx.slots.register({
|
|
8546
|
+
name: "conversation.input.right",
|
|
8547
|
+
id: "zhipu-quota",
|
|
8548
|
+
order: 40,
|
|
8549
|
+
locale: NS_ZHIPU,
|
|
8550
|
+
inject: (sessionId) => {
|
|
8551
|
+
const directory = ctx.modelDirectories.directoryFor(sessionId);
|
|
8552
|
+
return {
|
|
8553
|
+
directory: directory.store,
|
|
8554
|
+
loadModelDirectory: () => {
|
|
8555
|
+
directory.load().catch(() => void 0);
|
|
8556
|
+
}
|
|
8557
|
+
};
|
|
8558
|
+
}
|
|
8559
|
+
}, ZhipuComposerQuota));
|
|
6965
8560
|
ctx.slots.inject("tool.call.toolview", () => ctx.slots.register({
|
|
6966
8561
|
name: "tool.call.toolview",
|
|
6967
8562
|
key: CODEX_IMAGE_TOOL_NAME,
|