dsh-llm-verifier 0.1.9 → 0.1.11

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/lib/client.js CHANGED
@@ -7,6 +7,333 @@ window.__ModuleLoader__.load({
7
7
  let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
8
8
  let react = require("react");
9
9
  let react_jsx_runtime = require("react/jsx-runtime");
10
+ //#region src/client-i18n.ts
11
+ const zh = {
12
+ "settings.title": "LLM Verifier",
13
+ "settings.intro": "选择已在 DSH「模型」中配置的模型作为独立裁判。修改后点击页面底部的保存按钮生效。",
14
+ "settings.loading": "正在读取 DSH 模型和设置…",
15
+ "settings.retry": "重试",
16
+ "settings.nsUnregistered": "Verifier settings namespace is not registered. Restart the DSH host.",
17
+ "section.tools": "工具",
18
+ "field.enabled.title": "启用 Verifier 工具",
19
+ "field.enabled.helpOn": "允许 Agent 调用四个 verifier 工具并向裁判模型发起请求。",
20
+ "field.enabled.helpOff": "停用后,所有 verifier 工具都会立即返回错误。",
21
+ "field.enabled.warnDisabled": "verifier_compare、verifier_select、verifier_track 和 verifier_current_session 当前不可用。",
22
+ "section.autoVerify": "自动验收",
23
+ "field.autoVerifyMode.title": "调用策略",
24
+ "field.autoVerifyMode.help": "手动仅暴露工具;智能在有结构化/高置信证据时路由四工具;严格还会主动执行语义路由并对任何关键操作做最终验收。",
25
+ "field.autoVerifyMode.manual": "手动",
26
+ "field.autoVerifyMode.smart": "智能(推荐)",
27
+ "field.autoVerifyMode.strict": "严格",
28
+ "field.autoRouteSemantic.title": "混合语义路由",
29
+ "field.autoRouteSemantic.help": "结构化候选或检查点不足时,由裁判模型保守识别真实的 compare/select/track 对象。智能模式仅在有候选线索时运行;严格模式每次结束边界都会检查。",
30
+ "field.autoRouteMinConfidence.title": "语义路由置信度",
31
+ "field.autoRouteMinConfidence.help": "语义识别达到该置信度才执行 compare/select/track;范围 0–1,建议保持 0.9。",
32
+ "field.autoRouteMaxCandidates.title": "最多候选数",
33
+ "field.autoRouteMaxCandidates.help": "一次自动 select 最多纳入的真实候选数量,至少 3。",
34
+ "field.autoRouteMaxPerTask.title": "每任务最多路由",
35
+ "field.autoRouteMaxPerTask.help": "compare/select/track 自动路由的任务预算;指纹去重后仍受此上限约束。",
36
+ "field.autoRouteMaxPerSession.title": "每会话最多路由",
37
+ "field.autoRouteMaxPerSession.help": "同一会话中 compare/select/track 自动路由总预算。",
38
+ "field.autoTrackCompletionThreshold.title": "进度完成阈值",
39
+ "field.autoTrackCompletionThreshold.help": "track 任一检查点低于该值时 steering 要求 Agent 继续执行;范围 0–1。",
40
+ "field.autoRouteMaxItemChars.title": "单项证据字符上限",
41
+ "field.autoRouteMaxItemChars.help": "每个候选或检查点在脱敏后允许发送给裁判的最大字符数。",
42
+ "field.autoRouteMaxInputChars.title": "路由证据总字符上限",
43
+ "field.autoRouteMaxInputChars.help": "一次 compare/select/track 所有候选或步骤的总字符预算。",
44
+ "field.autoMaxModelCallsPerTask.title": "每任务模型调用预算",
45
+ "field.autoMaxModelCallsPerTask.help": "语义分类、中间路由和最终验收共享的估算模型调用上限。",
46
+ "field.autoMaxModelCallsPerSession.title": "每会话模型调用预算",
47
+ "field.autoMaxModelCallsPerSession.help": "整个会话所有自动验证阶段共享的估算模型调用上限。",
48
+ "field.autoVerifyThreshold.title": "通过阈值",
49
+ "field.autoVerifyThreshold.help": "会话证据分数达到该值且胜过空工作基线才允许结束;范围 0–1。",
50
+ "field.autoVerifyRepeats.title": "自动评估轮次",
51
+ "field.autoVerifyRepeats.help": "每项标准的自动评分重复次数;1 为低成本初筛。",
52
+ "field.autoVerifyMinToolCalls.title": "智能模式最少工具调用",
53
+ "field.autoVerifyMinToolCalls.help": "达到此工具证据数量且包含写入/执行类操作时才自动验收。",
54
+ "field.autoVerifyMaxChars.title": "最大证据字符",
55
+ "field.autoVerifyMaxChars.help": "发送给裁判前保留的最近会话证据字符数。",
56
+ "field.autoVerifyMaxPerTask.title": "每任务最多验收",
57
+ "field.autoVerifyMaxPerTask.help": "低分反馈后允许再次验收的次数上限,防止循环。",
58
+ "field.autoVerifyMaxPerSession.title": "每会话最多验收",
59
+ "field.autoVerifyMaxPerSession.help": "同一会话中的自动验收总预算。",
60
+ "field.autoVerify.warnNotice": "自动路由按 select → compare → track → current_session 的阶段顺序处理;脱敏后的任务、Assistant 轨迹与真实工具输出会发送给所选裁判模型。候选选择或进度不足会 steering 继续工作,最终验收未通过会要求修复并重新验证。",
61
+ "section.model": "裁判模型",
62
+ "field.provider.title": "供应商",
63
+ "field.provider.help": "当前 DSH 中可路由的模型供应商。",
64
+ "field.model.title": "模型",
65
+ "field.model.help": "用作裁判的具体模型。",
66
+ "field.reasoningEffort.title": "推理强度",
67
+ "field.reasoningEffort.help": "留空时使用所选模型的默认值。",
68
+ "field.reasoningEffort.default": "模型默认",
69
+ "field.maxTokens.title": "最大输出 Token",
70
+ "field.maxTokens.help": "单次裁判请求允许生成的最大 Token 数。",
71
+ "section.execution": "执行",
72
+ "field.maxConcurrency.title": "最大并发",
73
+ "field.maxConcurrency.help": "所有 verifier 工具共享的请求并发上限。",
74
+ "field.maxRetries.title": "最多重试",
75
+ "field.maxRetries.help": "限流、超时和短暂网络错误的重试次数。",
76
+ "field.timeoutMs.title": "请求超时",
77
+ "field.timeoutMs.help": "单次模型请求的超时时间,单位为毫秒。",
78
+ "field.cacheMaxEntries.title": "缓存条目上限",
79
+ "field.cacheMaxEntries.help": "本地持久评分缓存保留的最大条目数。",
80
+ "section.cost": "费用估算",
81
+ "field.estimatedInputUsdPerMillion.title": "输入价格",
82
+ "field.estimatedInputUsdPerMillion.help": "每百万输入 Token 的美元价格,仅用于统计估算。",
83
+ "field.estimatedOutputUsdPerMillion.title": "输出价格",
84
+ "field.estimatedOutputUsdPerMillion.help": "每百万输出 Token 的美元价格,仅用于统计估算。",
85
+ "settings.catalogFailures": "部分模型目录读取失败",
86
+ "settings.saved": "设置已保存。",
87
+ "settings.reload": "重新载入",
88
+ "settings.save": "保存设置",
89
+ "settings.saving": "保存中…",
90
+ "stats.pageTitle": "Verifier 工具统计",
91
+ "stats.updatedAt": "数据更新于 {time} · 自动记录四个验证工具的实际执行结果",
92
+ "stats.daysUnit": "{days} 天",
93
+ "stats.currentSession": "当前会话",
94
+ "stats.allSessions": "全部会话",
95
+ "stats.refresh": "刷新",
96
+ "stats.requestFailed": "统计接口请求失败",
97
+ "stats.hostRestartHint": "请确认宿主已重启并加载最新版本的 dsh-llm-verifier。",
98
+ "stats.loading": "正在读取工具运行统计…",
99
+ "stats.costSummary": "{days} 天估算费用",
100
+ "stats.callsSummary": "{invocations} 次工具调用 · {calls} 次裁判模型请求",
101
+ "stats.successCalls": "成功调用",
102
+ "stats.failedCalls": "失败调用",
103
+ "stats.avgDuration": "平均耗时",
104
+ "metric.cacheHitRate": "缓存命中率",
105
+ "metric.cacheHitNote": "{hits} 命中 / {total} 评分",
106
+ "metric.tokens": "Token",
107
+ "metric.tokensNote": "输入 {input} · 输出 {output}",
108
+ "metric.avgModelCalls": "平均模型请求",
109
+ "metric.avgModelCallsNote": "{attempts} 次尝试 · {retries} 次重试",
110
+ "metric.scoringMode": "评分模式",
111
+ "metric.scoringModeNote": "Top-logprobs · 显式标签 {explicit}",
112
+ "chart.title": "每日工具调用与模型请求趋势",
113
+ "chart.ariaLabel": "每日工具调用与模型请求趋势",
114
+ "chart.legendToolCalls": "工具调用",
115
+ "chart.legendModelCalls": "模型请求",
116
+ "table.title": "工具运行明细",
117
+ "table.toolCount": "{count} 类工具",
118
+ "table.colTool": "工具",
119
+ "table.colInvocations": "调用",
120
+ "table.colSuccessRate": "成功率",
121
+ "table.colAvgDuration": "平均耗时",
122
+ "table.colModelCalls": "模型请求",
123
+ "table.colTokens": "Token",
124
+ "table.colCacheHits": "缓存命中",
125
+ "table.colEstimatedCost": "估算费用",
126
+ "table.empty": "所选范围内还没有 Verifier 工具调用。后续执行会自动出现在这里。",
127
+ "recent.title": "最近调用",
128
+ "recent.maxCount": "最多 50 条",
129
+ "recent.empty": "暂无记录",
130
+ "models.title": "模型汇总",
131
+ "models.calls": "{calls} 请求",
132
+ "models.tokens": "{tokens} Token",
133
+ "models.empty": "暂无模型调用",
134
+ "slot.statistics": "工具统计"
135
+ };
136
+ const en = {
137
+ "settings.title": "LLM Verifier",
138
+ "settings.intro": "Select a model configured in DSH \"Models\" as an independent judge. Click the Save button at the bottom of the page to apply changes.",
139
+ "settings.loading": "Loading DSH models and settings…",
140
+ "settings.retry": "Retry",
141
+ "settings.nsUnregistered": "Verifier settings namespace is not registered. Restart the DSH host.",
142
+ "section.tools": "Tools",
143
+ "field.enabled.title": "Enable Verifier Tools",
144
+ "field.enabled.helpOn": "Allows the Agent to call verifier tools and make requests to the judge model.",
145
+ "field.enabled.helpOff": "When disabled, all verifier tools will return an error immediately.",
146
+ "field.enabled.warnDisabled": "verifier_compare, verifier_select, verifier_track, and verifier_current_session are currently unavailable.",
147
+ "section.autoVerify": "Automatic Verification",
148
+ "field.autoVerifyMode.title": "Invocation Policy",
149
+ "field.autoVerifyMode.help": "Manual exposes tools only; Smart routes tools when structured/high-confidence evidence is present; Strict actively runs semantic routing and performs final acceptance on any consequential action.",
150
+ "field.autoVerifyMode.manual": "Manual",
151
+ "field.autoVerifyMode.smart": "Smart (Recommended)",
152
+ "field.autoVerifyMode.strict": "Strict",
153
+ "field.autoRouteSemantic.title": "Hybrid Semantic Routing",
154
+ "field.autoRouteSemantic.help": "When structured candidates or checkpoints are lacking, the judge model conservatively identifies real compare/select/track targets. Smart mode only runs when candidate clues exist; Strict mode checks at every task boundary.",
155
+ "field.autoRouteMinConfidence.title": "Semantic Route Confidence",
156
+ "field.autoRouteMinConfidence.help": "Minimum confidence required for semantic recognition before executing compare/select/track; range 0–1, 0.9 recommended.",
157
+ "field.autoRouteMaxCandidates.title": "Max Candidates",
158
+ "field.autoRouteMaxCandidates.help": "Maximum number of real candidates included in an automatic select, at least 3.",
159
+ "field.autoRouteMaxPerTask.title": "Max Routes per Task",
160
+ "field.autoRouteMaxPerTask.help": "Task budget for automatic compare/select/track routing; still constrained by this cap after fingerprint deduplication.",
161
+ "field.autoRouteMaxPerSession.title": "Max Routes per Session",
162
+ "field.autoRouteMaxPerSession.help": "Total budget for automatic compare/select/track routing within the same session.",
163
+ "field.autoTrackCompletionThreshold.title": "Progress Completion Threshold",
164
+ "field.autoTrackCompletionThreshold.help": "When any track checkpoint falls below this score, steering instructs the Agent to continue; range 0–1.",
165
+ "field.autoRouteMaxItemChars.title": "Max Chars per Route Item",
166
+ "field.autoRouteMaxItemChars.help": "Maximum sanitized character count allowed per candidate or checkpoint when sent to the judge.",
167
+ "field.autoRouteMaxInputChars.title": "Total Route Input Chars Cap",
168
+ "field.autoRouteMaxInputChars.help": "Total character budget across all candidates or steps in a single compare/select/track call.",
169
+ "field.autoMaxModelCallsPerTask.title": "Model Call Budget per Task",
170
+ "field.autoMaxModelCallsPerTask.help": "Estimated model call cap shared across semantic classification, intermediate routing, and final acceptance per task.",
171
+ "field.autoMaxModelCallsPerSession.title": "Model Call Budget per Session",
172
+ "field.autoMaxModelCallsPerSession.help": "Estimated model call cap shared across all automatic verification phases throughout the entire session.",
173
+ "field.autoVerifyThreshold.title": "Pass Threshold",
174
+ "field.autoVerifyThreshold.help": "Evidence score must meet this threshold and beat the empty-work baseline to allow completion; range 0–1.",
175
+ "field.autoVerifyRepeats.title": "Auto Evaluation Repeats",
176
+ "field.autoVerifyRepeats.help": "Number of scoring repeats per criterion for auto evaluation; 1 is low-cost preliminary screening.",
177
+ "field.autoVerifyMinToolCalls.title": "Min Tool Calls (Smart Mode)",
178
+ "field.autoVerifyMinToolCalls.help": "Auto-verification triggers only when reaching this tool evidence count and containing write/exec operations.",
179
+ "field.autoVerifyMaxChars.title": "Max Evidence Characters",
180
+ "field.autoVerifyMaxChars.help": "Maximum recent session evidence characters retained before sending to the judge.",
181
+ "field.autoVerifyMaxPerTask.title": "Max Verifications per Task",
182
+ "field.autoVerifyMaxPerTask.help": "Maximum verification attempts allowed after low-score feedback to prevent infinite loops.",
183
+ "field.autoVerifyMaxPerSession.title": "Max Verifications per Session",
184
+ "field.autoVerifyMaxPerSession.help": "Total auto-verification budget within the same session.",
185
+ "field.autoVerify.warnNotice": "Automatic routing follows the phase order: select → compare → track → current_session. Sanitized tasks, Assistant trajectories, and real tool outputs are sent to the judge model. Candidate selection or insufficient progress steers the Agent to keep working; failed final acceptance requires remediation and re-verification.",
186
+ "section.model": "Judge Model",
187
+ "field.provider.title": "Provider",
188
+ "field.provider.help": "Routable model providers currently available in DSH.",
189
+ "field.model.title": "Model",
190
+ "field.model.help": "Specific model used as the independent judge.",
191
+ "field.reasoningEffort.title": "Reasoning Effort",
192
+ "field.reasoningEffort.help": "Leave empty to use the selected model default.",
193
+ "field.reasoningEffort.default": "Model Default",
194
+ "field.maxTokens.title": "Max Output Tokens",
195
+ "field.maxTokens.help": "Maximum tokens allowed in a single judge model completion.",
196
+ "section.execution": "Execution",
197
+ "field.maxConcurrency.title": "Max Concurrency",
198
+ "field.maxConcurrency.help": "Maximum concurrent requests shared across all verifier tools.",
199
+ "field.maxRetries.title": "Max Retries",
200
+ "field.maxRetries.help": "Retry attempts for rate limits, timeouts, and transient network errors.",
201
+ "field.timeoutMs.title": "Request Timeout",
202
+ "field.timeoutMs.help": "Timeout for a single model request, in milliseconds.",
203
+ "field.cacheMaxEntries.title": "Max Cache Entries",
204
+ "field.cacheMaxEntries.help": "Maximum entries retained in the local persistent score cache.",
205
+ "section.cost": "Cost Estimation",
206
+ "field.estimatedInputUsdPerMillion.title": "Input Price",
207
+ "field.estimatedInputUsdPerMillion.help": "USD price per million input tokens, for statistical estimation only.",
208
+ "field.estimatedOutputUsdPerMillion.title": "Output Price",
209
+ "field.estimatedOutputUsdPerMillion.help": "USD price per million output tokens, for statistical estimation only.",
210
+ "settings.catalogFailures": "Some model catalogs failed to load",
211
+ "settings.saved": "Settings saved.",
212
+ "settings.reload": "Reload",
213
+ "settings.save": "Save Settings",
214
+ "settings.saving": "Saving…",
215
+ "stats.pageTitle": "Verifier Tool Statistics",
216
+ "stats.updatedAt": "Updated at {time} · Automatically records execution results of the 4 verifier tools",
217
+ "stats.daysUnit": "{days} Days",
218
+ "stats.currentSession": "Current Session",
219
+ "stats.allSessions": "All Sessions",
220
+ "stats.refresh": "Refresh",
221
+ "stats.requestFailed": "Failed to query statistics API",
222
+ "stats.hostRestartHint": "Please make sure the host has restarted and loaded the latest version of dsh-llm-verifier.",
223
+ "stats.loading": "Loading tool execution statistics…",
224
+ "stats.costSummary": "{days}-Day Estimated Cost",
225
+ "stats.callsSummary": "{invocations} tool calls · {calls} judge requests",
226
+ "stats.successCalls": "Successful",
227
+ "stats.failedCalls": "Failed",
228
+ "stats.avgDuration": "Avg Duration",
229
+ "metric.cacheHitRate": "Cache Hit Rate",
230
+ "metric.cacheHitNote": "{hits} hits / {total} scored",
231
+ "metric.tokens": "Tokens",
232
+ "metric.tokensNote": "Input {input} · Output {output}",
233
+ "metric.avgModelCalls": "Avg Model Calls",
234
+ "metric.avgModelCallsNote": "{attempts} attempts · {retries} retries",
235
+ "metric.scoringMode": "Scoring Mode",
236
+ "metric.scoringModeNote": "Top-logprobs · Explicit tags {explicit}",
237
+ "chart.title": "Daily Tool Calls & Model Requests Trend",
238
+ "chart.ariaLabel": "Daily tool calls and model requests trend",
239
+ "chart.legendToolCalls": "Tool Calls",
240
+ "chart.legendModelCalls": "Model Requests",
241
+ "table.title": "Tool Breakdown",
242
+ "table.toolCount": "{count} Tool Types",
243
+ "table.colTool": "Tool",
244
+ "table.colInvocations": "Calls",
245
+ "table.colSuccessRate": "Success Rate",
246
+ "table.colAvgDuration": "Avg Duration",
247
+ "table.colModelCalls": "Model Calls",
248
+ "table.colTokens": "Tokens",
249
+ "table.colCacheHits": "Cache Hits",
250
+ "table.colEstimatedCost": "Estimated Cost",
251
+ "table.empty": "No verifier tool calls found in the selected range. Subsequent executions will appear here automatically.",
252
+ "recent.title": "Recent Invocations",
253
+ "recent.maxCount": "Max 50",
254
+ "recent.empty": "No records",
255
+ "models.title": "Model Summary",
256
+ "models.calls": "{calls} Requests",
257
+ "models.tokens": "{tokens} Tokens",
258
+ "models.empty": "No model calls",
259
+ "slot.statistics": "Statistics"
260
+ };
261
+ const dictionaries = {
262
+ zh,
263
+ en
264
+ };
265
+ const toolLabels = {
266
+ zh: {
267
+ verifier_route_classify: "路由分类",
268
+ verifier_compare: "两项对比",
269
+ verifier_select: "多项优选",
270
+ verifier_track: "进度跟踪",
271
+ verifier_current_session: "会话验收"
272
+ },
273
+ en: {
274
+ verifier_route_classify: "Route Classification",
275
+ verifier_compare: "Pairwise Comparison",
276
+ verifier_select: "Candidate Selection",
277
+ verifier_track: "Progress Tracking",
278
+ verifier_current_session: "Session Acceptance"
279
+ }
280
+ };
281
+ function tFormat(template, params) {
282
+ if (!params) return template;
283
+ return template.replace(/\{(\w+)\}/g, (match, key) => key in params ? String(params[key]) : match);
284
+ }
285
+ function detectLanguage() {
286
+ if (typeof document === "undefined") return "en";
287
+ return (document.documentElement.lang || "").toLowerCase().startsWith("zh") ? "zh" : "en";
288
+ }
289
+ function useLanguage() {
290
+ const [lang, setLang] = (0, react.useState)(detectLanguage);
291
+ (0, react.useEffect)(() => {
292
+ if (typeof document === "undefined") return;
293
+ const update = () => {
294
+ setLang(detectLanguage());
295
+ };
296
+ update();
297
+ const observer = new MutationObserver((mutations) => {
298
+ for (const mutation of mutations) if (mutation.type === "attributes" && mutation.attributeName === "lang") update();
299
+ });
300
+ observer.observe(document.documentElement, {
301
+ attributes: true,
302
+ attributeFilter: ["lang"]
303
+ });
304
+ return () => observer.disconnect();
305
+ }, []);
306
+ return lang;
307
+ }
308
+ function compact(value, lang = "en") {
309
+ const locale = lang === "zh" ? "zh-CN" : "en-US";
310
+ return new Intl.NumberFormat(locale, {
311
+ notation: value >= 1e4 ? "compact" : "standard",
312
+ maximumFractionDigits: value >= 1e3 ? 1 : 0
313
+ }).format(value);
314
+ }
315
+ function money(value) {
316
+ return "$" + value.toLocaleString("en-US", {
317
+ minimumFractionDigits: value < .01 ? 4 : 2,
318
+ maximumFractionDigits: value < .01 ? 4 : 2
319
+ });
320
+ }
321
+ function duration(value) {
322
+ if (value < 1e3) return Math.round(value) + " ms";
323
+ if (value < 6e4) return (value / 1e3).toFixed(1) + " s";
324
+ return (value / 6e4).toFixed(1) + " min";
325
+ }
326
+ function dateTime(value, lang = "en") {
327
+ const locale = lang === "zh" ? "zh-CN" : "en-US";
328
+ return new Intl.DateTimeFormat(locale, {
329
+ month: "2-digit",
330
+ day: "2-digit",
331
+ hour: "2-digit",
332
+ minute: "2-digit",
333
+ second: "2-digit"
334
+ }).format(value);
335
+ }
336
+ //#endregion
10
337
  //#region src/client.tsx
11
338
  const NS = "llm-verifier";
12
339
  const shell = {
@@ -101,13 +428,6 @@ window.__ModuleLoader__.load({
101
428
  color: "var(--dsw-text-secondary)",
102
429
  fontSize: 12
103
430
  };
104
- const toolLabels = {
105
- verifier_route_classify: "路由分类",
106
- verifier_compare: "两项对比",
107
- verifier_select: "多项优选",
108
- verifier_track: "进度跟踪",
109
- verifier_current_session: "会话验收"
110
- };
111
431
  const toolColors = {
112
432
  verifier_route_classify: "#d97706",
113
433
  verifier_compare: "#4f8cff",
@@ -183,32 +503,6 @@ window.__ModuleLoader__.load({
183
503
  children
184
504
  });
185
505
  }
186
- function compact(value) {
187
- return new Intl.NumberFormat("zh-CN", {
188
- notation: value >= 1e4 ? "compact" : "standard",
189
- maximumFractionDigits: value >= 1e3 ? 1 : 0
190
- }).format(value);
191
- }
192
- function money(value) {
193
- return "$" + value.toLocaleString("en-US", {
194
- minimumFractionDigits: value < .01 ? 4 : 2,
195
- maximumFractionDigits: value < .01 ? 4 : 2
196
- });
197
- }
198
- function duration(value) {
199
- if (value < 1e3) return Math.round(value) + " ms";
200
- if (value < 6e4) return (value / 1e3).toFixed(1) + " s";
201
- return (value / 6e4).toFixed(1) + " min";
202
- }
203
- function dateTime(value) {
204
- return new Intl.DateTimeFormat("zh-CN", {
205
- month: "2-digit",
206
- day: "2-digit",
207
- hour: "2-digit",
208
- minute: "2-digit",
209
- second: "2-digit"
210
- }).format(value);
211
- }
212
506
  function startOfRange(days) {
213
507
  const date = /* @__PURE__ */ new Date();
214
508
  date.setHours(0, 0, 0, 0);
@@ -222,6 +516,7 @@ window.__ModuleLoader__.load({
222
516
  return date.getTime();
223
517
  }
224
518
  function VerifierSettings({ remote }) {
519
+ const t = dictionaries[useLanguage()];
225
520
  const [loaded, setLoaded] = (0, react.useState)(null);
226
521
  const [draft, setDraft] = (0, react.useState)(null);
227
522
  const [busy, setBusy] = (0, react.useState)(false);
@@ -234,7 +529,7 @@ window.__ModuleLoader__.load({
234
529
  if (!m.ok) throw new Error(m.error.message);
235
530
  if (!s.ok) throw new Error(s.error.message);
236
531
  const view = s.value.namespaces.find((x) => x.ns === NS);
237
- if (!view) throw new Error("Verifier settings namespace is not registered. Restart the DSH host.");
532
+ if (!view) throw new Error(t["settings.nsUnregistered"]);
238
533
  const next = {
239
534
  groups: m.value.groups,
240
535
  settings: view,
@@ -286,16 +581,16 @@ window.__ModuleLoader__.load({
286
581
  children: [
287
582
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
288
583
  style: settingsHeading,
289
- children: "LLM Verifier"
584
+ children: t["settings.title"]
290
585
  }),
291
586
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
292
587
  style: settingsIntro,
293
- children: error ?? "正在读取 DSH 模型和设置…"
588
+ children: error ?? t["settings.loading"]
294
589
  }),
295
590
  error && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
296
591
  variant: "outline",
297
592
  onClick: () => void load(),
298
- children: "重试"
593
+ children: t["settings.retry"]
299
594
  }) })
300
595
  ]
301
596
  });
@@ -315,26 +610,26 @@ window.__ModuleLoader__.load({
315
610
  children: [
316
611
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
317
612
  style: settingsHeading,
318
- children: "LLM Verifier"
613
+ children: t["settings.title"]
319
614
  }),
320
615
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
321
616
  style: settingsIntro,
322
- children: "选择已在 DSH「模型」中配置的模型作为独立裁判。修改后点击页面底部的保存按钮生效。"
617
+ children: t["settings.intro"]
323
618
  }),
324
619
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
325
620
  style: group,
326
621
  children: [
327
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(GroupTitle, { children: "工具" }),
622
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(GroupTitle, { children: t["section.tools"] }),
328
623
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
329
624
  style: row,
330
625
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Label, {
331
- title: "启用 Verifier 工具",
332
- help: draft.enabled ? "允许 Agent 调用四个 verifier 工具并向裁判模型发起请求。" : "停用后,所有 verifier 工具都会立即返回错误。"
626
+ title: t["field.enabled.title"],
627
+ help: draft.enabled ? t["field.enabled.helpOn"] : t["field.enabled.helpOff"]
333
628
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
334
629
  type: "button",
335
630
  role: "switch",
336
631
  "aria-checked": draft.enabled,
337
- "aria-label": "启用 Verifier 工具",
632
+ "aria-label": t["field.enabled.title"],
338
633
  onClick: () => patch("enabled", !draft.enabled),
339
634
  style: toggleStyle(draft.enabled),
340
635
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { style: toggleThumbStyle(draft.enabled) })
@@ -347,19 +642,19 @@ window.__ModuleLoader__.load({
347
642
  lineHeight: "18px",
348
643
  color: "var(--dsw-alias-state-warn-label)"
349
644
  },
350
- children: "verifier_compare、verifier_select、verifier_track 和 verifier_current_session 当前不可用。"
645
+ children: t["field.enabled.warnDisabled"]
351
646
  })
352
647
  ]
