@tangle-network/agent-eval 0.120.0 → 0.120.2

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 (171) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/package.json +1 -1
  3. package/dist/analyst/index.d.ts +0 -3111
  4. package/dist/analyst/index.js +0 -403
  5. package/dist/analyst/index.js.map +0 -1
  6. package/dist/authenticity/index.d.ts +0 -161
  7. package/dist/authenticity/index.js +0 -215
  8. package/dist/authenticity/index.js.map +0 -1
  9. package/dist/belief-state/index.d.ts +0 -1301
  10. package/dist/belief-state/index.js +0 -2152
  11. package/dist/belief-state/index.js.map +0 -1
  12. package/dist/benchmarks/index.d.ts +0 -974
  13. package/dist/benchmarks/index.js +0 -60
  14. package/dist/benchmarks/index.js.map +0 -1
  15. package/dist/builder-eval/index.d.ts +0 -695
  16. package/dist/builder-eval/index.js +0 -366
  17. package/dist/builder-eval/index.js.map +0 -1
  18. package/dist/campaign/index.d.ts +0 -7454
  19. package/dist/campaign/index.js +0 -272
  20. package/dist/campaign/index.js.map +0 -1
  21. package/dist/chunk-32BZXMSO.js +0 -3878
  22. package/dist/chunk-32BZXMSO.js.map +0 -1
  23. package/dist/chunk-3A246TSA.js +0 -998
  24. package/dist/chunk-3A246TSA.js.map +0 -1
  25. package/dist/chunk-3RF76KTD.js +0 -84
  26. package/dist/chunk-3RF76KTD.js.map +0 -1
  27. package/dist/chunk-3YYRZDON.js +0 -45
  28. package/dist/chunk-3YYRZDON.js.map +0 -1
  29. package/dist/chunk-4I2E3LLO.js +0 -1030
  30. package/dist/chunk-4I2E3LLO.js.map +0 -1
  31. package/dist/chunk-ARU2PZFM.js +0 -312
  32. package/dist/chunk-ARU2PZFM.js.map +0 -1
  33. package/dist/chunk-BOD4O7OF.js +0 -40
  34. package/dist/chunk-BOD4O7OF.js.map +0 -1
  35. package/dist/chunk-DPZAEKA6.js +0 -880
  36. package/dist/chunk-DPZAEKA6.js.map +0 -1
  37. package/dist/chunk-DTJ6QUQB.js +0 -131
  38. package/dist/chunk-DTJ6QUQB.js.map +0 -1
  39. package/dist/chunk-GGE4NNQT.js +0 -65
  40. package/dist/chunk-GGE4NNQT.js.map +0 -1
  41. package/dist/chunk-H5UD2323.js +0 -286
  42. package/dist/chunk-H5UD2323.js.map +0 -1
  43. package/dist/chunk-HHWE3POT.js +0 -94
  44. package/dist/chunk-HHWE3POT.js.map +0 -1
  45. package/dist/chunk-HKUCJ437.js +0 -787
  46. package/dist/chunk-HKUCJ437.js.map +0 -1
  47. package/dist/chunk-JHCHEVET.js +0 -274
  48. package/dist/chunk-JHCHEVET.js.map +0 -1
  49. package/dist/chunk-JHOJHHU7.js +0 -867
  50. package/dist/chunk-JHOJHHU7.js.map +0 -1
  51. package/dist/chunk-JM2SKQMS.js +0 -750
  52. package/dist/chunk-JM2SKQMS.js.map +0 -1
  53. package/dist/chunk-JN2FCO5W.js +0 -7958
  54. package/dist/chunk-JN2FCO5W.js.map +0 -1
  55. package/dist/chunk-K4DBDHLK.js +0 -158
  56. package/dist/chunk-K4DBDHLK.js.map +0 -1
  57. package/dist/chunk-K6N6XJJX.js +0 -306
  58. package/dist/chunk-K6N6XJJX.js.map +0 -1
  59. package/dist/chunk-MA6HLL3S.js +0 -65
  60. package/dist/chunk-MA6HLL3S.js.map +0 -1
  61. package/dist/chunk-MAZ26DC7.js +0 -99
  62. package/dist/chunk-MAZ26DC7.js.map +0 -1
  63. package/dist/chunk-MOXWMGPC.js +0 -577
  64. package/dist/chunk-MOXWMGPC.js.map +0 -1
  65. package/dist/chunk-NJC7U437.js +0 -626
  66. package/dist/chunk-NJC7U437.js.map +0 -1
  67. package/dist/chunk-NPCTHQIO.js +0 -91
  68. package/dist/chunk-NPCTHQIO.js.map +0 -1
  69. package/dist/chunk-ONWEPEDO.js +0 -57
  70. package/dist/chunk-ONWEPEDO.js.map +0 -1
  71. package/dist/chunk-OYZAPX5G.js +0 -1526
  72. package/dist/chunk-OYZAPX5G.js.map +0 -1
  73. package/dist/chunk-PC4UYEBM.js +0 -166
  74. package/dist/chunk-PC4UYEBM.js.map +0 -1
  75. package/dist/chunk-PICTDURQ.js +0 -766
  76. package/dist/chunk-PICTDURQ.js.map +0 -1
  77. package/dist/chunk-PJQFMIOX.js +0 -1182
  78. package/dist/chunk-PJQFMIOX.js.map +0 -1
  79. package/dist/chunk-PXD6ZFNY.js +0 -1107
  80. package/dist/chunk-PXD6ZFNY.js.map +0 -1
  81. package/dist/chunk-PXE2VKMX.js +0 -140
  82. package/dist/chunk-PXE2VKMX.js.map +0 -1
  83. package/dist/chunk-PZ5AY32C.js +0 -10
  84. package/dist/chunk-PZ5AY32C.js.map +0 -1
  85. package/dist/chunk-QBRSJK47.js +0 -622
  86. package/dist/chunk-QBRSJK47.js.map +0 -1
  87. package/dist/chunk-QWMPPZ3X.js +0 -550
  88. package/dist/chunk-QWMPPZ3X.js.map +0 -1
  89. package/dist/chunk-S3UZOQ5Y.js +0 -328
  90. package/dist/chunk-S3UZOQ5Y.js.map +0 -1
  91. package/dist/chunk-S5TT5R3L.js +0 -2668
  92. package/dist/chunk-S5TT5R3L.js.map +0 -1
  93. package/dist/chunk-T4SQEITX.js +0 -95
  94. package/dist/chunk-T4SQEITX.js.map +0 -1
  95. package/dist/chunk-TT4KNT67.js +0 -124
  96. package/dist/chunk-TT4KNT67.js.map +0 -1
  97. package/dist/chunk-U5CHZ5M3.js +0 -357
  98. package/dist/chunk-U5CHZ5M3.js.map +0 -1
  99. package/dist/chunk-ULOKLHIQ.js +0 -1937
  100. package/dist/chunk-ULOKLHIQ.js.map +0 -1
  101. package/dist/chunk-VI2UW6B6.js +0 -162
  102. package/dist/chunk-VI2UW6B6.js.map +0 -1
  103. package/dist/chunk-VQMK5FMP.js +0 -247
  104. package/dist/chunk-VQMK5FMP.js.map +0 -1
  105. package/dist/chunk-VSMTAMNK.js +0 -53
  106. package/dist/chunk-VSMTAMNK.js.map +0 -1
  107. package/dist/chunk-VZSRQ272.js +0 -149
  108. package/dist/chunk-VZSRQ272.js.map +0 -1
  109. package/dist/chunk-WW2A73HW.js +0 -159
  110. package/dist/chunk-WW2A73HW.js.map +0 -1
  111. package/dist/chunk-X4UCIOTZ.js +0 -136
  112. package/dist/chunk-X4UCIOTZ.js.map +0 -1
  113. package/dist/chunk-XDIRG3TO.js +0 -1266
  114. package/dist/chunk-XDIRG3TO.js.map +0 -1
  115. package/dist/chunk-XJYR7XFV.js +0 -317
  116. package/dist/chunk-XJYR7XFV.js.map +0 -1
  117. package/dist/chunk-ZET2UAYW.js +0 -89
  118. package/dist/chunk-ZET2UAYW.js.map +0 -1
  119. package/dist/chunk-ZZUXHH3R.js +0 -99
  120. package/dist/chunk-ZZUXHH3R.js.map +0 -1
  121. package/dist/cli.d.ts +0 -1
  122. package/dist/cli.js +0 -112
  123. package/dist/cli.js.map +0 -1
  124. package/dist/contract/index.d.ts +0 -4969
  125. package/dist/contract/index.js +0 -1653
  126. package/dist/contract/index.js.map +0 -1
  127. package/dist/control.d.ts +0 -1013
  128. package/dist/control.js +0 -34
  129. package/dist/control.js.map +0 -1
  130. package/dist/fuzz.d.ts +0 -759
  131. package/dist/fuzz.js +0 -714
  132. package/dist/fuzz.js.map +0 -1
  133. package/dist/hosted/index.d.ts +0 -730
  134. package/dist/hosted/index.js +0 -14
  135. package/dist/hosted/index.js.map +0 -1
  136. package/dist/index.d.ts +0 -16780
  137. package/dist/index.js +0 -12168
  138. package/dist/index.js.map +0 -1
  139. package/dist/matrix/index.d.ts +0 -155
  140. package/dist/matrix/index.js +0 -8
  141. package/dist/matrix/index.js.map +0 -1
  142. package/dist/meta-eval/index.d.ts +0 -1030
  143. package/dist/meta-eval/index.js +0 -417
  144. package/dist/meta-eval/index.js.map +0 -1
  145. package/dist/multishot/index.d.ts +0 -579
  146. package/dist/multishot/index.js +0 -589
  147. package/dist/multishot/index.js.map +0 -1
  148. package/dist/openapi.json +0 -992
  149. package/dist/pipelines/index.d.ts +0 -567
  150. package/dist/pipelines/index.js +0 -515
  151. package/dist/pipelines/index.js.map +0 -1
  152. package/dist/reporting.d.ts +0 -1277
  153. package/dist/reporting.js +0 -48
  154. package/dist/reporting.js.map +0 -1
  155. package/dist/rl.d.ts +0 -4092
  156. package/dist/rl.js +0 -1724
  157. package/dist/rl.js.map +0 -1
  158. package/dist/run-campaign-HNFPJET4.js +0 -14
  159. package/dist/run-campaign-HNFPJET4.js.map +0 -1
  160. package/dist/storyboard/index.d.ts +0 -279
  161. package/dist/storyboard/index.js +0 -767
  162. package/dist/storyboard/index.js.map +0 -1
  163. package/dist/trace-attributes.d.ts +0 -52
  164. package/dist/trace-attributes.js +0 -62
  165. package/dist/trace-attributes.js.map +0 -1
  166. package/dist/traces.d.ts +0 -2343
  167. package/dist/traces.js +0 -249
  168. package/dist/traces.js.map +0 -1
  169. package/dist/wire/index.d.ts +0 -1252
  170. package/dist/wire/index.js +0 -81
  171. package/dist/wire/index.js.map +0 -1
