dsh-llm-verifier 0.1.13 → 0.1.14

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.
Files changed (50) hide show
  1. package/LICENSE +22 -22
  2. package/README.md +301 -301
  3. package/cordis.patch.yml +4 -4
  4. package/lib/client.js +176 -14
  5. package/lib/index.js +418 -43
  6. package/lib/types/client-i18n.d.ts +27 -0
  7. package/lib/types/client-i18n.js +18 -0
  8. package/lib/types/client.d.ts +15 -2
  9. package/lib/types/client.js +134 -9
  10. package/lib/types/config.d.ts +4 -0
  11. package/lib/types/config.js +5 -3
  12. package/lib/types/index.d.ts +2 -0
  13. package/lib/types/index.js +185 -4
  14. package/lib/types/plan-gate.d.ts +14 -0
  15. package/lib/types/plan-gate.js +70 -0
  16. package/lib/types/router.d.ts +10 -1
  17. package/lib/types/router.js +37 -7
  18. package/lib/types/session.js +25 -10
  19. package/lib/types/team-gate.d.ts +11 -0
  20. package/lib/types/team-gate.js +51 -0
  21. package/package.json +112 -112
  22. package/src/auto.test.ts +86 -86
  23. package/src/auto.ts +133 -133
  24. package/src/cache.ts +115 -115
  25. package/src/caller.test.ts +34 -34
  26. package/src/caller.ts +151 -151
  27. package/src/client-i18n.ts +18 -0
  28. package/src/client.tsx +385 -213
  29. package/src/config.ts +189 -183
  30. package/src/core.test.ts +71 -71
  31. package/src/core.ts +205 -205
  32. package/src/engine.test.ts +136 -136
  33. package/src/engine.ts +140 -140
  34. package/src/images.ts +33 -33
  35. package/src/index.ts +416 -247
  36. package/src/parity.test.ts +85 -85
  37. package/src/plan-gate.test.ts +56 -0
  38. package/src/plan-gate.ts +77 -0
  39. package/src/router.test.ts +107 -89
  40. package/src/router.ts +349 -309
  41. package/src/session.test.ts +53 -36
  42. package/src/session.ts +117 -103
  43. package/src/statistics.test.ts +80 -80
  44. package/src/statistics.ts +328 -328
  45. package/src/team-gate.test.ts +56 -0
  46. package/src/team-gate.ts +63 -0
  47. package/src/top-logprobs.test.ts +84 -84
  48. package/src/top-logprobs.ts +153 -153
  49. package/src/topic-storage.test.ts +31 -31
  50. package/src/topic-storage.ts +42 -42
package/lib/client.js CHANGED
@@ -131,7 +131,16 @@ window.__ModuleLoader__.load({
131
131
  "models.calls": "{calls} 请求",
132
132
  "models.tokens": "{tokens} Token",
133
133
  "models.empty": "暂无模型调用",
134
- "slot.statistics": "工具统计"
134
+ "slot.statistics": "工具统计",
135
+ "slot.globalDashboard": "Verifier 看板",
136
+ "global.panelTitle": "LLM Verifier 全局监控中心",
137
+ "global.panelIntro": "跨会话全局统计、裁判模型效能大盘与任务验收总览。",
138
+ "guide.verifier.title": "Verifier 统计",
139
+ "guide.verifier.desc": "大模型复核工具调用、耗时与成本统计",
140
+ "field.autoVerifyTeamTasks.title": "自动验收 Team 任务",
141
+ "field.autoVerifyTeamTasks.help": "当 Agent Teams 中的任务状态变更或进入完成状态时,自动路由进度追踪与任务验收。",
142
+ "field.autoVerifyPlanMode.title": "计划模式自动预审",
143
+ "field.autoVerifyPlanMode.help": "在 Agent 调用 exit_plan_mode 提交计划交付人类评审前,自动对计划完整度与风险进行独立预审。"
135
144
  };
136
145
  const en = {
137
146
  "settings.title": "LLM Verifier",
@@ -256,7 +265,16 @@ window.__ModuleLoader__.load({
256
265
  "models.calls": "{calls} Requests",
257
266
  "models.tokens": "{tokens} Tokens",
258
267
  "models.empty": "No model calls",
259
- "slot.statistics": "Statistics"
268
+ "slot.statistics": "Statistics",
269
+ "slot.globalDashboard": "Verifier Dashboard",
270
+ "global.panelTitle": "LLM Verifier Global Dashboard",
271
+ "global.panelIntro": "Cross-session statistics, judge model metrics, and task acceptance overview.",
272
+ "guide.verifier.title": "Verifier Stats",
273
+ "guide.verifier.desc": "LLM verifier tool calls, duration and cost statistics",
274
+ "field.autoVerifyTeamTasks.title": "Verify Team Tasks",
275
+ "field.autoVerifyTeamTasks.help": "Automatically route progress and verify tasks when Agent Teams task status changes or completes.",
276
+ "field.autoVerifyPlanMode.title": "Plan Mode Pre-verification",
277
+ "field.autoVerifyPlanMode.help": "Automatically pre-verify plan feasibility and risks before exit_plan_mode presents it for user review."
260
278
  };
261
279
  const dictionaries = {
262
280
  zh,
@@ -690,6 +708,36 @@ window.__ModuleLoader__.load({
690
708
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { style: toggleThumbStyle(draft.autoRouteSemantic) })
691
709
  })]
692
710
  }),