353
648
  }),
354
649
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
355
650
  style: group,
356
651
  children: [
357
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(GroupTitle, { children: "自动验收" }),
652
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(GroupTitle, { children: t["section.autoVerify"] }),
358
653
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
359
654
  style: row,
360
655
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Label, {
361
- title: "调用策略",
362
- help: "手动仅暴露工具;智能在有结构化/高置信证据时路由四工具;严格还会主动执行语义路由并对任何关键操作做最终验收。"
656
+ title: t["field.autoVerifyMode.title"],
657
+ help: t["field.autoVerifyMode.help"]
363
658
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
364
659
  style: selectStyle,
365
660
  value: draft.autoVerifyMode,
@@ -367,15 +662,15 @@ window.__ModuleLoader__.load({
367
662
  children: [
368
663
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
369
664
  value: "manual",
370
- children: "手动"
665
+ children: t["field.autoVerifyMode.manual"]
371
666
  }),
372
667
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
373
668
  value: "smart",
374
- children: "智能(推荐)"
669
+ children: t["field.autoVerifyMode.smart"]
375
670
  }),
376
671
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
377
672
  value: "strict",
378
- children: "严格"
673
+ children: t["field.autoVerifyMode.strict"]
379
674
  })
380
675
  ]
381
676
  })]
