niceeval 0.13.4-canary.49 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/INDEX.md +3 -3
  2. package/dist/inspection/overview.cjs +20 -4
  3. package/dist/inspection/overview.cjs.map +1 -1
  4. package/dist/inspection/overview.d.cts +5 -0
  5. package/dist/inspection/overview.d.mts +5 -0
  6. package/dist/inspection/overview.d.ts +5 -0
  7. package/dist/inspection/protocol.d.cts +238 -0
  8. package/dist/inspection/protocol.d.mts +238 -0
  9. package/dist/inspection/protocol.d.ts +238 -0
  10. package/dist/inspection/public.mjs +19 -16
  11. package/dist/inspection/results.cjs +11 -10
  12. package/dist/inspection/results.cjs.map +1 -1
  13. package/dist/inspection/results.d.cts +34 -0
  14. package/dist/inspection/results.d.mts +34 -0
  15. package/dist/inspection/results.d.ts +34 -0
  16. package/dist/show/contribution.cjs +11 -2
  17. package/dist/show/contribution.cjs.map +1 -1
  18. package/dist/show/contribution.d.cts +7 -0
  19. package/dist/show/contribution.d.mts +7 -0
  20. package/dist/show/contribution.d.ts +7 -0
  21. package/dist/show/model.cjs +1 -0
  22. package/dist/show/model.cjs.map +1 -1
  23. package/dist/show/model.d.cts +2 -0
  24. package/dist/show/model.d.mts +2 -0
  25. package/dist/show/model.d.ts +2 -0
  26. package/dist/show/render.cjs +149 -81
  27. package/dist/show/render.cjs.map +1 -1
  28. package/dist/show/render.d.cts +3 -1
  29. package/dist/show/render.d.mts +3 -1
  30. package/dist/show/render.d.ts +3 -1
  31. package/dist/view/app-dist/.vite/manifest.json +18 -18
  32. package/dist/view/app-dist/assets/{AttemptDialog-zlgkBA66.js → AttemptDialog-76dX1VQq.js} +1 -1
  33. package/dist/view/app-dist/assets/{AttemptRoute-DN6R4719.js → AttemptRoute-DRHVh2JA.js} +1 -1
  34. package/dist/view/app-dist/assets/{ResultsPage-BfH9vA6y.js → ResultsPage-9CSI8dvZ.js} +2 -2
  35. package/dist/view/app-dist/assets/{RunPage-XiJvNLB-.js → RunPage-BUF0REv7.js} +1 -1
  36. package/dist/view/app-dist/assets/{TableContentView-V8MYLnmk.js → TableContentView-_Sbg5wDr.js} +1 -1
  37. package/dist/view/app-dist/assets/index-BGr_6pGY.js +19 -0
  38. package/dist/view/app-dist/assets/{quality-cost-scatter-Bxyj_9oc.js → quality-cost-scatter-B5wDa_F1.js} +1 -1
  39. package/dist/view/app-dist/assets/useSuspenseQuery-D3W8Uy33.js +1 -0
  40. package/dist/view/app-dist/index.html +1 -1
  41. package/dist/view/function-runtime.mjs +35 -20
  42. package/docs-site/zh/examples/ai-agent-application.mdx +1 -1
  43. package/docs-site/zh/examples/index.mdx +1 -3
  44. package/docs-site/zh/explanation/evals.mdx +1 -1
  45. package/docs-site/zh/explanation/experiment.mdx +3 -1
  46. package/docs-site/zh/explanation/overview.mdx +6 -4
  47. package/docs-site/zh/explanation/record.mdx +9 -5
  48. package/docs-site/zh/explanation/runner.mdx +3 -3
  49. package/docs-site/zh/index.mdx +4 -8
  50. package/docs-site/zh/introduction.mdx +2 -2
  51. package/docs-site/zh/reference/cli.mdx +8 -7
  52. package/docs-site/zh/troubleshooting/debug-sandbox.mdx +5 -5
  53. package/docs-site/zh/troubleshooting/debugging.mdx +8 -8
  54. package/docs-site/zh/troubleshooting/recover-after-kill.mdx +35 -55
  55. package/docs-site/zh/tutorials/accept-results.mdx +4 -4
  56. package/docs-site/zh/tutorials/agent-onboarding.mdx +2 -2
  57. package/docs-site/zh/tutorials/authoring.mdx +1 -1
  58. package/docs-site/zh/tutorials/compare-runs.mdx +3 -3
  59. package/docs-site/zh/tutorials/concurrency.mdx +6 -6
  60. package/docs-site/zh/tutorials/connect-your-agent.mdx +2 -2
  61. package/docs-site/zh/tutorials/docker-in-docker.mdx +1 -1
  62. package/docs-site/zh/tutorials/experiments.mdx +1 -1
  63. package/docs-site/zh/tutorials/install-custom-sandbox-agent.mdx +1 -1
  64. package/docs-site/zh/tutorials/quickstart.mdx +2 -2
  65. package/docs-site/zh/tutorials/reporters.mdx +3 -3
  66. package/docs-site/zh/tutorials/sandbox-agent.mdx +2 -2
  67. package/docs-site/zh/tutorials/sandbox-reuse.mdx +3 -3
  68. package/docs-site/zh/tutorials/viewing-results.mdx +10 -11
  69. package/package.json +1 -1
  70. package/dist/view/app-dist/assets/index-BSJP_UAR.js +0 -19
  71. package/dist/view/app-dist/assets/useSuspenseQuery-Bdi9nQF1.js +0 -1
