niceeval 0.13.1 → 0.13.2-canary.35

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 (134) hide show
  1. package/INDEX.md +1 -0
  2. package/README.md +9 -10
  3. package/README.zh.md +9 -10
  4. package/dist/agents/ai-sdk.cjs.map +1 -1
  5. package/dist/agents/ai-sdk.d.cts +1 -1
  6. package/dist/agents/ai-sdk.d.mts +1 -1
  7. package/dist/agents/ai-sdk.d.ts +1 -1
  8. package/dist/agents/coding-cli-versions.cjs +10 -1
  9. package/dist/agents/coding-cli-versions.cjs.map +1 -1
  10. package/dist/agents/coding-cli-versions.d.cts +8 -3
  11. package/dist/agents/coding-cli-versions.d.mts +8 -3
  12. package/dist/agents/coding-cli-versions.d.ts +8 -3
  13. package/dist/agents/coding-cli-versions.js +18 -12
  14. package/dist/agents/deepseek-harness.cjs +103 -0
  15. package/dist/agents/deepseek-harness.cjs.map +1 -0
  16. package/dist/agents/deepseek-harness.d.cts +12 -0
  17. package/dist/agents/deepseek-harness.d.mts +12 -0
  18. package/dist/agents/deepseek-harness.d.ts +12 -0
  19. package/dist/agents/deepseek-harness.js +7 -0
  20. package/dist/agents/deepseek-harness.js.map +1 -0
  21. package/dist/agents/index.cjs +5 -1
  22. package/dist/agents/index.cjs.map +1 -1
  23. package/dist/agents/index.d.cts +4 -0
  24. package/dist/agents/index.d.mts +4 -0
  25. package/dist/agents/index.d.ts +4 -0
  26. package/dist/agents/index.js +54 -50
  27. package/dist/agents/index.mjs +54 -50
  28. package/dist/agents/omp.cjs +170 -0
  29. package/dist/agents/omp.cjs.map +1 -0
  30. package/dist/agents/omp.d.cts +14 -0
  31. package/dist/agents/omp.d.mts +14 -0
  32. package/dist/agents/omp.d.ts +14 -0
  33. package/dist/agents/omp.js +7 -0
  34. package/dist/agents/omp.js.map +1 -0
  35. package/dist/agents/types.cjs.map +1 -1
  36. package/dist/agents/types.d.cts +2 -2
  37. package/dist/agents/types.d.mts +2 -2
  38. package/dist/agents/types.d.ts +2 -2
  39. package/dist/analysis/api.cjs +9 -1
  40. package/dist/analysis/api.cjs.map +1 -1
  41. package/dist/analysis/api.d.cts +21 -0
  42. package/dist/analysis/api.d.mts +21 -0
  43. package/dist/analysis/api.d.ts +21 -0
  44. package/dist/analysis/api.js +8 -6
  45. package/dist/i18n/en.cjs +7 -2
  46. package/dist/i18n/en.cjs.map +1 -1
  47. package/dist/i18n/en.d.cts +7 -2
  48. package/dist/i18n/en.d.mts +7 -2
  49. package/dist/i18n/en.d.ts +7 -2
  50. package/dist/o11y/parsers/hermes.cjs +1 -1
  51. package/dist/o11y/parsers/hermes.cjs.map +1 -1
  52. package/dist/report/built-in/analysis-values.cjs +21 -5
  53. package/dist/report/built-in/analysis-values.cjs.map +1 -1
  54. package/dist/report/built-in/analysis-values.d.cts +11 -9
  55. package/dist/report/built-in/analysis-values.d.mts +11 -9
  56. package/dist/report/built-in/analysis-values.d.ts +11 -9
  57. package/dist/report/built-in/overview.cjs +1 -0
  58. package/dist/report/built-in/overview.cjs.map +1 -1
  59. package/dist/report/built-in/result-components.cjs +58 -12
  60. package/dist/report/built-in/result-components.cjs.map +1 -1
  61. package/dist/report/built-in/result-components.d.cts +15 -0
  62. package/dist/report/built-in/result-components.d.mts +15 -0
  63. package/dist/report/built-in/result-components.d.ts +15 -0
  64. package/dist/report/built-in/run-membership-overview.cjs +100 -4
  65. package/dist/report/built-in/run-membership-overview.cjs.map +1 -1
  66. package/dist/report/built-in/standard.cjs +1 -0
  67. package/dist/report/built-in/standard.cjs.map +1 -1
  68. package/dist/report/built-in/standard.d.cts +1 -0
  69. package/dist/report/built-in/standard.d.mts +1 -0
  70. package/dist/report/built-in/standard.d.ts +1 -0
  71. package/dist/report/components/entity-lists/compute.cjs +40 -3
  72. package/dist/report/components/entity-lists/compute.cjs.map +1 -1
  73. package/dist/report/components/entity-lists/compute.d.cts +8 -6
  74. package/dist/report/components/entity-lists/compute.d.mts +8 -6
  75. package/dist/report/components/entity-lists/compute.d.ts +8 -6
  76. package/dist/report/components/entity-lists/content.cjs +31 -6
  77. package/dist/report/components/entity-lists/content.cjs.map +1 -1
  78. package/dist/report/components/entity-lists/index.cjs +3 -2
  79. package/dist/report/components/entity-lists/index.cjs.map +1 -1
  80. package/dist/report/components/entity-lists/index.d.cts +1 -1
  81. package/dist/report/components/entity-lists/index.d.mts +1 -1
  82. package/dist/report/components/entity-lists/index.d.ts +1 -1
  83. package/dist/report/definition/cell.cjs +3 -0
  84. package/dist/report/definition/cell.cjs.map +1 -1
  85. package/dist/report/definition/cell.d.cts +2 -0
  86. package/dist/report/definition/cell.d.mts +2 -0
  87. package/dist/report/definition/cell.d.ts +2 -0
  88. package/dist/report/definition/primitives.cjs +9 -2
  89. package/dist/report/definition/primitives.cjs.map +1 -1
  90. package/dist/runner/feedback/human.cjs +180 -16
  91. package/dist/runner/feedback/human.cjs.map +1 -1
  92. package/dist/runner/run.cjs +43 -0
  93. package/dist/runner/run.cjs.map +1 -1
  94. package/dist/sample/capability.cjs +93 -0
  95. package/dist/sample/capability.cjs.map +1 -1
  96. package/dist/sample/capability.d.cts +3 -1
  97. package/dist/sample/capability.d.mts +3 -1
  98. package/dist/sample/capability.d.ts +3 -1
  99. package/dist/sample/capability.js +8 -6
  100. package/dist/sandbox/docker-agent-image.cjs +5 -1
  101. package/dist/sandbox/docker-agent-image.cjs.map +1 -1
  102. package/dist/sandbox/docker-agent-image.d.cts +2 -0
  103. package/dist/sandbox/docker-agent-image.d.mts +2 -0
  104. package/dist/sandbox/docker-agent-image.d.ts +2 -0
  105. package/dist/sandbox/docker-agent-image.js +14 -10
  106. package/dist/sandbox/index.cjs +4 -2
  107. package/dist/sandbox/index.cjs.map +1 -1
  108. package/dist/sandbox/index.d.cts +1 -1
  109. package/dist/sandbox/index.d.mts +1 -1
  110. package/dist/sandbox/index.d.ts +1 -1
  111. package/dist/sandbox/index.js +120 -116
  112. package/dist/sandbox/index.mjs +120 -116
  113. package/docs-site/images/hitl-handshake-zh.svg +3 -3
  114. package/docs-site/zh/examples/integrations/ai-sdk-v7.mdx +3 -3
  115. package/docs-site/zh/examples/integrations/claude-sdk.mdx +3 -3
  116. package/docs-site/zh/examples/integrations/codex-sdk.mdx +5 -5
  117. package/docs-site/zh/examples/integrations/langgraph.mdx +3 -3
  118. package/docs-site/zh/examples/integrations/pi-sdk.mdx +5 -5
  119. package/docs-site/zh/explanation/adapter.mdx +5 -5
  120. package/docs-site/zh/explanation/assert.mdx +1 -1
  121. package/docs-site/zh/explanation/drive.mdx +3 -1
  122. package/docs-site/zh/explanation/evals.mdx +3 -1
  123. package/docs-site/zh/explanation/hitl.mdx +7 -7
  124. package/docs-site/zh/reference/builtin-agents.mdx +4 -4
  125. package/docs-site/zh/reference/capabilities.mdx +1 -1
  126. package/docs-site/zh/reference/events.mdx +10 -10
  127. package/docs-site/zh/reference/official-adapters.mdx +1 -1
  128. package/docs-site/zh/reference/results-data.mdx +6 -0
  129. package/docs-site/zh/tutorials/docker-in-docker.mdx +3 -0
  130. package/docs-site/zh/tutorials/nixos-managed-dind.mdx +160 -0
  131. package/docs-site/zh/tutorials/rerun-and-cache.mdx +16 -0
  132. package/docs-site/zh/tutorials/viewing-results.mdx +19 -1
  133. package/docs-site/zh/tutorials/write-send.mdx +7 -6
  134. package/package.json +1 -1