@@ -383,13 +678,13 @@ window.__ModuleLoader__.load({
383
678
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
384
679
  style: row,
385
680
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Label, {
386
- title: "混合语义路由",
387
- help: "结构化候选或检查点不足时,由裁判模型保守识别真实的 compare/select/track 对象。智能模式仅在有候选线索时运行;严格模式每次结束边界都会检查。"
681
+ title: t["field.autoRouteSemantic.title"],
682
+ help: t["field.autoRouteSemantic.help"]
388
683
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
389
684
  type: "button",
390
685
  role: "switch",
391
686
  "aria-checked": draft.autoRouteSemantic,
392
- "aria-label": "混合语义路由",
687
+ "aria-label": t["field.autoRouteSemantic.title"],
393
688
  onClick: () => patch("autoRouteSemantic", !draft.autoRouteSemantic),
394
689
  style: toggleStyle(draft.autoRouteSemantic),
395
690
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { style: toggleThumbStyle(draft.autoRouteSemantic) })
@@ -398,106 +693,106 @@ window.__ModuleLoader__.load({
398
693
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
399
694
  style: row,
400
695
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Label, {
401
- title: "语义路由置信度",
402
- help: "语义识别达到该置信度才执行 compare/select/track;范围 0–1,建议保持 0.9。"
696
+ title: t["field.autoRouteMinConfidence.title"],
697
+ help: t["field.autoRouteMinConfidence.help"]
403
698
  }), numeric("autoRouteMinConfidence", 0)]
404
699
  }),
