@ljwei-stak/model-router-galgame 0.4.31 → 0.4.32

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.
@@ -37660,9 +37660,17 @@ function shouldRenderMarkdown(line) {
37660
37660
  function routeFromNode(node2) {
37661
37661
  if (node2 === null || typeof node2 !== "object") return null;
37662
37662
  const primary = node2.requestConfig;
37663
- if (primary?.provider && primary?.model) return { provider: primary.provider, model: primary.model };
37663
+ if (primary?.provider && primary?.model) return {
37664
+ provider: primary.provider,
37665
+ model: primary.model,
37666
+ ...primary.reasoningEffort === void 0 ? {} : { reasoningEffort: primary.reasoningEffort }
37667
+ };
37664
37668
  const provenance = node2.provenance;
37665
- if (provenance?.provider && provenance?.model) return { provider: provenance.provider, model: provenance.model };
37669
+ if (provenance?.provider && provenance?.model) return {
37670
+ provider: provenance.provider,
37671
+ model: provenance.model,
37672
+ ...provenance.reasoningEffort === void 0 ? {} : { reasoningEffort: provenance.reasoningEffort }
37673
+ };
37666
37674
  return null;
37667
37675
  }
37668
37676
  function contentToText(blocks) {
@@ -43829,9 +43837,19 @@ function liveBenchRow(snapshot, model) {
43829
43837
 
43830
43838
  // .dsh-plugin/shared/router.mjs
43831
43839
  var OBJECTIVE_WEIGHTS = Object.freeze({
43832
- simple: Object.freeze({ quality: 0.3, cost: 0.5, latency: 0.14, specialty: 0.04, risk: 0.02 }),
43833
- balanced: Object.freeze({ quality: 0.45, cost: 0.3, latency: 0.1, specialty: 0.1, risk: 0.05 }),
43834
- complex: Object.freeze({ quality: 0.55, cost: 0.16, latency: 0.06, specialty: 0.16, risk: 0.07 })
43840
+ simple: Object.freeze({ quality: 0.28, cost: 0.45, latency: 0.14, specialty: 0.04, reasoning: 0.07, risk: 0.02 }),
43841
+ balanced: Object.freeze({ quality: 0.4, cost: 0.26, latency: 0.1, specialty: 0.09, reasoning: 0.1, risk: 0.05 }),
43842
+ complex: Object.freeze({ quality: 0.48, cost: 0.14, latency: 0.06, specialty: 0.14, reasoning: 0.11, risk: 0.07 })
43843
+ });
43844
+ var REASONING_EFFORT_ORDER = Object.freeze(["off", "minimal", "low", "medium", "high", "xhigh", "max"]);
43845
+ var REASONING_EFFORT_MULTIPLIERS = Object.freeze({
43846
+ off: Object.freeze({ output: 0.78, latency: 0.75 }),
43847
+ minimal: Object.freeze({ output: 0.86, latency: 0.82 }),
43848
+ low: Object.freeze({ output: 0.93, latency: 0.9 }),
43849
+ medium: Object.freeze({ output: 1, latency: 1 }),
43850
+ high: Object.freeze({ output: 1.16, latency: 1.15 }),
43851
+ xhigh: Object.freeze({ output: 1.34, latency: 1.3 }),
43852
+ max: Object.freeze({ output: 1.58, latency: 1.5 })
43835
43853
  });
43836
43854
  var QUALITY_FLOORS = Object.freeze({ simple: 0.75, balanced: 0.78, complex: 0.82 });
43837
43855
  var MODEL_ROUTER_SETTINGS_NAMESPACE = "model-router";
@@ -44012,6 +44030,7 @@ function taskTokenBudget(text6, task, complexity, cacheReadRatio = 0, cacheWrite
44012
44030
  synthesis: { input: 1.65, output: 1.3 }
44013
44031
  };
44014
44032
  const multiplier = multipliers[task.purpose] ?? { input: 1, output: 1 };
44033
+ const effortMultiplier = reasoningEffortMultiplier(task.reasoningEffort);
44015
44034
  const totalInputTokens = Math.max(80, Math.round(inputTokens * multiplier.input));
44016
44035
  const ratios = normalizedCacheRatios(cacheReadRatio, cacheWriteRatio);
44017
44036
  const cacheReadTokens = Math.min(totalInputTokens, Math.max(0, Math.round(totalInputTokens * ratios.read)));
@@ -44020,7 +44039,7 @@ function taskTokenBudget(text6, task, complexity, cacheReadRatio = 0, cacheWrite
44020
44039
  inputTokens: totalInputTokens,
44021
44040
  cacheReadTokens,
44022
44041
  cacheWriteTokens,
44023
- outputTokens: Math.max(220, Math.round(900 * multiplier.output))
44042
+ outputTokens: Math.max(220, Math.round(900 * multiplier.output * effortMultiplier.output))
44024
44043
  };
44025
44044
  }
44026
44045
  function taskQualityFloor(band, task) {
@@ -44031,12 +44050,12 @@ function taskQualityFloor(band, task) {
44031
44050
  }
44032
44051
  function taskPackages(taskType, text6, band) {
44033
44052
  if (band !== "complex") {
44034
- const task = { id: "execution", name: "\u76F4\u63A5\u56DE\u7B54\u4E0E\u5FC5\u8981\u6821\u9A8C", type: taskType, purpose: "execution", criticality: 0.65, dependsOn: [] };
44053
+ const task = { id: "execution", name: "\u76F4\u63A5\u56DE\u7B54\u4E0E\u5FC5\u8981\u6821\u9A8C", type: taskType, purpose: "execution", criticality: 0.65, dependsOn: [], preferredReasoningEffort: band === "simple" ? "low" : "medium" };
44035
44054
  return [{ ...task, qualityFloor: taskQualityFloor(band, task) }];
44036
44055
  }
44037
44056
  const value = String(text6 ?? "");
44038
44057
  const packages = [
44039
- { id: "analysis", name: "\u95EE\u9898\u5EFA\u6A21\u4E0E\u7EA6\u675F\u63D0\u53D6", type: "reasoning", purpose: "analysis", criticality: 0.92, dependsOn: [] }
44058
+ { id: "analysis", name: "\u95EE\u9898\u5EFA\u6A21\u4E0E\u7EA6\u675F\u63D0\u53D6", type: "reasoning", purpose: "analysis", criticality: 0.92, dependsOn: [], preferredReasoningEffort: "high" }
44040
44059
  ];
44041
44060
  const domains = [...new Set([...detectTaskTypes(text6), taskType].filter((type) => type !== "general"))];
44042
44061
  for (const type of domains.length > 0 ? domains : [taskType]) {
@@ -44046,7 +44065,8 @@ function taskPackages(taskType, text6, band) {
44046
44065
  type,
44047
44066
  purpose: "execution",
44048
44067
  criticality: domains.length > 1 ? 0.8 : 0.78,
44049
- dependsOn: ["analysis"]
44068
+ dependsOn: ["analysis"],
44069
+ preferredReasoningEffort: "high"
44050
44070
  });
44051
44071
  }
44052
44072
  if (/(测试|验证|评估|对比|benchmark|test|verify|audit)/i.test(value)) {
@@ -44056,7 +44076,8 @@ function taskPackages(taskType, text6, band) {
44056
44076
  type: "reasoning",
44057
44077
  purpose: "verification",
44058
44078
  criticality: 0.88,
44059
- dependsOn: packages.filter((task) => task.purpose === "execution").map((task) => task.id)
44079
+ dependsOn: packages.filter((task) => task.purpose === "execution").map((task) => task.id),
44080
+ preferredReasoningEffort: "high"
44060
44081
  });
44061
44082
  }
44062
44083
  packages.push({
@@ -44065,11 +44086,12 @@ function taskPackages(taskType, text6, band) {
44065
44086
  type: "reasoning",
44066
44087
  purpose: "synthesis",
44067
44088
  criticality: 1,
44068
- dependsOn: packages.filter((task) => task.purpose !== "analysis").map((task) => task.id)
44089
+ dependsOn: packages.filter((task) => task.purpose !== "analysis").map((task) => task.id),
44090
+ preferredReasoningEffort: "xhigh"
44069
44091
  });
44070
44092
  return packages.map((task) => ({ ...task, qualityFloor: taskQualityFloor(band, task) }));
44071
44093
  }
44072
- var SYNTHESIS_WEIGHTS = Object.freeze({ quality: 0.7, cost: 0.1, latency: 0.04, specialty: 0.1, risk: 0.06 });
44094
+ var SYNTHESIS_WEIGHTS = Object.freeze({ quality: 0.58, cost: 0.08, latency: 0.04, specialty: 0.08, reasoning: 0.16, risk: 0.06 });
44073
44095
  var ROUTING_BEAM_WIDTH = 256;
44074
44096
  var ROUTING_CANDIDATE_LIMIT = 12;
44075
44097
  function weightsForTask(weights, task) {
@@ -44083,37 +44105,88 @@ function compareText(left, right) {
44083
44105
  function compareRowsStable(left, right) {
44084
44106
  return compareText(routeKey(left.provider, left.model), routeKey(right.provider, right.model));
44085
44107
  }
44108
+ function reasoningEffortRank(effort) {
44109
+ const normalized2 = String(effort ?? "").trim().toLowerCase().replace(/[\s_-]+/g, "");
44110
+ const aliases = { none: "off", disabled: "off", extra: "xhigh", extrahigh: "xhigh", maximum: "max" };
44111
+ const canonical = aliases[normalized2] ?? normalized2;
44112
+ const index2 = REASONING_EFFORT_ORDER.indexOf(canonical);
44113
+ return index2 < 0 ? REASONING_EFFORT_ORDER.indexOf("medium") : index2;
44114
+ }
44115
+ function reasoningEffortMultiplier(effort) {
44116
+ const normalized2 = String(effort ?? "").trim().toLowerCase().replace(/[\s_-]+/g, "");
44117
+ const aliases = { none: "off", disabled: "off", extra: "xhigh", extrahigh: "xhigh", maximum: "max" };
44118
+ return REASONING_EFFORT_MULTIPLIERS[aliases[normalized2] ?? normalized2] ?? REASONING_EFFORT_MULTIPLIERS.medium;
44119
+ }
44120
+ function selectReasoningEffort(efforts, preferred = "medium") {
44121
+ const exact = Array.isArray(efforts) ? [...new Set(efforts.map((effort) => String(effort?.id ?? effort ?? "")).filter(Boolean))] : [];
44122
+ if (exact.length === 0) return void 0;
44123
+ const preferredRank = reasoningEffortRank(preferred);
44124
+ return exact.slice().sort((left, right) => {
44125
+ const distance = Math.abs(reasoningEffortRank(left) - preferredRank) - Math.abs(reasoningEffortRank(right) - preferredRank);
44126
+ if (distance !== 0) return distance;
44127
+ return reasoningEffortRank(left) - reasoningEffortRank(right) || compareText(left, right);
44128
+ })[0];
44129
+ }
44130
+ function reasoningDecision(row, task) {
44131
+ const preferred = String(task.preferredReasoningEffort ?? "medium");
44132
+ const efforts = Array.isArray(row.reasoningEfforts) ? row.reasoningEfforts : [];
44133
+ if (efforts.length === 0) {
44134
+ const knownUnsupported = row.reasoningKnown === true;
44135
+ const preferredRank2 = reasoningEffortRank(preferred);
44136
+ return {
44137
+ reasoningEffort: void 0,
44138
+ reasoningFit: knownUnsupported ? clamp3(0.78 - preferredRank2 * 0.08) : 0.55,
44139
+ preferredReasoningEffort: preferred,
44140
+ multiplier: REASONING_EFFORT_MULTIPLIERS.medium
44141
+ };
44142
+ }
44143
+ const preferredRank = reasoningEffortRank(preferred);
44144
+ const chosen = selectReasoningEffort(efforts, preferred);
44145
+ const distance = Math.abs(reasoningEffortRank(chosen) - preferredRank);
44146
+ return {
44147
+ reasoningEffort: chosen,
44148
+ reasoningFit: clamp3(1 - distance / (REASONING_EFFORT_ORDER.length - 1)),
44149
+ preferredReasoningEffort: preferred,
44150
+ multiplier: reasoningEffortMultiplier(chosen)
44151
+ };
44152
+ }
44086
44153
  function candidateUtility(row, task, weights, maxCost, usedRoutes, cacheReadRatio = 0, cacheWriteRatio = 0) {
44087
44154
  const quality = qualityForTask(row, task.type);
44088
44155
  const floor = Number(task.qualityFloor ?? taskQualityFloor("complex", task));
44089
44156
  const qualityGap = Math.max(0, floor - quality);
44090
44157
  const duplicatePenalty = usedRoutes.has(routeKey(row.provider, row.model)) ? 0.08 : 0;
44091
44158
  const synthesisPreference = task.purpose === "synthesis" && /deepseek[- ]?v4[- ]?pro/i.test(row.model) ? 0.025 : 0;
44092
- const cost = costScore(row.pricing, maxCost, cacheReadRatio, cacheWriteRatio);
44093
- const score = weights.quality * quality + weights.cost * cost + weights.latency * (1 - clamp3(row.latency)) + weights.specialty * specialtyForTask(row, task.type) - weights.risk * row.risk - duplicatePenalty - qualityGap * (task.criticality ?? 0.75) + synthesisPreference;
44094
- return { score, floor, qualityGap };
44159
+ const reasoning = reasoningDecision(row, task);
44160
+ const cost = clamp3(costScore(row.pricing, maxCost, cacheReadRatio, cacheWriteRatio) / Math.sqrt(reasoning.multiplier.output));
44161
+ const score = weights.quality * quality + weights.cost * cost + weights.latency * (1 - clamp3(row.latency * reasoning.multiplier.latency)) + weights.specialty * specialtyForTask(row, task.type) + (weights.reasoning ?? 0) * reasoning.reasoningFit - weights.risk * row.risk - duplicatePenalty - qualityGap * (task.criticality ?? 0.75) + synthesisPreference;
44162
+ return { score, floor, qualityGap, ...reasoning };
44095
44163
  }
44096
44164
  function taskCost(row, task, text6, complexity, cacheReadRatio = 0, cacheWriteRatio = 0) {
44097
- const tokens = taskTokenBudget(text6, task, complexity, cacheReadRatio, cacheWriteRatio);
44165
+ const decision = row === null ? null : reasoningDecision(row, task);
44166
+ const tokens = taskTokenBudget(text6, { ...task, reasoningEffort: decision?.reasoningEffort }, complexity, cacheReadRatio, cacheWriteRatio);
44098
44167
  return row === null ? 0 : ((tokens.inputTokens - tokens.cacheReadTokens - tokens.cacheWriteTokens) * row.pricing.input + tokens.cacheReadTokens * row.pricing.cacheRead + tokens.cacheWriteTokens * row.pricing.cacheWrite + tokens.outputTokens * row.pricing.output) / 1e6;
44099
44168
  }
44100
44169
  function dominates(left, right, task, text6, complexity, cacheReadRatio, cacheWriteRatio) {
44170
+ const leftReasoning = reasoningDecision(left, task);
44171
+ const rightReasoning = reasoningDecision(right, task);
44101
44172
  const leftValues = {
44102
44173
  quality: qualityForTask(left, task.type),
44103
44174
  cost: taskCost(left, task, text6, complexity, cacheReadRatio, cacheWriteRatio),
44104
- latency: clamp3(left.latency),
44175
+ latency: clamp3(left.latency * leftReasoning.multiplier.latency),
44105
44176
  specialty: specialtyForTask(left, task.type),
44177
+ reasoning: leftReasoning.reasoningFit,
44106
44178
  risk: clamp3(left.risk)
44107
44179
  };
44108
44180
  const rightValues = {
44109
44181
  quality: qualityForTask(right, task.type),
44110
44182
  cost: taskCost(right, task, text6, complexity, cacheReadRatio, cacheWriteRatio),
44111
- latency: clamp3(right.latency),
44183
+ latency: clamp3(right.latency * rightReasoning.multiplier.latency),
44112
44184
  specialty: specialtyForTask(right, task.type),
44185
+ reasoning: rightReasoning.reasoningFit,
44113
44186
  risk: clamp3(right.risk)
44114
44187
  };
44115
- const noWorse = leftValues.quality >= rightValues.quality && leftValues.cost <= rightValues.cost && leftValues.latency <= rightValues.latency && leftValues.specialty >= rightValues.specialty && leftValues.risk <= rightValues.risk;
44116
- const strictlyBetter = leftValues.quality > rightValues.quality || leftValues.cost < rightValues.cost || leftValues.latency < rightValues.latency || leftValues.specialty > rightValues.specialty || leftValues.risk < rightValues.risk;
44188
+ const noWorse = leftValues.quality >= rightValues.quality && leftValues.cost <= rightValues.cost && leftValues.latency <= rightValues.latency && leftValues.specialty >= rightValues.specialty && leftValues.reasoning >= rightValues.reasoning && leftValues.risk <= rightValues.risk;
44189
+ const strictlyBetter = leftValues.quality > rightValues.quality || leftValues.cost < rightValues.cost || leftValues.latency < rightValues.latency || leftValues.specialty > rightValues.specialty || leftValues.reasoning > rightValues.reasoning || leftValues.risk < rightValues.risk;
44117
44190
  return noWorse && strictlyBetter;
44118
44191
  }
44119
44192
  function candidatePool(rows, task, weights, maxCost, text6, complexity, cacheReadRatio, cacheWriteRatio) {
@@ -44140,7 +44213,7 @@ function candidatePool(rows, task, weights, maxCost, text6, complexity, cacheRea
44140
44213
  };
44141
44214
  }
44142
44215
  function stateSignature(state) {
44143
- return state.assignments.map((assignment) => routeKey(assignment.row?.provider, assignment.row?.model)).join("|");
44216
+ return state.assignments.map((assignment) => `${routeKey(assignment.row?.provider, assignment.row?.model)}@${assignment.decision?.reasoningEffort ?? "provider-default"}`).join("|");
44144
44217
  }
44145
44218
  function compareUtilityStates(left, right) {
44146
44219
  return left.relaxedCount - right.relaxedCount || left.qualityShortfall - right.qualityShortfall || right.score - left.score || left.cost - right.cost || left.switches - right.switches || compareText(stateSignature(left), stateSignature(right));
@@ -44205,7 +44278,17 @@ function buildPlan({ text: text6 = "", available = [], mode = "collective", pric
44205
44278
  const complexity = assessComplexity(text6);
44206
44279
  const taskType = classifyTask(text6);
44207
44280
  const weights = OBJECTIVE_WEIGHTS[complexity.band];
44208
- const discovered = Array.isArray(available) ? available.map((entry) => ({ provider: String(entry.provider ?? ""), model: String(entry.model ?? "") })) : [];
44281
+ const discovered = Array.isArray(available) ? available.map((entry) => {
44282
+ const rawEfforts = Array.isArray(entry.reasoningEfforts) ? entry.reasoningEfforts : [];
44283
+ const reasoningEfforts = rawEfforts.map((effort) => String(effort?.id ?? effort ?? "")).filter(Boolean);
44284
+ return {
44285
+ provider: String(entry.provider ?? ""),
44286
+ model: String(entry.model ?? ""),
44287
+ reasoningEfforts: [...new Set(reasoningEfforts)],
44288
+ defaultReasoningEffort: entry.defaultReasoningEffort === void 0 ? void 0 : String(entry.defaultReasoningEffort),
44289
+ reasoningKnown: entry.reasoningKnown === true || Array.isArray(entry.reasoningEfforts)
44290
+ };
44291
+ }) : [];
44209
44292
  const rows = [];
44210
44293
  const normalizedPrices = normalizePricing(pricing);
44211
44294
  const maxCost = Math.max(1, ...MODEL_CATALOG.map((model) => {
@@ -44243,6 +44326,9 @@ function buildPlan({ text: text6 = "", available = [], mode = "collective", pric
44243
44326
  latency: metadata.latency,
44244
44327
  risk: metadata.risk,
44245
44328
  specialty,
44329
+ reasoningEfforts: route.reasoningEfforts,
44330
+ defaultReasoningEffort: route.defaultReasoningEffort,
44331
+ reasoningKnown: route.reasoningKnown,
44246
44332
  pricing: pricingRow,
44247
44333
  score: 0,
44248
44334
  estimatedCost: estimateCost(metadata, text6, 900, normalizedPrices, cacheReadRatio, cacheWriteRatio)
@@ -44292,27 +44378,36 @@ function buildPlan({ text: text6 = "", available = [], mode = "collective", pric
44292
44378
  row.score = candidateUtility(row, taskNodes[0] ?? { type: taskType, qualityFloor: QUALITY_FLOORS[complexity.band] }, weights, maxCost, /* @__PURE__ */ new Set(), cacheReadRatio, cacheWriteRatio).score;
44293
44379
  }
44294
44380
  rows.sort((left, right) => right.score - left.score || compareRowsStable(left, right));
44295
- const selected = assignments[0]?.row ?? rows[0] ?? null;
44296
- const synthesizer = assignments.at(-1)?.row ?? rows.find((row) => /deepseek/i.test(row.model)) ?? rows[0];
44297
- const subtasks = assignments.map(({ task, row }) => ({
44381
+ const selectedAssignment = assignments[0];
44382
+ const selected = selectedAssignment?.row ?? rows[0] ?? null;
44383
+ const synthesizerAssignment = assignments.at(-1);
44384
+ const synthesizer = synthesizerAssignment?.row ?? rows.find((row) => /deepseek/i.test(row.model)) ?? rows[0];
44385
+ const subtasks = assignments.map(({ task, row, decision }) => ({
44298
44386
  id: task.id,
44299
44387
  name: task.name,
44300
44388
  type: task.type,
44301
44389
  recommended: row?.model ?? "\u5F85\u53D1\u73B0\u6A21\u578B",
44302
44390
  recommendedProvider: row?.provider ?? "",
44391
+ recommendedReasoningEffort: decision?.reasoningEffort,
44392
+ preferredReasoningEffort: decision?.preferredReasoningEffort ?? task.preferredReasoningEffort,
44393
+ reasoningFit: Number(Number(decision?.reasoningFit ?? 0).toFixed(3)),
44303
44394
  purpose: task.purpose,
44304
44395
  criticality: task.criticality,
44305
44396
  qualityFloor: Number(task.qualityFloor.toFixed(3)),
44306
44397
  dependsOn: [...task.dependsOn ?? []]
44307
44398
  }));
44308
- const costBreakdown = assignments.map(({ task, row, estimatedCost, handoffPenalty }, index2) => {
44309
- const tokens = taskTokenBudget(text6, task, complexity.band, cacheReadRatio, cacheWriteRatio);
44399
+ const costBreakdown = assignments.map(({ task, row, decision, estimatedCost, handoffPenalty }, index2) => {
44400
+ const tokens = taskTokenBudget(text6, { ...task, reasoningEffort: decision?.reasoningEffort }, complexity.band, cacheReadRatio, cacheWriteRatio);
44310
44401
  const taskEstimate = estimatedCost ?? taskCost(row, task, text6, complexity.band, cacheReadRatio, cacheWriteRatio);
44311
44402
  return {
44312
44403
  stage: index2 + 1,
44313
44404
  purpose: task.purpose,
44314
44405
  model: row?.model ?? "\u5F85\u53D1\u73B0\u6A21\u578B",
44315
44406
  provider: row?.provider ?? "",
44407
+ reasoningEffort: decision?.reasoningEffort,
44408
+ preferredReasoningEffort: decision?.preferredReasoningEffort,
44409
+ reasoningFit: Number(Number(decision?.reasoningFit ?? 0).toFixed(3)),
44410
+ reasoningOutputMultiplier: Number(Number(decision?.multiplier?.output ?? 1).toFixed(2)),
44316
44411
  inputTokens: tokens.inputTokens,
44317
44412
  cacheReadTokens: tokens.cacheReadTokens,
44318
44413
  cacheWriteTokens: tokens.cacheWriteTokens,
@@ -44325,24 +44420,26 @@ function buildPlan({ text: text6 = "", available = [], mode = "collective", pric
44325
44420
  const totalEstimate = costBreakdown.reduce((sum, row) => sum + row.estimatedCost, 0);
44326
44421
  const baselineCost = assignments.reduce((sum, { task }) => {
44327
44422
  const strongest = rows.reduce((best, row) => qualityForTask(row, task.type) > (best === null ? -1 : qualityForTask(best, task.type)) ? row : best, null);
44328
- const tokens = taskTokenBudget(text6, task, complexity.band, cacheReadRatio, cacheWriteRatio);
44329
- return sum + (strongest === null ? 0 : ((tokens.inputTokens - tokens.cacheReadTokens - tokens.cacheWriteTokens) * strongest.pricing.input + tokens.cacheReadTokens * strongest.pricing.cacheRead + tokens.cacheWriteTokens * strongest.pricing.cacheWrite + tokens.outputTokens * strongest.pricing.output) / 1e6);
44423
+ return sum + taskCost(strongest, task, text6, complexity.band, cacheReadRatio, cacheWriteRatio);
44330
44424
  }, 0);
44331
44425
  const budgetExceeded = Number(budgetUsd) > 0 && totalEstimate > Number(budgetUsd);
44332
44426
  const savings = baselineCost <= 0 ? 0 : clamp3((baselineCost - totalEstimate) / baselineCost);
44333
44427
  const paretoPruned = (optimized?.candidatePools ?? []).reduce((sum, pool) => sum + pool.pruned, 0);
44334
44428
  const minimumFeasibleCost = optimized?.minimumFeasibleCost ?? minimumCostPlan?.cost ?? 0;
44335
- const reason = selected === null ? "\u5C1A\u672A\u53D1\u73B0\u53EF\u7528\u6A21\u578B\uFF0C\u4FDD\u7559 Harness \u539F\u59CB\u6A21\u578B\u9009\u62E9\u3002" : `${complexity.band === "simple" ? "\u4F4E\u590D\u6742\u5EA6\u4F18\u5148\u6210\u672C\u4E0E\u54CD\u5E94\u901F\u5EA6" : complexity.band === "balanced" ? "\u5728\u8D28\u91CF\u3001\u6210\u672C\u3001\u5EF6\u8FDF\u4E0E\u98CE\u9669\u4E4B\u95F4\u5E73\u8861" : "\u9AD8\u590D\u6742\u5EA6\u6267\u884C\u4F9D\u8D56\u611F\u77E5\u7684\u5168\u5C40\u7EA6\u675F\u5206\u914D"}\uFF1B\u4EFB\u52A1\u7C7B\u578B\u4E3A ${taskType}\uFF0C\u5DF2\u5BF9 ${String(subtasks.length)} \u4E2A\u5DE5\u4F5C\u5305\u8FDB\u884C Pareto \u526A\u679D\u548C\u6709\u754C\u7EC4\u5408\u641C\u7D22\u3002`;
44429
+ const reason = selected === null ? "\u5C1A\u672A\u53D1\u73B0\u53EF\u7528\u6A21\u578B\uFF0C\u4FDD\u7559 Harness \u539F\u59CB\u6A21\u578B\u9009\u62E9\u3002" : `${complexity.band === "simple" ? "\u4F4E\u590D\u6742\u5EA6\u4F18\u5148\u6210\u672C\u3001\u54CD\u5E94\u901F\u5EA6\u4E0E\u8F83\u4F4E\u63A8\u7406\u5F00\u9500" : complexity.band === "balanced" ? "\u5728\u8D28\u91CF\u3001\u6210\u672C\u3001\u63A8\u7406\u7B49\u7EA7\u3001\u5EF6\u8FDF\u4E0E\u98CE\u9669\u4E4B\u95F4\u5E73\u8861" : "\u9AD8\u590D\u6742\u5EA6\u6267\u884C\u5305\u542B\u63A8\u7406\u7B49\u7EA7\u7684\u4F9D\u8D56\u611F\u77E5\u5168\u5C40\u7EA6\u675F\u5206\u914D"}\uFF1B\u4EFB\u52A1\u7C7B\u578B\u4E3A ${taskType}\uFF0C\u5DF2\u5BF9 ${String(subtasks.length)} \u4E2A\u5DE5\u4F5C\u5305\u8FDB\u884C Pareto \u526A\u679D\u548C\u6709\u754C\u7EC4\u5408\u641C\u7D22\u3002`;
44336
44430
  return {
44337
44431
  mode,
44338
44432
  complexity: { value: Number(complexity.value.toFixed(3)), band: complexity.band },
44339
44433
  taskType,
44340
44434
  taskTypes: [...new Set(taskNodes.map((task) => task.type).filter((type) => type !== "reasoning"))],
44341
44435
  objectiveWeights: weights,
44342
- candidates: rows.slice(0, 8).map((row) => ({ provider: row.provider, model: row.model, score: Number(row.score.toFixed(3)), quality: Number(row.quality.toFixed(3)), specialty: Number(row.specialty.toFixed(3)), estimatedCost: Number(row.estimatedCost.toFixed(6)), inputPrice: row.pricing.input, outputPrice: row.pricing.output })),
44343
- selected: selected === null ? null : { provider: selected.provider, model: selected.model, estimatedCost: Number(selected.estimatedCost.toFixed(6)) },
44436
+ candidates: rows.slice(0, 8).map((row) => {
44437
+ const decision = candidateUtility(row, taskNodes[0] ?? { type: taskType, qualityFloor: QUALITY_FLOORS[complexity.band], preferredReasoningEffort: complexity.band === "simple" ? "low" : "medium" }, weights, maxCost, /* @__PURE__ */ new Set(), cacheReadRatio, cacheWriteRatio);
44438
+ return { provider: row.provider, model: row.model, score: Number(row.score.toFixed(3)), quality: Number(row.quality.toFixed(3)), specialty: Number(row.specialty.toFixed(3)), reasoningEffort: decision.reasoningEffort, preferredReasoningEffort: decision.preferredReasoningEffort, reasoningFit: Number(decision.reasoningFit.toFixed(3)), reasoningKnown: row.reasoningKnown, reasoningEfforts: row.reasoningEfforts, estimatedCost: Number(row.estimatedCost.toFixed(6)), inputPrice: row.pricing.input, outputPrice: row.pricing.output };
44439
+ }),
44440
+ selected: selected === null ? null : { provider: selected.provider, model: selected.model, reasoningEffort: selectedAssignment?.decision?.reasoningEffort, estimatedCost: Number(selected.estimatedCost.toFixed(6)) },
44344
44441
  subtasks,
44345
- synthesizer: synthesizer === void 0 ? null : { provider: synthesizer.provider, model: synthesizer.model },
44442
+ synthesizer: synthesizer === void 0 ? null : { provider: synthesizer.provider, model: synthesizer.model, reasoningEffort: synthesizerAssignment?.decision?.reasoningEffort },
44346
44443
  estimatedCost: Number(totalEstimate.toFixed(6)),
44347
44444
  costBreakdown,
44348
44445
  optimization: {
@@ -44428,29 +44525,56 @@ function ModelPicker({ mode, snapshot, actions, onMode, selectedRoute }) {
44428
44525
  const groups = Array.isArray(snapshot?.groups) ? snapshot.groups : [];
44429
44526
  const options = (0, import_react14.useMemo)(() => {
44430
44527
  const rows = [];
44431
- for (const group of groups) for (const model of group.models ?? []) rows.push({ provider: group.id, model: model.id, label: model.name || model.id });
44528
+ for (const group of groups) for (const model of group.models ?? []) {
44529
+ const effortRows = Array.isArray(model.reasoning?.efforts) ? model.reasoning.efforts : [];
44530
+ rows.push({
44531
+ provider: group.id,
44532
+ model: model.id,
44533
+ label: model.name || model.id,
44534
+ reasoningEfforts: effortRows.map((effort) => effort.id),
44535
+ reasoningLabels: Object.fromEntries(effortRows.map((effort) => [effort.id, effort.name || effort.id])),
44536
+ defaultReasoningEffort: model.reasoning?.defaultEffort
44537
+ });
44538
+ }
44432
44539
  if (rows.length > 0) return rows;
44433
- return (snapshot?.available ?? []).map((route) => ({ provider: route.provider, model: route.model, label: route.model }));
44540
+ return (snapshot?.available ?? []).map((route) => ({ ...route, label: route.model, reasoningLabels: {} }));
44434
44541
  }, [groups, snapshot?.available]);
44435
44542
  (0, import_react14.useEffect)(() => {
44436
44543
  if (mode === "single" && groups.length === 0 && snapshot?.status === "idle") actions?.load?.();
44437
44544
  }, [actions, groups.length, mode, snapshot?.status]);
44438
44545
  const current = snapshot?.current ?? selectedRoute ?? null;
44439
44546
  const value = current ? `${current.provider}\0${current.model}` : "";
44440
- return /* @__PURE__ */ import_react14.default.createElement("div", { className: "gv-model-picker" }, /* @__PURE__ */ import_react14.default.createElement("div", { className: "gv-picker-label" }, "\u4F1A\u8BDD\u65B9\u5F0F"), /* @__PURE__ */ import_react14.default.createElement("div", { className: "gv-picker-tabs", role: "tablist", "aria-label": "AI \u4F1A\u8BDD\u65B9\u5F0F" }, /* @__PURE__ */ import_react14.default.createElement("button", { type: "button", className: mode === "collective" ? "is-on" : "", onClick: () => onMode("collective") }, "\u96C6\u4F53\u5408\u4F5C"), /* @__PURE__ */ import_react14.default.createElement("button", { type: "button", className: mode === "single" ? "is-on" : "", onClick: () => onMode("single") }, "\u5355\u72EC\u4F1A\u8BDD")), mode === "single" ? /* @__PURE__ */ import_react14.default.createElement("label", { className: "gv-picker-select" }, /* @__PURE__ */ import_react14.default.createElement("span", null, "\u5F53\u524D\u5973\u4EC6"), /* @__PURE__ */ import_react14.default.createElement(
44547
+ const currentOption = options.find((option3) => option3.provider === current?.provider && option3.model === current?.model);
44548
+ const currentEfforts = currentOption?.reasoningEfforts ?? [];
44549
+ const currentEffort = current?.reasoningEffort ?? currentOption?.defaultReasoningEffort ?? selectReasoningEffort(currentEfforts, "medium") ?? "";
44550
+ return /* @__PURE__ */ import_react14.default.createElement("div", { className: "gv-model-picker" }, /* @__PURE__ */ import_react14.default.createElement("div", { className: "gv-picker-label" }, "\u4F1A\u8BDD\u65B9\u5F0F"), /* @__PURE__ */ import_react14.default.createElement("div", { className: "gv-picker-tabs", role: "tablist", "aria-label": "AI \u4F1A\u8BDD\u65B9\u5F0F" }, /* @__PURE__ */ import_react14.default.createElement("button", { type: "button", className: mode === "collective" ? "is-on" : "", onClick: () => onMode("collective") }, "\u96C6\u4F53\u5408\u4F5C"), /* @__PURE__ */ import_react14.default.createElement("button", { type: "button", className: mode === "single" ? "is-on" : "", onClick: () => onMode("single") }, "\u5355\u72EC\u4F1A\u8BDD")), mode === "single" ? /* @__PURE__ */ import_react14.default.createElement(import_react14.default.Fragment, null, /* @__PURE__ */ import_react14.default.createElement("label", { className: "gv-picker-select" }, /* @__PURE__ */ import_react14.default.createElement("span", null, "\u5F53\u524D\u5973\u4EC6"), /* @__PURE__ */ import_react14.default.createElement(
44441
44551
  "select",
44442
44552
  {
44443
44553
  value,
44444
44554
  onChange: (event) => {
44445
44555
  const [provider, model] = String(event.target.value).split("\0");
44446
- if (provider && model) void actions?.select?.({ provider, model });
44556
+ const option3 = options.find((row) => row.provider === provider && row.model === model);
44557
+ const reasoningEffort = option3?.defaultReasoningEffort ?? selectReasoningEffort(option3?.reasoningEfforts, current?.reasoningEffort ?? "medium");
44558
+ if (provider && model) void actions?.select?.({ provider, model, ...reasoningEffort === void 0 ? {} : { reasoningEffort } });
44447
44559
  },
44448
44560
  onFocus: () => actions?.load?.(),
44449
44561
  "aria-label": "\u9009\u62E9\u5355\u72EC\u4F1A\u8BDD\u6A21\u578B"
44450
44562
  },
44451
44563
  /* @__PURE__ */ import_react14.default.createElement("option", { value: "" }, snapshot?.status === "loading" ? "\u6B63\u5728\u8BFB\u53D6\u6A21\u578B\u2026" : "\u9009\u62E9\u6A21\u578B"),
44452
44564
  options.map((option3) => /* @__PURE__ */ import_react14.default.createElement("option", { key: `${option3.provider}\0${option3.model}`, value: `${option3.provider}\0${option3.model}` }, option3.label))
44453
- )) : /* @__PURE__ */ import_react14.default.createElement("div", { className: "gv-picker-note" }, "\u7531 Harness \u6839\u636E\u590D\u6742\u5EA6\u3001\u4E13\u957F\u3001LiveBench \u8D28\u91CF\u3001\u6210\u672C\u3001\u5EF6\u8FDF\u548C\u98CE\u9669\u81EA\u52A8\u5206\u914D"), snapshot?.error && /* @__PURE__ */ import_react14.default.createElement("div", { className: "gv-picker-error" }, "\u6A21\u578B\u76EE\u5F55\uFF1A", snapshot.error));
44565
+ )), currentEfforts.length > 0 && /* @__PURE__ */ import_react14.default.createElement("label", { className: "gv-picker-select" }, /* @__PURE__ */ import_react14.default.createElement("span", null, "\u63A8\u7406\u7B49\u7EA7"), /* @__PURE__ */ import_react14.default.createElement(
44566
+ "select",
44567
+ {
44568
+ value: currentEffort,
44569
+ onChange: (event) => {
44570
+ if (current?.provider && current?.model && event.target.value) {
44571
+ void actions?.select?.({ provider: current.provider, model: current.model, reasoningEffort: event.target.value });
44572
+ }
44573
+ },
44574
+ "aria-label": "\u9009\u62E9\u5355\u72EC\u4F1A\u8BDD\u63A8\u7406\u7B49\u7EA7"
44575
+ },
44576
+ currentEfforts.map((effort) => /* @__PURE__ */ import_react14.default.createElement("option", { key: effort, value: effort }, currentOption?.reasoningLabels?.[effort] ?? effort))
44577
+ ))) : /* @__PURE__ */ import_react14.default.createElement("div", { className: "gv-picker-note" }, "\u7531 Harness \u6839\u636E\u590D\u6742\u5EA6\u3001\u63A8\u7406\u7B49\u7EA7\u3001\u4E13\u957F\u3001LiveBench \u8D28\u91CF\u3001\u6210\u672C\u3001\u5EF6\u8FDF\u548C\u98CE\u9669\u81EA\u52A8\u5206\u914D"), snapshot?.error && /* @__PURE__ */ import_react14.default.createElement("div", { className: "gv-picker-error" }, "\u6A21\u578B\u76EE\u5F55\uFF1A", snapshot.error));
44454
44578
  }
44455
44579
  function ArchiveRail({ archives, currentId, onOpen, onClose }) {
44456
44580
  return /* @__PURE__ */ import_react14.default.createElement("aside", { className: "gv-archive-rail", "aria-label": "GAL \u5B58\u6863" }, /* @__PURE__ */ import_react14.default.createElement("div", { className: "gv-archive-head" }, /* @__PURE__ */ import_react14.default.createElement("span", null, "\u5B58\u6863"), /* @__PURE__ */ import_react14.default.createElement("button", { type: "button", className: "gv-icon-btn", onClick: onClose, "aria-label": "\u5173\u95ED\u5B58\u6863" }, "\xD7")), /* @__PURE__ */ import_react14.default.createElement("div", { className: "gv-archive-hint" }, "\u6BCF\u4E2A Harness \u65B0\u5BF9\u8BDD\u81EA\u52A8\u6210\u4E3A\u4E00\u4E2A\u5B58\u6863\uFF1B\u7EE7\u7EED\u63D0\u95EE\u4F1A\u7559\u5728\u540C\u4E00\u6761\u8BB0\u5F55\u3002"), /* @__PURE__ */ import_react14.default.createElement("div", { className: "gv-archive-list" }, archives.length === 0 && /* @__PURE__ */ import_react14.default.createElement("div", { className: "gv-archive-empty" }, "\u5C1A\u65E0\u5386\u53F2\u5B58\u6863"), archives.map((archive) => /* @__PURE__ */ import_react14.default.createElement("button", { type: "button", key: archive.sessionId, className: "gv-archive-item" + (archive.sessionId === currentId ? " is-current" : ""), onClick: () => onOpen?.(archive.sessionId) }, /* @__PURE__ */ import_react14.default.createElement("span", { className: "gv-archive-item-title" }, archive.title), /* @__PURE__ */ import_react14.default.createElement("span", { className: "gv-archive-item-meta" }, archive.mode === "single" ? "\u5355\u72EC" : "\u96C6\u4F53", " \xB7 ", archive.model || "\u5F85\u5206\u914D", " \xB7 ", formatTime(archive.updatedAt))))));
@@ -44468,15 +44592,15 @@ function CollaborationBoard({ plan, activeRoute, nodes: nodes3, running }) {
44468
44592
  const completedCount = assignments.filter((task) => task.completed).length;
44469
44593
  const activeTask = assignments.find((task) => task.active);
44470
44594
  const progress = activeTask !== void 0 ? `\u5DE5\u4F5C\u4E2D\uFF1A${activeTask.name}` : `${completedCount}/${assignments.length} \u5DF2\u5B8C\u6210`;
44471
- return /* @__PURE__ */ import_react14.default.createElement("details", { className: "gv-collab-board", "aria-label": "\u534F\u4F5C\u4EFB\u52A1\u5206\u914D" }, /* @__PURE__ */ import_react14.default.createElement("summary", { className: "gv-board-summary" }, /* @__PURE__ */ import_react14.default.createElement("span", { className: "gv-board-title" }, "\u534F\u4F5C\u6D41\u7A0B"), /* @__PURE__ */ import_react14.default.createElement("span", { className: "gv-board-progress" }, progress), /* @__PURE__ */ import_react14.default.createElement("span", { className: "gv-board-synth" }, "\u6C47\u62A5\uFF1A", plan.synthesizer?.model || "DeepSeek V4 Pro\uFF08\u81EA\u52A8\u56DE\u9000\uFF09")), /* @__PURE__ */ import_react14.default.createElement("div", { className: "gv-collab-body" }, /* @__PURE__ */ import_react14.default.createElement("div", { className: "gv-task-list" }, assignments.map((task, index2) => {
44595
+ return /* @__PURE__ */ import_react14.default.createElement("details", { className: "gv-collab-board", "aria-label": "\u534F\u4F5C\u4EFB\u52A1\u5206\u914D" }, /* @__PURE__ */ import_react14.default.createElement("summary", { className: "gv-board-summary" }, /* @__PURE__ */ import_react14.default.createElement("span", { className: "gv-board-title" }, "\u534F\u4F5C\u6D41\u7A0B"), /* @__PURE__ */ import_react14.default.createElement("span", { className: "gv-board-progress" }, progress), /* @__PURE__ */ import_react14.default.createElement("span", { className: "gv-board-synth" }, "\u6C47\u62A5\uFF1A", plan.synthesizer?.model || "DeepSeek V4 Pro\uFF08\u81EA\u52A8\u56DE\u9000\uFF09", plan.synthesizer?.reasoningEffort ? ` \xB7 ${plan.synthesizer.reasoningEffort}` : "")), /* @__PURE__ */ import_react14.default.createElement("div", { className: "gv-collab-body" }, /* @__PURE__ */ import_react14.default.createElement("div", { className: "gv-task-list" }, assignments.map((task, index2) => {
44472
44596
  const character = characterForModel(task.recommended, task.recommendedProvider);
44473
- return /* @__PURE__ */ import_react14.default.createElement("div", { className: "gv-task-row" + (task.active ? " is-active" : "") + (task.completed ? " is-complete" : ""), key: `${task.name}-${index2}` }, /* @__PURE__ */ import_react14.default.createElement(MaidAvatar, { model: task.recommended, active: task.active }), /* @__PURE__ */ import_react14.default.createElement("div", { className: "gv-task-main" }, /* @__PURE__ */ import_react14.default.createElement("div", { className: "gv-task-title" }, /* @__PURE__ */ import_react14.default.createElement("span", null, index2 + 1, ". ", task.name), /* @__PURE__ */ import_react14.default.createElement("b", null, task.completed ? "\u5DF2\u5B8C\u6210" : task.active ? "\u5DE5\u4F5C\u4E2D" : "\u6392\u961F")), /* @__PURE__ */ import_react14.default.createElement("div", { className: "gv-task-meta" }, character.label, " \xB7 ", task.recommendedProvider || "\u81EA\u52A8\u8DEF\u7531", "/", task.recommended, " \xB7 ", task.type)));
44474
- })), activeRoute && /* @__PURE__ */ import_react14.default.createElement("div", { className: "gv-board-foot" }, "\u5F53\u524D\u8BF7\u6C42\uFF1A", activeRoute.provider, "/", activeRoute.model)));
44597
+ return /* @__PURE__ */ import_react14.default.createElement("div", { className: "gv-task-row" + (task.active ? " is-active" : "") + (task.completed ? " is-complete" : ""), key: `${task.name}-${index2}` }, /* @__PURE__ */ import_react14.default.createElement(MaidAvatar, { model: task.recommended, active: task.active }), /* @__PURE__ */ import_react14.default.createElement("div", { className: "gv-task-main" }, /* @__PURE__ */ import_react14.default.createElement("div", { className: "gv-task-title" }, /* @__PURE__ */ import_react14.default.createElement("span", null, index2 + 1, ". ", task.name), /* @__PURE__ */ import_react14.default.createElement("b", null, task.completed ? "\u5DF2\u5B8C\u6210" : task.active ? "\u5DE5\u4F5C\u4E2D" : "\u6392\u961F")), /* @__PURE__ */ import_react14.default.createElement("div", { className: "gv-task-meta" }, character.label, " \xB7 ", task.recommendedProvider || "\u81EA\u52A8\u8DEF\u7531", "/", task.recommended, " \xB7 \u63A8\u7406 ", task.recommendedReasoningEffort || "\u63D0\u4F9B\u65B9\u9ED8\u8BA4", " \xB7 ", task.type)));
44598
+ })), activeRoute && /* @__PURE__ */ import_react14.default.createElement("div", { className: "gv-board-foot" }, "\u5F53\u524D\u8BF7\u6C42\uFF1A", activeRoute.provider, "/", activeRoute.model, " \xB7 \u63A8\u7406 ", activeRoute.reasoningEffort || "\u63D0\u4F9B\u65B9\u9ED8\u8BA4")));
44475
44599
  }
44476
44600
  function AnalysisSummary({ plan }) {
44477
44601
  if (!plan) return null;
44478
44602
  const weights = plan.objectiveWeights ?? {};
44479
- return /* @__PURE__ */ import_react14.default.createElement("details", { className: "gv-analysis-summary" }, /* @__PURE__ */ import_react14.default.createElement("summary", null, /* @__PURE__ */ import_react14.default.createElement("span", { className: "gv-analysis-summary-title" }, /* @__PURE__ */ import_react14.default.createElement(MaidAvatar, { model: "DeepSeek Harness", size: "tiny" }), "\u67E5\u770B\u8DEF\u7531\u5206\u6790\u6458\u8981")), /* @__PURE__ */ import_react14.default.createElement("div", { className: "gv-analysis-body" }, /* @__PURE__ */ import_react14.default.createElement("p", null, plan.reason), /* @__PURE__ */ import_react14.default.createElement("div", { className: "gv-analysis-metrics" }, /* @__PURE__ */ import_react14.default.createElement("span", null, "\u590D\u6742\u5EA6 ", /* @__PURE__ */ import_react14.default.createElement("b", null, Math.round((plan.complexity?.value ?? 0) * 100), "%")), /* @__PURE__ */ import_react14.default.createElement("span", null, "\u7C7B\u578B ", /* @__PURE__ */ import_react14.default.createElement("b", null, plan.taskType)), Array.isArray(plan.taskTypes) && plan.taskTypes.length > 1 && /* @__PURE__ */ import_react14.default.createElement("span", null, "\u4E1A\u52A1\u65B9\u5411 ", /* @__PURE__ */ import_react14.default.createElement("b", null, plan.taskTypes.join("\u3001"))), /* @__PURE__ */ import_react14.default.createElement("span", null, "\u8D28\u91CF ", /* @__PURE__ */ import_react14.default.createElement("b", null, Math.round((weights.quality ?? 0) * 100), "%")), /* @__PURE__ */ import_react14.default.createElement("span", null, "\u6210\u672C ", /* @__PURE__ */ import_react14.default.createElement("b", null, Math.round((weights.cost ?? 0) * 100), "%")), /* @__PURE__ */ import_react14.default.createElement("span", null, "\u5EF6\u8FDF ", /* @__PURE__ */ import_react14.default.createElement("b", null, Math.round((weights.latency ?? 0) * 100), "%")), /* @__PURE__ */ import_react14.default.createElement("span", null, "\u4E13\u957F ", /* @__PURE__ */ import_react14.default.createElement("b", null, Math.round((weights.specialty ?? 0) * 100), "%")), /* @__PURE__ */ import_react14.default.createElement("span", null, "\u98CE\u9669 ", /* @__PURE__ */ import_react14.default.createElement("b", null, Math.round((weights.risk ?? 0) * 100), "%")), /* @__PURE__ */ import_react14.default.createElement("span", null, "\u8D28\u91CF\u4E0B\u9650 ", /* @__PURE__ */ import_react14.default.createElement("b", null, Math.round((plan.optimization?.qualityFloor ?? 0) * 100), "%"))), /* @__PURE__ */ import_react14.default.createElement("div", { className: "gv-analysis-cost" }, "\u9884\u8BA1\u603B\u8D39\u7528 ", /* @__PURE__ */ import_react14.default.createElement("b", null, "$", Number(plan.estimatedCost ?? 0).toFixed(6))), /* @__PURE__ */ import_react14.default.createElement("div", { className: "gv-analysis-cost" }, "\u5168\u9AD8\u8D28\u91CF\u57FA\u7EBF ", /* @__PURE__ */ import_react14.default.createElement("b", null, "$", Number(plan.optimization?.baselineAllStrongCost ?? 0).toFixed(6)), " \xB7 \u9884\u8BA1\u8282\u7701 ", /* @__PURE__ */ import_react14.default.createElement("b", null, Math.round(Number(plan.optimization?.estimatedSavings ?? 0) * 100), "%")), /* @__PURE__ */ import_react14.default.createElement("div", { className: "gv-analysis-breakdown" }, /* @__PURE__ */ import_react14.default.createElement("span", null, "\u7F13\u5B58\u8BFB/\u5199\u6BD4\u4F8B\uFF1A", Math.round(Number(plan.optimization?.cacheReadRatio ?? 0) * 100), "% / ", Math.round(Number(plan.optimization?.cacheWriteRatio ?? 0) * 100), "%"), /* @__PURE__ */ import_react14.default.createElement("span", null, "\u672A\u586B\u5199\u6BD4\u4F8B\u65F6\u6309\u666E\u901A\u8F93\u5165\u8BA1\u8D39")), /* @__PURE__ */ import_react14.default.createElement("div", { className: "gv-analysis-breakdown" }, /* @__PURE__ */ import_react14.default.createElement("span", null, "\u5B9E\u9645\u4F7F\u7528 ", Number(plan.optimization?.distinctRoutes ?? 0), " \u4E2A\u6A21\u578B"), /* @__PURE__ */ import_react14.default.createElement("span", null, plan.optimization?.budgetExceeded ? "\u9884\u7B97\u8D85\u9650\uFF1A\u5DF2\u5728\u8D28\u91CF\u4E0B\u9650\u5185\u5C3D\u91CF\u538B\u7F29" : "\u9884\u7B97\u7EA6\u675F\u6EE1\u8DB3"), /* @__PURE__ */ import_react14.default.createElement("span", null, plan.optimization?.constraintRelaxed ? "\u90E8\u5206\u8D28\u91CF\u4E0B\u9650\u672A\u6EE1\u8DB3\uFF0C\u5DF2\u8BB0\u5F55\u56DE\u9000" : "\u8D28\u91CF\u7EA6\u675F\u6EE1\u8DB3")), /* @__PURE__ */ import_react14.default.createElement("div", { className: "gv-analysis-breakdown" }, /* @__PURE__ */ import_react14.default.createElement("span", null, "LiveBench\uFF1A", plan.optimization?.liveBench?.fetchedAt ? `\u5FEB\u7167 ${formatTime(Number(plan.optimization.liveBench.fetchedAt))}${plan.optimization.liveBench.stale ? "\uFF08\u6CBF\u7528\u4E0A\u6B21\u5FEB\u7167\uFF09" : ""}` : "\u672A\u5B8C\u6210\u8054\u7F51\u6838\u9A8C\uFF0C\u4F7F\u7528\u5B9E\u9A8C\u57FA\u7EBF"), /* @__PURE__ */ import_react14.default.createElement("span", null, "\u6570\u636E\u6E90\uFF1A", plan.optimization?.liveBench?.source ?? "experimental-baseline")), Array.isArray(plan.costBreakdown) && plan.costBreakdown.length > 0 && /* @__PURE__ */ import_react14.default.createElement("div", { className: "gv-analysis-breakdown" }, plan.costBreakdown.map((row) => /* @__PURE__ */ import_react14.default.createElement("span", { key: `${row.stage}-${row.provider}-${row.model}` }, "\u9636\u6BB5 ", row.stage, " \xB7 ", row.model, " \xB7 \u8F93\u5165 ", row.inputTokens, "\uFF08\u7F13\u5B58\u8BFB ", row.cacheReadTokens ?? 0, " / \u5199 ", row.cacheWriteTokens ?? 0, "\uFF09/ \u8F93\u51FA ", row.outputTokens, " tokens \xB7 \u8D28\u91CF ", Math.round(Number(row.quality ?? 0) * 100), "% \xB7 $", Number(row.estimatedCost ?? 0).toFixed(6)))), /* @__PURE__ */ import_react14.default.createElement("div", { className: "gv-analysis-candidates" }, (plan.candidates ?? []).slice(0, 5).map((candidate) => /* @__PURE__ */ import_react14.default.createElement("span", { key: `${candidate.provider}/${candidate.model}` }, candidate.model, " \xB7 \u7EFC\u5408 ", Math.round(candidate.score * 100), "% \xB7 \u8D28\u91CF ", Math.round(Number(candidate.quality ?? 0) * 100), "% \xB7 \u4E13\u957F ", Math.round(Number(candidate.specialty ?? 0) * 100), "% \xB7 $", Number(candidate.inputPrice ?? 0).toFixed(2), "/$", Number(candidate.outputPrice ?? 0).toFixed(2))))));
44603
+ return /* @__PURE__ */ import_react14.default.createElement("details", { className: "gv-analysis-summary" }, /* @__PURE__ */ import_react14.default.createElement("summary", null, /* @__PURE__ */ import_react14.default.createElement("span", { className: "gv-analysis-summary-title" }, /* @__PURE__ */ import_react14.default.createElement(MaidAvatar, { model: "DeepSeek Harness", size: "tiny" }), "\u67E5\u770B\u8DEF\u7531\u5206\u6790\u6458\u8981")), /* @__PURE__ */ import_react14.default.createElement("div", { className: "gv-analysis-body" }, /* @__PURE__ */ import_react14.default.createElement("p", null, plan.reason), /* @__PURE__ */ import_react14.default.createElement("div", { className: "gv-analysis-metrics" }, /* @__PURE__ */ import_react14.default.createElement("span", null, "\u590D\u6742\u5EA6 ", /* @__PURE__ */ import_react14.default.createElement("b", null, Math.round((plan.complexity?.value ?? 0) * 100), "%")), /* @__PURE__ */ import_react14.default.createElement("span", null, "\u7C7B\u578B ", /* @__PURE__ */ import_react14.default.createElement("b", null, plan.taskType)), Array.isArray(plan.taskTypes) && plan.taskTypes.length > 1 && /* @__PURE__ */ import_react14.default.createElement("span", null, "\u4E1A\u52A1\u65B9\u5411 ", /* @__PURE__ */ import_react14.default.createElement("b", null, plan.taskTypes.join("\u3001"))), /* @__PURE__ */ import_react14.default.createElement("span", null, "\u8D28\u91CF ", /* @__PURE__ */ import_react14.default.createElement("b", null, Math.round((weights.quality ?? 0) * 100), "%")), /* @__PURE__ */ import_react14.default.createElement("span", null, "\u6210\u672C ", /* @__PURE__ */ import_react14.default.createElement("b", null, Math.round((weights.cost ?? 0) * 100), "%")), /* @__PURE__ */ import_react14.default.createElement("span", null, "\u5EF6\u8FDF ", /* @__PURE__ */ import_react14.default.createElement("b", null, Math.round((weights.latency ?? 0) * 100), "%")), /* @__PURE__ */ import_react14.default.createElement("span", null, "\u4E13\u957F ", /* @__PURE__ */ import_react14.default.createElement("b", null, Math.round((weights.specialty ?? 0) * 100), "%")), /* @__PURE__ */ import_react14.default.createElement("span", null, "\u63A8\u7406\u7B49\u7EA7 ", /* @__PURE__ */ import_react14.default.createElement("b", null, Math.round((weights.reasoning ?? 0) * 100), "%")), /* @__PURE__ */ import_react14.default.createElement("span", null, "\u98CE\u9669 ", /* @__PURE__ */ import_react14.default.createElement("b", null, Math.round((weights.risk ?? 0) * 100), "%")), /* @__PURE__ */ import_react14.default.createElement("span", null, "\u8D28\u91CF\u4E0B\u9650 ", /* @__PURE__ */ import_react14.default.createElement("b", null, Math.round((plan.optimization?.qualityFloor ?? 0) * 100), "%"))), /* @__PURE__ */ import_react14.default.createElement("div", { className: "gv-analysis-cost" }, "\u9884\u8BA1\u603B\u8D39\u7528 ", /* @__PURE__ */ import_react14.default.createElement("b", null, "$", Number(plan.estimatedCost ?? 0).toFixed(6))), /* @__PURE__ */ import_react14.default.createElement("div", { className: "gv-analysis-cost" }, "\u5168\u9AD8\u8D28\u91CF\u57FA\u7EBF ", /* @__PURE__ */ import_react14.default.createElement("b", null, "$", Number(plan.optimization?.baselineAllStrongCost ?? 0).toFixed(6)), " \xB7 \u9884\u8BA1\u8282\u7701 ", /* @__PURE__ */ import_react14.default.createElement("b", null, Math.round(Number(plan.optimization?.estimatedSavings ?? 0) * 100), "%")), /* @__PURE__ */ import_react14.default.createElement("div", { className: "gv-analysis-breakdown" }, /* @__PURE__ */ import_react14.default.createElement("span", null, "\u7F13\u5B58\u8BFB/\u5199\u6BD4\u4F8B\uFF1A", Math.round(Number(plan.optimization?.cacheReadRatio ?? 0) * 100), "% / ", Math.round(Number(plan.optimization?.cacheWriteRatio ?? 0) * 100), "%"), /* @__PURE__ */ import_react14.default.createElement("span", null, "\u672A\u586B\u5199\u6BD4\u4F8B\u65F6\u6309\u666E\u901A\u8F93\u5165\u8BA1\u8D39")), /* @__PURE__ */ import_react14.default.createElement("div", { className: "gv-analysis-breakdown" }, /* @__PURE__ */ import_react14.default.createElement("span", null, "\u5B9E\u9645\u4F7F\u7528 ", Number(plan.optimization?.distinctRoutes ?? 0), " \u4E2A\u6A21\u578B"), /* @__PURE__ */ import_react14.default.createElement("span", null, plan.optimization?.budgetExceeded ? "\u9884\u7B97\u8D85\u9650\uFF1A\u5DF2\u5728\u8D28\u91CF\u4E0B\u9650\u5185\u5C3D\u91CF\u538B\u7F29" : "\u9884\u7B97\u7EA6\u675F\u6EE1\u8DB3"), /* @__PURE__ */ import_react14.default.createElement("span", null, plan.optimization?.constraintRelaxed ? "\u90E8\u5206\u8D28\u91CF\u4E0B\u9650\u672A\u6EE1\u8DB3\uFF0C\u5DF2\u8BB0\u5F55\u56DE\u9000" : "\u8D28\u91CF\u7EA6\u675F\u6EE1\u8DB3")), /* @__PURE__ */ import_react14.default.createElement("div", { className: "gv-analysis-breakdown" }, /* @__PURE__ */ import_react14.default.createElement("span", null, "LiveBench\uFF1A", plan.optimization?.liveBench?.fetchedAt ? `\u5FEB\u7167 ${formatTime(Number(plan.optimization.liveBench.fetchedAt))}${plan.optimization.liveBench.stale ? "\uFF08\u6CBF\u7528\u4E0A\u6B21\u5FEB\u7167\uFF09" : ""}` : "\u672A\u5B8C\u6210\u8054\u7F51\u6838\u9A8C\uFF0C\u4F7F\u7528\u5B9E\u9A8C\u57FA\u7EBF"), /* @__PURE__ */ import_react14.default.createElement("span", null, "\u6570\u636E\u6E90\uFF1A", plan.optimization?.liveBench?.source ?? "experimental-baseline")), Array.isArray(plan.costBreakdown) && plan.costBreakdown.length > 0 && /* @__PURE__ */ import_react14.default.createElement("div", { className: "gv-analysis-breakdown" }, plan.costBreakdown.map((row) => /* @__PURE__ */ import_react14.default.createElement("span", { key: `${row.stage}-${row.provider}-${row.model}` }, "\u9636\u6BB5 ", row.stage, " \xB7 ", row.model, " \xB7 \u63A8\u7406 ", row.reasoningEffort || "\u63D0\u4F9B\u65B9\u9ED8\u8BA4", "\uFF08\u5339\u914D ", Math.round(Number(row.reasoningFit ?? 0) * 100), "%\uFF09\xB7 \u8F93\u5165 ", row.inputTokens, "\uFF08\u7F13\u5B58\u8BFB ", row.cacheReadTokens ?? 0, " / \u5199 ", row.cacheWriteTokens ?? 0, "\uFF09/ \u8F93\u51FA ", row.outputTokens, " tokens \xB7 \u8D28\u91CF ", Math.round(Number(row.quality ?? 0) * 100), "% \xB7 $", Number(row.estimatedCost ?? 0).toFixed(6)))), /* @__PURE__ */ import_react14.default.createElement("div", { className: "gv-analysis-candidates" }, (plan.candidates ?? []).slice(0, 5).map((candidate) => /* @__PURE__ */ import_react14.default.createElement("span", { key: `${candidate.provider}/${candidate.model}` }, candidate.model, " \xB7 \u63A8\u7406 ", candidate.reasoningEffort || "\u63D0\u4F9B\u65B9\u9ED8\u8BA4", " \xB7 \u7EFC\u5408 ", Math.round(candidate.score * 100), "% \xB7 \u8D28\u91CF ", Math.round(Number(candidate.quality ?? 0) * 100), "% \xB7 \u4E13\u957F ", Math.round(Number(candidate.specialty ?? 0) * 100), "% \xB7 $", Number(candidate.inputPrice ?? 0).toFixed(2), "/$", Number(candidate.outputPrice ?? 0).toFixed(2))))));
44480
44604
  }
44481
44605
 
44482
44606
  // .dsh-plugin/client/attachment-bridge.mjs
@@ -44595,7 +44719,7 @@ function routeFromNodes(nodes3) {
44595
44719
  if (node2?.kind !== "assistant") continue;
44596
44720
  if (Number(node2.seq ?? -Infinity) <= latestUserSeq) continue;
44597
44721
  const route = routeFromNode(node2);
44598
- if (route?.provider && route?.model) return { provider: route.provider, model: route.model };
44722
+ if (route?.provider && route?.model) return route;
44599
44723
  }
44600
44724
  return null;
44601
44725
  }
@@ -44628,11 +44752,11 @@ function needsWholeMarkdown(text6) {
44628
44752
  return value.length > 800 || /(^|\n)\s*(?:#{1,6}\s|```|~~~|[-*+]\s|\d+[.)]\s|\|.+\|)|\$\$|\\\[|\\\(|\[[^\]]+\]\([^)]+\)/m.test(value);
44629
44753
  }
44630
44754
  function RouterPanel({ plan, route, displayRoute, onMode, routerMode, routerSnapshot, routerActions }) {
44631
- const weights = plan?.objectiveWeights ?? { quality: 0, cost: 0, latency: 0, risk: 0 };
44755
+ const weights = plan?.objectiveWeights ?? { quality: 0, cost: 0, reasoning: 0, latency: 0, risk: 0 };
44632
44756
  const selected = route ?? plan?.selected;
44633
44757
  const modeLabel = routerMode === "single" ? "\u5355\u72EC\u4F1A\u8BDD" : "\u96C6\u4F53\u5408\u4F5C";
44634
- const modeDetail = routerMode === "single" ? selected?.model ? `\u56FA\u5B9A\uFF1A${selected.model}` : "\u7B49\u5F85\u9009\u62E9\u6A21\u578B" : "\u6309\u4EFB\u52A1\u590D\u6742\u5EA6\u81EA\u52A8\u5206\u914D";
44635
- return /* @__PURE__ */ import_react15.default.createElement("section", { className: "gv-router-panel", "aria-label": "\u667A\u80FD\u5206\u914D\u65B9\u6848" }, /* @__PURE__ */ import_react15.default.createElement("div", { className: "gv-router-head" }, /* @__PURE__ */ import_react15.default.createElement("span", { className: "gv-router-title" }, "\u667A\u80FD\u5206\u914D\u65B9\u6848"), /* @__PURE__ */ import_react15.default.createElement(MaidAvatar, { model: displayRoute?.model || selected?.model || "DeepSeek Harness", provider: displayRoute?.provider ?? selected?.provider, active: Boolean(selected) })), /* @__PURE__ */ import_react15.default.createElement("details", { className: "gv-session-details" }, /* @__PURE__ */ import_react15.default.createElement("summary", { className: "gv-session-summary" }, /* @__PURE__ */ import_react15.default.createElement("span", { className: "gv-session-summary-title" }, "\u4F1A\u8BDD\u65B9\u5F0F"), /* @__PURE__ */ import_react15.default.createElement("strong", null, modeLabel), /* @__PURE__ */ import_react15.default.createElement("span", { className: "gv-session-summary-detail" }, modeDetail)), /* @__PURE__ */ import_react15.default.createElement("div", { className: "gv-session-body" }, /* @__PURE__ */ import_react15.default.createElement(ModelPicker, { mode: routerMode, snapshot: routerSnapshot, actions: routerActions, onMode, selectedRoute: selected }), /* @__PURE__ */ import_react15.default.createElement("div", { className: "gv-router-grid" }, /* @__PURE__ */ import_react15.default.createElement("span", null, "\u590D\u6742\u5EA6 ", /* @__PURE__ */ import_react15.default.createElement("b", null, plan ? `${Math.round((plan.complexity?.value ?? 0) * 100)}%` : "\u5206\u6790\u4E2D")), /* @__PURE__ */ import_react15.default.createElement("span", null, "\u4EFB\u52A1\u7C7B\u578B ", /* @__PURE__ */ import_react15.default.createElement("b", null, plan?.taskType ?? "\u5F85\u63D0\u95EE")), /* @__PURE__ */ import_react15.default.createElement("span", null, "\u5F53\u524D\u6A21\u578B ", /* @__PURE__ */ import_react15.default.createElement("b", null, selected?.model ?? "\u7B49\u5F85\u8DEF\u7531")), /* @__PURE__ */ import_react15.default.createElement("span", null, "\u9884\u4F30\u8D39\u7528 ", /* @__PURE__ */ import_react15.default.createElement("b", null, plan ? `$${Number(plan.estimatedCost ?? 0).toFixed(4)}` : "\u2014"))), plan && routerMode === "collective" && /* @__PURE__ */ import_react15.default.createElement(import_react15.default.Fragment, null, /* @__PURE__ */ import_react15.default.createElement("div", { className: "gv-router-weights", "aria-label": "\u76EE\u6807\u6743\u91CD" }, /* @__PURE__ */ import_react15.default.createElement("span", null, "\u8D28\u91CF ", Math.round(weights.quality * 100), "%"), /* @__PURE__ */ import_react15.default.createElement("span", null, "\u6210\u672C ", Math.round(weights.cost * 100), "%"), /* @__PURE__ */ import_react15.default.createElement("span", null, "\u5EF6\u8FDF ", Math.round(weights.latency * 100), "%"), /* @__PURE__ */ import_react15.default.createElement("span", null, "\u98CE\u9669 ", Math.round(weights.risk * 100), "%")), /* @__PURE__ */ import_react15.default.createElement("div", { className: "gv-router-reason" }, plan.reason), /* @__PURE__ */ import_react15.default.createElement("div", { className: "gv-router-candidates" }, (plan.candidates ?? []).slice(0, 4).map((candidate) => /* @__PURE__ */ import_react15.default.createElement("span", { key: `${candidate.provider}/${candidate.model}`, title: `\u7EFC\u5408 ${candidate.score}\uFF0C\u4E13\u957F ${candidate.specialty}` }, candidate.model, " \xB7 ", Math.round(candidate.score * 100), "%")))), routerMode === "single" && selected && /* @__PURE__ */ import_react15.default.createElement("div", { className: "gv-router-single-note" }, "\u540E\u7EED\u8BF7\u6C42\u56FA\u5B9A\u4EA4\u7ED9 ", /* @__PURE__ */ import_react15.default.createElement("b", null, selected.provider, "/", selected.model), "\uFF0C\u96C6\u4F53\u8DEF\u7531\u4E0D\u4F1A\u6539\u5199\u5355\u72EC\u4F1A\u8BDD\u3002"))));
44758
+ const modeDetail = routerMode === "single" ? selected?.model ? `\u56FA\u5B9A\uFF1A${selected.model}${selected.reasoningEffort ? ` \xB7 ${selected.reasoningEffort}` : ""}` : "\u7B49\u5F85\u9009\u62E9\u6A21\u578B" : "\u6309\u4EFB\u52A1\u590D\u6742\u5EA6\u81EA\u52A8\u5206\u914D";
44759
+ return /* @__PURE__ */ import_react15.default.createElement("section", { className: "gv-router-panel", "aria-label": "\u667A\u80FD\u5206\u914D\u65B9\u6848" }, /* @__PURE__ */ import_react15.default.createElement("div", { className: "gv-router-head" }, /* @__PURE__ */ import_react15.default.createElement("span", { className: "gv-router-title" }, "\u667A\u80FD\u5206\u914D\u65B9\u6848"), /* @__PURE__ */ import_react15.default.createElement(MaidAvatar, { model: displayRoute?.model || selected?.model || "DeepSeek Harness", provider: displayRoute?.provider ?? selected?.provider, active: Boolean(selected) })), /* @__PURE__ */ import_react15.default.createElement("details", { className: "gv-session-details" }, /* @__PURE__ */ import_react15.default.createElement("summary", { className: "gv-session-summary" }, /* @__PURE__ */ import_react15.default.createElement("span", { className: "gv-session-summary-title" }, "\u4F1A\u8BDD\u65B9\u5F0F"), /* @__PURE__ */ import_react15.default.createElement("strong", null, modeLabel), /* @__PURE__ */ import_react15.default.createElement("span", { className: "gv-session-summary-detail" }, modeDetail)), /* @__PURE__ */ import_react15.default.createElement("div", { className: "gv-session-body" }, /* @__PURE__ */ import_react15.default.createElement(ModelPicker, { mode: routerMode, snapshot: routerSnapshot, actions: routerActions, onMode, selectedRoute: selected }), /* @__PURE__ */ import_react15.default.createElement("div", { className: "gv-router-grid" }, /* @__PURE__ */ import_react15.default.createElement("span", null, "\u590D\u6742\u5EA6 ", /* @__PURE__ */ import_react15.default.createElement("b", null, plan ? `${Math.round((plan.complexity?.value ?? 0) * 100)}%` : "\u5206\u6790\u4E2D")), /* @__PURE__ */ import_react15.default.createElement("span", null, "\u4EFB\u52A1\u7C7B\u578B ", /* @__PURE__ */ import_react15.default.createElement("b", null, plan?.taskType ?? "\u5F85\u63D0\u95EE")), /* @__PURE__ */ import_react15.default.createElement("span", null, "\u5F53\u524D\u6A21\u578B ", /* @__PURE__ */ import_react15.default.createElement("b", null, selected?.model ?? "\u7B49\u5F85\u8DEF\u7531")), /* @__PURE__ */ import_react15.default.createElement("span", null, "\u63A8\u7406\u7B49\u7EA7 ", /* @__PURE__ */ import_react15.default.createElement("b", null, selected?.reasoningEffort ?? "\u63D0\u4F9B\u65B9\u9ED8\u8BA4")), /* @__PURE__ */ import_react15.default.createElement("span", null, "\u9884\u4F30\u8D39\u7528 ", /* @__PURE__ */ import_react15.default.createElement("b", null, plan ? `$${Number(plan.estimatedCost ?? 0).toFixed(4)}` : "\u2014"))), plan && routerMode === "collective" && /* @__PURE__ */ import_react15.default.createElement(import_react15.default.Fragment, null, /* @__PURE__ */ import_react15.default.createElement("div", { className: "gv-router-weights", "aria-label": "\u76EE\u6807\u6743\u91CD" }, /* @__PURE__ */ import_react15.default.createElement("span", null, "\u8D28\u91CF ", Math.round(weights.quality * 100), "%"), /* @__PURE__ */ import_react15.default.createElement("span", null, "\u6210\u672C ", Math.round(weights.cost * 100), "%"), /* @__PURE__ */ import_react15.default.createElement("span", null, "\u63A8\u7406 ", Math.round((weights.reasoning ?? 0) * 100), "%"), /* @__PURE__ */ import_react15.default.createElement("span", null, "\u5EF6\u8FDF ", Math.round(weights.latency * 100), "%"), /* @__PURE__ */ import_react15.default.createElement("span", null, "\u98CE\u9669 ", Math.round(weights.risk * 100), "%")), /* @__PURE__ */ import_react15.default.createElement("div", { className: "gv-router-reason" }, plan.reason), /* @__PURE__ */ import_react15.default.createElement("div", { className: "gv-router-candidates" }, (plan.candidates ?? []).slice(0, 4).map((candidate) => /* @__PURE__ */ import_react15.default.createElement("span", { key: `${candidate.provider}/${candidate.model}`, title: `\u7EFC\u5408 ${candidate.score}\uFF0C\u4E13\u957F ${candidate.specialty}\uFF0C\u63A8\u7406\u5339\u914D ${candidate.reasoningFit}` }, candidate.model, " \xB7 ", candidate.reasoningEffort || "\u9ED8\u8BA4", " \xB7 ", Math.round(candidate.score * 100), "%")))), routerMode === "single" && selected && /* @__PURE__ */ import_react15.default.createElement("div", { className: "gv-router-single-note" }, "\u540E\u7EED\u8BF7\u6C42\u56FA\u5B9A\u4EA4\u7ED9 ", /* @__PURE__ */ import_react15.default.createElement("b", null, selected.provider, "/", selected.model), "\uFF0C\u63A8\u7406\u7B49\u7EA7\u4E3A ", /* @__PURE__ */ import_react15.default.createElement("b", null, selected.reasoningEffort || "\u63D0\u4F9B\u65B9\u9ED8\u8BA4"), "\uFF0C\u96C6\u4F53\u8DEF\u7531\u4E0D\u4F1A\u6539\u5199\u5355\u72EC\u4F1A\u8BDD\u3002"))));
44636
44760
  }
44637
44761
  function HistoryPanel({ scene: scene3, lines: lines2, onClose }) {
44638
44762
  const listRef = (0, import_react15.useRef)(null);
@@ -44924,7 +45048,7 @@ function GalView({ sessionId, useSession, useSessions, useConversation, useChat,
44924
45048
  const actualRoute = (0, import_react15.useMemo)(() => routeFromNodes(nodes3), [nodes3]);
44925
45049
  const manualRoute = (0, import_react15.useMemo)(() => {
44926
45050
  const current = routerSnapshot?.current;
44927
- if (current?.provider && current?.model) return { provider: current.provider, model: current.model };
45051
+ if (current?.provider && current?.model) return { provider: current.provider, model: current.model, ...current.reasoningEffort === void 0 ? {} : { reasoningEffort: current.reasoningEffort } };
44928
45052
  return null;
44929
45053
  }, [routerSnapshot?.current]);
44930
45054
  const routeCatalog = (0, import_react15.useMemo)(() => {
@@ -45784,16 +45908,27 @@ function createIdbAssets(dbName = "gal-view") {
45784
45908
  }
45785
45909
 
45786
45910
  // .dsh-plugin/client/model-directory-bridge.mjs
45787
- function catalogSnapshot(catalog, previous4 = {}) {
45788
- const value = catalog ?? {};
45789
- const loadedGroups = Array.isArray(value.groups) ? value.groups : [];
45790
- const groups = loadedGroups.length > 0 ? loadedGroups : previous4.groups ?? [];
45911
+ function catalogRoutes(groups) {
45791
45912
  const flattened = [];
45792
- for (const group of groups) {
45913
+ for (const group of Array.isArray(groups) ? groups : []) {
45793
45914
  for (const model of group.models ?? []) {
45794
- flattened.push({ provider: group.id, model: model.id });
45915
+ const reasoning = model.reasoning;
45916
+ flattened.push({
45917
+ provider: group.id,
45918
+ model: model.id,
45919
+ reasoningKnown: true,
45920
+ reasoningEfforts: Array.isArray(reasoning?.efforts) ? reasoning.efforts.map((effort) => effort.id) : [],
45921
+ ...reasoning?.defaultEffort === void 0 ? {} : { defaultReasoningEffort: reasoning.defaultEffort }
45922
+ });
45795
45923
  }
45796
45924
  }
45925
+ return flattened;
45926
+ }
45927
+ function catalogSnapshot(catalog, previous4 = {}) {
45928
+ const value = catalog ?? {};
45929
+ const loadedGroups = Array.isArray(value.groups) ? value.groups : [];
45930
+ const groups = loadedGroups.length > 0 ? loadedGroups : previous4.groups ?? [];
45931
+ const flattened = catalogRoutes(groups);
45797
45932
  return {
45798
45933
  available: flattened.length > 0 ? flattened : previous4.available ?? [],
45799
45934
  groups,
@@ -46013,7 +46148,7 @@ var gal_scene_default = { version: 1, settings: { stageW: 1920, stageH: 1080, sh
46013
46148
 
46014
46149
  // .dsh-plugin/client/index.mjs
46015
46150
  var name = "gal-view";
46016
- var PLUGIN_VERSION = "0.4.31";
46151
+ var PLUGIN_VERSION = "0.4.32";
46017
46152
  function createUpdateApi2(ctx) {
46018
46153
  let connection;
46019
46154
  try {
@@ -46538,10 +46673,7 @@ function apply(ctx) {
46538
46673
  const previous4 = source.getSnapshot();
46539
46674
  const loadedGroups = Array.isArray(state.groups) ? state.groups : [];
46540
46675
  const groups = loadedGroups.length > 0 ? loadedGroups : previous4.groups ?? [];
46541
- const fromGroups = [];
46542
- for (const group of groups) {
46543
- for (const model of group.models ?? []) fromGroups.push({ provider: group.id, model: model.id });
46544
- }
46676
+ const fromGroups = catalogRoutes(groups);
46545
46677
  const available = fromGroups.length > 0 ? fromGroups : previous4.available ?? [];
46546
46678
  const rawStatus = state.status ?? "loading";
46547
46679
  const status = rawStatus === "idle" && groups.length === 0 && available.length === 0 ? "loading" : rawStatus;