@@ -58,6 +58,130 @@ const NON_TTY_HEARTBEAT_IDLE_MS = 30000;
58
58
  /** dashboard 高度预留:避免最后一行触发终端自动滚动(与 live.ts 旧实现的 `rows - 2` 同一动机,
59
59
  * 这里只需要给「下一帧」留出一行余地,不需要额外的表头/尾行预留)。 */
60
60
  const DASHBOARD_ROW_RESERVE = 1;
61
+ const HUMAN_RESULTS_EXPERIMENT_CAP = 5;
62
+ function freshHumanResult(result) {
63
+ const score = result.scoreResult;
64
+ const scoreState = score === undefined
65
+ ? undefined
66
+ : score.status === "scored"
67
+ ? "complete"
68
+ : score.earnedScore > 0
69
+ ? "partial"
70
+ : "unavailable";
71
+ return {
72
+ experimentId: result.experimentId ?? "default",
73
+ evalId: result.id,
74
+ evaluationKind: result.evaluationKind,
75
+ verdict: result.verdict,
76
+ ...(scoreState === undefined || score === undefined ? {} : { scoreState, earned: score.earnedScore }),
77
+ };
78
+ }
79
+ function reusedHumanResult(result) {
80
+ const attachment = result.score.state === "applicable" && result.score.attachment.state === "available"
81
+ ? result.score.attachment.value
82
+ : undefined;
83
+ return {
84
+ experimentId: result.target.experimentId,
85
+ evalId: result.target.evalId,
86
+ evaluationKind: result.source.evaluationKind,
87
+ verdict: result.verdict,
88
+ ...(attachment === undefined
89
+ ? {}
90
+ : {
91
+ scoreState: attachment.state,
92
+ ...(attachment.earned === undefined ? {} : { earned: attachment.earned }),
93
+ }),
94
+ };
95
+ }
96
+ function humanResultItems(summary) {
97
+ return [
98
+ ...summary.results.map(freshHumanResult),
99
+ ...summary.reusedAttempts.map(reusedHumanResult),
100
+ ];
101
+ }
102
+ function buildResultsPanelRows(items) {
103
+ const byExperiment = new Map();
104
+ for (const item of items) {
105
+ const group = byExperiment.get(item.experimentId);
106
+ if (group)
107
+ group.push(item);
108
+ else
109
+ byExperiment.set(item.experimentId, [item]);
110
+ }
111
+ const groups = [...byExperiment.entries()];
112
+ const rows = [];
113
+ for (const [experimentId, members] of groups.slice(0, HUMAN_RESULTS_EXPERIMENT_CAP)) {
114
+ rows.push({ kind: "line", text: experimentId });
115
+ const byEval = new Map();
116
+ for (const member of members) {
117
+ const evalGroup = byEval.get(member.evalId);
118
+ if (evalGroup)
119
+ evalGroup.push(member);
120
+ else
121
+ byEval.set(member.evalId, [member]);
122
+ }
123
+ for (const [evalId, attempts] of byEval) {
124
+ if (attempts.some((attempt) => attempt.evaluationKind === "score")) {
125
+ const complete = attempts.filter((attempt) => attempt.scoreState === "complete" && attempt.earned !== undefined);
126
+ const partial = attempts.filter((attempt) => attempt.scoreState === "partial" && attempt.earned !== undefined);
127
+ const reading = complete.length > 0
128
+ ? `${complete.reduce((sum, attempt) => sum + attempt.earned, 0) / complete.length} score · ${complete.length}/${attempts.length} complete`
129
+ : partial.length > 0
130
+ ? `≥${partial.map((attempt) => attempt.earned).join(", ≥")} score · partial`
131
+ : "score unavailable";
132
+ rows.push({ kind: "line", text: ` ${evalId} ${reading}` });
133
+ }
134
+ else {
135
+ const passed = attempts.filter((attempt) => attempt.verdict === "passed").length;
136
+ rows.push({ kind: "line", text: ` ${evalId} ${passed}/${attempts.length} passed` });
137
+ }
138
+ }
139
+ }
140
+ if (groups.length > HUMAN_RESULTS_EXPERIMENT_CAP) {
141
+ rows.push({
142
+ kind: "line",
143
+ text: (0, index_ts_1.t)("feedback.human.resultsMore", { count: groups.length - HUMAN_RESULTS_EXPERIMENT_CAP }),
144
+ });
145
+ }
146
+ return rows;
147
+ }
148
+ function buildPreAttemptErrorRows(results) {
149
+ const errored = results.filter((result) => result.verdict === "errored" && result.locator === undefined && result.error !== undefined);
150
+ if (errored.length === 0)
151
+ return undefined;
152
+ const groups = new Map();
153
+ for (const result of errored) {
154
+ const error = result.error;
155
+ const failureId = error.origin.scope === "run" ? error.origin.timingNodeId : `${error.code}:${error.message}`;
156
+ const members = groups.get(failureId);
157
+ if (members)
158
+ members.push(result);
159
+ else
160
+ groups.set(failureId, [result]);
161
+ }
162
+ const rows = [];
163
+ for (const [failureId, members] of groups) {
164
+ const representative = members[0];
165
+ const error = representative.error;
166
+ const codeMatch = /\bERR_[A-Z0-9_]+\b/u.exec(error.message);
167
+ const errorCode = codeMatch?.[0] ?? error.code;
168
+ const focusedMessage = codeMatch === null ? error.message.slice(-600) : error.message.slice(codeMatch.index);
169
+ rows.push({ kind: "line", text: `${FAILURE_SYMBOL} ${representative.experimentId ?? "default"} · sandbox provisioning failed` });
170
+ rows.push({ kind: "line", text: ` phase: ${error.origin.scope === "run" ? "sandbox.image.build" : error.origin.phase}` });
171
+ rows.push({ kind: "line", text: ` affected: ${members.map((member) => member.id).join(", ")}` });
172
+ rows.push({ kind: "line", text: ` shared failure: ${failureId}` });
173
+ rows.push({ kind: "line", text: ` ${errorCode}` });
174
+ for (const line of focusedMessage.split(/\r?\n/u).slice(0, 6)) {
175
+ const text = line.trimEnd();
176
+ if (text.length > 0)
177
+ rows.push({ kind: "line", text: ` ${text}` });
178
+ }
179
+ if (errorCode === "ERR_PNPM_IGNORED_BUILDS") {
180
+ rows.push({ kind: "line", text: " fix: Review these dependencies and configure pnpm allowBuilds." });
181
+ }
182
+ }
183
+ return { rows, slots: errored.length };
184
+ }
61
185
  /** 按 `io.stderr.isTTY` 派发:构造时选一次,运行期不再切换。 */