405
700
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
406
701
  style: row,
407
702
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Label, {
408
- title: "最多候选数",
409
- help: "一次自动 select 最多纳入的真实候选数量,至少 3。"
703
+ title: t["field.autoRouteMaxCandidates.title"],
704
+ help: t["field.autoRouteMaxCandidates.help"]
410
705
  }), numeric("autoRouteMaxCandidates", 3)]
411
706
  }),
412
707
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
413
708
  style: row,
414
709
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Label, {
415
- title: "每任务最多路由",
416
- help: "compare/select/track 自动路由的任务预算;指纹去重后仍受此上限约束。"
710
+ title: t["field.autoRouteMaxPerTask.title"],
711
+ help: t["field.autoRouteMaxPerTask.help"]
417
712
  }), numeric("autoRouteMaxPerTask", 1)]
418
713
  }),
419
714
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
420
715
  style: row,
421
716
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Label, {
422
- title: "每会话最多路由",
423
- help: "同一会话中 compare/select/track 自动路由总预算。"
717
+ title: t["field.autoRouteMaxPerSession.title"],
718
+ help: t["field.autoRouteMaxPerSession.help"]
424
719
  }), numeric("autoRouteMaxPerSession", 1)]
425
720
  }),
426
721
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
427
722
  style: row,