711
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
712
+ style: row,
713
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Label, {
714
+ title: t["field.autoVerifyTeamTasks.title"],
715
+ help: t["field.autoVerifyTeamTasks.help"]
716
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
717
+ type: "button",
718
+ role: "switch",
719
+ "aria-checked": draft.autoVerifyTeamTasks ?? true,
720
+ "aria-label": t["field.autoVerifyTeamTasks.title"],
721
+ onClick: () => patch("autoVerifyTeamTasks", !(draft.autoVerifyTeamTasks ?? true)),
722
+ style: toggleStyle(draft.autoVerifyTeamTasks ?? true),
723
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { style: toggleThumbStyle(draft.autoVerifyTeamTasks ?? true) })
724
+ })]
725
+ }),
726
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
727
+ style: row,
728
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Label, {
729
+ title: t["field.autoVerifyPlanMode.title"],
730
+ help: t["field.autoVerifyPlanMode.help"]
731
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
732
+ type: "button",
733
+ role: "switch",
734
+ "aria-checked": draft.autoVerifyPlanMode ?? true,
735
+ "aria-label": t["field.autoVerifyPlanMode.title"],
736
+ onClick: () => patch("autoVerifyPlanMode", !(draft.autoVerifyPlanMode ?? true)),
737
+ style: toggleStyle(draft.autoVerifyPlanMode ?? true),
738
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { style: toggleThumbStyle(draft.autoVerifyPlanMode ?? true) })
739
+ })]
740
+ }),
693
741
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
694
742
  style: row,
695
743
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Label, {
@@ -1169,12 +1217,12 @@ window.__ModuleLoader__.load({
1169
1217
  })]
1170
1218
  });
1171
1219
  }