@@ -1,622 +0,0 @@
1
- import {
2
- cohensD
3
- } from "./chunk-PJQFMIOX.js";
4
- import {
5
- argHash,
6
- groupBy,
7
- hasCapturedToolArgs,
8
- toolSpans
9
- } from "./chunk-ZET2UAYW.js";
10
-
11
- // src/failure-taxonomy.ts
12
- var DEFAULT_RULES = [
13
- // Outcome already named? Respect it.
14
- {
15
- id: "explicit-outcome",
16
- match: ({ run }) => {
17
- const fc = run.outcome?.failureClass;
18
- if (fc && fc !== "unknown")
19
- return { failureClass: fc, reason: "outcome.failureClass set explicitly" };
20
- return null;
21
- }
22
- },
23
- {
24
- id: "knowledge-readiness-blocked",
25
- match: ({ events }) => {
26
- const event = events.find(
27
- (e) => e.kind === "custom" && e.payload.kind === "readiness_scored" && e.payload.passed === false
28
- );
29
- return event ? {
30
- failureClass: "knowledge_readiness_blocked",
31
- reason: "knowledge readiness report blocked execution",
32
- triggerEventId: event.eventId
33
- } : null;
34
- }
35
- },
36
- {
37
- id: "bad-integration-manifest",
38
- match: ({ events }) => {
39
- const event = events.find(
40
- (e) => e.kind === "custom" && (e.payload.kind === "integration_manifest_validated" && e.payload.valid === false || e.payload.kind === "integration_invoke_failed" && e.payload.code === "manifest_invalid")
41
- );
42
- return event ? {
43
- failureClass: "bad_integration_manifest",
44
- reason: "integration manifest validation failed before launch",
45
- triggerEventId: event.eventId
46
- } : null;
47
- }
48
- },
49
- {
50
- id: "missing-integration-connection",
51
- match: ({ events }) => {
52
- const event = events.find(
53
- (e) => e.kind === "custom" && e.payload.kind === "integration_manifest_resolved" && hasResolutionStatus(e.payload, "missing_connection")
54
- );
55
- return event ? {
56
- failureClass: "missing_integration_connection",
57
- reason: "required integration connection was missing",
58
- triggerEventId: event.eventId
59
- } : null;
60
- }
61
- },
62
- {
63
- id: "missing-integration-scope",
64
- match: ({ events }) => {
65
- const event = events.find(
66
- (e) => e.kind === "custom" && (e.payload.kind === "integration_manifest_resolved" && hasMissingScopes(e.payload) || e.payload.kind === "integration_invoke_failed" && e.payload.code === "scope_denied")
67
- );
68
- return event ? {
69
- failureClass: "missing_integration_scope",
70
- reason: "integration grant or connection lacks required scopes",
71
- triggerEventId: event.eventId
72
- } : null;
73
- }
74
- },
75
- {
76
- id: "integration-approval-required",
77
- match: ({ events }) => {
78
- const event = events.find(
79
- (e) => e.kind === "custom" && (e.payload.kind === "integration_invoke" && e.payload.status === "approval_required" || e.payload.kind === "integration_invoke_failed" && e.payload.code === "approval_required" || e.payload.kind === "integration_approval_required")
80
- );
81
- return event ? {
82
- failureClass: "integration_approval_required",
83
- reason: "integration write paused for user approval",
84
- triggerEventId: event.eventId
85
- } : null;
86
- }
87
- },
88
- {
89
- id: "integration-auth-expired",
90
- match: ({ events }) => {
91
- const event = events.find(
92
- (e) => e.kind === "custom" && e.payload.kind === "integration_invoke_failed" && (e.payload.code === "auth_expired" || e.payload.code === "connection_not_active" || e.payload.code === "capability_expired" || e.payload.status === "expired")
93
- );
94
- return event ? {
95
- failureClass: "integration_auth_expired",
96
- reason: "integration connection or capability expired",
97
- triggerEventId: event.eventId
98
- } : null;
99
- }
100
- },
101
- {
102
- id: "unsafe-integration-write-denied",
103
- match: ({ events }) => {
104
- const event = events.find(
105
- (e) => e.kind === "custom" && e.payload.kind === "integration_invoke_failed" && (e.payload.code === "unsafe_write_denied" || e.payload.code === "policy_denied" || e.payload.code === "action_denied")
106
- );
107
- return event ? {
108
- failureClass: "unsafe_integration_write_denied",
109
- reason: "integration write was denied by policy or capability scope",
110
- triggerEventId: event.eventId
111
- } : null;
112
- }
113
- },
114
- {
115
- id: "integration-provider-failure",
116
- match: ({ events }) => {
117
- const event = events.find(
118
- (e) => e.kind === "custom" && e.payload.kind === "integration_invoke_failed" && ![
119
- "scope_denied",
120
- "approval_required",
121
- "auth_expired",
122
- "connection_not_active",
123
- "capability_expired",
124
- "unsafe_write_denied",
125
- "policy_denied",
126
- "action_denied",
127
- "manifest_invalid"
128
- ].includes(String(e.payload.code))
129
- );
130
- return event ? {
131
- failureClass: "integration_provider_failure",
132
- reason: "integration provider invocation failed",
133
- triggerEventId: event.eventId
134
- } : null;
135
- }
136
- },
137
- {
138
- id: "missing-credentials",
139
- match: ({ events }) => {
140
- const event = events.find(
141
- (e) => e.kind === "custom" && e.payload.kind === "knowledge_gap" && e.payload.category === "credential_or_secret"
142
- );
143
- return event ? {
144
- failureClass: "missing_credentials",
145
- reason: "required credential or secret was missing",
146
- triggerEventId: event.eventId
147
- } : null;
148
- }
149
- },
150
- {
151
- id: "bad-retrieval",
152
- match: ({ run, spans }) => {
153
- if (run.outcome?.pass !== false) return null;
154
- const retrieval = spans.find(
155
- (s) => s.kind === "retrieval" && (s.hits.length === 0 || s.hits.every((hit) => hit.score <= 0))
156
- );
157
- return retrieval ? {
158
- failureClass: "bad_retrieval",
159
- reason: "retrieval returned no useful hits for a failed run",
160
- triggerSpanId: retrieval.spanId
161
- } : null;
162
- }
163
- },
164
- {
165
- id: "insufficient-evidence",
166
- match: ({ events }) => {
167
- const event = events.find(
168
- (e) => e.kind === "custom" && e.payload.kind === "knowledge_gap" && e.payload.reason === "insufficient_evidence"
169
- );
170
- return event ? {
171
- failureClass: "insufficient_evidence",
172
- reason: "task proceeded with insufficient supporting evidence",
173
- triggerEventId: event.eventId
174
- } : null;
175
- }
176
- },
177
- {
178
- id: "contradictory-evidence",
179
- match: ({ events }) => {
180
- const event = events.find(
181
- (e) => e.kind === "custom" && e.payload.kind === "knowledge_gap" && e.payload.reason === "contradictory_evidence"
182
- );
183
- return event ? {
184
- failureClass: "contradictory_evidence",
185
- reason: "supporting evidence contradicted itself",
186
- triggerEventId: event.eventId
187
- } : null;
188
- }
189
- },
190
- // Budget breach events
191
- {
192
- id: "budget-breach",
193
- match: ({ events }) => {
194
- const breach = events.find((e) => e.kind === "budget_breach");
195
- return breach ? {
196
- failureClass: "budget_exceeded",
197
- reason: `budget breached on ${breach.payload.dimension ?? "unknown dimension"}`,
198
- triggerEventId: breach.eventId
199
- } : null;
200
- }
201
- },
202
- // Policy violations
203
- {
204
- id: "policy-violation",
205
- match: ({ events }) => {
206
- const e = events.find((x) => x.kind === "policy_violation");
207
- return e ? {
208
- failureClass: "policy_violation",
209
- reason: "policy_violation event emitted",
210
- triggerEventId: e.eventId
211
- } : null;
212
- }
213
- },
214
- // Sandbox non-zero exit code
215
- {
216
- id: "sandbox-failure",
217
- match: ({ spans }) => {
218
- const s = spans.find(
219
- (x) => x.kind === "sandbox" && typeof x.exitCode === "number" && x.exitCode !== 0
220
- );
221
- if (!s) return null;
222
- return {
223
- failureClass: "sandbox_failure",
224
- reason: `sandbox exited ${s.exitCode}`,
225
- triggerSpanId: s.spanId
226
- };
227
- }
228
- },
229
- // Timeout: run aborted by external signal
230
- {
231
- id: "timeout",
232
- match: ({ run, events }) => {
233
- if (run.status !== "aborted") return null;
234
- const hasTimeout = events.some(
235
- (e) => e.kind === "error" && String(e.payload.reason ?? "").toLowerCase().includes("timeout")
236
- );
237
- const note = (run.outcome?.notes ?? "").toLowerCase();
238
- if (hasTimeout || note.includes("timeout") || note.includes("deadline")) {
239
- return { failureClass: "timeout", reason: "timeout signal observed" };
240
- }
241
- return null;
242
- }
243
- },
244
- // Tool recovery failure: many consecutive tool errors on the same tool
245
- {
246
- id: "tool-recovery-failure",
247
- match: ({ spans }) => {
248
- const tools = spans.filter((s) => s.kind === "tool");
249
- const byTool = /* @__PURE__ */ new Map();
250
- for (const t of tools) {
251
- const name = t.toolName;
252
- const arr = byTool.get(name) ?? [];
253
- arr.push(t);
254
- byTool.set(name, arr);
255
- }
256
- for (const [name, arr] of byTool) {
257
- const errs = arr.filter((s) => s.status === "error");
258
- if (errs.length >= 3 && errs.length === arr.length) {
259
- return {
260
- failureClass: "tool_recovery_failure",
261
- reason: `${errs.length} consecutive errors on tool "${name}"`,
262
- triggerSpanId: errs[errs.length - 1].spanId
263
- };
264
- }
265
- }
266
- return null;
267
- }
268
- },
269
- // Tool selection error: the run failed and agent called zero tools despite having them
270
- {
271
- id: "tool-selection-error",
272
- match: ({ run, spans }) => {
273
- if (run.outcome?.pass !== false) return null;
274
- const hasToolsAvailable = spans.some(
275
- (s) => s.kind === "agent" && s.attributes?.toolsAvailable !== void 0 && s.attributes?.toolsAvailable > 0
276
- );
277
- const tools = spans.filter((s) => s.kind === "tool");
278
- if (hasToolsAvailable && tools.length === 0) {
279
- return {
280
- failureClass: "tool_selection_error",
281
- reason: "tools were available but none were called"
282
- };
283
- }
284
- return null;
285
- }
286
- },
287
- // Format drift: scored by a judge with dimension='format' below threshold
288
- {
289
- id: "format-drift",
290
- match: ({ spans }) => {
291
- const judge = spans.find(
292
- (s) => s.kind === "judge" && s.dimension === "format" && s.score < 0.5
293
- );
294
- return judge ? {
295
- failureClass: "format_drift",
296
- reason: "format judge scored below 0.5",
297
- triggerSpanId: judge.spanId
298
- } : null;
299
- }
300
- }
301
- ];
302
- function hasResolutionStatus(payload, status) {
303
- if (status === "missing_connection" && stringArray(payload.missingConnections).length > 0)
304
- return true;
305
- return resolutionItems(payload).some((item) => item.status === status);
306
- }
307
- function hasMissingScopes(payload) {
308
- if (stringArray(payload.missingScopes).length > 0) return true;
309
- return resolutionItems(payload).some(
310
- (item) => Array.isArray(item.missingScopes) && item.missingScopes.length > 0
311
- );
312
- }
313
- function resolutionItems(payload) {
314
- return [
315
- ...records(payload.missing),
316
- ...records(payload.optionalMissing),
317
- ...records(payload.ready)
318
- ];
319
- }
320
- function records(value) {
321
- if (!Array.isArray(value)) return [];
322
- return value.filter(
323
- (item) => Boolean(item) && typeof item === "object" && !Array.isArray(item)
324
- );
325
- }
326
- function stringArray(value) {
327
- return Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
328
- }
329
- function classifyFailure(ctx, rules = DEFAULT_RULES) {
330
- if (ctx.run.outcome?.pass !== false && ctx.run.status === "completed") {
331
- return { failureClass: "success", reason: "run completed with pass=true (or no explicit fail)" };
332
- }
333
- for (const rule of rules) {
334
- const hit = rule.match(ctx);
335
- if (hit) return hit;
336
- }
337
- return { failureClass: "unknown", reason: "no rule matched; run failed for unclassified reason" };
338
- }
339
-
340
- // src/tool-use-metrics.ts
341
- async function computeToolUseMetrics(store, runId, options = {}) {
342
- const tools = await toolSpans(store, runId);
343
- if (tools.length === 0) {
344
- return {
345
- runId,
346
- totalCalls: 0,
347
- callsWithCapturedArgs: 0,
348
- byTool: {},
349
- errorRate: 0,
350
- duplicateRate: 0,
351
- retryRate: 0
352
- };
353
- }
354
- const byTool = {};
355
- let totalErrors = 0;
356
- let totalDuplicates = 0;
357
- let callsWithCapturedArgs = 0;
358
- const sortedTools = [...tools].sort((a, b) => a.startedAt - b.startedAt);
359
- const seenSignatures = /* @__PURE__ */ new Set();
360
- for (const t of sortedTools) {
361
- byTool[t.toolName] ??= {
362
- calls: 0,
363
- callsWithCapturedArgs: 0,
364
- errors: 0,
365
- avgLatencyMs: 0,
366
- duplicates: 0
367
- };
368
- const stat = byTool[t.toolName];
369
- stat.calls += 1;
370
- if (t.status === "error") {
371
- stat.errors += 1;
372
- totalErrors += 1;
373
- }
374
- if (typeof t.latencyMs === "number") stat.avgLatencyMs += t.latencyMs;
375
- if (hasCapturedToolArgs(t)) {
376
- callsWithCapturedArgs += 1;
377
- stat.callsWithCapturedArgs += 1;
378
- const sig = `${t.toolName}|${argHash(t.args)}`;
379
- if (seenSignatures.has(sig)) {
380
- stat.duplicates += 1;
381
- totalDuplicates += 1;
382
- }
383
- seenSignatures.add(sig);
384
- }
385
- }
386
- for (const stat of Object.values(byTool)) {
387
- stat.avgLatencyMs = stat.calls > 0 ? stat.avgLatencyMs / stat.calls : 0;
388
- }
389
- let retryOpportunities = 0;
390
- let retriesFollowed = 0;
391
- for (const [, arr] of groupBy(sortedTools, (t) => t.toolName)) {
392
- for (let i = 0; i < arr.length; i++) {
393
- if (arr[i].status !== "error") continue;
394
- retryOpportunities += 1;
395
- if (arr[i + 1]) retriesFollowed += 1;
396
- }
397
- }
398
- const retryRate = retryOpportunities > 0 ? retriesFollowed / retryOpportunities : 0;
399
- let selectionAccuracy;
400
- if (options.selectionLabels) {
401
- const labeled = sortedTools.filter((t) => t.spanId in options.selectionLabels);
402
- if (labeled.length > 0) {
403
- selectionAccuracy = labeled.filter((t) => options.selectionLabels[t.spanId]).length / labeled.length;
404
- }
405
- }
406
- return {
407
- runId,
408
- totalCalls: sortedTools.length,
409
- callsWithCapturedArgs,
410
- byTool,
411
- errorRate: totalErrors / sortedTools.length,
412
- duplicateRate: callsWithCapturedArgs > 0 ? totalDuplicates / callsWithCapturedArgs : 0,
413
- retryRate,
414
- selectionAccuracy
415
- };
416
- }
417
-
418
- // src/trajectory.ts
419
- async function buildTrajectory(store, runId) {
420
- const spans = await store.spans({ runId });
421
- const events = await store.events({ runId });
422
- const childrenOf = /* @__PURE__ */ new Map();
423
- for (const s of spans) {
424
- const arr = childrenOf.get(s.parentSpanId) ?? [];
425
- arr.push(s);
426
- childrenOf.set(s.parentSpanId, arr);
427
- }
428
- for (const arr of childrenOf.values()) arr.sort((a, b) => a.startedAt - b.startedAt);
429
- const eventsBySpan = /* @__PURE__ */ new Map();
430
- for (const e of events) {
431
- if (!e.spanId) continue;
432
- const arr = eventsBySpan.get(e.spanId) ?? [];
433
- arr.push(e);
434
- eventsBySpan.set(e.spanId, arr);
435
- }
436
- const steps = [];
437
- const walk = (spanId, depth) => {
438
- const kids = childrenOf.get(spanId) ?? [];
439
- for (const child of kids) {
440
- steps.push({
441
- index: steps.length,
442
- span: child,
443
- depth,
444
- events: eventsBySpan.get(child.spanId) ?? []
445
- });
446
- walk(child.spanId, depth + 1);
447
- }
448
- };
449
- walk(void 0, 0);
450
- const llmTurns = steps.filter((s) => s.span.kind === "llm").length;
451
- const toolCalls = steps.filter((s) => s.span.kind === "tool").length;
452
- const judgeVerdicts = steps.filter((s) => s.span.kind === "judge").length;
453
- const retrievals = steps.filter((s) => s.span.kind === "retrieval").length;
454
- let totalDurationMs = 0;
455
- if (steps.length > 0) {
456
- const starts = spans.map((s) => s.startedAt);
457
- const ends = spans.map((s) => s.endedAt ?? s.startedAt);
458
- totalDurationMs = Math.max(...ends) - Math.min(...starts);
459
- }
460
- return { runId, steps, llmTurns, toolCalls, judgeVerdicts, retrievals, totalDurationMs };
461
- }
462
-
463
- // src/baseline.ts
464
- function compareToBaseline(samples, options = {}) {
465
- const effectThreshold = options.effectThreshold ?? 0.5;
466
- const alpha = options.alpha ?? 0.05;
467
- const cvThreshold = options.unstableCvThreshold ?? 0.3;
468
- const metrics = samples.map((s) => {
469
- if (s.baseline.length < 2 || s.candidate.length < 2) {
470
- throw new Error(`compareToBaseline: need \u22652 samples per side for "${s.metric}"`);
471
- }
472
- const bMean = mean(s.baseline);
473
- const cMean = mean(s.candidate);
474
- const delta = cMean - bMean;
475
- const d = cohensD(s.baseline, s.candidate);
476
- const { t, df, p } = welchsTTest(s.baseline, s.candidate);
477
- const baselineIqr = iqr(s.baseline);
478
- const candidateIqr = iqr(s.candidate);
479
- const baselineStable = baselineIqr / Math.max(Math.abs(bMean), 1e-9) <= cvThreshold;
480
- const candidateStable = candidateIqr / Math.max(Math.abs(cMean), 1e-9) <= cvThreshold;
481
- const stable = baselineStable && candidateStable;
482
- const reportedIqr = Math.max(baselineIqr, candidateIqr);
483
- let verdict;
484
- if (!stable) {
485
- verdict = "unstable";
486
- } else if (p < alpha && Math.abs(d) >= effectThreshold) {
487
- const candidateIsBetter = s.higherIsBetter ? delta > 0 : delta < 0;
488
- verdict = candidateIsBetter ? "improved" : "regressed";
489
- } else {
490
- verdict = "stable";
491
- }
492
- return {
493
- metric: s.metric,
494
- baselineMean: bMean,
495
- candidateMean: cMean,
496
- delta,
497
- cohensD: d,
498
- welchT: t,
499
- welchDf: df,
500
- welchP: p,
501
- stable,
502
- iqr: reportedIqr,
503
- verdict
504
- };
505
- });
506
- return {
507
- metrics,
508
- hasRegression: metrics.some((m) => m.verdict === "regressed"),
509
- hasUnstable: metrics.some((m) => m.verdict === "unstable")
510
- };
511
- }
512
- function mean(xs) {
513
- return xs.reduce((a, b) => a + b, 0) / xs.length;
514
- }
515
- function iqr(xs) {
516
- if (xs.length === 0) return 0;
517
- const sorted = [...xs].sort((a, b) => a - b);
518
- const q = (p) => {
519
- const idx = p * (sorted.length - 1);
520
- const lo = Math.floor(idx);
521
- const hi = Math.ceil(idx);
522
- return sorted[lo] + (sorted[hi] - sorted[lo]) * (idx - lo);
523
- };
524
- return q(0.75) - q(0.25);
525
- }
526
- function welchsTTest(a, b) {
527
- if (a.length < 2 || b.length < 2) return { t: 0, df: 0, p: 1 };
528
- const mA = mean(a);
529
- const mB = mean(b);
530
- const vA = variance(a, mA);
531
- const vB = variance(b, mB);
532
- const seSquared = vA / a.length + vB / b.length;
533
- if (seSquared === 0) return { t: mA === mB ? 0 : Infinity, df: 0, p: mA === mB ? 1 : 0 };
534
- const t = (mB - mA) / Math.sqrt(seSquared);
535
- const df = seSquared * seSquared / ((vA / a.length) ** 2 / (a.length - 1) + (vB / b.length) ** 2 / (b.length - 1));
536
- const p = 2 * (1 - studentTCdf(Math.abs(t), df));
537
- return { t, df, p };
538
- }
539
- function variance(xs, m) {
540
- return xs.reduce((acc, x) => acc + (x - m) ** 2, 0) / (xs.length - 1);
541
- }
542
- function studentTCdf(t, df) {
543
- if (df <= 0) return 0.5;
544
- if (df > 100) return normalCdf(t);
545
- const x = df / (df + t * t);
546
- const ib = incompleteBeta(x, df / 2, 0.5);
547
- return t >= 0 ? 1 - 0.5 * ib : 0.5 * ib;
548
- }
549
- function incompleteBeta(x, a, b) {
550
- if (x <= 0) return 0;
551
- if (x >= 1) return 1;
552
- const lnBeta = lnGamma(a) + lnGamma(b) - lnGamma(a + b);
553
- const front = Math.exp(Math.log(x) * a + Math.log(1 - x) * b - lnBeta) / a;
554
- let c = 1;
555
- let d = 1 - (a + b) * x / (a + 1);
556
- if (Math.abs(d) < 1e-30) d = 1e-30;
557
- d = 1 / d;
558
- let f = d;
559
- for (let m = 1; m <= 200; m++) {
560
- const m2 = 2 * m;
561
- let num = m * (b - m) * x / ((a + m2 - 1) * (a + m2));
562
- d = 1 + num * d;
563
- if (Math.abs(d) < 1e-30) d = 1e-30;
564
- c = 1 + num / c;
565
- if (Math.abs(c) < 1e-30) c = 1e-30;
566
- d = 1 / d;
567
- f *= d * c;
568
- num = -((a + m) * (a + b + m) * x) / ((a + m2) * (a + m2 + 1));
569
- d = 1 + num * d;
570
- if (Math.abs(d) < 1e-30) d = 1e-30;
571
- c = 1 + num / c;
572
- if (Math.abs(c) < 1e-30) c = 1e-30;
573
- d = 1 / d;
574
- const delta = d * c;
575
- f *= delta;
576
- if (Math.abs(delta - 1) < 3e-7) break;
577
- }
578
- return front * f;
579
- }
580
- function lnGamma(z) {
581
- const coefs = [
582
- 0.9999999999998099,
583
- 676.5203681218851,
584
- -1259.1392167224028,
585
- 771.3234287776531,
586
- -176.6150291621406,
587
- 12.507343278686905,
588
- -0.13857109526572012,
589
- 9984369578019572e-21,
590
- 15056327351493116e-23
591
- ];
592
- if (z < 0.5) return Math.log(Math.PI / Math.sin(Math.PI * z)) - lnGamma(1 - z);
593
- z -= 1;
594
- let x = coefs[0];
595
- for (let i = 1; i < 9; i++) x += coefs[i] / (z + i);
596
- const t = z + 7.5;
597
- return 0.5 * Math.log(2 * Math.PI) + (z + 0.5) * Math.log(t) - t + Math.log(x);
598
- }
599
- function normalCdf(x) {
600
- const a1 = 0.254829592;
601
- const a2 = -0.284496736;
602
- const a3 = 1.421413741;
603
- const a4 = -1.453152027;
604
- const a5 = 1.061405429;
605
- const p = 0.3275911;
606
- const sign = x < 0 ? -1 : 1;
607
- const absX = Math.abs(x);
608
- const t = 1 / (1 + p * absX);
609
- const y = 1 - ((((a5 * t + a4) * t + a3) * t + a2) * t + a1) * t * Math.exp(-absX * absX / 2);
610
- return 0.5 * (1 + sign * y);
611
- }
612
-
613
- export {
614
- DEFAULT_RULES,
615
- classifyFailure,
616
- computeToolUseMetrics,
617
- buildTrajectory,
618
- compareToBaseline,
619
- iqr,
620
- welchsTTest
621
- };
622
- //# sourceMappingURL=chunk-QBRSJK47.js.map