428
723
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Label, {
429
- title: "进度完成阈值",
430
- help: "track 任一检查点低于该值时 steering 要求 Agent 继续执行;范围 0–1。"
724
+ title: t["field.autoTrackCompletionThreshold.title"],
725
+ help: t["field.autoTrackCompletionThreshold.help"]
431
726
  }), numeric("autoTrackCompletionThreshold", 0)]
432
727
  }),
433
728
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
434
729
  style: row,
435
730
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Label, {
436
- title: "单项证据字符上限",
437
- help: "每个候选或检查点在脱敏后允许发送给裁判的最大字符数。"
731
+ title: t["field.autoRouteMaxItemChars.title"],
732
+ help: t["field.autoRouteMaxItemChars.help"]
438
733
  }), numeric("autoRouteMaxItemChars", 100)]
439
734
  }),
440
735
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
441
736
  style: row,
442
737
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Label, {
443
- title: "路由证据总字符上限",
444
- help: "一次 compare/select/track 所有候选或步骤的总字符预算。"
738
+ title: t["field.autoRouteMaxInputChars.title"],
739
+ help: t["field.autoRouteMaxInputChars.help"]
445
740
  }), numeric("autoRouteMaxInputChars", 1e3)]
446
741
  }),
447
742
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
448
743
  style: row,
449
744
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Label, {
450
- title: "每任务模型调用预算",
451
- help: "语义分类、中间路由和最终验收共享的估算模型调用上限。"
745
+ title: t["field.autoMaxModelCallsPerTask.title"],
746
+ help: t["field.autoMaxModelCallsPerTask.help"]
452
747
  }), numeric("autoMaxModelCallsPerTask", 1)]
453
748
  }),
454
749
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
455
750
  style: row,
456
751
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Label, {
457
- title: "每会话模型调用预算",
458
- help: "整个会话所有自动验证阶段共享的估算模型调用上限。"
752
+ title: t["field.autoMaxModelCallsPerSession.title"],
753
+ help: t["field.autoMaxModelCallsPerSession.help"]
459
754
  }), numeric("autoMaxModelCallsPerSession", 1)]
460
755
  }),
461
756
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
462
757
  style: row,
463
758
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Label, {
464
- title: "通过阈值",
465
- help: "会话证据分数达到该值且胜过空工作基线才允许结束;范围 0–1。"
759
+ title: t["field.autoVerifyThreshold.title"],
760
+ help: t["field.autoVerifyThreshold.help"]
466
761
  }), numeric("autoVerifyThreshold", 0)]
467
762
  }),
468
763
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
469
764
  style: row,
470
765
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Label, {
471
- title: "自动评估轮次",
472
- help: "每项标准的自动评分重复次数;1 为低成本初筛。"
766
+ title: t["field.autoVerifyRepeats.title"],
767
+ help: t["field.autoVerifyRepeats.help"]
473
768
  }), numeric("autoVerifyRepeats", 1)]
474
769
  }),
475
770
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
476
771
  style: row,
477
772
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Label, {
478
- title: "智能模式最少工具调用",
479
- help: "达到此工具证据数量且包含写入/执行类操作时才自动验收。"
773
+ title: t["field.autoVerifyMinToolCalls.title"],
774
+ help: t["field.autoVerifyMinToolCalls.help"]
480
775
  }), numeric("autoVerifyMinToolCalls", 1)]
481
776
  }),
482
777
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
483
778
  style: row,
484
779
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Label, {
485
- title: "最大证据字符",
486
- help: "发送给裁判前保留的最近会话证据字符数。"
780
+ title: t["field.autoVerifyMaxChars.title"],
781
+ help: t["field.autoVerifyMaxChars.help"]
487
782
  }), numeric("autoVerifyMaxChars", 1e3)]
488
783
  }),
489
784
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
490
785
  style: row,
491
786
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Label, {
492
- title: "每任务最多验收",
493
- help: "低分反馈后允许再次验收的次数上限,防止循环。"
787
+ title: t["field.autoVerifyMaxPerTask.title"],
788
+ help: t["field.autoVerifyMaxPerTask.help"]
494
789
  }), numeric("autoVerifyMaxPerTask", 1)]
495
790
  }),
496
791
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
497
792
  style: row,
498
793
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Label, {
499
- title: "每会话最多验收",
500
- help: "同一会话中的自动验收总预算。"
794
+ title: t["field.autoVerifyMaxPerSession.title"],
795
+ help: t["field.autoVerifyMaxPerSession.help"]
501
796
  }), numeric("autoVerifyMaxPerSession", 1)]
502
797
  }),
503
798
  draft.autoVerifyMode !== "manual" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
@@ -507,19 +802,19 @@ window.__ModuleLoader__.load({
507
802
  lineHeight: "18px",
508
803
  color: "var(--dsw-alias-state-warn-label)"
509
804
  },
510
- children: "自动路由按 select → compare → track → current_session 的阶段顺序处理;脱敏后的任务、Assistant 轨迹与真实工具输出会发送给所选裁判模型。候选选择或进度不足会 steering 继续工作,最终验收未通过会要求修复并重新验证。"
805
+ children: t["field.autoVerify.warnNotice"]
511
806
  })
512
807
  ]
513
808
  }),
514
809
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
515
810
  style: group,