1172
- function StatisticsPage({ sessionId, rpc }) {
1220
+ function StatisticsPage({ sessionId, rpc, isGlobal }) {
1173
1221
  const lang = useLanguage();
1174
1222
  const t = dictionaries[lang];
1175
1223
  const labels = toolLabels[lang];
1176
1224
  const [days, setDays] = (0, react.useState)(30);
1177
- const [sessionOnly, setSessionOnly] = (0, react.useState)(false);
1225
+ const [sessionOnly, setSessionOnly] = (0, react.useState)(!isGlobal && Boolean(sessionId));
1178
1226
  const [data, setData] = (0, react.useState)(null);
1179
1227
  const [loading, setLoading] = (0, react.useState)(true);
1180
1228
  const [error, setError] = (0, react.useState)(null);
@@ -1183,17 +1231,37 @@ window.__ModuleLoader__.load({
1183
1231
  const controller = new AbortController();
1184
1232
  setLoading(true);
1185
1233
  setError(null);
1186
- rpc.call("/llm-verifier", "statistics", {
1234
+ const effectiveSessionId = sessionOnly && sessionId ? String(sessionId) : void 0;
1235
+ const queryPayload = {
1187
1236
  fromMs: startOfRange(days),
1188
1237
  toMs: endOfToday(),
1189
1238
  timezoneOffsetMinutes: (/* @__PURE__ */ new Date()).getTimezoneOffset(),
1190
1239
  recentLimit: 50,
1191
- ...sessionOnly ? { sessionId: String(sessionId) } : {}
1192
- }, controller.signal).then((result) => {
1193
- if (!result.ok) throw new Error(result.error?.message ?? t["stats.requestFailed"]);
1194
- setData(result.value);
1195
- }, (cause) => {
1196
- if (!controller.signal.aborted) throw cause;
1240
+ ...effectiveSessionId ? { sessionId: effectiveSessionId } : {}
1241
+ };
1242
+ const fetchOverview = async () => {
1243
+ if (rpc && typeof rpc.call === "function") try {
1244
+ const result = await rpc.call("/api", "llm-verifier/statistics", queryPayload, controller.signal);
1245
+ if (result && result.ok) return result.value;
1246
+ if (result && result.ok === false) throw new Error(result.error?.message ?? t["stats.requestFailed"]);
1247
+ } catch (rpcError) {
1248
+ if (controller.signal.aborted) throw rpcError;
1249
+ console.warn("[llm-verifier] rpc.call failed, trying fetch fallback:", rpcError);
1250
+ }
1251
+ const response = await fetch("/api/llm-verifier/statistics", {
1252
+ method: "POST",
1253
+ headers: { "content-type": "application/json" },
1254
+ body: JSON.stringify(queryPayload),
1255
+ signal: controller.signal
1256
+ });
1257
+ if (!response.ok) throw new Error(`HTTP ${response.status}: ${response.statusText || t["stats.requestFailed"]}`);
1258
+ const data = await response.json();
1259
+ if (data && data.ok === true) return data.value;
1260
+ if (data && data.type === "server-response" && data.result?.ok === true) return data.result.value;
1261
+ throw new Error(data?.error?.message ?? data?.result?.error?.message ?? t["stats.requestFailed"]);
1262
+ };
1263
+ fetchOverview().then((overview) => {
1264
+ setData(overview);
1197
1265
  }).catch((cause) => {
1198
1266
  if (!controller.signal.aborted) setError(message(cause));
1199
1267
  }).finally(() => {
@@ -1257,14 +1325,14 @@ window.__ModuleLoader__.load({
1257
1325
  margin: 0,
1258
1326
  fontSize: 23
1259
1327
  },
1260
- children: t["stats.pageTitle"]
1328
+ children: isGlobal ? t["global.panelTitle"] : t["stats.pageTitle"]
1261
1329
  })]
1262
1330
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1263
1331
  style: {
1264
1332
  margin: "7px 0 0 44px",
1265
1333
  ...muted
1266
1334
  },
1267
- children: tFormat(t["stats.updatedAt"], { time: data ? dateTime(data.generatedAt, lang) : "--" })
1335
+ children: isGlobal ? t["global.panelIntro"] : tFormat(t["stats.updatedAt"], { time: data ? dateTime(data.generatedAt, lang) : "--" })
1268
1336
  })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1269
1337
  style: {
1270
1338
  display: "flex",
@@ -1298,7 +1366,7 @@ window.__ModuleLoader__.load({
1298
1366
  children: tFormat(t["stats.daysUnit"], { days: value })
1299
1367
  }, value))
1300
1368
  }),
1301
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1369
+ Boolean(sessionId) && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1302
1370
  onClick: () => setSessionOnly((value) => !value),
1303
1371
  style: {
1304
1372
  border: "1px solid var(--dsw-alias-border-l2, rgba(255,255,255,.15))",
@@ -1756,6 +1824,49 @@ window.__ModuleLoader__.load({
1756
1824
  })
1757
1825
  });
1758
1826
  }
1827
+ function VerifierSidebarIcon({ size, active }) {
1828
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1829
+ style: {
1830
+ display: "inline-flex",
1831
+ alignItems: "center",
1832
+ justifyContent: "center",
1833
+ width: size,
1834
+ height: size,
1835
+ color: active ? "var(--dsw-alias-brand-primary, #4f8cff)" : "currentColor"
1836
+ },
1837
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconDataOutline16, { size: Math.min(18, size) })
1838
+ });
1839
+ }
1840
+ function GlobalVerifierDashboard({ rpc }) {
1841
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(StatisticsPage, {
1842
+ rpc,
1843
+ isGlobal: true
1844
+ });
1845
+ }
1846
+ function RightSidebarVerifierPanel({ rpc, sessionId }) {
1847
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1848
+ style: {
1849
+ height: "100%",
1850
+ overflow: "hidden",
1851
+ display: "flex",
1852
+ flexDirection: "column"
1853
+ },
1854
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(StatisticsPage, {
1855
+ rpc,
1856
+ sessionId
1857
+ })
1858
+ });
1859
+ }
1860
+ function RightSidebarVerifierTitle() {
1861
+ const t = dictionaries[useLanguage()];
1862
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1863
+ style: {
1864
+ fontSize: 13,
1865
+ fontWeight: 500
1866
+ },
1867
+ children: t["slot.statistics"]
1868
+ });
1869
+ }
1759
1870
  const inject = [
1760
1871
  "slots",
1761
1872
  "connection",
@@ -1780,10 +1891,61 @@ window.__ModuleLoader__.load({
1780
1891
  label: detectLanguage() === "zh" ? zh["slot.statistics"] : en["slot.statistics"],
1781
1892
  inject: () => ({ rpc: connection.rpc })
1782
1893
  }, StatisticsPage));
