@ljwei-stak/dsh-model-router 0.14.0-beta.4 → 0.15.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/.dsh-plugin/client.js +246 -73
- package/.dsh-plugin/index.mjs +9 -9
- package/.dsh-plugin/shared/router-state.mjs +17 -7
- package/.dsh-plugin/shared/run-ledger.mjs +88 -24
- package/CHANGELOG.md +22 -38
- package/INSTALLATION_GUIDE.zh.md +36 -28
- package/MIGRATION.md +3 -3
- package/README.md +154 -364
- package/README.zh.md +154 -355
- package/docs/WORKBENCH_USER_GUIDE.zh.md +170 -0
- package/docs/assets/workbench-task-preview.jpg +0 -0
- package/package.json +4 -1
package/.dsh-plugin/client.js
CHANGED
|
@@ -1464,6 +1464,24 @@ function createPlanFromRoutes(task, availableRoutes, {
|
|
|
1464
1464
|
// .dsh-plugin/shared/run-ledger.mjs
|
|
1465
1465
|
var finite = (value) => typeof value === "number" && Number.isFinite(value);
|
|
1466
1466
|
var routeKey2 = (provider, model) => `${String(provider ?? "")}\0${String(model ?? "")}`;
|
|
1467
|
+
var MAX_SPENDING_DAYS = 90;
|
|
1468
|
+
var MAX_SPENDING_MONTHS = 24;
|
|
1469
|
+
function periodSpending(value) {
|
|
1470
|
+
const amount = (field2) => finite(value?.[field2]) && value[field2] >= 0 ? value[field2] : 0;
|
|
1471
|
+
return {
|
|
1472
|
+
costUsd: amount("costUsd"),
|
|
1473
|
+
unknown: Math.floor(amount("unknown")),
|
|
1474
|
+
subscriptionUsd: amount("subscriptionUsd"),
|
|
1475
|
+
subscriptionRuns: Math.floor(amount("subscriptionRuns"))
|
|
1476
|
+
};
|
|
1477
|
+
}
|
|
1478
|
+
function sanitizeArchivedSpending(value) {
|
|
1479
|
+
const periods = (entries, pattern, limit) => Object.fromEntries(Object.entries(entries && typeof entries === "object" && !Array.isArray(entries) ? entries : {}).filter(([key, entry]) => pattern.test(key) && entry && typeof entry === "object" && !Array.isArray(entry)).sort(([left], [right]) => left.localeCompare(right)).slice(-limit).map(([key, entry]) => [key, periodSpending(entry)]));
|
|
1480
|
+
return {
|
|
1481
|
+
days: periods(value?.days, /^\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01])$/, MAX_SPENDING_DAYS),
|
|
1482
|
+
months: periods(value?.months, /^\d{4}-(?:0[1-9]|1[0-2])$/, MAX_SPENDING_MONTHS)
|
|
1483
|
+
};
|
|
1484
|
+
}
|
|
1467
1485
|
function formatUsd(value) {
|
|
1468
1486
|
return typeof value === "number" && Number.isFinite(value) ? `$${value.toFixed(4)}` : "\u2014";
|
|
1469
1487
|
}
|
|
@@ -1846,11 +1864,23 @@ function packageCost(item) {
|
|
|
1846
1864
|
}
|
|
1847
1865
|
return { budget: item?.ran ? "\u8D39\u7528\u672A\u77E5" : "\u2014", reference: null };
|
|
1848
1866
|
}
|
|
1867
|
+
function priorAttemptTotals(run) {
|
|
1868
|
+
const months = sanitizeArchivedSpending(run?.priorAttemptSpending).months;
|
|
1869
|
+
const totals = { budgetUsd: 0, referenceUsd: 0, unknownCalls: 0, subscriptionRuns: 0 };
|
|
1870
|
+
for (const period of Object.values(months)) {
|
|
1871
|
+
totals.budgetUsd += period.costUsd;
|
|
1872
|
+
totals.referenceUsd += period.subscriptionUsd;
|
|
1873
|
+
totals.unknownCalls += period.unknown;
|
|
1874
|
+
totals.subscriptionRuns += period.subscriptionRuns;
|
|
1875
|
+
}
|
|
1876
|
+
return totals;
|
|
1877
|
+
}
|
|
1849
1878
|
function runTotals(run) {
|
|
1850
1879
|
const items = [...run?.packages ?? [], ...run?.reviews ?? []];
|
|
1851
|
-
|
|
1852
|
-
let
|
|
1853
|
-
let
|
|
1880
|
+
const prior = priorAttemptTotals(run);
|
|
1881
|
+
let budgetUsd = prior.budgetUsd;
|
|
1882
|
+
let referenceUsd = prior.referenceUsd;
|
|
1883
|
+
let subscription = prior.subscriptionRuns > 0;
|
|
1854
1884
|
for (const item of items) {
|
|
1855
1885
|
if (item.billing === "subscription") {
|
|
1856
1886
|
subscription = true;
|
|
@@ -2081,7 +2111,10 @@ function RunHistoryCard({ ledger, routes, onRefresh, onRate, onRerun, busy, erro
|
|
|
2081
2111
|
const runs = ledger?.runs ?? [];
|
|
2082
2112
|
const [openId, setOpenId] = import_react2.default.useState(null);
|
|
2083
2113
|
const current = runs.find((run) => run.id === openId) ?? runs[0];
|
|
2084
|
-
|
|
2114
|
+
const totals = runTotals(current);
|
|
2115
|
+
const prior = priorAttemptTotals(current);
|
|
2116
|
+
const unknownCalls = prior.unknownCalls + [...current?.packages ?? [], ...current?.reviews ?? []].filter((item) => item.ran && item.billing !== "subscription" && !Number.isFinite(item.costUsd)).length;
|
|
2117
|
+
return /* @__PURE__ */ import_react2.default.createElement("section", { className: "mr-card mr-results", "aria-label": "\u6267\u884C\u8BB0\u5F55" }, /* @__PURE__ */ import_react2.default.createElement("div", { className: "mr-card-head" }, /* @__PURE__ */ import_react2.default.createElement("div", null, /* @__PURE__ */ import_react2.default.createElement("h2", { className: "mr-card-title" }, "\u6267\u884C\u8BB0\u5F55\u4E0E\u5B50\u4EFB\u52A1"), /* @__PURE__ */ import_react2.default.createElement("p", { className: "mr-card-copy" }, "\u67E5\u770B\u6A21\u578B\u5206\u914D\u3001\u9010\u6B65\u7ED3\u679C\u4E0E\u8D39\u7528\u3002\u5931\u8D25\u6B65\u9AA4\u53EF\u91CD\u8DD1\u6216\u6539\u6D3E\uFF1B\u5DF2\u5B8C\u6210\u7684\u4E0A\u6E38\u4FDD\u6301\u539F\u7ED3\u679C\u3002")), /* @__PURE__ */ import_react2.default.createElement("button", { className: "mr-button mr-button-secondary", type: "button", disabled: busy, onClick: onRefresh }, "\u5237\u65B0")), /* @__PURE__ */ import_react2.default.createElement("div", { className: "mr-card-body" }, error && /* @__PURE__ */ import_react2.default.createElement("p", { className: "mr-error", role: "alert" }, error), !ledger && !error && /* @__PURE__ */ import_react2.default.createElement("p", { className: "mr-empty", role: "status" }, "\u6B63\u5728\u8BFB\u53D6\u6267\u884C\u8BB0\u5F55\u2026"), ledger && runs.length === 0 && /* @__PURE__ */ import_react2.default.createElement("p", { className: "mr-empty" }, "\u8FD8\u6CA1\u6709\u6267\u884C\u8BB0\u5F55\u3002\u53EF\u5728\u4E0A\u65B9\u201C\u5728\u5DE5\u4F5C\u53F0\u6267\u884C\u201D\u4E2D\u9884\u89C8\u5E76\u6267\u884C\uFF0C\u6216\u5728\u5B98\u65B9\u4F1A\u8BDD\u4E2D\u8C03\u7528 model_router_execute\u3001model_router_team_execute\u3001model_router_tool_run\uFF0C\u8FD9\u91CC\u4F1A\u663E\u793A\u51B3\u7B56\u548C\u7ED3\u679C\u3002"), runs.length > 0 && /* @__PURE__ */ import_react2.default.createElement(import_react2.default.Fragment, null, /* @__PURE__ */ import_react2.default.createElement("label", { className: "mr-label", htmlFor: "mr-run-select" }, "\u9009\u62E9\u8BB0\u5F55"), /* @__PURE__ */ import_react2.default.createElement("select", { className: "mr-input", id: "mr-run-select", value: current?.id ?? "", onChange: (event) => setOpenId(event.target.value) }, runs.map((run) => /* @__PURE__ */ import_react2.default.createElement("option", { key: run.id, value: run.id }, new Date(run.createdAt).toLocaleString(), " \xB7 ", RUN_KIND_LABEL[run.kind ?? "assign"] ?? run.kind, " \xB7 ", RUN_STATUS_LABEL[run.status] ?? run.status, " \xB7 ", run.task.slice(0, 40)))), current && /* @__PURE__ */ import_react2.default.createElement("div", { className: "mr-run" }, /* @__PURE__ */ import_react2.default.createElement("div", { className: "mr-result-grid" }, /* @__PURE__ */ import_react2.default.createElement("div", { className: "mr-metric" }, /* @__PURE__ */ import_react2.default.createElement("div", { className: "mr-metric-label" }, "\u65B9\u6848"), /* @__PURE__ */ import_react2.default.createElement("div", { className: "mr-metric-value" }, ROUTING_PRESETS[current.preset]?.label ?? current.preset, current.budget?.downgraded ? "\uFF08\u8D85\u9884\u7B97\u81EA\u52A8\u964D\u7EA7\uFF09" : "")), /* @__PURE__ */ import_react2.default.createElement("div", { className: "mr-metric" }, /* @__PURE__ */ import_react2.default.createElement("div", { className: "mr-metric-label" }, "\u96BE\u5EA6"), /* @__PURE__ */ import_react2.default.createElement("div", { className: "mr-metric-value" }, BAND[current.decision?.complexity?.band] ?? "\u2014", current.decision?.complexity?.value !== null && current.decision?.complexity?.value !== void 0 ? ` \xB7 ${current.decision.complexity.value}` : "")), /* @__PURE__ */ import_react2.default.createElement("div", { className: "mr-metric" }, /* @__PURE__ */ import_react2.default.createElement("div", { className: "mr-metric-label" }, "\u9884\u4F30 / ", unknownCalls ? "\u5DF2\u77E5\u5B9E\u9645" : "\u5B9E\u9645", "\uFF08\u8BA1\u5165\u9884\u7B97\uFF09"), /* @__PURE__ */ import_react2.default.createElement("div", { className: "mr-metric-value" }, money(current.decision?.estimatedCost), " / ", money(totals.budgetUsd))), /* @__PURE__ */ import_react2.default.createElement("div", { className: "mr-metric" }, /* @__PURE__ */ import_react2.default.createElement("div", { className: "mr-metric-label" }, "\u7C7B\u578B"), /* @__PURE__ */ import_react2.default.createElement("div", { className: "mr-metric-value" }, RUN_KIND_LABEL[current.kind ?? "assign"] ?? current.kind, current.kind === "team" || current.kind === "tool" ? ` \xB7 ${current.executionMode === "workspace-write" ? "\u53EF\u7F16\u8F91" : "\u53EA\u8BFB"}` : ""))), totals.subscription && /* @__PURE__ */ import_react2.default.createElement("p", { className: "mr-caption" }, "\u8BA2\u9605\u53C2\u8003\u8D39\u7528\uFF08\u6309 API \u4EF7\u6298\u7B97\uFF0C\u4E0D\u8BA1\u5165\u9884\u7B97\uFF09\uFF1A", money(totals.referenceUsd)), unknownCalls > 0 && /* @__PURE__ */ import_react2.default.createElement("p", { className: "mr-caption" }, "\u53E6\u6709 ", unknownCalls, " \u6B21\u8C03\u7528\u8D39\u7528\u672A\u77E5\uFF0C\u672A\u8BA1\u5165\u4E0A\u65B9\u91D1\u989D\u3002"), (prior.budgetUsd > 0 || prior.subscriptionRuns > 0 || prior.unknownCalls > 0) && /* @__PURE__ */ import_react2.default.createElement("p", { className: "mr-caption" }, "\u7D2F\u8BA1\u5305\u542B\u6B64\u524D\u91CD\u8DD1\u5C1D\u8BD5\uFF1AAPI ", money(prior.budgetUsd), " \xB7 \u8BA2\u9605\u53C2\u8003 ", money(prior.referenceUsd), prior.unknownCalls > 0 ? ` \xB7 \u8D39\u7528\u672A\u77E5 ${prior.unknownCalls} \u6B21` : "", "\u3002\u4E0B\u65B9\u8282\u70B9\u663E\u793A\u6700\u8FD1\u4E00\u6B21\u7ED3\u679C\u3002"), current.isolatedWorkspace && /* @__PURE__ */ import_react2.default.createElement("p", { className: "mr-caption" }, "\u72EC\u7ACB\u5DE5\u4F5C\u533A\uFF1A", /* @__PURE__ */ import_react2.default.createElement("code", null, current.isolatedWorkspace)), current.rerunOf && /* @__PURE__ */ import_react2.default.createElement("p", { className: "mr-caption" }, "\u91CD\u65B0\u6267\u884C\u81EA\u8FD0\u884C ", current.rerunOf.slice(0, 8), "\u3002"), current.decision?.reason && /* @__PURE__ */ import_react2.default.createElement("p", { className: "mr-caption" }, "\u8DEF\u7531\u539F\u56E0\uFF1A", current.decision.reason), /* @__PURE__ */ import_react2.default.createElement(DagView, { packages: current.packages, renderNode: (item) => /* @__PURE__ */ import_react2.default.createElement(RunNode, { run: current, item, routes, allowReassign: ledger?.settings?.allowManualReassign !== false, busy, onRate, onRerun }) })))));
|
|
2085
2118
|
}
|
|
2086
2119
|
function BillingCard({ billing, error, onRefresh, refreshing }) {
|
|
2087
2120
|
const rows = billingRows(billing);
|
|
@@ -2104,22 +2137,31 @@ var STATUS_TEXT = Object.freeze({
|
|
|
2104
2137
|
"paused-budget": "\u5DF2\u56E0\u9884\u7B97\u6682\u505C\uFF0C\u672A\u542F\u52A8\u6A21\u578B",
|
|
2105
2138
|
"paused-subscription-failure": "\u6709\u6B65\u9AA4\u56E0\u8BA2\u9605\u8C03\u7528\u5931\u8D25\u800C\u6682\u505C\uFF0C\u8BF7\u5728\u4E0B\u65B9\u6267\u884C\u8BB0\u5F55\u4E2D\u9009\u62E9\u5982\u4F55\u7EE7\u7EED"
|
|
2106
2139
|
});
|
|
2107
|
-
function RunLauncher({ task, mode, directRoute, budgetUsd, defaultPreset, ledger, previewRun, startRun, onStarted, disabledReason }) {
|
|
2140
|
+
function RunLauncher({ task, mode, directRoute, budgetUsd, defaultPreset, ledger, previewRun, startRun, onStarted, disabledReason, planningRevision }) {
|
|
2108
2141
|
const [preset, setPreset] = import_react3.default.useState(defaultPreset || "balanced");
|
|
2109
2142
|
const lastWorkspace = [...ledger?.runs ?? []].map((run) => run.workspace).find(Boolean) ?? "";
|
|
2110
2143
|
const [workspace, setWorkspace] = import_react3.default.useState("");
|
|
2111
2144
|
const [phase, setPhase] = import_react3.default.useState({ kind: "idle" });
|
|
2112
2145
|
const mounted = import_react3.default.useRef(true);
|
|
2113
2146
|
const confirmRef = import_react3.default.useRef(null);
|
|
2114
|
-
import_react3.default.
|
|
2115
|
-
|
|
2147
|
+
const pendingRequest = import_react3.default.useRef(0);
|
|
2148
|
+
const inputSignature = JSON.stringify([task, mode, directRoute?.provider, directRoute?.model, budgetUsd, preset, workspace, lastWorkspace, planningRevision, disabledReason]);
|
|
2149
|
+
const latestSignature = import_react3.default.useRef(inputSignature);
|
|
2150
|
+
latestSignature.current = inputSignature;
|
|
2151
|
+
import_react3.default.useEffect(() => {
|
|
2152
|
+
mounted.current = true;
|
|
2153
|
+
return () => {
|
|
2154
|
+
mounted.current = false;
|
|
2155
|
+
pendingRequest.current += 1;
|
|
2156
|
+
};
|
|
2116
2157
|
}, []);
|
|
2117
2158
|
import_react3.default.useEffect(() => {
|
|
2118
2159
|
setPreset(defaultPreset || "balanced");
|
|
2119
2160
|
}, [defaultPreset]);
|
|
2120
2161
|
import_react3.default.useEffect(() => {
|
|
2121
|
-
|
|
2122
|
-
|
|
2162
|
+
pendingRequest.current += 1;
|
|
2163
|
+
setPhase((previous) => ["previewing", "preview", "error"].includes(previous.kind) ? { kind: "idle" } : previous);
|
|
2164
|
+
}, [inputSignature]);
|
|
2123
2165
|
import_react3.default.useEffect(() => {
|
|
2124
2166
|
if (phase.kind === "preview") confirmRef.current?.focus();
|
|
2125
2167
|
}, [phase.kind]);
|
|
@@ -2128,22 +2170,29 @@ function RunLauncher({ task, mode, directRoute, budgetUsd, defaultPreset, ledger
|
|
|
2128
2170
|
const blocked = disabledReason || (unavailable ? "\u5DE5\u4F5C\u53F0\u6267\u884C\u670D\u52A1\u5C1A\u672A\u52A0\u8F7D\uFF0C\u8BF7\u66F4\u65B0\u63D2\u4EF6\u540E\u91CD\u8BD5\u3002" : !text2(task) ? "\u5148\u5728\u4E0A\u65B9\u201C\u4EFB\u52A1\u89C4\u5212\u201D\u4E2D\u63CF\u8FF0\u4EFB\u52A1\u3002" : "");
|
|
2129
2171
|
const busy = phase.kind === "previewing" || phase.kind === "running";
|
|
2130
2172
|
const preview = async () => {
|
|
2173
|
+
if (blocked || busy) return;
|
|
2174
|
+
const current = ++pendingRequest.current;
|
|
2175
|
+
const snapshot = request();
|
|
2176
|
+
const signature = inputSignature;
|
|
2131
2177
|
setPhase({ kind: "previewing" });
|
|
2132
2178
|
try {
|
|
2133
|
-
const value = unwrapRemote(await previewRun(
|
|
2134
|
-
if (mounted.current) setPhase({ kind: "preview", value });
|
|
2179
|
+
const value = unwrapRemote(await previewRun(snapshot), "\u6267\u884C\u9884\u89C8\u5931\u8D25\u3002");
|
|
2180
|
+
if (mounted.current && current === pendingRequest.current && signature === latestSignature.current) setPhase({ kind: "preview", value, request: snapshot, signature });
|
|
2135
2181
|
} catch (error) {
|
|
2136
|
-
if (mounted.current) setPhase({ kind: "error", message: text2(error?.message) || "\u6267\u884C\u9884\u89C8\u5931\u8D25\u3002" });
|
|
2182
|
+
if (mounted.current && current === pendingRequest.current && signature === latestSignature.current) setPhase({ kind: "error", message: text2(error?.message) || "\u6267\u884C\u9884\u89C8\u5931\u8D25\u3002" });
|
|
2137
2183
|
}
|
|
2138
2184
|
};
|
|
2139
2185
|
const confirm2 = async () => {
|
|
2186
|
+
if (phase.kind !== "preview" || phase.signature !== latestSignature.current) return;
|
|
2140
2187
|
const shown = phase.value;
|
|
2141
|
-
|
|
2188
|
+
const snapshot = phase.request;
|
|
2189
|
+
const signature = phase.signature;
|
|
2190
|
+
setPhase({ kind: "running", value: shown, request: snapshot, signature });
|
|
2142
2191
|
try {
|
|
2143
|
-
const value = unwrapRemote(await startRun({ ...
|
|
2192
|
+
const value = unwrapRemote(await startRun({ ...snapshot, confirmedReasons: (shown.reasons ?? []).map((item) => item.code) }), "\u6267\u884C\u5931\u8D25\u3002");
|
|
2144
2193
|
if (!mounted.current) return;
|
|
2145
2194
|
if (value.status === "needs-confirmation") {
|
|
2146
|
-
setPhase({ kind: "preview", value, changed: true });
|
|
2195
|
+
setPhase(signature === latestSignature.current ? { kind: "preview", value, request: snapshot, signature, changed: true } : { kind: "idle" });
|
|
2147
2196
|
return;
|
|
2148
2197
|
}
|
|
2149
2198
|
setPhase({ kind: "done", value });
|
|
@@ -2166,7 +2215,7 @@ function RunLauncher({ task, mode, directRoute, budgetUsd, defaultPreset, ledger
|
|
|
2166
2215
|
},
|
|
2167
2216
|
onCancel: () => setPhase({ kind: "idle" })
|
|
2168
2217
|
}
|
|
2169
|
-
), phase.kind === "done" && /* @__PURE__ */ import_react3.default.createElement("div", { className: phase.value.status === "failed" || phase.value.status?.startsWith("paused") ? "mr-error" : "mr-empty", role: "status" }, STATUS_TEXT[phase.value.status] ?? `\u72B6\u6001\uFF1A${phase.value.status}`, phase.value.runId ? `\uFF1B\u7ED3\u679C\u5DF2\u8BB0\u5F55\uFF08\u8FD0\u884C ${phase.value.runId.slice(0, 8)}\uFF09\uFF0C\u89C1\u4E0B\u65B9\u201C\u6267\u884C\u8BB0\u5F55\u4E0E\u5B50\u4EFB\u52A1\u201D\u3002` : "\u3002", phase.value.budget?.message ? ` ${phase.value.budget.exceeded && phase.value.status !== "paused-budget" ? "\u5DF2\u6309\u4F60\u7684\u786E\u8BA4\u8D85\u9884\u7B97\u6267\u884C\uFF1A" : ""}${phase.value.budget.message}` : "")));
|
|
2218
|
+
), phase.kind === "done" && /* @__PURE__ */ import_react3.default.createElement("div", { className: phase.value.status === "failed" || phase.value.status === "partial" || phase.value.status?.startsWith("paused") ? "mr-error" : "mr-empty", role: "status" }, STATUS_TEXT[phase.value.status] ?? `\u72B6\u6001\uFF1A${phase.value.status}`, phase.value.runId ? `\uFF1B\u7ED3\u679C\u5DF2\u8BB0\u5F55\uFF08\u8FD0\u884C ${phase.value.runId.slice(0, 8)}\uFF09\uFF0C\u89C1\u4E0B\u65B9\u201C\u6267\u884C\u8BB0\u5F55\u4E0E\u5B50\u4EFB\u52A1\u201D\u3002` : "\u3002", phase.value.budget?.message ? ` ${phase.value.budget.exceeded && phase.value.status !== "paused-budget" ? "\u5DF2\u6309\u4F60\u7684\u786E\u8BA4\u8D85\u9884\u7B97\u6267\u884C\uFF1A" : ""}${phase.value.budget.message}` : "")));
|
|
2170
2219
|
}
|
|
2171
2220
|
function LaunchPreview({ value, changed, running, confirmRef, onConfirm, onCancel }) {
|
|
2172
2221
|
const packages = value.decision?.packages ?? [];
|
|
@@ -11604,7 +11653,7 @@ var xterm_default = `/**
|
|
|
11604
11653
|
`;
|
|
11605
11654
|
|
|
11606
11655
|
// .dsh-plugin/client/host-version.mjs
|
|
11607
|
-
var ROUTER_CLIENT_VERSION = true ? "0.
|
|
11656
|
+
var ROUTER_CLIENT_VERSION = true ? "0.15.0" : "";
|
|
11608
11657
|
var STALE_HOST_MESSAGE = "\u63D2\u4EF6\u540E\u53F0\u7248\u672C\u8F83\u65E7\uFF0C\u8BF7\u5B8C\u5168\u9000\u51FA\u5E76\u91CD\u542F Harness\uFF08\u5305\u62EC\u6258\u76D8\u56FE\u6807\uFF09\u540E\u518D\u4F7F\u7528\u3002";
|
|
11609
11658
|
function isMissingRemoteMethod(message) {
|
|
11610
11659
|
const value = String(message ?? "");
|
|
@@ -12101,62 +12150,64 @@ function CliTerminalCard({ api, health }) {
|
|
|
12101
12150
|
|
|
12102
12151
|
// .dsh-plugin/client/router-main.css
|
|
12103
12152
|
var router_main_default = `.mr-workspace {
|
|
12104
|
-
--mr-card:
|
|
12105
|
-
--mr-ink: #
|
|
12106
|
-
--mr-muted: #
|
|
12107
|
-
--mr-line:
|
|
12108
|
-
--mr-accent: #
|
|
12153
|
+
--mr-card: #fff;
|
|
12154
|
+
--mr-ink: #1e2c3e;
|
|
12155
|
+
--mr-muted: #586b80;
|
|
12156
|
+
--mr-line: #dce4ed;
|
|
12157
|
+
--mr-accent: #2859c5;
|
|
12109
12158
|
--mr-soft: #edf3ff;
|
|
12159
|
+
--mr-surface: #f3f6fa;
|
|
12160
|
+
--mr-button-ink: #fff;
|
|
12161
|
+
container: mr-workspace / inline-size;
|
|
12110
12162
|
box-sizing: border-box;
|
|
12111
12163
|
width: 100%;
|
|
12112
12164
|
height: 100%;
|
|
12113
12165
|
min-height: 0;
|
|
12114
12166
|
overflow-y: auto;
|
|
12115
|
-
background:
|
|
12116
|
-
backdrop-filter: blur(18px);
|
|
12167
|
+
background: var(--mr-surface);
|
|
12117
12168
|
color: var(--mr-ink);
|
|
12118
12169
|
font-family: inherit;
|
|
12119
12170
|
}
|
|
12120
12171
|
.mr-workspace *, .mr-workspace *::before, .mr-workspace *::after { box-sizing: border-box; }
|
|
12121
|
-
.mr-shell { width: min(
|
|
12122
|
-
.mr-header { display: flex; flex-wrap: wrap; gap: 20px; align-items:
|
|
12172
|
+
.mr-shell { width: min(1320px, 100%); margin: 0 auto; padding: 24px 32px 48px; }
|
|
12173
|
+
.mr-header { display: flex; flex-wrap: wrap; gap: 20px; align-items: center; justify-content: space-between; margin-bottom: 18px; }
|
|
12123
12174
|
.mr-eyebrow { margin: 0 0 8px; color: var(--mr-accent); font-size: 11px; font-weight: 750; letter-spacing: .14em; text-transform: uppercase; }
|
|
12124
|
-
.mr-title { margin: 0; font-size: clamp(25px, 3vw,
|
|
12175
|
+
.mr-title { margin: 0; font-size: clamp(25px, 3vw, 30px); letter-spacing: -.035em; line-height: 1.3; }
|
|
12125
12176
|
.mr-subtitle { margin: 10px 0 0; color: var(--mr-muted); font-size: 14px; line-height: 1.65; }
|
|
12126
12177
|
.mr-status { display: inline-flex; align-items: center; gap: 8px; padding: 8px 12px; border: 1px solid var(--mr-line); border-radius: 999px; background: var(--mr-card); color: var(--mr-muted); font-size: 12px; white-space: nowrap; }
|
|
12127
12178
|
.mr-status-dot { width: 7px; height: 7px; border-radius: 50%; background: #2cba83; }
|
|
12128
12179
|
.mr-status-dot.loading { background: #e9a640; }
|
|
12129
12180
|
.mr-status-dot.error { background: #d95360; }
|
|
12130
|
-
.mr-grid { display: grid; grid-template-columns: minmax(0, 1.
|
|
12131
|
-
.mr-card { min-width: 0; border: 1px solid var(--mr-line); border-radius:
|
|
12181
|
+
.mr-grid { display: grid; grid-template-columns: minmax(0, 1.7fr) minmax(280px, .85fr); gap: 20px; align-items: start; }
|
|
12182
|
+
.mr-card { min-width: 0; border: 1px solid var(--mr-line); border-radius: 14px; background: var(--mr-card); box-shadow: 0 3px 12px rgba(25, 45, 76, .025); }
|
|
12132
12183
|
.mr-card-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 20px 22px 0; }
|
|
12133
|
-
.mr-card-title { margin: 0; font-size:
|
|
12184
|
+
.mr-card-title { margin: 0; font-size: 17px; font-weight: 700; line-height: 1.5; }
|
|
12134
12185
|
.mr-card-copy { margin: 5px 0 0; color: var(--mr-muted); font-size: 12px; line-height: 1.55; }
|
|
12135
12186
|
.mr-card-body { padding: 18px 22px 22px; }
|
|
12136
12187
|
.mr-label { display: block; margin: 0 0 8px; font-size: 12px; font-weight: 700; }
|
|
12137
12188
|
.mr-textarea, .mr-input { width: 100%; border: 1px solid var(--mr-line); border-radius: 11px; background: #fff; color: var(--mr-ink); font: inherit; outline: none; }
|
|
12138
|
-
.mr-textarea { min-height:
|
|
12189
|
+
.mr-textarea { min-height: 150px; padding: 13px 14px; resize: vertical; line-height: 1.7; font-size: 14px; }
|
|
12139
12190
|
.mr-input { min-height: 38px; padding: 8px 11px; font-size: 13px; }
|
|
12140
12191
|
.mr-textarea:focus, .mr-input:focus { border-color: var(--mr-accent); box-shadow: 0 0 0 3px rgba(49, 92, 200, .13); }
|
|
12141
12192
|
.mr-controls { display: flex; flex-wrap: wrap; align-items: end; justify-content: space-between; gap: 14px; margin-top: 17px; }
|
|
12142
|
-
.mr-control-group { display: flex; flex-direction: column; gap: 7px; }
|
|
12143
|
-
.mr-control-label { color: var(--mr-muted); font-size:
|
|
12193
|
+
.mr-control-group { display: flex; flex-direction: column; gap: 7px; min-width: 0; max-width: 100%; }
|
|
12194
|
+
.mr-control-label { color: var(--mr-muted); font-size: 12px; font-weight: 650; }
|
|
12144
12195
|
.mr-segment { display: inline-flex; padding: 3px; border-radius: 10px; background: #edf1f7; }
|
|
12145
12196
|
.mr-segment button { border: 0; border-radius: 8px; padding: 8px 12px; background: transparent; color: var(--mr-muted); font: inherit; font-size: 12px; cursor: pointer; }
|
|
12146
12197
|
.mr-segment button[aria-pressed='true'] { background: #fff; color: var(--mr-ink); box-shadow: 0 2px 8px rgba(20, 35, 56, .1); font-weight: 700; }
|
|
12147
12198
|
.mr-budget { width: 140px; }
|
|
12148
12199
|
.mr-direct { min-width: min(100%, 280px); }
|
|
12149
12200
|
.mr-actions { display: flex; flex-wrap: wrap; gap: 9px; align-items: center; margin-top: 18px; }
|
|
12150
|
-
.mr-button { border: 1px solid transparent; border-radius:
|
|
12201
|
+
.mr-button { border: 1px solid transparent; border-radius: 9px; min-height: 38px; padding: 8px 14px; background: var(--mr-accent); color: var(--mr-button-ink); font: inherit; font-size: 13px; font-weight: 700; cursor: pointer; }
|
|
12151
12202
|
.mr-button:hover:not(:disabled) { filter: brightness(.94); }
|
|
12152
12203
|
.mr-button:disabled { cursor: not-allowed; opacity: .5; }
|
|
12153
12204
|
.mr-button-secondary { border-color: var(--mr-line); background: #fff; color: var(--mr-ink); }
|
|
12154
|
-
.mr-caption { color: var(--mr-muted); font-size:
|
|
12155
|
-
.mr-search { margin-top:
|
|
12205
|
+
.mr-caption { color: var(--mr-muted); font-size: 12px; line-height: 1.65; overflow-wrap: anywhere; }
|
|
12206
|
+
.mr-search { margin-top: 0; }
|
|
12156
12207
|
.mr-list { display: grid; gap: 8px; margin-top: 13px; max-height: 395px; overflow-y: auto; }
|
|
12157
12208
|
.mr-route { display: flex; justify-content: space-between; gap: 10px; padding: 10px 11px; border: 1px solid var(--mr-line); border-radius: 10px; background: #f9fbfe; }
|
|
12158
|
-
.mr-route-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size:
|
|
12159
|
-
.mr-route-provider { margin-top:
|
|
12209
|
+
.mr-route-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13px; font-weight: 700; }
|
|
12210
|
+
.mr-route-provider { margin-top: 4px; color: var(--mr-muted); font-size: 11px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
12160
12211
|
.mr-pill { align-self: start; flex: none; padding: 3px 7px; border-radius: 7px; background: var(--mr-soft); color: var(--mr-accent); font-size: 10px; font-weight: 700; }
|
|
12161
12212
|
.mr-empty, .mr-error { padding: 14px; border-radius: 10px; background: #f4f6fa; color: var(--mr-muted); font-size: 12px; line-height: 1.6; }
|
|
12162
12213
|
.mr-error { background: #fff0f1; color: #a52d3c; }
|
|
@@ -12171,12 +12222,12 @@ var router_main_default = `.mr-workspace {
|
|
|
12171
12222
|
.mr-package-top { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 8px; align-items: center; }
|
|
12172
12223
|
.mr-package-name { font-size: 12px; font-weight: 750; }
|
|
12173
12224
|
.mr-package-route { color: var(--mr-accent); font-size: 11px; font-weight: 700; }
|
|
12174
|
-
.mr-package-copy { margin: 7px 0 0; color: var(--mr-muted); font-size:
|
|
12225
|
+
.mr-package-copy { margin: 7px 0 0; color: var(--mr-muted); font-size: 12px; line-height: 1.65; overflow-wrap: anywhere; }
|
|
12175
12226
|
.mr-notice { margin-top: 18px; padding: 14px 16px; border: 1px solid rgba(49, 92, 200, .16); border-radius: 12px; background: #eff4ff; color: #354d7a; font-size: 11px; line-height: 1.65; }
|
|
12176
12227
|
.mr-notice code { font-family: ui-monospace, SFMono-Regular, Consolas, monospace; font-size: 11px; }
|
|
12177
12228
|
@media (max-width: 850px) { .mr-grid { grid-template-columns: 1fr; } .mr-shell { padding: 24px 18px 48px; } }
|
|
12178
12229
|
@media (prefers-color-scheme: dark) {
|
|
12179
|
-
.mr-workspace { --mr-card:
|
|
12230
|
+
.mr-workspace { --mr-card: #1e2633; --mr-ink: #ecf2ff; --mr-muted: #aebbd0; --mr-line: #354154; --mr-accent: #a1baff; --mr-soft: #2b3959; --mr-surface: #141b26; --mr-button-ink: #17243b; color-scheme: dark; }
|
|
12180
12231
|
.mr-textarea, .mr-input, .mr-segment button[aria-pressed='true'], .mr-button-secondary { background: #273245; color: var(--mr-ink); }
|
|
12181
12232
|
.mr-segment, .mr-empty, .mr-metric { background: #222d3e; }
|
|
12182
12233
|
.mr-route, .mr-package { background: #222d3e; }
|
|
@@ -12295,6 +12346,86 @@ var router_main_default = `.mr-workspace {
|
|
|
12295
12346
|
.mr-term-history { margin-top: 14px; font-size: 12px; }
|
|
12296
12347
|
.mr-term-table { width: 100%; border-collapse: collapse; margin-top: 6px; }
|
|
12297
12348
|
.mr-term-table th, .mr-term-table td { padding: 4px 6px; border-bottom: 1px solid rgba(127, 127, 127, .25); text-align: left; vertical-align: top; max-width: 320px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
12349
|
+
|
|
12350
|
+
/* Workspace navigation keeps every panel mounted, including running terminals. */
|
|
12351
|
+
.mr-view[hidden] { display: none !important; }
|
|
12352
|
+
.mr-view { min-width: 0; }
|
|
12353
|
+
.mr-stack { display: grid; gap: 20px; }
|
|
12354
|
+
.mr-stack > .mr-card, .mr-model-grid > .mr-card { margin: 0; }
|
|
12355
|
+
.mr-overview { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); border: 1px solid var(--mr-line); background: var(--mr-card); border-radius: 14px; overflow: hidden; margin-bottom: 16px; }
|
|
12356
|
+
.mr-overview-item { display: grid; align-content: start; gap: 4px; min-width: 0; padding: 12px 22px; border: 0; text-align: left; background: transparent; color: var(--mr-ink); font: inherit; cursor: pointer; }
|
|
12357
|
+
.mr-overview-item + .mr-overview-item { border-left: 1px solid var(--mr-line); }
|
|
12358
|
+
.mr-overview-item:hover { background: var(--mr-soft); }
|
|
12359
|
+
.mr-overview-label { color: var(--mr-muted); font-size: 12px; }
|
|
12360
|
+
.mr-overview-item strong { font-size: 25px; font-weight: 650; line-height: 1.3; font-variant-numeric: tabular-nums; }
|
|
12361
|
+
.mr-overview-item small { color: var(--mr-muted); font-size: 14px; font-weight: 400; }
|
|
12362
|
+
.mr-overview-detail { color: var(--mr-muted); font-size: 11px; line-height: 1.5; }
|
|
12363
|
+
.mr-workspace-tabs { display: flex; gap: 6px; position: sticky; top: 0; z-index: 5; background: var(--mr-surface); padding: 10px 0; margin-bottom: 14px; border-bottom: 1px solid var(--mr-line); }
|
|
12364
|
+
.mr-workspace-tabs button { display: flex; align-items: center; justify-content: center; gap: 10px; min-height: 44px; padding: 10px 18px; border: 1px solid transparent; border-radius: 9px; color: var(--mr-muted); background: transparent; font: inherit; font-size: 13px; font-weight: 600; cursor: pointer; }
|
|
12365
|
+
.mr-workspace-tabs button:hover { background: var(--mr-card); color: var(--mr-ink); }
|
|
12366
|
+
.mr-workspace-tabs button[aria-selected='true'] { background: var(--mr-card); border-color: var(--mr-line); color: var(--mr-accent); box-shadow: 0 2px 4px rgba(25, 45, 76, .04); }
|
|
12367
|
+
.mr-tab-number { font-size: 10px; font-weight: 500; opacity: .7; font-variant-numeric: tabular-nums; }
|
|
12368
|
+
.mr-view-heading { margin: 4px 0 20px; }
|
|
12369
|
+
.mr-stack > .mr-view-heading { margin-bottom: 0; }
|
|
12370
|
+
.mr-view-heading h2 { margin: 0; font-size: 20px; }
|
|
12371
|
+
.mr-view-heading p { margin: 7px 0 0; color: var(--mr-muted); font-size: 13px; line-height: 1.6; }
|
|
12372
|
+
.mr-planning-grid { grid-template-columns: minmax(0, 1fr) 290px; }
|
|
12373
|
+
.mr-planning-guide { min-width: 0; padding: 20px 4px 4px 8px; }
|
|
12374
|
+
.mr-workflow { display: grid; gap: 24px; margin: 20px 0 24px; padding: 0; list-style: none; }
|
|
12375
|
+
.mr-workflow li { display: flex; align-items: start; gap: 12px; }
|
|
12376
|
+
.mr-workflow li > span { display: grid; place-items: center; flex: 0 0 30px; height: 30px; border: 1px solid var(--mr-line); border-radius: 50%; background: var(--mr-card); color: var(--mr-accent); font-size: 10px; font-weight: 650; }
|
|
12377
|
+
.mr-workflow strong { font-size: 13px; line-height: 30px; }
|
|
12378
|
+
.mr-workflow p { margin: 2px 0 0; color: var(--mr-muted); font-size: 12px; line-height: 1.65; }
|
|
12379
|
+
.mr-guide-links { display: grid; gap: 8px; }
|
|
12380
|
+
.mr-guide-links .mr-button { text-align: left; font-weight: 500; font-size: 12px; }
|
|
12381
|
+
.mr-task-hint { margin: 8px 0 0; }
|
|
12382
|
+
.mr-plan-explanation { margin: 12px 0; padding: 10px 12px; border: 1px solid var(--mr-line); border-radius: 9px; color: var(--mr-muted); font-size: 12px; line-height: 1.65; }
|
|
12383
|
+
.mr-plan-explanation summary, .mr-package-details summary { cursor: pointer; }
|
|
12384
|
+
.mr-package-details summary { line-height: 1.8; }
|
|
12385
|
+
.mr-package-details summary .mr-package-route { display: block; margin-left: 16px; overflow-wrap: anywhere; }
|
|
12386
|
+
.mr-package-details[open] { border-color: var(--mr-accent); }
|
|
12387
|
+
.mr-footer { margin-top: 28px; padding-top: 18px; border-top: 1px solid var(--mr-line); color: var(--mr-muted); font-size: 11px; line-height: 1.8; overflow-wrap: anywhere; }
|
|
12388
|
+
.mr-footer code { font-size: 11px; }
|
|
12389
|
+
.mr-tool-status { flex-wrap: wrap; line-height: 1.6; }
|
|
12390
|
+
.mr-table td { overflow-wrap: anywhere; }
|
|
12391
|
+
.mr-term-cwd { min-width: min(100%, 240px); }
|
|
12392
|
+
|
|
12393
|
+
/* Respond to the Harness panel width, even when a wide window has a sidebar. */
|
|
12394
|
+
@container mr-workspace (max-width: 960px) {
|
|
12395
|
+
.mr-shell { padding: 24px 22px 40px; }
|
|
12396
|
+
.mr-planning-grid { grid-template-columns: minmax(0, 1fr) 240px; }
|
|
12397
|
+
.mr-model-grid { grid-template-columns: 1fr; }
|
|
12398
|
+
.mr-planning-grid .mr-card-head { flex-wrap: wrap; }
|
|
12399
|
+
.mr-profile-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
|
|
12400
|
+
}
|
|
12401
|
+
@container mr-workspace (max-width: 680px) {
|
|
12402
|
+
.mr-shell { padding: 20px 14px 32px; }
|
|
12403
|
+
.mr-header { gap: 14px; margin-bottom: 18px; }
|
|
12404
|
+
.mr-subtitle { font-size: 13px; }
|
|
12405
|
+
.mr-overview { margin-bottom: 12px; }
|
|
12406
|
+
.mr-overview-item { padding: 13px 10px; gap: 6px; }
|
|
12407
|
+
.mr-overview-item strong { font-size: 20px; }
|
|
12408
|
+
.mr-overview-detail { font-size: 10px; }
|
|
12409
|
+
.mr-overview-item small { font-size: 11px; }
|
|
12410
|
+
.mr-workspace-tabs { gap: 2px; }
|
|
12411
|
+
.mr-workspace-tabs button { flex: 1; min-width: 0; padding: 9px 4px; font-size: 12px; }
|
|
12412
|
+
.mr-tab-number { display: none; }
|
|
12413
|
+
.mr-grid { grid-template-columns: 1fr; }
|
|
12414
|
+
.mr-planning-guide { padding: 12px 4px 0; }
|
|
12415
|
+
.mr-workflow { gap: 12px; margin: 14px 0; }
|
|
12416
|
+
.mr-guide-links { grid-template-columns: repeat(2, minmax(0, 1fr)); }
|
|
12417
|
+
.mr-guide-links .mr-button { font-size: 11px; }
|
|
12418
|
+
.mr-card-head { padding: 18px 16px 0; align-items: start; flex-wrap: wrap; }
|
|
12419
|
+
.mr-card-body { padding: 14px 16px 18px; }
|
|
12420
|
+
.mr-profile-grid { grid-template-columns: 1fr; }
|
|
12421
|
+
.mr-tool { align-items: stretch; flex-direction: column; gap: 10px; }
|
|
12422
|
+
.mr-tool-actions { justify-content: flex-start; }
|
|
12423
|
+
.mr-segment { flex-wrap: wrap; max-width: 100%; }
|
|
12424
|
+
.mr-launch-workspace { min-width: 0; }
|
|
12425
|
+
.mr-result-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
|
|
12426
|
+
.mr-meters { grid-template-columns: 1fr; }
|
|
12427
|
+
}
|
|
12428
|
+
@media (prefers-reduced-motion: reduce) { .mr-workspace { scroll-behavior: auto; } }
|
|
12298
12429
|
`;
|
|
12299
12430
|
|
|
12300
12431
|
// .dsh-plugin/client/router-main.jsx
|
|
@@ -12316,10 +12447,12 @@ function ChannelBadge({ item }) {
|
|
|
12316
12447
|
const official = item.executionChannel === "official-cli";
|
|
12317
12448
|
return /* @__PURE__ */ import_react5.default.createElement("span", { className: official ? "mr-pill mr-pill-channel-ok" : "mr-pill", title: item.channelDetail ?? "" }, official ? `\u5B98\u65B9 CLI \xB7 ${item.channelLabel ?? item.channelTool}` : "\u6A21\u578B\u76EE\u5F55 API");
|
|
12318
12449
|
}
|
|
12319
|
-
function PlanResults({ plan, ledger }) {
|
|
12450
|
+
function PlanResults({ plan, ledger, headingRef }) {
|
|
12320
12451
|
const selected = plan.selected;
|
|
12321
12452
|
const budget = planBudget(ledger, plan.estimatedCost);
|
|
12322
|
-
|
|
12453
|
+
const packageNames = new Map((plan.team?.workPackages ?? []).map((item) => [item.id, item.name]));
|
|
12454
|
+
const purposeLabel = { analysis: "\u4EFB\u52A1\u5206\u6790", execution: "\u4EFB\u52A1\u5B9E\u65BD", verification: "\u72EC\u7ACB\u9A8C\u8BC1", synthesis: "\u7ED3\u679C\u6574\u5408" };
|
|
12455
|
+
return /* @__PURE__ */ import_react5.default.createElement("section", { className: "mr-card mr-results", "aria-label": "\u8DEF\u7531\u5EFA\u8BAE" }, /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-card-head" }, /* @__PURE__ */ import_react5.default.createElement("div", null, /* @__PURE__ */ import_react5.default.createElement("h2", { className: "mr-card-title", ref: headingRef, tabIndex: -1 }, "\u8DEF\u7531\u5EFA\u8BAE"), /* @__PURE__ */ import_react5.default.createElement("p", { className: "mr-card-copy" }, "\u672C\u5730\u8BA1\u7B97\u5B8C\u6210\uFF0C\u672A\u5411\u6A21\u578B\u53D1\u9001\u4EFB\u52A1\u5185\u5BB9\u3002"))), /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-card-body" }, /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-result-grid" }, /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-metric" }, /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-metric-label" }, "\u63A8\u8350\u8DEF\u7EBF"), /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-metric-value" }, selected ? `${selected.provider}/${selected.model}` : "\u6682\u65E0\u8DEF\u7EBF")), /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-metric" }, /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-metric-label" }, "\u4EFB\u52A1\u590D\u6742\u5EA6 \xB7 \u5206\u503C\uFF080\u20131\uFF09"), /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-metric-value" }, { simple: "\u7B80\u5355", balanced: "\u4E2D\u7B49", complex: "\u590D\u6742" }[plan.complexity.band] || plan.complexity.band, " \xB7 ", plan.complexity.value)), /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-metric" }, /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-metric-label" }, "\u4F30\u7B97\u603B\u6210\u672C"), /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-metric-value" }, money2(plan.estimatedCost))), /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-metric" }, /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-metric-label" }, "\u8DEF\u7531\u65B9\u6848"), /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-metric-value" }, ROUTING_PRESETS[plan.preset]?.label ?? "\u5747\u8861"))), budget?.exceeded && /* @__PURE__ */ import_react5.default.createElement("p", { className: "mr-error", role: "alert" }, "\u6267\u884C\u524D\u9884\u7B97\u68C0\u67E5\uFF1A", budget.message, " \u5B9E\u9645\u6267\u884C\u65F6\u5C06\u6309\u8BBE\u7F6E\u81EA\u52A8\u964D\u7EA7\u6216\u6682\u505C\u8BE2\u95EE\u3002"), budget?.limited && !budget.exceeded && budget.estimateKnown && /* @__PURE__ */ import_react5.default.createElement("p", { className: "mr-caption" }, "\u6267\u884C\u524D\u9884\u7B97\u68C0\u67E5\uFF1A\u672C\u6B21\u9884\u4F30 ", money2(plan.estimatedCost), "\uFF0C\u5269\u4F59\u989D\u5EA6 ", money2(budget.remainingUsd), "\u3002"), plan.loginRequired && /* @__PURE__ */ import_react5.default.createElement("p", { className: "mr-caption" }, "\u63A8\u8350\u6A21\u578B\u7684\u5B98\u65B9 CLI \u672A\u767B\u5F55\uFF0C\u6267\u884C\u65F6\u76F4\u63A5\u8D70\u6A21\u578B\u76EE\u5F55 API\uFF1B\u53EF\u5728\u201C\u5B98\u65B9\u5DE5\u5177\u201D\u5361\u7247\u70B9\u201C\u53BB\u767B\u5F55\u201D\u3002"), /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-channel-line" }, /* @__PURE__ */ import_react5.default.createElement("span", { className: "mr-control-label" }, "\u6267\u884C\u6E20\u9053"), /* @__PURE__ */ import_react5.default.createElement(ChannelBadge, { item: plan })), /* @__PURE__ */ import_react5.default.createElement("details", { className: "mr-plan-explanation" }, /* @__PURE__ */ import_react5.default.createElement("summary", null, "\u67E5\u770B\u89C4\u5212\u4F9D\u636E\u4E0E\u4F30\u7B97\u8BF4\u660E"), /* @__PURE__ */ import_react5.default.createElement("p", { className: "mr-caption" }, plan.reason), /* @__PURE__ */ import_react5.default.createElement("p", { className: "mr-caption" }, plan.pricingNotice, " ", plan.qualityNotice, " ", plan.availabilityNotice, " ", plan.modalityNotice || "")), plan.optimization.budgetExceeded && /* @__PURE__ */ import_react5.default.createElement("p", { className: "mr-error" }, "\u6309\u5DF2\u63D0\u4F9B\u5355\u4EF7\u4F30\u7B97\uFF0C\u4EFB\u52A1\u53EF\u80FD\u8D85\u8FC7\u672C\u6B21\u9884\u7B97\u3002\u9884\u7B97\u53EA\u5F71\u54CD\u5EFA\u8BAE\uFF0C\u4E0D\u4F1A\u963B\u6B62\u5B9E\u9645\u6263\u8D39\u3002"), plan.mode === "team" && /* @__PURE__ */ import_react5.default.createElement(import_react5.default.Fragment, null, /* @__PURE__ */ import_react5.default.createElement("h3", { className: "mr-section-title" }, "\u56E2\u961F\u5DE5\u4F5C\u5305"), /* @__PURE__ */ import_react5.default.createElement("p", { className: "mr-caption" }, "\u4E0B\u65B9\u6A21\u578B\u662F\u89C4\u5212\u5EFA\u8BAE\uFF1B\u6258\u7BA1\u6267\u884C\u4F1A\u6309\u5382\u5546 CLI \u7684\u6A21\u578B\u540D\u89C4\u5219\u9009\u7528\uFF0C\u672A\u6838\u9A8C\u6620\u5C04\u65F6\u4F7F\u7528\u8BE5 CLI \u7684\u9ED8\u8BA4\u6A21\u578B\u3002"), plan.team.workPackages.length > 1 && /* @__PURE__ */ import_react5.default.createElement(DagView, { packages: plan.team.workPackages, label: "\u5DE5\u4F5C\u5305\u4F9D\u8D56\u56FE", renderNode: (item) => /* @__PURE__ */ import_react5.default.createElement("p", { className: "mr-package-route" }, item.recommendedProvider, "/", item.recommendedModel) }), plan.team.workPackages.length === 0 ? /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-empty" }, "\u5F53\u524D\u76EE\u5F55\u6CA1\u6709\u53EF\u5206\u914D\u7684\u6A21\u578B\u8DEF\u7EBF\u3002") : plan.team.workPackages.map((item, index) => /* @__PURE__ */ import_react5.default.createElement("details", { className: "mr-package mr-package-details", key: item.id }, /* @__PURE__ */ import_react5.default.createElement("summary", null, /* @__PURE__ */ import_react5.default.createElement("span", { className: "mr-package-name" }, index + 1, ". ", item.name), /* @__PURE__ */ import_react5.default.createElement("span", { className: "mr-package-route" }, item.recommendedProvider, "/", item.recommendedModel)), item.objective && /* @__PURE__ */ import_react5.default.createElement("p", { className: "mr-package-copy" }, "\u5177\u4F53\u76EE\u6807\uFF1A", item.objective), /* @__PURE__ */ import_react5.default.createElement("p", { className: "mr-package-copy" }, purposeLabel[item.purpose] ?? item.purpose, item.dependsOn.length > 0 ? ` \xB7 \u4F9D\u8D56\uFF1A${item.dependsOn.map((id2) => packageNames.get(id2) ?? id2).join("\u3001")}` : ""), /* @__PURE__ */ import_react5.default.createElement("p", { className: "mr-package-copy" }, "\u96BE\u5EA6\uFF1A", { simple: "\u7B80\u5355", balanced: "\u4E2D\u7B49", complex: "\u56F0\u96BE" }[item.difficulty] || item.difficulty || "\u5F85\u8BC4\u4F30", " \xB7 \u8D39\u7528\uFF1A", money2(item.estimatedCost)), /* @__PURE__ */ import_react5.default.createElement("p", { className: "mr-package-copy" }, "\u9A8C\u6536\uFF1A", item.verificationChecklist.join("\uFF1B")), /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-channel-line" }, /* @__PURE__ */ import_react5.default.createElement(ChannelBadge, { item }), item.loginRequired && /* @__PURE__ */ import_react5.default.createElement("span", { className: "mr-pill" }, "CLI \u672A\u767B\u5F55")), item.channelDetail && /* @__PURE__ */ import_react5.default.createElement("p", { className: "mr-package-copy" }, "\u6E20\u9053\u8BF4\u660E\uFF1A", item.channelDetail)))), plan.routingBypassed && /* @__PURE__ */ import_react5.default.createElement("p", { className: "mr-caption" }, "\u5DF2\u6307\u5B9A\u5355\u4E00\u6A21\u578B\uFF0C\u672A\u4E0E\u5176\u4ED6\u8DEF\u7EBF\u6BD4\u8F83\u3002\u5728\u5B98\u65B9\u4F1A\u8BDD\u4E2D\u8C03\u7528 ", /* @__PURE__ */ import_react5.default.createElement("code", null, "model_router_execute"), " \u5E76\u4F20\u5165\u8BE5 provider \u4E0E model \u5373\u53EF\u76F4\u63A5\u6267\u884C\uFF1B\u82E5\u8BE5\u6A21\u578B\u5141\u8BB8\u5B98\u65B9\u5DE5\u5177\uFF0C\u4F1A\u4F18\u5148\u4F7F\u7528\u5BF9\u5E94 CLI\u3002"), plan.mode === "team" && /* @__PURE__ */ import_react5.default.createElement("p", { className: "mr-caption" }, plan.team.handoff)));
|
|
12323
12456
|
}
|
|
12324
12457
|
var remoteError = (response, fallback) => text5(response?.error?.message) || text5(response?.value?.error) || fallback;
|
|
12325
12458
|
function probeLabel(probe) {
|
|
@@ -12466,6 +12599,12 @@ function OfficialToolsCard({ listOfficialTools, installOfficialTool, cancelOffic
|
|
|
12466
12599
|
})), /* @__PURE__ */ import_react5.default.createElement("p", { className: "mr-caption", style: { marginTop: 12 } }, "\u5B89\u88C5\u7531 Host \u6309\u6CE8\u518C\u8868\u56FA\u5B9A\u6765\u6E90\u6267\u884C\uFF0C\u4E0D\u63A5\u53D7\u81EA\u5B9A\u4E49\u5305\u540D\uFF1B\u53EF\u70B9\u201C\u53D6\u6D88\u5B89\u88C5\u201D\u7EC8\u6B62\u4E0B\u8F7D\u4EFB\u52A1\uFF0C\u968F\u540E\u91CD\u65B0\u68C0\u6D4B\u5B9E\u9645\u7248\u672C\u3002ZCode \u5B89\u88C5\u5668\u542F\u52A8\u540E\u4ECD\u9700\u5728\u539F\u5382\u7A97\u53E3\u9009\u62E9\u76EE\u5F55\u5E76\u5B8C\u6210\u5B89\u88C5\u3002Agent \u4E5F\u53EF\u8C03\u7528 ", /* @__PURE__ */ import_react5.default.createElement("code", null, "model_router_tool_install"), "\uFF0C\u6216\u5728\u4F1A\u8BDD\u4F7F\u7528 ", /* @__PURE__ */ import_react5.default.createElement("code", null, "/tools"), "\u3002")));
|
|
12467
12600
|
}
|
|
12468
12601
|
var HEADLESS_TOOLS = /* @__PURE__ */ new Set(["claude-code", "codex", "gemini"]);
|
|
12602
|
+
var WORKSPACE_VIEWS = [
|
|
12603
|
+
{ id: "plan", label: "\u4EFB\u52A1\u4E0E\u6267\u884C", number: "01" },
|
|
12604
|
+
{ id: "models", label: "\u6A21\u578B\u914D\u7F6E", number: "02" },
|
|
12605
|
+
{ id: "tools", label: "\u5B98\u65B9\u5DE5\u5177", number: "03" },
|
|
12606
|
+
{ id: "controls", label: "\u9884\u7B97\u4E0E\u5B89\u5168", number: "04" }
|
|
12607
|
+
];
|
|
12469
12608
|
function useWorkbenchData({ toolHealth, completeOnboarding, loadLedger, rateResult, rerunStep, loadBoundaries }) {
|
|
12470
12609
|
const [health, setHealth] = import_react5.default.useState({ report: null, error: "", refreshing: false });
|
|
12471
12610
|
const [ledger, setLedger] = import_react5.default.useState({ value: null, error: "" });
|
|
@@ -12573,14 +12712,40 @@ function RouterMainPage({ loadCatalog, settingsScope, listOfficialTools, install
|
|
|
12573
12712
|
const [plan, setPlan] = import_react5.default.useState(null);
|
|
12574
12713
|
const [planError, setPlanError] = import_react5.default.useState("");
|
|
12575
12714
|
const [toolProbes, setToolProbes] = import_react5.default.useState(null);
|
|
12715
|
+
const [routingSettings, setRoutingSettings] = import_react5.default.useState(() => {
|
|
12716
|
+
const value = settingsScope.getSnapshot().value ?? {};
|
|
12717
|
+
return JSON.stringify([value.modelProfilesJson, value.routingPreset]);
|
|
12718
|
+
});
|
|
12719
|
+
const [view, setView] = import_react5.default.useState("plan");
|
|
12720
|
+
const tabRefs = import_react5.default.useRef({});
|
|
12721
|
+
const resultHeading = import_react5.default.useRef(null);
|
|
12576
12722
|
const budgetEdited = import_react5.default.useRef(false);
|
|
12577
12723
|
const budgetValue = import_react5.default.useRef(budget);
|
|
12578
12724
|
const mounted = import_react5.default.useRef(false);
|
|
12579
12725
|
const catalogRequest = import_react5.default.useRef(0);
|
|
12726
|
+
import_react5.default.useEffect(() => {
|
|
12727
|
+
if (plan) resultHeading.current?.focus({ preventScroll: true });
|
|
12728
|
+
}, [plan]);
|
|
12729
|
+
const selectView = (id2) => {
|
|
12730
|
+
setView(id2);
|
|
12731
|
+
tabRefs.current[id2]?.focus({ preventScroll: true });
|
|
12732
|
+
};
|
|
12733
|
+
const navigateTabs = (event, index) => {
|
|
12734
|
+
const next = event.key === "ArrowRight" ? (index + 1) % WORKSPACE_VIEWS.length : event.key === "ArrowLeft" ? (index + WORKSPACE_VIEWS.length - 1) % WORKSPACE_VIEWS.length : event.key === "Home" ? 0 : event.key === "End" ? WORKSPACE_VIEWS.length - 1 : null;
|
|
12735
|
+
if (next === null) return;
|
|
12736
|
+
event.preventDefault();
|
|
12737
|
+
selectView(WORKSPACE_VIEWS[next].id);
|
|
12738
|
+
};
|
|
12580
12739
|
import_react5.default.useEffect(() => {
|
|
12581
12740
|
const syncBudget = () => {
|
|
12741
|
+
const value = settingsScope.getSnapshot().value ?? {};
|
|
12742
|
+
const signature = JSON.stringify([value.modelProfilesJson, value.routingPreset]);
|
|
12743
|
+
setRoutingSettings((previous) => {
|
|
12744
|
+
if (previous === signature) return previous;
|
|
12745
|
+
return signature;
|
|
12746
|
+
});
|
|
12582
12747
|
if (budgetEdited.current) return;
|
|
12583
|
-
const next = String(
|
|
12748
|
+
const next = String(value.budgetUsd ?? 0);
|
|
12584
12749
|
if (next !== budgetValue.current) {
|
|
12585
12750
|
budgetValue.current = next;
|
|
12586
12751
|
setBudget(next);
|
|
@@ -12591,6 +12756,10 @@ function RouterMainPage({ loadCatalog, settingsScope, listOfficialTools, install
|
|
|
12591
12756
|
syncBudget();
|
|
12592
12757
|
return settingsScope.subscribe(syncBudget);
|
|
12593
12758
|
}, [settingsScope]);
|
|
12759
|
+
import_react5.default.useEffect(() => {
|
|
12760
|
+
setPlan(null);
|
|
12761
|
+
setPlanError("");
|
|
12762
|
+
}, [routingSettings]);
|
|
12594
12763
|
import_react5.default.useEffect(() => {
|
|
12595
12764
|
mounted.current = true;
|
|
12596
12765
|
const request = ++catalogRequest.current;
|
|
@@ -12655,34 +12824,13 @@ function RouterMainPage({ loadCatalog, settingsScope, listOfficialTools, install
|
|
|
12655
12824
|
setPlanError(text5(error?.message) || "\u65E0\u6CD5\u751F\u6210\u8DEF\u7531\u5EFA\u8BAE\u3002");
|
|
12656
12825
|
}
|
|
12657
12826
|
};
|
|
12658
|
-
|
|
12659
|
-
|
|
12660
|
-
|
|
12661
|
-
|
|
12662
|
-
error: workbench.health.error,
|
|
12663
|
-
refreshing: workbench.health.refreshing,
|
|
12664
|
-
onRefresh: () => {
|
|
12665
|
-
void workbench.refreshHealth(true);
|
|
12666
|
-
},
|
|
12667
|
-
onDone: () => {
|
|
12668
|
-
void workbench.finishOnboarding();
|
|
12669
|
-
}
|
|
12670
|
-
}
|
|
12671
|
-
), /* @__PURE__ */ import_react5.default.createElement(
|
|
12672
|
-
CostControlCard,
|
|
12673
|
-
{
|
|
12674
|
-
ledger: workbench.ledger.value,
|
|
12675
|
-
error: workbench.ledger.error && !workbench.ledger.value ? workbench.ledger.error : "",
|
|
12676
|
-
settingsScope,
|
|
12677
|
-
onChanged: () => {
|
|
12678
|
-
invalidatePlan();
|
|
12679
|
-
void workbench.refreshLedger();
|
|
12680
|
-
}
|
|
12681
|
-
}
|
|
12682
|
-
), /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-grid" }, /* @__PURE__ */ import_react5.default.createElement("section", { className: "mr-card", "aria-label": "\u4EFB\u52A1\u89C4\u5212" }, /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-card-head" }, /* @__PURE__ */ import_react5.default.createElement("div", null, /* @__PURE__ */ import_react5.default.createElement("h2", { className: "mr-card-title" }, "\u4EFB\u52A1\u89C4\u5212"), /* @__PURE__ */ import_react5.default.createElement("p", { className: "mr-card-copy" }, "\u201C\u751F\u6210\u8DEF\u7531\u5EFA\u8BAE\u201D\u5728\u672C\u673A\u5B8C\u6210\uFF0C\u4E0D\u4F1A\u542F\u52A8\u6A21\u578B\uFF1B\u8981\u5B9E\u9645\u6267\u884C\uFF0C\u8BF7\u5728\u4E0B\u65B9\u201C\u5728\u5DE5\u4F5C\u53F0\u6267\u884C\u201D\u4E2D\u9884\u89C8\u5E76\u786E\u8BA4\u3002"))), /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-card-body" }, /* @__PURE__ */ import_react5.default.createElement("label", { className: "mr-label", htmlFor: "mr-task" }, "\u4EFB\u52A1\u63CF\u8FF0"), /* @__PURE__ */ import_react5.default.createElement("textarea", { className: "mr-textarea", id: "mr-task", value: task, onChange: (event) => {
|
|
12827
|
+
const summary = healthSummary(workbench.health.report?.tools);
|
|
12828
|
+
return /* @__PURE__ */ import_react5.default.createElement("main", { className: "mr-workspace" }, /* @__PURE__ */ import_react5.default.createElement("style", null, router_main_default), /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-shell" }, /* @__PURE__ */ import_react5.default.createElement("header", { className: "mr-header" }, /* @__PURE__ */ import_react5.default.createElement("div", null, /* @__PURE__ */ import_react5.default.createElement("p", { className: "mr-eyebrow" }, "Model Router \xB7 DeepSeek Harness"), /* @__PURE__ */ import_react5.default.createElement("h1", { className: "mr-title" }, "\u6A21\u578B\u8DEF\u7531\u5DE5\u4F5C\u53F0"), /* @__PURE__ */ import_react5.default.createElement("p", { className: "mr-subtitle" }, "\u628A\u4EFB\u52A1\u4EA4\u7ED9\u5408\u9002\u7684\u6A21\u578B\u3002\u4ECE\u672C\u5730\u89C4\u5212\uFF0C\u5230\u53EF\u786E\u8BA4\u7684\u6267\u884C\u3002")), /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-status" }, /* @__PURE__ */ import_react5.default.createElement("span", { className: `mr-status-dot ${catalogState.status === "loading" ? "loading" : catalogState.status === "error" ? "error" : ""}` }), catalogState.status === "ready" ? `${providerCount} \u4E2A\u4F9B\u5E94\u5546 \xB7 ${routes.length} \u6761\u8DEF\u7EBF` : catalogState.status === "loading" ? "\u6B63\u5728\u8BFB\u53D6\u6A21\u578B\u76EE\u5F55" : "\u6A21\u578B\u76EE\u5F55\u8BFB\u53D6\u5931\u8D25")), /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-overview", "aria-label": "\u5DE5\u4F5C\u53F0\u6982\u89C8" }, /* @__PURE__ */ import_react5.default.createElement("button", { type: "button", className: "mr-overview-item", onClick: () => selectView("models") }, /* @__PURE__ */ import_react5.default.createElement("span", { className: "mr-overview-label" }, "\u6A21\u578B\u8DEF\u7EBF"), /* @__PURE__ */ import_react5.default.createElement("strong", null, catalogState.status === "ready" ? routes.length : "\u2014"), /* @__PURE__ */ import_react5.default.createElement("span", { className: "mr-overview-detail" }, catalogState.status === "ready" ? `${providerCount} \u4E2A\u4F9B\u5E94\u5546 \xB7 \u914D\u7F6E\u4EF7\u683C\u4E0E\u80FD\u529B \u2192` : "\u7B49\u5F85\u76EE\u5F55\u52A0\u8F7D")), /* @__PURE__ */ import_react5.default.createElement("button", { type: "button", className: "mr-overview-item", onClick: () => selectView("tools") }, /* @__PURE__ */ import_react5.default.createElement("span", { className: "mr-overview-label" }, "\u5B98\u65B9\u5DE5\u5177"), /* @__PURE__ */ import_react5.default.createElement("strong", null, workbench.health.report ? summary.installed : "\u2014", /* @__PURE__ */ import_react5.default.createElement("small", null, " / ", OFFICIAL_TOOLS.length)), /* @__PURE__ */ import_react5.default.createElement("span", { className: "mr-overview-detail" }, workbench.health.report ? `${summary.ready} \u4E2A\u5DF2\u767B\u5F55 \xB7 \u67E5\u770B\u4F53\u68C0 \u2192` : "\u67E5\u770B\u5B89\u88C5\u4E0E\u767B\u5F55\u72B6\u6001 \u2192")), /* @__PURE__ */ import_react5.default.createElement("button", { type: "button", className: "mr-overview-item", onClick: () => selectView("controls") }, /* @__PURE__ */ import_react5.default.createElement("span", { className: "mr-overview-label" }, "\u4ECA\u65E5 API \u8D39\u7528"), /* @__PURE__ */ import_react5.default.createElement("strong", null, workbench.ledger.value ? money2(workbench.ledger.value.spent?.today ?? 0) : "\u2014"), /* @__PURE__ */ import_react5.default.createElement("span", { className: "mr-overview-detail" }, "\u672C\u673A\u8BB0\u5F55\u4F30\u7B97 \xB7 \u67E5\u770B\u9884\u7B97 \u2192"))), /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-workspace-tabs", role: "tablist", "aria-label": "\u5DE5\u4F5C\u53F0\u529F\u80FD" }, WORKSPACE_VIEWS.map((item, index) => /* @__PURE__ */ import_react5.default.createElement("button", { key: item.id, ref: (element) => {
|
|
12829
|
+
tabRefs.current[item.id] = element;
|
|
12830
|
+
}, type: "button", role: "tab", id: `mr-tab-${item.id}`, "aria-selected": view === item.id, "aria-controls": `mr-panel-${item.id}`, tabIndex: view === item.id ? 0 : -1, onKeyDown: (event) => navigateTabs(event, index), onClick: () => setView(item.id) }, /* @__PURE__ */ import_react5.default.createElement("span", { className: "mr-tab-number", "aria-hidden": "true" }, item.number), item.label))), staleHostNotice({ hostVersion: toolProbes?.hostVersion, loaded: Boolean(toolProbes?.probes?.length) }) && /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-error", role: "alert" }, staleHostNotice({ hostVersion: toolProbes?.hostVersion })), (workbench.health.report?.notices ?? []).map((notice) => /* @__PURE__ */ import_react5.default.createElement("div", { key: `${notice.kind}-${notice.at}`, className: "mr-error", role: "alert" }, notice.message)), /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-view mr-stack", role: "tabpanel", id: "mr-panel-plan", "aria-labelledby": "mr-tab-plan", hidden: view !== "plan" }, /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-grid mr-planning-grid" }, /* @__PURE__ */ import_react5.default.createElement("section", { className: "mr-card", "aria-label": "\u4EFB\u52A1\u89C4\u5212" }, /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-card-head" }, /* @__PURE__ */ import_react5.default.createElement("div", null, /* @__PURE__ */ import_react5.default.createElement("h2", { className: "mr-card-title" }, "\u4EFB\u52A1\u89C4\u5212"), /* @__PURE__ */ import_react5.default.createElement("p", { className: "mr-card-copy" }, "\u5199\u6E05\u76EE\u6807\u4E0E\u9A8C\u6536\u6807\u51C6\uFF0C\u5148\u751F\u6210\u672C\u5730\u5EFA\u8BAE\uFF0C\u518D\u9884\u89C8\u6267\u884C\u3002")), /* @__PURE__ */ import_react5.default.createElement("span", { className: "mr-pill" }, "\u672C\u5730\u89C4\u5212 \xB7 \u4E0D\u6D88\u8017 token")), /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-card-body" }, /* @__PURE__ */ import_react5.default.createElement("label", { className: "mr-label", htmlFor: "mr-task" }, "\u4EFB\u52A1\u63CF\u8FF0"), /* @__PURE__ */ import_react5.default.createElement("textarea", { className: "mr-textarea", id: "mr-task", value: task, onChange: (event) => {
|
|
12683
12831
|
setTask(event.target.value);
|
|
12684
12832
|
invalidatePlan();
|
|
12685
|
-
}, placeholder: "\u4F8B\u5982\uFF1A\u5206\u6790\u9879\u76EE\u67B6\u6784\uFF0C\u5206\u5DE5\u4FEE\u590D\u5173\u952E\u95EE\u9898\uFF0C\u5E76\u7ED9\u51FA\u9A8C\u6536\u6E05\u5355" }), /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-controls" }, /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-control-group" }, /* @__PURE__ */ import_react5.default.createElement("span", { className: "mr-control-label" }, "\u89C4\u5212\u6A21\u5F0F"), /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-segment", role: "group", "aria-label": "\u89C4\u5212\u6A21\u5F0F" }, /* @__PURE__ */ import_react5.default.createElement("button", { type: "button", "aria-pressed": mode === "single", onClick: () => {
|
|
12833
|
+
}, placeholder: "\u4F8B\u5982\uFF1A\u5206\u6790\u9879\u76EE\u67B6\u6784\uFF0C\u5206\u5DE5\u4FEE\u590D\u5173\u952E\u95EE\u9898\uFF0C\u5E76\u7ED9\u51FA\u9A8C\u6536\u6E05\u5355", "aria-describedby": "mr-task-hint" }), /* @__PURE__ */ import_react5.default.createElement("p", { className: "mr-caption mr-task-hint", id: "mr-task-hint" }, "\u56E2\u961F\u4EFB\u52A1\u53EF\u6309\u7F16\u53F7\u5199\u51FA\u6B65\u9AA4\u3001\u4EA4\u4ED8\u7269\u548C\u4F9D\u8D56\uFF1B\u89C4\u5212\u4E0D\u4F1A\u66F4\u6539\u4E3B\u4F1A\u8BDD\u6A21\u578B\u3002"), /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-controls" }, /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-control-group" }, /* @__PURE__ */ import_react5.default.createElement("span", { className: "mr-control-label" }, "\u89C4\u5212\u6A21\u5F0F"), /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-segment", role: "group", "aria-label": "\u89C4\u5212\u6A21\u5F0F" }, /* @__PURE__ */ import_react5.default.createElement("button", { type: "button", "aria-pressed": mode === "single", onClick: () => {
|
|
12686
12834
|
setMode("single");
|
|
12687
12835
|
invalidatePlan();
|
|
12688
12836
|
} }, "\u5355\u4EFB\u52A1"), /* @__PURE__ */ import_react5.default.createElement("button", { type: "button", "aria-pressed": mode === "team", onClick: () => {
|
|
@@ -12699,7 +12847,7 @@ function RouterMainPage({ loadCatalog, settingsScope, listOfficialTools, install
|
|
|
12699
12847
|
budgetValue.current = event.target.value;
|
|
12700
12848
|
setBudget(event.target.value);
|
|
12701
12849
|
invalidatePlan();
|
|
12702
|
-
} }))), /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-actions" }, /* @__PURE__ */ import_react5.default.createElement("button", { className: "mr-button", type: "button", disabled: catalogState.status !== "ready" || routes.length === 0 || toolProbes === null, onClick: generate }, "\u751F\u6210\u8DEF\u7531\u5EFA\u8BAE"), /* @__PURE__ */ import_react5.default.createElement("span", { className: "mr-caption" },
|
|
12850
|
+
} }))), /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-actions" }, /* @__PURE__ */ import_react5.default.createElement("button", { className: "mr-button", type: "button", disabled: catalogState.status !== "ready" || routes.length === 0 || toolProbes === null, onClick: generate }, "\u751F\u6210\u8DEF\u7531\u5EFA\u8BAE"), /* @__PURE__ */ import_react5.default.createElement("span", { className: "mr-caption" }, catalogState.status === "loading" ? "\u6B63\u5728\u8BFB\u53D6\u6A21\u578B\u76EE\u5F55\u2026" : catalogState.status === "error" ? "\u76EE\u5F55\u8BFB\u53D6\u5931\u8D25\uFF0C\u8BF7\u5728\u201C\u6A21\u578B\u914D\u7F6E\u201D\u4E2D\u5237\u65B0\u3002" : routes.length === 0 ? "\u8BF7\u5148\u5728 Harness \u7684\u201C\u6A21\u578B\u201D\u9875\u6DFB\u52A0\u6A21\u578B\u3002" : toolProbes === null ? "\u6B63\u5728\u68C0\u6D4B\u5B98\u65B9\u5DE5\u5177\u2026" : "\u9884\u7B97 0 \u4E3A\u4E0D\u9650\uFF1B\u8D39\u7528\u4E3A\u4F30\u7B97\u3002")), planError && /* @__PURE__ */ import_react5.default.createElement("p", { className: "mr-error", role: "alert" }, planError))), /* @__PURE__ */ import_react5.default.createElement("aside", { className: "mr-planning-guide", "aria-label": "\u89C4\u5212\u4F7F\u7528\u63D0\u793A" }, /* @__PURE__ */ import_react5.default.createElement("p", { className: "mr-eyebrow" }, "\u5DE5\u4F5C\u6D41\u7A0B"), /* @__PURE__ */ import_react5.default.createElement("ol", { className: "mr-workflow" }, /* @__PURE__ */ import_react5.default.createElement("li", null, /* @__PURE__ */ import_react5.default.createElement("span", null, "01"), /* @__PURE__ */ import_react5.default.createElement("div", null, /* @__PURE__ */ import_react5.default.createElement("strong", null, "\u63CF\u8FF0\u4EFB\u52A1"), /* @__PURE__ */ import_react5.default.createElement("p", null, "\u9009\u62E9\u5355\u4EFB\u52A1\u3001\u56E2\u961F\u5206\u5DE5\u6216\u6307\u5B9A\u6A21\u578B\u3002"))), /* @__PURE__ */ import_react5.default.createElement("li", null, /* @__PURE__ */ import_react5.default.createElement("span", null, "02"), /* @__PURE__ */ import_react5.default.createElement("div", null, /* @__PURE__ */ import_react5.default.createElement("strong", null, "\u6838\u5BF9\u8DEF\u7531\u5EFA\u8BAE"), /* @__PURE__ */ import_react5.default.createElement("p", null, "\u68C0\u67E5\u6A21\u578B\u3001\u5DE5\u4F5C\u5305\u4F9D\u8D56\u548C\u4F30\u7B97\u8D39\u7528\u3002"))), /* @__PURE__ */ import_react5.default.createElement("li", null, /* @__PURE__ */ import_react5.default.createElement("span", null, "03"), /* @__PURE__ */ import_react5.default.createElement("div", null, /* @__PURE__ */ import_react5.default.createElement("strong", null, "\u9884\u89C8\u5E76\u786E\u8BA4\u6267\u884C"), /* @__PURE__ */ import_react5.default.createElement("p", null, "\u786E\u8BA4\u540E\u8C03\u7528\u6A21\u578B\uFF0C\u7ED3\u679C\u5199\u5165\u6267\u884C\u8BB0\u5F55\u3002")))), /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-guide-links" }, /* @__PURE__ */ import_react5.default.createElement("button", { className: "mr-button mr-button-secondary", type: "button", onClick: () => selectView("models") }, "\u914D\u7F6E\u6A21\u578B\u4EF7\u683C\u4E0E\u80FD\u529B \u2192"), /* @__PURE__ */ import_react5.default.createElement("button", { className: "mr-button mr-button-secondary", type: "button", onClick: () => selectView("tools") }, "\u68C0\u67E5\u5B98\u65B9\u5DE5\u5177\u4E0E\u767B\u5F55 \u2192")), /* @__PURE__ */ import_react5.default.createElement("p", { className: "mr-caption" }, "\u7F3A\u5C11\u4EF7\u683C\u65F6\u4F1A\u63D0\u793A\u201C\u4EF7\u683C\u5F85\u914D\u7F6E\u201D\u3002\u53EA\u8BFB\u6267\u884C\u53EF\u5728\u6B64\u5B8C\u6210\uFF1B\u4FEE\u6539\u6587\u4EF6\u7684\u4EFB\u52A1\u9700\u5728\u5B98\u65B9\u4F1A\u8BDD\u4E2D\u5BA1\u6279\u3002"))), plan && /* @__PURE__ */ import_react5.default.createElement(PlanResults, { plan, ledger: workbench.ledger.value, headingRef: resultHeading }), /* @__PURE__ */ import_react5.default.createElement(
|
|
12703
12851
|
RunLauncher,
|
|
12704
12852
|
{
|
|
12705
12853
|
task,
|
|
@@ -12708,9 +12856,10 @@ function RouterMainPage({ loadCatalog, settingsScope, listOfficialTools, install
|
|
|
12708
12856
|
ledger: workbench.ledger.value,
|
|
12709
12857
|
previewRun,
|
|
12710
12858
|
startRun,
|
|
12859
|
+
planningRevision: routingSettings,
|
|
12711
12860
|
directRoute: mode === "direct" ? routes.find((route) => `${route.provider}/${route.model}` === directKey) ?? routes[0] ?? null : null,
|
|
12712
12861
|
defaultPreset: settingsScope.getSnapshot().value?.routingPreset ?? "balanced",
|
|
12713
|
-
disabledReason: catalogState.status === "loading" ? "\u6B63\u5728\u8BFB\u53D6\u6A21\u578B\u76EE\u5F55\u2026" : catalogState.status === "error" ? "\u6A21\u578B\u76EE\u5F55\u8BFB\u53D6\u5931\u8D25\uFF0C\u8BF7\u5728\u201C\u6A21\u578B\
|
|
12862
|
+
disabledReason: catalogState.status === "loading" ? "\u6B63\u5728\u8BFB\u53D6\u6A21\u578B\u76EE\u5F55\u2026" : catalogState.status === "error" ? "\u6A21\u578B\u76EE\u5F55\u8BFB\u53D6\u5931\u8D25\uFF0C\u8BF7\u5728\u201C\u6A21\u578B\u914D\u7F6E\u201D\u4E2D\u5237\u65B0\u3002" : routes.length === 0 ? "\u8BF7\u5148\u5728\u5B98\u65B9\u201C\u6A21\u578B\u201D\u9875\u914D\u7F6E\u81F3\u5C11\u4E00\u6761\u6A21\u578B\u8DEF\u7EBF\u3002" : "",
|
|
12714
12863
|
onStarted: () => {
|
|
12715
12864
|
void workbench.refreshLedger();
|
|
12716
12865
|
}
|
|
@@ -12732,6 +12881,19 @@ function RouterMainPage({ loadCatalog, settingsScope, listOfficialTools, install
|
|
|
12732
12881
|
void workbench.rerun(runId, packageId, override, choice);
|
|
12733
12882
|
}
|
|
12734
12883
|
}
|
|
12884
|
+
)), /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-view", role: "tabpanel", id: "mr-panel-models", "aria-labelledby": "mr-tab-models", hidden: view !== "models" }, /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-view-heading" }, /* @__PURE__ */ import_react5.default.createElement("h2", null, "\u6A21\u578B\u914D\u7F6E"), /* @__PURE__ */ import_react5.default.createElement("p", null, "\u4ECE\u5B98\u65B9\u76EE\u5F55\u9009\u62E9\u8DEF\u7EBF\uFF0C\u8865\u9F50\u6BD4\u8F83\u6240\u9700\u7684\u4EF7\u683C\u3001\u80FD\u529B\u4E0E\u6267\u884C\u65B9\u5F0F\u3002")), /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-grid mr-model-grid" }, /* @__PURE__ */ import_react5.default.createElement(ModelProfileEditor, { routes, settingsScope, onSaved: invalidatePlan }), /* @__PURE__ */ import_react5.default.createElement("section", { className: "mr-card", "aria-label": "\u6A21\u578B\u76EE\u5F55" }, /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-card-head" }, /* @__PURE__ */ import_react5.default.createElement("div", null, /* @__PURE__ */ import_react5.default.createElement("h2", { className: "mr-card-title" }, "\u6A21\u578B\u76EE\u5F55"), /* @__PURE__ */ import_react5.default.createElement("p", { className: "mr-card-copy" }, routes.length, " \u6761\u8DEF\u7EBF \xB7 \u53EA\u8BFB\u53D6\u5B98\u65B9\u76EE\u5F55\uFF0C\u4E0D\u8BFB\u53D6 API Key\u3002")), /* @__PURE__ */ import_react5.default.createElement("button", { className: "mr-button mr-button-secondary", type: "button", disabled: catalogState.status === "loading", onClick: refresh }, "\u5237\u65B0")), /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-card-body" }, catalogState.status === "error" && /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-error", role: "alert" }, catalogState.error), catalogState.status === "loading" && /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-empty" }, "\u6B63\u5728\u52A0\u8F7D\u5B98\u65B9\u6A21\u578B\u76EE\u5F55\u2026"), catalogState.status === "ready" && /* @__PURE__ */ import_react5.default.createElement(import_react5.default.Fragment, null, /* @__PURE__ */ import_react5.default.createElement("label", { className: "mr-label", htmlFor: "mr-model-search" }, "\u641C\u7D22\u8DEF\u7EBF"), /* @__PURE__ */ import_react5.default.createElement("input", { className: "mr-input mr-search", id: "mr-model-search", value: query, onChange: (event) => setQuery(event.target.value), placeholder: "\u6A21\u578B\u6216\u4F9B\u5E94\u5546" }), /* @__PURE__ */ import_react5.default.createElement(RouteList, { routes, query }), catalogState.catalog?.failures?.length > 0 && /* @__PURE__ */ import_react5.default.createElement("p", { className: "mr-caption" }, catalogState.catalog.failures.length, " \u4E2A\u4F9B\u5E94\u5546\u7684\u76EE\u5F55\u8BFB\u53D6\u5931\u8D25\uFF0C\u8BF7\u5728\u5B98\u65B9\u6A21\u578B\u9875\u68C0\u67E5\u914D\u7F6E\u3002")), /* @__PURE__ */ import_react5.default.createElement("p", { className: "mr-caption", style: { marginTop: 13 } }, "\u76EE\u5F55\u767B\u8BB0\u4E0D\u4EE3\u8868\u51ED\u636E\u6216\u7F51\u7EDC\u5F53\u524D\u53EF\u7528\uFF1B\u56FE\u50CF\u80FD\u529B\u9700\u8981\u5728\u5B9E\u9645\u4F7F\u7528\u524D\u6838\u5BF9\u3002"))))), /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-view mr-stack", role: "tabpanel", id: "mr-panel-tools", "aria-labelledby": "mr-tab-tools", hidden: view !== "tools" }, /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-view-heading" }, /* @__PURE__ */ import_react5.default.createElement("h2", null, "\u5B98\u65B9\u5DE5\u5177"), /* @__PURE__ */ import_react5.default.createElement("p", null, "\u7BA1\u7406\u672C\u673A CLI\u3001\u68C0\u67E5\u767B\u5F55\u72B6\u6001\uFF0C\u6216\u6253\u5F00\u4EA4\u4E92\u5F0F\u7EC8\u7AEF\u3002")), workbench.health.report && !workbench.health.report.onboarding?.completedAt && /* @__PURE__ */ import_react5.default.createElement(
|
|
12885
|
+
OnboardingBanner,
|
|
12886
|
+
{
|
|
12887
|
+
health: workbench.health.report,
|
|
12888
|
+
error: workbench.health.error,
|
|
12889
|
+
refreshing: workbench.health.refreshing,
|
|
12890
|
+
onRefresh: () => {
|
|
12891
|
+
void workbench.refreshHealth(true);
|
|
12892
|
+
},
|
|
12893
|
+
onDone: () => {
|
|
12894
|
+
void workbench.finishOnboarding();
|
|
12895
|
+
}
|
|
12896
|
+
}
|
|
12735
12897
|
), /* @__PURE__ */ import_react5.default.createElement(
|
|
12736
12898
|
OfficialToolsCard,
|
|
12737
12899
|
{
|
|
@@ -12745,7 +12907,18 @@ function RouterMainPage({ loadCatalog, settingsScope, listOfficialTools, install
|
|
|
12745
12907
|
void workbench.refreshHealth(true);
|
|
12746
12908
|
}
|
|
12747
12909
|
}
|
|
12748
|
-
), terminalApi && /* @__PURE__ */ import_react5.default.createElement(CliTerminalCard, { api: terminalApi, health: workbench.health.report }), /* @__PURE__ */ import_react5.default.createElement(
|
|
12910
|
+
), terminalApi && /* @__PURE__ */ import_react5.default.createElement(CliTerminalCard, { api: terminalApi, health: workbench.health.report })), /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-view mr-stack", role: "tabpanel", id: "mr-panel-controls", "aria-labelledby": "mr-tab-controls", hidden: view !== "controls" }, /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-view-heading" }, /* @__PURE__ */ import_react5.default.createElement("h2", null, "\u9884\u7B97\u4E0E\u5B89\u5168"), /* @__PURE__ */ import_react5.default.createElement("p", null, "\u8BBE\u7F6E\u6210\u672C\u4E0E\u8D28\u91CF\u7B56\u7565\uFF0C\u6838\u5BF9\u8BA2\u9605\u8BA1\u8D39\u548C\u6267\u884C\u8FB9\u754C\u3002")), /* @__PURE__ */ import_react5.default.createElement(
|
|
12911
|
+
CostControlCard,
|
|
12912
|
+
{
|
|
12913
|
+
ledger: workbench.ledger.value,
|
|
12914
|
+
error: workbench.ledger.error && !workbench.ledger.value ? workbench.ledger.error : "",
|
|
12915
|
+
settingsScope,
|
|
12916
|
+
onChanged: () => {
|
|
12917
|
+
invalidatePlan();
|
|
12918
|
+
void workbench.refreshLedger();
|
|
12919
|
+
}
|
|
12920
|
+
}
|
|
12921
|
+
), /* @__PURE__ */ import_react5.default.createElement(
|
|
12749
12922
|
BillingCard,
|
|
12750
12923
|
{
|
|
12751
12924
|
billing: workbench.health.report?.billing ?? null,
|
|
@@ -12757,7 +12930,7 @@ function RouterMainPage({ loadCatalog, settingsScope, listOfficialTools, install
|
|
|
12757
12930
|
}
|
|
12758
12931
|
), /* @__PURE__ */ import_react5.default.createElement(SecurityCard, { data: workbench.boundaries.value, error: workbench.boundaries.error, onRefresh: () => {
|
|
12759
12932
|
void workbench.refreshBoundaries();
|
|
12760
|
-
} }), /* @__PURE__ */ import_react5.default.createElement("
|
|
12933
|
+
} })), /* @__PURE__ */ import_react5.default.createElement("footer", { className: "mr-footer" }, "\u4E3B\u4F1A\u8BDD\u6A21\u578B\u7531 Harness \u7BA1\u7406\u3002\u66F4\u591A\u8BBE\u7F6E\uFF1A\u63D2\u4EF6 \u2192 \u5DF2\u5B89\u88C5 \u2192 ", /* @__PURE__ */ import_react5.default.createElement("code", null, "@ljwei-stak/dsh-model-router"), "\u3002")));
|
|
12761
12934
|
}
|
|
12762
12935
|
|
|
12763
12936
|
// .dsh-plugin/shared/official-tools-remote.mjs
|