516
811
  children: [
517
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(GroupTitle, { children: "裁判模型" }),
812
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(GroupTitle, { children: t["section.model"] }),
518
813
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
519
814
  style: row,
520
815
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Label, {
521
- title: "供应商",
522
- help: "当前 DSH 中可路由的模型供应商。"
816
+ title: t["field.provider.title"],
817
+ help: t["field.provider.help"]
523
818
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("select", {
524
819
  style: selectStyle,
525
820
  value: draft.provider,
@@ -548,8 +843,8 @@ window.__ModuleLoader__.load({
548
843
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
549
844
  style: row,
550
845
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Label, {
551
- title: "模型",
552
- help: "用作裁判的具体模型。"
846
+ title: t["field.model.title"],
847
+ help: t["field.model.help"]
553
848
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("select", {
554
849
  style: selectStyle,
555
850
  value: draft.model,
@@ -575,15 +870,15 @@ window.__ModuleLoader__.load({
575
870
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
576
871
  style: row,
577
872
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Label, {
578
- title: "推理强度",
579
- help: "留空时使用所选模型的默认值。"
873
+ title: t["field.reasoningEffort.title"],
874
+ help: t["field.reasoningEffort.help"]
580
875
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
581
876
  style: selectStyle,
582
877
  value: draft.reasoningEffort ?? "",
583
878
  onChange: (e) => patch("reasoningEffort", e.target.value || void 0),
584
879
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
585
880
  value: "",
586
- children: "模型默认"
881
+ children: t["field.reasoningEffort.default"]
587
882
  }), efforts.map((e) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
588
883
  value: e.id,
589
884
  children: e.name
@@ -593,8 +888,8 @@ window.__ModuleLoader__.load({
593
888
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
594
889
  style: row,
595
890
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Label, {
596
- title: "最大输出 Token",
597
- help: "单次裁判请求允许生成的最大 Token 数。"
891
+ title: t["field.maxTokens.title"],
892
+ help: t["field.maxTokens.help"]
598
893
  }), numeric("maxTokens", 1)]
599
894
  })
600
895
  ]
@@ -602,33 +897,33 @@ window.__ModuleLoader__.load({
602
897
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
603
898
  style: group,
604
899
  children: [
605
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(GroupTitle, { children: "执行" }),
900
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(GroupTitle, { children: t["section.execution"] }),
606
901
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
607
902
  style: row,
608
903
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Label, {
609
- title: "最大并发",
610
- help: "所有 verifier 工具共享的请求并发上限。"
904
+ title: t["field.maxConcurrency.title"],
905
+ help: t["field.maxConcurrency.help"]
611
906
  }), numeric("maxConcurrency", 1)]
612
907
  }),
613
908
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
614
909
  style: row,
615
910
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Label, {
616
- title: "最多重试",
617
- help: "限流、超时和短暂网络错误的重试次数。"
911
+ title: t["field.maxRetries.title"],
912
+ help: t["field.maxRetries.help"]
618
913
  }), numeric("maxRetries", 0)]
619
914
  }),
620
915
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
621
916
  style: row,
622
917
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Label, {
623
- title: "请求超时",
624
- help: "单次模型请求的超时时间,单位为毫秒。"
918
+ title: t["field.timeoutMs.title"],
919
+ help: t["field.timeoutMs.help"]
625
920
  }), numeric("timeoutMs", 1)]
626
921
  }),
627
922
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
628
923
  style: row,
629
924
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Label, {
630
- title: "缓存条目上限",
631
- help: "本地持久评分缓存保留的最大条目数。"
925
+ title: t["field.cacheMaxEntries.title"],
926
+ help: t["field.cacheMaxEntries.help"]
632
927
  }), numeric("cacheMaxEntries", 1)]
633
928
  })
634
929
  ]
@@ -636,19 +931,19 @@ window.__ModuleLoader__.load({
636
931
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
637
932
  style: group,
638
933
  children: [
639
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(GroupTitle, { children: "费用估算" }),
934
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(GroupTitle, { children: t["section.cost"] }),
640
935
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
641
936
  style: row,
642
937
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Label, {
643
- title: "输入价格",
644
- help: "每百万输入 Token 的美元价格,仅用于统计估算。"
938
+ title: t["field.estimatedInputUsdPerMillion.title"],
939
+ help: t["field.estimatedInputUsdPerMillion.help"]
645
940
  }), numeric("estimatedInputUsdPerMillion", 0)]
646
941
  }),
647
942
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
648
943
  style: row,
649
944
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Label, {
650
- title: "输出价格",
651
- help: "每百万输出 Token 的美元价格,仅用于统计估算。"
945
+ title: t["field.estimatedOutputUsdPerMillion.title"],
946
+ help: t["field.estimatedOutputUsdPerMillion.help"]
652
947
  }), numeric("estimatedOutputUsdPerMillion", 0)]
653
948
  })
654
949
  ]
@@ -667,7 +962,7 @@ window.__ModuleLoader__.load({
667
962
  fontWeight: 500,
668
963
  marginBottom: 3
669
964
  },
670
- children: "部分模型目录读取失败"
965
+ children: t["settings.catalogFailures"]
671
966
  }), loaded.failures.map((x) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { children: x }, x))]
672
967
  }),
673
968
  error && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
@@ -686,7 +981,7 @@ window.__ModuleLoader__.load({
686
981
  lineHeight: "18px",
687
982
  color: "var(--dsw-alias-state-success-primary)"
688
983
  },
689
- children: "设置已保存。"
984
+ children: t["settings.saved"]
690
985
  }),
691
986
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
692
987
  style: {
@@ -699,12 +994,12 @@ window.__ModuleLoader__.load({
699
994
  variant: "outline",
700
995
  disabled: busy,
701
996
  onClick: () => void load(),
702
- children: "重新载入"
997
+ children: t["settings.reload"]
703
998
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
704
999
  variant: "primary",
705
1000
  disabled: busy || !loaded.writable,
706
1001
  onClick: () => void save(),
707
- children: busy ? "保存中…" : "保存设置"
1002
+ children: busy ? t["settings.saving"] : t["settings.save"]
708
1003
  })]
709
1004
  })
710
1005
  ]
@@ -744,7 +1039,8 @@ window.__ModuleLoader__.load({
744
1039
  ]
745
1040
  });
746
1041
  }
747
- function TrendChart({ daily, days }) {
1042
+ function TrendChart({ daily, days, lang }) {
1043
+ const t = dictionaries[lang];
748
1044
  const rows = (0, react.useMemo)(() => {
749
1045
  const map = new Map(daily.map((row) => [row.date, row]));
750
1046
  const values = [];
@@ -796,7 +1092,7 @@ window.__ModuleLoader__.load({
796
1092
  minWidth: 620,
797
1093
  height: "auto"
798
1094
  },
799
- "aria-label": "每日工具调用与模型请求趋势",
1095
+ "aria-label": t["chart.ariaLabel"],
800
1096
  children: [
801
1097
  [
802
1098
  0,
@@ -862,18 +1158,21 @@ window.__ModuleLoader__.load({
862
1158
  borderRadius: 2,
863
1159
  background: "#4f8cff",
864
1160
  marginRight: 6
865
- } }), "工具调用"] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("i", { style: {
1161
+ } }), t["chart.legendToolCalls"]] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("i", { style: {
866
1162
  display: "inline-block",
867
1163
  width: 14,
868
1164
  height: 2,
869
1165
  background: "#5ed7e8",
870
1166
  marginRight: 6,
871
1167
  verticalAlign: "middle"
872
- } }), "模型请求"] })]
1168
+ } }), t["chart.legendModelCalls"]] })]
873
1169
  })]
874
1170
  });
875
1171
  }