1894
+ ctx.slots.inject("sidebar.panellist", () => ctx.slots.register({
1895
+ name: "sidebar.panellist",
1896
+ id: "llm-verifier",
1897
+ order: 40,
1898
+ label: detectLanguage() === "zh" ? zh["slot.globalDashboard"] : en["slot.globalDashboard"]
1899
+ }, VerifierSidebarIcon));
1900
+ ctx.slots.inject("main", () => ctx.slots.register({
1901
+ name: "main",
1902
+ key: "llm-verifier",
1903
+ inject: () => ({ rpc: connection.rpc })
1904
+ }, GlobalVerifierDashboard));
1905
+ const VERIFIER_TAB_KIND = "llm-verifier";
1906
+ const VERIFIER_TAB_ID = "dsh-llm-verifier";
1907
+ const registerRightSidebar = (tabs) => {
1908
+ if (!tabs || typeof tabs.register !== "function") return;
1909
+ try {
1910
+ tabs.register({
1911
+ id: VERIFIER_TAB_ID,
1912
+ kind: VERIFIER_TAB_KIND,
1913
+ priority: "extension",
1914
+ title: () => detectLanguage() === "zh" ? zh["slot.statistics"] : en["slot.statistics"],
1915
+ guide: [{
1916
+ order: 45,
1917
+ title: () => detectLanguage() === "zh" ? zh["guide.verifier.title"] : en["guide.verifier.title"],
1918
+ description: () => detectLanguage() === "zh" ? zh["guide.verifier.desc"] : en["guide.verifier.desc"],
1919
+ icon: VerifierSidebarIcon
1920
+ }]
1921
+ });
1922
+ } catch {}
1923
+ };
1924
+ const existingTabs = typeof ctx.get === "function" ? ctx.get("sidebarRightTabs") : void 0;
1925
+ if (existingTabs) registerRightSidebar(existingTabs);
1926
+ if (typeof ctx.inject === "function") try {
1927
+ ctx.inject(["sidebarRightTabs"], (subCtx) => {
1928
+ const subTabs = typeof subCtx?.get === "function" ? subCtx.get("sidebarRightTabs") : subCtx?.sidebarRightTabs;
1929
+ if (subTabs) registerRightSidebar(subTabs);
1930
+ });
1931
+ } catch {}
1932
+ ctx.slots.inject("sidebar.right.pane.tab", () => ctx.slots.register({
1933
+ name: "sidebar.right.pane.tab",
1934
+ key: VERIFIER_TAB_ID,
1935
+ inject: () => ({ rpc: connection.rpc })
1936
+ }, RightSidebarVerifierPanel));
1937
+ ctx.slots.inject("sidebar.right.pane.tab.title", () => ctx.slots.register({
1938
+ name: "sidebar.right.pane.tab.title",
1939
+ key: VERIFIER_TAB_ID
1940
+ }, RightSidebarVerifierTitle));
1783
1941
  }
1784
1942
  //#endregion
1943
+ exports.GlobalVerifierDashboard = GlobalVerifierDashboard;
1944
+ exports.RightSidebarVerifierPanel = RightSidebarVerifierPanel;
1945
+ exports.RightSidebarVerifierTitle = RightSidebarVerifierTitle;
1785
1946
  exports.StatisticsPage = StatisticsPage;
1786
1947
  exports.VerifierSettings = VerifierSettings;
1948
+ exports.VerifierSidebarIcon = VerifierSidebarIcon;
1787
1949
  exports.apply = apply;
1788
1950
  exports.compact = compact;
1789
1951
  exports.dateTime = dateTime;