dsh-multi-router 0.6.12 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -430
- package/package.json +5 -81
- package/CHANGELOG.md +0 -243
- package/LICENSE +0 -21
- package/THIRD_PARTY_NOTICES.md +0 -171
- package/cordis.patch.yml +0 -3
- package/lib/accounts.js +0 -19
- package/lib/accounts.js.map +0 -7
- package/lib/api-service.js +0 -11
- package/lib/api-service.js.map +0 -7
- package/lib/chunk-2UM45OXY.js +0 -181
- package/lib/chunk-2UM45OXY.js.map +0 -7
- package/lib/chunk-4L2CBGXN.js +0 -674
- package/lib/chunk-4L2CBGXN.js.map +0 -7
- package/lib/chunk-4V52V5GO.js +0 -105
- package/lib/chunk-4V52V5GO.js.map +0 -7
- package/lib/chunk-DNQPZMPF.js +0 -33
- package/lib/chunk-DNQPZMPF.js.map +0 -7
- package/lib/chunk-FLL3DUVP.js +0 -2017
- package/lib/chunk-FLL3DUVP.js.map +0 -7
- package/lib/chunk-GEBZMIMA.js +0 -287
- package/lib/chunk-GEBZMIMA.js.map +0 -7
- package/lib/chunk-KWXLQJS5.js +0 -1102
- package/lib/chunk-KWXLQJS5.js.map +0 -7
- package/lib/chunk-NZF36O5I.js +0 -5421
- package/lib/chunk-NZF36O5I.js.map +0 -7
- package/lib/chunk-S5KMFAQM.js +0 -50
- package/lib/chunk-S5KMFAQM.js.map +0 -7
- package/lib/chunk-TM5XDMGY.js +0 -332
- package/lib/chunk-TM5XDMGY.js.map +0 -7
- package/lib/chunk-V37VG7MN.js +0 -2101
- package/lib/chunk-V37VG7MN.js.map +0 -7
- package/lib/chunk-WDIT4E2W.js +0 -120
- package/lib/chunk-WDIT4E2W.js.map +0 -7
- package/lib/cli.js +0 -103
- package/lib/cli.js.map +0 -7
- package/lib/client.js +0 -2805
- package/lib/client.js.map +0 -7
- package/lib/clients.js +0 -30
- package/lib/clients.js.map +0 -7
- package/lib/host-v0.6.12.js +0 -414
- package/lib/host.js +0 -414
- package/lib/index.js +0 -414
- package/lib/index.js.map +0 -7
- package/lib/manager.js +0 -27
- package/lib/manager.js.map +0 -7
- package/lib/region-DO3KAV7V.js +0 -15
- package/lib/region-DO3KAV7V.js.map +0 -7
- package/lib/router.js +0 -14
- package/lib/router.js.map +0 -7
- package/lib/shim.js +0 -10
- package/lib/shim.js.map +0 -7
- package/lib/upstream-VP6J7LU2.js +0 -25
- package/lib/upstream-VP6J7LU2.js.map +0 -7
- package/router.example.json +0 -289
- package/upstream-lock.json +0 -17
package/lib/client.js
DELETED
|
@@ -1,2805 +0,0 @@
|
|
|
1
|
-
window.__ModuleLoader__.load({ id: "dsh-multi-router", factory: (require) => { var module = { exports: {} };
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __export = (target, all) => {
|
|
7
|
-
for (var name2 in all)
|
|
8
|
-
__defProp(target, name2, { get: all[name2], enumerable: true });
|
|
9
|
-
};
|
|
10
|
-
var __copyProps = (to, from, except, desc) => {
|
|
11
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
-
for (let key of __getOwnPropNames(from))
|
|
13
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
-
}
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
-
|
|
20
|
-
// src/client.jsx
|
|
21
|
-
var client_exports = {};
|
|
22
|
-
__export(client_exports, {
|
|
23
|
-
AccountPool: () => AccountPool,
|
|
24
|
-
ApiServicePanel: () => ApiServicePanel,
|
|
25
|
-
CheckinPanel: () => CheckinPanel,
|
|
26
|
-
ContextSelect: () => ContextSelect,
|
|
27
|
-
InitialSetup: () => InitialSetup,
|
|
28
|
-
ModelSettings: () => ModelSettings,
|
|
29
|
-
ModelsPanel: () => ModelsPanel,
|
|
30
|
-
PluginUpdatesPanel: () => PluginUpdatesPanel,
|
|
31
|
-
RestartGuidance: () => RestartGuidance,
|
|
32
|
-
RouteReasoningSelect: () => RouteReasoningSelect,
|
|
33
|
-
RouterPage: () => RouterPage,
|
|
34
|
-
RoutesTable: () => RoutesTable,
|
|
35
|
-
SidebarUsage: () => SidebarUsage,
|
|
36
|
-
SidebarUsageCard: () => SidebarUsageCard,
|
|
37
|
-
UpdateReminder: () => UpdateReminder,
|
|
38
|
-
UsageDetails: () => UsageDetails,
|
|
39
|
-
apply: () => apply,
|
|
40
|
-
backendNeedsRestart: () => backendNeedsRestart,
|
|
41
|
-
duration: () => duration,
|
|
42
|
-
inject: () => inject,
|
|
43
|
-
name: () => name,
|
|
44
|
-
performanceSummary: () => performanceSummary,
|
|
45
|
-
readManagementResponse: () => readManagementResponse,
|
|
46
|
-
requestPluginReload: () => requestPluginReload,
|
|
47
|
-
usageDateBounds: () => usageDateBounds
|
|
48
|
-
});
|
|
49
|
-
module.exports = __toCommonJS(client_exports);
|
|
50
|
-
var import_react = require("react");
|
|
51
|
-
|
|
52
|
-
// package.json
|
|
53
|
-
var version = "0.6.12";
|
|
54
|
-
|
|
55
|
-
// src/client.jsx
|
|
56
|
-
var import_jsx_runtime = require("react/jsx-runtime");
|
|
57
|
-
var name = "dsh-multi-router-client";
|
|
58
|
-
var inject = ["slots"];
|
|
59
|
-
var ENDPOINT = "/.well-known/dsh-multi-router";
|
|
60
|
-
var reloadFromHost;
|
|
61
|
-
async function requestPluginReload(remote) {
|
|
62
|
-
if (!remote?.pluginManager?.setBundleEnabled) throw Error("\u5F53\u524D DSH \u672A\u63D0\u4F9B\u91CD\u65B0\u52A0\u8F7D\u63A5\u53E3\uFF0C\u8BF7\u5347\u7EA7 DSH \u6216\u5728\u63D2\u4EF6\u9875\u5173\u95ED\u540E\u91CD\u65B0\u542F\u7528\u672C\u63D2\u4EF6\u3002");
|
|
63
|
-
const answer = await remote.pluginManager.setBundleEnabled("dsh-multi-router", true);
|
|
64
|
-
const result = answer?.ok === true ? answer.value : answer;
|
|
65
|
-
if (answer?.ok === false || result?.application !== "applied") throw Error("DSH \u672A\u80FD\u5373\u65F6\u91CD\u8F7D\uFF0C\u8BF7\u68C0\u67E5\u7EC4\u4EF6\u9519\u8BEF\uFF1B\u4E0D\u652F\u6301\u70ED\u52A0\u8F7D\u7684\u65E7\u7248 DSH \u4ECD\u9700\u91CD\u542F\u3002");
|
|
66
|
-
}
|
|
67
|
-
var backendNeedsRestart = (data) => !!data && data.pluginVersion !== version;
|
|
68
|
-
function RestartGuidance({ data, retry, reload, busy }) {
|
|
69
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "box stack", role: "alert", children: [
|
|
70
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { children: "\u63D2\u4EF6\u6B63\u5728\u8FDE\u63A5\u6216\u540C\u6B65\u7248\u672C" }),
|
|
71
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: data ? `\u9762\u677F v${version}\uFF0C\u8FD0\u884C\u4E2D\u7684\u540E\u53F0 v${data.pluginVersion || "\u65E7\u7248"}\u3002\u6B63\u5728\u7B49\u5F85 DSH \u540C\u6B65\u65B0\u7248\u672C\u3002` : "\u6682\u65F6\u65E0\u6CD5\u8FDE\u63A5\u63D2\u4EF6\u540E\u53F0\u3002\u5B89\u88C5\u6216\u66F4\u65B0\u540E\u4F1A\u81EA\u52A8\u91CD\u8BD5\uFF0C\u4E5F\u53EF\u4EE5\u53EA\u91CD\u65B0\u52A0\u8F7D\u672C\u63D2\u4EF6\u3002" }),
|
|
72
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "row", children: [
|
|
73
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: busy, onClick: reload, children: "\u91CD\u65B0\u52A0\u8F7D\u63D2\u4EF6" }),
|
|
74
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: busy, onClick: retry, children: "\u91CD\u65B0\u8FDE\u63A5" })
|
|
75
|
-
] }),
|
|
76
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("details", { children: [
|
|
77
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("summary", { children: "\u4ECD\u65E0\u6CD5\u8FDE\u63A5\uFF1F" }),
|
|
78
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u5148\u68C0\u67E5\u4E0B\u65B9\u7EC4\u4EF6\u7684\u542F\u7528\u9519\u8BEF\u3002\u65E7\u7248 DSH \u82E5\u4E0D\u652F\u6301\u8FD0\u884C\u4E2D\u91CD\u8F7D\uFF0C\u53EF\u5347\u7EA7 DSH\uFF0C\u6216\u901A\u8FC7\u300C\u9000\u51FA DeepSeek Harness\u300D\u5B8C\u5168\u9000\u51FA\u540E\u91CD\u65B0\u6253\u5F00\u3002\u5173\u95ED\u7A97\u53E3\u4E0D\u7B49\u4E8E\u9000\u51FA\uFF0C\u8D26\u53F7\u3001\u8DEF\u7531\u4E0E\u7528\u91CF\u4F1A\u4FDD\u7559\u3002" })
|
|
79
|
-
] })
|
|
80
|
-
] });
|
|
81
|
-
}
|
|
82
|
-
async function readManagementResponse(res) {
|
|
83
|
-
let next;
|
|
84
|
-
try {
|
|
85
|
-
next = JSON.parse(await res.text());
|
|
86
|
-
} catch {
|
|
87
|
-
throw Error(`\u63D2\u4EF6\u540E\u53F0\u672A\u5C31\u7EEA\uFF08HTTP ${res.status}\uFF09\u3002\u6B63\u5728\u91CD\u65B0\u8FDE\u63A5\uFF1B\u82E5\u6301\u7EED\u5931\u8D25\uFF0C\u8BF7\u91CD\u65B0\u52A0\u8F7D\u63D2\u4EF6\u5E76\u68C0\u67E5\u7EC4\u4EF6\u9519\u8BEF\u3002`);
|
|
88
|
-
}
|
|
89
|
-
if (!next || typeof next !== "object" || Array.isArray(next)) throw Error("\u63D2\u4EF6\u540E\u53F0\u8FD4\u56DE\u4E86\u65E0\u6548\u6570\u636E\uFF0C\u8BF7\u5237\u65B0\u9762\u677F\u6216\u91CD\u542F DSH\u3002");
|
|
90
|
-
if (!res.ok) throw Error(next.error || `\u64CD\u4F5C\u5931\u8D25\uFF08HTTP ${res.status}\uFF09`);
|
|
91
|
-
return next;
|
|
92
|
-
}
|
|
93
|
-
var fmt = (n) => typeof n === "number" ? new Intl.NumberFormat("zh-CN", { maximumFractionDigits: 2 }).format(n) : "\u2014";
|
|
94
|
-
var when = (n) => n ? new Date(n).toLocaleString("zh-CN", { hour12: false }) : "\u5C1A\u672A\u83B7\u53D6";
|
|
95
|
-
var strategies = { failover: "\u6545\u969C\u5207\u6362", weighted: "\u6309\u6743\u91CD\u5206\u914D", tokens: "\u6309 Token \u989D\u5EA6\u8F6E\u6362", credits: "\u6309\u79EF\u5206\u6D88\u8017\u8F6E\u6362" };
|
|
96
|
-
var loginNames = { valid: "\u767B\u5F55\u6709\u6548", configured: "\u5DF2\u4FDD\u5B58 PAT", "refresh-needed": "\u7B49\u5F85\u5237\u65B0", expired: "\u767B\u5F55\u5DF2\u8FC7\u671F", missing: "\u672A\u83B7\u53D6\u767B\u5F55\u4FE1\u606F" };
|
|
97
|
-
var effortNames = { off: "\u5173\u95ED\u601D\u8003 \xB7 Off", minimal: "\u6700\u4F4E \xB7 Minimal", low: "\u4F4E \xB7 Low", medium: "\u4E2D \xB7 Medium", high: "\u9AD8 \xB7 High", xhigh: "\u8D85\u9AD8 \xB7 XHigh", max: "\u6700\u9AD8 \xB7 Max" };
|
|
98
|
-
function downloadJson(exported) {
|
|
99
|
-
const url = URL.createObjectURL(new Blob([JSON.stringify(exported.document, null, 2)], { type: "application/json" }));
|
|
100
|
-
const a = document.createElement("a");
|
|
101
|
-
a.href = url;
|
|
102
|
-
a.download = exported.filename;
|
|
103
|
-
document.body.append(a);
|
|
104
|
-
a.click();
|
|
105
|
-
a.remove();
|
|
106
|
-
setTimeout(() => URL.revokeObjectURL(url), 1e4);
|
|
107
|
-
}
|
|
108
|
-
var styles = `
|
|
109
|
-
.mr{--mr-accent:var(--dsw-alias-state-active-primary,#3a71db);--mr-border:var(--dsw-alias-border-l2,#444);--mr-bg:var(--dsw-alias-bg-layer-1,#202020);--mr-card:var(--dsw-alias-bg-module-platform,#282828);--mr-text:var(--dsw-alias-label-primary,#f4f4f4);--mr-muted:var(--dsw-alias-label-secondary,#b0b0b0);color:var(--mr-text);font:inherit;font-size:14px;line-height:1.6;max-width:1120px}
|
|
110
|
-
.mr *{box-sizing:border-box}.mr h2,.mr h3,.mr p{margin:0}.mr h2{font-size:22px}.mr h3{font-size:16px}.mr small,.mr .muted,.mr .notice{color:var(--mr-muted)}.mr .notice{font-size:13px}.mr .mono{font:12px ui-monospace,monospace;overflow-wrap:anywhere}
|
|
111
|
-
.mr .bar,.mr .row{display:flex;gap:12px;align-items:center;flex-wrap:wrap}.mr .bar{justify-content:space-between}.mr .stack{display:flex;flex-direction:column;gap:16px}.mr .grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px}.mr .metrics{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px}.mr .providers{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px}.mr .full{grid-column:1/-1}
|
|
112
|
-
.mr .box{border:1px solid var(--mr-border);border-radius:12px;padding:20px;background:var(--mr-card)}.mr .metric strong{font-size:26px;line-height:1.3;display:block;margin:8px 0}.mr .metric small{font-size:12px}.mr .item{padding:16px 0;border-top:1px solid var(--mr-border)}.mr .item:first-child{border-top:0}.mr .item:last-child{padding-bottom:0}.mr .badge{border:1px solid var(--mr-border);border-radius:6px;padding:3px 8px;font-size:12px;white-space:nowrap}.mr .empty{padding:24px 0;text-align:center;color:var(--mr-muted)}
|
|
113
|
-
.mr nav{display:flex;flex-wrap:wrap;gap:8px;border-bottom:1px solid var(--mr-border);padding:18px 0;margin-bottom:20px}.mr button,.mr input,.mr select,.mr textarea,.mr .link{font:inherit;color:inherit;border:1px solid var(--mr-border);border-radius:8px;background:var(--mr-bg);min-height:44px;padding:9px 12px}.mr button,.mr .link{cursor:pointer;transition:background .15s}.mr button:hover,.mr .link:hover{background:var(--mr-card)}.mr button:disabled{opacity:.45;cursor:default}.mr button.primary,.mr button[aria-pressed=true]{background:var(--mr-accent);color:#fff;border-color:transparent}.mr button.quiet{border-color:transparent;background:transparent}.mr :is(button,input,select,textarea,a):focus-visible{outline:2px solid var(--mr-accent);outline-offset:3px}.mr input:not([type=checkbox]),.mr select,.mr textarea{width:100%;min-width:0}.mr input[type=checkbox]{width:18px;height:18px;min-height:0;accent-color:var(--mr-accent)}.mr label{display:flex;flex-direction:column;gap:6px;font-size:13px}.mr label.check{flex-direction:row;align-items:center;gap:8px;min-height:44px}.mr .filter{min-width:170px;max-width:240px}.mr .feedback{padding:12px 16px;border-radius:8px;border:1px solid var(--mr-border)}.mr .error{color:var(--dsw-alias-state-error-primary,#ef9393)}.mr .good{color:var(--dsw-alias-state-success-primary,#77ca9d)}.mr .route-path{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.mr .route-path span{padding:4px 9px;border:1px solid var(--mr-border);border-radius:6px}.mr details{border-top:1px solid var(--mr-border);padding-top:14px}.mr summary{cursor:pointer;color:var(--mr-muted)}.mr progress{width:100%;height:7px;accent-color:var(--mr-accent)}.mr .trend{height:100px;display:flex;align-items:flex-end;gap:8px;margin:16px 0}.mr .trend>div{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:flex-end;height:100%;min-width:0}.mr .trend i{display:block;width:100%;min-height:3px;border-radius:4px 4px 0 0;background:var(--mr-accent)}.mr .trend small{font-size:11px;white-space:nowrap}.mr .table{width:100%;border-collapse:collapse;font-size:13px}.mr th,.mr td{text-align:left;border-bottom:1px solid var(--mr-border);padding:10px 8px}.mr th{font-weight:500;color:var(--mr-muted)}.mr .scroll{overflow:auto}.mr .steps{padding:14px 16px;border-left:3px solid var(--mr-accent);background:var(--mr-bg);border-radius:8px}.mr .link{text-decoration:none;display:inline-flex;align-items:center}
|
|
114
|
-
.mr dialog{color:var(--mr-text);background:var(--mr-bg);border:1px solid var(--mr-border);border-radius:16px;width:min(900px,calc(100vw - 32px));max-height:calc(100vh - 40px);padding:0;box-shadow:0 24px 80px #0008}.mr dialog::backdrop{background:#000a}.mr .modal-head,.mr .modal-foot{padding:18px 24px;background:var(--mr-bg);position:sticky;z-index:1}.mr .modal-head{top:0;border-bottom:1px solid var(--mr-border)}.mr .modal-foot{bottom:0;border-top:1px solid var(--mr-border)}.mr .modal-body{padding:24px}.mr .target-head strong{font-size:14px}.mr .subtle{background:var(--mr-bg)}
|
|
115
|
-
@media(max-width:850px){.mr .providers{grid-template-columns:1fr}.mr .metrics{grid-template-columns:repeat(2,minmax(0,1fr))}}@media(max-width:600px){.mr .grid{grid-template-columns:1fr}.mr .box{padding:16px}.mr nav{flex-wrap:wrap}.mr .modal-body,.mr .modal-head,.mr .modal-foot{padding:16px}.mr .metrics{gap:8px}.mr .metric strong{font-size:22px}}
|
|
116
|
-
.mr{--mr-soft:color-mix(in srgb,var(--mr-text) 3%,var(--mr-card));--mr-selected:color-mix(in srgb,var(--mr-accent) 7%,var(--mr-card));max-width:1280px;min-width:0;line-height:1.55}
|
|
117
|
-
.mr h2{font-size:24px;letter-spacing:-.5px;font-weight:650}.mr h3{font-weight:600}.mr .stack{gap:20px}.mr .row{gap:8px}.mr .box{border-radius:14px;background:var(--mr-card)}.mr .box.stack{gap:16px}
|
|
118
|
-
.mr nav{gap:4px;padding:16px 0 0;margin-bottom:24px}.mr nav button{border:0;border-radius:0;background:transparent;padding:12px 14px;border-bottom:2px solid transparent;color:var(--mr-muted)}.mr nav button[aria-pressed=true]{background:transparent;color:var(--mr-text);border-bottom-color:var(--mr-text);font-weight:600}.mr nav button:hover{background:var(--mr-soft)}
|
|
119
|
-
.mr button.primary{background:var(--mr-text);color:var(--mr-card);border-color:var(--mr-text)}.mr button.primary:hover{opacity:.85}.mr button:active:not(:disabled){filter:brightness(.9)}.mr button.quiet{color:var(--mr-muted)}.mr .badge{border-radius:100px;background:var(--mr-soft);padding:4px 10px}.mr .metric{background:var(--mr-soft)}.mr .metric strong{font-size:28px;font-variant-numeric:tabular-nums;letter-spacing:-.5px;margin:10px 0 4px}.mr .metrics{gap:16px}
|
|
120
|
-
.mr .status{display:inline-flex;align-items:center;gap:7px;font-size:13px;white-space:nowrap}.mr .status i{width:8px;height:8px;border-radius:50%;background:var(--mr-muted);display:inline-block;flex-shrink:0}.mr .status i.good{background:var(--dsw-alias-state-success-primary,#38a16a)}.mr .status i.warn{background:var(--dsw-alias-state-warning-primary,#c48b28)}.mr .warn{color:var(--dsw-alias-state-warning-primary,#c48b28)}
|
|
121
|
-
.mr .table-shell{padding:0;overflow:hidden}.mr .scroll>.table{min-width:760px}.mr .table{font-size:14px}.mr .table th{background:var(--mr-soft);font-size:12px;letter-spacing:.02em;font-weight:500;white-space:nowrap}.mr .table th,.mr .table td{padding:16px 20px;vertical-align:middle}.mr .table td:last-child{white-space:nowrap}.mr .table tbody tr:last-child td{border-bottom:0}.mr .table td small{display:block;font-size:12px;margin-top:3px}.mr .table td>strong{font-weight:600}.mr .table tr.selected{background:var(--mr-selected)}.mr .table tbody tr:hover{background:var(--mr-soft)}.mr .table .account-name{max-width:230px;overflow-wrap:anywhere}.mr .table .amount{font-size:20px;line-height:1.35;font-variant-numeric:tabular-nums;font-weight:600;white-space:nowrap}.mr .table .cell-actions{white-space:nowrap;text-align:right}.mr .table .account-check{min-width:44px;min-height:44px;justify-content:center;flex-shrink:0}.mr .table .account-cell{display:flex;gap:10px;align-items:center}.mr .table .account-cell .check{margin-left:-12px}.mr .table .account-cell input{accent-color:var(--mr-text)}.mr .table .row{flex-wrap:nowrap}.mr .section-title{margin-bottom:4px}.mr .toolbar{align-items:flex-end;gap:16px}.mr .search{max-width:280px;flex:1;min-width:160px}.mr .table-footer{padding:14px 20px;background:var(--mr-soft)}.mr .hint{font-size:13px;color:var(--mr-muted)}.mr details.help{border:0;padding:0}.mr details.help>div{padding:12px 0;max-width:76ch}.mr .plan-form{align-items:flex-end;padding:16px 0 0;border-top:1px solid var(--mr-border)}.mr .plan-form .filter{min-width:180px}.mr .steps{border:1px solid var(--mr-border);border-radius:10px;background:var(--mr-soft);padding:14px 16px}.mr .route-path span{background:var(--mr-soft);border-color:transparent;font-size:12px}.mr .route-card details{padding-top:10px}.mr .feedback{margin-bottom:16px}.mr .box .feedback{margin-bottom:0}.mr .scroll{max-width:100%}.mr .scroll:focus-visible{outline:2px solid var(--mr-accent);outline-offset:-3px}
|
|
122
|
-
@media(max-width:850px){.mr .metrics{gap:10px}.mr nav{gap:0}.mr nav button{padding:12px 10px}}@media(max-width:600px){.mr h2{font-size:22px}.mr nav{display:grid;grid-template-columns:repeat(4,minmax(0,1fr))}.mr nav button{padding:10px 4px;font-size:12px;white-space:nowrap}.mr .toolbar>.row{width:100%}.mr .toolbar .search{max-width:none}.mr .metric strong{font-size:24px}.mr .table th,.mr .table td{padding:14px 16px}.mr .filter{max-width:none}.mr .plan-form label{flex:1}.mr .box.table-shell{padding:0}}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
.mr .metrics{gap:0;border:1px solid var(--mr-border);border-radius:12px;overflow:hidden;background:var(--mr-card)}
|
|
126
|
-
.mr .metrics .metric{border:0;border-radius:0;background:transparent;border-right:1px solid var(--mr-border);padding:16px 20px}.mr .metrics .metric:last-child{border-right:0}.mr .metric strong{font-size:25px;margin:6px 0}.mr .performance{gap:10px}.mr .performance .metrics{background:var(--mr-soft);border-color:transparent}.mr .performance .metric strong{font-size:21px}.mr .performance .metric{padding:12px 20px}.mr .performance h3{font-size:14px}.mr .refresh-control{font-size:12px;color:var(--mr-muted)}
|
|
127
|
-
.mr .section-pad{padding:16px 20px}.mr .table-shell>.section-pad+.section-pad{padding-top:0}.mr .route-table td{max-width:300px}.mr .route-table .route-targets{max-width:300px;white-space:normal;overflow-wrap:anywhere}.mr .route-table small{max-width:320px}.mr .model-table td:first-child{width:38%}.mr .table .cell-actions{width:1%}.mr .install-plugin>div{padding-top:16px}.mr details.help.box{padding:18px 20px}.mr .sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap}
|
|
128
|
-
@media(max-width:600px){.mr .metrics .metric{padding:12px 14px}.mr .metrics .metric:nth-child(2){border-right:0}.mr .metrics .metric:nth-child(-n+2){border-bottom:1px solid var(--mr-border)}.mr .section-pad{padding:14px 16px}}
|
|
129
|
-
|
|
130
|
-
@media(prefers-reduced-motion:reduce){.mr *{transition:none!important}}
|
|
131
|
-
`;
|
|
132
|
-
function apply(ctx) {
|
|
133
|
-
reloadFromHost = () => requestPluginReload(ctx.get?.("remote"));
|
|
134
|
-
ctx.slots.inject("plugins.bundle.config", () => ctx.slots.register({ name: "plugins.bundle.config", key: "dsh-multi-router" }, RouterPage));
|
|
135
|
-
ctx.slots.inject("shell.overlay", () => ctx.slots.register({ name: "shell.overlay", id: "dsh-multi-router-updates" }, UpdateReminder));
|
|
136
|
-
ctx.slots.inject("sidebar.footer.action", () => ctx.slots.register({
|
|
137
|
-
name: "sidebar.footer.action",
|
|
138
|
-
id: "dsh-multi-router-usage",
|
|
139
|
-
order: 10,
|
|
140
|
-
inject: () => ({ open: () => {
|
|
141
|
-
const navigation = ctx.get?.("pluginNavigation");
|
|
142
|
-
if (!navigation?.openBundle) throw Error("\u8BF7\u5728\u63D2\u4EF6\u9875\u6253\u5F00 dsh-multi-router\uFF1B\u5F53\u524D DSH \u672A\u63D0\u4F9B\u8BE6\u60C5\u5BFC\u822A\u3002");
|
|
143
|
-
navigation.openBundle("dsh-multi-router");
|
|
144
|
-
} })
|
|
145
|
-
}, SidebarUsage));
|
|
146
|
-
}
|
|
147
|
-
var SUMMARY_EVENT = "dsh-multi-router-summary";
|
|
148
|
-
var compactTokens = (n) => n >= 1e9 ? `${(n / 1e9).toFixed(1)}B` : n >= 1e6 ? `${(n / 1e6).toFixed(1)}M` : n >= 1e3 ? `${(n / 1e3).toFixed(1)}K` : fmt(n);
|
|
149
|
-
function SidebarUsageCard({ data, wide = true, open, error }) {
|
|
150
|
-
const title = `${data.today}\uFF08\u5317\u4EAC\u65F6\u95F4\uFF09
|
|
151
|
-
\u4ECA\u65E5 ${fmt(data.tokens)} Token \xB7 ${fmt(data.requests)} \u6B21\u8BF7\u6C42
|
|
152
|
-
\u7D2F\u8BA1 ${fmt(data.totalTokens)} Token${data.unmetered ? `
|
|
153
|
-
${fmt(data.unmetered)} \u6B21\u8C03\u7528\u672A\u8FD4\u56DE\u7528\u91CF` : ""}${error ? `
|
|
154
|
-
${error}` : ""}
|
|
155
|
-
\u70B9\u51FB\u6253\u5F00\u8D26\u53F7\u4E0E\u8DEF\u7531`;
|
|
156
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
157
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: `
|
|
158
|
-
[class*="_footArea"] [class*="_footerActions"]:has(.mr-sidebar-usage){flex-direction:column}
|
|
159
|
-
.mr-sidebar-usage{box-sizing:border-box;display:flex;align-items:center;gap:10px;width:100%;min-width:0;min-height:48px;padding:7px 10px;border:1px solid var(--dsw-alias-border-l2,#444);border-radius:8px;background:transparent;color:var(--dsw-alias-label-primary,#eee);font:inherit;text-align:left;cursor:pointer}
|
|
160
|
-
.mr-sidebar-usage:hover{background:var(--dsw-alias-bg-module-platform,#303036)}.mr-sidebar-usage:focus-visible{outline:2px solid var(--dsw-alias-state-active-primary,#3a71db);outline-offset:2px}
|
|
161
|
-
.mr-sidebar-usage svg{flex-shrink:0}.mr-sidebar-usage span{flex:1;min-width:0}.mr-sidebar-usage small{display:block;color:var(--dsw-alias-label-secondary,#aaa);font-size:10px;line-height:15px;white-space:nowrap}.mr-sidebar-usage strong{display:block;font-size:13px;font-weight:600;line-height:18px;font-variant-numeric:tabular-nums;white-space:nowrap}.mr-sidebar-usage[data-wide=false]{width:36px;min-height:36px;padding:8px;justify-content:center}
|
|
162
|
-
` }),
|
|
163
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", { className: "mr-sidebar-usage", "data-wide": wide, title, "aria-label": `Token \u7528\u91CF\u6982\u89C8\uFF0C\u4ECA\u65E5 ${fmt(data.tokens)}\uFF0C\u7D2F\u8BA1 ${fmt(data.totalTokens)}\uFF0C\u6253\u5F00\u63D2\u4EF6\u8BE6\u60C5`, onClick: open, children: [
|
|
164
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.6", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M4 4v16h17M8 16v-5m5 5V7m5 9v-7" }) }),
|
|
165
|
-
wide && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
166
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: [
|
|
167
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("small", { children: [
|
|
168
|
-
"\u4ECA\u65E5 Token",
|
|
169
|
-
error ? " \xB7 \u672A\u5237\u65B0" : ""
|
|
170
|
-
] }),
|
|
171
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: compactTokens(data.tokens) })
|
|
172
|
-
] }),
|
|
173
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: [
|
|
174
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("small", { children: "\u7D2F\u8BA1 Token" }),
|
|
175
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: compactTokens(data.totalTokens) })
|
|
176
|
-
] })
|
|
177
|
-
] })
|
|
178
|
-
] })
|
|
179
|
-
] });
|
|
180
|
-
}
|
|
181
|
-
function SidebarUsage({ wide = true, open }) {
|
|
182
|
-
const [data, setData] = (0, import_react.useState)(null), [error, setError] = (0, import_react.useState)("");
|
|
183
|
-
(0, import_react.useEffect)(() => {
|
|
184
|
-
let stopped = false, pending = false, again = false;
|
|
185
|
-
const abort = new AbortController();
|
|
186
|
-
async function poll(event) {
|
|
187
|
-
if (document.hidden) return;
|
|
188
|
-
if (pending) {
|
|
189
|
-
if (event?.type === SUMMARY_EVENT) again = true;
|
|
190
|
-
return;
|
|
191
|
-
}
|
|
192
|
-
pending = true;
|
|
193
|
-
try {
|
|
194
|
-
const next = await readManagementResponse(await fetch(`${ENDPOINT}/summary`, { cache: "no-store", signal: AbortSignal.any([abort.signal, AbortSignal.timeout(8e3)]) }));
|
|
195
|
-
if (!stopped) {
|
|
196
|
-
setData(next);
|
|
197
|
-
setError("");
|
|
198
|
-
}
|
|
199
|
-
} catch {
|
|
200
|
-
if (!stopped) setError("\u6682\u65F6\u65E0\u6CD5\u5237\u65B0\u672C\u673A\u7EDF\u8BA1");
|
|
201
|
-
} finally {
|
|
202
|
-
pending = false;
|
|
203
|
-
if (again && !stopped) {
|
|
204
|
-
again = false;
|
|
205
|
-
void poll();
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
void poll();
|
|
210
|
-
const timer = setInterval(() => {
|
|
211
|
-
void poll();
|
|
212
|
-
}, 6e4);
|
|
213
|
-
document.addEventListener("visibilitychange", poll);
|
|
214
|
-
window.addEventListener(SUMMARY_EVENT, poll);
|
|
215
|
-
return () => {
|
|
216
|
-
stopped = true;
|
|
217
|
-
abort.abort();
|
|
218
|
-
clearInterval(timer);
|
|
219
|
-
document.removeEventListener("visibilitychange", poll);
|
|
220
|
-
window.removeEventListener(SUMMARY_EVENT, poll);
|
|
221
|
-
};
|
|
222
|
-
}, []);
|
|
223
|
-
if (!data || data.enabled === false) return null;
|
|
224
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SidebarUsageCard, { data, wide, error, open: () => {
|
|
225
|
-
try {
|
|
226
|
-
open();
|
|
227
|
-
} catch (e) {
|
|
228
|
-
setError(e.message);
|
|
229
|
-
}
|
|
230
|
-
} });
|
|
231
|
-
}
|
|
232
|
-
function Modal({ title, close, children, busy }) {
|
|
233
|
-
const ref = (0, import_react.useRef)(null);
|
|
234
|
-
(0, import_react.useEffect)(() => {
|
|
235
|
-
const dialog = ref.current;
|
|
236
|
-
dialog.showModal();
|
|
237
|
-
return () => dialog.close();
|
|
238
|
-
}, []);
|
|
239
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("dialog", { ref, "aria-label": title, onCancel: (e) => {
|
|
240
|
-
e.preventDefault();
|
|
241
|
-
if (!busy) close();
|
|
242
|
-
}, children: [
|
|
243
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "modal-head bar", children: [
|
|
244
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { children: title }),
|
|
245
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", disabled: busy, onClick: close, children: "\u5173\u95ED" })
|
|
246
|
-
] }),
|
|
247
|
-
children
|
|
248
|
-
] });
|
|
249
|
-
}
|
|
250
|
-
function UpdateReminder() {
|
|
251
|
-
const [data, setData] = (0, import_react.useState)(null), [opened, setOpened] = (0, import_react.useState)(null), [manage, setManage] = (0, import_react.useState)(false), [busy, setBusy] = (0, import_react.useState)(false), [error, setError] = (0, import_react.useState)("");
|
|
252
|
-
(0, import_react.useEffect)(() => {
|
|
253
|
-
let live = true, pending = false;
|
|
254
|
-
async function poll() {
|
|
255
|
-
if (document.hidden || pending) return;
|
|
256
|
-
pending = true;
|
|
257
|
-
try {
|
|
258
|
-
const next = await readManagementResponse(await fetch(ENDPOINT, { cache: "no-store" }));
|
|
259
|
-
if (live && !backendNeedsRestart(next)) {
|
|
260
|
-
setData(next);
|
|
261
|
-
setOpened((current) => current ?? (next.pluginUpdates?.reminders?.length && !document.querySelector("dialog[open]") ? next.pluginUpdates.reminders : null));
|
|
262
|
-
}
|
|
263
|
-
} catch {
|
|
264
|
-
} finally {
|
|
265
|
-
pending = false;
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
void poll();
|
|
269
|
-
const timer = setInterval(() => {
|
|
270
|
-
void poll();
|
|
271
|
-
}, 6e4);
|
|
272
|
-
return () => {
|
|
273
|
-
live = false;
|
|
274
|
-
clearInterval(timer);
|
|
275
|
-
};
|
|
276
|
-
}, []);
|
|
277
|
-
(0, import_react.useEffect)(() => {
|
|
278
|
-
if (data?.pluginUpdates?.job?.state !== "running") return;
|
|
279
|
-
let live = true;
|
|
280
|
-
const timer = setInterval(() => {
|
|
281
|
-
void fetch(ENDPOINT, { cache: "no-store" }).then(readManagementResponse).then((next) => {
|
|
282
|
-
if (live) setData(next);
|
|
283
|
-
}).catch(() => {
|
|
284
|
-
});
|
|
285
|
-
}, 2e3);
|
|
286
|
-
return () => {
|
|
287
|
-
live = false;
|
|
288
|
-
clearInterval(timer);
|
|
289
|
-
};
|
|
290
|
-
}, [data?.pluginUpdates?.job?.state]);
|
|
291
|
-
async function act(action) {
|
|
292
|
-
if (busy) return false;
|
|
293
|
-
setBusy(true);
|
|
294
|
-
setError("");
|
|
295
|
-
try {
|
|
296
|
-
const next = await readManagementResponse(await fetch(ENDPOINT, { method: "POST", headers: { "Content-Type": "application/json", "X-Multi-Router-Key": data.key }, body: JSON.stringify({ revision: data.revision, ...action }) }));
|
|
297
|
-
setData(next);
|
|
298
|
-
return next;
|
|
299
|
-
} catch (e) {
|
|
300
|
-
setError(e.message);
|
|
301
|
-
return false;
|
|
302
|
-
} finally {
|
|
303
|
-
setBusy(false);
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
async function dismiss() {
|
|
307
|
-
if (await act({ action: "plugins.dismiss", keys: opened.map((r) => r.key) })) {
|
|
308
|
-
setOpened(null);
|
|
309
|
-
setManage(false);
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
if (!opened || !data) return null;
|
|
313
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "mr", children: [
|
|
314
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: styles }),
|
|
315
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Modal, { title: "\u53D1\u73B0\u63D2\u4EF6\u66F4\u65B0", busy: busy || data.pluginUpdates?.job?.state === "running", close: () => {
|
|
316
|
-
void dismiss();
|
|
317
|
-
}, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "modal-body stack", children: [
|
|
318
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Feedback, { error }),
|
|
319
|
-
manage ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PluginUpdatesPanel, { data: data.pluginUpdates, busy, act }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
320
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { children: [
|
|
321
|
-
opened.length,
|
|
322
|
-
" \u4E2A\u7528\u6237\u5B89\u88C5\u7684\u63D2\u4EF6\u6709\u66F4\u65B0\u3002\u8BF7\u9009\u62E9\u67E5\u770B\u66F4\u65B0\uFF0C\u6216\u7A0D\u540E\u5904\u7406\u3002"
|
|
323
|
-
] }),
|
|
324
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("ul", { children: opened.map((r) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("li", { children: [
|
|
325
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: r.name }),
|
|
326
|
-
" \xB7 ",
|
|
327
|
-
r.version || "\u672A\u77E5\u7248\u672C",
|
|
328
|
-
" \u2192 ",
|
|
329
|
-
r.latestVersion || `Git ${r.latestCommit?.slice(0, 8)}`
|
|
330
|
-
] }, r.key)) }),
|
|
331
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u6BCF 24 \u5C0F\u65F6\u81EA\u52A8\u68C0\u67E5 GitHub / npm \u5B89\u88C5\u6765\u6E90\uFF1B\u540C\u4E00\u7248\u672C\u53EA\u63D0\u9192\u4E00\u6B21\u3002DSH \u5185\u7F6E\u63D2\u4EF6\u4E0D\u53C2\u4E0E\u68C0\u67E5\uFF0C\u4E0D\u4F1A\u81EA\u52A8\u5B89\u88C5\u66F4\u65B0\u3002" })
|
|
332
|
-
] }),
|
|
333
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "row", children: [
|
|
334
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: busy || data.pluginUpdates?.job?.state === "running", onClick: () => {
|
|
335
|
-
void dismiss();
|
|
336
|
-
}, children: "\u7A0D\u540E\u5904\u7406" }),
|
|
337
|
-
!manage && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { className: "primary", disabled: busy, onClick: () => setManage(true), children: "\u67E5\u770B\u5E76\u66F4\u65B0" })
|
|
338
|
-
] })
|
|
339
|
-
] }) })
|
|
340
|
-
] });
|
|
341
|
-
}
|
|
342
|
-
function Feedback({ error, notice }) {
|
|
343
|
-
return error ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "feedback error", role: "alert", children: error }) : notice ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "feedback", role: "status", children: notice }) : null;
|
|
344
|
-
}
|
|
345
|
-
var metric = (label, value, detail) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "box metric", children: [
|
|
346
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("small", { children: label }),
|
|
347
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: value }),
|
|
348
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("small", { children: detail })
|
|
349
|
-
] });
|
|
350
|
-
function RouterPage({ view = "page" }) {
|
|
351
|
-
const [data, setData] = (0, import_react.useState)(null), [tab, setTab] = (0, import_react.useState)("overview");
|
|
352
|
-
const [accountProvider, setAccountProvider] = (0, import_react.useState)(""), [provider, setProvider] = (0, import_react.useState)("workbuddy"), [busy, setBusy] = (0, import_react.useState)(false), [live, setLive] = (0, import_react.useState)(true);
|
|
353
|
-
const [error, setError] = (0, import_react.useState)(""), [notice, setNotice] = (0, import_react.useState)(""), [draft, setDraft] = (0, import_react.useState)(null), [accountModal, setAccountModal] = (0, import_react.useState)(null), [presetModal, setPresetModal] = (0, import_react.useState)(false), [search, setSearch] = (0, import_react.useState)("");
|
|
354
|
-
const polling = (0, import_react.useRef)(false);
|
|
355
|
-
async function load(signal = AbortSignal.timeout(8e3)) {
|
|
356
|
-
const next = await readManagementResponse(await fetch(ENDPOINT, { cache: "no-store", signal }));
|
|
357
|
-
setData(next);
|
|
358
|
-
setError("");
|
|
359
|
-
}
|
|
360
|
-
(0, import_react.useEffect)(() => {
|
|
361
|
-
if (view === "summary") return;
|
|
362
|
-
let stopped = false, retry, attempts = 0;
|
|
363
|
-
const abort = new AbortController();
|
|
364
|
-
async function connect() {
|
|
365
|
-
try {
|
|
366
|
-
await load(AbortSignal.any([abort.signal, AbortSignal.timeout(4e3)]));
|
|
367
|
-
} catch (e) {
|
|
368
|
-
if (stopped) return;
|
|
369
|
-
if (++attempts < 8) retry = setTimeout(connect, 750);
|
|
370
|
-
else setError(e.message);
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
void connect();
|
|
374
|
-
const timer = live && setInterval(() => {
|
|
375
|
-
if (document.hidden || polling.current) return;
|
|
376
|
-
polling.current = true;
|
|
377
|
-
void load(abort.signal).catch((e) => {
|
|
378
|
-
if (!stopped) setError(e.message);
|
|
379
|
-
}).finally(() => {
|
|
380
|
-
polling.current = false;
|
|
381
|
-
});
|
|
382
|
-
}, 6e4);
|
|
383
|
-
return () => {
|
|
384
|
-
stopped = true;
|
|
385
|
-
abort.abort();
|
|
386
|
-
clearTimeout(retry);
|
|
387
|
-
clearInterval(timer);
|
|
388
|
-
};
|
|
389
|
-
}, [view, live]);
|
|
390
|
-
(0, import_react.useEffect)(() => {
|
|
391
|
-
if (data?.startup?.phase !== "discovering" && !["waiting", "reloading"].includes(data?.runtime?.phase) && data?.pluginUpdates?.job?.state !== "running" && !data?.checkins?.running) return;
|
|
392
|
-
const timer = setInterval(() => {
|
|
393
|
-
if (document.hidden || polling.current) return;
|
|
394
|
-
polling.current = true;
|
|
395
|
-
void load().catch((e) => setError(e.message)).finally(() => {
|
|
396
|
-
polling.current = false;
|
|
397
|
-
});
|
|
398
|
-
}, 2e3);
|
|
399
|
-
return () => clearInterval(timer);
|
|
400
|
-
}, [data?.startup?.phase, data?.runtime?.phase, data?.pluginUpdates?.job?.state, data?.checkins?.running]);
|
|
401
|
-
async function reload() {
|
|
402
|
-
setBusy(true);
|
|
403
|
-
setError("");
|
|
404
|
-
try {
|
|
405
|
-
if (!reloadFromHost) throw Error("\u8BF7\u5728 DSH \u63D2\u4EF6\u9875\u91CD\u65B0\u542F\u7528\u672C\u63D2\u4EF6\u3002");
|
|
406
|
-
await reloadFromHost();
|
|
407
|
-
await load();
|
|
408
|
-
} catch (e) {
|
|
409
|
-
setError(e.message);
|
|
410
|
-
} finally {
|
|
411
|
-
setBusy(false);
|
|
412
|
-
}
|
|
413
|
-
}
|
|
414
|
-
async function act(action) {
|
|
415
|
-
if (busy || backendNeedsRestart(data)) return false;
|
|
416
|
-
setBusy(true);
|
|
417
|
-
setError("");
|
|
418
|
-
setNotice("");
|
|
419
|
-
try {
|
|
420
|
-
const res = await fetch(ENDPOINT, { method: "POST", headers: { "Content-Type": "application/json", "X-Multi-Router-Key": data.key }, body: JSON.stringify({ revision: data.revision, ...action }) });
|
|
421
|
-
const next = await readManagementResponse(res);
|
|
422
|
-
const { exported, workbuddyLogin, loginResult, apiKey, modelTest, ...state } = next;
|
|
423
|
-
setData(state);
|
|
424
|
-
if (action.sidebarUsage !== void 0 || action.action === "config.import") window.dispatchEvent(new Event(SUMMARY_EVENT));
|
|
425
|
-
setNotice(action.action === "model.test" ? "" : action.action.startsWith("api.") ? next.apiService?.phase === "error" ? "\u914D\u7F6E\u5DF2\u4FDD\u5B58\uFF0C\u4F46\u670D\u52A1\u5C1A\u672A\u542F\u52A8\uFF0C\u8BF7\u67E5\u770B\u4E0B\u65B9\u63D0\u793A\u3002" : action.action === "api.key.reveal" ? "" : "API \u8BBE\u7F6E\u5DF2\u4FDD\u5B58\u3002" : action.action === "workbuddy.sms" ? "" : action.action === "workbuddy.login" ? loginResult?.warning || "\u767B\u5F55\u51ED\u8BC1\u5DF2\u4FDD\u5B58\uFF0C\u81EA\u52A8\u7B7E\u5230\u5F00\u5173\u4FDD\u6301\u539F\u8BBE\u7F6E\u3002" : action.action === "checkins.verify" ? "\u767B\u5F55\u9A8C\u8BC1\u901A\u8FC7\uFF0C\u65E7\u7684\u4EE4\u724C\u5931\u6548\u63D0\u793A\u5DF2\u89E3\u9664\uFF1B\u672A\u63D0\u4EA4\u7B7E\u5230\u3002" : action.action === "checkins.settings" ? "\u7B7E\u5230\u8BA1\u5212\u5DF2\u4FDD\u5B58\uFF1B\u4ECA\u65E5\u5DF2\u5904\u7406\u8BB0\u5F55\u4FDD\u6301\u4E0D\u53D8\u3002" : action.action.startsWith("checkins.") || action.action.startsWith("plugins.") || action.action === "setup.dismiss" ? "" : action.action === "accounts.discover" || action.action === "monitor.refresh" ? "\u5DF2\u91CD\u65B0\u68C0\u6D4B\u672C\u673A\u767B\u5F55\u5E76\u5237\u65B0\u7528\u91CF\uFF1B\u68C0\u6D4B\u7ED3\u679C\u89C1\u4E0B\u65B9\u3002" : action.action.includes("refresh") ? "\u5DF2\u5237\u65B0\u3002\u65E0\u6CD5\u83B7\u53D6\u7684\u8D26\u53F7\u4F1A\u4FDD\u7559\u4E0A\u6B21\u6570\u636E\u5E76\u6807\u8BB0\u3002" : action.action === "config.import" ? "\u914D\u7F6E\u5DF2\u5BFC\u5165\u5E76\u751F\u6548\uFF0C\u539F\u914D\u7F6E\u5DF2\u5907\u4EFD\uFF1B\u6A21\u578B\u548C\u7528\u91CF\u6B63\u5728\u540E\u53F0\u66F4\u65B0\u3002" : action.action.startsWith("config.") || action.action === "account.export" ? "" : "\u5DF2\u4FDD\u5B58\u5E76\u751F\u6548\u3002");
|
|
426
|
-
return next;
|
|
427
|
-
} catch (e) {
|
|
428
|
-
setError(e.message);
|
|
429
|
-
return false;
|
|
430
|
-
} finally {
|
|
431
|
-
setBusy(false);
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
function openAccount(mode, account) {
|
|
435
|
-
setError("");
|
|
436
|
-
setNotice("");
|
|
437
|
-
setAccountModal({ mode, account, revision: data.revision });
|
|
438
|
-
}
|
|
439
|
-
const newTarget = (target = { provider: "workbuddy" }) => ({ ...target, key: crypto.randomUUID(), weight: target.weight ?? 1, tokenBudget: target.tokenBudget ?? 1e5, creditBudget: target.creditBudget ?? 100, modelText: (target.models ?? [target.model ?? ""]).join(", ") });
|
|
440
|
-
function editRoute(route) {
|
|
441
|
-
setError("");
|
|
442
|
-
setNotice("");
|
|
443
|
-
setDraft({ ...structuredClone(route), revision: data.revision, previousId: route.id, strategy: route.strategy ?? "failover", targets: route.targets.map(newTarget) });
|
|
444
|
-
}
|
|
445
|
-
const p = data?.providers.find((p2) => p2.id === provider);
|
|
446
|
-
const providerSelect = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "filter", children: [
|
|
447
|
-
"\u4F9B\u5E94\u5546 / \u533A\u57DF",
|
|
448
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("select", { value: provider, onChange: (e) => {
|
|
449
|
-
setProvider(e.target.value);
|
|
450
|
-
setSearch("");
|
|
451
|
-
}, children: data?.providers.map((p2) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: p2.id, children: p2.name }, p2.id)) })
|
|
452
|
-
] });
|
|
453
|
-
const accountProviderSelect = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "filter", children: [
|
|
454
|
-
"\u4F9B\u5E94\u5546 / \u533A\u57DF",
|
|
455
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", { value: accountProvider, onChange: (e) => setAccountProvider(e.target.value), children: [
|
|
456
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "", children: "\u5168\u90E8\u4F9B\u5E94\u5546" }),
|
|
457
|
-
data?.providers.map((p2) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: p2.id, children: p2.name }, p2.id))
|
|
458
|
-
] })
|
|
459
|
-
] });
|
|
460
|
-
if (view === "summary") return "\u4E09\u5BB6\u8D26\u53F7\u4E0E\u767B\u5F55\u4FE1\u606F\u3001\u7528\u91CF\u76D1\u63A7\u3001\u6A21\u578B\u7BA1\u7406\uFF0C\u4EE5\u53CA\u6743\u91CD\u548C\u989D\u5EA6\u8DEF\u7531\u3002";
|
|
461
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "mr", children: [
|
|
462
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: styles }),
|
|
463
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bar", children: [
|
|
464
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
465
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { children: "\u8D26\u53F7\u4E0E\u8DEF\u7531" }),
|
|
466
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "muted", children: "\u7BA1\u7406\u4E09\u5BB6\u8D26\u53F7\u3001\u6A21\u578B\u4E0E\u7528\u91CF" })
|
|
467
|
-
] }),
|
|
468
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "row", children: [
|
|
469
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "badge", children: [
|
|
470
|
-
"v",
|
|
471
|
-
data?.pluginVersion ?? version
|
|
472
|
-
] }),
|
|
473
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "check refresh-control", children: [
|
|
474
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "checkbox", disabled: busy || !data || backendNeedsRestart(data), checked: data?.options?.sidebarUsage !== false, onChange: (e) => {
|
|
475
|
-
void act({ action: "options.save", sidebarUsage: e.target.checked });
|
|
476
|
-
} }),
|
|
477
|
-
"\u4FA7\u680F\u7528\u91CF"
|
|
478
|
-
] }),
|
|
479
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "status", children: [
|
|
480
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("i", { className: busy || !data ? "warn" : "good", "aria-hidden": "true" }),
|
|
481
|
-
busy ? "\u6B63\u5728\u5904\u7406\u2026" : !data ? "\u6B63\u5728\u8FDE\u63A5\u2026" : "\u672C\u673A\u8FD0\u884C"
|
|
482
|
-
] }),
|
|
483
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "check refresh-control", children: [
|
|
484
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "checkbox", checked: live, onChange: (e) => setLive(e.target.checked) }),
|
|
485
|
-
"\u6BCF\u5206\u949F\u5237\u65B0"
|
|
486
|
-
] }),
|
|
487
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: busy, onClick: () => {
|
|
488
|
-
void load().catch((e) => setError(e.message));
|
|
489
|
-
}, children: "\u5237\u65B0\u9762\u677F" })
|
|
490
|
-
] })
|
|
491
|
-
] }),
|
|
492
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("nav", { "aria-label": "\u8DEF\u7531\u63D2\u4EF6\u914D\u7F6E\u9875\u7B7E", children: [["overview", "\u603B\u89C8\u4E0E\u7528\u91CF"], ["usage", "Token \u660E\u7EC6"], ["accounts", "\u8D26\u53F7\u4E0E\u767B\u5F55"], ["checkins", "\u79EF\u5206\u7B7E\u5230"], ["models", "\u6A21\u578B\u7BA1\u7406"], ["routes", "\u8DEF\u7531\u89C4\u5219"], ["api", "API \u670D\u52A1"], ["plugins", "\u63D2\u4EF6\u66F4\u65B0"], ["migration", "\u914D\u7F6E\u8FC1\u79FB"]].map(([key, label]) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { "aria-pressed": tab === key, onClick: () => {
|
|
493
|
-
setTab(key);
|
|
494
|
-
setError("");
|
|
495
|
-
setNotice("");
|
|
496
|
-
}, children: label }, key)) }),
|
|
497
|
-
!draft && !accountModal && !presetModal && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Feedback, { error, notice }),
|
|
498
|
-
(backendNeedsRestart(data) || !data && error) && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RestartGuidance, { data, busy, reload: () => {
|
|
499
|
-
void reload();
|
|
500
|
-
}, retry: () => {
|
|
501
|
-
void load().catch((e) => setError(e.message));
|
|
502
|
-
} }),
|
|
503
|
-
!data ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "box stack", role: "status", "aria-live": "polite", children: [
|
|
504
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { children: error ? "\u7B49\u5F85\u540E\u53F0\u8FDE\u63A5" : "\u6B63\u5728\u8FDE\u63A5\u672C\u673A\u63D2\u4EF6\u2026" }),
|
|
505
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u9875\u9762\u4F1A\u81EA\u52A8\u91CD\u65B0\u8FDE\u63A5\u3002\u8D26\u53F7\u53D1\u73B0\u3001\u7528\u91CF\u548C\u6A21\u578B\u76EE\u5F55\u5C06\u5728\u540E\u53F0\u66F4\u65B0\u3002" }),
|
|
506
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("progress", { "aria-label": "\u6B63\u5728\u8FDE\u63A5\u63D2\u4EF6\u540E\u53F0" })
|
|
507
|
-
] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("fieldset", { className: "stack", style: { border: 0, padding: 0, margin: 0, minWidth: 0 }, disabled: backendNeedsRestart(data), "aria-busy": busy, children: [
|
|
508
|
-
data.startup?.phase === "discovering" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "steps", role: "status", children: "\u6B63\u5728\u540E\u53F0\u83B7\u53D6\u672C\u673A\u8D26\u53F7\uFF0C\u5DF2\u6709\u8D26\u53F7\u548C\u8DEF\u7531\u73B0\u5728\u5373\u53EF\u4F7F\u7528\u3002" }),
|
|
509
|
-
data.runtime?.phase && data.runtime.phase !== "current" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "steps", children: [
|
|
510
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { children: [
|
|
511
|
-
data.runtime.message,
|
|
512
|
-
"\uFF08\u8FD0\u884C v",
|
|
513
|
-
data.runtime.runningVersion,
|
|
514
|
-
" / \u5DF2\u5B89\u88C5 v",
|
|
515
|
-
data.runtime.installedVersion,
|
|
516
|
-
"\uFF09"
|
|
517
|
-
] }),
|
|
518
|
-
["failed", "restart-required"].includes(data.runtime.phase) && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: busy, onClick: () => {
|
|
519
|
-
void reload();
|
|
520
|
-
}, children: "\u91CD\u65B0\u52A0\u8F7D\u63D2\u4EF6" })
|
|
521
|
-
] }),
|
|
522
|
-
["overview", "accounts"].includes(tab) && data.setup?.dismissed !== true && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(InitialSetup, { data, busy, act, go: (key) => setTab(key) }),
|
|
523
|
-
tab === "overview" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Overview, { data, busy, act, go: (key) => setTab(key) }),
|
|
524
|
-
tab === "api" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ApiServicePanel, { data: data.apiService, busy, act }),
|
|
525
|
-
tab === "plugins" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PluginUpdatesPanel, { data: data.pluginUpdates, busy, act }),
|
|
526
|
-
tab === "checkins" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CheckinPanel, { data, busy, act }),
|
|
527
|
-
tab === "usage" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(UsageDetails, { data, busy, act }),
|
|
528
|
-
tab === "accounts" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AccountPool, { data, provider: accountProvider, providerSelect: accountProviderSelect, busy, act, manage: (a) => openAccount("edit", a), add: () => openAccount("add") }, accountProvider),
|
|
529
|
-
tab === "models" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ModelsPanel, { error, notice, data, provider, providerSelect, search, setSearch, busy, act }),
|
|
530
|
-
tab === "routes" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "stack", children: [
|
|
531
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bar", children: [
|
|
532
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
533
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { children: "\u6A21\u578B\u8DEF\u7531" }),
|
|
534
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "notice", children: [
|
|
535
|
-
data.routes.length,
|
|
536
|
-
" \u6761\u8DEF\u7531 \xB7 \u89C4\u5219\u4E0E\u8D26\u53F7\u5728\u7F16\u8F91\u4E2D\u8C03\u6574"
|
|
537
|
-
] })
|
|
538
|
-
] }),
|
|
539
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "row", children: [
|
|
540
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: busy, onClick: () => {
|
|
541
|
-
setError("");
|
|
542
|
-
setNotice("");
|
|
543
|
-
setPresetModal(true);
|
|
544
|
-
}, children: "\u6DFB\u52A0\u9884\u914D\u7F6E" }),
|
|
545
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { className: "primary", disabled: busy, onClick: () => {
|
|
546
|
-
setError("");
|
|
547
|
-
setNotice("");
|
|
548
|
-
setDraft({ id: "", name: "", revision: data.revision, contextMode: "maximum", contextWindow: 2e5, maxTokens: 32e3, strategy: "failover", preferExpiringCredits: true, expiringWithinDays: 7, visible: true, targets: [newTarget()] });
|
|
549
|
-
}, children: "\u65B0\u5EFA\u8DEF\u7531" })
|
|
550
|
-
] })
|
|
551
|
-
] }),
|
|
552
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(RoutesTable, { data, busy, act, edit: editRoute }),
|
|
553
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("details", { children: [
|
|
554
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("summary", { children: "\u5168\u5C40\u5207\u6362\u8BBE\u7F6E" }),
|
|
555
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("form", { className: "box stack", style: { marginTop: 16 }, onSubmit: (e) => {
|
|
556
|
-
e.preventDefault();
|
|
557
|
-
const f = new FormData(e.currentTarget);
|
|
558
|
-
void act({ action: "options.save", cooldownMs: Number(f.get("cooldown")) * 1e3, requestTimeoutMs: Number(f.get("timeout")) * 1e3, retryServerErrors: f.has("server") });
|
|
559
|
-
}, children: [
|
|
560
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "grid", children: [
|
|
561
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [
|
|
562
|
-
"\u5931\u8D25\u8D26\u53F7\u51B7\u5374\uFF08\u79D2\uFF09",
|
|
563
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { disabled: busy, name: "cooldown", type: "number", min: "1", required: true, defaultValue: data.options.cooldownMs / 1e3 })
|
|
564
|
-
] }),
|
|
565
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [
|
|
566
|
-
"\u8BF7\u6C42\u8D85\u65F6\uFF08\u79D2\uFF09",
|
|
567
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { disabled: busy, name: "timeout", type: "number", min: "1", required: true, defaultValue: data.options.requestTimeoutMs / 1e3 })
|
|
568
|
-
] })
|
|
569
|
-
] }),
|
|
570
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "check", children: [
|
|
571
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { disabled: busy, name: "server", type: "checkbox", defaultChecked: data.options.retryServerErrors }),
|
|
572
|
-
"5xx \u548C\u7F51\u7EDC\u9519\u8BEF\u4E5F\u5207\u6362\u8D26\u53F7"
|
|
573
|
-
] }),
|
|
574
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: busy, type: "submit", children: "\u4FDD\u5B58\u8BBE\u7F6E" }) })
|
|
575
|
-
] })
|
|
576
|
-
] })
|
|
577
|
-
] }),
|
|
578
|
-
tab === "migration" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MigrationForm, { data, act, busy })
|
|
579
|
-
] }),
|
|
580
|
-
draft && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Modal, { title: draft.previousId ? "\u7F16\u8F91\u8DEF\u7531" : "\u65B0\u5EFA\u8DEF\u7531", busy, close: () => setDraft(null), children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RouteForm, { draft, setDraft, data, act, busy, error, notice }) }),
|
|
581
|
-
presetModal && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Modal, { title: "\u6A21\u578B\u8DEF\u7531\u9884\u914D\u7F6E", busy, close: () => setPresetModal(false), children: [
|
|
582
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "modal-body stack", children: [
|
|
583
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Feedback, { error, notice }),
|
|
584
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "steps", children: "Free \u81EA\u52A8\u53D1\u73B0\u5404\u8D26\u53F7\u7684\u514D\u8D39\u6A21\u578B\uFF1B\u5176\u4ED6\u9884\u914D\u7F6E\u7ED1\u5B9A\u5DF2\u6838\u5BF9\u7684\u6E20\u9053\u6A21\u578B\u3002\u5DF2\u6709\u8DEF\u7531\u4E0D\u4F1A\u88AB\u8986\u76D6\u3002" }),
|
|
585
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "grid", children: (data.presets || []).map((preset) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "box stack", children: [
|
|
586
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { children: preset.name }) }),
|
|
587
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: preset.freeOnly ? "\u6BCF\u5929\u81EA\u52A8\u68C0\u67E5\u514D\u8D39\u6A21\u578B\uFF0C\u8C03\u7528\u524D\u590D\u6838\u96F6\u500D\u7387\uFF1B\u4EC5\u5728\u514D\u8D39\u6A21\u578B\u95F4\u5207\u6362\u3002" : `\u5DF2\u53D1\u73B0\u53EF\u7528\u6E20\u9053\uFF1A${preset.availableProviders.length} / ${preset.providerCount ?? preset.targets.length}${preset.availableProviders.length < (preset.providerCount ?? preset.targets.length) ? " \xB7 \u53EF\u6DFB\u52A0\u8D26\u53F7\u6216\u5237\u65B0\u6A21\u578B\u76EE\u5F55\u540E\u4F7F\u7528" : ""}` }),
|
|
588
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: busy || preset.added, onClick: () => {
|
|
589
|
-
void act({ action: "preset.add", id: preset.id });
|
|
590
|
-
}, children: preset.added ? "\u5DF2\u6DFB\u52A0" : "\u6DFB\u52A0\u6B64\u8DEF\u7531" })
|
|
591
|
-
] }, preset.id)) })
|
|
592
|
-
] }),
|
|
593
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "modal-foot bar", children: [
|
|
594
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u65B0\u589E\u8DEF\u7531\u53EF\u7EE7\u7EED\u7F16\u8F91\u540D\u79F0\u3001\u8D26\u53F7\u548C\u5207\u6362\u89C4\u5219\u3002" }),
|
|
595
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { className: "primary", disabled: busy || !(data.presets || []).some((p2) => !p2.added), onClick: () => {
|
|
596
|
-
void act({ action: "preset.add-all" });
|
|
597
|
-
}, children: "\u8865\u9F50\u5168\u90E8\u9884\u914D\u7F6E" })
|
|
598
|
-
] })
|
|
599
|
-
] }),
|
|
600
|
-
accountModal && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Modal, { title: accountModal.mode === "edit" ? "\u8D26\u53F7\u767B\u5F55\u8BE6\u60C5" : accountModal.mode === "credentials" ? "\u8865\u5145 / \u66F4\u65B0\u8D26\u53F7\u51ED\u8BC1" : "\u6DFB\u52A0\u8D26\u53F7\u4E0E\u83B7\u53D6\u767B\u5F55", busy, close: () => setAccountModal(null), children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AccountForm, { modal: accountModal, provider: accountProvider || "workbuddy", data, busy, act, replace: () => openAccount("credentials", accountModal.account), close: (selected) => {
|
|
601
|
-
if (typeof selected === "string" && accountProvider) setAccountProvider(selected);
|
|
602
|
-
setAccountModal(null);
|
|
603
|
-
}, error, notice }) })
|
|
604
|
-
] });
|
|
605
|
-
}
|
|
606
|
-
function ApiServicePanel({ data: a, busy, act }) {
|
|
607
|
-
const [key, setKey] = (0, import_react.useState)(""), [hint, setHint] = (0, import_react.useState)(""), [confirmKey, setConfirmKey] = (0, import_react.useState)(null), [models, setModels] = (0, import_react.useState)(false), [example, setExample] = (0, import_react.useState)("");
|
|
608
|
-
const copyField = (0, import_react.useRef)(null);
|
|
609
|
-
(0, import_react.useEffect)(() => {
|
|
610
|
-
setKey((current) => a?.keyHint && current.endsWith(a.keyHint.slice(-4)) ? current : "");
|
|
611
|
-
}, [a?.keyHint]);
|
|
612
|
-
(0, import_react.useEffect)(() => {
|
|
613
|
-
if (!key) return;
|
|
614
|
-
const timer = setTimeout(() => setKey(""), 6e4);
|
|
615
|
-
return () => clearTimeout(timer);
|
|
616
|
-
}, [key]);
|
|
617
|
-
if (!a) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "steps", children: "\u5F53\u524D\u540E\u53F0\u672A\u63D0\u4F9B API \u670D\u52A1\uFF0C\u8BF7\u66F4\u65B0\u63D2\u4EF6\u3002" });
|
|
618
|
-
const save = (fields) => act({ action: "api.settings", apiRevision: a.revision, ...fields });
|
|
619
|
-
async function keyAction(action) {
|
|
620
|
-
const result = await act({ action, apiRevision: a.revision });
|
|
621
|
-
if (result) {
|
|
622
|
-
setKey(result.apiKey || "");
|
|
623
|
-
setConfirmKey(null);
|
|
624
|
-
}
|
|
625
|
-
}
|
|
626
|
-
async function copy(value, fallback = false) {
|
|
627
|
-
try {
|
|
628
|
-
await navigator.clipboard.writeText(value);
|
|
629
|
-
setHint("\u5DF2\u590D\u5236\u3002");
|
|
630
|
-
} catch {
|
|
631
|
-
setHint("\u5F53\u524D\u73AF\u5883\u65E0\u6CD5\u81EA\u52A8\u590D\u5236\uFF0C\u8BF7\u5728\u6587\u672C\u6846\u4E2D\u5168\u9009\u590D\u5236\u3002");
|
|
632
|
-
if (fallback) copyField.current?.select();
|
|
633
|
-
else setExample(value);
|
|
634
|
-
}
|
|
635
|
-
}
|
|
636
|
-
const model = a.models[0]?.id || "\u4F60\u7684\u8DEF\u7531\u6A21\u578B ID";
|
|
637
|
-
const command = `curl '${a.baseUrl}/chat/completions' \\
|
|
638
|
-
-H 'Authorization: Bearer YOUR_API_KEY' \\
|
|
639
|
-
-H 'Content-Type: application/json' \\
|
|
640
|
-
-d '${JSON.stringify({ model, messages: [{ role: "user", content: "\u4F60\u597D" }], stream: true })}'`;
|
|
641
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "stack", children: [
|
|
642
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "box stack", children: [
|
|
643
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bar", children: [
|
|
644
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
645
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { children: "API \u670D\u52A1" }),
|
|
646
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u5C06\u8D26\u53F7\u6C60\u4E0E\u7EDF\u4E00\u8DEF\u7531\u63D0\u4F9B\u7ED9\u5176\u4ED6\u5DE5\u5177\u3002\u968F DSH \u8FD0\u884C\uFF0C\u9ED8\u8BA4\u5173\u95ED\u3002" })
|
|
647
|
-
] }),
|
|
648
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "status", role: "status", children: [
|
|
649
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("i", { className: a.phase === "running" ? "good" : a.phase === "error" ? "warn" : "", "aria-hidden": "true" }),
|
|
650
|
-
{ running: "\u8FD0\u884C\u4E2D", stopped: "\u5DF2\u5173\u95ED", starting: "\u542F\u52A8\u4E2D", error: "\u542F\u52A8\u5931\u8D25" }[a.phase] || a.phase
|
|
651
|
-
] })
|
|
652
|
-
] }),
|
|
653
|
-
a.error && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "error", role: "alert", children: a.error }),
|
|
654
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bar", children: [
|
|
655
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: a.phase === "running" ? `${a.active} \u4E2A\u5904\u7406\u4E2D\u8BF7\u6C42 \xB7 ${a.allowLan ? "\u672C\u673A\u4E0E\u7F51\u7EDC\u8BBF\u95EE" : "\u4EC5\u672C\u673A\u8BBF\u95EE"}` : "\u5F00\u542F\u540E\u5373\u53EF\u590D\u5236\u63A5\u5165\u5730\u5740\uFF1B\u5173\u95ED\u4F1A\u7EC8\u6B62\u6B63\u5728\u5904\u7406\u7684 API \u8BF7\u6C42\u3002" }),
|
|
656
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "check", children: [
|
|
657
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "checkbox", checked: a.enabled, disabled: busy || !a.hasKey, onChange: (e) => {
|
|
658
|
-
void save({ enabled: e.target.checked });
|
|
659
|
-
} }),
|
|
660
|
-
"\u542F\u7528 API \u670D\u52A1"
|
|
661
|
-
] })
|
|
662
|
-
] }),
|
|
663
|
-
!a.hasKey && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "steps", children: "\u5148\u751F\u6210 API Key\uFF0C\u518D\u542F\u7528\u670D\u52A1\u3002\u8D26\u53F7\u767B\u5F55\u51ED\u8BC1\u4E0D\u4F1A\u901A\u8FC7\u6B64\u670D\u52A1\u63D0\u4F9B\u3002" })
|
|
664
|
-
] }),
|
|
665
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "metrics", children: [
|
|
666
|
-
metric("\u4ECA\u65E5 API \u8C03\u7528", fmt(a.today.calls), `${a.today.attempts} \u6B21\u4E0A\u6E38\u5C1D\u8BD5\uFF0C\u542B\u6545\u969C\u5207\u6362`),
|
|
667
|
-
metric("\u4ECA\u65E5 API Token", fmt(a.today.tokens), "\u5E73\u53F0\u5B9E\u9645\u8FD4\u56DE\u7528\u91CF"),
|
|
668
|
-
metric("\u5DF2\u5F00\u653E\u6A21\u578B", fmt(a.models.length), a.modelIds === null ? "\u8DDF\u968F\u8DEF\u7531\u5C55\u793A\u8BBE\u7F6E" : "\u81EA\u9009\u6A21\u578B"),
|
|
669
|
-
metric("\u5904\u7406\u4E2D", fmt(a.active), "\u6700\u591A 8 \u4E2A\u5E76\u53D1 API \u8BF7\u6C42")
|
|
670
|
-
] }),
|
|
671
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "box stack", children: [
|
|
672
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bar", children: [
|
|
673
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
674
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { children: "\u63A5\u5165\u4FE1\u606F" }),
|
|
675
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u5BA2\u6237\u7AEF\u9009\u62E9 OpenAI \u517C\u5BB9\u65B9\u5F0F\uFF0C\u586B\u5199\u4E0B\u65B9 Base URL \u4E0E API Key\u3002" })
|
|
676
|
-
] }),
|
|
677
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: busy, onClick: () => setExample(command), children: "\u8C03\u7528\u793A\u4F8B" })
|
|
678
|
-
] }),
|
|
679
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [
|
|
680
|
-
"Base URL",
|
|
681
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "row", children: [
|
|
682
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { className: "mono", style: { flex: 1, minWidth: 180 }, readOnly: true, value: a.baseUrl, onFocus: (e) => e.currentTarget.select() }),
|
|
683
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { onClick: () => {
|
|
684
|
-
void copy(a.baseUrl);
|
|
685
|
-
}, children: "\u590D\u5236\u5730\u5740" })
|
|
686
|
-
] })
|
|
687
|
-
] }),
|
|
688
|
-
a.allowLan && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
689
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u5176\u4ED6\u8BBE\u5907\u53EF\u4F7F\u7528\u4EE5\u4E0B\u672C\u673A\u7F51\u5361\u5730\u5740\uFF08\u9700\u8981\u7F51\u7EDC\u53EF\u8FBE\u53CA\u9632\u706B\u5899\u653E\u884C\uFF09\uFF1A" }),
|
|
690
|
-
a.lanUrls.length ? a.lanUrls.map((url) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "mono", style: { overflowWrap: "anywhere" }, children: url }, url)) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u6682\u65E0\u53EF\u7528 IPv4 \u7F51\u5361\u5730\u5740\u3002" })
|
|
691
|
-
] }),
|
|
692
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [
|
|
693
|
-
"API Key",
|
|
694
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "row", children: [
|
|
695
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { ref: copyField, className: "mono", style: { flex: 1, minWidth: 180 }, readOnly: true, autoComplete: "off", spellCheck: "false", value: key || a.keyHint || "\u5C1A\u672A\u751F\u6210", onFocus: (e) => e.currentTarget.select() }),
|
|
696
|
-
a.hasKey && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
697
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: busy, onClick: () => {
|
|
698
|
-
if (key) setKey("");
|
|
699
|
-
else void keyAction("api.key.reveal");
|
|
700
|
-
}, children: key ? "\u9690\u85CF" : "\u663E\u793A" }),
|
|
701
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: busy, onClick: async () => {
|
|
702
|
-
const result = await act({ action: "api.key.reveal", apiRevision: a.revision });
|
|
703
|
-
if (result?.apiKey) {
|
|
704
|
-
setKey(result.apiKey);
|
|
705
|
-
await copy(result.apiKey, true);
|
|
706
|
-
}
|
|
707
|
-
}, children: "\u590D\u5236 Key" })
|
|
708
|
-
] })
|
|
709
|
-
] })
|
|
710
|
-
] }),
|
|
711
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "row", children: [
|
|
712
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: busy, onClick: () => {
|
|
713
|
-
if (a.hasKey) setConfirmKey("create");
|
|
714
|
-
else void keyAction("api.key.create");
|
|
715
|
-
}, children: a.hasKey ? "\u91CD\u7F6E API Key" : "\u751F\u6210 API Key" }),
|
|
716
|
-
a.hasKey && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: busy, onClick: () => setConfirmKey("revoke"), children: "\u64A4\u9500 Key \u5E76\u5173\u95ED\u670D\u52A1" }),
|
|
717
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "Key \u4EC5\u4FDD\u5B58\u5728\u672C\u673A\u79C1\u6709\u6587\u4EF6\uFF1B\u663E\u793A\u540E 60 \u79D2\u81EA\u52A8\u9690\u85CF\u3002" })
|
|
718
|
-
] }),
|
|
719
|
-
hint && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", role: "status", children: hint })
|
|
720
|
-
] }),
|
|
721
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "box stack", children: [
|
|
722
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { children: "\u670D\u52A1\u8BBE\u7F6E" }),
|
|
723
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("form", { className: "stack", onSubmit: (e) => {
|
|
724
|
-
e.preventDefault();
|
|
725
|
-
const f = new FormData(e.currentTarget);
|
|
726
|
-
void save({ port: Number(f.get("port")), allowLan: f.has("lan") });
|
|
727
|
-
}, children: [
|
|
728
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "row", children: [
|
|
729
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "filter", children: [
|
|
730
|
-
"\u76D1\u542C\u7AEF\u53E3",
|
|
731
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "number", name: "port", min: "1024", max: "65535", required: true, defaultValue: a.port, disabled: busy })
|
|
732
|
-
] }),
|
|
733
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "check", children: [
|
|
734
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "checkbox", name: "lan", defaultChecked: a.allowLan, disabled: busy }),
|
|
735
|
-
"\u5141\u8BB8\u5C40\u57DF\u7F51\u8BBF\u95EE"
|
|
736
|
-
] }),
|
|
737
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: busy, children: "\u4FDD\u5B58\u8BBE\u7F6E" })
|
|
738
|
-
] }),
|
|
739
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u9ED8\u8BA4\u76D1\u542C 127.0.0.1\u3002\u5F00\u542F\u7F51\u7EDC\u8BBF\u95EE\u540E\u76D1\u542C\u6240\u6709 IPv4 \u7F51\u5361\uFF0C\u4F7F\u7528 HTTP\uFF0C\u8BF7\u4EC5\u7528\u4E8E\u53EF\u4FE1\u7F51\u7EDC\uFF1B\u5982\u9700\u5916\u7F51\u8BBF\u95EE\uFF0C\u8BF7\u81EA\u884C\u914D\u7F6E HTTPS \u4E0E\u8BBF\u95EE\u9650\u5236\u3002\u4FEE\u6539\u7AEF\u53E3\u6216\u8BBF\u95EE\u8303\u56F4\u4F1A\u4E2D\u65AD\u5F53\u524D API \u8BF7\u6C42\u3002" })
|
|
740
|
-
] }, a.revision)
|
|
741
|
-
] }),
|
|
742
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "box table-shell", children: [
|
|
743
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bar table-footer", children: [
|
|
744
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
745
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { children: "\u5F00\u653E\u6A21\u578B" }),
|
|
746
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: a.modelIds === null ? "\u81EA\u52A8\u8DDF\u968F\u5DF2\u5C55\u793A\u8DEF\u7531\uFF0C\u5305\u542B\u52A8\u6001\u514D\u8D39\u6A21\u578B\u3002" : "\u4EC5\u5F00\u653E\u624B\u52A8\u9009\u62E9\u7684\u8DEF\u7531\u3002" })
|
|
747
|
-
] }),
|
|
748
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: busy, onClick: () => setModels(true), children: "\u9009\u62E9\u5F00\u653E\u6A21\u578B" })
|
|
749
|
-
] }),
|
|
750
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "scroll", role: "region", "aria-label": "API \u5F00\u653E\u6A21\u578B", tabIndex: "0", children: [
|
|
751
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("table", { className: "table", children: [
|
|
752
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tr", { children: [
|
|
753
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { children: "\u6A21\u578B\u540D\u79F0" }),
|
|
754
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { children: "\u8C03\u7528\u6A21\u578B ID" })
|
|
755
|
-
] }) }),
|
|
756
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("tbody", { children: a.models.map((m) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tr", { children: [
|
|
757
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { children: m.name }),
|
|
758
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "mono", style: { overflowWrap: "anywhere" }, children: m.id })
|
|
759
|
-
] }, m.id)) })
|
|
760
|
-
] }),
|
|
761
|
-
!a.models.length && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "empty", children: "\u6682\u672A\u5F00\u653E\u6A21\u578B\uFF0C\u8BF7\u5C55\u793A\u8DEF\u7531\u6216\u624B\u52A8\u9009\u62E9\u3002" })
|
|
762
|
-
] })
|
|
763
|
-
] }),
|
|
764
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("details", { children: [
|
|
765
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("summary", { children: "\u63A5\u53E3\u4E0E\u7EDF\u8BA1\u8BF4\u660E" }),
|
|
766
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u652F\u6301 GET /v1/models\u3001POST /v1/chat/completions\uFF08\u6D41\u5F0F\u4E0E\u666E\u901A JSON\uFF09\uFF0C\u6CBF\u7528\u8DEF\u7531\u7684\u63A8\u7406\u9ED8\u8BA4\u503C\uFF0C\u53EF\u7528 reasoning_effort \u8986\u76D6\u3002\u5DE5\u5177\u8C03\u7528\u4E0E\u56FE\u7247\u80FD\u529B\u53D6\u51B3\u4E8E\u76EE\u6807\u6A21\u578B\uFF1B\u5916\u90E8\u5DE5\u5177\u81EA\u884C\u6267\u884C\u5DE5\u5177\u5E76\u56DE\u4F20\u7ED3\u679C\u3002\u7528\u91CF\u8BB0\u5F55\u5230 Token \u660E\u7EC6\u7684\u300CAPI \u670D\u52A1\u300D\u6765\u6E90\uFF0C\u4E0D\u4FDD\u5B58\u8BF7\u6C42\u5185\u5BB9\u6216 Key\uFF1B\u4E0A\u4E0B\u6587\u7531\u8C03\u7528\u5BA2\u6237\u7AEF\u4F20\u5165\u3002\u6B64\u7248\u672C\u4E0D\u63D0\u4F9B Responses\u3001Embeddings \u6216\u8DE8\u7AD9\u6D4F\u89C8\u5668 CORS \u63A5\u53E3\u3002\u542F\u7528\u72B6\u6001\u4F1A\u4FDD\u5B58\uFF0CDSH \u4E0B\u6B21\u542F\u52A8\u81EA\u52A8\u6062\u590D\uFF1B\u9000\u51FA DSH \u540E\u505C\u6B62\u3002" })
|
|
767
|
-
] }),
|
|
768
|
-
confirmKey && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Modal, { title: confirmKey === "create" ? "\u91CD\u7F6E API Key" : "\u64A4\u9500 API Key", busy, close: () => setConfirmKey(null), children: [
|
|
769
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "modal-body stack", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: confirmKey === "create" ? "\u65E7 Key \u5C06\u7ACB\u5373\u5931\u6548\uFF0C\u5176\u4ED6\u5BA2\u6237\u7AEF\u9700\u8981\u586B\u5199\u65B0 Key\u3002" : "Key \u5C06\u7ACB\u5373\u5931\u6548\uFF0CAPI \u670D\u52A1\u4F1A\u5173\u95ED\uFF0C\u6B63\u5728\u5904\u7406\u7684 API \u8BF7\u6C42\u5C06\u4E2D\u65AD\u3002" }) }),
|
|
770
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "modal-foot row", children: [
|
|
771
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: busy, onClick: () => setConfirmKey(null), children: "\u53D6\u6D88" }),
|
|
772
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", { className: "primary", disabled: busy, onClick: () => {
|
|
773
|
-
void keyAction(`api.key.${confirmKey}`);
|
|
774
|
-
}, children: [
|
|
775
|
-
"\u786E\u8BA4",
|
|
776
|
-
confirmKey === "create" ? "\u91CD\u7F6E" : "\u64A4\u9500"
|
|
777
|
-
] })
|
|
778
|
-
] })
|
|
779
|
-
] }),
|
|
780
|
-
models && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Modal, { title: "\u9009\u62E9 API \u5F00\u653E\u6A21\u578B", busy, close: () => setModels(false), children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ApiModels, { data: a, busy, save: async (modelIds) => {
|
|
781
|
-
if (await save({ modelIds })) setModels(false);
|
|
782
|
-
} }) }),
|
|
783
|
-
example && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Modal, { title: "\u63A5\u5165\u793A\u4F8B / \u624B\u52A8\u590D\u5236", busy: false, close: () => setExample(""), children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "modal-body stack", children: [
|
|
784
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u5C06 YOUR_API_KEY \u66FF\u6362\u4E3A\u81EA\u5DF1\u7684\u670D\u52A1 Key\u3002Base URL \u5DF2\u5305\u542B /v1\uFF1B\u6D4B\u8BD5\u8C03\u7528\u4F1A\u6B63\u5E38\u6D88\u8017\u76EE\u6807\u8D26\u53F7\u7684\u7528\u91CF\u3002" }),
|
|
785
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [
|
|
786
|
-
"\u53EF\u590D\u5236\u5185\u5BB9",
|
|
787
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("textarea", { className: "mono", readOnly: true, rows: 8, value: example, onFocus: (e) => e.currentTarget.select() })
|
|
788
|
-
] })
|
|
789
|
-
] }) })
|
|
790
|
-
] });
|
|
791
|
-
}
|
|
792
|
-
function ApiModels({ data, busy, save }) {
|
|
793
|
-
const [follow, setFollow] = (0, import_react.useState)(data.modelIds === null), [selected, setSelected] = (0, import_react.useState)(data.modelIds ?? data.models.map((m) => m.id));
|
|
794
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("form", { onSubmit: (e) => {
|
|
795
|
-
e.preventDefault();
|
|
796
|
-
void save(follow ? null : selected);
|
|
797
|
-
}, children: [
|
|
798
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "modal-body stack", children: [
|
|
799
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "check", children: [
|
|
800
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "checkbox", checked: follow, disabled: busy, onChange: (e) => setFollow(e.target.checked) }),
|
|
801
|
-
"\u8DDF\u968F\u8DEF\u7531\u5C55\u793A\uFF08\u65B0\u53D1\u73B0\u7684\u514D\u8D39\u6A21\u578B\u4E5F\u81EA\u52A8\u5F00\u653E\uFF09"
|
|
802
|
-
] }),
|
|
803
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "row", children: [
|
|
804
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", disabled: busy || follow, onClick: () => setSelected(data.choices.map((m) => m.id)), children: "\u5168\u9009" }),
|
|
805
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", disabled: busy || follow, onClick: () => setSelected([]), children: "\u5168\u4E0D\u9009" })
|
|
806
|
-
] }),
|
|
807
|
-
data.choices.map((m) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "check", children: [
|
|
808
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "checkbox", disabled: busy || follow, checked: follow ? m.visible : selected.includes(m.id), onChange: (e) => setSelected(e.target.checked ? [...selected, m.id] : selected.filter((id) => id !== m.id)) }),
|
|
809
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: [
|
|
810
|
-
m.name,
|
|
811
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("small", { className: "mono muted", style: { overflowWrap: "anywhere" }, children: m.id })
|
|
812
|
-
] })
|
|
813
|
-
] }, m.id)),
|
|
814
|
-
!data.choices.length && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u8BF7\u5148\u6DFB\u52A0\u8DEF\u7531\u3002" })
|
|
815
|
-
] }),
|
|
816
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "modal-foot row", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { className: "primary", disabled: busy, children: "\u4FDD\u5B58\u5F00\u653E\u8303\u56F4" }) })
|
|
817
|
-
] });
|
|
818
|
-
}
|
|
819
|
-
function ModelsPanel({ error = "", notice = "", data, provider, providerSelect, search, setSearch, busy, act }) {
|
|
820
|
-
const [editing, setEditing] = (0, import_react.useState)(null), [testing, setTesting] = (0, import_react.useState)(null), [testResult, setTestResult] = (0, import_react.useState)(null);
|
|
821
|
-
const models = data.providers.find((p) => p.id === provider)?.models ?? [];
|
|
822
|
-
const all = data.providers.flatMap((p) => p.models), shown = models.filter((m) => `${m.id} ${m.name}`.toLowerCase().includes(search.toLowerCase()));
|
|
823
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "stack", children: [
|
|
824
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bar", children: [
|
|
825
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
826
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { children: "\u539F\u59CB\u6A21\u578B\u5C55\u793A" }),
|
|
827
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "notice", children: [
|
|
828
|
-
"\u5DF2\u5C55\u793A ",
|
|
829
|
-
all.filter((m) => m.visible).length,
|
|
830
|
-
" / ",
|
|
831
|
-
all.length,
|
|
832
|
-
" \u4E2A \xB7 \u9ED8\u8BA4\u4EC5\u5C55\u793A\u7EDF\u4E00\u8DEF\u7531"
|
|
833
|
-
] })
|
|
834
|
-
] }),
|
|
835
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "row", children: [
|
|
836
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: busy, onClick: () => {
|
|
837
|
-
void act({ action: "models.visibility", visible: true });
|
|
838
|
-
}, children: "\u5168\u90E8\u5C55\u793A" }),
|
|
839
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: busy, onClick: () => {
|
|
840
|
-
void act({ action: "models.visibility", visible: false });
|
|
841
|
-
}, children: "\u5168\u90E8\u9690\u85CF\uFF08\u4EC5\u8DEF\u7531\uFF09" })
|
|
842
|
-
] })
|
|
843
|
-
] }),
|
|
844
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bar toolbar", children: [
|
|
845
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "row", children: [
|
|
846
|
-
providerSelect,
|
|
847
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "search", children: [
|
|
848
|
-
"\u641C\u7D22\u6A21\u578B",
|
|
849
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "search", placeholder: "\u540D\u79F0\u6216\u6A21\u578B ID", value: search, onChange: (e) => setSearch(e.target.value) })
|
|
850
|
-
] })
|
|
851
|
-
] }),
|
|
852
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: busy, onClick: () => {
|
|
853
|
-
void act({ action: "refresh", provider });
|
|
854
|
-
}, children: "\u83B7\u53D6\u6A21\u578B\u76EE\u5F55" })
|
|
855
|
-
] }),
|
|
856
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "box table-shell", children: [
|
|
857
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "scroll", role: "region", "aria-label": "\u6A21\u578B\u5C55\u793A\u7BA1\u7406", tabIndex: "0", children: [
|
|
858
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("table", { className: "table model-table", children: [
|
|
859
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tr", { children: [
|
|
860
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { scope: "col", children: "\u6A21\u578B" }),
|
|
861
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { scope: "col", children: "\u4E0A\u4E0B\u6587 / \u63A8\u7406" }),
|
|
862
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { scope: "col", children: "\u9009\u62E9\u5668\u5C55\u793A" }),
|
|
863
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { scope: "col", className: "cell-actions", children: "\u7BA1\u7406" })
|
|
864
|
-
] }) }),
|
|
865
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("tbody", { children: shown.map((m) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tr", { className: m.visible ? "selected" : "", children: [
|
|
866
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("td", { children: [
|
|
867
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: m.name }),
|
|
868
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("small", { className: "mono muted", children: m.id })
|
|
869
|
-
] }),
|
|
870
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("td", { children: [
|
|
871
|
-
capacity(m.contextWindow),
|
|
872
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("small", { className: "muted", children: [
|
|
873
|
-
"\u6700\u5927 ",
|
|
874
|
-
capacity(m.maxContextWindow ?? m.contextWindow),
|
|
875
|
-
" \xB7 \u8F93\u51FA ",
|
|
876
|
-
capacity(m.maxTokens),
|
|
877
|
-
m.supportsImages ? " \xB7 \u56FE\u7247" : ""
|
|
878
|
-
] }),
|
|
879
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("small", { className: "muted", children: m.reasoning?.supportedEfforts?.length ? m.reasoning.supportedEfforts.map((e) => effortNames[e] || e).join(" / ") : "\u5E73\u53F0\u9ED8\u8BA4" })
|
|
880
|
-
] }),
|
|
881
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "check", children: [
|
|
882
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "checkbox", "aria-label": `\u5C55\u793A ${m.name}`, disabled: busy, checked: m.visible, onChange: (e) => {
|
|
883
|
-
void act({ action: "model.update", provider, id: m.id, visible: e.target.checked });
|
|
884
|
-
} }),
|
|
885
|
-
m.visible ? "\u5DF2\u5C55\u793A" : "\u5DF2\u9690\u85CF"
|
|
886
|
-
] }) }),
|
|
887
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("td", { className: "cell-actions", children: [
|
|
888
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: busy, onClick: () => setEditing({ id: m.id, name: m.name, provider, contextWindow: m.configuredContextWindow ?? null, supportsImages: m.supportsImages, reasoningEffort: m.configuredEffort ?? null }), children: "\u8BBE\u7F6E" }),
|
|
889
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: busy, onClick: () => {
|
|
890
|
-
setTesting(m);
|
|
891
|
-
setTestResult(null);
|
|
892
|
-
}, children: "\u6D4B\u8BD5" })
|
|
893
|
-
] })
|
|
894
|
-
] }, m.id)) })
|
|
895
|
-
] }),
|
|
896
|
-
!shown.length && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "empty", children: models.length ? "\u6CA1\u6709\u5339\u914D\u7684\u6A21\u578B\u3002" : "\u6DFB\u52A0\u5E76\u542F\u7528\u8D26\u53F7\u540E\uFF0C\u83B7\u53D6\u6A21\u578B\u76EE\u5F55\u3002" })
|
|
897
|
-
] }),
|
|
898
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "table-footer", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u4E0A\u4E0B\u6587\u9ED8\u8BA4\u6700\u5927\uFF0C\u53EF\u5728\u8BBE\u7F6E\u4E2D\u8C03\u4F4E\uFF1B\u539F\u59CB\u6A21\u578B\u4E0E\u8DEF\u7531\u9884\u7B97\u72EC\u7ACB\u3002\u9690\u85CF\u4E0D\u5F71\u54CD\u8DEF\u7531\u6216\u5DF2\u6709\u4F1A\u8BDD\u3002" }) })
|
|
899
|
-
] }),
|
|
900
|
-
editing && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Modal, { title: "\u6A21\u578B\u8BBE\u7F6E", busy, close: () => setEditing(null), children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ModelSettings, { error, notice, model: models.find((m) => m.id === editing.id), draft: editing, setDraft: setEditing, busy, save: async () => {
|
|
901
|
-
if (await act({ action: "model.update", ...editing })) setEditing(null);
|
|
902
|
-
} }) }),
|
|
903
|
-
testing && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Modal, { title: `\u6D4B\u8BD5 ${testing.name}`, busy, close: () => {
|
|
904
|
-
setTesting(null);
|
|
905
|
-
setTestResult(null);
|
|
906
|
-
}, children: [
|
|
907
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "modal-body stack", children: [
|
|
908
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Feedback, { error, notice }),
|
|
909
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "steps", children: "\u53D1\u9001\u4E00\u6761\u7B80\u77ED\u8BF7\u6C42\uFF0C\u6B63\u5E38\u6D88\u8017\u76EE\u6807\u8D26\u53F7\u7684\u7528\u91CF\u3002\u6B64\u6D4B\u8BD5\u4EC5\u68C0\u67E5\u8FDE\u901A\u6027\uFF0C\u4E0D\u4EE3\u8868\u5DF2\u9A8C\u8BC1\u6EE1\u4E0A\u4E0B\u6587\u6216\u56FE\u7247\u8BC6\u522B\u80FD\u529B\u3002" }),
|
|
910
|
-
testResult && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { role: "status", className: testResult.ok ? "good" : "warn", children: testResult.ok ? `\u53EF\u7528 \xB7 ${testResult.elapsedMs} ms` : `\u6D4B\u8BD5\u5931\u8D25\uFF08HTTP ${testResult.status}\uFF09\xB7 ${testResult.hint}` })
|
|
911
|
-
] }),
|
|
912
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "modal-foot row", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: busy, onClick: async () => {
|
|
913
|
-
setTestResult(null);
|
|
914
|
-
const result = await act({ action: "model.test", provider, id: testing.id });
|
|
915
|
-
if (result) setTestResult(result.modelTest);
|
|
916
|
-
}, children: busy ? "\u6B63\u5728\u6D4B\u8BD5\u2026" : "\u5F00\u59CB\u6D4B\u8BD5" }) })
|
|
917
|
-
] })
|
|
918
|
-
] });
|
|
919
|
-
}
|
|
920
|
-
var capacity = (n) => n >= 1e6 && n % 1e6 === 0 ? `${n / 1e6}M` : `${fmt(n / 1e3)}K`;
|
|
921
|
-
function ContextSelect({ model, value, onChange, disabled, label = "\u4E0A\u4E0B\u6587\u9884\u7B97" }) {
|
|
922
|
-
const max = model.maxContextWindow ?? model.contextWindow;
|
|
923
|
-
const choices = [...new Set([model.defaultContextWindow, ...model.supportedContextWindows ?? [], 2e5, 3e5, 5e5, 6e5, value].filter((n) => Number.isSafeInteger(n) && n > 0 && n <= max))].sort((a, b) => a - b);
|
|
924
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [
|
|
925
|
-
label,
|
|
926
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", { "aria-label": label, disabled, value: value ?? "", onChange: (e) => onChange(e.target.value ? Number(e.target.value) : null), children: [
|
|
927
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("option", { value: "", children: [
|
|
928
|
-
"\u6700\u5927\u5BB9\u91CF \xB7 ",
|
|
929
|
-
capacity(max),
|
|
930
|
-
"\uFF08\u9ED8\u8BA4\uFF09"
|
|
931
|
-
] }),
|
|
932
|
-
choices.map((n) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("option", { value: n, children: [
|
|
933
|
-
capacity(n),
|
|
934
|
-
n === model.defaultContextWindow ? " \xB7 \u6E20\u9053\u9ED8\u8BA4" : " \xB7 \u672C\u5730\u9884\u7B97"
|
|
935
|
-
] }, n))
|
|
936
|
-
] })
|
|
937
|
-
] });
|
|
938
|
-
}
|
|
939
|
-
function ModelSettings({ error = "", notice = "", model, draft, setDraft, busy, save }) {
|
|
940
|
-
const set = (key, value) => setDraft((d) => ({ ...d, [key]: value }));
|
|
941
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("form", { onSubmit: (e) => {
|
|
942
|
-
e.preventDefault();
|
|
943
|
-
void save();
|
|
944
|
-
}, children: [
|
|
945
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "modal-body stack", children: [
|
|
946
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Feedback, { error, notice }),
|
|
947
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [
|
|
948
|
-
"\u6A21\u578B\u540D\u79F0",
|
|
949
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { autoFocus: true, required: true, maxLength: 200, disabled: busy, value: draft.name, onChange: (e) => set("name", e.target.value) })
|
|
950
|
-
] }),
|
|
951
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "mono muted", children: model.id }),
|
|
952
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ContextSelect, { model, value: draft.contextWindow, disabled: busy, onChange: (n) => set("contextWindow", n) }),
|
|
953
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "notice", children: [
|
|
954
|
-
"\u6700\u5927\u4E0A\u4E0B\u6587 ",
|
|
955
|
-
capacity(model.maxContextWindow),
|
|
956
|
-
" \xB7 \u6700\u5927\u8F93\u51FA ",
|
|
957
|
-
capacity(model.maxTokens),
|
|
958
|
-
"\u3002\u624B\u52A8\u9884\u7B97\u53EA\u8C03\u4F4E DSH \u7684\u4F1A\u8BDD\u538B\u7F29\u9608\u503C\uFF1B\u8BF7\u6C42\u4F7F\u7528\u80FD\u591F\u5BB9\u7EB3\u8BE5\u9884\u7B97\u7684\u6E20\u9053\u6863\u4F4D\u3002"
|
|
959
|
-
] }),
|
|
960
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "check", children: [
|
|
961
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "checkbox", disabled: busy || !model.imageCapable, checked: draft.supportsImages, onChange: (e) => set("supportsImages", e.target.checked) }),
|
|
962
|
-
"\u56FE\u7247\u8F93\u5165",
|
|
963
|
-
!model.imageCapable && "\uFF08\u6E20\u9053\u672A\u58F0\u660E\u652F\u6301\uFF09"
|
|
964
|
-
] }),
|
|
965
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [
|
|
966
|
-
"\u9ED8\u8BA4\u63A8\u7406\u7B49\u7EA7",
|
|
967
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", { disabled: busy, value: draft.reasoningEffort ?? "", onChange: (e) => set("reasoningEffort", e.target.value || null), children: [
|
|
968
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "", children: "\u5E73\u53F0\u9ED8\u8BA4" }),
|
|
969
|
-
model.reasoning?.supportedEfforts?.map((e) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: e, children: effortNames[e] || e }, e))
|
|
970
|
-
] })
|
|
971
|
-
] }),
|
|
972
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u5173\u95ED\u601D\u8003\u4EC5\u5728\u6E20\u9053\u58F0\u660E\u652F\u6301\u65F6\u63D0\u4F9B\u3002\u4F1A\u8BDD\u4E2D\u7684\u624B\u52A8\u9009\u62E9\u4F18\u5148\u4E8E\u6B64\u9ED8\u8BA4\u503C\u3002" })
|
|
973
|
-
] }),
|
|
974
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "modal-foot row", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { className: "primary", disabled: busy, children: "\u4FDD\u5B58\u5E76\u751F\u6548" }) })
|
|
975
|
-
] });
|
|
976
|
-
}
|
|
977
|
-
function RoutesTable({ data, busy, act, edit }) {
|
|
978
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("section", { className: "box table-shell", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "scroll", role: "region", "aria-label": "\u6A21\u578B\u8DEF\u7531\u89C4\u5219", tabIndex: "0", children: [
|
|
979
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("table", { className: "table route-table", children: [
|
|
980
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tr", { children: [
|
|
981
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { scope: "col", children: "\u8DEF\u7531 / \u6A21\u578B" }),
|
|
982
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { scope: "col", children: "\u8D26\u53F7\u4E0E\u6E20\u9053" }),
|
|
983
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { scope: "col", children: "\u5207\u6362\u89C4\u5219" }),
|
|
984
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { scope: "col", children: "\u5C55\u793A" }),
|
|
985
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { scope: "col", className: "cell-actions", children: "\u7BA1\u7406" })
|
|
986
|
-
] }) }),
|
|
987
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("tbody", { children: data.routes.map((r) => {
|
|
988
|
-
const accounts = data.accounts.filter((a) => a.enabled !== false && (!r.eligibleAccountIds || r.eligibleAccountIds.includes(a.id)) && r.targets.some((t) => t.provider === a.provider && (!t.account || t.account === a.id)));
|
|
989
|
-
const providers = [...new Set(r.targets.map((t) => data.providers.find((p) => p.id === t.provider)?.name || t.provider))];
|
|
990
|
-
const cooling = r.expiringStatus?.cooldownUntil > Date.now(), modes = r.reasoning?.supportedEfforts ?? [];
|
|
991
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tr", { className: r.visible !== false ? "selected" : "", children: [
|
|
992
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("td", { children: [
|
|
993
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: r.name }),
|
|
994
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("small", { className: "muted", children: r.contextKnown === false ? "\u7B49\u5F85\u6A21\u578B\u76EE\u5F55" : `${capacity(r.contextWindow)} \u4E0A\u4E0B\u6587 \xB7 ${r.contextMode === "custom" ? "\u81EA\u5B9A\u4E49\u9884\u7B97" : "\u9ED8\u8BA4\u6700\u5927"}` }),
|
|
995
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("small", { className: "muted", children: r.freeOnly ? `${r.freeStatus?.modelRoutes?.filter((m) => m.selected).length || 0} \u4E2A\u514D\u8D39\u6A21\u578B\u5DF2\u5C55\u793A` : modes.length ? `\u63A8\u7406\uFF1A${modes.map((e) => effortNames[e] || e).join(" / ")}` : "\u63A8\u7406\uFF1A\u5E73\u53F0\u9ED8\u8BA4" })
|
|
996
|
-
] }),
|
|
997
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("td", { className: "route-targets", children: [
|
|
998
|
-
accounts.length,
|
|
999
|
-
" \u4E2A\u53C2\u4E0E\u8D26\u53F7",
|
|
1000
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("small", { className: "muted", children: providers.join("\u3001") })
|
|
1001
|
-
] }),
|
|
1002
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("td", { children: [
|
|
1003
|
-
r.freeOnly ? "\u4EC5\u514D\u8D39 \xB7 \u81EA\u52A8\u53D1\u73B0" : strategies[r.strategy || "failover"],
|
|
1004
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("small", { className: cooling ? "warn" : "muted", children: cooling ? "\u4E34\u671F\u4F18\u5148\u51B7\u5374\u4E2D" : r.preferExpiringCredits ? "\u4E34\u671F\u79EF\u5206\u4F18\u5148" : `${r.targets.length} \u4E2A\u76EE\u6807 \xB7 4xx \u5207\u6362` })
|
|
1005
|
-
] }),
|
|
1006
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "check", children: [
|
|
1007
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "checkbox", "aria-label": `\u5C55\u793A\u8DEF\u7531 ${r.name}`, disabled: busy, checked: r.visible !== false, onChange: (e) => {
|
|
1008
|
-
const { id, reasoning, supportsImages, expiringStatus, freeStatus, creditRates, maxContextWindow, supportedContextWindows, configuredContextWindow, contextKnown, eligibleAccountIds, enforceContext, ...route } = r;
|
|
1009
|
-
void act({ action: "route.save", id, previousId: id, route: { ...route, visible: e.target.checked } });
|
|
1010
|
-
} }),
|
|
1011
|
-
r.visible !== false ? "\u5F00\u542F" : "\u5173\u95ED"
|
|
1012
|
-
] }) }),
|
|
1013
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "cell-actions", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: busy, onClick: () => edit(r), children: r.freeOnly ? "\u7BA1\u7406\u514D\u8D39\u6A21\u578B" : "\u7F16\u8F91\u8DEF\u7531" }) })
|
|
1014
|
-
] }, r.id);
|
|
1015
|
-
}) })
|
|
1016
|
-
] }),
|
|
1017
|
-
!data.routes.length && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "empty", children: "\u6DFB\u52A0\u6A21\u578B\u9884\u914D\u7F6E\uFF0C\u6216\u521B\u5EFA\u81EA\u5B9A\u4E49\u8DEF\u7531\u3002" })
|
|
1018
|
-
] }) });
|
|
1019
|
-
}
|
|
1020
|
-
var displayName = (a) => (a?.name || a?.id || "\u672A\u77E5\u8D26\u53F7").replace(/(?<!\d)(\+?\d{2,3})\d{3,8}(\d{4})(?!\d)/g, "$1****$2");
|
|
1021
|
-
var resultLabels = { claimed: "\u7B7E\u5230\u6210\u529F", "already-claimed": "\u5DF2\u9886\u53D6", "no-campaign": "\u65E0\u6D3B\u52A8", retryable: "\u67E5\u8BE2\u5931\u8D25", "before-window": "\u7A97\u53E3\u672A\u5F00", "auth-invalid": "\u4EE4\u724C\u5931\u6548", paused: "\u5E73\u53F0\u6682\u505C", uncertain: "\u5F85\u6838\u5BF9", "device-used": "\u8BBE\u5907\u5DF2\u53C2\u4E0E" };
|
|
1022
|
-
function Balance({ account }) {
|
|
1023
|
-
const b = account.usage?.balance, now = Date.now();
|
|
1024
|
-
const expiring = b?.unit === "credits" && !b.error ? (b.packages || []).filter((p) => Number.isFinite(p.remaining) && p.remaining > 0 && p.expiresAt > now && p.expiresAt <= now + 3 * 864e5).reduce((n, p) => n + p.remaining, 0) : 0;
|
|
1025
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
1026
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "amount", children: [
|
|
1027
|
-
b?.unlimited ? "\u4E0D\u9650\u91CF" : fmt(b?.remaining),
|
|
1028
|
-
b?.unit === "credits" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("small", { className: "muted", style: { display: "inline", marginLeft: 5 }, children: "\u79EF\u5206" })
|
|
1029
|
-
] }),
|
|
1030
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("small", { className: b?.error ? "error" : expiring ? "warn" : "muted", children: b?.error ? "\u67E5\u8BE2\u5931\u8D25 \xB7 \u4FDD\u7559\u4E0A\u6B21\u4F59\u989D" : expiring ? `${fmt(expiring)} \u79EF\u5206 3 \u5929\u5185\u5230\u671F` : b?.fetchedAt ? `\u66F4\u65B0\u4E8E ${when(b.fetchedAt)}` : "\u7B49\u5F85\u5237\u65B0\u5E73\u53F0\u7528\u91CF" })
|
|
1031
|
-
] });
|
|
1032
|
-
}
|
|
1033
|
-
function CheckinResult({ row, compact = false }) {
|
|
1034
|
-
const last = row?.last, today = (/* @__PURE__ */ new Date()).toLocaleDateString("en-CA", { timeZone: "Asia/Shanghai" });
|
|
1035
|
-
const current = last?.day === today;
|
|
1036
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
1037
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: current && ["claimed", "already-claimed"].includes(last.status) ? "good" : last && ["auth-invalid", "paused", "uncertain", "retryable"].includes(last.status) ? "warn" : "muted", children: !row?.supported ? "\u6682\u4E0D\u652F\u6301" : current || last?.status === "auth-invalid" ? resultLabels[last.status] || "\u5DF2\u5904\u7406" : "\u4ECA\u65E5\u672A\u7B7E\u5230" }),
|
|
1038
|
-
(!compact || current && last.amount !== void 0) && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("small", { className: "muted", children: current && last.amount !== void 0 ? `\u672C\u6B21 ${fmt(last.amount)} \u79EF\u5206` : row?.auto ? "\u81EA\u52A8\u7B7E\u5230\u5DF2\u5F00\u542F" : "\u81EA\u52A8\u7B7E\u5230\u672A\u5F00\u542F" })
|
|
1039
|
-
] });
|
|
1040
|
-
}
|
|
1041
|
-
function AccountPool({ data, provider, providerSelect, busy, act, manage, add }) {
|
|
1042
|
-
const [search, setSearch] = (0, import_react.useState)("");
|
|
1043
|
-
const accounts = data.accounts.filter((a) => !provider || a.provider === provider), chosen = accounts.filter((a) => a.enabled !== false).length;
|
|
1044
|
-
const visible = accounts.filter((a) => `${a.name} ${a.id}`.toLowerCase().includes(search.toLowerCase()));
|
|
1045
|
-
const rows = data.checkins?.accounts || [], eligible = rows.filter((r) => accounts.some((a) => a.id === r.id && a.enabled !== false) && r.ready);
|
|
1046
|
-
const setAll = (enabled) => {
|
|
1047
|
-
void act({ action: "accounts.enabled", ...provider ? { provider } : {}, enabled });
|
|
1048
|
-
};
|
|
1049
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "stack", children: [
|
|
1050
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bar", children: [
|
|
1051
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
1052
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { className: "section-title", children: "\u8D26\u53F7\u6C60" }),
|
|
1053
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "muted", children: [
|
|
1054
|
-
accounts.length,
|
|
1055
|
-
" \u4E2A\u8D26\u53F7 \xB7 ",
|
|
1056
|
-
chosen,
|
|
1057
|
-
" \u4E2A\u53C2\u4E0E\u8DEF\u7531"
|
|
1058
|
-
] })
|
|
1059
|
-
] }),
|
|
1060
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { className: "primary", disabled: busy, onClick: add, children: "\u6DFB\u52A0\u8D26\u53F7" })
|
|
1061
|
-
] }),
|
|
1062
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bar toolbar", children: [
|
|
1063
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "row", children: [
|
|
1064
|
-
providerSelect,
|
|
1065
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "search", children: [
|
|
1066
|
-
"\u641C\u7D22\u8D26\u53F7",
|
|
1067
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "search", value: search, placeholder: "\u540D\u79F0\u6216\u8D26\u53F7 ID", onChange: (e) => setSearch(e.target.value) })
|
|
1068
|
-
] })
|
|
1069
|
-
] }),
|
|
1070
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "row", children: [
|
|
1071
|
-
!provider?.startsWith("qoder") && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: busy, onClick: () => {
|
|
1072
|
-
void act({ action: "accounts.discover", ...provider ? { provider } : {} });
|
|
1073
|
-
}, children: "\u83B7\u53D6\u672C\u673A\u767B\u5F55" }),
|
|
1074
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: busy, onClick: () => {
|
|
1075
|
-
void act({ action: "monitor.refresh", ...provider ? { provider } : {} });
|
|
1076
|
-
}, children: "\u5237\u65B0\u72B6\u6001\u4E0E\u7528\u91CF" })
|
|
1077
|
-
] })
|
|
1078
|
-
] }),
|
|
1079
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bar", children: [
|
|
1080
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "hint", children: "\u52FE\u9009\u7684\u8D26\u53F7\u53C2\u4E0E\u8DEF\u7531\uFF1B\u81EA\u52A8\u7B7E\u5230\u5728\u300C\u79EF\u5206\u7B7E\u5230\u300D\u4E2D\u5355\u72EC\u8BBE\u7F6E\u3002" }),
|
|
1081
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "row", children: [
|
|
1082
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "notice", children: [
|
|
1083
|
-
"\u5DF2\u9009 ",
|
|
1084
|
-
chosen,
|
|
1085
|
-
" / ",
|
|
1086
|
-
accounts.length
|
|
1087
|
-
] }),
|
|
1088
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: busy || !accounts.length || chosen === accounts.length, onClick: () => setAll(true), children: "\u5168\u9009" }),
|
|
1089
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: busy || !chosen, onClick: () => setAll(false), children: "\u5168\u4E0D\u9009" }),
|
|
1090
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", { disabled: busy || data.checkins?.running || data.checkins?.error || !eligible.length, onClick: () => {
|
|
1091
|
-
void act({ action: "checkins.run", ids: eligible.map((r) => r.id) });
|
|
1092
|
-
}, children: [
|
|
1093
|
-
"\u7B7E\u5230\u53EF\u7528\u8D26\u53F7\uFF08",
|
|
1094
|
-
eligible.length,
|
|
1095
|
-
"\uFF09"
|
|
1096
|
-
] })
|
|
1097
|
-
] })
|
|
1098
|
-
] }),
|
|
1099
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("section", { className: "box table-shell", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "scroll", role: "region", "aria-label": "\u8D26\u53F7\u6C60\u5217\u8868", tabIndex: "0", children: [
|
|
1100
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("table", { className: "table", children: [
|
|
1101
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tr", { children: [
|
|
1102
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { scope: "col", children: "\u8D26\u53F7 / \u8DEF\u7531\u53C2\u4E0E" }),
|
|
1103
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { scope: "col", children: "\u5E73\u53F0\u79EF\u5206" }),
|
|
1104
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { scope: "col", children: "\u6A21\u578B\u4E0E\u8C03\u7528" }),
|
|
1105
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { scope: "col", children: "\u4ECA\u65E5\u7B7E\u5230" }),
|
|
1106
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { scope: "col", className: "cell-actions", children: "\u7BA1\u7406" })
|
|
1107
|
-
] }) }),
|
|
1108
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("tbody", { children: visible.map((a) => {
|
|
1109
|
-
const cooldown = a.status?.cooldowns || [], active = a.status?.activeFor?.length, enabled = a.enabled !== false;
|
|
1110
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tr", { className: enabled ? "selected" : "", children: [
|
|
1111
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "account-cell", children: [
|
|
1112
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { className: "check account-check", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { "aria-label": `${displayName(a)} \u53C2\u4E0E\u8DEF\u7531`, type: "checkbox", disabled: busy, checked: enabled, onChange: (e) => {
|
|
1113
|
-
void act({ action: "account.update", id: a.id, enabled: e.target.checked });
|
|
1114
|
-
} }) }),
|
|
1115
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "account-name", children: [
|
|
1116
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: displayName(a) }),
|
|
1117
|
-
!provider && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("small", { className: "muted", children: data.providers?.find((p) => p.id === a.provider)?.name || a.provider }),
|
|
1118
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("small", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "status", children: [
|
|
1119
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("i", { className: !enabled ? "" : cooldown.length ? "warn" : "good", "aria-hidden": "true" }),
|
|
1120
|
-
!enabled ? "\u672A\u5165\u6C60" : active ? "\u6B63\u5728\u8C03\u7528" : cooldown.length ? "\u90E8\u5206\u8DEF\u7531\u51B7\u5374\u4E2D" : "\u5DF2\u5728\u6C60\u4E2D"
|
|
1121
|
-
] }) }),
|
|
1122
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("small", { className: "muted", children: loginNames[a.login?.state] || "\u5C1A\u672A\u67E5\u8BE2\u767B\u5F55" })
|
|
1123
|
-
] })
|
|
1124
|
-
] }) }),
|
|
1125
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Balance, { account: a }) }),
|
|
1126
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("td", { children: [
|
|
1127
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: [
|
|
1128
|
-
fmt(a.modelCount || 0),
|
|
1129
|
-
" \u4E2A\u76EE\u5F55\u6A21\u578B"
|
|
1130
|
-
] }),
|
|
1131
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("small", { className: "muted", children: [
|
|
1132
|
-
fmt(a.usage?.requests || 0),
|
|
1133
|
-
" \u6B21\u8C03\u7528 \xB7 ",
|
|
1134
|
-
fmt(a.usage?.tokens || 0),
|
|
1135
|
-
" Token"
|
|
1136
|
-
] }),
|
|
1137
|
-
cooldown.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("small", { className: "warn", children: [
|
|
1138
|
-
"\u6700\u957F\u7EA6 ",
|
|
1139
|
-
Math.ceil(Math.max(...cooldown.map((c) => c.remainingMs)) / 6e4),
|
|
1140
|
-
" \u5206\u949F\u540E\u6062\u590D"
|
|
1141
|
-
] })
|
|
1142
|
-
] }),
|
|
1143
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CheckinResult, { row: rows.find((r) => r.id === a.id) }) }),
|
|
1144
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "cell-actions", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: busy, onClick: () => manage(a), children: "\u7BA1\u7406\u8D26\u53F7" }) })
|
|
1145
|
-
] }, a.id);
|
|
1146
|
-
}) })
|
|
1147
|
-
] }),
|
|
1148
|
-
!visible.length && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "empty", children: accounts.length ? "\u6CA1\u6709\u5339\u914D\u7684\u8D26\u53F7\uFF0C\u8BF7\u8C03\u6574\u641C\u7D22\u3002" : "\u8FD8\u6CA1\u6709\u8D26\u53F7\uFF0C\u70B9\u51FB\u300C\u6DFB\u52A0\u8D26\u53F7\u300D\u83B7\u53D6\u767B\u5F55\u6216\u586B\u5199\u51ED\u8BC1\u3002" })
|
|
1149
|
-
] }) }),
|
|
1150
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("details", { className: "help", children: [
|
|
1151
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("summary", { children: "\u672C\u673A\u8D26\u53F7\u83B7\u53D6\u4E0E\u51ED\u8BC1\u8BF4\u660E" }),
|
|
1152
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "stack", children: [
|
|
1153
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "WorkBuddy \u4E0E Trae \u542F\u52A8\u65F6\u81EA\u52A8\u8BFB\u53D6\u672C\u673A\u5DF2\u767B\u5F55\u8D26\u53F7\uFF0C\u6BCF\u5206\u949F\u91CD\u65B0\u68C0\u6D4B\uFF1BTrae \u81EA\u52A8\u8BC6\u522B CN\u3001Global \u4E0E SOLO\u3002\u4E5F\u53EF\u6DFB\u52A0\u624B\u52A8\u51ED\u8BC1\u6216\u5BFC\u5165\u5176\u5B83\u8BBE\u5907\u8D26\u53F7\uFF0C\u5404\u8D26\u53F7\u72EC\u7ACB\u4FDD\u5B58\u3002Qoder \u9700\u6DFB\u52A0 PAT\u3002" }),
|
|
1154
|
-
data.localDiscovery?.filter((s) => !provider || s.provider === provider).map((s) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "notice", children: [
|
|
1155
|
-
data.providers?.find((p) => p.id === s.provider)?.name || s.provider,
|
|
1156
|
-
" \xB7 ",
|
|
1157
|
-
s.state === "found" ? "\u5DF2\u53D1\u73B0\u672C\u673A\u5BA2\u6237\u7AEF\u767B\u5F55\u3002" : s.state === "unreadable" ? "\u65E0\u6CD5\u8BFB\u53D6\u672C\u673A\u767B\u5F55\u6587\u4EF6\uFF0C\u8BF7\u5728\u5B98\u65B9\u5BA2\u6237\u7AEF\u91CD\u65B0\u767B\u5F55\uFF0C\u6216\u624B\u52A8\u586B\u5199\u51ED\u8BC1\u3002" : "\u672A\u627E\u5230\u672C\u673A\u767B\u5F55\uFF0C\u8BF7\u5148\u767B\u5F55\u5BF9\u5E94\u533A\u57DF\u7684\u5B98\u65B9\u5BA2\u6237\u7AEF\u3002",
|
|
1158
|
-
" \xB7 ",
|
|
1159
|
-
when(s.checkedAt)
|
|
1160
|
-
] }, s.provider))
|
|
1161
|
-
] })
|
|
1162
|
-
] })
|
|
1163
|
-
] });
|
|
1164
|
-
}
|
|
1165
|
-
function CheckinPanel({ data, busy, act }) {
|
|
1166
|
-
const info = data.checkins || {}, rows = info.accounts || [], today = (/* @__PURE__ */ new Date()).toLocaleDateString("en-CA", { timeZone: "Asia/Shanghai" });
|
|
1167
|
-
const saved = info.settings ?? { mode: "scheduled", time: "10:05" };
|
|
1168
|
-
const [schedule, setSchedule] = (0, import_react.useState)(saved);
|
|
1169
|
-
(0, import_react.useEffect)(() => {
|
|
1170
|
-
setSchedule(saved);
|
|
1171
|
-
}, [saved.mode, saved.time]);
|
|
1172
|
-
const changed = schedule.mode !== saved.mode || schedule.time !== saved.time;
|
|
1173
|
-
const blocked = busy || info.running || !!info.error;
|
|
1174
|
-
const eligible = rows.filter((r) => r.supported && !r.paused && data.accounts.find((a) => a.id === r.id)?.enabled && r.ready === true);
|
|
1175
|
-
const ready = (r) => eligible.includes(r);
|
|
1176
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "stack", children: [
|
|
1177
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "box stack", children: [
|
|
1178
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bar", children: [
|
|
1179
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
1180
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { children: "\u6BCF\u65E5\u79EF\u5206\u7B7E\u5230" }),
|
|
1181
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: info.schedule }),
|
|
1182
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u81EA\u52A8\u7B7E\u5230\u9ED8\u8BA4\u5173\u95ED\uFF0C\u8BF7\u5728\u4E0B\u65B9\u9010\u4E2A\u5F00\u542F\u3002" })
|
|
1183
|
-
] }),
|
|
1184
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", { className: "primary", disabled: blocked || !eligible.length, onClick: () => {
|
|
1185
|
-
void act({ action: "checkins.run", ids: eligible.map((r) => r.id) });
|
|
1186
|
-
}, children: [
|
|
1187
|
-
"\u7B7E\u5230\u5168\u90E8\u53EF\u7528\u8D26\u53F7\uFF08",
|
|
1188
|
-
eligible.length,
|
|
1189
|
-
"\uFF09"
|
|
1190
|
-
] })
|
|
1191
|
-
] }),
|
|
1192
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("form", { className: "row plan-form", onSubmit: (e) => {
|
|
1193
|
-
e.preventDefault();
|
|
1194
|
-
void act({ action: "checkins.settings", schedule });
|
|
1195
|
-
}, children: [
|
|
1196
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "filter", children: [
|
|
1197
|
-
"\u81EA\u52A8\u7B7E\u5230\u65B9\u5F0F",
|
|
1198
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", { "aria-label": "\u81EA\u52A8\u7B7E\u5230\u65B9\u5F0F", value: schedule.mode, disabled: blocked, onChange: (e) => setSchedule({ ...schedule, mode: e.target.value }), children: [
|
|
1199
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "startup", children: "\u6BCF\u65E5\u542F\u52A8\u65F6\u7B7E\u5230" }),
|
|
1200
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "scheduled", children: "\u6BCF\u5929\u5B9A\u65F6\u7B7E\u5230" })
|
|
1201
|
-
] })
|
|
1202
|
-
] }),
|
|
1203
|
-
schedule.mode === "scheduled" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "filter", children: [
|
|
1204
|
-
"\u7B7E\u5230\u65F6\u95F4\uFF08\u5317\u4EAC\u65F6\u95F4\uFF09",
|
|
1205
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { "aria-label": "\u7B7E\u5230\u65F6\u95F4\uFF08\u5317\u4EAC\u65F6\u95F4\uFF09", type: "time", required: true, value: schedule.time, disabled: blocked, onChange: (e) => setSchedule({ ...schedule, time: e.target.value }) })
|
|
1206
|
-
] }),
|
|
1207
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: blocked || !changed, children: "\u4FDD\u5B58\u7B7E\u5230\u8BA1\u5212" })
|
|
1208
|
-
] }),
|
|
1209
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("details", { className: "help", children: [
|
|
1210
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("summary", { children: "\u6267\u884C\u89C4\u5219\u3001\u8865\u67E5\u4E0E\u8BBE\u5907\u9650\u5236" }),
|
|
1211
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "stack", children: [
|
|
1212
|
-
" ",
|
|
1213
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u81EA\u52A8\u7B7E\u5230\u9ED8\u8BA4\u5173\u95ED\uFF0C\u6309\u8D26\u53F7\u5F00\u542F\u3002\u5148\u67E5\u9886\u53D6\u72B6\u6001\u3001\u4E32\u884C\u63D0\u4EA4\uFF0C\u8D26\u53F7\u95F4\u9694\u81F3\u5C11 10 \u79D2\uFF1B\u6BCF\u4E2A\u8D26\u53F7\u6BCF\u5929\u6700\u591A\u63D0\u4EA4\u4E00\u6B21\u9886\u53D6\u3002\u786E\u8BA4\u5C1A\u672A\u63D0\u4EA4\u7684\u67E5\u8BE2\u5931\u8D25\uFF0C20:05 \u540E\u6700\u591A\u8865\u67E5\u4E00\u6B21\uFF1B\u5DF2\u9886\u53D6\u3001\u65E0\u6D3B\u52A8\u548C\u7ED3\u679C\u4E0D\u660E\u7684\u8D26\u53F7\u8DF3\u8FC7\u3002\u9047\u5230\u9A8C\u8BC1\u3001\u9650\u6D41\u6216\u8BBE\u5907\u9650\u5236\u5C31\u505C\u6B62\uFF0C\u4E0D\u4F1A\u4FEE\u6539\u8BBE\u5907\u8EAB\u4EFD\u6216\u5207\u6362\u8D26\u53F7\u91CD\u8BD5\u3002" }),
|
|
1214
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u542F\u52A8\u6A21\u5F0F\u5728\u5F53\u5929\u9996\u6B21\u8FD0\u884C\u65F6\u6267\u884C\uFF0C\u6301\u7EED\u8FD0\u884C\u5219\u65B0\u4E00\u5929\u81EA\u52A8\u6267\u884C\uFF1B\u5B9A\u65F6\u6A21\u5F0F\u5728\u8BBE\u5B9A\u65F6\u95F4\u540E\u6267\u884C\uFF0C\u9519\u8FC7\u65F6\u4E0B\u6B21\u542F\u52A8\u8865\u67E5\u3002Qoder \u6700\u65E9\u5317\u4EAC\u65F6\u95F4 10:05 \u67E5\u8BE2\u5F53\u65E5\u6D3B\u52A8\u3002DSH \u5173\u95ED\u671F\u95F4\u4E0D\u6267\u884C\uFF0C\u8FD0\u884C\u65F6\u7EA6\u4E00\u5206\u949F\u5185\u89E6\u53D1\u3002\u4FEE\u6539\u8BA1\u5212\u3001\u5237\u65B0\u9762\u677F\u6216\u91CD\u542F\u4E0D\u4F1A\u6E05\u9664\u5DF2\u5904\u7406\u8BB0\u5F55\uFF1B\u4EE4\u724C\u5931\u6548\u540E\u8BF7\u66F4\u65B0\u51ED\u8BC1\u518D\u6062\u590D\u3002" })
|
|
1215
|
-
] })
|
|
1216
|
-
] }),
|
|
1217
|
-
info.error && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { role: "alert", className: "error", children: info.error }),
|
|
1218
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { role: "status", children: info.running ? `\u6B63\u5728\u5904\u7406 ${displayName(data.accounts.find((a) => a.id === info.current)) || "\u7B7E\u5230\u961F\u5217"}\u2026` : "\u7B7E\u5230\u7ED3\u679C\u548C\u9886\u53D6\u79EF\u5206\u4EE5\u4E0B\u65B9\u5E73\u53F0\u54CD\u5E94\u4E3A\u51C6\u3002" }),
|
|
1219
|
-
info.report && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "notice", children: [
|
|
1220
|
-
"\u6700\u8FD1\u4E00\u8F6E \xB7 ",
|
|
1221
|
-
when(info.report.at),
|
|
1222
|
-
" \xB7 ",
|
|
1223
|
-
Object.entries(info.report.counts || {}).map(([key, n]) => `${resultLabels[key] || "\u672A\u5B8C\u6210"} ${n}`).join(" \xB7 "),
|
|
1224
|
-
"\u3002\u6CA1\u6709\u5F85\u8865\u67E5\u8D26\u53F7\u65F6\u4E0D\u91CD\u590D\u6C47\u62A5\u3002"
|
|
1225
|
-
] })
|
|
1226
|
-
] }),
|
|
1227
|
-
data.providers.map((p) => {
|
|
1228
|
-
const accounts = data.accounts.filter((a) => a.provider === p.id);
|
|
1229
|
-
if (!accounts.length) return null;
|
|
1230
|
-
const supported = rows.some((r) => r.id === accounts[0].id && r.supported), paused = rows.some((r) => accounts.some((a) => a.id === r.id) && r.paused);
|
|
1231
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "box stack", children: [
|
|
1232
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bar", children: [
|
|
1233
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { children: p.name }),
|
|
1234
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "badge", children: supported ? paused ? "\u5DF2\u6682\u505C" : "\u652F\u6301\u7B7E\u5230" : "\u5B98\u65B9\u5BA2\u6237\u7AEF\u9886\u53D6" })
|
|
1235
|
-
] }),
|
|
1236
|
-
!supported ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: p.id.startsWith("workbuddy") ? "WorkBuddy AI \u6682\u672A\u63A5\u5165\u53EF\u6838\u9A8C\u7684\u7B7E\u5230\u63A5\u53E3\uFF0C\u8BF7\u5728\u5B98\u65B9\u5BA2\u6237\u7AEF\u67E5\u770B\u6D3B\u52A8\u4E0E\u9886\u53D6\u5165\u53E3\u3002" : "Trae Global \u6682\u65E0\u5DF2\u6838\u9A8C\u7684\u79EF\u5206\u7B7E\u5230\u63A5\u53E3\uFF0C\u8BF7\u5728\u5B98\u65B9\u5BA2\u6237\u7AEF\u67E5\u770B\u6743\u76CA\u3002" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
1237
|
-
paused && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "steps", children: [
|
|
1238
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: "\u5E73\u53F0\u9650\u5236\u6216\u9700\u8981\u9A8C\u8BC1\uFF0C\u5DF2\u6682\u505C\u8BE5\u5E73\u53F0\u7B7E\u5230\u3002\u8BF7\u5728\u5B98\u65B9\u5BA2\u6237\u7AEF\u5904\u7406\u540E\u518D\u6062\u590D\uFF1B\u6062\u590D\u4ECD\u4FDD\u7559\u4ECA\u65E5\u5C1D\u8BD5\u8BB0\u5F55\u548C\u8BBE\u5907\u9650\u5236\u3002" }),
|
|
1239
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: blocked, onClick: () => {
|
|
1240
|
-
void act({ action: "checkins.resume", provider: p.id });
|
|
1241
|
-
}, children: "\u6211\u5DF2\u5728\u5B98\u65B9\u5BA2\u6237\u7AEF\u5904\u7406\uFF0C\u6062\u590D\u540E\u7EED\u7B7E\u5230" })
|
|
1242
|
-
] }),
|
|
1243
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "scroll", role: "region", "aria-label": `${p.name} \u7B7E\u5230\u8BB0\u5F55`, tabIndex: "0", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("table", { className: "table", children: [
|
|
1244
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tr", { children: [
|
|
1245
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { scope: "col", children: "\u8D26\u53F7" }),
|
|
1246
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { scope: "col", children: "\u81EA\u52A8\u7B7E\u5230" }),
|
|
1247
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { scope: "col", children: "\u4ECA\u65E5\u7ED3\u679C" }),
|
|
1248
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { scope: "col", children: "\u6700\u8FD1\u8BB0\u5F55" }),
|
|
1249
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { scope: "col", className: "cell-actions", children: "\u64CD\u4F5C" })
|
|
1250
|
-
] }) }),
|
|
1251
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("tbody", { children: accounts.map((a) => {
|
|
1252
|
-
const r = rows.find((r2) => r2.id === a.id) || {}, last = r.last?.day === today ? r.last : void 0;
|
|
1253
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tr", { className: info.current === a.id ? "selected" : "", children: [
|
|
1254
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("td", { children: [
|
|
1255
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: displayName(a) }),
|
|
1256
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("small", { className: "muted", children: a.enabled === false ? "\u8D26\u53F7\u5DF2\u505C\u7528" : "\u5DF2\u5728\u8D26\u53F7\u6C60\u4E2D" })
|
|
1257
|
-
] }),
|
|
1258
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "check", children: [
|
|
1259
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { "aria-label": `${displayName(a)} \u6BCF\u65E5\u81EA\u52A8\u7B7E\u5230`, type: "checkbox", disabled: blocked, checked: r.auto === true, onChange: (e) => {
|
|
1260
|
-
void act({ action: "account.update", id: a.id, autoCheckin: e.target.checked });
|
|
1261
|
-
} }),
|
|
1262
|
-
"\u6BCF\u65E5\u81EA\u52A8\u7B7E\u5230"
|
|
1263
|
-
] }) }),
|
|
1264
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CheckinResult, { row: r, compact: true }) }),
|
|
1265
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("td", { children: [
|
|
1266
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("small", { className: "muted", children: r.last ? when(r.last.at) : "\u5C1A\u65E0\u8BB0\u5F55" }),
|
|
1267
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("small", { className: "muted", children: r.last?.message || "\u7B49\u5F85\u9996\u6B21\u7B7E\u5230" }),
|
|
1268
|
-
last?.retryAt && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("small", { className: "warn", children: [
|
|
1269
|
-
"\u8865\u67E5\u65F6\u95F4 ",
|
|
1270
|
-
when(last.retryAt)
|
|
1271
|
-
] }),
|
|
1272
|
-
r.last?.activity && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("details", { children: [
|
|
1273
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("summary", { children: "\u6D3B\u52A8\u8BE6\u60C5" }),
|
|
1274
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("small", { className: "muted", children: [r.last.activity.streakDays !== void 0 && `\u8FDE\u7B7E ${fmt(r.last.activity.streakDays)} \u5929`, r.last.activity.totalCredits !== void 0 && `\u6D3B\u52A8\u7D2F\u8BA1 ${fmt(r.last.activity.totalCredits)} \u79EF\u5206`, r.last.activity.nextStreakDay !== void 0 && `\u4E0B\u4E00\u8FDE\u7B7E\u6863\u4F4D ${fmt(r.last.activity.nextStreakDay)} \u5929`, r.last.activity.endsAt !== void 0 && `\u6D3B\u52A8\u622A\u6B62 ${when(r.last.activity.endsAt)}`].filter(Boolean).join(" \xB7 ") })
|
|
1275
|
-
] })
|
|
1276
|
-
] }),
|
|
1277
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "cell-actions", children: p.id === "workbuddy" && r.last?.status === "auth-invalid" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: blocked, onClick: () => {
|
|
1278
|
-
void act({ action: "checkins.verify", id: a.id });
|
|
1279
|
-
}, children: "\u91CD\u65B0\u9A8C\u8BC1\u767B\u5F55" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: blocked || !ready(r), onClick: () => {
|
|
1280
|
-
void act({ action: "checkins.run", ids: [a.id] });
|
|
1281
|
-
}, children: r.last?.status === "auth-invalid" ? "\u8BF7\u66F4\u65B0\u51ED\u8BC1" : last?.retryReady ? "\u8865\u67E5\u7B7E\u5230" : last?.retryAt ? "\u7B49\u5F85\u665A\u95F4\u8865\u67E5" : last ? "\u4ECA\u65E5\u5DF2\u5904\u7406" : "\u7ACB\u5373\u7B7E\u5230" }) })
|
|
1282
|
-
] }, a.id);
|
|
1283
|
-
}) })
|
|
1284
|
-
] }) })
|
|
1285
|
-
] })
|
|
1286
|
-
] }, p.id);
|
|
1287
|
-
}),
|
|
1288
|
-
!data.accounts.length && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "box empty", children: "\u5148\u5230\u300C\u8D26\u53F7\u4E0E\u767B\u5F55\u300D\u6DFB\u52A0\u8D26\u53F7\uFF0C\u518D\u5F00\u542F\u6BCF\u65E5\u81EA\u52A8\u7B7E\u5230\u3002" }),
|
|
1289
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u591A\u53F0\u8BBE\u5907\u7684\u672C\u5730\u8BB0\u5F55\u4E0D\u4F1A\u4E92\u76F8\u540C\u6B65\uFF0C\u6BCF\u6B21\u90FD\u4F1A\u67E5\u8BE2\u5E73\u53F0\u9886\u53D6\u72B6\u6001\uFF1B\u5EFA\u8BAE\u4EC5\u5728\u4E00\u53F0\u5E38\u7528\u8BBE\u5907\u5F00\u542F\u81EA\u52A8\u7B7E\u5230\u3002\u540C\u4E00 Trae \u8BBE\u5907\u6BCF\u5929\u6700\u591A\u5904\u7406\u4E00\u4E2A\u9886\u53D6\u8BF7\u6C42\uFF0C\u91CD\u590D\u8D26\u53F7\u526F\u672C\u4F1A\u53BB\u91CD\uFF1B\u4E0D\u4FDD\u8BC1\u5E73\u53F0\u4E00\u5B9A\u53D1\u653E\u5956\u52B1\u3002" })
|
|
1290
|
-
] });
|
|
1291
|
-
}
|
|
1292
|
-
function Overview({ data, busy, act, go }) {
|
|
1293
|
-
const t = data.telemetry || {}, today = t.days?.[t.today] || {}, totals = data.accounts.reduce((s, a) => ({ requests: s.requests + (a.usage?.requests || 0), tokens: s.tokens + (a.usage?.tokens || 0) }), { requests: 0, tokens: 0 });
|
|
1294
|
-
const dates = Array.from({ length: 7 }, (_, i) => {
|
|
1295
|
-
const d = /* @__PURE__ */ new Date();
|
|
1296
|
-
d.setDate(d.getDate() - 6 + i);
|
|
1297
|
-
const key = d.toLocaleDateString("en-CA", { timeZone: "Asia/Shanghai" });
|
|
1298
|
-
return { key, tokens: t.days?.[key]?.tokens || 0 };
|
|
1299
|
-
});
|
|
1300
|
-
const max = Math.max(1, ...dates.map((d) => d.tokens));
|
|
1301
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "stack", children: [
|
|
1302
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "metrics", children: [
|
|
1303
|
-
metric("\u4ECA\u65E5 Token", fmt(today.tokens || 0), "\u8F93\u5165 + \u8F93\u51FA \xB7 \u5317\u4EAC\u65F6\u95F4"),
|
|
1304
|
-
metric("\u4ECA\u65E5\u8BF7\u6C42", fmt(today.requests || 0), `\u5931\u8D25 ${fmt(today.failures || 0)} \u6B21`),
|
|
1305
|
-
metric("\u8D26\u53F7\u6C60", `${data.accounts.filter((a) => a.enabled).length} / ${data.accounts.length}`, "\u542F\u7528 / \u5168\u90E8\u8D26\u53F7"),
|
|
1306
|
-
metric("\u7D2F\u8BA1 Token", fmt(totals.tokens), `${fmt(totals.requests)} \u6B21\u8BF7\u6C42`)
|
|
1307
|
-
] }),
|
|
1308
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(PerformanceMetrics, { events: (t.events || []).filter((e) => e.at >= usageDateBounds("1")[0]) }),
|
|
1309
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bar", children: [
|
|
1310
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { children: "\u5E73\u53F0\u989D\u5EA6" }),
|
|
1311
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "row", children: [
|
|
1312
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "notice", children: "\u5E73\u53F0\u7528\u91CF \xB7 \u6BCF 5 \u5206\u949F\u66F4\u65B0" }),
|
|
1313
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: busy, onClick: () => {
|
|
1314
|
-
void act({ action: "monitor.refresh" });
|
|
1315
|
-
}, children: "\u5237\u65B0\u5E73\u53F0\u7528\u91CF" })
|
|
1316
|
-
] })
|
|
1317
|
-
] }),
|
|
1318
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "box table-shell", children: [
|
|
1319
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "scroll", role: "region", "aria-label": "\u5404\u5E73\u53F0\u8D26\u53F7\u989D\u5EA6", tabIndex: "0", children: [
|
|
1320
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("table", { className: "table", children: [
|
|
1321
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tr", { children: [
|
|
1322
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { scope: "col", children: "\u8D26\u53F7" }),
|
|
1323
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { scope: "col", children: "\u4F9B\u5E94\u5546 / \u533A\u57DF" }),
|
|
1324
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { scope: "col", children: "\u5E73\u53F0\u79EF\u5206" }),
|
|
1325
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { scope: "col", children: "\u4ECA\u65E5\u7B7E\u5230" }),
|
|
1326
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { scope: "col", className: "cell-actions", children: "\u8DEF\u7531\u72B6\u6001" })
|
|
1327
|
-
] }) }),
|
|
1328
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("tbody", { children: data.accounts.map((a) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tr", { children: [
|
|
1329
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("td", { children: [
|
|
1330
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: displayName(a) }),
|
|
1331
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("small", { className: "muted", children: loginNames[a.login?.state] || "\u5C1A\u672A\u67E5\u8BE2\u767B\u5F55" })
|
|
1332
|
-
] }),
|
|
1333
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { children: data.providers.find((p) => p.id === a.provider)?.name || a.provider }),
|
|
1334
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Balance, { account: a }) }),
|
|
1335
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CheckinResult, { row: data.checkins?.accounts.find((r) => r.id === a.id) }) }),
|
|
1336
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "cell-actions", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "status", children: [
|
|
1337
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("i", { className: a.enabled === false ? "" : a.status?.cooldowns?.length ? "warn" : "good", "aria-hidden": "true" }),
|
|
1338
|
-
a.enabled === false ? "\u672A\u5165\u6C60" : a.status?.cooldowns?.length ? "\u90E8\u5206\u8DEF\u7531\u51B7\u5374" : "\u5DF2\u5728\u6C60\u4E2D"
|
|
1339
|
-
] }) })
|
|
1340
|
-
] }, a.id)) })
|
|
1341
|
-
] }),
|
|
1342
|
-
!data.accounts.length && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "empty", children: "\u5C1A\u672A\u8FDE\u63A5\u8D26\u53F7\uFF0C\u8BF7\u5148\u83B7\u53D6\u672C\u673A\u767B\u5F55\u6216\u6DFB\u52A0\u51ED\u8BC1\u3002" })
|
|
1343
|
-
] }),
|
|
1344
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "table-footer bar", children: [
|
|
1345
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u5404\u5E73\u53F0\u79EF\u5206\u72EC\u7ACB\u5C55\u793A\uFF0C\u4E34\u671F\u63D0\u9192\u4EC5\u663E\u793A\u5DF2\u786E\u8BA4\u7684\u4F59\u989D\u3002" }),
|
|
1346
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: busy, onClick: () => go("accounts"), children: "\u7BA1\u7406\u8D26\u53F7\u6C60" })
|
|
1347
|
-
] })
|
|
1348
|
-
] }),
|
|
1349
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u9762\u677F\u8BFB\u53D6\u672C\u673A\u7F13\u5B58\uFF0C\u4E0D\u4F1A\u89E6\u53D1\u5E73\u53F0\u67E5\u8BE2\u3002\u5E73\u53F0\u4F59\u989D\u6BCF 5 \u5206\u949F\u66F4\u65B0\uFF0C\u624B\u52A8\u5237\u65B0\u7ACB\u5373\u67E5\u8BE2\uFF1B\u79EF\u5206\u8F6E\u6362\u4E0E\u4E34\u671F\u4F18\u5148\u6309\u9700\u590D\u6838\u3002Token \u4EC5\u7EDF\u8BA1\u672C\u63D2\u4EF6\u8BF7\u6C42\u3002" }),
|
|
1350
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "grid", children: [
|
|
1351
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "box", children: [
|
|
1352
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { children: "\u8FD1 7 \u65E5 Token" }),
|
|
1353
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "trend", role: "img", "aria-label": dates.map((d) => `${d.key} ${d.tokens} Token`).join("\uFF0C"), children: dates.map((d) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { title: `${d.key} \xB7 ${fmt(d.tokens)} Token`, children: [
|
|
1354
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("i", { style: { height: `${Math.max(3, d.tokens / max * 78)}%` } }),
|
|
1355
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("small", { children: d.key.slice(5) })
|
|
1356
|
-
] }, d.key)) }),
|
|
1357
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "notice", children: [
|
|
1358
|
-
"\u672A\u8FD4\u56DE Token \u7528\u91CF\u7684\u8BF7\u6C42\uFF1A",
|
|
1359
|
-
fmt(data.accounts.reduce((n, a) => n + (a.usage?.unmetered || 0), 0)),
|
|
1360
|
-
" \u6B21"
|
|
1361
|
-
] })
|
|
1362
|
-
] }),
|
|
1363
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "box stack", children: [
|
|
1364
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { children: "\u5E38\u7528\u5165\u53E3" }),
|
|
1365
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u8FDE\u63A5\u8D26\u53F7\u540E\uFF0C\u5728 DSH \u6A21\u578B\u9009\u62E9\u5668\u4E2D\u4F7F\u7528\u300C\u7EDF\u4E00\u8DEF\u7531\u300D\u3002" }),
|
|
1366
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "row", children: [
|
|
1367
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { onClick: () => go("accounts"), children: "\u67E5\u770B\u8D26\u53F7" }),
|
|
1368
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { onClick: () => go("routes"), children: "\u914D\u7F6E\u8DEF\u7531" }),
|
|
1369
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { onClick: () => go("checkins"), children: "\u79EF\u5206\u7B7E\u5230" }),
|
|
1370
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { onClick: () => go("plugins"), children: "\u68C0\u67E5\u6240\u6709\u63D2\u4EF6\u66F4\u65B0" })
|
|
1371
|
-
] })
|
|
1372
|
-
] })
|
|
1373
|
-
] }),
|
|
1374
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "box", children: [
|
|
1375
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bar", children: [
|
|
1376
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { children: "\u6700\u8FD1\u8BF7\u6C42" }),
|
|
1377
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { onClick: () => go("usage"), children: "\u67E5\u770B Token \u660E\u7EC6" })
|
|
1378
|
-
] }),
|
|
1379
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "scroll", children: [
|
|
1380
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("table", { className: "table", children: [
|
|
1381
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tr", { children: [
|
|
1382
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { children: "\u65F6\u95F4" }),
|
|
1383
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { children: "\u8D26\u53F7" }),
|
|
1384
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { children: "\u8DEF\u7531 / \u6A21\u578B" }),
|
|
1385
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { children: "Token" }),
|
|
1386
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { children: "\u6027\u80FD" }),
|
|
1387
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { children: "\u7ED3\u679C" })
|
|
1388
|
-
] }) }),
|
|
1389
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("tbody", { children: (t.events || []).slice(0, 15).map((e, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tr", { children: [
|
|
1390
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { children: when(e.at) }),
|
|
1391
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { children: data.accounts.find((a) => a.id === e.account)?.name || e.account }),
|
|
1392
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "mono", children: e.alias }),
|
|
1393
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { children: fmt(e.tokens) }),
|
|
1394
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RequestPerformance, { event: e }) }),
|
|
1395
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { children: e.outcome === "completed" ? "\u6210\u529F" : e.outcome === "cancelled" ? "\u5DF2\u53D6\u6D88" : `\u5931\u8D25 ${e.status}` })
|
|
1396
|
-
] }, `${e.at}:${i}`)) })
|
|
1397
|
-
] }),
|
|
1398
|
-
!t.events?.length && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "empty", children: "\u5C1A\u65E0\u8BF7\u6C42\u8BB0\u5F55\u3002\u901A\u8FC7\u672C\u63D2\u4EF6\u8C03\u7528\u6A21\u578B\u540E\u4F1A\u663E\u793A\u5728\u8FD9\u91CC\u3002" })
|
|
1399
|
-
] })
|
|
1400
|
-
] })
|
|
1401
|
-
] });
|
|
1402
|
-
}
|
|
1403
|
-
function usageDateBounds(period, start, end, now = Date.now()) {
|
|
1404
|
-
const today = new Date(now).toLocaleDateString("en-CA", { timeZone: "Asia/Shanghai" });
|
|
1405
|
-
const midnight = (day) => Date.parse(`${day}T00:00:00+08:00`);
|
|
1406
|
-
if (period === "custom") return [midnight(start), midnight(end) + 864e5];
|
|
1407
|
-
if (period === "all") return [-Infinity, Infinity];
|
|
1408
|
-
return [midnight(today) - (Number(period) - 1) * 864e5, midnight(today) + 864e5];
|
|
1409
|
-
}
|
|
1410
|
-
var duration = (ms) => typeof ms !== "number" || !Number.isFinite(ms) ? "\u2014" : ms < 6e4 ? `${fmt(ms / 1e3)} \u79D2` : `${Math.floor(ms / 6e4)} \u5206 ${fmt(ms % 6e4 / 1e3)} \u79D2`;
|
|
1411
|
-
function performanceSummary(events) {
|
|
1412
|
-
const rows = events.filter((e) => e.outcome === "completed" && e.timing);
|
|
1413
|
-
const sum = (key, source = rows) => source.some((e) => e.timing[key] != null) ? source.reduce((n, e) => n + (e.timing[key] ?? 0), 0) : null;
|
|
1414
|
-
const first = rows.filter((e) => e.timing.ttftMs != null), decode = rows.filter((e) => e.timing.decodeMs > 0 && e.timing.decodeTokens != null), tools = rows.filter((e) => e.timingSource === "dsh-step");
|
|
1415
|
-
return {
|
|
1416
|
-
modelMs: sum("modelMs"),
|
|
1417
|
-
toolMs: sum("toolMs", tools),
|
|
1418
|
-
ttftMs: first.length ? sum("ttftMs", first) / first.length : null,
|
|
1419
|
-
tps: decode.length ? sum("decodeTokens", decode) / (sum("decodeMs", decode) / 1e3) : null,
|
|
1420
|
-
samples: rows.length,
|
|
1421
|
-
firstSamples: first.length,
|
|
1422
|
-
decodeSamples: decode.length,
|
|
1423
|
-
toolSamples: tools.length,
|
|
1424
|
-
pendingTools: tools.reduce((n, e) => n + (e.timing.toolCount ?? 0) - (e.timing.toolsCompleted ?? 0), 0)
|
|
1425
|
-
};
|
|
1426
|
-
}
|
|
1427
|
-
function PerformanceMetrics({ events }) {
|
|
1428
|
-
const stats = performanceSummary(events);
|
|
1429
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "stack performance", "aria-label": "\u8C03\u7528\u6027\u80FD\u7EDF\u8BA1", children: [
|
|
1430
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bar", children: [
|
|
1431
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { children: "\u8C03\u7528\u6027\u80FD" }),
|
|
1432
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "notice", children: [
|
|
1433
|
-
"\u6210\u529F\u8C03\u7528 \xB7 ",
|
|
1434
|
-
fmt(stats.samples),
|
|
1435
|
-
" \u6761\u6027\u80FD\u8BB0\u5F55"
|
|
1436
|
-
] })
|
|
1437
|
-
] }),
|
|
1438
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "metrics", children: [
|
|
1439
|
-
metric("\u6A21\u578B\u7528\u65F6", duration(stats.modelMs), "\u6210\u529F\u8C03\u7528\u7528\u65F6\u5408\u8BA1"),
|
|
1440
|
-
metric("\u5DE5\u5177\u8C03\u7528\u7528\u65F6", duration(stats.toolMs), `${stats.toolSamples} \u6761 DSH \u6B65\u9AA4${stats.pendingTools ? ` \xB7 ${stats.pendingTools} \u4E2A\u5DE5\u5177\u672A\u5B8C\u6210` : ""}`),
|
|
1441
|
-
metric("\u9996 Token \u5E73\u5747\uFF08TTFT\uFF09", duration(stats.ttftMs), `${stats.firstSamples} \u6761\u9996 Token \u8BB0\u5F55`),
|
|
1442
|
-
metric("\u8F93\u51FA\u901F\u5EA6\uFF08TPS\uFF09", stats.tps === null ? "\u2014" : `${fmt(stats.tps)} tok/s`, `${stats.decodeSamples} \u6761\u89E3\u7801\u8BB0\u5F55 \xB7 \u52A0\u6743\u901F\u5EA6`)
|
|
1443
|
-
] }),
|
|
1444
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("details", { className: "help", children: [
|
|
1445
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("summary", { children: "\u7EDF\u8BA1\u53E3\u5F84\u4E0E\u7F3A\u5931\u6570\u636E" }),
|
|
1446
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u968F\u5F53\u524D\u65F6\u95F4\u3001\u8D26\u53F7\u3001\u8DEF\u7531\u548C\u7ED3\u679C\u7B5B\u9009\u6C47\u603B\uFF0C\u4ECE\u672C\u7248\u5F00\u59CB\u8BB0\u5F55\uFF1B\u65E7\u6570\u636E\u4E0D\u8865\u7B97\u3002DSH \u6B65\u9AA4\u53E3\u5F84\u4E0E\u4F1A\u8BDD\u7EDF\u8BA1\u4E00\u81F4\uFF1A\u6A21\u578B\u7528\u65F6\u4ECE\u6B65\u9AA4\u5F00\u59CB\u5230\u56DE\u590D\u5B8C\u6210\uFF0C\u9996 Token \u5305\u62EC\u975E\u7A7A\u6587\u672C\u3001\u63A8\u7406\u6216\u5DE5\u5177\u8C03\u7528\uFF0C\u5DE5\u5177\u7528\u65F6\u6309\u8C03\u7528\u4E0E\u7ED3\u679C\u914D\u5BF9\u76F8\u52A0\uFF08\u5E76\u884C\u5DE5\u5177\u53EF\u80FD\u91CD\u53E0\uFF09\u3002TPS = \u6709\u6548\u8F93\u51FA Token \u5408\u8BA1 \xF7 \u9996 Token \u540E\u7684\u89E3\u7801\u79D2\u6570\u5408\u8BA1\uFF0C\u4E0D\u5BF9\u5404\u6B21\u901F\u5EA6\u7B80\u5355\u5E73\u5747\u3002\u672A\u7ECF\u8FC7 DSH \u6B65\u9AA4\u7684\u8BF7\u6C42\u4F7F\u7528\u4E0A\u6E38\u8BA1\u65F6\uFF0C\u65E0\u6CD5\u8BB0\u5F55\u5DE5\u5177\u6267\u884C\u7528\u65F6\u3002\u8FD9\u91CC\u53EA\u6C47\u603B\u672C\u63D2\u4EF6\u4FDD\u7559\u4E14\u7B5B\u9009\u5185\u7684\u8C03\u7528\uFF0C\u5E76\u975E\u67D0\u4E2A\u4F1A\u8BDD\u7684\u5B8C\u6574\u5386\u53F2\u3002\u5931\u8D25\u4E0E\u53D6\u6D88\u4FDD\u7559\u9010\u6B21\u8017\u65F6\uFF0C\u4E0D\u8BA1\u5165\u4EE5\u4E0A\u6210\u529F\u8C03\u7528\u6307\u6807\u3002" }) })
|
|
1447
|
-
] })
|
|
1448
|
-
] });
|
|
1449
|
-
}
|
|
1450
|
-
function UsageDetails({ data, busy, act }) {
|
|
1451
|
-
const [account, setAccount] = (0, import_react.useState)(""), [route, setRoute] = (0, import_react.useState)(""), [outcome, setOutcome] = (0, import_react.useState)(""), [source, setSource] = (0, import_react.useState)(""), [page, setPage] = (0, import_react.useState)(0);
|
|
1452
|
-
const [period, setPeriod] = (0, import_react.useState)("30"), [start, setStart] = (0, import_react.useState)(() => new Date(Date.now() - 29 * 864e5).toLocaleDateString("en-CA", { timeZone: "Asia/Shanghai" })), [end, setEnd] = (0, import_react.useState)(() => (/* @__PURE__ */ new Date()).toLocaleDateString("en-CA", { timeZone: "Asia/Shanghai" }));
|
|
1453
|
-
const all = data.telemetry?.events || [], retention = data.options.usageRetentionDays;
|
|
1454
|
-
const [from, until] = usageDateBounds(period, start, end), invalidRange = !(from < until);
|
|
1455
|
-
const events = all.filter((e) => e.at >= from && e.at < until && (!account || e.account === account) && (!route || e.alias === route) && (!outcome || e.outcome === outcome) && (!source || (e.source || "dsh") === source));
|
|
1456
|
-
const pages = Math.max(1, Math.ceil(events.length / 50)), current = Math.min(page, pages - 1);
|
|
1457
|
-
const accountName = (id) => data.accounts.find((a) => a.id === id)?.name || id;
|
|
1458
|
-
const routeName = (id) => data.routes.find((r) => r.id === id)?.name || id;
|
|
1459
|
-
const total = (key) => events.some((e) => e[key] != null) ? events.reduce((n, e) => n + (e[key] ?? 0), 0) : null;
|
|
1460
|
-
const missing = events.filter((e) => e.input == null || e.output == null).length;
|
|
1461
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "stack", children: [
|
|
1462
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "box stack", children: [
|
|
1463
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bar", children: [
|
|
1464
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
1465
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { children: "\u9010\u6B21\u8BF7\u6C42\u7528\u91CF" }),
|
|
1466
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u8BB0\u5F55\u6BCF\u6B21\u4E0A\u6E38\u8C03\u7528\uFF0C\u5305\u62EC\u6545\u969C\u5207\u6362\u4E2D\u5931\u8D25\u7684\u5C1D\u8BD5\u3002" })
|
|
1467
|
-
] }),
|
|
1468
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "badge", children: [
|
|
1469
|
-
"\u6700\u8FD1 ",
|
|
1470
|
-
retention,
|
|
1471
|
-
" \u5929 \xB7 ",
|
|
1472
|
-
fmt(all.length),
|
|
1473
|
-
" \u6761"
|
|
1474
|
-
] })
|
|
1475
|
-
] }),
|
|
1476
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("details", { className: "help", children: [
|
|
1477
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("summary", { children: [
|
|
1478
|
-
"\u8C03\u6574\u660E\u7EC6\u4FDD\u7559\u5929\u6570\uFF08\u5F53\u524D ",
|
|
1479
|
-
retention,
|
|
1480
|
-
" \u5929\uFF09"
|
|
1481
|
-
] }),
|
|
1482
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "stack", children: [
|
|
1483
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("form", { className: "row", onSubmit: (e) => {
|
|
1484
|
-
e.preventDefault();
|
|
1485
|
-
void act({ action: "options.save", usageRetentionDays: Number(new FormData(e.currentTarget).get("days")) });
|
|
1486
|
-
}, children: [
|
|
1487
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "filter", children: [
|
|
1488
|
-
"\u660E\u7EC6\u4FDD\u7559\u5929\u6570",
|
|
1489
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { name: "days", type: "number", min: "1", max: "365", step: "1", required: true, disabled: busy, defaultValue: retention })
|
|
1490
|
-
] }),
|
|
1491
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "submit", disabled: busy, children: "\u4FDD\u5B58\u4FDD\u7559\u671F\u9650" })
|
|
1492
|
-
] }, retention),
|
|
1493
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u9ED8\u8BA4\u6EDA\u52A8\u4FDD\u7559\u6700\u8FD1 30 \u5929\uFF0C\u53EF\u8BBE\u7F6E 1\u2013365 \u5929\u3002\u7F29\u77ED\u671F\u9650\u4F1A\u5220\u9664\u8D85\u671F\u660E\u7EC6\uFF0C\u5EF6\u957F\u4E0D\u80FD\u6062\u590D\u5DF2\u5220\u9664\u8BB0\u5F55\uFF1B\u7D2F\u8BA1\u7EDF\u8BA1\u3001\u989D\u5EA6\u8F6E\u6362\u548C\u4E34\u671F\u51B7\u5374\u4E0D\u53D7\u5F71\u54CD\u3002" })
|
|
1494
|
-
] })
|
|
1495
|
-
] })
|
|
1496
|
-
] }),
|
|
1497
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bar", children: [
|
|
1498
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "row", role: "group", "aria-label": "\u660E\u7EC6\u65F6\u95F4\u8303\u56F4", children: [["1", "\u4ECA\u65E5"], ["3", "\u8FD1 3 \u65E5"], ["7", "\u8FD1 7 \u65E5"], ["30", "\u8FD1 30 \u65E5"], ["all", "\u5168\u90E8\u5DF2\u4FDD\u7559"], ["custom", "\u81EA\u5B9A\u4E49"]].map(([value, label]) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { "aria-pressed": period === value, onClick: () => {
|
|
1499
|
-
setPeriod(value);
|
|
1500
|
-
setPage(0);
|
|
1501
|
-
}, children: label }, value)) }),
|
|
1502
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u6309\u5317\u4EAC\u65F6\u95F4\u81EA\u7136\u65E5\u7B5B\u9009" })
|
|
1503
|
-
] }),
|
|
1504
|
-
period === "custom" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "row", children: [
|
|
1505
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "filter", children: [
|
|
1506
|
-
"\u5F00\u59CB\u65E5\u671F\uFF08\u5317\u4EAC\u65F6\u95F4\uFF09",
|
|
1507
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "date", value: start, max: end || void 0, required: true, onChange: (e) => {
|
|
1508
|
-
setStart(e.target.value);
|
|
1509
|
-
setPage(0);
|
|
1510
|
-
} })
|
|
1511
|
-
] }),
|
|
1512
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "filter", children: [
|
|
1513
|
-
"\u7ED3\u675F\u65E5\u671F\uFF08\u5317\u4EAC\u65F6\u95F4\uFF09",
|
|
1514
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "date", value: end, min: start || void 0, required: true, onChange: (e) => {
|
|
1515
|
-
setEnd(e.target.value);
|
|
1516
|
-
setPage(0);
|
|
1517
|
-
} })
|
|
1518
|
-
] }),
|
|
1519
|
-
invalidRange && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { role: "alert", className: "error", children: "\u8BF7\u9009\u62E9\u6709\u6548\u7684\u8D77\u6B62\u65E5\u671F\uFF0C\u7ED3\u675F\u65E5\u671F\u4E0D\u80FD\u65E9\u4E8E\u5F00\u59CB\u65E5\u671F\u3002" })
|
|
1520
|
-
] }),
|
|
1521
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "row", children: [
|
|
1522
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "filter", children: [
|
|
1523
|
-
"\u8D26\u53F7",
|
|
1524
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", { value: account, onChange: (e) => {
|
|
1525
|
-
setAccount(e.target.value);
|
|
1526
|
-
setPage(0);
|
|
1527
|
-
}, children: [
|
|
1528
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "", children: "\u5168\u90E8\u8D26\u53F7" }),
|
|
1529
|
-
[...new Set(all.map((e) => e.account))].map((id) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: id, children: accountName(id) }, id))
|
|
1530
|
-
] })
|
|
1531
|
-
] }),
|
|
1532
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "filter", children: [
|
|
1533
|
-
"\u8DEF\u7531 / \u6A21\u578B",
|
|
1534
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", { value: route, onChange: (e) => {
|
|
1535
|
-
setRoute(e.target.value);
|
|
1536
|
-
setPage(0);
|
|
1537
|
-
}, children: [
|
|
1538
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "", children: "\u5168\u90E8\u8DEF\u7531 / \u6A21\u578B" }),
|
|
1539
|
-
[...new Set(all.map((e) => e.alias))].map((id) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: id, children: routeName(id) }, id))
|
|
1540
|
-
] })
|
|
1541
|
-
] }),
|
|
1542
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "filter", children: [
|
|
1543
|
-
"\u6765\u6E90",
|
|
1544
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", { value: source, onChange: (e) => {
|
|
1545
|
-
setSource(e.target.value);
|
|
1546
|
-
setPage(0);
|
|
1547
|
-
}, children: [
|
|
1548
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "", children: "\u5168\u90E8\u6765\u6E90" }),
|
|
1549
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "dsh", children: "DSH \u4F1A\u8BDD" }),
|
|
1550
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "api", children: "API \u670D\u52A1" })
|
|
1551
|
-
] })
|
|
1552
|
-
] }),
|
|
1553
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "filter", children: [
|
|
1554
|
-
"\u7ED3\u679C",
|
|
1555
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", { value: outcome, onChange: (e) => {
|
|
1556
|
-
setOutcome(e.target.value);
|
|
1557
|
-
setPage(0);
|
|
1558
|
-
}, children: [
|
|
1559
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "", children: "\u5168\u90E8\u7ED3\u679C" }),
|
|
1560
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "completed", children: "\u6210\u529F" }),
|
|
1561
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "failed", children: "\u5931\u8D25" }),
|
|
1562
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "cancelled", children: "\u5DF2\u53D6\u6D88" })
|
|
1563
|
-
] })
|
|
1564
|
-
] })
|
|
1565
|
-
] }),
|
|
1566
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "metrics", children: [
|
|
1567
|
-
metric("\u7B5B\u9009\u5185\u8C03\u7528", fmt(events.length), "\u4E0A\u6E38\u5C1D\u8BD5\u6B21\u6570"),
|
|
1568
|
-
metric("\u8F93\u5165 Token", fmt(total("input")), "\u5DF2\u8FD4\u56DE\u7684\u8F93\u5165\u5206\u9879"),
|
|
1569
|
-
metric("\u8F93\u51FA Token", fmt(total("output")), "\u5DF2\u8FD4\u56DE\u7684\u8F93\u51FA\u5206\u9879"),
|
|
1570
|
-
metric("\u603B Token", fmt(total("tokens")), "\u5DF2\u8FD4\u56DE\u7684\u603B\u91CF")
|
|
1571
|
-
] }),
|
|
1572
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "notice", children: [
|
|
1573
|
-
"\u6570\u636E\u6765\u81EA\u5E73\u53F0\u8FD4\u56DE\u7684 usage\u3002",
|
|
1574
|
-
missing ? fmt(missing) + " \u6761\u7F3A\u5C11\u8F93\u5165\u6216\u8F93\u51FA\u5206\u9879\uFF1B\u65E7\u8BB0\u5F55\u4E0D\u8865\u7B97\u3002" : "\u8F93\u5165\u3001\u8F93\u51FA\u4E3A\u5B9E\u9645\u8FD4\u56DE\u503C\u3002",
|
|
1575
|
-
"\u7F13\u5B58\u8F93\u5165\u5305\u542B\u5728\u8F93\u5165\u4E2D\uFF0C\u63A8\u7406\u8F93\u51FA\u5305\u542B\u5728\u8F93\u51FA\u4E2D\uFF0C\u5747\u4E0D\u91CD\u590D\u76F8\u52A0\u3002\u672A\u8FD4\u56DE\u7684\u6570\u636E\u4EE5\u300C\u2014\u300D\u663E\u793A\u3002"
|
|
1576
|
-
] }),
|
|
1577
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(PerformanceMetrics, { events }),
|
|
1578
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "box table-shell", children: [
|
|
1579
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "scroll", role: "region", "aria-label": "\u8BF7\u6C42\u7528\u91CF\u4E0E\u6027\u80FD\u660E\u7EC6", tabIndex: "0", children: [
|
|
1580
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("table", { className: "table", children: [
|
|
1581
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tr", { children: [
|
|
1582
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { children: "\u65F6\u95F4" }),
|
|
1583
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { children: "\u6E20\u9053 / \u8D26\u53F7" }),
|
|
1584
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { children: "\u8DEF\u7531 / \u5B9E\u9645\u6A21\u578B" }),
|
|
1585
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { children: "\u8F93\u5165" }),
|
|
1586
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { children: "\u8F93\u51FA" }),
|
|
1587
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { children: "\u603B Token" }),
|
|
1588
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { children: "\u6027\u80FD" }),
|
|
1589
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { children: "\u7ED3\u679C" })
|
|
1590
|
-
] }) }),
|
|
1591
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("tbody", { children: events.slice(current * 50, (current + 1) * 50).map((e, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tr", { children: [
|
|
1592
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("td", { children: [
|
|
1593
|
-
when(e.at),
|
|
1594
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("small", { className: "muted", children: e.source === "api" ? "API \u670D\u52A1" : "DSH \u4F1A\u8BDD" })
|
|
1595
|
-
] }),
|
|
1596
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("td", { children: [
|
|
1597
|
-
data.providers.find((p) => p.id === e.provider)?.name || e.provider,
|
|
1598
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("br", {}),
|
|
1599
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("small", { children: accountName(e.account) })
|
|
1600
|
-
] }),
|
|
1601
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("td", { children: [
|
|
1602
|
-
routeName(e.alias),
|
|
1603
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("br", {}),
|
|
1604
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("small", { className: "mono", children: e.model || "\u672A\u8BB0\u5F55\u5B9E\u9645\u6A21\u578B" })
|
|
1605
|
-
] }),
|
|
1606
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("td", { children: [
|
|
1607
|
-
fmt(e.input),
|
|
1608
|
-
e.cachedInput != null && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
1609
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("br", {}),
|
|
1610
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("small", { children: [
|
|
1611
|
-
"\u7F13\u5B58 ",
|
|
1612
|
-
fmt(e.cachedInput)
|
|
1613
|
-
] })
|
|
1614
|
-
] })
|
|
1615
|
-
] }),
|
|
1616
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("td", { children: [
|
|
1617
|
-
fmt(e.output),
|
|
1618
|
-
e.reasoningOutput != null && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
1619
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("br", {}),
|
|
1620
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("small", { children: [
|
|
1621
|
-
"\u63A8\u7406 ",
|
|
1622
|
-
fmt(e.reasoningOutput)
|
|
1623
|
-
] })
|
|
1624
|
-
] })
|
|
1625
|
-
] }),
|
|
1626
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { children: fmt(e.tokens) }),
|
|
1627
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RequestPerformance, { event: e }) }),
|
|
1628
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("td", { children: [
|
|
1629
|
-
e.outcome === "completed" ? "\u6210\u529F" : e.outcome === "cancelled" ? "\u5DF2\u53D6\u6D88" : "\u5931\u8D25",
|
|
1630
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("br", {}),
|
|
1631
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("small", { children: e.status })
|
|
1632
|
-
] })
|
|
1633
|
-
] }, e.at + ":" + current + ":" + i)) })
|
|
1634
|
-
] }),
|
|
1635
|
-
!events.length && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "empty", children: "\u5F53\u524D\u7B5B\u9009\u548C\u4FDD\u7559\u671F\u9650\u5185\u6CA1\u6709\u8BF7\u6C42\u660E\u7EC6\u3002" })
|
|
1636
|
-
] }),
|
|
1637
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bar table-footer", children: [
|
|
1638
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "notice", children: [
|
|
1639
|
-
"\u7B2C ",
|
|
1640
|
-
current + 1,
|
|
1641
|
-
" / ",
|
|
1642
|
-
pages,
|
|
1643
|
-
" \u9875 \xB7 \u6BCF\u9875 50 \u6761"
|
|
1644
|
-
] }),
|
|
1645
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "row", children: [
|
|
1646
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: current === 0, onClick: () => setPage(current - 1), children: "\u4E0A\u4E00\u9875" }),
|
|
1647
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: current >= pages - 1, onClick: () => setPage(current + 1), children: "\u4E0B\u4E00\u9875" })
|
|
1648
|
-
] })
|
|
1649
|
-
] })
|
|
1650
|
-
] })
|
|
1651
|
-
] });
|
|
1652
|
-
}
|
|
1653
|
-
function RequestPerformance({ event: e }) {
|
|
1654
|
-
const t = e.timing;
|
|
1655
|
-
if (!t) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("small", { children: "\u672A\u8BB0\u5F55" });
|
|
1656
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("details", { className: "help", children: [
|
|
1657
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("summary", { children: duration(t.modelMs) }),
|
|
1658
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { minWidth: 170 }, children: [
|
|
1659
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("small", { children: [
|
|
1660
|
-
"\u6A21\u578B\uFF1A",
|
|
1661
|
-
duration(t.modelMs)
|
|
1662
|
-
] }),
|
|
1663
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("small", { children: [
|
|
1664
|
-
"\u9996 Token\uFF1A",
|
|
1665
|
-
duration(t.ttftMs)
|
|
1666
|
-
] }),
|
|
1667
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("small", { children: [
|
|
1668
|
-
"TPS\uFF1A",
|
|
1669
|
-
t.decodeMs > 0 && t.decodeTokens != null ? `${fmt(t.decodeTokens / (t.decodeMs / 1e3))} tok/s` : "\u2014"
|
|
1670
|
-
] }),
|
|
1671
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("small", { children: [
|
|
1672
|
-
"\u5DE5\u5177\uFF1A",
|
|
1673
|
-
duration(t.toolMs),
|
|
1674
|
-
t.toolCount != null ? ` \xB7 ${t.toolsCompleted} / ${t.toolCount} \u5B8C\u6210` : ""
|
|
1675
|
-
] }),
|
|
1676
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("small", { children: e.timingSource === "dsh-step" ? "DSH \u6B65\u9AA4\u8BA1\u65F6" : "\u4E0A\u6E38\u8BF7\u6C42\u8BA1\u65F6" })
|
|
1677
|
-
] })
|
|
1678
|
-
] });
|
|
1679
|
-
}
|
|
1680
|
-
function AccountForm({ modal, provider, data, busy, act, close, replace, error, notice }) {
|
|
1681
|
-
const [revision, setRevision] = (0, import_react.useState)(modal.revision);
|
|
1682
|
-
const edit = modal.mode === "edit", account = edit ? data.accounts.find((a) => a.id === modal.account.id) : null;
|
|
1683
|
-
return edit ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "modal-body stack", children: [
|
|
1684
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Feedback, { error, notice }),
|
|
1685
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "box stack", children: [
|
|
1686
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { children: account.name }),
|
|
1687
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: loginNames[account.login?.state] || "\u5C1A\u672A\u67E5\u8BE2" }),
|
|
1688
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "notice", children: [
|
|
1689
|
-
"\u8D26\u53F7\u8EAB\u4EFD\uFF1A",
|
|
1690
|
-
account.login?.name || "\u5C1A\u672A\u83B7\u53D6",
|
|
1691
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("br", {}),
|
|
1692
|
-
"\u8BA4\u8BC1\u65B9\u5F0F\uFF1A",
|
|
1693
|
-
account.login?.kind || "\u672A\u77E5",
|
|
1694
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("br", {}),
|
|
1695
|
-
"\u767B\u5F55\u6709\u6548\u81F3\uFF1A",
|
|
1696
|
-
account.login?.kind === "PAT" ? "\u5E73\u53F0\u672A\u8FD4\u56DE\u6709\u6548\u671F" : when(account.login?.expiresAt),
|
|
1697
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("br", {}),
|
|
1698
|
-
"\u81EA\u52A8\u5237\u65B0\uFF1A",
|
|
1699
|
-
account.login?.refreshable ? "\u652F\u6301" : "\u65E0\u5237\u65B0\u51ED\u8BC1",
|
|
1700
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("br", {}),
|
|
1701
|
-
"\u4E0A\u6B21\u7528\u91CF\u66F4\u65B0\uFF1A",
|
|
1702
|
-
when(account.usage?.balance?.fetchedAt)
|
|
1703
|
-
] }),
|
|
1704
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: busy, onClick: () => {
|
|
1705
|
-
void act({ action: "account.refresh", id: account.id });
|
|
1706
|
-
}, children: "\u5237\u65B0\u767B\u5F55\u4E0E\u7528\u91CF" }),
|
|
1707
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: busy, onClick: replace, children: "\u8865\u5145 / \u66F4\u65B0\u51ED\u8BC1" })
|
|
1708
|
-
] }),
|
|
1709
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bar", children: [
|
|
1710
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
1711
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { children: "\u8DEF\u7531\u8D26\u53F7\u987A\u5E8F" }),
|
|
1712
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u6545\u969C\u5207\u6362\u6309\u6B64\u987A\u5E8F\u5C1D\u8BD5\uFF1B\u6743\u91CD\u6216\u989D\u5EA6\u7B56\u7565\u4EE5\u8DEF\u7531\u914D\u7F6E\u4E3A\u51C6\u3002" })
|
|
1713
|
-
] }),
|
|
1714
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "row", children: [-1, 1].map((direction) => {
|
|
1715
|
-
const group = data.accounts.filter((a) => a.provider === account.provider), i = group.findIndex((a) => a.id === account.id);
|
|
1716
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", disabled: busy || (direction < 0 ? i === 0 : i === group.length - 1), onClick: async () => {
|
|
1717
|
-
const next = await act({ action: "account.move", id: account.id, direction });
|
|
1718
|
-
if (next) setRevision(next.revision);
|
|
1719
|
-
}, children: direction < 0 ? "\u524D\u79FB" : "\u540E\u79FB" }, direction);
|
|
1720
|
-
}) })
|
|
1721
|
-
] }),
|
|
1722
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(CredentialTransfer, { account, busy, act }),
|
|
1723
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "box", children: [
|
|
1724
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { children: "\u5E73\u53F0\u5957\u9910\u4E0E\u989D\u5EA6" }),
|
|
1725
|
-
account.usage?.balance?.plan && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: account.usage.balance.plan }),
|
|
1726
|
-
(account.usage?.balance?.packages || []).map((p, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "item", children: [
|
|
1727
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bar", children: [
|
|
1728
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: p.name || "\u989D\u5EA6\u5305" }),
|
|
1729
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: p.unlimited ? "\u4E0D\u9650\u91CF" : `${fmt(p.remaining)} / ${fmt(p.total)}` })
|
|
1730
|
-
] }),
|
|
1731
|
-
p.expiresAt && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "notice", children: [
|
|
1732
|
-
"\u6709\u6548\u81F3 ",
|
|
1733
|
-
when(p.expiresAt)
|
|
1734
|
-
] })
|
|
1735
|
-
] }, i)),
|
|
1736
|
-
!account.usage?.balance?.packages?.length && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u5C1A\u65E0\u53EF\u5C55\u793A\u989D\u5EA6\u5305\uFF0C\u70B9\u51FB\u5237\u65B0\u83B7\u53D6\u3002" })
|
|
1737
|
-
] }),
|
|
1738
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("form", { className: "stack", onSubmit: async (e) => {
|
|
1739
|
-
e.preventDefault();
|
|
1740
|
-
if (await act({ action: "account.update", revision, id: account.id, name: new FormData(e.currentTarget).get("name") })) close();
|
|
1741
|
-
}, children: [
|
|
1742
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [
|
|
1743
|
-
"\u8D26\u53F7\u663E\u793A\u540D\u79F0",
|
|
1744
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { name: "name", required: true, defaultValue: account.name, maxLength: 100, disabled: busy })
|
|
1745
|
-
] }),
|
|
1746
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bar", children: [
|
|
1747
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", disabled: busy, onClick: async () => {
|
|
1748
|
-
if (await act({ action: "account.remove", id: account.id })) close();
|
|
1749
|
-
}, children: "\u79FB\u51FA\u8D26\u53F7\u6C60" }),
|
|
1750
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { className: "primary", type: "submit", disabled: busy, children: "\u4FDD\u5B58\u540D\u79F0" })
|
|
1751
|
-
] }),
|
|
1752
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u79FB\u51FA\u8D26\u53F7\u6C60\u540E\u4FDD\u7559\u51ED\u8BC1\u6587\u4EF6\uFF0C\u53EF\u4ECE\u6587\u4EF6\u91CD\u65B0\u5BFC\u5165\u3002" })
|
|
1753
|
-
] })
|
|
1754
|
-
] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CredentialForm, { modal, provider, data, busy, act, close, error, notice }, modal.mode);
|
|
1755
|
-
}
|
|
1756
|
-
function CredentialTransfer({ account, busy, act }) {
|
|
1757
|
-
const container = (0, import_react.useRef)(null), [pending, setPending] = (0, import_react.useState)(false), [notice, setNotice] = (0, import_react.useState)(""), [error, setError] = (0, import_react.useState)(""), [manual, setManual] = (0, import_react.useState)("");
|
|
1758
|
-
async function extract(copy) {
|
|
1759
|
-
if (pending || busy) return;
|
|
1760
|
-
setPending(true);
|
|
1761
|
-
setNotice("");
|
|
1762
|
-
setError("");
|
|
1763
|
-
setManual("");
|
|
1764
|
-
try {
|
|
1765
|
-
const result = await act({ action: "account.export", id: account.id });
|
|
1766
|
-
if (!result) return;
|
|
1767
|
-
if (!copy) {
|
|
1768
|
-
downloadJson(result.exported);
|
|
1769
|
-
setNotice("\u5DF2\u53D1\u8D77\u51ED\u8BC1 JSON \u4E0B\u8F7D\uFF0C\u5728\u5176\u4ED6\u8BBE\u5907\u6DFB\u52A0\u8D26\u53F7\u65F6\u9009\u62E9\u8BE5\u6587\u4EF6\u5373\u53EF\u3002");
|
|
1770
|
-
return;
|
|
1771
|
-
}
|
|
1772
|
-
const text = JSON.stringify(result.exported.document, null, 2);
|
|
1773
|
-
try {
|
|
1774
|
-
await navigator.clipboard.writeText(text);
|
|
1775
|
-
} catch {
|
|
1776
|
-
const focus = document.activeElement, area = document.createElement("textarea");
|
|
1777
|
-
area.value = text;
|
|
1778
|
-
area.style.cssText = "position:fixed;opacity:0;pointer-events:none";
|
|
1779
|
-
container.current.append(area);
|
|
1780
|
-
area.select();
|
|
1781
|
-
let copied = false;
|
|
1782
|
-
try {
|
|
1783
|
-
copied = document.execCommand("copy");
|
|
1784
|
-
} catch {
|
|
1785
|
-
} finally {
|
|
1786
|
-
area.remove();
|
|
1787
|
-
focus?.focus();
|
|
1788
|
-
}
|
|
1789
|
-
if (!copied) {
|
|
1790
|
-
setManual(text);
|
|
1791
|
-
setNotice("\u5F53\u524D\u73AF\u5883\u4E0D\u5141\u8BB8\u81EA\u52A8\u590D\u5236\uFF0C\u8BF7\u70B9\u51FB\u4E0B\u65B9\u6587\u672C\u6846\u5168\u9009\u5E76\u590D\u5236\u3002");
|
|
1792
|
-
return;
|
|
1793
|
-
}
|
|
1794
|
-
}
|
|
1795
|
-
setNotice("\u51ED\u8BC1 JSON \u5DF2\u590D\u5236\uFF0C\u53EF\u5728\u5176\u4ED6\u8BBE\u5907\u6DFB\u52A0\u8D26\u53F7\u65F6\u76F4\u63A5\u7C98\u8D34\u3002");
|
|
1796
|
-
} catch {
|
|
1797
|
-
setError("\u51ED\u8BC1\u63D0\u53D6\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5\u3002");
|
|
1798
|
-
} finally {
|
|
1799
|
-
setPending(false);
|
|
1800
|
-
}
|
|
1801
|
-
}
|
|
1802
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { ref: container, className: "box stack", children: [
|
|
1803
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { children: "\u51ED\u8BC1\u63D0\u53D6\u4E0E\u8DE8\u8BBE\u5907\u4F7F\u7528" }),
|
|
1804
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u5355\u8D26\u53F7 JSON \u5305\u542B\u767B\u5F55 Token / PAT\uFF0CTrae \u540C\u65F6\u5305\u542B\u5FC5\u8981\u8BBE\u5907\u8EAB\u4EFD\u3002\u590D\u5236\u53CA\u6B64\u5904\u5BFC\u51FA\u4E3A\u660E\u6587\uFF0C\u8BF7\u4EC5\u5728\u81EA\u5DF1\u7684\u8BBE\u5907\u95F4\u4F20\u9012\uFF1B\u9700\u8981\u52A0\u5BC6\u65F6\u4F7F\u7528\u300C\u914D\u7F6E\u8FC1\u79FB\u300D\u3002" }),
|
|
1805
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "row", children: [
|
|
1806
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", disabled: busy || pending, onClick: () => {
|
|
1807
|
-
void extract(true);
|
|
1808
|
-
}, children: "\u590D\u5236\u51ED\u8BC1 JSON" }),
|
|
1809
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", disabled: busy || pending, onClick: () => {
|
|
1810
|
-
void extract(false);
|
|
1811
|
-
}, children: "\u5BFC\u51FA\u51ED\u8BC1 JSON" })
|
|
1812
|
-
] }),
|
|
1813
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Feedback, { error, notice }),
|
|
1814
|
-
manual && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [
|
|
1815
|
-
"\u624B\u52A8\u590D\u5236\u51ED\u8BC1 JSON",
|
|
1816
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("textarea", { readOnly: true, rows: "5", autoComplete: "off", spellCheck: "false", value: manual, onFocus: (e) => e.currentTarget.select() })
|
|
1817
|
-
] }),
|
|
1818
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u65B0\u8BBE\u5907\uFF1A\u6DFB\u52A0\u8D26\u53F7 \u2192 \u7C98\u8D34 / \u9009\u62E9\u51ED\u8BC1 JSON \u2192 \u4FDD\u5B58\u3002\u5E73\u53F0\u8981\u6C42\u91CD\u65B0\u767B\u5F55\u65F6\uFF0C\u9700\u66F4\u65B0\u51ED\u8BC1\u3002" })
|
|
1819
|
-
] });
|
|
1820
|
-
}
|
|
1821
|
-
function CredentialForm({ modal, provider, data, busy, act, close, error, notice }) {
|
|
1822
|
-
const replacing = modal.mode === "credentials";
|
|
1823
|
-
const [selected, setSelected] = (0, import_react.useState)(modal.account?.provider || provider), [mode, setMode] = (0, import_react.useState)("client"), [localError, setLocalError] = (0, import_react.useState)(""), [json, setJson] = (0, import_react.useState)("");
|
|
1824
|
-
const [edition, setEdition] = (0, import_react.useState)(modal.account?.login?.edition || "auto");
|
|
1825
|
-
const [phone, setPhone] = (0, import_react.useState)(""), [smsCode, setSmsCode] = (0, import_react.useState)(""), [sms, setSms] = (0, import_react.useState)(null), [verify, setVerify] = (0, import_react.useState)(true), [clock, setClock] = (0, import_react.useState)(Date.now());
|
|
1826
|
-
(0, import_react.useEffect)(() => {
|
|
1827
|
-
if (mode !== "sms") return;
|
|
1828
|
-
const timer = setInterval(() => setClock(Date.now()), 1e3);
|
|
1829
|
-
return () => clearInterval(timer);
|
|
1830
|
-
}, [mode]);
|
|
1831
|
-
const resend = Math.max(0, Math.ceil(((sms?.resendAt || 0) - clock) / 1e3));
|
|
1832
|
-
const isTrae = selected.startsWith("trae"), isQoder = selected.startsWith("qoder"), global = selected === "trae-global" || selected === "workbuddy-ai" || selected === "qoder-global";
|
|
1833
|
-
const field = (label, name2, type = "text", required = true, value) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [
|
|
1834
|
-
label,
|
|
1835
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { name: name2, type, autoComplete: "off", required, defaultValue: value, disabled: busy })
|
|
1836
|
-
] });
|
|
1837
|
-
function receiveJson(text) {
|
|
1838
|
-
setJson(text);
|
|
1839
|
-
setLocalError("");
|
|
1840
|
-
try {
|
|
1841
|
-
const parsed = JSON.parse(text);
|
|
1842
|
-
if (!replacing && parsed.format === "dsh-multi-router-account" && data.providers.some((p) => p.id === parsed.provider)) {
|
|
1843
|
-
setSelected(parsed.provider);
|
|
1844
|
-
setEdition(parsed.credential?.edition || (parsed.provider === "trae-global" ? "sg" : "cn"));
|
|
1845
|
-
}
|
|
1846
|
-
} catch {
|
|
1847
|
-
}
|
|
1848
|
-
}
|
|
1849
|
-
async function submit(e) {
|
|
1850
|
-
e.preventDefault();
|
|
1851
|
-
setLocalError("");
|
|
1852
|
-
const f = Object.fromEntries(new FormData(e.currentTarget));
|
|
1853
|
-
if (mode === "sms") {
|
|
1854
|
-
const result = await act({ action: "workbuddy.login", revision: data.revision, challenge: sms?.challenge, code: smsCode, verify, id: replacing ? modal.account.id : void 0, name: f.name || void 0 });
|
|
1855
|
-
if (result) {
|
|
1856
|
-
setPhone("");
|
|
1857
|
-
setSmsCode("");
|
|
1858
|
-
setSms(null);
|
|
1859
|
-
close(selected);
|
|
1860
|
-
}
|
|
1861
|
-
return;
|
|
1862
|
-
}
|
|
1863
|
-
let document2, identityDocument;
|
|
1864
|
-
try {
|
|
1865
|
-
if (mode === "json") {
|
|
1866
|
-
document2 = JSON.parse(json);
|
|
1867
|
-
if (f.identityJSON?.trim()) identityDocument = JSON.parse(f.identityJSON);
|
|
1868
|
-
}
|
|
1869
|
-
if (mode === "manual") {
|
|
1870
|
-
if (isQoder) document2 = { version: 2, pat: f.pat.trim(), region: global ? "global" : "china" };
|
|
1871
|
-
else {
|
|
1872
|
-
const credential = {
|
|
1873
|
-
accessToken: f.accessToken.trim(),
|
|
1874
|
-
...f.refreshToken?.trim() ? { refreshToken: f.refreshToken.trim() } : {},
|
|
1875
|
-
expiresAtMs: new Date(f.expiresAt).getTime(),
|
|
1876
|
-
...f.refreshExpiresAt ? { refreshExpiresAtMs: new Date(f.refreshExpiresAt).getTime() } : {},
|
|
1877
|
-
...isTrae ? { userId: f.identityId.trim(), edition, host: global ? "https://growsg-normal.trae.ai" : "https://api.trae.cn" } : { uid: f.identityId.trim(), domain: f.domain.trim() }
|
|
1878
|
-
};
|
|
1879
|
-
document2 = { version: 1, credential };
|
|
1880
|
-
if (isTrae) identityDocument = { edition, machineId: f.machineId.trim(), deviceId: f.deviceId.trim() };
|
|
1881
|
-
}
|
|
1882
|
-
}
|
|
1883
|
-
} catch {
|
|
1884
|
-
setLocalError("JSON \u683C\u5F0F\u65E0\u6548\uFF0C\u8BF7\u68C0\u67E5\u51ED\u8BC1\u53CA\u8BBE\u5907\u8EAB\u4EFD JSON\u3002");
|
|
1885
|
-
return;
|
|
1886
|
-
}
|
|
1887
|
-
const action = replacing ? "account.credentials" : "account.capture";
|
|
1888
|
-
if (await act({
|
|
1889
|
-
action,
|
|
1890
|
-
revision: modal.revision,
|
|
1891
|
-
id: modal.account?.id,
|
|
1892
|
-
provider: selected,
|
|
1893
|
-
edition,
|
|
1894
|
-
name: f.name || (document2?.format === "dsh-multi-router-account" ? document2.name : void 0),
|
|
1895
|
-
...document2 ? { document: document2, identityDocument } : { source: f.source || void 0, identity: f.identity || void 0 }
|
|
1896
|
-
})) {
|
|
1897
|
-
setJson("");
|
|
1898
|
-
close(selected);
|
|
1899
|
-
}
|
|
1900
|
-
}
|
|
1901
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("form", { onSubmit: submit, children: [
|
|
1902
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "modal-body stack", children: [
|
|
1903
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Feedback, { error: localError || error, notice }),
|
|
1904
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "grid", children: [
|
|
1905
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [
|
|
1906
|
-
"\u4F9B\u5E94\u5546 / \u533A\u57DF",
|
|
1907
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("select", { disabled: busy || replacing, value: selected, onChange: (e) => {
|
|
1908
|
-
setSelected(e.target.value);
|
|
1909
|
-
setEdition("auto");
|
|
1910
|
-
setMode("client");
|
|
1911
|
-
setJson("");
|
|
1912
|
-
setLocalError("");
|
|
1913
|
-
setSms(null);
|
|
1914
|
-
setSmsCode("");
|
|
1915
|
-
setPhone("");
|
|
1916
|
-
}, children: data.providers.map((p) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: p.id, children: p.name }, p.id)) })
|
|
1917
|
-
] }),
|
|
1918
|
-
field("\u8D26\u53F7\u540D\u79F0\uFF08\u53EF\u9009\uFF09", "name", "text", false, modal.account?.name),
|
|
1919
|
-
isTrae && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [
|
|
1920
|
-
"\u767B\u5F55\u7684\u5BA2\u6237\u7AEF",
|
|
1921
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("select", { value: edition, disabled: busy, onChange: (e) => setEdition(e.target.value), children: (mode === "client" ? [["auto", "\u81EA\u52A8\u8BC6\u522B\uFF08\u63A8\u8350\uFF09"], ...global ? [["sg", "Trae Global"], ["solo-sg", "TRAE SOLO Global"]] : [["cn", "Trae CN"], ["solo", "TRAE SOLO CN"]]] : global ? [["sg", "Trae Global"], ["solo-sg", "TRAE SOLO Global"]] : [["cn", "Trae CN"], ["solo", "TRAE SOLO CN"]]).map(([id, label]) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: id, children: label }, id)) })
|
|
1922
|
-
] })
|
|
1923
|
-
] }),
|
|
1924
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [
|
|
1925
|
-
"\u51ED\u8BC1\u6DFB\u52A0\u65B9\u5F0F",
|
|
1926
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", { disabled: busy, value: mode, onChange: (e) => {
|
|
1927
|
-
setMode(e.target.value);
|
|
1928
|
-
if (e.target.value !== "client" && edition === "auto") setEdition(global ? "sg" : "cn");
|
|
1929
|
-
setJson("");
|
|
1930
|
-
setLocalError("");
|
|
1931
|
-
}, children: [
|
|
1932
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "client", children: "\u4E00\u952E\u8BFB\u53D6\u672C\u673A\u767B\u5F55" }),
|
|
1933
|
-
selected === "workbuddy" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "sms", children: "\u77ED\u4FE1\u767B\u5F55\u5E76\u4FDD\u5B58\u51ED\u8BC1" }),
|
|
1934
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("option", { value: "manual", children: [
|
|
1935
|
-
"\u624B\u52A8\u586B\u5199",
|
|
1936
|
-
isQoder ? " PAT" : "\u51ED\u8BC1"
|
|
1937
|
-
] }),
|
|
1938
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "json", children: "\u7C98\u8D34 / \u9009\u62E9\u51ED\u8BC1 JSON" })
|
|
1939
|
-
] })
|
|
1940
|
-
] }),
|
|
1941
|
-
mode === "sms" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "steps stack", children: [
|
|
1942
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { children: "WorkBuddy \u624B\u673A\u53F7\u767B\u5F55" }),
|
|
1943
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u4EC5\u7528\u4E8E\u5DF2\u6709\u4E2D\u56FD\u7248\u8D26\u53F7\u3002\u624B\u673A\u53F7\u548C\u9A8C\u8BC1\u7801\u63D0\u4EA4\u81F3 WorkBuddy \u5B98\u65B9\uFF0C\u51ED\u8BC1\u4EC5\u4FDD\u5B58\u5728\u672C\u673A\uFF0C\u65E0\u9700\u5B89\u88C5 Python\u3002" }),
|
|
1944
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [
|
|
1945
|
-
"\u624B\u673A\u53F7",
|
|
1946
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "tel", inputMode: "tel", autoComplete: "tel", required: true, pattern: "1[3-9][0-9]{9}", maxLength: "11", value: phone, disabled: busy || resend > 0, onChange: (e) => {
|
|
1947
|
-
setPhone(e.target.value);
|
|
1948
|
-
setSms(null);
|
|
1949
|
-
setSmsCode("");
|
|
1950
|
-
} })
|
|
1951
|
-
] }),
|
|
1952
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "row", children: [
|
|
1953
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", disabled: busy || resend > 0 || !/^1[3-9]\d{9}$/.test(phone), onClick: async () => {
|
|
1954
|
-
const next = await act({ action: "workbuddy.sms", phone });
|
|
1955
|
-
if (next) {
|
|
1956
|
-
setSms(next.workbuddyLogin);
|
|
1957
|
-
setClock(Date.now());
|
|
1958
|
-
setSmsCode("");
|
|
1959
|
-
}
|
|
1960
|
-
}, children: resend ? `${resend} \u79D2\u540E\u53EF\u91CD\u53D1` : sms ? "\u91CD\u65B0\u53D1\u9001\u9A8C\u8BC1\u7801" : "\u53D1\u9001\u9A8C\u8BC1\u7801" }),
|
|
1961
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "notice", role: "status", children: sms ? clock >= sms.expiresAt ? "\u9A8C\u8BC1\u7801\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u91CD\u65B0\u83B7\u53D6" : "\u9A8C\u8BC1\u7801\u5DF2\u53D1\u9001\uFF0C\u8BF7\u67E5\u770B\u77ED\u4FE1" : "\u70B9\u51FB\u53D1\u9001\u624D\u4F1A\u8BF7\u6C42\u77ED\u4FE1\uFF0C\u4E0D\u81EA\u52A8\u91CD\u8BD5" })
|
|
1962
|
-
] }),
|
|
1963
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [
|
|
1964
|
-
"\u77ED\u4FE1\u9A8C\u8BC1\u7801",
|
|
1965
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "text", inputMode: "numeric", autoComplete: "one-time-code", required: true, pattern: "[0-9]{4,8}", maxLength: "8", value: smsCode, disabled: busy || !sms, onChange: (e) => setSmsCode(e.target.value) })
|
|
1966
|
-
] }),
|
|
1967
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "check", children: [
|
|
1968
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "checkbox", checked: verify, disabled: busy, onChange: (e) => setVerify(e.target.checked) }),
|
|
1969
|
-
"\u767B\u5F55\u540E\u9A8C\u8BC1\u5237\u65B0\u4EE4\u724C\uFF08\u63A8\u8350\uFF09"
|
|
1970
|
-
] }),
|
|
1971
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u540C\u4E00\u8D26\u53F7\u66F4\u65B0\u51ED\u8BC1\uFF0C\u65B0\u8D26\u53F7\u72EC\u7ACB\u4FDD\u5B58\uFF1B\u4E0D\u4F1A\u5F00\u542F\u81EA\u52A8\u7B7E\u5230\u3002\u9047\u5E73\u53F0\u9A8C\u8BC1\u6216\u9650\u5236\uFF0C\u8BF7\u6539\u7528\u672C\u673A\u5BA2\u6237\u7AEF\u8BFB\u53D6\u3002" })
|
|
1972
|
-
] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "steps stack", children: [
|
|
1973
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { children: "\u83B7\u53D6\u51ED\u8BC1\u5F15\u5BFC" }),
|
|
1974
|
-
isQoder ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: "\u5728\u5BF9\u5E94\u56FD\u5185 / \u56FD\u9645\u7AD9\u7684\u8D26\u53F7\u8BBE\u7F6E\u4E2D\u521B\u5EFA PAT\uFF0C\u7136\u540E\u9009\u62E9\u300C\u624B\u52A8\u586B\u5199 PAT\u300D\u7C98\u8D34\u3002\u5DF2\u6709\u65E7\u8FDE\u63A5\u5668\u767B\u5F55\u65F6\uFF0C\u53EF\u4E00\u952E\u8BFB\u53D6\u672C\u673A\u4FDD\u5B58\u7684 PAT\u3002\u7F51\u9875\u767B\u5F55 Cookie \u4E0D\u4F5C\u4E3A PAT \u4F7F\u7528\u3002" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { children: [
|
|
1975
|
-
"1. \u5728\u6240\u9009\u533A\u57DF\u7684\u5B98\u65B9\u5BA2\u6237\u7AEF\u767B\u5F55\u8D26\u53F7\u3002",
|
|
1976
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("br", {}),
|
|
1977
|
-
"2. \u56DE\u5230\u672C\u9762\u677F\uFF0C\u9009\u62E9\u300C\u4E00\u952E\u8BFB\u53D6\u672C\u673A\u767B\u5F55\u300D\u5E76\u70B9\u51FB\u5E95\u90E8\u6309\u94AE\u3002",
|
|
1978
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("br", {}),
|
|
1979
|
-
"3. \u6DFB\u52A0\u53E6\u4E00\u4E2A\u8D26\u53F7\u65F6\uFF0C\u5148\u5728\u5BA2\u6237\u7AEF\u5207\u6362\u767B\u5F55\uFF0C\u518D\u91CD\u590D\u8BFB\u53D6\uFF1B\u5DF2\u6DFB\u52A0\u7684\u8D26\u53F7\u4F1A\u4FDD\u7559\u72EC\u7ACB\u526F\u672C\u3002"
|
|
1980
|
-
] }),
|
|
1981
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "row", children: isQoder ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
1982
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", { className: "link", href: "https://docs.qoder.com/cli/authentication", target: "_blank", rel: "noreferrer", children: "\u5B98\u65B9 PAT \u83B7\u53D6\u8BF4\u660E" }),
|
|
1983
|
-
global && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", { className: "link", href: "https://qoder.com/account/integrations", target: "_blank", rel: "noreferrer", children: "\u6253\u5F00 PAT \u7BA1\u7406\u9875" })
|
|
1984
|
-
] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", { className: "link", href: isTrae ? global ? "https://www.trae.ai/" : "https://www.trae.cn/" : global ? "https://www.codebuddy.ai/" : "https://www.codebuddy.cn/", target: "_blank", rel: "noreferrer", children: "\u6253\u5F00\u5B98\u65B9\u5BA2\u6237\u7AEF\u7F51\u7AD9" }) }),
|
|
1985
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u8DE8\u8BBE\u5907\u5DF2\u6709\u51ED\u8BC1\u6587\u4EF6\u65F6\u53EF\u9009\u62E9 JSON\uFF1BWorkBuddy \u9700\u8981 accessToken\u3001uid\u3001domain\u3001expiresAtMs\uFF1BTrae \u8FD8\u9700\u8981 userId\u3001edition\uFF0C\u4EE5\u53CA\u540C\u8D26\u53F7\u7684 machineId / deviceId\u3002\u63A8\u8350\u8BFB\u53D6\u5BA2\u6237\u7AEF\u6216\u4F7F\u7528\u52A0\u5BC6\u914D\u7F6E\u8FC1\u79FB\uFF0C\u4E0D\u9700\u8981\u731C\u6D4B\u5B57\u6BB5\u3002" })
|
|
1986
|
-
] }),
|
|
1987
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "stack", children: [
|
|
1988
|
-
mode === "manual" && (isQoder ? field("Qoder PAT", "pat", "password") : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "grid", children: [
|
|
1989
|
-
field("Access Token", "accessToken", "password"),
|
|
1990
|
-
field("Refresh Token\uFF08\u53EF\u9009\uFF09", "refreshToken", "password", false),
|
|
1991
|
-
field(isTrae ? "User ID" : "UID", "identityId"),
|
|
1992
|
-
field("Access Token \u6709\u6548\u81F3", "expiresAt", "datetime-local"),
|
|
1993
|
-
field("Refresh Token \u6709\u6548\u81F3\uFF08\u53EF\u9009\uFF09", "refreshExpiresAt", "datetime-local", false),
|
|
1994
|
-
!isTrae && field("\u767B\u5F55 Domain", "domain", "text", false, global ? "www.codebuddy.ai" : "www.codebuddy.cn"),
|
|
1995
|
-
isTrae && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
1996
|
-
field("Machine ID", "machineId"),
|
|
1997
|
-
field("Device ID", "deviceId")
|
|
1998
|
-
] })
|
|
1999
|
-
] })),
|
|
2000
|
-
mode === "json" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
2001
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u672C\u63D2\u4EF6\u590D\u5236 / \u5BFC\u51FA\u7684\u5355\u8D26\u53F7 JSON \u4F1A\u81EA\u52A8\u8BC6\u522B\u4F9B\u5E94\u5546\u3001\u533A\u57DF\u53CA\u8D26\u53F7\u540D\u79F0\uFF1BTrae \u8BBE\u5907\u8EAB\u4EFD\u968F\u6587\u4EF6\u5BFC\u5165\u3002" }),
|
|
2002
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [
|
|
2003
|
-
"\u9009\u62E9\u51ED\u8BC1 JSON \u6587\u4EF6",
|
|
2004
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "file", accept: ".json,application/json", disabled: busy, onChange: async (e) => {
|
|
2005
|
-
const file = e.target.files?.[0];
|
|
2006
|
-
if (!file) return;
|
|
2007
|
-
if (file.size > 256 * 1024) {
|
|
2008
|
-
setLocalError("\u51ED\u8BC1\u6587\u4EF6\u4E0D\u80FD\u8D85\u8FC7 256 KB");
|
|
2009
|
-
return;
|
|
2010
|
-
}
|
|
2011
|
-
try {
|
|
2012
|
-
receiveJson(await file.text());
|
|
2013
|
-
} catch {
|
|
2014
|
-
setLocalError("\u65E0\u6CD5\u8BFB\u53D6\u6587\u4EF6");
|
|
2015
|
-
}
|
|
2016
|
-
} })
|
|
2017
|
-
] }),
|
|
2018
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [
|
|
2019
|
-
"\u51ED\u8BC1 JSON",
|
|
2020
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("textarea", { rows: "7", required: true, autoComplete: "off", spellCheck: "false", disabled: busy, value: json, onChange: (e) => receiveJson(e.target.value), placeholder: isQoder ? '{"pat":"\u2026","region":"china"}' : '{"version":1,"credential":{"accessToken":"\u2026", "expiresAtMs":\u2026}}' })
|
|
2021
|
-
] }),
|
|
2022
|
-
isTrae && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [
|
|
2023
|
-
"Trae \u8BBE\u5907\u8EAB\u4EFD JSON\uFF08\u51ED\u8BC1\u4E2D\u5DF2\u6709 identity \u65F6\u53EF\u7559\u7A7A\uFF09",
|
|
2024
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("textarea", { name: "identityJSON", rows: "3", disabled: busy, autoComplete: "off", placeholder: '{"edition":"cn","machineId":"\u2026","deviceId":"\u2026"}' })
|
|
2025
|
-
] })
|
|
2026
|
-
] }),
|
|
2027
|
-
mode === "client" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("details", { children: [
|
|
2028
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("summary", { children: "\u9AD8\u7EA7\uFF1A\u6307\u5B9A\u767B\u5F55\u6587\u4EF6\u4F4D\u7F6E" }),
|
|
2029
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "stack", style: { marginTop: 12 }, children: [
|
|
2030
|
-
field("\u767B\u5F55 / PAT \u6587\u4EF6\u8DEF\u5F84\uFF08\u9ED8\u8BA4\u81EA\u52A8\u67E5\u627E\uFF09", "source", "text", false),
|
|
2031
|
-
isTrae && field("Trae \u8BBE\u5907\u8EAB\u4EFD\u6587\u4EF6\u8DEF\u5F84\uFF08\u53EF\u9009\uFF09", "identity", "text", false)
|
|
2032
|
-
] })
|
|
2033
|
-
] })
|
|
2034
|
-
] }, `${selected}:${mode}`),
|
|
2035
|
-
mode !== "sms" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "notice", children: [
|
|
2036
|
-
"\u51ED\u8BC1\u4EC5\u4FDD\u5B58\u5230\u672C\u673A\u63D2\u4EF6\u8D26\u53F7\u6C60\u3002\u4E0D\u4F1A\u5728\u8D26\u53F7\u5217\u8868\u663E\u793A Token\uFF1B\u6BCF\u4E2A\u8D26\u53F7\u72EC\u7ACB\u5237\u65B0\u3002",
|
|
2037
|
-
replacing ? "\u4FDD\u5B58\u540E\u542F\u7528\u6B64\u8D26\u53F7\uFF0C\u539F\u51ED\u8BC1\u526F\u672C\u4FDD\u7559\u3002" : "\u91CD\u590D\u8BFB\u53D6\u540C\u4E00\u8D26\u53F7\u4F1A\u63D0\u793A\u3002"
|
|
2038
|
-
] })
|
|
2039
|
-
] }),
|
|
2040
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "modal-foot bar", children: [
|
|
2041
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", disabled: busy, onClick: close, children: "\u53D6\u6D88" }),
|
|
2042
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { className: "primary", type: "submit", disabled: busy || mode === "sms" && (!sms || clock >= sms.expiresAt), children: busy ? "\u6B63\u5728\u5904\u7406\u2026" : mode === "sms" ? "\u767B\u5F55\u5E76\u4FDD\u5B58\u5230\u8D26\u53F7\u6C60" : mode === "client" ? "\u4E00\u952E\u83B7\u53D6\u5E76\u4FDD\u5B58\u767B\u5F55" : "\u4FDD\u5B58\u51ED\u8BC1\u5E76\u83B7\u53D6\u6A21\u578B" })
|
|
2043
|
-
] })
|
|
2044
|
-
] });
|
|
2045
|
-
}
|
|
2046
|
-
function MigrationForm({ data, act, busy }) {
|
|
2047
|
-
const [panel, setPanel] = (0, import_react.useState)(null);
|
|
2048
|
-
const [include, setInclude] = (0, import_react.useState)(false), [exportPassword, setExportPassword] = (0, import_react.useState)(""), [confirmPassword, setConfirmPassword] = (0, import_react.useState)(""), [exportError, setExportError] = (0, import_react.useState)("");
|
|
2049
|
-
const [document2, setDocument] = (0, import_react.useState)(""), [fileName, setFileName] = (0, import_react.useState)(""), [password, setPassword] = (0, import_react.useState)(""), [mode, setMode] = (0, import_react.useState)("merge"), [preview, setPreview] = (0, import_react.useState)(null), [error, setError] = (0, import_react.useState)("");
|
|
2050
|
-
const resetPreview = () => {
|
|
2051
|
-
setPreview(null);
|
|
2052
|
-
setError("");
|
|
2053
|
-
};
|
|
2054
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "stack", children: [
|
|
2055
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
2056
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { children: "\u914D\u7F6E\u8FC1\u79FB" }),
|
|
2057
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u5728\u8BBE\u5907\u95F4\u8FC1\u79FB\u8D26\u53F7\u3001\u6A21\u578B\u548C\u8DEF\u7531\u8BBE\u7F6E\u3002" })
|
|
2058
|
-
] }),
|
|
2059
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("section", { className: "box table-shell", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("table", { className: "table", children: [
|
|
2060
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tr", { children: [
|
|
2061
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { scope: "col", children: "\u64CD\u4F5C" }),
|
|
2062
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { scope: "col", children: "\u5185\u5BB9" }),
|
|
2063
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { scope: "col", className: "cell-actions", children: "\u5F00\u59CB" })
|
|
2064
|
-
] }) }),
|
|
2065
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tbody", { children: [
|
|
2066
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tr", { children: [
|
|
2067
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: "\u5BFC\u51FA\u5230\u5176\u4ED6\u8BBE\u5907" }) }),
|
|
2068
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("td", { children: [
|
|
2069
|
-
"\u8D26\u53F7\u4E0E\u8DEF\u7531\u8BBE\u7F6E",
|
|
2070
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("small", { className: "muted", children: "\u53EF\u9009\u5BC6\u7801\u52A0\u5BC6\u643A\u5E26\u767B\u5F55\u51ED\u8BC1" })
|
|
2071
|
-
] }),
|
|
2072
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "cell-actions", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: busy, onClick: () => setPanel("export"), children: "\u5BFC\u51FA\u914D\u7F6E" }) })
|
|
2073
|
-
] }),
|
|
2074
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tr", { children: [
|
|
2075
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: "\u5BFC\u5165\u5DF2\u6709\u914D\u7F6E" }) }),
|
|
2076
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("td", { children: [
|
|
2077
|
-
"\u5148\u9884\u89C8\uFF0C\u518D\u786E\u8BA4\u5408\u5E76\u6216\u66FF\u6362",
|
|
2078
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("small", { className: "muted", children: "\u5BFC\u5165\u524D\u81EA\u52A8\u5907\u4EFD\u672C\u673A\u914D\u7F6E" })
|
|
2079
|
-
] }),
|
|
2080
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "cell-actions", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: busy, onClick: () => setPanel("import"), children: "\u5BFC\u5165\u914D\u7F6E" }) })
|
|
2081
|
-
] })
|
|
2082
|
-
] })
|
|
2083
|
-
] }) }),
|
|
2084
|
-
panel && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Modal, { title: panel === "export" ? "\u5BFC\u51FA\u914D\u7F6E" : "\u5BFC\u5165\u914D\u7F6E", busy, close: () => setPanel(null), children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "modal-body stack", children: [
|
|
2085
|
-
panel === "export" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("form", { className: "box stack", onSubmit: async (e) => {
|
|
2086
|
-
e.preventDefault();
|
|
2087
|
-
setExportError("");
|
|
2088
|
-
if (include && exportPassword !== confirmPassword) {
|
|
2089
|
-
setExportError("\u4E24\u6B21\u8FC1\u79FB\u5BC6\u7801\u4E0D\u4E00\u81F4");
|
|
2090
|
-
return;
|
|
2091
|
-
}
|
|
2092
|
-
const result = await act({ action: "config.export", includeCredentials: include, password: include ? exportPassword : void 0 });
|
|
2093
|
-
if (!result) return;
|
|
2094
|
-
downloadJson(result.exported);
|
|
2095
|
-
setExportPassword("");
|
|
2096
|
-
setConfirmPassword("");
|
|
2097
|
-
}, children: [
|
|
2098
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { children: "\u5BFC\u51FA\u5230\u5176\u4ED6\u8BBE\u5907" }),
|
|
2099
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u5305\u542B\u8D26\u53F7\u540D\u79F0\u548C\u987A\u5E8F\u3001\u6A21\u578B\u5C55\u793A\u8BBE\u7F6E\u3001\u8DEF\u7531\u4E0E\u5207\u6362\u89C4\u5219\u3002\u4E0D\u4F1A\u5BFC\u51FA\u4F1A\u8BDD\u3001\u7EDF\u8BA1\u3001\u6587\u4EF6\u8DEF\u5F84\u6216\u7BA1\u7406\u5BC6\u94A5\u3002" }),
|
|
2100
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "check", children: [
|
|
2101
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "checkbox", checked: include, disabled: busy, onChange: (e) => {
|
|
2102
|
-
setInclude(e.target.checked);
|
|
2103
|
-
setExportPassword("");
|
|
2104
|
-
setConfirmPassword("");
|
|
2105
|
-
} }),
|
|
2106
|
-
"\u540C\u65F6\u8FC1\u79FB\u8D26\u53F7\u767B\u5F55\u51ED\u8BC1\uFF08\u5BC6\u7801\u52A0\u5BC6\uFF09"
|
|
2107
|
-
] }),
|
|
2108
|
-
include ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
2109
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "steps", children: "\u52A0\u5BC6\u6587\u4EF6\u5305\u542B\u767B\u5F55 Token / PAT \u548C\u5FC5\u8981\u8BBE\u5907\u8EAB\u4EFD\uFF0C\u8BF7\u81EA\u884C\u4FDD\u7BA1\u3002\u65B0\u8BBE\u5907\u9700\u8981\u540C\u4E00\u5BC6\u7801\uFF1B\u51ED\u8BC1\u53EF\u80FD\u56E0\u5E73\u53F0\u8BBE\u5907\u9650\u5236\u800C\u9700\u8981\u91CD\u65B0\u767B\u5F55\u3002" }),
|
|
2110
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [
|
|
2111
|
-
"\u8BBE\u7F6E\u8FC1\u79FB\u5BC6\u7801",
|
|
2112
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "password", autoComplete: "new-password", required: true, minLength: "10", maxLength: "1024", value: exportPassword, disabled: busy, onChange: (e) => setExportPassword(e.target.value) })
|
|
2113
|
-
] }),
|
|
2114
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [
|
|
2115
|
-
"\u518D\u6B21\u8F93\u5165\u5BC6\u7801",
|
|
2116
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "password", autoComplete: "new-password", required: true, value: confirmPassword, disabled: busy, onChange: (e) => setConfirmPassword(e.target.value) })
|
|
2117
|
-
] })
|
|
2118
|
-
] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "steps", children: "\u4EC5\u914D\u7F6E\u6587\u4EF6\u4E0D\u542B\u767B\u5F55\u51ED\u8BC1\u3002\u65B0\u8BBE\u5907\u4E0A\u7684\u8D26\u53F7\u4F1A\u5148\u505C\u7528\uFF0C\u8865\u5145\u51ED\u8BC1\u540E\u5373\u53EF\u542F\u7528\uFF1B\u5408\u5E76\u5BFC\u5165\u4F1A\u4FDD\u7559\u672C\u673A\u5DF2\u6709\u8D26\u53F7\u51ED\u8BC1\u3002" }),
|
|
2119
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Feedback, { error: exportError }),
|
|
2120
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { className: "primary", type: "submit", disabled: busy, children: include ? "\u5BFC\u51FA\u52A0\u5BC6\u8FC1\u79FB\u6587\u4EF6" : "\u5BFC\u51FA\u914D\u7F6E JSON" })
|
|
2121
|
-
] }),
|
|
2122
|
-
panel === "import" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("form", { className: "box stack", onSubmit: async (e) => {
|
|
2123
|
-
e.preventDefault();
|
|
2124
|
-
setError("");
|
|
2125
|
-
const result = await act({ action: "config.preview", document: document2, password, mode });
|
|
2126
|
-
if (result) setPreview({ ...result.importPreview, revision: result.revision });
|
|
2127
|
-
}, children: [
|
|
2128
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { children: "\u5BFC\u5165\u63D2\u4EF6\u914D\u7F6E" }),
|
|
2129
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [
|
|
2130
|
-
"\u9009\u62E9\u8FC1\u79FB JSON \u6587\u4EF6",
|
|
2131
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "file", accept: ".json,application/json", required: true, disabled: busy, onChange: async (e) => {
|
|
2132
|
-
resetPreview();
|
|
2133
|
-
setPassword("");
|
|
2134
|
-
setDocument("");
|
|
2135
|
-
const file = e.target.files?.[0];
|
|
2136
|
-
if (!file) return;
|
|
2137
|
-
if (file.size > 900 * 1024) {
|
|
2138
|
-
setError("\u8FC1\u79FB\u6587\u4EF6\u4E0D\u80FD\u8D85\u8FC7 900 KB");
|
|
2139
|
-
return;
|
|
2140
|
-
}
|
|
2141
|
-
try {
|
|
2142
|
-
setDocument(await file.text());
|
|
2143
|
-
setFileName(file.name);
|
|
2144
|
-
} catch {
|
|
2145
|
-
setError("\u65E0\u6CD5\u8BFB\u53D6\u6587\u4EF6");
|
|
2146
|
-
}
|
|
2147
|
-
} })
|
|
2148
|
-
] }),
|
|
2149
|
-
fileName && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "mono muted", children: fileName }),
|
|
2150
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [
|
|
2151
|
-
"\u8FC1\u79FB\u5BC6\u7801\uFF08\u4EC5\u52A0\u5BC6\u6587\u4EF6\u9700\u8981\uFF09",
|
|
2152
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "password", autoComplete: "off", maxLength: "1024", disabled: busy, value: password, onChange: (e) => {
|
|
2153
|
-
setPassword(e.target.value);
|
|
2154
|
-
resetPreview();
|
|
2155
|
-
} })
|
|
2156
|
-
] }),
|
|
2157
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [
|
|
2158
|
-
"\u5BFC\u5165\u65B9\u5F0F",
|
|
2159
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", { disabled: busy, value: mode, onChange: (e) => {
|
|
2160
|
-
setMode(e.target.value);
|
|
2161
|
-
resetPreview();
|
|
2162
|
-
}, children: [
|
|
2163
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "merge", children: "\u5408\u5E76\uFF1A\u4FDD\u7559\u672C\u673A\u989D\u5916\u8D26\u53F7\u548C\u8DEF\u7531" }),
|
|
2164
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "replace", children: "\u66FF\u6362\uFF1A\u4F7F\u7528\u5BFC\u5165\u6587\u4EF6\u7684\u5B8C\u6574\u914D\u7F6E" })
|
|
2165
|
-
] })
|
|
2166
|
-
] }),
|
|
2167
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u5408\u5E76\u65F6\u540C ID \u7684\u914D\u7F6E\u4F1A\u66F4\u65B0\uFF1B\u5E26\u51ED\u8BC1\u7684\u8D26\u53F7\u4F1A\u66F4\u65B0\u767B\u5F55\u526F\u672C\u3002\u66FF\u6362\u4F1A\u79FB\u51FA\u73B0\u6709\u914D\u7F6E\u4E2D\u7684\u989D\u5916\u8D26\u53F7 / \u8DEF\u7531\uFF0C\u4F46\u4FDD\u7559\u539F\u51ED\u8BC1\u6587\u4EF6\u3002\u4E24\u79CD\u65B9\u5F0F\u90FD\u4F1A\u5148\u5907\u4EFD\u672C\u673A\u914D\u7F6E\u3002" }),
|
|
2168
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Feedback, { error }),
|
|
2169
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "submit", disabled: busy || !document2, children: "\u68C0\u67E5\u6587\u4EF6\u5E76\u9884\u89C8\u53D8\u66F4" }),
|
|
2170
|
-
preview && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "steps stack", children: [
|
|
2171
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { children: "\u5BFC\u5165\u9884\u89C8" }),
|
|
2172
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { children: [
|
|
2173
|
-
preview.accounts,
|
|
2174
|
-
" \u4E2A\u8D26\u53F7\uFF08\u65B0\u589E ",
|
|
2175
|
-
preview.newAccounts,
|
|
2176
|
-
"\uFF09 \xB7 ",
|
|
2177
|
-
preview.credentials,
|
|
2178
|
-
" \u4EFD\u51ED\u8BC1",
|
|
2179
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("br", {}),
|
|
2180
|
-
preview.routes,
|
|
2181
|
-
" \u6761\u8DEF\u7531 \xB7 \u66F4\u65B0\u540C\u540D\u8DEF\u7531 ",
|
|
2182
|
-
preview.overwrittenRoutes,
|
|
2183
|
-
" \u6761",
|
|
2184
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("br", {}),
|
|
2185
|
-
preview.needsLogin,
|
|
2186
|
-
" \u4E2A\u65B0\u8D26\u53F7\u9700\u8865\u5145\u767B\u5F55\uFF0C\u5C06\u5148\u505C\u7528"
|
|
2187
|
-
] }),
|
|
2188
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", { className: "primary", type: "button", disabled: busy, onClick: async () => {
|
|
2189
|
-
if (await act({ action: "config.import", revision: preview.revision, document: document2, password, mode })) {
|
|
2190
|
-
setDocument("");
|
|
2191
|
-
setPassword("");
|
|
2192
|
-
setPreview(null);
|
|
2193
|
-
}
|
|
2194
|
-
}, children: [
|
|
2195
|
-
"\u786E\u8BA4",
|
|
2196
|
-
mode === "merge" ? "\u5408\u5E76" : "\u66FF\u6362",
|
|
2197
|
-
"\u5E76\u5BFC\u5165"
|
|
2198
|
-
] })
|
|
2199
|
-
] })
|
|
2200
|
-
] })
|
|
2201
|
-
] }) })
|
|
2202
|
-
] });
|
|
2203
|
-
}
|
|
2204
|
-
function ExpiryStatus({ route, act, busy, revision, onForce }) {
|
|
2205
|
-
const status = route.expiringStatus || {}, cooling = status.cooldownUntil > Date.now();
|
|
2206
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "steps stack", children: [
|
|
2207
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: cooling ? `\u4E34\u671F\u4F18\u5148\u51B7\u5374\u4E2D \xB7 \u5269\u4F59\u7EA6 ${Math.ceil((status.cooldownUntil - Date.now()) / 36e5)} \u5C0F\u65F6\uFF0C${when(status.cooldownUntil)} \u540E\u6062\u590D` : `\u4E34\u671F\u4F18\u5148\u5DF2\u5C31\u7EEA \xB7 \u7B2C ${status.number || 1} \u8F6E${status.accounts?.length ? ` \xB7 \u5DF2\u5B8C\u6210 ${status.completed?.length || 0} / ${status.accounts.length} \u4E2A\u8D26\u53F7` : ""}` }),
|
|
2208
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u6240\u6709\u4E34\u671F\u8D26\u53F7\u7684\u79EF\u5206\u8017\u5C3D\u6216\u8FBE\u5230\u6BCF\u8F6E\u989D\u5EA6\u540E\uFF0C\u4E34\u671F\u4F18\u5148\u6682\u505C 3 \u5929\uFF1B\u671F\u95F4\u6309\u666E\u901A\u8DEF\u7531\u89C4\u5219\u8FD0\u884C\uFF0C\u91CD\u542F\u540E\u51B7\u5374\u4ECD\u4FDD\u7559\u3002" }),
|
|
2209
|
-
cooling && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", disabled: busy, onClick: async () => {
|
|
2210
|
-
const result = await act({ action: "route.force-expiring", id: route.id, revision });
|
|
2211
|
-
if (result) onForce?.(result);
|
|
2212
|
-
}, children: "\u5F3A\u5236\u5F00\u542F\u5E76\u5F00\u59CB\u65B0\u4E00\u8F6E" }),
|
|
2213
|
-
cooling && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u5F3A\u5236\u5F00\u542F\u4F1A\u6E05\u9664\u4E34\u671F\u51B7\u5374\uFF0C\u5E76\u91CD\u7F6E\u672C\u8DEF\u7531\u7684\u672C\u8F6E\u989D\u5EA6\u8BA1\u6570\uFF1B\u7D2F\u8BA1\u7528\u91CF\u4FDD\u7559\u3002" })
|
|
2214
|
-
] });
|
|
2215
|
-
}
|
|
2216
|
-
function FreeStatus({ route, busy, act, onUpdate }) {
|
|
2217
|
-
const status = route.freeStatus, accounts = status?.accounts || [], count = accounts.reduce((n, a) => n + a.models.length, 0);
|
|
2218
|
-
const models = status?.modelRoutes || [];
|
|
2219
|
-
const update = async (model, patch) => {
|
|
2220
|
-
const next = await act({ action: "free.model.update", parentId: route.id, id: model.id, ...patch });
|
|
2221
|
-
if (next) onUpdate?.(next);
|
|
2222
|
-
};
|
|
2223
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "steps stack", children: [
|
|
2224
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bar", children: [
|
|
2225
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("h3", { children: [
|
|
2226
|
-
"\u514D\u8D39\u6A21\u578B \xB7 ",
|
|
2227
|
-
models.length,
|
|
2228
|
-
" \u79CD \xB7 ",
|
|
2229
|
-
count,
|
|
2230
|
-
" \u4E2A\u8D26\u53F7 / \u6A21\u578B\u7EC4\u5408"
|
|
2231
|
-
] }),
|
|
2232
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", disabled: busy || status?.checking, onClick: () => {
|
|
2233
|
-
void act({ action: "free.refresh" });
|
|
2234
|
-
}, children: status?.checking ? "\u6B63\u5728\u68C0\u67E5\u2026" : "\u7ACB\u5373\u68C0\u67E5\u514D\u8D39\u6A21\u578B" })
|
|
2235
|
-
] }),
|
|
2236
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u6309\u6A21\u578B\u81EA\u52A8\u521B\u5EFA\u8DEF\u7531\uFF0C\u52FE\u9009\u540E\u5206\u522B\u51FA\u73B0\u5728 DSH \u6A21\u578B\u5217\u8868\u4E2D\u3002\u540C\u4E00\u6A21\u578B\u53EA\u5728\u6709\u514D\u8D39\u8D44\u683C\u4E14\u652F\u6301\u6240\u9009\u63A8\u7406\u7B49\u7EA7\u7684\u8D26\u53F7\u95F4\u5207\u6362\uFF0C\u4E0D\u6DF7\u7528\u5176\u4ED6\u6A21\u578B\u3002\u6BCF\u5929\u68C0\u67E5\uFF0C\u8C03\u7528\u524D\u590D\u6838\uFF1B\u6062\u590D\u6536\u8D39\u6216\u68C0\u67E5\u5931\u8D25\u65F6\u81EA\u52A8\u79FB\u51FA\uFF0C\u514D\u8D39\u6062\u590D\u540E\u4FDD\u7559\u4F60\u7684\u52FE\u9009\u548C\u6863\u4F4D\u8BBE\u7F6E\u3002" }),
|
|
2237
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "box table-shell", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "scroll", role: "region", "aria-label": "\u514D\u8D39\u6A21\u578B\u5C55\u793A\u4E0E\u63A8\u7406\u7B49\u7EA7", tabIndex: "0", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("table", { className: "table", children: [
|
|
2238
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tr", { children: [
|
|
2239
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { scope: "col", children: "\u6A21\u578B / \u5C55\u793A" }),
|
|
2240
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { scope: "col", children: "\u53EF\u7528\u8D26\u53F7" }),
|
|
2241
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { scope: "col", children: "\u4E0A\u4E0B\u6587 / \u63A8\u7406\u7B49\u7EA7" })
|
|
2242
|
-
] }) }),
|
|
2243
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("tbody", { children: models.map((m) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tr", { className: m.selected ? "selected" : "", children: [
|
|
2244
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("td", { children: [
|
|
2245
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "check", children: [
|
|
2246
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "checkbox", "aria-label": `\u5C55\u793A ${m.modelName}`, disabled: busy, checked: m.selected, onChange: (e) => {
|
|
2247
|
-
void update(m, { visible: e.target.checked });
|
|
2248
|
-
} }),
|
|
2249
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: m.modelName })
|
|
2250
|
-
] }),
|
|
2251
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("small", { className: "muted", children: [
|
|
2252
|
-
m.name.split(" \xB7 ").at(-1),
|
|
2253
|
-
" \xB7 ",
|
|
2254
|
-
fmt(m.contextWindow / 1e3),
|
|
2255
|
-
"K \u4E0A\u4E0B\u6587"
|
|
2256
|
-
] })
|
|
2257
|
-
] }),
|
|
2258
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { children: m.accountNames.join("\u3001") || "\u6682\u65E0\u8D26\u53F7" }),
|
|
2259
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("td", { children: [
|
|
2260
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ContextSelect, { model: m, value: m.configuredContextWindow, disabled: busy, label: `${m.modelName} \u4E0A\u4E0B\u6587`, onChange: (contextWindow) => {
|
|
2261
|
-
void update(m, { contextWindow });
|
|
2262
|
-
} }),
|
|
2263
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [
|
|
2264
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "sr-only", children: [
|
|
2265
|
-
m.modelName,
|
|
2266
|
-
" \u63A8\u7406\u7B49\u7EA7"
|
|
2267
|
-
] }),
|
|
2268
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", { "aria-label": `${m.modelName} \u63A8\u7406\u7B49\u7EA7`, disabled: busy, value: m.reasoningEffort || "", onChange: (e) => {
|
|
2269
|
-
void update(m, { reasoningEffort: e.target.value || null });
|
|
2270
|
-
}, children: [
|
|
2271
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "", children: "\u5E73\u53F0\u9ED8\u8BA4" }),
|
|
2272
|
-
m.reasoning?.supportedEfforts?.map((e) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: e, children: effortNames[e] || e }, e))
|
|
2273
|
-
] })
|
|
2274
|
-
] }),
|
|
2275
|
-
m.effortUnavailable && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("small", { className: "warn", children: "\u539F\u6863\u4F4D\u6682\u4E0D\u53EF\u7528\uFF0C\u4F7F\u7528\u5E73\u53F0\u9ED8\u8BA4" })
|
|
2276
|
-
] })
|
|
2277
|
-
] }, m.id)) })
|
|
2278
|
-
] }) }) }),
|
|
2279
|
-
!models.length && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u6682\u65E0\u786E\u8BA4\u514D\u8D39\u7684\u6A21\u578B\u3002\u6DFB\u52A0\u5E76\u542F\u7528\u8D26\u53F7\uFF0C\u6216\u7ACB\u5373\u68C0\u67E5\u76EE\u5F55\u3002" }),
|
|
2280
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("details", { children: [
|
|
2281
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("summary", { children: "\u5404\u8D26\u53F7\u68C0\u67E5\u72B6\u6001" }),
|
|
2282
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "stack", style: { marginTop: 12 }, children: accounts.map((a) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
2283
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { children: [
|
|
2284
|
-
a.name,
|
|
2285
|
-
" \xB7 ",
|
|
2286
|
-
a.models.length ? a.models.map((m) => m.name).join("\u3001") : a.error ? "\u68C0\u67E5\u5931\u8D25\uFF0C\u6682\u4E0D\u53C2\u4E0E" : "\u6682\u65E0\u786E\u8BA4\u514D\u8D39\u7684\u6A21\u578B"
|
|
2287
|
-
] }),
|
|
2288
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "notice", children: [
|
|
2289
|
-
a.provider,
|
|
2290
|
-
" \xB7 \u4E0A\u6B21\u76EE\u5F55\u68C0\u67E5 ",
|
|
2291
|
-
when(a.checkedAt)
|
|
2292
|
-
] })
|
|
2293
|
-
] }, a.id)) })
|
|
2294
|
-
] })
|
|
2295
|
-
] });
|
|
2296
|
-
}
|
|
2297
|
-
function FreeRouteForm({ draft, setDraft, data, act, busy, error, notice }) {
|
|
2298
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("form", { onSubmit: async (e) => {
|
|
2299
|
-
e.preventDefault();
|
|
2300
|
-
const { id, previousId, revision, reasoning, supportsImages, expiringStatus, freeStatus, creditRates, maxContextWindow, supportedContextWindows, configuredContextWindow, contextKnown, eligibleAccountIds, enforceContext, ...route } = draft;
|
|
2301
|
-
route.targets = route.targets.map((t) => ({ provider: t.provider, ...t.account ? { account: t.account } : {}, ...t.model ? { model: t.model } : {}, ...t.models ? { models: t.models } : {} }));
|
|
2302
|
-
if (await act({ action: "route.save", id, previousId, revision, route })) setDraft(null);
|
|
2303
|
-
}, children: [
|
|
2304
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "modal-body stack", children: [
|
|
2305
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Feedback, { error, notice }),
|
|
2306
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [
|
|
2307
|
-
"\u7BA1\u7406\u7EC4\u540D\u79F0",
|
|
2308
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { required: true, maxLength: 200, disabled: busy, value: draft.name, onChange: (e) => setDraft((d) => ({ ...d, name: e.target.value })) })
|
|
2309
|
-
] }),
|
|
2310
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "Free \u7684\u6A21\u578B\u8DEF\u7531\u7531\u76EE\u5F55\u81EA\u52A8\u7EF4\u62A4\uFF0C\u65E0\u9700\u586B\u5199\u6A21\u578B ID\u3002\u8D26\u53F7\u542F\u505C\u5728\u300C\u8D26\u53F7\u4E0E\u767B\u5F55\u300D\u8C03\u6574\u3002" }),
|
|
2311
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(FreeStatus, { route: data.routes.find((r) => r.id === draft.id) || draft, act, busy, onUpdate: (next) => setDraft((d) => ({ ...d, revision: next.revision, freeModels: next.routes.find((r) => r.id === d.id)?.freeModels })) }),
|
|
2312
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "check", children: [
|
|
2313
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "checkbox", checked: draft.visible !== false, disabled: busy, onChange: (e) => setDraft((d) => ({ ...d, visible: e.target.checked })) }),
|
|
2314
|
-
"\u5C55\u793A\u52FE\u9009\u7684\u514D\u8D39\u6A21\u578B"
|
|
2315
|
-
] })
|
|
2316
|
-
] }),
|
|
2317
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "modal-foot bar", children: [
|
|
2318
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", disabled: busy, onClick: async () => {
|
|
2319
|
-
if (await act({ action: "route.remove", id: draft.id, revision: draft.revision })) setDraft(null);
|
|
2320
|
-
}, children: "\u79FB\u9664\u514D\u8D39\u7BA1\u7406\u7EC4" }),
|
|
2321
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { className: "primary", disabled: busy, type: "submit", children: "\u4FDD\u5B58\u8BBE\u7F6E" })
|
|
2322
|
-
] })
|
|
2323
|
-
] });
|
|
2324
|
-
}
|
|
2325
|
-
function RouteReasoningSelect({ draft, setDraft, data, busy }) {
|
|
2326
|
-
const targets = draft.targets.map((t) => ({
|
|
2327
|
-
provider: t.provider,
|
|
2328
|
-
...t.account ? { account: t.account } : {},
|
|
2329
|
-
models: t.modelText.split(",").map((x) => x.trim()).filter(Boolean)
|
|
2330
|
-
}));
|
|
2331
|
-
const signature = JSON.stringify({
|
|
2332
|
-
action: "route.preview",
|
|
2333
|
-
revision: data.revision,
|
|
2334
|
-
catalogs: data.accounts?.map((a) => [a.id, a.enabled, a.fetchedAt]),
|
|
2335
|
-
id: draft.id || "preview",
|
|
2336
|
-
route: {
|
|
2337
|
-
contextMode: draft.contextMode ?? "maximum",
|
|
2338
|
-
contextWindow: draft.contextWindow,
|
|
2339
|
-
maxTokens: 1,
|
|
2340
|
-
targets: targets.map(({ models, ...target }) => ({ ...target, ...models.length ? { models } : {} }))
|
|
2341
|
-
}
|
|
2342
|
-
});
|
|
2343
|
-
const [preview, setPreview] = (0, import_react.useState)(null);
|
|
2344
|
-
(0, import_react.useEffect)(() => {
|
|
2345
|
-
const abort = new AbortController();
|
|
2346
|
-
const timer = setTimeout(async () => {
|
|
2347
|
-
try {
|
|
2348
|
-
const res = await fetch(ENDPOINT, {
|
|
2349
|
-
method: "POST",
|
|
2350
|
-
signal: abort.signal,
|
|
2351
|
-
headers: { "Content-Type": "application/json", "X-Multi-Router-Key": data.key },
|
|
2352
|
-
body: signature
|
|
2353
|
-
});
|
|
2354
|
-
const next = await readManagementResponse(res);
|
|
2355
|
-
if (!abort.signal.aborted) setPreview({ signature, ...next.routePreview });
|
|
2356
|
-
} catch (e) {
|
|
2357
|
-
if (!abort.signal.aborted) setPreview({ signature, error: e.message });
|
|
2358
|
-
}
|
|
2359
|
-
}, 250);
|
|
2360
|
-
return () => {
|
|
2361
|
-
clearTimeout(timer);
|
|
2362
|
-
abort.abort();
|
|
2363
|
-
};
|
|
2364
|
-
}, [signature, data.key]);
|
|
2365
|
-
const pending = preview?.signature !== signature, modes = pending ? [] : preview?.reasoning?.supportedEfforts ?? [];
|
|
2366
|
-
const effort = draft.reasoningEffort ?? "", unavailable = !!effort && !pending && !preview?.error && !modes.includes(effort);
|
|
2367
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "stack", children: [
|
|
2368
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [
|
|
2369
|
-
"\u9ED8\u8BA4\u601D\u8003\u6DF1\u5EA6",
|
|
2370
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", { "aria-describedby": "route-reasoning-help", disabled: busy || pending || !!preview?.error, value: effort, onChange: (e) => setDraft((d) => ({ ...d, reasoningEffort: e.target.value || null })), children: [
|
|
2371
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "", children: "\u5E73\u53F0\u9ED8\u8BA4" }),
|
|
2372
|
-
effort && !modes.includes(effort) && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("option", { value: effort, disabled: true, children: [
|
|
2373
|
-
effortNames[effort] || effort,
|
|
2374
|
-
"\uFF08",
|
|
2375
|
-
pending ? "\u6838\u5BF9\u4E2D" : "\u5F53\u524D\u4E0D\u53EF\u7528",
|
|
2376
|
-
"\uFF09"
|
|
2377
|
-
] }),
|
|
2378
|
-
modes.map((e) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: e, children: effortNames[e] || e }, e))
|
|
2379
|
-
] })
|
|
2380
|
-
] }),
|
|
2381
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { id: "route-reasoning-help", className: preview?.error || unavailable ? "warn notice" : "notice", role: "status", children: pending ? "\u6B63\u5728\u6838\u5BF9\u76EE\u6807\u6A21\u578B\u652F\u6301\u7684\u6863\u4F4D\u2026" : preview?.error || (unavailable ? "\u539F\u6863\u4F4D\u5F53\u524D\u4E0D\u53EF\u7528\uFF0C\u8BF7\u9009\u62E9\u5176\u4ED6\u6863\u4F4D\u6216\u5E73\u53F0\u9ED8\u8BA4\u3002" : !preview?.contextKnown ? "\u5C1A\u672A\u83B7\u53D6\u76EE\u6807\u6A21\u578B\u76EE\u5F55\uFF0C\u6682\u65F6\u53EA\u80FD\u4F7F\u7528\u5E73\u53F0\u9ED8\u8BA4\u3002" : !modes.length ? "\u76EE\u6807\u6A21\u578B\u672A\u58F0\u660E\u53EF\u8C03\u6863\u4F4D\uFF0C\u4F7F\u7528\u5E73\u53F0\u9ED8\u8BA4\u3002" : "\u4EC5\u5C55\u793A\u5F53\u524D\u76EE\u6807\u4E0E\u4E0A\u4E0B\u6587\u5BB9\u91CF\u652F\u6301\u7684\u6863\u4F4D\u3002") }),
|
|
2382
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u4F1A\u8BDD\u91CC\u624B\u52A8\u9009\u62E9\u7684\u6863\u4F4D\u4F18\u5148\u3002\u6307\u5B9A\u6DF1\u5EA6\u540E\uFF0C\u4EC5\u5728\u652F\u6301\u8BE5\u6863\u4F4D\u7684\u8D26\u53F7\u95F4\u5207\u6362\uFF1B\u5173\u95ED\u601D\u8003\u4EC5\u5728\u6E20\u9053\u652F\u6301\u65F6\u63D0\u4F9B\u3002" })
|
|
2383
|
-
] });
|
|
2384
|
-
}
|
|
2385
|
-
function RouteForm({ draft, setDraft, data, act, busy, error, notice }) {
|
|
2386
|
-
if (draft.freeOnly) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FreeRouteForm, { draft, setDraft, data, act, busy, error, notice });
|
|
2387
|
-
const set = (key, value) => setDraft((d) => ({ ...d, [key]: value }));
|
|
2388
|
-
const target = (i, patch) => setDraft((d) => ({ ...d, targets: d.targets.map((t, index) => i === index ? { ...t, ...patch } : t) }));
|
|
2389
|
-
const move = (i, delta) => {
|
|
2390
|
-
const targets = [...draft.targets];
|
|
2391
|
-
[targets[i], targets[i + delta]] = [targets[i + delta], targets[i]];
|
|
2392
|
-
set("targets", targets);
|
|
2393
|
-
};
|
|
2394
|
-
const strategyHelp = { failover: "\u4F18\u5148\u4F7F\u7528\u524D\u9762\u7684\u8D26\u53F7\uFF1B\u9047\u5230 4xx \u540E\u6362\u4E0B\u4E00\u4E2A\uFF0C\u6210\u529F\u8D26\u53F7\u7EE7\u7EED\u627F\u63A5\u8BF7\u6C42\u3002", weighted: "\u6309\u6BCF\u4E2A\u8D26\u53F7\u7684\u6743\u91CD\u5206\u914D\u8BF7\u6C42\u3002\u4F8B\u5982 3:1\uFF0C\u957F\u671F\u7EA6 75%:25%\uFF1B\u77ED\u671F\u6BD4\u4F8B\u4E0E\u8BF7\u6C42\u957F\u5EA6\u53EF\u80FD\u4E0D\u540C\u3002", tokens: "\u6BCF\u4E2A\u8D26\u53F7\u7D2F\u8BA1\u8FBE\u5230\u672C\u8F6E Token \u989D\u5EA6\u540E\uFF0C\u4E0B\u4E00\u6B21\u8BF7\u6C42\u6362\u8D26\u53F7\u3002\u6240\u6709\u76EE\u6807\u7528\u5B8C\u989D\u5EA6\u540E\u5F00\u59CB\u65B0\u4E00\u8F6E\u3002", credits: "\u6309\u5E73\u53F0\u4F59\u989D\u4E0B\u964D\u8BA1\u7B97\u672C\u8F6E\u6D88\u8017\uFF0C\u8FBE\u5230\u9608\u503C\u540E\u6362\u8D26\u53F7\u3002\u4F59\u989D\u53EF\u80FD\u5305\u542B\u5176\u4ED6\u5E94\u7528\u7684\u6D88\u8D39\uFF1B\u79EF\u5206\u67E5\u8BE2\u5931\u8D25\u65F6\u6682\u4E0D\u4F7F\u7528\u8BE5\u8D26\u53F7\u3002" };
|
|
2395
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("form", { onSubmit: async (e) => {
|
|
2396
|
-
e.preventDefault();
|
|
2397
|
-
if (draft.id !== "ds4.1f" && draft.targets.some((t) => !t.modelText.trim())) {
|
|
2398
|
-
e.currentTarget.querySelector("details")?.setAttribute("open", "");
|
|
2399
|
-
return;
|
|
2400
|
-
}
|
|
2401
|
-
const { id, previousId, revision, reasoning, supportsImages, expiringStatus, maxContextWindow, supportedContextWindows, configuredContextWindow, contextKnown, eligibleAccountIds, enforceContext, ...route } = draft;
|
|
2402
|
-
route.targets = route.targets.map((t) => {
|
|
2403
|
-
const models = t.modelText.split(",").map((x) => x.trim()).filter(Boolean);
|
|
2404
|
-
return { provider: t.provider, ...t.account ? { account: t.account } : {}, ...models.length ? { models } : {}, ...route.strategy === "weighted" ? { weight: Number(t.weight) } : {}, ...route.strategy === "tokens" ? { tokenBudget: Number(t.tokenBudget) } : {}, ...route.strategy === "credits" ? { creditBudget: Number(t.creditBudget) } : {} };
|
|
2405
|
-
});
|
|
2406
|
-
if (await act({ action: "route.save", id, previousId, revision, route })) setDraft(null);
|
|
2407
|
-
}, children: [
|
|
2408
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "modal-body stack", children: [
|
|
2409
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Feedback, { error, notice }),
|
|
2410
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [
|
|
2411
|
-
"\u8DEF\u7531\u540D\u79F0",
|
|
2412
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { required: true, maxLength: 200, value: draft.name, disabled: busy, onChange: (e) => set("name", e.target.value), placeholder: "\u4F8B\u5982 \u6211\u7684 Flash \u81EA\u52A8\u5207\u6362" })
|
|
2413
|
-
] }),
|
|
2414
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u540D\u79F0\u663E\u793A\u5728 DSH \u6A21\u578B\u5217\u8868\u4E2D\uFF0C\u53EF\u968F\u65F6\u4FEE\u6539\uFF0C\u4E0D\u5F71\u54CD\u5DF2\u6709\u4F1A\u8BDD\u7684\u8DEF\u7531\u9009\u62E9\u3002" }),
|
|
2415
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "box stack", "aria-labelledby": "route-model-parameters", children: [
|
|
2416
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { id: "route-model-parameters", children: "\u6A21\u578B\u53C2\u6570" }),
|
|
2417
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "grid", children: [
|
|
2418
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "stack", children: [
|
|
2419
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [
|
|
2420
|
-
"\u4E0A\u4E0B\u6587\u5BB9\u91CF",
|
|
2421
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", { disabled: busy, value: draft.contextMode ?? "maximum", onChange: (e) => set("contextMode", e.target.value), children: [
|
|
2422
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "maximum", children: "\u4F7F\u7528\u6A21\u578B\u6700\u5927\u5BB9\u91CF\uFF08\u9ED8\u8BA4\uFF09" }),
|
|
2423
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "custom", children: "\u624B\u52A8\u8BBE\u7F6E\u672C\u5730\u9884\u7B97" })
|
|
2424
|
-
] })
|
|
2425
|
-
] }),
|
|
2426
|
-
draft.contextMode === "custom" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [
|
|
2427
|
-
"\u4E0A\u4E0B\u6587\u9884\u7B97\uFF08Token\uFF09",
|
|
2428
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "number", disabled: busy, min: "1", required: true, value: draft.contextWindow, onChange: (e) => set("contextWindow", Number(e.target.value)) })
|
|
2429
|
-
] }),
|
|
2430
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u9ED8\u8BA4\u968F\u6A21\u578B\u76EE\u5F55\u66F4\u65B0\u3002\u53EA\u5411\u652F\u6301\u5F53\u524D\u5BB9\u91CF\u7684\u6E20\u9053\u5207\u6362\uFF1B\u8C03\u4F4E\u9884\u7B97\u53EF\u8BA9\u66F4\u591A\u6E20\u9053\u53C2\u4E0E\u3002\u4E0D\u4F1A\u5220\u9664\u4F1A\u8BDD\u5386\u53F2\u3002" })
|
|
2431
|
-
] }),
|
|
2432
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(RouteReasoningSelect, { draft, setDraft, data, busy })
|
|
2433
|
-
] })
|
|
2434
|
-
] }),
|
|
2435
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [
|
|
2436
|
-
"\u8D26\u53F7\u5207\u6362\u89C4\u5219",
|
|
2437
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("select", { disabled: busy, value: draft.strategy, onChange: (e) => set("strategy", e.target.value), children: Object.entries(strategies).map(([id, label]) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: id, children: label }, id)) })
|
|
2438
|
-
] }),
|
|
2439
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "steps", children: [
|
|
2440
|
-
strategyHelp[draft.strategy],
|
|
2441
|
-
["tokens", "credits"].includes(draft.strategy) && " \u6B63\u5728\u8F93\u51FA\u7684\u56DE\u7B54\u4F1A\u5B8C\u6210\uFF0C\u989D\u5EA6\u5141\u8BB8\u8D85\u8FC7\u6700\u540E\u4E00\u6B21\u8BF7\u6C42\u7684\u7528\u91CF\u3002"
|
|
2442
|
-
] }),
|
|
2443
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "box stack", children: [
|
|
2444
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "check", children: [
|
|
2445
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "checkbox", disabled: busy, checked: draft.preferExpiringCredits !== false, onChange: (e) => set("preferExpiringCredits", e.target.checked) }),
|
|
2446
|
-
"\u4F18\u5148\u4F7F\u7528\u4E34\u671F\u79EF\u5206\uFF08\u9ED8\u8BA4\u5F00\u542F\uFF09"
|
|
2447
|
-
] }),
|
|
2448
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u4F18\u5148\u4F7F\u7528\u4ECD\u6709\u4F59\u989D\u4E14\u66F4\u65E9\u5230\u671F\u7684\u79EF\u5206\u5305\uFF1B\u4F18\u5148\u7EA7\u9AD8\u4E8E\u987A\u5E8F\u548C\u6743\u91CD\uFF0C\u4ECD\u9075\u5B88\u6BCF\u8F6E\u989D\u5EA6\u4E0E\u6545\u969C\u5207\u6362\u3002\u5E73\u53F0\u672A\u63D0\u4F9B\u6709\u6548\u671F\u6216\u7528\u91CF\u6570\u636E\u8FC7\u671F\u65F6\uFF0C\u6309\u666E\u901A\u89C4\u5219\u6267\u884C\u3002" }),
|
|
2449
|
-
draft.preferExpiringCredits !== false && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [
|
|
2450
|
-
"\u4E34\u671F\u8303\u56F4\uFF08\u5929\uFF09",
|
|
2451
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "number", disabled: busy, min: "1", max: "365", required: true, value: draft.expiringWithinDays ?? 7, onChange: (e) => set("expiringWithinDays", Number(e.target.value)) })
|
|
2452
|
-
] })
|
|
2453
|
-
] }),
|
|
2454
|
-
draft.preferExpiringCredits !== false && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ExpiryStatus, { route: data.routes.find((r) => r.id === draft.previousId) || draft, busy, act, revision: draft.revision, onForce: (result) => setDraft((d) => ({ ...d, revision: result.revision, expiringStatus: result.routes.find((r) => r.id === draft.previousId)?.expiringStatus })) }),
|
|
2455
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "box stack", children: [
|
|
2456
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "check", children: [
|
|
2457
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "checkbox", disabled: busy, checked: draft.balanceCredits !== false, onChange: (e) => set("balanceCredits", e.target.checked) }),
|
|
2458
|
-
"\u79EF\u5206\u4F7F\u7528\u5747\u8861\uFF08\u9ED8\u8BA4\u5F00\u542F\uFF09"
|
|
2459
|
-
] }),
|
|
2460
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u67D0\u4E2A\u8D26\u53F7\u672C\u8F6E\u6D88\u8017\u8FBE\u5230\u9608\u503C\u540E\uFF0C\u4E0B\u4E00\u6B21\u8BF7\u6C42\u4F18\u5148\u6362\u5230\u5176\u4ED6\u4ECD\u6709\u4F59\u989D\u7684\u8D26\u53F7\u3002\u6240\u6709\u8D26\u53F7\u90FD\u8FBE\u5230\u9608\u503C\u65F6\u7EE7\u7EED\u4F7F\u7528\u73B0\u6709\u8D26\u53F7\uFF0C\u4E0D\u4F1A\u56E0\u6B64\u5931\u8D25\u3002\u4F59\u989D\u7531\u5E73\u53F0\u67E5\u8BE2\u63A8\u7B97\uFF0C\u53EF\u80FD\u591A\u51FA\u4E00\u6B21\u8BF7\u6C42\u7684\u7528\u91CF\uFF1B\u67E5\u8BE2\u5931\u8D25\u671F\u95F4\u4E0D\u505A\u5207\u6362\u5224\u65AD\u3002" }),
|
|
2461
|
-
draft.balanceCredits !== false && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [
|
|
2462
|
-
"\u6BCF\u8D26\u53F7\u5207\u6362\u9608\u503C\uFF08\u79EF\u5206\uFF09",
|
|
2463
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "number", disabled: busy, min: "1", step: "1", required: true, value: draft.creditBalanceThreshold ?? 1e3, onChange: (e) => set("creditBalanceThreshold", Number(e.target.value)) })
|
|
2464
|
-
] })
|
|
2465
|
-
] }),
|
|
2466
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "box stack", children: [
|
|
2467
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "check", children: [
|
|
2468
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "checkbox", disabled: busy, checked: draft.discountOrder !== false, onChange: (e) => set("discountOrder", e.target.checked) }),
|
|
2469
|
-
"\u6309\u79EF\u5206\u6298\u6263\u6392\u5E8F\uFF08\u9ED8\u8BA4\u5F00\u542F\uFF09"
|
|
2470
|
-
] }),
|
|
2471
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u6BCF\u6B21\u8BF7\u6C42\u6309\u5404\u6E20\u9053\u5F53\u524D\u516C\u5E03\u7684\u79EF\u5206\u500D\u7387\u4ECE\u5C0F\u5230\u5927\u6392\u5217\u5019\u9009\u8D26\u53F7\uFF0C\u500D\u7387\u8D8A\u4F4E\u8D8A\u4FBF\u5B9C\u3001\u8D8A\u5148\u7528\u3002\u500D\u7387\u6765\u81EA\u6A21\u578B\u76EE\u5F55\u5E76\u968F\u76EE\u5F55\u5237\u65B0\uFF0C\u9650\u65F6\u4FC3\u9500\u5230\u671F\u540E\u81EA\u52A8\u6062\u590D\u3002\u4E34\u671F\u79EF\u5206\u4E0E\u79EF\u5206\u5747\u8861\u989D\u5EA6\u4ECD\u7136\u4F18\u5148\uFF0C\u6298\u6263\u53EA\u5728\u540C\u7C7B\u5019\u9009\u4E4B\u95F4\u51B3\u5B9A\u5148\u540E\uFF1B\u6CA1\u6709\u516C\u5E03\u500D\u7387\u7684\u8D26\u53F7\u6392\u5728\u6700\u540E\u3002" })
|
|
2472
|
-
] }),
|
|
2473
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bar", children: [
|
|
2474
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { children: "\u6A21\u578B\u4E0E\u8D26\u53F7\u76EE\u6807" }),
|
|
2475
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "notice", children: "\u6309\u4E0B\u65B9\u987A\u5E8F\u5207\u6362" })
|
|
2476
|
-
] }),
|
|
2477
|
-
draft.targets.map((t, i) => {
|
|
2478
|
-
const models = data.providers.find((p) => p.id === t.provider)?.models || [];
|
|
2479
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "box stack", children: [
|
|
2480
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bar target-head", children: [
|
|
2481
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("strong", { children: [
|
|
2482
|
-
"\u76EE\u6807 ",
|
|
2483
|
-
i + 1
|
|
2484
|
-
] }),
|
|
2485
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "row", children: [
|
|
2486
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", disabled: busy || i === 0, onClick: () => move(i, -1), children: "\u524D\u79FB" }),
|
|
2487
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", disabled: busy || i === draft.targets.length - 1, onClick: () => move(i, 1), children: "\u540E\u79FB" }),
|
|
2488
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", disabled: busy || draft.targets.length === 1, onClick: () => set("targets", draft.targets.filter((_, index) => index !== i)), children: "\u79FB\u9664" })
|
|
2489
|
-
] })
|
|
2490
|
-
] }),
|
|
2491
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "grid", children: [
|
|
2492
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [
|
|
2493
|
-
"\u4F9B\u5E94\u5546",
|
|
2494
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("select", { disabled: busy, value: t.provider, onChange: (e) => target(i, { provider: e.target.value, account: "", modelText: "" }), children: data.providers.map((p) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: p.id, children: p.name }, p.id)) })
|
|
2495
|
-
] }),
|
|
2496
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [
|
|
2497
|
-
"\u4F7F\u7528\u8D26\u53F7",
|
|
2498
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", { disabled: busy, value: t.account || "", onChange: (e) => target(i, { account: e.target.value }), children: [
|
|
2499
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "", children: "\u6B64\u4F9B\u5E94\u5546\u5168\u90E8\u542F\u7528\u8D26\u53F7" }),
|
|
2500
|
-
data.accounts.filter((a) => a.provider === t.provider).map((a) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: a.id, children: a.name }, a.id))
|
|
2501
|
-
] })
|
|
2502
|
-
] }),
|
|
2503
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "full", children: [
|
|
2504
|
-
"\u76EE\u6807\u6A21\u578B",
|
|
2505
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", { disabled: busy, required: draft.id !== "ds4.1f", value: t.modelText, onChange: (e) => {
|
|
2506
|
-
if (e.target.value) target(i, { modelText: e.target.value });
|
|
2507
|
-
}, children: [
|
|
2508
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "", children: "\u4ECE\u5DF2\u53D1\u73B0\u6A21\u578B\u4E2D\u9009\u62E9" }),
|
|
2509
|
-
t.modelText && !models.some((m) => m.id === t.modelText) && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: t.modelText, children: t.modelText }),
|
|
2510
|
-
models.map((m) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("option", { value: m.id, children: [
|
|
2511
|
-
m.name,
|
|
2512
|
-
" \xB7 ",
|
|
2513
|
-
m.id
|
|
2514
|
-
] }, m.id))
|
|
2515
|
-
] })
|
|
2516
|
-
] }),
|
|
2517
|
-
draft.strategy === "weighted" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [
|
|
2518
|
-
"\u6BCF\u4E2A\u8D26\u53F7\u7684\u6743\u91CD",
|
|
2519
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "number", disabled: busy, min: "1", max: "1000", required: true, value: t.weight, onChange: (e) => target(i, { weight: e.target.value }) })
|
|
2520
|
-
] }),
|
|
2521
|
-
draft.strategy === "tokens" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [
|
|
2522
|
-
"\u6BCF\u4E2A\u8D26\u53F7\u6BCF\u8F6E Token \u989D\u5EA6",
|
|
2523
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "number", disabled: busy, min: "1", step: "1", required: true, value: t.tokenBudget, onChange: (e) => target(i, { tokenBudget: e.target.value }) })
|
|
2524
|
-
] }),
|
|
2525
|
-
draft.strategy === "credits" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [
|
|
2526
|
-
"\u6BCF\u4E2A\u8D26\u53F7\u6BCF\u8F6E\u79EF\u5206\u6D88\u8017",
|
|
2527
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "number", disabled: busy, min: "0.01", step: "any", required: true, value: t.creditBudget, onChange: (e) => target(i, { creditBudget: e.target.value }) })
|
|
2528
|
-
] })
|
|
2529
|
-
] }),
|
|
2530
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("details", { children: [
|
|
2531
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("summary", { children: "\u9AD8\u7EA7\uFF1A\u624B\u52A8\u586B\u5199\u5019\u9009\u6A21\u578B ID" }),
|
|
2532
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: { marginTop: 10 }, children: [
|
|
2533
|
-
"\u5019\u9009\u6A21\u578B ID\uFF08\u9017\u53F7\u5206\u9694\uFF09",
|
|
2534
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { disabled: busy, value: t.modelText, onChange: (e) => target(i, { modelText: e.target.value }), placeholder: "\u6309\u987A\u5E8F\u5339\u914D\u771F\u5B9E\u6A21\u578B\u76EE\u5F55" })
|
|
2535
|
-
] })
|
|
2536
|
-
] })
|
|
2537
|
-
] }, t.key);
|
|
2538
|
-
}),
|
|
2539
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", disabled: busy, onClick: () => set("targets", [...draft.targets, { provider: "workbuddy", account: "", key: crypto.randomUUID(), weight: 1, tokenBudget: 1e5, creditBudget: 100, modelText: "" }]), children: "\u6DFB\u52A0\u5207\u6362\u76EE\u6807" }),
|
|
2540
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("details", { children: [
|
|
2541
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("summary", { children: "\u9AD8\u7EA7\uFF1A\u8F93\u51FA\u957F\u5EA6" }),
|
|
2542
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "grid", style: { marginTop: 12 }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [
|
|
2543
|
-
"\u6700\u5927\u8F93\u51FA\u957F\u5EA6",
|
|
2544
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "number", disabled: busy, min: "1", max: draft.contextWindow, required: true, value: draft.maxTokens, onChange: (e) => set("maxTokens", Number(e.target.value)) })
|
|
2545
|
-
] }) })
|
|
2546
|
-
] })
|
|
2547
|
-
] }),
|
|
2548
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "modal-foot bar", children: [
|
|
2549
|
-
draft.previousId ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", disabled: busy, onClick: async () => {
|
|
2550
|
-
if (await act({ action: "route.remove", revision: draft.revision, id: draft.previousId })) setDraft(null);
|
|
2551
|
-
}, children: "\u79FB\u9664\u8DEF\u7531" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: busy, type: "button", onClick: () => setDraft(null), children: "\u53D6\u6D88" }),
|
|
2552
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { className: "primary", type: "submit", disabled: busy, children: busy ? "\u6B63\u5728\u4FDD\u5B58\u2026" : "\u4FDD\u5B58\u8DEF\u7531" })
|
|
2553
|
-
] })
|
|
2554
|
-
] });
|
|
2555
|
-
}
|
|
2556
|
-
function InitialSetup({ data, busy, act, go }) {
|
|
2557
|
-
const discovery = data.localDiscovery ?? [];
|
|
2558
|
-
const discovering = data.startup?.phase === "discovering";
|
|
2559
|
-
const saved = discovery.reduce((n, s) => n + (s.savedCount ?? 0), 0);
|
|
2560
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "box stack", "aria-label": "\u9996\u6B21\u8D26\u53F7\u8BBE\u7F6E", children: [
|
|
2561
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bar", children: [
|
|
2562
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
2563
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("h3", { children: [
|
|
2564
|
-
"\u672C\u673A\u8D26\u53F7\u81EA\u52A8\u83B7\u53D6",
|
|
2565
|
-
discovering ? "\u8FDB\u884C\u4E2D" : discovery.length ? "\u5DF2\u5B8C\u6210" : "\u5F85\u91CD\u8BD5"
|
|
2566
|
-
] }),
|
|
2567
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: discovering ? "\u6B63\u5728\u540E\u53F0\u8BFB\u53D6 WorkBuddy / Trae \u672C\u673A\u767B\u5F55\uFF0C\u65E0\u9700\u624B\u52A8\u91CD\u590D\u83B7\u53D6\uFF0C\u5DF2\u6709\u8D26\u53F7\u53EF\u4EE5\u7EE7\u7EED\u4F7F\u7528\u3002" : saved ? `\u5DF2\u4FDD\u5B58 ${saved} \u4E2A WorkBuddy / Trae \u672C\u673A\u767B\u5F55\uFF0C\u65E0\u9700\u518D\u6B21\u624B\u52A8\u6DFB\u52A0\u3002` : "\u6682\u672A\u4FDD\u5B58\u672C\u673A\u767B\u5F55\u3002\u5148\u5728\u5B98\u65B9\u5BA2\u6237\u7AEF\u767B\u5F55\uFF0C\u518D\u70B9\u51FB\u300C\u4E00\u952E\u83B7\u53D6\u5E76\u4FDD\u5B58\u300D\u3002" })
|
|
2568
|
-
] }),
|
|
2569
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: busy, onClick: () => {
|
|
2570
|
-
void act({ action: "setup.dismiss" });
|
|
2571
|
-
}, children: "\u77E5\u9053\u4E86" })
|
|
2572
|
-
] }),
|
|
2573
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "providers", children: discovery.map((s) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "steps", children: [
|
|
2574
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: data.providers.find((p) => p.id === s.provider)?.name ?? s.provider }),
|
|
2575
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: (s.savedCount ?? 0) > 0 ? "good" : "notice", children: s.savedCount ? `\u5DF2\u4FDD\u5B58 ${s.savedCount} \u4E2A\u767B\u5F55` : s.state === "found" ? "\u68C0\u6D4B\u5230\u767B\u5F55\uFF1B\u5DF2\u5FFD\u7565\u6216\u5C1A\u672A\u4FDD\u5B58\uFF0C\u8BF7\u91CD\u65B0\u83B7\u53D6" : s.state === "unreadable" ? "\u767B\u5F55\u6587\u4EF6\u65E0\u6CD5\u8BFB\u53D6\uFF0C\u8BF7\u5728\u5BA2\u6237\u7AEF\u91CD\u65B0\u767B\u5F55\u540E\u91CD\u8BD5" : "\u672A\u68C0\u6D4B\u5230\u767B\u5F55\uFF0C\u8BF7\u5148\u767B\u5F55\u5B98\u65B9\u5BA2\u6237\u7AEF" })
|
|
2576
|
-
] }, s.provider)) }),
|
|
2577
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "row", children: [
|
|
2578
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { className: "primary", disabled: busy || discovering, onClick: () => {
|
|
2579
|
-
void act({ action: "accounts.discover" });
|
|
2580
|
-
}, children: "\u4E00\u952E\u83B7\u53D6\u5E76\u4FDD\u5B58 WorkBuddy / Trae" }),
|
|
2581
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: busy, onClick: () => go("accounts"), children: "\u67E5\u770B\u8D26\u53F7 / \u624B\u52A8\u6DFB\u52A0" }),
|
|
2582
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: busy, onClick: () => go("routes"), children: "\u9009\u62E9\u8DEF\u7531\u6A21\u578B" })
|
|
2583
|
-
] }),
|
|
2584
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u9996\u6B21\u542F\u52A8\u81EA\u52A8\u6267\u884C\u4E00\u6B21\uFF0C\u4E4B\u540E\u6BCF\u5206\u949F\u68C0\u6D4B\u65B0\u589E\u767B\u5F55\u3002Qoder \u4F7F\u7528 PAT\uFF0C\u8BF7\u5230\u300C\u8D26\u53F7\u4E0E\u767B\u5F55\u300D\u6DFB\u52A0\uFF1B\u672A\u5B89\u88C5\u5BA2\u6237\u7AEF\u4E5F\u53EF\u4EE5\u624B\u52A8\u586B\u5199\u51ED\u8BC1\u3002" })
|
|
2585
|
-
] });
|
|
2586
|
-
}
|
|
2587
|
-
var updateNames = { unchecked: "\u5F85\u68C0\u67E5", available: "\u53EF\u66F4\u65B0", current: "\u5DF2\u540C\u6B65", pinned: "\u56FA\u5B9A\u63D0\u4EA4", unsupported: "\u672C\u5730\u6765\u6E90", failed: "\u68C0\u67E5 / \u5B89\u88C5\u5931\u8D25", installed: "\u5DF2\u5B89\u88C5" };
|
|
2588
|
-
function PluginUpdatesPanel({ data, busy, act }) {
|
|
2589
|
-
const [query, setQuery] = (0, import_react.useState)(""), [selected, setSelected] = (0, import_react.useState)([]), [plan, setPlan] = (0, import_react.useState)(null), [registry, setRegistry] = (0, import_react.useState)(""), [filter, setFilter] = (0, import_react.useState)("all"), [pluginSearch, setPluginSearch] = (0, import_react.useState)("");
|
|
2590
|
-
const [diagnostic, setDiagnostic] = (0, import_react.useState)(null), [copied, setCopied] = (0, import_react.useState)(false);
|
|
2591
|
-
const running = data?.job?.state === "running", blocked = busy || running;
|
|
2592
|
-
const rows = (data?.rows ?? []).filter((r) => r.source.kind !== "builtin"), available = rows.filter((r) => r.status === "available" || r.status === "failed" && r.target);
|
|
2593
|
-
(0, import_react.useEffect)(() => {
|
|
2594
|
-
if (data?.available && !running) void act({ action: !data.checkedAt || Date.now() - data.checkedAt > 864e5 ? "plugins.check" : "plugins.list" });
|
|
2595
|
-
}, []);
|
|
2596
|
-
const chosen = available.filter((r) => selected.includes(r.name));
|
|
2597
|
-
const freshVersions = plan?.kind === "update" ? [...new Set(plan.rows.filter((r) => r.source.kind === "npm" && r.latestVersion).map((r) => `${r.source.package}@${r.latestVersion}`))] : [];
|
|
2598
|
-
const visibleRows = rows.filter((r) => r.name.toLowerCase().includes(pluginSearch.toLowerCase()) && (filter === "all" || (filter === "updates" ? available.includes(r) : r.source.kind === filter)));
|
|
2599
|
-
async function submitPlan() {
|
|
2600
|
-
if (await act(plan.kind === "install" ? { action: "plugins.install", spec: plan.spec, registry: registry || void 0 } : { action: "plugins.update", names: plan.rows.map((r) => r.name), registry: registry || void 0, allowFreshVersions: plan.allowFresh !== false ? freshVersions : [] })) {
|
|
2601
|
-
setPlan(null);
|
|
2602
|
-
setSelected([]);
|
|
2603
|
-
}
|
|
2604
|
-
}
|
|
2605
|
-
if (!data?.available) return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "box stack", children: [
|
|
2606
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { children: "\u5F53\u524D DSH \u672A\u63D0\u4F9B\u63D2\u4EF6\u7BA1\u7406\u63A5\u53E3" }),
|
|
2607
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: "\u8BF7\u5347\u7EA7 DeepSeek Harness \u540E\u91CD\u8BD5\u3002\u672C\u9875\u7BA1\u7406\u5F53\u524D DSH \u914D\u7F6E\u4E2D\u7531\u7528\u6237\u5B89\u88C5\u7684\u63D2\u4EF6\u3002" })
|
|
2608
|
-
] });
|
|
2609
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "stack", children: [
|
|
2610
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "box stack", children: [
|
|
2611
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bar", children: [
|
|
2612
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
2613
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { children: "\u7528\u6237\u5B89\u88C5\u7684\u63D2\u4EF6\u4E0E\u66F4\u65B0" }),
|
|
2614
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "notice", children: [
|
|
2615
|
-
rows.length,
|
|
2616
|
-
" \u4E2A\u7528\u6237\u5B89\u88C5\u63D2\u4EF6 \xB7 ",
|
|
2617
|
-
available.length,
|
|
2618
|
-
" \u4E2A\u53EF\u66F4\u65B0"
|
|
2619
|
-
] })
|
|
2620
|
-
] }),
|
|
2621
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { className: "primary", disabled: blocked, onClick: () => {
|
|
2622
|
-
void act({ action: "plugins.check" });
|
|
2623
|
-
}, children: "\u68C0\u67E5\u5168\u90E8\u66F4\u65B0" })
|
|
2624
|
-
] }),
|
|
2625
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "notice", children: [
|
|
2626
|
-
"\u4E0A\u6B21\u68C0\u67E5 ",
|
|
2627
|
-
when(data.checkedAt),
|
|
2628
|
-
" \xB7 \u6BCF\u5929\u81EA\u52A8\u68C0\u67E5\u5E76\u63D0\u9192"
|
|
2629
|
-
] }),
|
|
2630
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("details", { className: "help", children: [
|
|
2631
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("summary", { children: "\u5B89\u88C5\u6E90\u4E0E\u68C0\u67E5\u89C4\u5219" }),
|
|
2632
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "stack", children: [
|
|
2633
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "filter", children: [
|
|
2634
|
-
"npm \u5B89\u88C5\u6E90",
|
|
2635
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", { value: registry, disabled: blocked, onChange: (e) => setRegistry(e.target.value), children: [
|
|
2636
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "", children: "DSH \u8BBE\u7F6E\uFF08\u542B\u56DE\u9000\u6765\u6E90\uFF09" }),
|
|
2637
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "https://registry.npmjs.org/", children: "npm \u5B98\u65B9" }),
|
|
2638
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "https://registry.npmmirror.com/", children: "npmmirror" })
|
|
2639
|
-
] })
|
|
2640
|
-
] }),
|
|
2641
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "npm \u6309\u7248\u672C / \u53D1\u5E03\u9891\u9053\u68C0\u67E5\uFF0CGitHub \u6309\u5206\u652F\u63D0\u4EA4\u68C0\u67E5\uFF1B\u4FDD\u7559\u542F\u7528\u72B6\u6001\uFF0C\u56FA\u5B9A Git \u63D0\u4EA4\u4FDD\u6301\u4E0D\u52A8\u3002" })
|
|
2642
|
-
] })
|
|
2643
|
-
] })
|
|
2644
|
-
] }),
|
|
2645
|
-
data.job && !(data.job.kind === "check" && data.job.state === "done") && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "box stack", "aria-live": "polite", children: [
|
|
2646
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bar", children: [
|
|
2647
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { children: running ? data.job.kind === "check" ? "\u6B63\u5728\u68C0\u67E5\u66F4\u65B0\u2026" : "\u6B63\u5728\u5B89\u88C5\u63D2\u4EF6\u2026" : data.job.state === "cancelled" ? "\u64CD\u4F5C\u5DF2\u53D6\u6D88" : data.job.state === "failed" || data.job.results.some((r) => r.status === "failed") ? "\u6709\u63D2\u4EF6\u672A\u5B8C\u6210\u5B89\u88C5" : "\u64CD\u4F5C\u5DF2\u5B8C\u6210" }),
|
|
2648
|
-
running && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: busy, onClick: () => {
|
|
2649
|
-
void act({ action: "plugins.cancel" });
|
|
2650
|
-
}, children: "\u53D6\u6D88" })
|
|
2651
|
-
] }),
|
|
2652
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("progress", { max: Math.max(1, data.job.total), value: data.job.results.length, "aria-label": "\u63D2\u4EF6\u64CD\u4F5C\u8FDB\u5EA6" }),
|
|
2653
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "notice", children: [
|
|
2654
|
-
data.job.results.length,
|
|
2655
|
-
" / ",
|
|
2656
|
-
data.job.total,
|
|
2657
|
-
data.job.current ? ` \xB7 ${data.job.current}` : ""
|
|
2658
|
-
] }),
|
|
2659
|
-
data.job.message && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "error", children: data.job.message }),
|
|
2660
|
-
data.job.results.map((r, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "item", children: [
|
|
2661
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: r.name }),
|
|
2662
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: r.status === "failed" ? "error" : "notice", children: r.message || updateNames[r.status] || r.status }),
|
|
2663
|
-
r.diagnostic && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", onClick: () => {
|
|
2664
|
-
setCopied(false);
|
|
2665
|
-
setDiagnostic(JSON.stringify({ plugin: r.name, targetVersion: r.expectedVersion, ...r.diagnostic }, null, 2));
|
|
2666
|
-
}, children: "\u67E5\u770B\u8131\u654F\u8BCA\u65AD" }),
|
|
2667
|
-
r.pendingBuilds?.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "notice", children: [
|
|
2668
|
-
"\u5F85\u6388\u6743\u811A\u672C\uFF1A",
|
|
2669
|
-
r.pendingBuilds.join("\u3001"),
|
|
2670
|
-
"\u3002\u8BF7\u5728 DSH \u539F\u63D2\u4EF6\u5B89\u88C5\u9875\u6388\u6743\u540E\u91CD\u8BD5\u3002"
|
|
2671
|
-
] })
|
|
2672
|
-
] }, r.name + i)),
|
|
2673
|
-
data.job.results.some((r) => r.restartRequired) && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "steps", children: "\u66F4\u65B0\u6587\u4EF6\u5DF2\u5B89\u88C5\u3002macOS \u4F7F\u7528 \u2318Q \u5B8C\u5168\u9000\u51FA DSH \u540E\u91CD\u5F00\uFF1BWindows \u9000\u51FA\u6258\u76D8\u5E94\u7528\u540E\u91CD\u5F00\uFF1B\u7F51\u9875\u7248\u91CD\u542F\u670D\u52A1\u3002\u5173\u95ED\u7A97\u53E3\u548C\u300C\u5237\u65B0\u9762\u677F\u300D\u4E0D\u4F1A\u91CD\u8F7D\u540E\u53F0\u3002" })
|
|
2674
|
-
] }),
|
|
2675
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "box table-shell", children: [
|
|
2676
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bar section-pad", children: [
|
|
2677
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "row", children: [
|
|
2678
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: blocked || !available.length, onClick: () => setSelected(available.map((r) => r.name)), children: "\u9009\u62E9\u5168\u90E8\u53EF\u66F4\u65B0" }),
|
|
2679
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: blocked || !selected.length, onClick: () => setSelected([]), children: "\u6E05\u7A7A\u9009\u62E9" })
|
|
2680
|
-
] }),
|
|
2681
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", { className: "primary", disabled: blocked || !chosen.length, onClick: () => setPlan({ kind: "update", rows: chosen }), children: [
|
|
2682
|
-
"\u66F4\u65B0\u6240\u9009\uFF08",
|
|
2683
|
-
chosen.length,
|
|
2684
|
-
"\uFF09"
|
|
2685
|
-
] })
|
|
2686
|
-
] }),
|
|
2687
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "row section-pad", children: [
|
|
2688
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: { flex: 1 }, children: [
|
|
2689
|
-
"\u641C\u7D22\u5DF2\u5B89\u88C5\u63D2\u4EF6",
|
|
2690
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { value: pluginSearch, onChange: (e) => setPluginSearch(e.target.value), placeholder: "\u6309\u63D2\u4EF6\u540D\u79F0\u7B5B\u9009" })
|
|
2691
|
-
] }),
|
|
2692
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "filter", children: [
|
|
2693
|
-
"\u663E\u793A\u8303\u56F4",
|
|
2694
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", { value: filter, onChange: (e) => setFilter(e.target.value), children: [
|
|
2695
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "all", children: "\u5168\u90E8\u7528\u6237\u5B89\u88C5\u63D2\u4EF6" }),
|
|
2696
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "updates", children: "\u53EF\u66F4\u65B0 / \u91CD\u8BD5" }),
|
|
2697
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "npm", children: "npm \u6765\u6E90" }),
|
|
2698
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "github", children: "GitHub \u6765\u6E90" })
|
|
2699
|
-
] })
|
|
2700
|
-
] })
|
|
2701
|
-
] }),
|
|
2702
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "scroll", role: "region", "aria-label": "\u7528\u6237\u5B89\u88C5\u63D2\u4EF6\u5217\u8868", tabIndex: "0", children: [
|
|
2703
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("table", { className: "table", children: [
|
|
2704
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tr", { children: [
|
|
2705
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { scope: "col", children: "\u63D2\u4EF6 / \u9009\u62E9" }),
|
|
2706
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { scope: "col", children: "\u6765\u6E90\u4E0E\u7248\u672C" }),
|
|
2707
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { scope: "col", children: "\u72B6\u6001" }),
|
|
2708
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { scope: "col", className: "cell-actions", children: "\u64CD\u4F5C" })
|
|
2709
|
-
] }) }),
|
|
2710
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("tbody", { children: visibleRows.map((r) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tr", { className: selected.includes(r.name) ? "selected" : "", children: [
|
|
2711
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("td", { children: [
|
|
2712
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "check", children: [
|
|
2713
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { "aria-label": `\u9009\u62E9\u66F4\u65B0 ${r.name}`, type: "checkbox", disabled: blocked || !available.includes(r), checked: selected.includes(r.name), onChange: (e) => setSelected(e.target.checked ? [...selected, r.name] : selected.filter((n) => n !== r.name)) }),
|
|
2714
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { className: "mono", children: r.name })
|
|
2715
|
-
] }),
|
|
2716
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("small", { className: "muted", children: r.enabled ? "\u542F\u7528" : "\u505C\u7528" })
|
|
2717
|
-
] }),
|
|
2718
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("td", { children: [
|
|
2719
|
-
r.source.kind === "npm" ? `npm \xB7 ${r.version || "\u672A\u77E5"}${r.latestVersion ? " \u2192 " + r.latestVersion : ""}` : r.source.kind === "github" ? `GitHub \xB7 ${r.version || "\u672A\u77E5\u7248\u672C"}` : "\u672C\u5730\u6587\u4EF6 / \u5F00\u53D1\u94FE\u63A5",
|
|
2720
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("small", { className: "muted mono", children: r.source.kind === "npm" ? `\u5B89\u88C5\u58F0\u660E ${r.source.source} \xB7 \u68C0\u67E5 ${r.source.tag}` : r.source.kind === "github" ? `${r.commit?.slice(0, 8) || "\u672A\u77E5\u63D0\u4EA4"}${r.latestCommit ? " \u2192 " + r.latestCommit.slice(0, 8) : ""}` : "" })
|
|
2721
|
-
] }),
|
|
2722
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("td", { children: [
|
|
2723
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: r.status === "failed" ? "error" : r.status === "available" ? "good" : "muted", children: updateNames[r.status] }),
|
|
2724
|
-
r.message && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("small", { className: r.status === "failed" ? "error" : "muted", children: r.message })
|
|
2725
|
-
] }),
|
|
2726
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "cell-actions", children: available.includes(r) ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: blocked, onClick: () => setPlan({ kind: "update", rows: [r] }), children: "\u67E5\u770B\u5E76\u66F4\u65B0" }) : "\u2014" })
|
|
2727
|
-
] }, r.name)) })
|
|
2728
|
-
] }),
|
|
2729
|
-
!visibleRows.length && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "empty", children: running ? "\u6B63\u5728\u8BFB\u53D6\u63D2\u4EF6\u6E05\u5355\u2026" : rows.length ? "\u6CA1\u6709\u5339\u914D\u7684\u5DF2\u5B89\u88C5\u63D2\u4EF6\uFF0C\u8BF7\u8C03\u6574\u7B5B\u9009\u3002" : "\u5F53\u524D\u914D\u7F6E\u5C1A\u672A\u8BFB\u53D6\u63D2\u4EF6\uFF0C\u8BF7\u68C0\u67E5\u66F4\u65B0\u3002" })
|
|
2730
|
-
] })
|
|
2731
|
-
] }),
|
|
2732
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("details", { className: "box help install-plugin", children: [
|
|
2733
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("summary", { children: "\u5B89\u88C5 npm / GitHub \u63D2\u4EF6" }),
|
|
2734
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "stack", children: [
|
|
2735
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("form", { className: "row", onSubmit: (e) => {
|
|
2736
|
-
e.preventDefault();
|
|
2737
|
-
const spec = new FormData(e.currentTarget).get("spec").trim();
|
|
2738
|
-
if (spec) setPlan({ kind: "install", spec });
|
|
2739
|
-
}, children: [
|
|
2740
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: { flex: 1 }, children: [
|
|
2741
|
-
"\u5B89\u88C5\u5730\u5740",
|
|
2742
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { name: "spec", value: query, onChange: (e) => setQuery(e.target.value), disabled: blocked, required: true, placeholder: "\u5305\u540D\u3001\u5305\u540D@\u7248\u672C \u6216 github:\u7528\u6237/\u4ED3\u5E93", autoComplete: "off" })
|
|
2743
|
-
] }),
|
|
2744
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: blocked || !query.trim(), children: "\u67E5\u770B\u5E76\u5B89\u88C5" })
|
|
2745
|
-
] }),
|
|
2746
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u4F7F\u7528 DSH \u81EA\u5E26\u5B89\u88C5\u5668\u6267\u884C\u517C\u5BB9\u68C0\u67E5\u3001\u955C\u50CF\u91CD\u8BD5\u548C\u5931\u8D25\u56DE\u6EDA\u3002npm \u955C\u50CF\u53EA\u4F5C\u7528\u4E8E npm \u5305\uFF0CGitHub \u4E0B\u8F7D\u5931\u8D25\u9700\u68C0\u67E5 GitHub \u7F51\u7EDC\u3002\u7F51\u7EDC\u5931\u8D25\u540E\u53EF\u91CD\u65B0\u68C0\u67E5\u6216\u66F4\u6362 npm \u5B89\u88C5\u6E90\u518D\u91CD\u8BD5\u3002" })
|
|
2747
|
-
] })
|
|
2748
|
-
] }),
|
|
2749
|
-
diagnostic && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Modal, { title: "\u63D2\u4EF6\u5B89\u88C5\u8BCA\u65AD", close: () => setDiagnostic(null), children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "modal-body stack", children: [
|
|
2750
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u4EE5\u4E0B\u4FE1\u606F\u53EA\u542B\u63D2\u4EF6\u540D\u3001\u7248\u672C\u3001\u7CFB\u7EDF\u548C\u9519\u8BEF\u5206\u7C7B\uFF0C\u53EF\u590D\u5236\u7528\u4E8E\u6392\u67E5\uFF1B\u672A\u5305\u542B\u539F\u59CB\u65E5\u5FD7\u3001\u7528\u6237\u540D\u8DEF\u5F84\u6216\u51ED\u8BC1\u3002\u82E5\u539F\u56E0\u672A\u77E5\uFF0C\u8BF7\u5728 DSH \u539F\u751F\u63D2\u4EF6\u9875\u83B7\u53D6\u5B89\u88C5\u65E5\u5FD7\u3002" }),
|
|
2751
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("textarea", { "aria-label": "\u8131\u654F\u5B89\u88C5\u8BCA\u65AD", readOnly: true, rows: "9", value: diagnostic, onFocus: (e) => e.currentTarget.select() }),
|
|
2752
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { onClick: async () => {
|
|
2753
|
-
try {
|
|
2754
|
-
await navigator.clipboard.writeText(diagnostic);
|
|
2755
|
-
setCopied(true);
|
|
2756
|
-
} catch {
|
|
2757
|
-
setCopied(false);
|
|
2758
|
-
}
|
|
2759
|
-
}, children: copied ? "\u5DF2\u590D\u5236" : "\u590D\u5236\u8BCA\u65AD" })
|
|
2760
|
-
] }) }),
|
|
2761
|
-
plan && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Modal, { title: plan.kind === "install" ? "\u786E\u8BA4\u5B89\u88C5\u63D2\u4EF6" : "\u786E\u8BA4\u66F4\u65B0\u63D2\u4EF6", close: () => setPlan(null), busy: blocked, children: [
|
|
2762
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "modal-body stack", children: [
|
|
2763
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: "\u8FD9\u4E9B\u64CD\u4F5C\u4F5C\u7528\u4E8E\u5F53\u524D DSH \u914D\u7F6E\u7684\u6240\u6709\u4F1A\u8BDD\u3002\u5B89\u88C5\u540E\u662F\u5426\u9700\u8981\u91CD\u542F\uFF0C\u4F1A\u5728\u7ED3\u679C\u4E2D\u8BF4\u660E\u3002" }),
|
|
2764
|
-
plan.kind === "install" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "mono", children: plan.spec }) : plan.rows.map((r) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "steps", children: [
|
|
2765
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: r.name }),
|
|
2766
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "mono", children: r.target }),
|
|
2767
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: r.source.kind === "npm" ? `${r.version || "\u672A\u77E5"} \u2192 ${r.latestVersion}` : `${r.commit?.slice(0, 8) || "\u672A\u77E5\u63D0\u4EA4"} \u2192 ${r.latestCommit?.slice(0, 8) || "\u672A\u77E5\u63D0\u4EA4"}` }),
|
|
2768
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "notice", children: [
|
|
2769
|
-
"\u4FDD\u7559\u4E3A",
|
|
2770
|
-
r.enabled ? "\u542F\u7528" : "\u505C\u7528",
|
|
2771
|
-
"\uFF1B",
|
|
2772
|
-
r.source.kind === "github" ? "\u7EE7\u7EED\u8DDF\u968F\u539F\u5206\u652F / \u6807\u7B7E" : "\u66F4\u65B0\u5230\u6240\u793A npm \u7248\u672C",
|
|
2773
|
-
"\u3002"
|
|
2774
|
-
] })
|
|
2775
|
-
] }, r.name)),
|
|
2776
|
-
freshVersions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "steps stack", children: [
|
|
2777
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "check", children: [
|
|
2778
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "checkbox", disabled: blocked, checked: plan.allowFresh !== false, onChange: (e) => setPlan((p) => ({ ...p, allowFresh: e.target.checked })) }),
|
|
2779
|
-
"\u5141\u8BB8\u672C\u6B21\u6307\u5B9A\u7248\u672C\u7ACB\u5373\u5B89\u88C5\uFF08\u4E0D\u7B49\u5F85 24 \u5C0F\u65F6\uFF09"
|
|
2780
|
-
] }),
|
|
2781
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "notice", children: [
|
|
2782
|
-
"\u786E\u8BA4\u66F4\u65B0\u540E\uFF0C\u4EC5\u4E3A\u4EE5\u4E0B\u7248\u672C\u4FDD\u5B58\u7B49\u5F85\u671F\u4F8B\u5916\uFF1A",
|
|
2783
|
-
freshVersions.join("\u3001"),
|
|
2784
|
-
"\u3002\u65B0\u5305\u7B49\u5F85\u671F\u7528\u4E8E\u964D\u4F4E\u4F9B\u5E94\u94FE\u98CE\u9669\uFF1B\u5176\u4ED6\u7248\u672C\u3001\u4F9D\u8D56\u548C\u811A\u672C\u6388\u6743\u4ECD\u9075\u5B88 DSH \u7B56\u7565\u3002\u53EF\u53D6\u6D88\u52FE\u9009\uFF0C\u7EE7\u7EED\u9075\u5B88\u7B49\u5F85\u671F\u3002"
|
|
2785
|
-
] })
|
|
2786
|
-
] }),
|
|
2787
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "notice", children: [
|
|
2788
|
-
"npm \u5B89\u88C5\u6E90\uFF1A",
|
|
2789
|
-
registry || "\u6CBF\u7528 DSH \u8BBE\u7F6E"
|
|
2790
|
-
] })
|
|
2791
|
-
] }),
|
|
2792
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "modal-foot row", children: [
|
|
2793
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", { className: "primary", disabled: blocked, onClick: () => {
|
|
2794
|
-
void submitPlan();
|
|
2795
|
-
}, children: [
|
|
2796
|
-
"\u786E\u8BA4",
|
|
2797
|
-
plan.kind === "install" ? "\u5B89\u88C5" : "\u66F4\u65B0"
|
|
2798
|
-
] }),
|
|
2799
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: blocked, onClick: () => setPlan(null), children: "\u53D6\u6D88" })
|
|
2800
|
-
] })
|
|
2801
|
-
] })
|
|
2802
|
-
] });
|
|
2803
|
-
}
|
|
2804
|
-
return module.exports; } });
|
|
2805
|
-
//# sourceMappingURL=client.js.map
|