876
1172
  function StatisticsPage({ sessionId, rpc }) {
1173
+ const lang = useLanguage();
1174
+ const t = dictionaries[lang];
1175
+ const labels = toolLabels[lang];
877
1176
  const [days, setDays] = (0, react.useState)(30);
878
1177
  const [sessionOnly, setSessionOnly] = (0, react.useState)(false);
879
1178
  const [data, setData] = (0, react.useState)(null);
@@ -891,7 +1190,7 @@ window.__ModuleLoader__.load({
891
1190
  recentLimit: 50,
892
1191
  ...sessionOnly ? { sessionId: String(sessionId) } : {}
893
1192
  }, controller.signal).then((result) => {
894
- if (!result.ok) throw new Error(result.error?.message ?? "统计接口请求失败");
1193
+ if (!result.ok) throw new Error(result.error?.message ?? t["stats.requestFailed"]);
895
1194
  setData(result.value);
896
1195
  }, (cause) => {
897
1196
  if (!controller.signal.aborted) throw cause;
@@ -906,7 +1205,8 @@ window.__ModuleLoader__.load({
906
1205
  sessionOnly,
907
1206
  sessionId,
908
1207
  refresh,
909
- rpc
1208
+ rpc,
1209
+ t
910
1210
  ]);
911
1211
  const totals = data?.totals;
912
1212
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("main", {
@@ -957,18 +1257,14 @@ window.__ModuleLoader__.load({
957
1257
  margin: 0,
958
1258
  fontSize: 23
959
1259
  },
960
- children: "Verifier 工具统计"
1260
+ children: t["stats.pageTitle"]
961
1261
  })]
962
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
1262
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
963
1263
  style: {
964
1264
  margin: "7px 0 0 44px",
965
1265
  ...muted
966
1266
  },
967
- children: [
968
- "数据更新于 ",
969
- data ? dateTime(data.generatedAt) : "--",
970
- " · 自动记录四个验证工具的实际执行结果"
971
- ]
1267
+ children: tFormat(t["stats.updatedAt"], { time: data ? dateTime(data.generatedAt, lang) : "--" })
972
1268
  })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
973
1269
  style: {
974
1270
  display: "flex",
@@ -989,7 +1285,7 @@ window.__ModuleLoader__.load({
989
1285
  7,
990
1286
  30,
991
1287
  90
992
- ].map((value) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
1288
+ ].map((value) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
993
1289
  onClick: () => setDays(value),
994
1290
  style: {
995
1291
  border: 0,
@@ -999,7 +1295,7 @@ window.__ModuleLoader__.load({
999
1295
  color: days === value ? "#fff" : "var(--dsw-text-secondary)",
1000
1296
  background: days === value ? "#3f68d8" : "transparent"
1001
1297
  },
1002
- children: [value, " 天"]
1298
+ children: tFormat(t["stats.daysUnit"], { days: value })
1003
1299
  }, value))
1004
1300
  }),
1005
1301
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
@@ -1012,10 +1308,10 @@ window.__ModuleLoader__.load({
1012
1308
  color: "var(--dsw-text-primary)",
1013
1309
  background: sessionOnly ? "rgba(79,140,255,.18)" : "var(--dsw-surface-sunken)"
1014
1310
  },
1015
- children: sessionOnly ? "当前会话" : "全部会话"
1311
+ children: sessionOnly ? t["stats.currentSession"] : t["stats.allSessions"]
1016
1312
  }),
1017
1313
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1018
- title: "刷新",
1314
+ title: t["stats.refresh"],
1019
1315
  onClick: () => setRefresh((value) => value + 1),
1020
1316
  style: {
1021
1317
  display: "grid",
@@ -1045,7 +1341,7 @@ window.__ModuleLoader__.load({
1045
1341
  ...muted,
1046
1342
  marginTop: 6
1047
1343
  },
1048
- children: "请确认宿主已重启并加载最新版本的 dsh-llm-verifier。"
1344
+ children: t["stats.hostRestartHint"]
1049
1345
  })]
1050
1346
  }),
1051
1347
  loading && !data ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
@@ -1055,7 +1351,7 @@ window.__ModuleLoader__.load({
1055
1351
  textAlign: "center",
1056
1352
  ...muted
1057
1353
  },
1058
- children: "正在读取工具运行统计…"
1354
+ children: t["stats.loading"]
1059
1355
  }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
1060
1356
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
1061
1357
  style: {
@@ -1067,9 +1363,9 @@ window.__ModuleLoader__.load({
1067
1363
  alignItems: "center"
1068
1364
  },
1069
1365
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [
1070
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1366
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1071
1367
  style: muted,
1072
- children: [days, " 天估算费用"]
1368
+ children: tFormat(t["stats.costSummary"], { days })
1073
1369
  }),
1074
1370
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1075
1371
  style: {
@@ -1080,14 +1376,12 @@ window.__ModuleLoader__.load({
1080
1376
  },
1081
1377
  children: money(totals?.estimatedCostUsd ?? 0)
1082
1378
  }),
1083
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1379
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1084
1380
  style: muted,
1085
- children: [
1086
- compact(totals?.invocations ?? 0),
1087
- " 次工具调用 · ",
1088
- compact(totals?.calls ?? 0),
1089
- " 次裁判模型请求"
1090
- ]
1381
+ children: tFormat(t["stats.callsSummary"], {
1382
+ invocations: compact(totals?.invocations ?? 0, lang),
1383
+ calls: compact(totals?.calls ?? 0, lang)
1384
+ })
1091
1385
  })
1092
1386
  ] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1093
1387
  style: {
@@ -1099,10 +1393,10 @@ window.__ModuleLoader__.load({
1099
1393
  children: [
1100
1394
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1101
1395
  style: muted,
1102
- children: "成功调用"
1396
+ children: t["stats.successCalls"]
1103
1397
  }),
1104
1398
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("strong", { children: [
1105
- compact(totals?.successes ?? 0),
1399
+ compact(totals?.successes ?? 0, lang),
1106
1400
  " ",
1107
1401
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("small", {
1108
1402
  style: { color: "#77d49b" },
@@ -1115,12 +1409,12 @@ window.__ModuleLoader__.load({
1115
1409
  ] }),
1116
1410
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1117
1411
  style: muted,
1118
- children: "失败调用"
1412
+ children: t["stats.failedCalls"]
1119
1413
  }),
1120
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: compact(totals?.failures ?? 0) }),
1414
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: compact(totals?.failures ?? 0, lang) }),
1121
1415
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1122
1416
  style: muted,
1123
- children: "平均耗时"
1417
+ children: t["stats.avgDuration"]
1124
1418
  }),
1125
1419
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: duration(totals?.averageDurationMs ?? 0) })
1126
1420
  ]
@@ -1134,25 +1428,34 @@ window.__ModuleLoader__.load({
1134
1428
  },
1135
1429
  children: [
1136
1430
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Metric, {
1137
- label: "缓存命中率",
1431
+ label: t["metric.cacheHitRate"],
1138
1432
  value: ((totals?.cacheHitRate ?? 0) * 100).toFixed(1) + "%",
1139
- note: `${compact(totals?.cacheHits ?? 0)} 命中 / ${compact((totals?.cacheHits ?? 0) + (totals?.cacheMisses ?? 0))} 评分`,
1433
+ note: tFormat(t["metric.cacheHitNote"], {
1434
+ hits: compact(totals?.cacheHits ?? 0, lang),
1435
+ total: compact((totals?.cacheHits ?? 0) + (totals?.cacheMisses ?? 0), lang)
1436
+ }),
1140
1437
  accent: "#b7dd64"
1141
1438
  }),
1142
1439
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Metric, {
1143
- label: "Token",
1144
- value: compact(totals?.tokens ?? 0),
1145
- note: `输入 ${compact((totals?.inputTokens ?? 0) + (totals?.cachedInputTokens ?? 0))} · 输出 ${compact(totals?.outputTokens ?? 0)}`
1440
+ label: t["metric.tokens"],
1441
+ value: compact(totals?.tokens ?? 0, lang),
1442
+ note: tFormat(t["metric.tokensNote"], {
1443
+ input: compact((totals?.inputTokens ?? 0) + (totals?.cachedInputTokens ?? 0), lang),
1444
+ output: compact(totals?.outputTokens ?? 0, lang)
1445
+ })
1146
1446
  }),
1147
1447
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Metric, {
1148
- label: "平均模型请求",
1448
+ label: t["metric.avgModelCalls"],
1149
1449
  value: (totals?.invocations ?? 0) > 0 ? ((totals?.calls ?? 0) / (totals?.invocations ?? 1)).toFixed(1) : "0",
1150
- note: `${compact(totals?.attempts ?? 0)} 次尝试 · ${compact(totals?.retries ?? 0)} 次重试`
1450
+ note: tFormat(t["metric.avgModelCallsNote"], {
1451
+ attempts: compact(totals?.attempts ?? 0, lang),
1452
+ retries: compact(totals?.retries ?? 0, lang)
1453
+ })
1151
1454
  }),
1152
1455
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Metric, {
1153
- label: "评分模式",
1154
- value: compact(totals?.topLogprobScores ?? 0),
1155
- note: `Top-logprobs · 显式标签 ${compact(totals?.explicitTagScores ?? 0)}`
1456
+ label: t["metric.scoringMode"],
1457
+ value: compact(totals?.topLogprobScores ?? 0, lang),
1458
+ note: tFormat(t["metric.scoringModeNote"], { explicit: compact(totals?.explicitTagScores ?? 0, lang) })
1156
1459
  })
1157
1460
  ]
1158
1461
  }),