62
186
  function createHumanRenderer(options) {
63
187
  const { io, command } = options;
@@ -327,36 +451,76 @@ function buildDiagnosticLines(event, state) {
327
451
  function buildSummaryLines(event, state, panel) {
328
452
  const { summary, completion } = event;
329
453
  const fullReuse = state.total > 0 && state.total === state.reused;
454
+ const resultItems = humanResultItems(summary);
455
+ const hasScore = resultItems.some((item) => item.evaluationKind === "score");
456
+ const hasPass = resultItems.some((item) => item.evaluationKind === "pass");
457
+ const scored = resultItems.filter((item) => item.evaluationKind === "score" && item.scoreState === "complete").length;
330
458
  // required reporter(显式 --junit)写失败必须让这行判红——它不是
331
459
  // CompletionStatus 的第四个值(那个枚举只有 complete/incomplete/interrupted 三态),但必须
332
460
  // 避免人看到一句会被误读成"全绿"的 PASSED、进程却以非零退出。
333
461
  const verdictWord = completion.status === "interrupted"
334
462
  ? (0, index_ts_1.t)("feedback.human.resultInterrupted")
335
- : completion.status === "incomplete"
336
- ? (0, index_ts_1.t)("feedback.human.resultIncomplete")
337
- : summary.failed > 0 || summary.errored > 0 || completion.reporterErrors.some((e) => e.required)
338
- ? (0, index_ts_1.t)("feedback.human.resultFailed")
339
- : (0, index_ts_1.t)("feedback.human.resultPassed");
463
+ : summary.errored > 0
464
+ ? (0, index_ts_1.t)("feedback.human.resultErrored")
465
+ : completion.status === "incomplete"
466
+ ? (0, index_ts_1.t)("feedback.human.resultIncomplete")
467
+ : completion.reporterErrors.some((e) => e.required)
468
+ ? (0, index_ts_1.t)("feedback.human.resultFailed")
469
+ : hasScore && !hasPass
470
+ ? (0, index_ts_1.t)("feedback.human.resultScored")
471
+ : hasScore && hasPass
472
+ ? summary.failed > 0
473
+ ? (0, index_ts_1.t)("feedback.human.resultFailed")
474
+ : (0, index_ts_1.t)("feedback.human.resultCompleted")
475
+ : summary.failed > 0
476
+ ? (0, index_ts_1.t)("feedback.human.resultFailed")
477
+ : (0, index_ts_1.t)("feedback.human.resultPassed");
340
478
  const summaryRows = [
341
479
  {
342
480
  kind: "line",
343
- text: (0, index_ts_1.t)(completion.unstarted > 0
344
- ? "feedback.human.summaryIncompleteLine"
345
- : fullReuse
346
- ? "feedback.human.summaryAllReusedLine"
347
- : "feedback.human.summaryLine", {
348
- passed: summary.passed,
349
- failed: summary.failed,
350
- errored: summary.errored,
351
- unstarted: completion.unstarted,
352
- reused: state.reused,
353
- }),
481
+ text: hasScore && !hasPass
482
+ ? (0, index_ts_1.t)("feedback.human.scoreSummaryLine", {
483
+ scored,
484
+ skipped: summary.skipped,
485
+ errored: summary.errored,
486
+ reused: state.reused,
487
+ })
488
+ : (0, index_ts_1.t)(completion.unstarted > 0
489
+ ? "feedback.human.summaryIncompleteLine"
490
+ : fullReuse
491
+ ? "feedback.human.summaryAllReusedLine"
492
+ : "feedback.human.summaryLine", {
493
+ passed: summary.passed,
494
+ failed: summary.failed,
495
+ errored: summary.errored,
496
+ unstarted: completion.unstarted,
497
+ reused: state.reused,
498
+ }),
354
499
  },
355
500
  { kind: "line", text: formatSummaryCostLine(state) },
356
501
  ];
357
502
  const blocks = [
358
503
  (0, panel_ts_1.renderPanel)({ title: verdictWord, meta: formatElapsed(summary.durationMs), rows: summaryRows, width: panel.width, mode: panel.mode }),
359
504
  ];
505
+ if (resultItems.length > 0) {
506
+ blocks.push((0, panel_ts_1.renderPanel)({
507
+ title: (0, index_ts_1.t)("feedback.human.resultsHeader"),
508
+ meta: `${new Set(resultItems.map((item) => item.experimentId)).size} configs`,
509
+ rows: buildResultsPanelRows(resultItems),
510
+ width: panel.width,
511
+ mode: panel.mode,
512
+ }));
513
+ }
514
+ const preAttemptErrors = buildPreAttemptErrorRows(summary.results);
515
+ if (preAttemptErrors !== undefined) {
516
+ blocks.push((0, panel_ts_1.renderPanel)({
517
+ title: (0, index_ts_1.t)("feedback.human.errorsHeader"),
518
+ meta: `${preAttemptErrors.slots} slots`,
519
+ rows: preAttemptErrors.rows,
520
+ width: panel.width,
521
+ mode: panel.mode,
522
+ }));
523
+ }
360
524
  // 全通过时(state.failures 为空)不留空 FAILURES 面板。fresh 失败来自 durable event,carry
361
525
  // 失败由 plan 静态注入;reducer 把两者按 locator 收进同一清单,这里不从 InvocationSummary 再造 ——
362
526
  // 整套结果集(含携入)都要出现在这里,不只是本次派发的那部分(见 cli.md「计数口径…」)。