@@ -26,6 +26,15 @@ const metric = (value, formatValue = fmt) => {
26
26
  : `${rendered} (${value.state})`;
27
27
  };
28
28
  const passRate = (value) => metric(value, (rate) => `${fmt(rate * 100)}%`);
29
+ const duration = (value) => metric(value, (milliseconds) => {
30
+ if (milliseconds < 1000)
31
+ return `${fmt(milliseconds)} ms`;
32
+ if (milliseconds < 60000)
33
+ return `${fmt(milliseconds / 1000)} s`;
34
+ if (milliseconds < 3600000)
35
+ return `${fmt(milliseconds / 60000)} min`;
36
+ return `${fmt(milliseconds / 3600000)} h`;
37
+ });
29
38
  const score = (value) => value.state === "not-scored"
30
39
  ? value.state
31
40
  : `${fmt(value.earned)}/${fmt(value.possible)} (${value.state}${value.state === "unavailable"
@@ -42,8 +51,10 @@ const aggregateEntries = (value) => ({
42
51
  : `${value.passed} passed; ${value.failed} failed; ${value.errored} errored; ${value.skipped} skipped`,
43
52
  },
44
53
  { key: "Pass rate", value: passRate(value.passRate) },
45
- { key: "Score", value: metric(value.score) },
46
- { key: "Duration", value: metric(value.durationMs, (value) => `${fmt(value)} ms`) },
54
+ ...(value.evaluationKind === "pass"
55
+ ? []
56
+ : [{ key: "Score", value: metric(value.score) }]),
57
+ { key: "Duration", value: duration(value.durationMs) },
47
58
  { key: "Tokens", value: metric(value.tokens) },
48
59
  ],
49
60
  });
@@ -65,35 +76,114 @@ function groupExperiments(value) {
65
76
  }
66
77
  return [...groups].map(([name, experiments]) => ({ name, experiments }));
67
78
  }
68
- const attemptTable = (cells, group) => ({
69
- kind: "table",
70
- columns: [
71
- { header: "Eval", maxWidth: 55 },
72
- { header: "Attempt", maxWidth: 14 },
73
- { header: "Score" },
74
- ],
75
- overflow: "wrap",
76
- rows: cells.flatMap((cell) => cell.members.length === 0
77
- ? [[
78
- relativeToGroup(cell.evalId, group),
79
- "not-recorded",
80
- metric(cell.aggregate.score),
81
- ]]
82
- : cell.members.map((member) => [
83
- relativeToGroup(cell.evalId, group),
84
- member.publication.state === "published"
85
- ? member.publication.attemptLocator
86
- : member.publication.state === "absent"
87
- ? `absent (${member.publication.reason})`
88
- : "pending",
89
- member.publication.state === "published"
90
- ? metric(member.publication.score)
91
- : member.publication.state,
92
- ])),
93
- });
79
+ const attemptBlocks = (cells, group, all) => {
80
+ let shownErrors = 0;
81
+ return cells.flatMap((cell) => {
82
+ const showScore = cell.aggregate.evaluationKind !== "pass";
83
+ const members = all
84
+ ? cell.members
85
+ : cell.members.filter((member) => {
86
+ if (member.publication.state !== "published")
87
+ return true;
88
+ if (member.publication.verdict === "passed" ||
89
+ member.publication.verdict === "failed")
90
+ return false;
91
+ if (member.publication.verdict !== "errored")
92
+ return true;
93
+ shownErrors += 1;
94
+ return shownErrors <= 5;
95
+ });
96
+ if (cell.members.length > 0 && members.length === 0)
97
+ return [];
98
+ return [
99
+ {
100
+ kind: "divider",
101
+ title: `Eval ${relativeToGroup(cell.evalId, group)}`,
102
+ attachNext: true,
103
+ },
104
+ {
105
+ kind: "table",
106
+ columns: [
107
+ { header: "Attempt", maxWidth: 14 },
108
+ { header: "Verdict" },
109
+ { header: "Duration" },
110
+ ...(showScore ? [{ header: "Score" }] : []),
111
+ ],
112
+ overflow: "wrap",
113
+ rows: members.length === 0
114
+ ? [[
115
+ "not-recorded",
116
+ "not-recorded",
117
+ duration(cell.aggregate.durationMs),
118
+ ...(showScore ? [metric(cell.aggregate.score)] : []),
119
+ ]]
120
+ : members.map((member) => [
121
+ member.publication.state === "published"
122
+ ? member.publication.attemptLocator
123
+ : member.publication.state === "absent"
124
+ ? `absent (${member.publication.reason})`
125
+ : "pending",
126
+ member.publication.state === "published"
127
+ ? member.publication.verdict ?? "not-recorded"
128
+ : member.publication.state,
129
+ member.publication.state === "published"
130
+ ? duration(member.publication.durationMs)
131
+ : member.publication.state,
132
+ ...(showScore
133
+ ? [member.publication.state === "published"
134
+ ? metric(member.publication.score)
135
+ : member.publication.state]
136
+ : []),
137
+ ]),
138
+ },
139
+ ];
140
+ });
141
+ };
142
+ const hiddenAttemptSummary = (cells) => {
143
+ const counts = { passed: 0, failed: 0, errored: 0 };
144
+ for (const cell of cells) {
145
+ for (const member of cell.members) {
146
+ if (member.publication.state !== "published")
147
+ continue;
148
+ const verdict = member.publication.verdict;
149
+ if (verdict === "passed" ||
150
+ verdict === "failed" ||
151
+ verdict === "errored")
152
+ counts[verdict] += 1;
153
+ }
154
+ }
155
+ const hidden = [
156
+ ...(counts.passed > 0 ? [`${counts.passed} passed`] : []),
157
+ ...(counts.failed > 0 ? [`${counts.failed} failed`] : []),
158
+ ...(counts.errored > 5 ? [`${counts.errored - 5} errored`] : []),
159
+ ];
160
+ return hidden.length === 0 ? null : `${hidden.join("; ")} Attempts hidden`;
161
+ };
162
+ const compactContinuation = (cells, experimentId, all) => {
163
+ if (all)
164
+ return [];
165
+ const hidden = hiddenAttemptSummary(cells);
166
+ return hidden === null
167
+ ? []
168
+ : [
169
+ {
170
+ kind: "divider",
171
+ title: hidden,
172
+ attachNext: true,
173
+ },
174
+ {
175
+ kind: "keyValue",
176
+ entries: [{
177
+ key: "See more",
178
+ value: `niceeval show --experiment ${experimentId}`,
179
+ }],
180
+ },
181
+ ];
182
+ };
94
183
  const stateCount = (state, count, noun) => `${state}; ${count} ${noun}s`;
95
184
  const textOrNotRecorded = (value) => value ?? "not-recorded";
96
- function renderOverview(value) {
185
+ function renderOverview(value, options = {}) {
186
+ const all = options.all === true;
97
187
  const blocks = [
98
188
  {
99
189
  kind: "panel",
@@ -109,30 +199,33 @@ function renderOverview(value) {
109
199
  blocks.push({
110
200
  kind: "panel",
111
201
  title: "Experiments",
112
- blocks: groups.flatMap((group) => [
113
- ...(group.name === null
114
- ? []
115
- : [{ kind: "divider", title: group.name }]),
116
- {
117
- kind: "table",
118
- columns: [
119
- { header: "Experiment" },
120
- { header: "Observed" },
121
- { header: "Agent" },
122
- { header: "Model" },
123
- { header: "Pass rate" },
124
- { header: "Score" },
125
- ],
126
- rows: group.experiments.map((experiment) => [
127
- relativeToGroup(experiment.experimentId, group.name),
128
- `${experiment.aggregate.observed}/${experiment.aggregate.expected}`,
129
- executionValue(experiment.agent),
130
- executionValue(experiment.model),
131
- passRate(experiment.aggregate.passRate),
132
- metric(experiment.aggregate.score),
133
- ]),
134
- },
135
- ]),
202
+ blocks: groups.flatMap((group) => {
203
+ const showScore = group.experiments.some(({ aggregate }) => aggregate.evaluationKind !== "pass");
204
+ return [
205
+ ...(group.name === null
206
+ ? []
207
+ : [{ kind: "divider", title: group.name }]),
208
+ {
209
+ kind: "table",
210
+ columns: [
211
+ { header: "Experiment" },
212
+ { header: "Observed" },
213
+ { header: "Agent" },
214
+ { header: "Model" },
215
+ { header: "Pass rate" },
216
+ ...(showScore ? [{ header: "Score" }] : []),
217
+ ],
218
+ rows: group.experiments.map((experiment) => [
219
+ relativeToGroup(experiment.experimentId, group.name),
220
+ `${experiment.aggregate.observed}/${experiment.aggregate.expected}`,
221
+ executionValue(experiment.agent),
222
+ executionValue(experiment.model),
223
+ passRate(experiment.aggregate.passRate),
224
+ ...(showScore ? [metric(experiment.aggregate.score)] : []),
225
+ ]),
226
+ },
227
+ ];
228
+ }),
136
229
  });
137
230
  }
138
231
  if (value.cells.length > 0) {
@@ -148,9 +241,9 @@ function renderOverview(value) {
148
241
  {
149
242
  kind: "divider",
150
243
  title: `Experiment ${experiment.experimentId}`,
151
- attachNext: true,
152
244
  },
153
- attemptTable(experimentCells, group.name),
245
+ ...attemptBlocks(experimentCells, group.name, all),
246
+ ...compactContinuation(experimentCells, experiment.experimentId, all),
154
247
  ];
155
248
  }),
156
249
  });
@@ -167,32 +260,7 @@ function renderExperiment(value) {
167
260
  { kind: "divider", title: "Summary" },
168
261
  aggregateEntries(value.aggregate),
169
262
  { kind: "divider", title: "Attempts" },
170
- {
171
- kind: "table",
172
- columns: [
173
- { header: "Eval", maxWidth: 55 },
174
- { header: "Attempt", maxWidth: 14 },
175
- { header: "Score" },
176
- ],
177
- overflow: "wrap",
178
- rows: value.cells.flatMap((cell) => cell.members.length === 0
179
- ? [[
180
- cell.evalId,
181
- "not-recorded",
182
- metric(cell.aggregate.score),
183
- ]]
184
- : cell.members.map((member) => [
185
- cell.evalId,
186
- member.publication.state === "published"
187
- ? member.publication.attemptLocator
188
- : member.publication.state === "absent"
189
- ? `absent (${member.publication.reason})`
190
- : "pending",
191
- member.publication.state === "published"
192
- ? metric(member.publication.score)
193
- : member.publication.state,
194
- ])),
195
- },
263
+ ...attemptBlocks(value.cells, null, true),
196
264
  ],
197
265
  },
198
266
  ]);