@@ -1168,13 +1471,14 @@ window.__ModuleLoader__.load({
1168
1471
  alignItems: "center",
1169
1472
  marginBottom: 4
1170
1473
  },
1171
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: "每日工具调用与模型请求趋势" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1474
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t["chart.title"] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1172
1475
  style: muted,
1173
- children: sessionOnly ? "当前会话" : "全部会话"
1476
+ children: sessionOnly ? t["stats.currentSession"] : t["stats.allSessions"]
1174
1477
  })]
1175
1478
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TrendChart, {
1176
1479
  daily: data?.daily ?? [],
1177
- days
1480
+ days,
1481
+ lang
1178
1482
  })]
1179
1483
  }),
1180
1484
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
@@ -1189,9 +1493,9 @@ window.__ModuleLoader__.load({
1189
1493
  justifyContent: "space-between",
1190
1494
  margin: "0 2px 12px"
1191
1495
  },
1192
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: "工具运行明细" }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1496
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t["table.title"] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1193
1497
  style: muted,
1194
- children: [data?.tools.length ?? 0, " 类工具"]
1498
+ children: tFormat(t["table.toolCount"], { count: data?.tools.length ?? 0 })
1195
1499
  })]
1196
1500
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1197
1501
  style: { overflowX: "auto" },
@@ -1209,14 +1513,14 @@ window.__ModuleLoader__.load({
1209
1513
  background: "var(--dsw-surface-sunken)"
1210
1514
  },
1211
1515
  children: [
1212
- "工具",
1213
- "调用",
1214
- "成功率",
1215
- "平均耗时",
1216
- "模型请求",
1217
- "Token",
1218
- "缓存命中",
1219
- "估算费用"
1516
+ t["table.colTool"],
1517
+ t["table.colInvocations"],
1518
+ t["table.colSuccessRate"],
1519
+ t["table.colAvgDuration"],
1520
+ t["table.colModelCalls"],
1521
+ t["table.colTokens"],
1522
+ t["table.colCacheHits"],
1523
+ t["table.colEstimatedCost"]
1220
1524
  ].map((value) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
1221
1525
  style: {
1222
1526
  padding: "10px 12px",
@@ -1238,7 +1542,7 @@ window.__ModuleLoader__.load({
1238
1542
  background: toolColors[tool.toolName] ?? "#8691a8",
1239
1543
  marginRight: 8
1240
1544
  } }),
1241
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: toolLabels[tool.toolName] ?? tool.toolName }),
1545
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: labels[tool.toolName] ?? tool.toolName }),
1242
1546
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1243
1547
  style: {
1244
1548
  ...muted,
@@ -1250,7 +1554,7 @@ window.__ModuleLoader__.load({
1250
1554
  }),
1251
1555
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
1252
1556
  style: { padding: "13px 12px" },
1253
- children: compact(tool.invocations)
1557
+ children: compact(tool.invocations, lang)
1254
1558
  }),
1255
1559
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("td", {
1256
1560
  style: {
@@ -1265,11 +1569,11 @@ window.__ModuleLoader__.load({
1265
1569
  }),
1266
1570
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
1267
1571
  style: { padding: "13px 12px" },
1268
- children: compact(tool.calls)
1572
+ children: compact(tool.calls, lang)
1269
1573
  }),
1270
1574
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
1271
1575
  style: { padding: "13px 12px" },
1272
- children: compact(tool.tokens)
1576
+ children: compact(tool.tokens, lang)
1273
1577
  }),
1274
1578
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("td", {
1275
1579
  style: { padding: "13px 12px" },
@@ -1291,7 +1595,7 @@ window.__ModuleLoader__.load({
1291
1595
  textAlign: "center",
1292
1596
  ...muted
1293
1597
  },
1294
- children: "所选范围内还没有 Verifier 工具调用。后续执行会自动出现在这里。"
1598
+ children: t["table.empty"]
1295
1599
  }) })] })]
1296
1600
  })
1297
1601
  })]
@@ -1315,9 +1619,9 @@ window.__ModuleLoader__.load({
1315
1619
  justifyContent: "space-between",
1316
1620
  margin: "0 2px 12px"
1317
1621
  },
1318
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: "最近调用" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1622
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t["recent.title"] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1319
1623
  style: muted,
1320
- children: "最多 50 条"
1624
+ children: t["recent.maxCount"]
1321
1625
  })]
1322
1626
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1323
1627
  style: {
@@ -1347,7 +1651,7 @@ window.__ModuleLoader__.load({
1347
1651
  } }),
1348
1652
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", {
1349
1653
  style: { fontSize: 13 },
1350
- children: toolLabels[item.toolName] ?? item.toolName
1654
+ children: labels[item.toolName] ?? item.toolName
1351
1655
  }),
1352
1656
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1353
1657
  style: muted,
@@ -1379,7 +1683,7 @@ window.__ModuleLoader__.load({
1379
1683
  ...muted,
1380
1684
  marginTop: 3
1381
1685
  },
1382
- children: dateTime(item.startedAt)
1686
+ children: dateTime(item.startedAt, lang)
1383
1687
  })]
1384
1688
  })]
1385
1689
  }, item.id)), (data?.recent.length ?? 0) === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
@@ -1388,7 +1692,7 @@ window.__ModuleLoader__.load({
1388
1692
  textAlign: "center",
1389
1693
  ...muted
1390
1694
  },
1391
- children: "暂无记录"
1695
+ children: t["recent.empty"]
1392
1696
  })]
1393
1697
  })]
1394
1698
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -1396,7 +1700,7 @@ window.__ModuleLoader__.load({
1396
1700
  ...dashboardCard,
1397
1701
  padding: "18px"
1398
1702
  },
1399
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: "模型汇总" }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1703
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t["models.title"] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1400
1704
  style: {
1401
1705
  marginTop: 10,
1402
1706
  display: "flex",
@@ -1434,15 +1738,15 @@ window.__ModuleLoader__.load({
1434
1738
  fontSize: 12
1435
1739
  },
1436
1740
  children: [
1437
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [compact(model.calls), " 请求"] }),
1438
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [compact(model.tokens), " Token"] }),
1741
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: tFormat(t["models.calls"], { calls: compact(model.calls, lang) }) }),
1742
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: tFormat(t["models.tokens"], { tokens: compact(model.tokens, lang) }) }),
1439
1743
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: money(model.estimatedCostUsd) })
1440
1744
  ]
1441
1745
  })
1442
1746
  ]
1443
1747
  }, model.provider + "\0" + model.model)), (data?.models.length ?? 0) === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1444
1748
  style: muted,
1445
- children: "暂无模型调用"
1749
+ children: t["models.empty"]
1446
1750
  })]
1447
1751
  })]
1448
1752
  })]
@@ -1473,13 +1777,26 @@ window.__ModuleLoader__.load({
1473
1777
  name: "conversation.view",
1474
1778
  id: "llm-verifier-statistics",
1475
1779
  order: 30,
1476
- label: "工具统计",
1780
+ label: detectLanguage() === "zh" ? zh["slot.statistics"] : en["slot.statistics"],
1477
1781
  inject: () => ({ rpc: connection.rpc })
1478
1782
  }, StatisticsPage));
1479
1783
  }
1480
1784
  //#endregion
1785
+ exports.StatisticsPage = StatisticsPage;
1786
+ exports.VerifierSettings = VerifierSettings;
1481
1787
  exports.apply = apply;
1788
+ exports.compact = compact;
1789
+ exports.dateTime = dateTime;
1790
+ exports.detectLanguage = detectLanguage;
1791
+ exports.dictionaries = dictionaries;
1792
+ exports.duration = duration;
1793
+ exports.en = en;
1482
1794
  exports.inject = inject;
1795
+ exports.money = money;
1796
+ exports.tFormat = tFormat;
1797
+ exports.toolLabels = toolLabels;
1798
+ exports.useLanguage = useLanguage;
1799
+ exports.zh = zh;
1483
1800
  return module.exports;
1484
1801
  }
1485
1802
  });