@ljwei-stak/dsh-model-router 0.23.1 → 0.24.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 +83 -34
- package/.dsh-plugin/index.mjs +281 -51
- package/.dsh-plugin/shared/budget-reservations.mjs +254 -0
- package/.dsh-plugin/shared/execution-lifecycle.mjs +141 -0
- package/.dsh-plugin/shared/official-team-runtime.mjs +37 -13
- package/.dsh-plugin/shared/official-tools-runtime.mjs +3 -2
- package/.dsh-plugin/shared/router-state.mjs +23 -8
- package/.dsh-plugin/shared/run-ledger.mjs +6 -1
- package/.dsh-plugin/shared/task-executors.mjs +32 -3
- package/.dsh-plugin/shared/zcode-bundle.mjs +3 -3
- package/CHANGELOG.md +13 -0
- package/README.i18n.yaml +2 -2
- package/README.md +25 -17
- package/README.zh.md +24 -16
- package/docs/assets/workbench-budget-reservations.png +0 -0
- package/docs/releases/0.24.0-validation.md +41 -0
- package/package.json +7 -3
package/.dsh-plugin/client.js
CHANGED
|
@@ -3254,6 +3254,8 @@ var import_react2 = __toESM(require("react"), 1);
|
|
|
3254
3254
|
// .dsh-plugin/client/insights-state.mjs
|
|
3255
3255
|
var PACKAGE_STATUS = Object.freeze({
|
|
3256
3256
|
pending: Object.freeze({ label: "\u5F85\u6267\u884C", tone: "pending" }),
|
|
3257
|
+
running: Object.freeze({ label: "\u6267\u884C\u4E2D", tone: "pending" }),
|
|
3258
|
+
interrupted: Object.freeze({ label: "\u6267\u884C\u4E2D\u65AD\uFF0C\u8D39\u7528\u5F85\u6838\u5BF9", tone: "warn" }),
|
|
3257
3259
|
succeeded: Object.freeze({ label: "\u5B98\u65B9 CLI \u5B8C\u6210", tone: "ok" }),
|
|
3258
3260
|
fallback: Object.freeze({ label: "\u5DF2\u56DE\u9000 API \u5B8C\u6210", tone: "warn" }),
|
|
3259
3261
|
failed: Object.freeze({ label: "\u5931\u8D25", tone: "error" }),
|
|
@@ -3314,14 +3316,43 @@ function budgetMeter(spent, limit) {
|
|
|
3314
3316
|
const share = Math.min(1, Math.max(0, spent / limit));
|
|
3315
3317
|
return { limited: true, share, over: spent >= limit, text: `${money(spent)} / ${money(limit)}` };
|
|
3316
3318
|
}
|
|
3319
|
+
var nonnegative2 = (value) => typeof value === "number" && Number.isFinite(value) && value > 0 ? value : 0;
|
|
3320
|
+
function reservationSummary(ledger) {
|
|
3321
|
+
const value = ledger?.reserved ?? {};
|
|
3322
|
+
const reservations = (ledger?.reservations ?? []).filter((item) => ["active", "interrupted"].includes(item.status));
|
|
3323
|
+
return {
|
|
3324
|
+
today: nonnegative2(value.today),
|
|
3325
|
+
month: nonnegative2(value.month),
|
|
3326
|
+
unknownToday: nonnegative2(value.unknownToday),
|
|
3327
|
+
unknownMonth: nonnegative2(value.unknownMonth),
|
|
3328
|
+
activeCount: value.activeCount === void 0 ? reservations.filter((item) => item.status === "active").length : nonnegative2(value.activeCount),
|
|
3329
|
+
interruptedCount: value.interruptedCount === void 0 ? reservations.filter((item) => item.status === "interrupted").length : nonnegative2(value.interruptedCount)
|
|
3330
|
+
};
|
|
3331
|
+
}
|
|
3332
|
+
function budgetOccupancyMeter(spent, limit, reserved = 0) {
|
|
3333
|
+
const actual = nonnegative2(spent);
|
|
3334
|
+
const hold = nonnegative2(reserved);
|
|
3335
|
+
const meter = budgetMeter(actual + hold, limit);
|
|
3336
|
+
return { ...meter, text: `\u5DF2\u53D1\u751F ${money(actual)} \xB7 \u9884\u5360 ${money(hold)}${limit > 0 ? ` / \u4E0A\u9650 ${money(limit)}` : "\uFF08\u672A\u8BBE\u4E0A\u9650\uFF09"}` };
|
|
3337
|
+
}
|
|
3317
3338
|
function planBudget(ledger, estimateUsd) {
|
|
3318
3339
|
if (!ledger?.budget) return null;
|
|
3319
|
-
|
|
3340
|
+
const actual = ledger.spent ?? { today: 0, month: 0 };
|
|
3341
|
+
const reserved = reservationSummary(ledger);
|
|
3342
|
+
const result = budgetCheck({
|
|
3320
3343
|
estimateUsd,
|
|
3321
|
-
spent:
|
|
3344
|
+
spent: { ...actual, today: nonnegative2(actual.today) + reserved.today, month: nonnegative2(actual.month) + reserved.month },
|
|
3322
3345
|
dailyLimitUsd: ledger.budget.dailyLimitUsd,
|
|
3323
3346
|
monthlyLimitUsd: ledger.budget.monthlyLimitUsd
|
|
3324
3347
|
});
|
|
3348
|
+
if (result.exceeded) {
|
|
3349
|
+
const period = result.exceeded === "daily" ? "today" : "month";
|
|
3350
|
+
if (reserved[period] > 0) result.message = result.message.replace(
|
|
3351
|
+
`\u5DF2\u7528 ${money(nonnegative2(actual[period]) + reserved[period])}`,
|
|
3352
|
+
`\u5DF2\u53D1\u751F ${money(nonnegative2(actual[period]))}\uFF0C\u9884\u5360 ${money(reserved[period])}`
|
|
3353
|
+
);
|
|
3354
|
+
}
|
|
3355
|
+
return result;
|
|
3325
3356
|
}
|
|
3326
3357
|
function unwrapRemote(response, fallback) {
|
|
3327
3358
|
if (!response?.ok) throw new Error(String(response?.error?.message ?? "") || fallback);
|
|
@@ -3338,6 +3369,8 @@ var RUN_STATUS_LABEL = Object.freeze({
|
|
|
3338
3369
|
partial: "\u90E8\u5206\u5B8C\u6210",
|
|
3339
3370
|
failed: "\u5931\u8D25",
|
|
3340
3371
|
"cli-completed": "\u5B8C\u6210",
|
|
3372
|
+
running: "\u6267\u884C\u4E2D",
|
|
3373
|
+
interrupted: "\u6267\u884C\u4E2D\u65AD\uFF0C\u8D39\u7528\u5F85\u6838\u5BF9",
|
|
3341
3374
|
incomplete: "\u672A\u5B8C\u6210",
|
|
3342
3375
|
paused: "\u7B49\u5F85\u786E\u8BA4",
|
|
3343
3376
|
"integration-pending": "\u5F85\u6574\u5408",
|
|
@@ -3382,7 +3415,18 @@ function runTotals(run) {
|
|
|
3382
3415
|
}
|
|
3383
3416
|
return { budgetUsd, referenceUsd, subscription };
|
|
3384
3417
|
}
|
|
3385
|
-
function rerunSupport(run) {
|
|
3418
|
+
function rerunSupport(run, ledger = null) {
|
|
3419
|
+
const reservation = (ledger?.reservations ?? []).find((item) => item.runId === run?.id && ["active", "interrupted"].includes(item.status));
|
|
3420
|
+
if (["running", "interrupted"].includes(run?.status) || reservation) {
|
|
3421
|
+
const interrupted = run?.status === "interrupted" || reservation?.status === "interrupted";
|
|
3422
|
+
return {
|
|
3423
|
+
supported: false,
|
|
3424
|
+
writes: run?.executionMode === "workspace-write",
|
|
3425
|
+
reassign: false,
|
|
3426
|
+
confirm: "",
|
|
3427
|
+
reason: interrupted ? "\u6267\u884C\u4E2D\u65AD\uFF0C\u8D39\u7528\u5F85\u6838\u5BF9\uFF0C\u4E0D\u80FD\u76F4\u63A5\u91CD\u8DD1\u3002\u8BF7\u5148\u6838\u5BF9\u65E7\u4EFB\u52A1\u4E0E\u5382\u5546\u8D26\u5355\uFF0C\u5E76\u4FDD\u7559\u539F\u59CB\u72B6\u6001\u53CA\u5DF2\u4FDD\u5B58\u7ED3\u679C\uFF1B\u4E0D\u4F1A\u81EA\u52A8\u4ED8\u8D39\u6062\u590D\u3002" : "\u4EFB\u52A1\u4ECD\u5728\u6267\u884C\u6216\u4FDD\u7559\u9884\u7B97\u9884\u5360\uFF0C\u4E0D\u80FD\u76F4\u63A5\u91CD\u8DD1\u3002\u8BF7\u5148\u7B49\u5F85\u539F\u4EFB\u52A1\u7ED3\u675F\uFF0C\u6216\u5728\u6267\u884C\u8FDB\u5EA6\u4E2D\u53D6\u6D88\u540E\u6838\u5BF9\u7ED3\u679C\u4E0E\u5382\u5546\u8D26\u5355\u3002"
|
|
3428
|
+
};
|
|
3429
|
+
}
|
|
3386
3430
|
if (run?.kind === "tool") {
|
|
3387
3431
|
const editable = run.executionMode === "workspace-write";
|
|
3388
3432
|
return {
|
|
@@ -3512,7 +3556,8 @@ function launchRequest({ task, mode, directRoute, budgetUsd, preset, workspace,
|
|
|
3512
3556
|
}
|
|
3513
3557
|
function rerunConfirmations({ run, item, override = null, choice = null, ledger = null, health = null, toolFor = () => null, headlessIds = /* @__PURE__ */ new Set() } = {}) {
|
|
3514
3558
|
const reasons = [];
|
|
3515
|
-
const support = rerunSupport(run);
|
|
3559
|
+
const support = rerunSupport(run, ledger);
|
|
3560
|
+
if (!support.supported) return reasons;
|
|
3516
3561
|
if (support.writes) reasons.push({ code: "workspace-write", text: support.confirm });
|
|
3517
3562
|
if (run?.kind === "team" && run.executionEnvironment === "cli-native") reasons.push({
|
|
3518
3563
|
code: "unsandboxed",
|
|
@@ -3525,12 +3570,7 @@ function rerunConfirmations({ run, item, override = null, choice = null, ledger
|
|
|
3525
3570
|
reasons.push({ code: "unsandboxed", text: `\u4F1A\u76F4\u63A5\u542F\u52A8 ${tool.label} \u7684\u65E0\u754C\u9762 CLI\uFF0C\u4E0D\u7ECF\u8FC7 Harness \u8FDB\u7A0B\u6C99\u7BB1\uFF0C\u53EA\u8BFB\u4EC5\u7531 CLI \u53C2\u6570\u4FDD\u8BC1\u3002` });
|
|
3526
3571
|
}
|
|
3527
3572
|
const estimate = override ? null : item?.estimatedCost;
|
|
3528
|
-
const check = ledger
|
|
3529
|
-
estimateUsd: typeof estimate === "number" ? estimate : null,
|
|
3530
|
-
spent: ledger.spent ?? {},
|
|
3531
|
-
dailyLimitUsd: ledger.budget.dailyLimitUsd,
|
|
3532
|
-
monthlyLimitUsd: ledger.budget.monthlyLimitUsd
|
|
3533
|
-
}) : null;
|
|
3573
|
+
const check = planBudget(ledger, typeof estimate === "number" ? estimate : null);
|
|
3534
3574
|
if (check?.exceeded) reasons.push({ code: "over-budget", text: `\u8D85\u51FA\u9884\u7B97\uFF1A${check.message}` });
|
|
3535
3575
|
return reasons;
|
|
3536
3576
|
}
|
|
@@ -3598,18 +3638,18 @@ function feedbackRatingArguments(run, item, direction) {
|
|
|
3598
3638
|
const active = direction === "up" ? item?.rating === 1 : item?.rating === -1;
|
|
3599
3639
|
return [run?.id, item?.id, active ? "clear" : direction, item?.finishedAt];
|
|
3600
3640
|
}
|
|
3601
|
-
var
|
|
3641
|
+
var nonnegative3 = (value) => Number.isFinite(value) && value >= 0 ? value : 0;
|
|
3602
3642
|
function learningView(learning, settings = {}) {
|
|
3603
3643
|
return {
|
|
3604
3644
|
available: Boolean(learning && typeof learning === "object" && !Array.isArray(learning)),
|
|
3605
3645
|
// Current settings govern the next plan; a failed refresh must not make an
|
|
3606
3646
|
// older profile claim that a newly disabled policy is still enabled.
|
|
3607
3647
|
enabled: adaptiveSettingValue(settings, "feedbackLearningEnabled") !== false,
|
|
3608
|
-
feedbackCount:
|
|
3609
|
-
ignoredCount:
|
|
3610
|
-
effectiveWeight:
|
|
3648
|
+
feedbackCount: nonnegative3(learning?.feedbackCount),
|
|
3649
|
+
ignoredCount: nonnegative3(learning?.ignoredCount),
|
|
3650
|
+
effectiveWeight: nonnegative3(learning?.effectiveWeight),
|
|
3611
3651
|
policyVersion: typeof learning?.policyVersion === "string" ? learning.policyVersion.slice(0, 100) : null,
|
|
3612
|
-
resetAt:
|
|
3652
|
+
resetAt: nonnegative3(adaptiveSettingValue(settings, "feedbackResetAt"))
|
|
3613
3653
|
};
|
|
3614
3654
|
}
|
|
3615
3655
|
function learningEvidenceRows(learning, limit = 12) {
|
|
@@ -3625,11 +3665,11 @@ function learningEvidenceRows(learning, limit = 12) {
|
|
|
3625
3665
|
id: JSON.stringify([key, domain]),
|
|
3626
3666
|
route: identity.map((part) => part.slice(0, 100)).join("/"),
|
|
3627
3667
|
domain: domain.slice(0, 80),
|
|
3628
|
-
feedbackCount:
|
|
3629
|
-
positiveCount:
|
|
3630
|
-
negativeCount:
|
|
3631
|
-
effectiveWeight:
|
|
3632
|
-
effectiveSampleSize:
|
|
3668
|
+
feedbackCount: nonnegative3(cell.feedbackCount),
|
|
3669
|
+
positiveCount: nonnegative3(cell.positiveCount),
|
|
3670
|
+
negativeCount: nonnegative3(cell.negativeCount),
|
|
3671
|
+
effectiveWeight: nonnegative3(cell.effectiveWeight),
|
|
3672
|
+
effectiveSampleSize: nonnegative3(cell.effectiveSampleSize),
|
|
3633
3673
|
shrinkage: Number.isFinite(cell.shrinkage) && cell.shrinkage >= 0 && cell.shrinkage <= 1 ? cell.shrinkage : 0,
|
|
3634
3674
|
adjustment: cell.adjustment
|
|
3635
3675
|
});
|
|
@@ -3652,7 +3692,7 @@ var EXCLUSION_LABELS = Object.freeze({
|
|
|
3652
3692
|
});
|
|
3653
3693
|
function learningExclusionRows(learning) {
|
|
3654
3694
|
return Object.entries(EXCLUSION_LABELS).flatMap(([reason, label]) => {
|
|
3655
|
-
const count =
|
|
3695
|
+
const count = nonnegative3(learning?.exclusionReasons?.[reason]);
|
|
3656
3696
|
return count > 0 ? [{ reason, label, count }] : [];
|
|
3657
3697
|
});
|
|
3658
3698
|
}
|
|
@@ -3669,7 +3709,7 @@ function dynamicSourceView(source, enabled = true) {
|
|
|
3669
3709
|
source: publicSource,
|
|
3670
3710
|
version: enabled !== false && typeof source?.version === "string" ? source.version.slice(0, 160) : null,
|
|
3671
3711
|
verifiedAt: enabled !== false && Number.isFinite(source?.verifiedAt) && source.verifiedAt > 0 ? source.verifiedAt : null,
|
|
3672
|
-
count: enabled === false ? 0 :
|
|
3712
|
+
count: enabled === false ? 0 : nonnegative3(source?.modelCount ?? source?.rowCount),
|
|
3673
3713
|
refreshing: enabled !== false && source?.refreshing === true,
|
|
3674
3714
|
pending: enabled !== false && source?.pending === true,
|
|
3675
3715
|
lastAttemptAt: enabled === false ? null : positiveTime(source?.lastAttemptAt),
|
|
@@ -3911,6 +3951,8 @@ function CostControlCard({ ledger, settingsScope, onChanged, error, refreshing =
|
|
|
3911
3951
|
const daily = Number(value.dailyBudgetUsd ?? 0);
|
|
3912
3952
|
const monthly = Number(value.monthlyBudgetUsd ?? 0);
|
|
3913
3953
|
const spent = ledger?.spent ?? { today: 0, month: 0, unknownToday: 0, unknownMonth: 0 };
|
|
3954
|
+
const reserved = reservationSummary(ledger);
|
|
3955
|
+
const reservations = (ledger?.reservations ?? []).filter((item) => ["active", "interrupted"].includes(item.status));
|
|
3914
3956
|
const set = async (key, next) => {
|
|
3915
3957
|
if (await settings.write(key, next)) onChanged?.();
|
|
3916
3958
|
};
|
|
@@ -3922,7 +3964,7 @@ function CostControlCard({ ledger, settingsScope, onChanged, error, refreshing =
|
|
|
3922
3964
|
onChanged?.();
|
|
3923
3965
|
}
|
|
3924
3966
|
};
|
|
3925
|
-
return /* @__PURE__ */ import_react2.default.createElement("section", { className: "mr-card mr-cost", "aria-label": "\u6210\u672C\u63A7\u5236" }, /* @__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" }, "\u6210\u672C\u63A7\u5236\u4E0E\u8DEF\u7531\u65B9\u6848"), /* @__PURE__ */ import_react2.default.createElement("p", { className: "mr-card-copy" }, "\u9884\u7B97\u53EA\u8BA1\u7B97\u8D70 API Key \u6216\u6A21\u578B\u76EE\u5F55 API \u7684\u82B1\u8D39\uFF08CLI \u81EA\u62A5\u91D1\u989D\u6216 token \u7528\u91CF \xD7 \u4F60\u914D\u7F6E\u7684\u5355\u4EF7\uFF09\u3002\u5B98\u65B9 CLI \u7528\u8BA2\u9605\u8D26\u53F7\u767B\u5F55\u3001\u672A\u6CE8\u5165 API Key \u65F6\uFF0C\u53EA\u663E\u793A\u6309 API \u4EF7\u6298\u7B97\u7684\u201C\u8BA2\u9605\u53C2\u8003\u8D39\u7528\u201D\uFF0C\u4E0D\u8BA1\u5165\u9884\u7B97\u3002\u7F3A\u5C11\u5355\u4EF7\u7684\u8C03\u7528\u8BA1\u4E3A\u201C\u8D39\u7528\u672A\u77E5\u201D\u3002\u8FD9\u662F\u672C\u673A\u4F30\u7B97\uFF0C\u4E0D\u662F\u5382\u5546\u8D26\u5355\u3002"))), /* @__PURE__ */ import_react2.default.createElement("div", { className: "mr-card-body" }, error && /* @__PURE__ */ import_react2.default.createElement("p", { className: "mr-error", role: "alert" }, error), /* @__PURE__ */ import_react2.default.createElement("div", { className: "mr-meters" }, /* @__PURE__ */ import_react2.default.createElement(Meter, { label: "\u4ECA\u65E5\
|
|
3967
|
+
return /* @__PURE__ */ import_react2.default.createElement("section", { className: "mr-card mr-cost", "aria-label": "\u6210\u672C\u63A7\u5236" }, /* @__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" }, "\u6210\u672C\u63A7\u5236\u4E0E\u8DEF\u7531\u65B9\u6848"), /* @__PURE__ */ import_react2.default.createElement("p", { className: "mr-card-copy" }, "\u9884\u7B97\u53EA\u8BA1\u7B97\u8D70 API Key \u6216\u6A21\u578B\u76EE\u5F55 API \u7684\u82B1\u8D39\uFF08CLI \u81EA\u62A5\u91D1\u989D\u6216 token \u7528\u91CF \xD7 \u4F60\u914D\u7F6E\u7684\u5355\u4EF7\uFF09\u3002\u5B98\u65B9 CLI \u7528\u8BA2\u9605\u8D26\u53F7\u767B\u5F55\u3001\u672A\u6CE8\u5165 API Key \u65F6\uFF0C\u53EA\u663E\u793A\u6309 API \u4EF7\u6298\u7B97\u7684\u201C\u8BA2\u9605\u53C2\u8003\u8D39\u7528\u201D\uFF0C\u4E0D\u8BA1\u5165\u9884\u7B97\u3002\u7F3A\u5C11\u5355\u4EF7\u7684\u8C03\u7528\u8BA1\u4E3A\u201C\u8D39\u7528\u672A\u77E5\u201D\u3002\u8FD9\u662F\u672C\u673A\u4F30\u7B97\uFF0C\u4E0D\u662F\u5382\u5546\u8D26\u5355\u3002"))), /* @__PURE__ */ import_react2.default.createElement("div", { className: "mr-card-body" }, error && /* @__PURE__ */ import_react2.default.createElement("p", { className: "mr-error", role: "alert" }, error), /* @__PURE__ */ import_react2.default.createElement("div", { className: "mr-meters" }, /* @__PURE__ */ import_react2.default.createElement(Meter, { label: "\u4ECA\u65E5\u9884\u7B97\u5360\u7528", meter: budgetOccupancyMeter(spent.today, daily, reserved.today) }), /* @__PURE__ */ import_react2.default.createElement(Meter, { label: "\u672C\u6708\u9884\u7B97\u5360\u7528", meter: budgetOccupancyMeter(spent.month, monthly, reserved.month) })), /* @__PURE__ */ import_react2.default.createElement("p", { className: "mr-caption" }, "\u9884\u5360\u662F\u5C1A\u672A\u7ED3\u7B97\u7684\u8D39\u7528\u4F30\u7B97\uFF0C\u4E0D\u662F\u5B9E\u9645\u8D26\u5355\uFF1B\u5269\u4F59\u989D\u5EA6\u5DF2\u6263\u9664\u5DF2\u53D1\u751F\u8D39\u7528\u4E0E\u5DF2\u77E5\u9884\u5360\u3002\u6267\u884C\u4E2D ", reserved.activeCount, " \u9879 \xB7 \u5F85\u6838\u5BF9\u4E2D\u65AD ", reserved.interruptedCount, " \u9879\u3002"), (reserved.unknownToday > 0 || reserved.unknownMonth > 0) && /* @__PURE__ */ import_react2.default.createElement("p", { className: "mr-caption mr-warn-text" }, "\u9884\u5360\u91D1\u989D\u672A\u77E5\uFF1A\u4ECA\u65E5 ", reserved.unknownToday, " \u9879 \xB7 \u672C\u6708 ", reserved.unknownMonth, " \u9879\uFF0C\u672A\u8BA1\u5165\u4E0A\u65B9\u9884\u5360\u91D1\u989D\uFF0C\u4E0D\u80FD\u89C6\u4E3A\u96F6\u8D39\u7528\u3002\u8BF7\u6838\u5BF9\u5382\u5546\u8D26\u5355\u4E0E\u539F\u4EFB\u52A1\u8BB0\u5F55\u3002"), reserved.interruptedCount > 0 && /* @__PURE__ */ import_react2.default.createElement("p", { className: "mr-error", role: "alert" }, "\u6709\u4E2D\u65AD\u4EFB\u52A1\u5C1A\u672A\u6838\u5BF9\uFF0C\u9884\u5360\u7EE7\u7EED\u4FDD\u7559\uFF0C\u4E0D\u80FD\u76F4\u63A5\u91CD\u8DD1\u3002\u8BF7\u5148\u6838\u5BF9\u65E7\u4EFB\u52A1\u4E0E\u5382\u5546\u8D26\u5355\uFF0C\u4FDD\u7559\u539F\u59CB\u72B6\u6001\u6587\u4EF6\u548C\u5DF2\u4FDD\u5B58\u7ED3\u679C\uFF1B\u82E5\u8BB0\u5F55\u635F\u574F\uFF0C\u4ECE\u53EF\u4FE1\u5907\u4EFD\u6062\u590D\u5B8C\u6574\u72B6\u6001\u3002\u5F53\u524D\u754C\u9762\u4E0D\u652F\u6301\u624B\u52A8\u7ED3\u7B97\u6216\u81EA\u52A8\u4ED8\u8D39\u6062\u590D\u3002"), reservations.length > 0 && /* @__PURE__ */ import_react2.default.createElement("details", { className: "mr-tool-log" }, /* @__PURE__ */ import_react2.default.createElement("summary", null, "\u67E5\u770B\u672A\u7ED3\u7B97\u9884\u5360\uFF08", reservations.length, " \u9879\uFF09"), /* @__PURE__ */ import_react2.default.createElement("ul", { className: "mr-checklist" }, reservations.map((item) => /* @__PURE__ */ import_react2.default.createElement("li", { key: item.id }, "\u8FD0\u884C ", /* @__PURE__ */ import_react2.default.createElement("code", null, item.runId || item.id), " \xB7 ", item.status === "interrupted" ? "\u6267\u884C\u4E2D\u65AD\uFF0C\u8D39\u7528\u5F85\u6838\u5BF9" : "\u6267\u884C\u4E2D", " \xB7 \u5269\u4F59\u9884\u5360 ", item.unknown || !Number.isFinite(item.remainingEstimateUsd) ? "\u91D1\u989D\u672A\u77E5" : money(item.remainingEstimateUsd), Number.isFinite(item.updatedAt) ? ` \xB7 \u6700\u8FD1\u4FDD\u5B58 ${new Date(item.updatedAt).toLocaleString()}` : "")))), (spent.subscriptionRunsMonth ?? 0) > 0 && /* @__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\u4ECA\u65E5 ", money(spent.subscriptionToday ?? 0), " \xB7 \u672C\u6708 ", money(spent.subscriptionMonth ?? 0), "\uFF0C\u672C\u6708\u5171 ", spent.subscriptionRunsMonth, " \u6B21\u8BA2\u9605\u767B\u5F55\u8C03\u7528\u3002"), (spent.unknownToday > 0 || spent.unknownMonth > 0) && /* @__PURE__ */ import_react2.default.createElement("p", { className: "mr-caption" }, "\u672C\u6708\u6709 ", spent.unknownMonth, " \u6B21\u8C03\u7528\u7F3A\u5C11\u5355\u4EF7\u6216\u7528\u91CF\uFF0C\u672A\u8BA1\u5165\u91D1\u989D\u3002\u8BF7\u5728\u201C\u6A21\u578B\u4EF7\u683C\u4E0E\u80FD\u529B\u201D\u4E2D\u8865\u9F50\u5355\u4EF7\u3002"), ledger?.budget?.exceeded && /* @__PURE__ */ import_react2.default.createElement("p", { className: "mr-error", role: "alert" }, ledger.budget.message, " ", ledger.budget.action === "pause" ? "\u65B0\u7684\u6267\u884C\u4F1A\u5148\u6682\u505C\u5E76\u8BF7\u6C42\u786E\u8BA4\u3002" : "\u65B0\u7684\u6267\u884C\u4F1A\u5C1D\u8BD5\u81EA\u52A8\u964D\u7EA7\u4E3A\u201C\u7701\u94B1\u4F18\u5148\u201D\u3002"), /* @__PURE__ */ import_react2.default.createElement("div", { className: "mr-controls" }, /* @__PURE__ */ import_react2.default.createElement("div", { className: "mr-control-group" }, /* @__PURE__ */ import_react2.default.createElement("span", { className: "mr-control-label" }, "\u8DEF\u7531\u65B9\u6848"), /* @__PURE__ */ import_react2.default.createElement("div", { className: "mr-segment", role: "group", "aria-label": "\u8DEF\u7531\u65B9\u6848" }, Object.values(ROUTING_PRESETS).map((item) => /* @__PURE__ */ import_react2.default.createElement("button", { key: item.id, type: "button", title: item.description, "aria-pressed": preset === item.id, disabled: !settings.writable, onClick: () => {
|
|
3926
3968
|
void set("routingPreset", item.id);
|
|
3927
3969
|
} }, item.label))), /* @__PURE__ */ import_react2.default.createElement("span", { className: "mr-caption" }, ROUTING_PRESETS[preset]?.description)), /* @__PURE__ */ import_react2.default.createElement("div", { className: "mr-control-group" }, /* @__PURE__ */ import_react2.default.createElement("label", { className: "mr-control-label", htmlFor: "mr-daily-budget" }, "\u6BCF\u65E5\u4E0A\u9650\uFF08USD\uFF0C0 \u4E3A\u4E0D\u9650\uFF09"), /* @__PURE__ */ import_react2.default.createElement("div", { className: "mr-inline" }, /* @__PURE__ */ import_react2.default.createElement("input", { className: "mr-input mr-budget", id: "mr-daily-budget", type: "number", min: "0", step: "0.5", placeholder: String(daily), value: dailyDraft, onChange: (event) => setDailyDraft(event.target.value) }), /* @__PURE__ */ import_react2.default.createElement("button", { className: "mr-button mr-button-secondary", type: "button", disabled: !settings.writable || dailyDraft === "", onClick: () => {
|
|
3928
3970
|
void saveLimit("dailyBudgetUsd", dailyDraft, setDailyDraft);
|
|
@@ -3952,22 +3994,22 @@ function DagView({ packages, renderNode, label = "\u5B50\u4EFB\u52A1\u4F9D\u8D56
|
|
|
3952
3994
|
}))));
|
|
3953
3995
|
}
|
|
3954
3996
|
function ChannelText({ item }) {
|
|
3955
|
-
if (!item.channel) return /* @__PURE__ */ import_react2.default.createElement("span", { className: "mr-pill" }, "\u5F85\u6267\u884C");
|
|
3997
|
+
if (!item.channel) return /* @__PURE__ */ import_react2.default.createElement("span", { className: "mr-pill" }, item.status === "running" ? "\u6267\u884C\u4E2D" : item.status === "interrupted" ? "\u6267\u884C\u4E2D\u65AD" : "\u5F85\u6267\u884C");
|
|
3956
3998
|
return /* @__PURE__ */ import_react2.default.createElement("span", { className: item.channel === "official-cli" ? "mr-pill mr-pill-channel-ok" : "mr-pill" }, item.channel === "official-cli" ? `\u5B98\u65B9 CLI \xB7 ${item.toolId ?? ""}` : "\u6A21\u578B\u76EE\u5F55 API");
|
|
3957
3999
|
}
|
|
3958
|
-
function RunNode({ run, item, routes, allowReassign, busy, onRate, onRerun }) {
|
|
4000
|
+
function RunNode({ run, item, routes, allowReassign, busy, onRate, onRerun, ledger }) {
|
|
3959
4001
|
const [target, setTarget] = import_react2.default.useState("");
|
|
3960
|
-
|
|
4002
|
+
const rerun = rerunSupport(run, ledger);
|
|
4003
|
+
if (item.status === "paused") return /* @__PURE__ */ import_react2.default.createElement(PausedNode, { run, item, busy, onRerun, rerun });
|
|
3961
4004
|
const cost = packageCost(item);
|
|
3962
|
-
const rerun = rerunSupport(run);
|
|
3963
4005
|
const canRerun = rerun.supported && !item.ok && !busy;
|
|
3964
4006
|
const others = routes.filter((route) => `${route.provider}/${route.model}` !== `${item.provider}/${item.model}`);
|
|
3965
|
-
return /* @__PURE__ */ import_react2.default.createElement(import_react2.default.Fragment, null, /* @__PURE__ */ import_react2.default.createElement("p", { className: "mr-package-route" }, item.provider, "/", item.model, item.reassigned ? "\uFF08\u5DF2\u6539\u6D3E\uFF09" : ""), item.manualAssignment && /* @__PURE__ */ import_react2.default.createElement("p", { className: "mr-caption" }, "\u624B\u52A8\u5206\u914D \xB7 ", item.manualAssignment.kind === "tool" ? `\u5B98\u65B9\u5DE5\u5177 ${item.manualAssignment.toolId}\uFF08\u5382\u5546\u9ED8\u8BA4\u6A21\u578B\uFF09` : `\u6A21\u578B API ${item.manualAssignment.provider}/${item.manualAssignment.model}`, item.algorithmRecommendation?.provider ? ` \xB7 \u539F\u63A8\u8350 ${item.algorithmRecommendation.provider}/${item.algorithmRecommendation.model}` : ""), /* @__PURE__ */ import_react2.default.createElement("div", { className: "mr-channel-line" }, /* @__PURE__ */ import_react2.default.createElement(ChannelText, { item }), /* @__PURE__ */ import_react2.default.createElement("span", { className: "mr-caption" }, "\u9884\u4F30 ", money(item.estimatedCost), " \xB7 \u5B9E\u9645 ", cost.budget, item.difficulty ? ` \xB7 \u96BE\u5EA6 ${BAND[item.difficulty] ?? item.difficulty}` : "")), cost.reference && /* @__PURE__ */ import_react2.default.createElement("p", { className: "mr-package-copy" }, cost.reference), item.actualModel && /* @__PURE__ */ import_react2.default.createElement("p", { className: "mr-package-copy" }, "CLI \u56DE\u62A5\u6A21\u578B\uFF1A", item.actualModel), (item.billing || item.billingMode) && /* @__PURE__ */ import_react2.default.createElement("p", { className: "mr-package-copy" }, "\u8BA1\u8D39\uFF1A", BILLING_CHANNEL_LABEL[item.billing] ?? "\u2014", item.subscriptionRoute ? ` \xB7 \u5957\u9910\u8DEF\u7EBF ${item.subscriptionRoute.provider}/${item.subscriptionRoute.model}` : "", item.billingMode && item.billingMode !== "subscription-first" ? ` \xB7 ${BILLING_MODE_LABEL[item.billingMode] ?? item.billingMode}` : ""), billingSwitchText(item) && /* @__PURE__ */ import_react2.default.createElement("p", { className: "mr-package-copy mr-warn-text" }, "\u8BA1\u8D39\u5207\u6362\uFF1A", billingSwitchText(item)), item.fallback?.reason && item.fallback.reason !== billingSwitchText(item) && /* @__PURE__ */ import_react2.default.createElement("p", { className: "mr-package-copy" }, "\u56DE\u9000\u539F\u56E0\uFF1A", item.fallback.reason), item.fallback?.error && /* @__PURE__ */ import_react2.default.createElement("p", { className: "mr-package-copy mr-fallback-error" }, "CLI \u539F\u59CB\u9519\u8BEF\uFF1A", /* @__PURE__ */ import_react2.default.createElement("code", null, item.fallback.error)), !item.ok && item.error && /* @__PURE__ */ import_react2.default.createElement("p", { className: "mr-package-copy mr-fallback-error" }, item.error), !item.ok && item.diagnostic && /* @__PURE__ */ import_react2.default.createElement("details", { className: "mr-tool-log" }, /* @__PURE__ */ import_react2.default.createElement("summary", null, "CLI \u8BCA\u65AD", Number.isInteger(item.exitCode) ? `\uFF08\u9000\u51FA\u7801 ${item.exitCode}\uFF09` : ""), /* @__PURE__ */ import_react2.default.createElement("pre", null, item.diagnostic)), item.review && /* @__PURE__ */ import_react2.default.createElement("p", { className: "mr-package-copy" }, "\u5F3A\u6A21\u578B\u62BD\u67E5\uFF08", item.review.provider, "/", item.review.model, "\uFF09\uFF1A", item.review.score ? `${item.review.score}/5` : "\u672A\u8BC4\u5206", " ", item.review.summary), item.answer && /* @__PURE__ */ import_react2.default.createElement("details", { className: "mr-tool-log" }, /* @__PURE__ */ import_react2.default.createElement("summary", null, "\u67E5\u770B\u7ED3\u679C"), /* @__PURE__ */ import_react2.default.createElement("pre", null, item.answer, item.answerTruncated ? "\n\u2026\uFF08\u5DF2\u622A\u65AD\uFF09" : "")), /* @__PURE__ */ import_react2.default.createElement("div", { className: "mr-node-actions" }, item.ok && /* @__PURE__ */ import_react2.default.createElement(import_react2.default.Fragment, null, /* @__PURE__ */ import_react2.default.createElement("button", { className: "mr-button mr-button-secondary mr-mini", type: "button", title: item.rating === 1 ? "\u518D\u6B21\u70B9\u51FB\u64A4\u56DE\u6709\u7528\u8BC4\u4EF7" : "\u8BC4\u4EF7\u6B64\u7ED3\u679C\u6709\u7528", "aria-pressed": item.rating === 1, disabled: busy, onClick: () => onRate(...feedbackRatingArguments(run, item, "up")) }, "\u{1F44D} \u6709\u7528"), /* @__PURE__ */ import_react2.default.createElement("button", { className: "mr-button mr-button-secondary mr-mini", type: "button", title: item.rating === -1 ? "\u518D\u6B21\u70B9\u51FB\u64A4\u56DE\u4E0D\u597D\u8BC4\u4EF7" : "\u8BC4\u4EF7\u6B64\u7ED3\u679C\u4E0D\u597D", "aria-pressed": item.rating === -1, disabled: busy, onClick: () => onRate(...feedbackRatingArguments(run, item, "down")) }, "\u{1F44E} \u4E0D\u597D")), canRerun && /* @__PURE__ */ import_react2.default.createElement("button", { className: "mr-button mr-mini", type: "button", title: rerun.confirm || void 0, onClick: () => onRerun(run.id, item.id, null) }, run.kind === "tool" ? "\u91CD\u65B0\u6267\u884C\u6B64\u8C03\u7528" : rerun.writes ? "\u5728\u65B0\u5DE5\u4F5C\u533A\u7EED\u8DD1" : "\u91CD\u8DD1\u6B64\u6B65"), !rerun.supported && !item.ok &&
|
|
4007
|
+
return /* @__PURE__ */ import_react2.default.createElement(import_react2.default.Fragment, null, /* @__PURE__ */ import_react2.default.createElement("p", { className: "mr-package-route" }, item.provider, "/", item.model, item.reassigned ? "\uFF08\u5DF2\u6539\u6D3E\uFF09" : ""), item.manualAssignment && /* @__PURE__ */ import_react2.default.createElement("p", { className: "mr-caption" }, "\u624B\u52A8\u5206\u914D \xB7 ", item.manualAssignment.kind === "tool" ? `\u5B98\u65B9\u5DE5\u5177 ${item.manualAssignment.toolId}\uFF08\u5382\u5546\u9ED8\u8BA4\u6A21\u578B\uFF09` : `\u6A21\u578B API ${item.manualAssignment.provider}/${item.manualAssignment.model}`, item.algorithmRecommendation?.provider ? ` \xB7 \u539F\u63A8\u8350 ${item.algorithmRecommendation.provider}/${item.algorithmRecommendation.model}` : ""), /* @__PURE__ */ import_react2.default.createElement("div", { className: "mr-channel-line" }, /* @__PURE__ */ import_react2.default.createElement(ChannelText, { item }), /* @__PURE__ */ import_react2.default.createElement("span", { className: "mr-caption" }, "\u9884\u4F30 ", money(item.estimatedCost), " \xB7 \u5B9E\u9645 ", cost.budget, item.difficulty ? ` \xB7 \u96BE\u5EA6 ${BAND[item.difficulty] ?? item.difficulty}` : "")), cost.reference && /* @__PURE__ */ import_react2.default.createElement("p", { className: "mr-package-copy" }, cost.reference), item.actualModel && /* @__PURE__ */ import_react2.default.createElement("p", { className: "mr-package-copy" }, "CLI \u56DE\u62A5\u6A21\u578B\uFF1A", item.actualModel), (item.billing || item.billingMode) && /* @__PURE__ */ import_react2.default.createElement("p", { className: "mr-package-copy" }, "\u8BA1\u8D39\uFF1A", BILLING_CHANNEL_LABEL[item.billing] ?? "\u2014", item.subscriptionRoute ? ` \xB7 \u5957\u9910\u8DEF\u7EBF ${item.subscriptionRoute.provider}/${item.subscriptionRoute.model}` : "", item.billingMode && item.billingMode !== "subscription-first" ? ` \xB7 ${BILLING_MODE_LABEL[item.billingMode] ?? item.billingMode}` : ""), billingSwitchText(item) && /* @__PURE__ */ import_react2.default.createElement("p", { className: "mr-package-copy mr-warn-text" }, "\u8BA1\u8D39\u5207\u6362\uFF1A", billingSwitchText(item)), item.fallback?.reason && item.fallback.reason !== billingSwitchText(item) && /* @__PURE__ */ import_react2.default.createElement("p", { className: "mr-package-copy" }, "\u56DE\u9000\u539F\u56E0\uFF1A", item.fallback.reason), item.fallback?.error && /* @__PURE__ */ import_react2.default.createElement("p", { className: "mr-package-copy mr-fallback-error" }, "CLI \u539F\u59CB\u9519\u8BEF\uFF1A", /* @__PURE__ */ import_react2.default.createElement("code", null, item.fallback.error)), !item.ok && item.error && /* @__PURE__ */ import_react2.default.createElement("p", { className: "mr-package-copy mr-fallback-error" }, item.error), !item.ok && item.diagnostic && /* @__PURE__ */ import_react2.default.createElement("details", { className: "mr-tool-log" }, /* @__PURE__ */ import_react2.default.createElement("summary", null, "CLI \u8BCA\u65AD", Number.isInteger(item.exitCode) ? `\uFF08\u9000\u51FA\u7801 ${item.exitCode}\uFF09` : ""), /* @__PURE__ */ import_react2.default.createElement("pre", null, item.diagnostic)), item.review && /* @__PURE__ */ import_react2.default.createElement("p", { className: "mr-package-copy" }, "\u5F3A\u6A21\u578B\u62BD\u67E5\uFF08", item.review.provider, "/", item.review.model, "\uFF09\uFF1A", item.review.score ? `${item.review.score}/5` : "\u672A\u8BC4\u5206", " ", item.review.summary), item.answer && /* @__PURE__ */ import_react2.default.createElement("details", { className: "mr-tool-log" }, /* @__PURE__ */ import_react2.default.createElement("summary", null, "\u67E5\u770B\u7ED3\u679C"), /* @__PURE__ */ import_react2.default.createElement("pre", null, item.answer, item.answerTruncated ? "\n\u2026\uFF08\u5DF2\u622A\u65AD\uFF09" : "")), /* @__PURE__ */ import_react2.default.createElement("div", { className: "mr-node-actions" }, item.ok && /* @__PURE__ */ import_react2.default.createElement(import_react2.default.Fragment, null, /* @__PURE__ */ import_react2.default.createElement("button", { className: "mr-button mr-button-secondary mr-mini", type: "button", title: item.rating === 1 ? "\u518D\u6B21\u70B9\u51FB\u64A4\u56DE\u6709\u7528\u8BC4\u4EF7" : "\u8BC4\u4EF7\u6B64\u7ED3\u679C\u6709\u7528", "aria-pressed": item.rating === 1, disabled: busy, onClick: () => onRate(...feedbackRatingArguments(run, item, "up")) }, "\u{1F44D} \u6709\u7528"), /* @__PURE__ */ import_react2.default.createElement("button", { className: "mr-button mr-button-secondary mr-mini", type: "button", title: item.rating === -1 ? "\u518D\u6B21\u70B9\u51FB\u64A4\u56DE\u4E0D\u597D\u8BC4\u4EF7" : "\u8BC4\u4EF7\u6B64\u7ED3\u679C\u4E0D\u597D", "aria-pressed": item.rating === -1, disabled: busy, onClick: () => onRate(...feedbackRatingArguments(run, item, "down")) }, "\u{1F44E} \u4E0D\u597D")), canRerun && /* @__PURE__ */ import_react2.default.createElement("button", { className: "mr-button mr-mini", type: "button", title: rerun.confirm || void 0, onClick: () => onRerun(run.id, item.id, null) }, run.kind === "tool" ? "\u91CD\u65B0\u6267\u884C\u6B64\u8C03\u7528" : rerun.writes ? "\u5728\u65B0\u5DE5\u4F5C\u533A\u7EED\u8DD1" : "\u91CD\u8DD1\u6B64\u6B65"), !rerun.supported && !item.ok && /* @__PURE__ */ import_react2.default.createElement("span", { className: "mr-caption" }, rerun.reason), rerun.supported && rerun.reassign && !(rerun.writes && item.ok) && allowReassign && others.length > 0 && !busy && /* @__PURE__ */ import_react2.default.createElement("span", { className: "mr-inline" }, /* @__PURE__ */ import_react2.default.createElement("select", { className: "mr-input mr-mini-select", "aria-label": "\u6539\u6D3E\u5230", value: target, onChange: (event) => setTarget(event.target.value) }, /* @__PURE__ */ import_react2.default.createElement("option", { value: "" }, "\u6539\u6D3E\u5230\u2026"), others.map((route) => /* @__PURE__ */ import_react2.default.createElement("option", { key: `${route.provider}/${route.model}`, value: `${route.provider}\0${route.model}` }, route.provider, "/", route.model))), /* @__PURE__ */ import_react2.default.createElement("button", { className: "mr-button mr-button-secondary mr-mini", type: "button", disabled: !target, onClick: () => {
|
|
3966
4008
|
const [provider, model] = target.split("\0");
|
|
3967
4009
|
onRerun(run.id, item.id, { provider, model });
|
|
3968
4010
|
} }, "\u6539\u6D3E\u5E76\u91CD\u8DD1"))));
|
|
3969
4011
|
}
|
|
3970
|
-
function PausedNode({ run, item, busy, onRerun }) {
|
|
4012
|
+
function PausedNode({ run, item, busy, onRerun, rerun }) {
|
|
3971
4013
|
const pause = item.pause ?? {};
|
|
3972
4014
|
return /* @__PURE__ */ import_react2.default.createElement(import_react2.default.Fragment, null, /* @__PURE__ */ import_react2.default.createElement("p", { className: "mr-package-route" }, item.provider, "/", item.model), /* @__PURE__ */ import_react2.default.createElement("div", { className: "mr-channel-line" }, /* @__PURE__ */ import_react2.default.createElement("span", { className: "mr-pill mr-pill-warn" }, "\u7B49\u5F85\u786E\u8BA4"), /* @__PURE__ */ import_react2.default.createElement("span", { className: "mr-caption" }, "\u8BA2\u9605\u8C03\u7528\u5931\u8D25\uFF0C\u672A\u81EA\u52A8\u6539\u7528 API Key")), /* @__PURE__ */ import_react2.default.createElement("p", { className: "mr-package-copy mr-warn-text" }, pause.reason ?? item.error), pause.detail && /* @__PURE__ */ import_react2.default.createElement("p", { className: "mr-package-copy mr-fallback-error" }, "\u771F\u5B9E\u9519\u8BEF\uFF1A", /* @__PURE__ */ import_react2.default.createElement("code", null, pause.detail)), pause.loginRequired && /* @__PURE__ */ import_react2.default.createElement("p", { className: "mr-package-copy" }, "\u770B\u8D77\u6765\u662F\u767B\u5F55\u95EE\u9898\uFF1A\u8BF7\u5148\u5728\u7EC8\u7AEF\u91CD\u65B0\u767B\u5F55\u8BE5 CLI\uFF0C\u518D\u70B9\u201C\u91CD\u8BD5\u8BA2\u9605\u201D\u3002"), /* @__PURE__ */ import_react2.default.createElement("div", { className: "mr-node-actions" }, SUBSCRIPTION_CHOICE_BUTTONS.map(([choice, label, secondary]) => /* @__PURE__ */ import_react2.default.createElement(
|
|
3973
4015
|
"button",
|
|
@@ -3975,20 +4017,22 @@ function PausedNode({ run, item, busy, onRerun }) {
|
|
|
3975
4017
|
key: choice,
|
|
3976
4018
|
className: `mr-button mr-mini${secondary ? " mr-button-secondary" : ""}`,
|
|
3977
4019
|
type: "button",
|
|
3978
|
-
disabled: busy,
|
|
4020
|
+
disabled: busy || !rerun.supported,
|
|
3979
4021
|
onClick: () => onRerun(run.id, item.id, null, choice)
|
|
3980
4022
|
},
|
|
3981
4023
|
label
|
|
3982
|
-
))));
|
|
4024
|
+
))), !rerun.supported && /* @__PURE__ */ import_react2.default.createElement("p", { className: "mr-caption" }, rerun.reason));
|
|
3983
4025
|
}
|
|
3984
4026
|
function RunHistoryCard({ ledger, routes, onRefresh, onRate, onRerun, busy, error }) {
|
|
3985
4027
|
const runs = ledger?.runs ?? [];
|
|
3986
4028
|
const [openId, setOpenId] = import_react2.default.useState(null);
|
|
3987
4029
|
const current = runs.find((run) => run.id === openId) ?? runs[0];
|
|
4030
|
+
const support = rerunSupport(current, ledger);
|
|
4031
|
+
const unresolved = ["running", "interrupted"].includes(current?.status) || (ledger?.reservations ?? []).some((item) => item.runId === current?.id && ["active", "interrupted"].includes(item.status));
|
|
3988
4032
|
const totals = runTotals(current);
|
|
3989
4033
|
const prior = priorAttemptTotals(current);
|
|
3990
4034
|
const unknownCalls = prior.unknownCalls + [...current?.packages ?? [], ...current?.reviews ?? []].filter((item) => item.ran && item.billing !== "subscription" && !Number.isFinite(item.costUsd)).length;
|
|
3991
|
-
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.kind === "team" && /* @__PURE__ */ import_react2.default.createElement("p", { className: "mr-caption" }, "\u6267\u884C\u73AF\u5883\uFF1A", current.executionEnvironment === "cli-native" ? "\u5382\u5546 CLI \u6B63\u5E38\u73AF\u5883 \xB7 \u5F53\u524D\u7528\u6237\u6743\u9650 \xB7 \u65E0 Harness \u8FDB\u7A0B\u6C99\u7BB1" : current.executionEnvironment === "harness" ? "Harness \u53D7\u9650\u73AF\u5883" : "\u5386\u53F2\u8BB0\u5F55\u672A\u8BB0\u5F55\u6267\u884C\u73AF\u5883"), 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 }) })))));
|
|
4035
|
+
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\u5DF2\u7ED3\u675F\u4EFB\u52A1\u7684\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.kind === "team" && /* @__PURE__ */ import_react2.default.createElement("p", { className: "mr-caption" }, "\u6267\u884C\u73AF\u5883\uFF1A", current.executionEnvironment === "cli-native" ? "\u5382\u5546 CLI \u6B63\u5E38\u73AF\u5883 \xB7 \u5F53\u524D\u7528\u6237\u6743\u9650 \xB7 \u65E0 Harness \u8FDB\u7A0B\u6C99\u7BB1" : current.executionEnvironment === "harness" ? "Harness \u53D7\u9650\u73AF\u5883" : "\u5386\u53F2\u8BB0\u5F55\u672A\u8BB0\u5F55\u6267\u884C\u73AF\u5883"), 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), !support.supported && unresolved && /* @__PURE__ */ import_react2.default.createElement("p", { className: "mr-caption mr-warn-text" }, support.reason), /* @__PURE__ */ import_react2.default.createElement(DagView, { packages: current.packages, renderNode: (item) => /* @__PURE__ */ import_react2.default.createElement(RunNode, { run: current, item, routes, ledger, allowReassign: ledger?.settings?.allowManualReassign !== false, busy, onRate, onRerun }) })))));
|
|
3992
4036
|
}
|
|
3993
4037
|
function BillingCard({ billing, error, onRefresh, refreshing }) {
|
|
3994
4038
|
const rows = billingRows(billing);
|
|
@@ -13886,7 +13930,7 @@ var xterm_default = `/**
|
|
|
13886
13930
|
`;
|
|
13887
13931
|
|
|
13888
13932
|
// .dsh-plugin/client/host-version.mjs
|
|
13889
|
-
var ROUTER_CLIENT_VERSION = true ? "0.
|
|
13933
|
+
var ROUTER_CLIENT_VERSION = true ? "0.24.0" : "";
|
|
13890
13934
|
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";
|
|
13891
13935
|
function isMissingRemoteMethod(message) {
|
|
13892
13936
|
const value = String(message ?? "");
|
|
@@ -15380,6 +15424,11 @@ function useWorkbenchData({ toolHealth, completeOnboarding, loadLedger, rateResu
|
|
|
15380
15424
|
if (mutationBusy.current) return;
|
|
15381
15425
|
const run = ledger.value?.runs?.find((item2) => item2.id === runId);
|
|
15382
15426
|
const item = run?.packages?.find((entry) => entry.id === packageId);
|
|
15427
|
+
const support = rerunSupport(run, ledger.value);
|
|
15428
|
+
if (!support.supported) {
|
|
15429
|
+
setLedger((previous) => ({ ...previous, error: support.reason }));
|
|
15430
|
+
return;
|
|
15431
|
+
}
|
|
15383
15432
|
const reasons = rerunConfirmations({ run, item, override, choice, ledger: ledger.value, health: health.report, toolFor: toolForProvider, headlessIds: HEADLESS_TOOLS });
|
|
15384
15433
|
if (reasons.length && !window.confirm(reasons.length === 1 ? `${reasons[0].text}
|
|
15385
15434
|
\u7EE7\u7EED\u5417\uFF1F` : `\u91CD\u8DD1\u524D\u9700\u8981\u786E\u8BA4\u4EE5\u4E0B ${reasons.length} \u9879\uFF1A
|
|
@@ -15595,7 +15644,7 @@ function RouterMainPage({ loadCatalog, settingsScope, listOfficialTools, loadOff
|
|
|
15595
15644
|
}
|
|
15596
15645
|
};
|
|
15597
15646
|
const summary = healthSummary(workbench.health.report?.tools);
|
|
15598
|
-
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" }, "\
|
|
15647
|
+
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\u5DF2\u53D1\u751F 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" }, "\u9884\u5360 ", money2(reservationSummary(workbench.ledger.value).today), " \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) => {
|
|
15599
15648
|
tabRefs.current[item.id] = element;
|
|
15600
15649
|
}, 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) => {
|
|
15601
15650
|
setTask(event.target.value);
|