@caveman-ai/cloud 0.1.0-rc.21 → 0.1.0-rc.23
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/README.md +59 -5
- package/bin/ci.mjs +13 -5
- package/bin/cvm.mjs +250 -25
- package/bin/evals.mjs +621 -0
- package/dist/cloud-client.mjs +32 -31
- package/dist/cloud-mcp.mjs +13 -13
- package/dist/criterion-registry.json +1370 -0
- package/dist/skills/caveman-cloud/SKILL.md +129 -0
- package/dist/skills/caveman-cloud/references/caveman-cloud-compare.md +12 -0
- package/dist/skills/caveman-cloud/references/caveman-cloud-connect.md +54 -0
- package/dist/skills/caveman-cloud/references/caveman-cloud-dashboards.md +72 -0
- package/dist/skills/caveman-cloud/references/caveman-cloud-evals.md +202 -0
- package/dist/skills/caveman-cloud/references/caveman-cloud-project.md +97 -0
- package/dist/skills/caveman-cloud/references/caveman-cloud-scenarios.md +51 -0
- package/dist/skills/caveman-cloud/references/caveman-cloud-setup.md +174 -0
- package/dist/skills/caveman-cloud/references/caveman-cloud-strict-evals.md +52 -0
- package/dist/skills/caveman-cloud/references/caveman-cloud-traces.md +16 -0
- package/dist/skills/caveman-cloud/references/caveman-discover.md +143 -0
- package/dist/skills/caveman-cloud/references/caveman-evidence-review.md +64 -0
- package/dist/skills/caveman-cloud/references/caveman-manage.md +59 -0
- package/dist/skills/caveman-cloud/references/caveman-onboard.md +100 -0
- package/dist/skills/caveman-cloud/references/caveman-optimize.md +113 -0
- package/dist/skills/caveman-cloud/references/caveman-setup.md +282 -0
- package/dist/skills/caveman-cloud/references/caveman-sql.md +92 -0
- package/package.json +5 -2
|
@@ -0,0 +1,1370 @@
|
|
|
1
|
+
{
|
|
2
|
+
"note": "Generated from cloud/internal/evalworkbench/registry.go by `make generate-criterion-registry`. Do not edit by hand.",
|
|
3
|
+
"inputs": [
|
|
4
|
+
{
|
|
5
|
+
"name": "output",
|
|
6
|
+
"meaning": "The answer under test: a run's output for a case, a recorded unit's final answer."
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
"name": "expected",
|
|
10
|
+
"meaning": "The known good answer of a case. A recorded unit has none, so a kind that reads it runs on dataset rows only."
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"name": "context",
|
|
14
|
+
"meaning": "The passages retrieved for the answer. On a recorded trace a judge reads the retrieval steps; in a run the output must carry them, because a judge is shown the output alone."
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"name": "question",
|
|
18
|
+
"meaning": "What was asked: a case's input, a recorded unit's request. In a run a judge sees it only when the output repeats it, except for a pairwise question."
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"name": "baseline",
|
|
22
|
+
"meaning": "Another answer to the same case, to compare with."
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"name": "tool_calls",
|
|
26
|
+
"meaning": "The tool calls made, each with its name and arguments."
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"name": "metrics",
|
|
30
|
+
"meaning": "What was measured: latency, cost, tokens and the HTTP status."
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"name": "steps",
|
|
34
|
+
"meaning": "The recorded steps of a span, trace or task, in order."
|
|
35
|
+
}
|
|
36
|
+
],
|
|
37
|
+
"categories": [
|
|
38
|
+
{
|
|
39
|
+
"key": "match",
|
|
40
|
+
"label": "Text match"
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"key": "structure",
|
|
44
|
+
"label": "Structure"
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"key": "tools",
|
|
48
|
+
"label": "Tool calls"
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"key": "thresholds",
|
|
52
|
+
"label": "Thresholds"
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"key": "similarity",
|
|
56
|
+
"label": "Similarity"
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"key": "retrieval",
|
|
60
|
+
"label": "Retrieval"
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"key": "safety",
|
|
64
|
+
"label": "Safety"
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"key": "judge",
|
|
68
|
+
"label": "LLM judge"
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"key": "external",
|
|
72
|
+
"label": "External"
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"key": "trajectory",
|
|
76
|
+
"label": "Trajectory rules"
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"key": "code",
|
|
80
|
+
"label": "Code"
|
|
81
|
+
}
|
|
82
|
+
],
|
|
83
|
+
"kinds": [
|
|
84
|
+
{
|
|
85
|
+
"id": "exact_match",
|
|
86
|
+
"kind": "output_grader",
|
|
87
|
+
"name": "Exact match",
|
|
88
|
+
"checks": "Passes when the answer equals the expected value after trimming, case folding and key-order-insensitive JSON normalisation.",
|
|
89
|
+
"category": "match",
|
|
90
|
+
"inputs": [
|
|
91
|
+
"output",
|
|
92
|
+
"expected"
|
|
93
|
+
],
|
|
94
|
+
"options": [
|
|
95
|
+
{
|
|
96
|
+
"name": "expected",
|
|
97
|
+
"type": "any",
|
|
98
|
+
"required": false,
|
|
99
|
+
"description": "The value to compare against. The TypeScript grader object carries it here; the Python grade service reads the case reference instead, so a suite that only sets this option compares against the fixture reference on the service."
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"name": "case_sensitive",
|
|
103
|
+
"type": "boolean",
|
|
104
|
+
"required": false,
|
|
105
|
+
"default": false,
|
|
106
|
+
"description": "Skip the case-folding step; JSON normalisation is unchanged."
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"name": "remove_punctuation",
|
|
110
|
+
"type": "boolean",
|
|
111
|
+
"required": false,
|
|
112
|
+
"default": false,
|
|
113
|
+
"description": "Delete ASCII punctuation before comparing; string-only, and fails closed when either side is a structured value."
|
|
114
|
+
}
|
|
115
|
+
],
|
|
116
|
+
"calls_model": false,
|
|
117
|
+
"cost": "free"
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
"id": "contains",
|
|
121
|
+
"kind": "output_grader",
|
|
122
|
+
"name": "Contains",
|
|
123
|
+
"checks": "Passes when every listed fragment appears somewhere in the answer, matched case-sensitively as a substring.",
|
|
124
|
+
"category": "match",
|
|
125
|
+
"inputs": [
|
|
126
|
+
"output"
|
|
127
|
+
],
|
|
128
|
+
"options": [
|
|
129
|
+
{
|
|
130
|
+
"name": "fragments",
|
|
131
|
+
"type": "array",
|
|
132
|
+
"required": true,
|
|
133
|
+
"description": "Fragments that must all be present. Legacy behaviour kept for compatibility: the Python service stringifies a non-string member instead of failing."
|
|
134
|
+
}
|
|
135
|
+
],
|
|
136
|
+
"calls_model": false,
|
|
137
|
+
"cost": "free"
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
"id": "not_contains",
|
|
141
|
+
"kind": "output_grader",
|
|
142
|
+
"name": "Does not contain",
|
|
143
|
+
"checks": "Passes only when none of the listed fragments appear in the answer.",
|
|
144
|
+
"category": "match",
|
|
145
|
+
"inputs": [
|
|
146
|
+
"output"
|
|
147
|
+
],
|
|
148
|
+
"options": [
|
|
149
|
+
{
|
|
150
|
+
"name": "fragments",
|
|
151
|
+
"type": "array",
|
|
152
|
+
"required": true,
|
|
153
|
+
"description": "Forbidden fragments; a non-string member is an invalid option and fails closed."
|
|
154
|
+
}
|
|
155
|
+
],
|
|
156
|
+
"calls_model": false,
|
|
157
|
+
"cost": "free"
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
"id": "regex",
|
|
161
|
+
"kind": "output_grader",
|
|
162
|
+
"name": "Regex match",
|
|
163
|
+
"checks": "Passes when the pattern matches the answer, using each language's own regex engine on the portable pattern subset.",
|
|
164
|
+
"category": "match",
|
|
165
|
+
"inputs": [
|
|
166
|
+
"output"
|
|
167
|
+
],
|
|
168
|
+
"options": [
|
|
169
|
+
{
|
|
170
|
+
"name": "pattern",
|
|
171
|
+
"type": "string",
|
|
172
|
+
"required": true,
|
|
173
|
+
"description": "Regular expression searched in the answer text; an invalid pattern fails closed."
|
|
174
|
+
}
|
|
175
|
+
],
|
|
176
|
+
"calls_model": false,
|
|
177
|
+
"cost": "free"
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
"id": "not_regex",
|
|
181
|
+
"kind": "output_grader",
|
|
182
|
+
"name": "Regex must not match",
|
|
183
|
+
"checks": "Passes when the pattern does not match the answer, after CRLF and a single trailing newline are normalised away.",
|
|
184
|
+
"category": "match",
|
|
185
|
+
"inputs": [
|
|
186
|
+
"output"
|
|
187
|
+
],
|
|
188
|
+
"options": [
|
|
189
|
+
{
|
|
190
|
+
"name": "pattern",
|
|
191
|
+
"type": "string",
|
|
192
|
+
"required": true,
|
|
193
|
+
"description": "Regular expression that must not match; an empty or invalid pattern fails closed."
|
|
194
|
+
}
|
|
195
|
+
],
|
|
196
|
+
"calls_model": false,
|
|
197
|
+
"cost": "free"
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
"id": "blocklist",
|
|
201
|
+
"kind": "output_grader",
|
|
202
|
+
"name": "Blocklist",
|
|
203
|
+
"checks": "Passes when none of the listed terms appear as whole words in the answer, compared case-insensitively.",
|
|
204
|
+
"category": "safety",
|
|
205
|
+
"inputs": [
|
|
206
|
+
"output"
|
|
207
|
+
],
|
|
208
|
+
"options": [
|
|
209
|
+
{
|
|
210
|
+
"name": "terms",
|
|
211
|
+
"type": "array",
|
|
212
|
+
"required": true,
|
|
213
|
+
"description": "Forbidden terms; word boundaries are pinned lookarounds, not the engine's own word-character rule."
|
|
214
|
+
}
|
|
215
|
+
],
|
|
216
|
+
"calls_model": false,
|
|
217
|
+
"cost": "free"
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
"id": "json_schema",
|
|
221
|
+
"kind": "output_grader",
|
|
222
|
+
"name": "JSON schema",
|
|
223
|
+
"checks": "Passes when the answer satisfies a small JSON-Schema subset covering type, enum, required, properties and items only.",
|
|
224
|
+
"category": "structure",
|
|
225
|
+
"inputs": [
|
|
226
|
+
"output"
|
|
227
|
+
],
|
|
228
|
+
"options": [
|
|
229
|
+
{
|
|
230
|
+
"name": "schema",
|
|
231
|
+
"type": "object",
|
|
232
|
+
"required": true,
|
|
233
|
+
"description": "The subset schema the answer must satisfy; an unknown type name fails closed."
|
|
234
|
+
}
|
|
235
|
+
],
|
|
236
|
+
"calls_model": false,
|
|
237
|
+
"cost": "free"
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
"id": "json_path_assertion",
|
|
241
|
+
"kind": "output_grader",
|
|
242
|
+
"name": "JSON path",
|
|
243
|
+
"checks": "Passes when the dotted path resolves in the answer and, when equals is set, holds that value.",
|
|
244
|
+
"category": "structure",
|
|
245
|
+
"inputs": [
|
|
246
|
+
"output"
|
|
247
|
+
],
|
|
248
|
+
"options": [
|
|
249
|
+
{
|
|
250
|
+
"name": "path",
|
|
251
|
+
"type": "string",
|
|
252
|
+
"required": true,
|
|
253
|
+
"description": "Dot-separated path; array steps are numeric indexes."
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
"name": "equals",
|
|
257
|
+
"type": "any",
|
|
258
|
+
"required": false,
|
|
259
|
+
"description": "Optional value assertion at the path; comparison is type-strict."
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
"name": "exists",
|
|
263
|
+
"type": "boolean",
|
|
264
|
+
"required": false,
|
|
265
|
+
"description": "Assert only presence (true) or absence (false) of the path, ignoring equals."
|
|
266
|
+
}
|
|
267
|
+
],
|
|
268
|
+
"calls_model": false,
|
|
269
|
+
"cost": "free"
|
|
270
|
+
},
|
|
271
|
+
{
|
|
272
|
+
"id": "tool_called",
|
|
273
|
+
"kind": "output_grader",
|
|
274
|
+
"name": "Tool called",
|
|
275
|
+
"checks": "Passes when every listed tool appears in the answer's tool calls.",
|
|
276
|
+
"category": "tools",
|
|
277
|
+
"inputs": [
|
|
278
|
+
"tool_calls"
|
|
279
|
+
],
|
|
280
|
+
"options": [
|
|
281
|
+
{
|
|
282
|
+
"name": "tools",
|
|
283
|
+
"type": "array",
|
|
284
|
+
"required": true,
|
|
285
|
+
"description": "Tool names that must all have been called."
|
|
286
|
+
}
|
|
287
|
+
],
|
|
288
|
+
"calls_model": false,
|
|
289
|
+
"cost": "free"
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
"id": "tool_not_called",
|
|
293
|
+
"kind": "output_grader",
|
|
294
|
+
"name": "Tool not called",
|
|
295
|
+
"checks": "Passes when none of the listed tools appear in the answer's tool calls.",
|
|
296
|
+
"category": "tools",
|
|
297
|
+
"inputs": [
|
|
298
|
+
"tool_calls"
|
|
299
|
+
],
|
|
300
|
+
"options": [
|
|
301
|
+
{
|
|
302
|
+
"name": "tools",
|
|
303
|
+
"type": "array",
|
|
304
|
+
"required": true,
|
|
305
|
+
"description": "Tool names that must not have been called."
|
|
306
|
+
}
|
|
307
|
+
],
|
|
308
|
+
"calls_model": false,
|
|
309
|
+
"cost": "free"
|
|
310
|
+
},
|
|
311
|
+
{
|
|
312
|
+
"id": "tool_sequence",
|
|
313
|
+
"kind": "output_grader",
|
|
314
|
+
"name": "Tool sequence",
|
|
315
|
+
"checks": "Passes when the listed tools appear as an ordered subsequence of the tool calls; other calls may sit between them.",
|
|
316
|
+
"category": "tools",
|
|
317
|
+
"inputs": [
|
|
318
|
+
"tool_calls"
|
|
319
|
+
],
|
|
320
|
+
"options": [
|
|
321
|
+
{
|
|
322
|
+
"name": "tools",
|
|
323
|
+
"type": "array",
|
|
324
|
+
"required": true,
|
|
325
|
+
"description": "Tool names in the order they must appear."
|
|
326
|
+
}
|
|
327
|
+
],
|
|
328
|
+
"calls_model": false,
|
|
329
|
+
"cost": "free"
|
|
330
|
+
},
|
|
331
|
+
{
|
|
332
|
+
"id": "tool_argument_assertion",
|
|
333
|
+
"kind": "output_grader",
|
|
334
|
+
"name": "Tool argument",
|
|
335
|
+
"checks": "Passes when some call to the named tool carries the argument at path equal to the expected value.",
|
|
336
|
+
"category": "tools",
|
|
337
|
+
"inputs": [
|
|
338
|
+
"tool_calls"
|
|
339
|
+
],
|
|
340
|
+
"options": [
|
|
341
|
+
{
|
|
342
|
+
"name": "tool",
|
|
343
|
+
"type": "string",
|
|
344
|
+
"required": true,
|
|
345
|
+
"description": "Name of the tool call to inspect."
|
|
346
|
+
},
|
|
347
|
+
{
|
|
348
|
+
"name": "path",
|
|
349
|
+
"type": "string",
|
|
350
|
+
"required": true,
|
|
351
|
+
"description": "Dot-separated path inside that call's arguments."
|
|
352
|
+
},
|
|
353
|
+
{
|
|
354
|
+
"name": "equals",
|
|
355
|
+
"type": "any",
|
|
356
|
+
"required": true,
|
|
357
|
+
"description": "Value the argument must equal; comparison is type-strict."
|
|
358
|
+
}
|
|
359
|
+
],
|
|
360
|
+
"calls_model": false,
|
|
361
|
+
"cost": "free"
|
|
362
|
+
},
|
|
363
|
+
{
|
|
364
|
+
"id": "http_status",
|
|
365
|
+
"kind": "output_grader",
|
|
366
|
+
"name": "HTTP status",
|
|
367
|
+
"checks": "Passes when the answer's status field equals the expected status code; an answer without a status fails.",
|
|
368
|
+
"category": "thresholds",
|
|
369
|
+
"inputs": [
|
|
370
|
+
"metrics"
|
|
371
|
+
],
|
|
372
|
+
"options": [
|
|
373
|
+
{
|
|
374
|
+
"name": "status",
|
|
375
|
+
"type": "integer",
|
|
376
|
+
"required": true,
|
|
377
|
+
"description": "Expected status, read from the answer's status or status_code field."
|
|
378
|
+
}
|
|
379
|
+
],
|
|
380
|
+
"calls_model": false,
|
|
381
|
+
"cost": "free"
|
|
382
|
+
},
|
|
383
|
+
{
|
|
384
|
+
"id": "latency_threshold",
|
|
385
|
+
"kind": "output_grader",
|
|
386
|
+
"name": "Latency ceiling",
|
|
387
|
+
"checks": "Passes when the answer's recorded p95 latency is at or under the ceiling; an unmeasured answer fails.",
|
|
388
|
+
"category": "thresholds",
|
|
389
|
+
"inputs": [
|
|
390
|
+
"metrics"
|
|
391
|
+
],
|
|
392
|
+
"options": [
|
|
393
|
+
{
|
|
394
|
+
"name": "p95_ms",
|
|
395
|
+
"type": "number",
|
|
396
|
+
"required": true,
|
|
397
|
+
"description": "Ceiling in milliseconds, compared against the answer's p95_ms or latency_ms field."
|
|
398
|
+
}
|
|
399
|
+
],
|
|
400
|
+
"calls_model": false,
|
|
401
|
+
"cost": "free"
|
|
402
|
+
},
|
|
403
|
+
{
|
|
404
|
+
"id": "cost_threshold",
|
|
405
|
+
"kind": "output_grader",
|
|
406
|
+
"name": "Cost ceiling",
|
|
407
|
+
"checks": "Passes when the answer's recorded cost is at or under the ceiling; an unmeasured answer fails.",
|
|
408
|
+
"category": "thresholds",
|
|
409
|
+
"inputs": [
|
|
410
|
+
"metrics"
|
|
411
|
+
],
|
|
412
|
+
"options": [
|
|
413
|
+
{
|
|
414
|
+
"name": "max_usd",
|
|
415
|
+
"type": "number",
|
|
416
|
+
"required": true,
|
|
417
|
+
"description": "Ceiling in US dollars, compared against the answer's cost_usd or total_cost_usd field."
|
|
418
|
+
}
|
|
419
|
+
],
|
|
420
|
+
"calls_model": false,
|
|
421
|
+
"cost": "free"
|
|
422
|
+
},
|
|
423
|
+
{
|
|
424
|
+
"id": "token_threshold",
|
|
425
|
+
"kind": "output_grader",
|
|
426
|
+
"name": "Token ceiling",
|
|
427
|
+
"checks": "Passes when the answer's recorded token count is at or under the ceiling; an unmeasured answer fails.",
|
|
428
|
+
"category": "thresholds",
|
|
429
|
+
"inputs": [
|
|
430
|
+
"metrics"
|
|
431
|
+
],
|
|
432
|
+
"options": [
|
|
433
|
+
{
|
|
434
|
+
"name": "max_tokens",
|
|
435
|
+
"type": "number",
|
|
436
|
+
"required": true,
|
|
437
|
+
"description": "Ceiling in tokens, compared against the answer's tokens or total_tokens field."
|
|
438
|
+
}
|
|
439
|
+
],
|
|
440
|
+
"calls_model": false,
|
|
441
|
+
"cost": "free"
|
|
442
|
+
},
|
|
443
|
+
{
|
|
444
|
+
"id": "bleu_score",
|
|
445
|
+
"kind": "output_grader",
|
|
446
|
+
"name": "BLEU score",
|
|
447
|
+
"checks": "Modified n-gram precision with a brevity penalty against a reference string on a pinned tokenizer, so it is deterministic but not comparable to published sacrebleu numbers.",
|
|
448
|
+
"category": "similarity",
|
|
449
|
+
"inputs": [
|
|
450
|
+
"output",
|
|
451
|
+
"expected"
|
|
452
|
+
],
|
|
453
|
+
"options": [
|
|
454
|
+
{
|
|
455
|
+
"name": "reference",
|
|
456
|
+
"type": "string",
|
|
457
|
+
"required": true,
|
|
458
|
+
"description": "Reference text; the Python service falls back to the case reference when this option is absent."
|
|
459
|
+
},
|
|
460
|
+
{
|
|
461
|
+
"name": "threshold",
|
|
462
|
+
"type": "number",
|
|
463
|
+
"required": false,
|
|
464
|
+
"default": 0.5,
|
|
465
|
+
"description": "Score the answer must reach to pass."
|
|
466
|
+
}
|
|
467
|
+
],
|
|
468
|
+
"calls_model": false,
|
|
469
|
+
"cost": "free"
|
|
470
|
+
},
|
|
471
|
+
{
|
|
472
|
+
"id": "rouge_score",
|
|
473
|
+
"kind": "output_grader",
|
|
474
|
+
"name": "ROUGE score",
|
|
475
|
+
"checks": "Unigram or longest-common-subsequence overlap against a reference string on the same pinned tokenizer, so it is deterministic but not comparable to published rouge-score numbers.",
|
|
476
|
+
"category": "similarity",
|
|
477
|
+
"inputs": [
|
|
478
|
+
"output",
|
|
479
|
+
"expected"
|
|
480
|
+
],
|
|
481
|
+
"options": [
|
|
482
|
+
{
|
|
483
|
+
"name": "reference",
|
|
484
|
+
"type": "string",
|
|
485
|
+
"required": true,
|
|
486
|
+
"description": "Reference text; the Python service falls back to the case reference when this option is absent."
|
|
487
|
+
},
|
|
488
|
+
{
|
|
489
|
+
"name": "rouge_type",
|
|
490
|
+
"type": "string",
|
|
491
|
+
"required": false,
|
|
492
|
+
"default": "rouge_1",
|
|
493
|
+
"enum": [
|
|
494
|
+
"rouge_1",
|
|
495
|
+
"rouge_l"
|
|
496
|
+
],
|
|
497
|
+
"description": "Unigram overlap or longest common subsequence."
|
|
498
|
+
},
|
|
499
|
+
{
|
|
500
|
+
"name": "measure",
|
|
501
|
+
"type": "string",
|
|
502
|
+
"required": false,
|
|
503
|
+
"default": "fmeasure",
|
|
504
|
+
"enum": [
|
|
505
|
+
"precision",
|
|
506
|
+
"recall",
|
|
507
|
+
"fmeasure"
|
|
508
|
+
],
|
|
509
|
+
"description": "Which figure the threshold is applied to."
|
|
510
|
+
},
|
|
511
|
+
{
|
|
512
|
+
"name": "threshold",
|
|
513
|
+
"type": "number",
|
|
514
|
+
"required": false,
|
|
515
|
+
"default": 0.5,
|
|
516
|
+
"description": "Score the answer must reach to pass."
|
|
517
|
+
}
|
|
518
|
+
],
|
|
519
|
+
"calls_model": false,
|
|
520
|
+
"cost": "free"
|
|
521
|
+
},
|
|
522
|
+
{
|
|
523
|
+
"id": "context_f1",
|
|
524
|
+
"kind": "output_grader",
|
|
525
|
+
"name": "Context F1",
|
|
526
|
+
"checks": "Precision, recall or F1 between the retrieved and expected context lists, matched by normalised Levenshtein similarity.",
|
|
527
|
+
"category": "retrieval",
|
|
528
|
+
"inputs": [
|
|
529
|
+
"context",
|
|
530
|
+
"expected"
|
|
531
|
+
],
|
|
532
|
+
"options": [
|
|
533
|
+
{
|
|
534
|
+
"name": "retrieved",
|
|
535
|
+
"type": "array",
|
|
536
|
+
"required": true,
|
|
537
|
+
"description": "Context chunks the system retrieved; both lists ride on the options and the answer value is unused."
|
|
538
|
+
},
|
|
539
|
+
{
|
|
540
|
+
"name": "expected",
|
|
541
|
+
"type": "array",
|
|
542
|
+
"required": true,
|
|
543
|
+
"description": "Context chunks that should have been retrieved."
|
|
544
|
+
},
|
|
545
|
+
{
|
|
546
|
+
"name": "measure",
|
|
547
|
+
"type": "string",
|
|
548
|
+
"required": false,
|
|
549
|
+
"default": "f1",
|
|
550
|
+
"enum": [
|
|
551
|
+
"precision",
|
|
552
|
+
"recall",
|
|
553
|
+
"f1"
|
|
554
|
+
],
|
|
555
|
+
"description": "Which figure the threshold is applied to."
|
|
556
|
+
},
|
|
557
|
+
{
|
|
558
|
+
"name": "similarity_threshold",
|
|
559
|
+
"type": "number",
|
|
560
|
+
"required": false,
|
|
561
|
+
"default": 0.7,
|
|
562
|
+
"description": "Similarity at which two chunks count as the same chunk."
|
|
563
|
+
},
|
|
564
|
+
{
|
|
565
|
+
"name": "threshold",
|
|
566
|
+
"type": "number",
|
|
567
|
+
"required": false,
|
|
568
|
+
"default": 0.5,
|
|
569
|
+
"description": "Score the answer must reach to pass."
|
|
570
|
+
}
|
|
571
|
+
],
|
|
572
|
+
"calls_model": false,
|
|
573
|
+
"cost": "free"
|
|
574
|
+
},
|
|
575
|
+
{
|
|
576
|
+
"id": "no_pii",
|
|
577
|
+
"kind": "output_grader",
|
|
578
|
+
"name": "No PII",
|
|
579
|
+
"checks": "Fails when the answer matches any selected PII pattern, using a conservative regex subset with checksum-valid cards and IBANs and international phone numbers only, not Presidio.",
|
|
580
|
+
"category": "safety",
|
|
581
|
+
"inputs": [
|
|
582
|
+
"output"
|
|
583
|
+
],
|
|
584
|
+
"options": [
|
|
585
|
+
{
|
|
586
|
+
"name": "entities",
|
|
587
|
+
"type": "array",
|
|
588
|
+
"required": false,
|
|
589
|
+
"description": "Entity kinds to look for; absent means all seven, and an unknown name fails closed."
|
|
590
|
+
}
|
|
591
|
+
],
|
|
592
|
+
"calls_model": false,
|
|
593
|
+
"cost": "free"
|
|
594
|
+
},
|
|
595
|
+
{
|
|
596
|
+
"id": "localization_f1",
|
|
597
|
+
"kind": "output_grader",
|
|
598
|
+
"name": "Localization F1",
|
|
599
|
+
"checks": "Scores cited files and line ranges against a gold localization set; file-level F1 and mean line-range overlap must both clear their thresholds.",
|
|
600
|
+
"category": "retrieval",
|
|
601
|
+
"inputs": [
|
|
602
|
+
"output",
|
|
603
|
+
"expected"
|
|
604
|
+
],
|
|
605
|
+
"options": [
|
|
606
|
+
{
|
|
607
|
+
"name": "reference",
|
|
608
|
+
"type": "any",
|
|
609
|
+
"required": false,
|
|
610
|
+
"description": "The gold localization set. The TypeScript grader object carries it here; the Python grade service reads the case reference instead."
|
|
611
|
+
},
|
|
612
|
+
{
|
|
613
|
+
"name": "threshold",
|
|
614
|
+
"type": "number",
|
|
615
|
+
"required": false,
|
|
616
|
+
"default": 0.5,
|
|
617
|
+
"description": "Default threshold for both figures."
|
|
618
|
+
},
|
|
619
|
+
{
|
|
620
|
+
"name": "file_threshold",
|
|
621
|
+
"type": "number",
|
|
622
|
+
"required": false,
|
|
623
|
+
"description": "File-level F1 the answer must reach; defaults to threshold."
|
|
624
|
+
},
|
|
625
|
+
{
|
|
626
|
+
"name": "line_threshold",
|
|
627
|
+
"type": "number",
|
|
628
|
+
"required": false,
|
|
629
|
+
"description": "Mean line-range overlap the answer must reach; defaults to threshold."
|
|
630
|
+
}
|
|
631
|
+
],
|
|
632
|
+
"calls_model": false,
|
|
633
|
+
"cost": "free"
|
|
634
|
+
},
|
|
635
|
+
{
|
|
636
|
+
"id": "custom_webhook",
|
|
637
|
+
"kind": "output_grader",
|
|
638
|
+
"name": "Custom webhook",
|
|
639
|
+
"checks": "Posts the answer to your endpoint — the url is SSRF-checked before the call and redirects are refused, not followed — and takes the verdict from a system Caveman does not control; a blocked url, a redirect, a transport error or a missing verdict fails.",
|
|
640
|
+
"category": "external",
|
|
641
|
+
"inputs": [
|
|
642
|
+
"output"
|
|
643
|
+
],
|
|
644
|
+
"options": [
|
|
645
|
+
{
|
|
646
|
+
"name": "url",
|
|
647
|
+
"type": "string",
|
|
648
|
+
"required": true,
|
|
649
|
+
"description": "Endpoint that receives the answer and returns {\"passed\": bool, \"reason\": string}."
|
|
650
|
+
},
|
|
651
|
+
{
|
|
652
|
+
"name": "timeout_s",
|
|
653
|
+
"type": "number",
|
|
654
|
+
"required": false,
|
|
655
|
+
"default": 5,
|
|
656
|
+
"description": "Request timeout on the Python grade service; the TypeScript package uses its injected fetch instead."
|
|
657
|
+
}
|
|
658
|
+
],
|
|
659
|
+
"extra_options": true,
|
|
660
|
+
"calls_model": false,
|
|
661
|
+
"cost": "external_call"
|
|
662
|
+
},
|
|
663
|
+
{
|
|
664
|
+
"id": "llm_judge",
|
|
665
|
+
"kind": "question",
|
|
666
|
+
"name": "LLM judge",
|
|
667
|
+
"checks": "Asks the project's judge whether the answer meets a rubric; an answer the judge is not sure of is inconclusive, never a pass or a fail.",
|
|
668
|
+
"category": "judge",
|
|
669
|
+
"inputs": [
|
|
670
|
+
"output"
|
|
671
|
+
],
|
|
672
|
+
"options": [
|
|
673
|
+
{
|
|
674
|
+
"name": "rubric",
|
|
675
|
+
"type": "string",
|
|
676
|
+
"required": true,
|
|
677
|
+
"description": "What the judge should check."
|
|
678
|
+
},
|
|
679
|
+
{
|
|
680
|
+
"name": "gateway_url",
|
|
681
|
+
"type": "string",
|
|
682
|
+
"required": false,
|
|
683
|
+
"description": "Caveman gateway base URL the judge call goes through; the TypeScript package fails closed without it, the Python service falls back to $CAVE_GATEWAY_URL."
|
|
684
|
+
},
|
|
685
|
+
{
|
|
686
|
+
"name": "model",
|
|
687
|
+
"type": "string",
|
|
688
|
+
"required": false,
|
|
689
|
+
"default": "gpt-5.5",
|
|
690
|
+
"description": "Judge model; pin it for any gate that uses a judge."
|
|
691
|
+
},
|
|
692
|
+
{
|
|
693
|
+
"name": "api_key",
|
|
694
|
+
"type": "string",
|
|
695
|
+
"required": false,
|
|
696
|
+
"description": "Project gateway key for the judge call. Required: a judge never falls back to a service credential."
|
|
697
|
+
},
|
|
698
|
+
{
|
|
699
|
+
"name": "upstream_key",
|
|
700
|
+
"type": "string",
|
|
701
|
+
"required": false,
|
|
702
|
+
"description": "Upstream provider key forwarded to the gateway; leave unset to use the project's stored provider credential."
|
|
703
|
+
},
|
|
704
|
+
{
|
|
705
|
+
"name": "subject_model",
|
|
706
|
+
"type": "string",
|
|
707
|
+
"required": false,
|
|
708
|
+
"description": "Model that produced the answer; the bias guard fails closed when it shares a family with the judge. The TypeScript package takes this from GradeDeps rather than options."
|
|
709
|
+
},
|
|
710
|
+
{
|
|
711
|
+
"name": "timeout_s",
|
|
712
|
+
"type": "number",
|
|
713
|
+
"required": false,
|
|
714
|
+
"default": 15,
|
|
715
|
+
"description": "Judge-call timeout on the Python grade service; the TypeScript package uses its injected fetch instead."
|
|
716
|
+
}
|
|
717
|
+
],
|
|
718
|
+
"calls_model": true,
|
|
719
|
+
"cost": "judge_call"
|
|
720
|
+
},
|
|
721
|
+
{
|
|
722
|
+
"id": "llm_score",
|
|
723
|
+
"kind": "question",
|
|
724
|
+
"name": "LLM score",
|
|
725
|
+
"checks": "Asks the project's judge to place the answer on a five-level scale against a rubric and passes when the score, from 0 to 1, reaches min_score.",
|
|
726
|
+
"category": "judge",
|
|
727
|
+
"inputs": [
|
|
728
|
+
"output"
|
|
729
|
+
],
|
|
730
|
+
"options": [
|
|
731
|
+
{
|
|
732
|
+
"name": "rubric",
|
|
733
|
+
"type": "string",
|
|
734
|
+
"required": true,
|
|
735
|
+
"description": "What the judge should score against."
|
|
736
|
+
},
|
|
737
|
+
{
|
|
738
|
+
"name": "min_score",
|
|
739
|
+
"type": "number",
|
|
740
|
+
"required": true,
|
|
741
|
+
"description": "Score the answer must reach; the comparison is inclusive and runs on the unrounded value."
|
|
742
|
+
},
|
|
743
|
+
{
|
|
744
|
+
"name": "gateway_url",
|
|
745
|
+
"type": "string",
|
|
746
|
+
"required": false,
|
|
747
|
+
"description": "Caveman gateway base URL the judge call goes through; the TypeScript package fails closed without it, the Python service falls back to $CAVE_GATEWAY_URL."
|
|
748
|
+
},
|
|
749
|
+
{
|
|
750
|
+
"name": "model",
|
|
751
|
+
"type": "string",
|
|
752
|
+
"required": false,
|
|
753
|
+
"default": "gpt-5.5",
|
|
754
|
+
"description": "Judge model; pin it for any gate that uses a judge."
|
|
755
|
+
},
|
|
756
|
+
{
|
|
757
|
+
"name": "api_key",
|
|
758
|
+
"type": "string",
|
|
759
|
+
"required": false,
|
|
760
|
+
"description": "Project gateway key for the judge call. Required: a judge never falls back to a service credential."
|
|
761
|
+
},
|
|
762
|
+
{
|
|
763
|
+
"name": "upstream_key",
|
|
764
|
+
"type": "string",
|
|
765
|
+
"required": false,
|
|
766
|
+
"description": "Upstream provider key forwarded to the gateway; leave unset to use the project's stored provider credential."
|
|
767
|
+
},
|
|
768
|
+
{
|
|
769
|
+
"name": "subject_model",
|
|
770
|
+
"type": "string",
|
|
771
|
+
"required": false,
|
|
772
|
+
"description": "Model that produced the answer; the bias guard fails closed when it shares a family with the judge. The TypeScript package takes this from GradeDeps rather than options."
|
|
773
|
+
},
|
|
774
|
+
{
|
|
775
|
+
"name": "timeout_s",
|
|
776
|
+
"type": "number",
|
|
777
|
+
"required": false,
|
|
778
|
+
"default": 15,
|
|
779
|
+
"description": "Judge-call timeout on the Python grade service; the TypeScript package uses its injected fetch instead."
|
|
780
|
+
}
|
|
781
|
+
],
|
|
782
|
+
"calls_model": true,
|
|
783
|
+
"cost": "judge_call"
|
|
784
|
+
},
|
|
785
|
+
{
|
|
786
|
+
"id": "llm_category",
|
|
787
|
+
"kind": "question",
|
|
788
|
+
"name": "LLM category",
|
|
789
|
+
"checks": "Asks the project's judge to put the answer in exactly one of your categories and passes when that category is one of the passing ones.",
|
|
790
|
+
"category": "judge",
|
|
791
|
+
"inputs": [
|
|
792
|
+
"output"
|
|
793
|
+
],
|
|
794
|
+
"options": [
|
|
795
|
+
{
|
|
796
|
+
"name": "prompt",
|
|
797
|
+
"type": "string",
|
|
798
|
+
"required": true,
|
|
799
|
+
"description": "How the judge should classify the answer."
|
|
800
|
+
},
|
|
801
|
+
{
|
|
802
|
+
"name": "categories",
|
|
803
|
+
"type": "array",
|
|
804
|
+
"required": true,
|
|
805
|
+
"description": "The full category list, unique case-insensitively; the prompt lists them joined with a comma and a space."
|
|
806
|
+
},
|
|
807
|
+
{
|
|
808
|
+
"name": "passing_categories",
|
|
809
|
+
"type": "array",
|
|
810
|
+
"required": true,
|
|
811
|
+
"description": "Categories that count as a pass; every entry must be one of categories."
|
|
812
|
+
},
|
|
813
|
+
{
|
|
814
|
+
"name": "gateway_url",
|
|
815
|
+
"type": "string",
|
|
816
|
+
"required": false,
|
|
817
|
+
"description": "Caveman gateway base URL the judge call goes through; the TypeScript package fails closed without it, the Python service falls back to $CAVE_GATEWAY_URL."
|
|
818
|
+
},
|
|
819
|
+
{
|
|
820
|
+
"name": "model",
|
|
821
|
+
"type": "string",
|
|
822
|
+
"required": false,
|
|
823
|
+
"default": "gpt-5.5",
|
|
824
|
+
"description": "Judge model; pin it for any gate that uses a judge."
|
|
825
|
+
},
|
|
826
|
+
{
|
|
827
|
+
"name": "api_key",
|
|
828
|
+
"type": "string",
|
|
829
|
+
"required": false,
|
|
830
|
+
"description": "Project gateway key for the judge call. Required: a judge never falls back to a service credential."
|
|
831
|
+
},
|
|
832
|
+
{
|
|
833
|
+
"name": "upstream_key",
|
|
834
|
+
"type": "string",
|
|
835
|
+
"required": false,
|
|
836
|
+
"description": "Upstream provider key forwarded to the gateway; leave unset to use the project's stored provider credential."
|
|
837
|
+
},
|
|
838
|
+
{
|
|
839
|
+
"name": "subject_model",
|
|
840
|
+
"type": "string",
|
|
841
|
+
"required": false,
|
|
842
|
+
"description": "Model that produced the answer; the bias guard fails closed when it shares a family with the judge. The TypeScript package takes this from GradeDeps rather than options."
|
|
843
|
+
},
|
|
844
|
+
{
|
|
845
|
+
"name": "timeout_s",
|
|
846
|
+
"type": "number",
|
|
847
|
+
"required": false,
|
|
848
|
+
"default": 15,
|
|
849
|
+
"description": "Judge-call timeout on the Python grade service; the TypeScript package uses its injected fetch instead."
|
|
850
|
+
}
|
|
851
|
+
],
|
|
852
|
+
"calls_model": true,
|
|
853
|
+
"cost": "judge_call"
|
|
854
|
+
},
|
|
855
|
+
{
|
|
856
|
+
"id": "llm_pairwise",
|
|
857
|
+
"kind": "question",
|
|
858
|
+
"name": "LLM pairwise",
|
|
859
|
+
"checks": "Asks the project's judge to compare the answer against a baseline in both orders, two judge calls, and passes only when the baseline wins neither.",
|
|
860
|
+
"category": "judge",
|
|
861
|
+
"inputs": [
|
|
862
|
+
"question",
|
|
863
|
+
"output",
|
|
864
|
+
"baseline"
|
|
865
|
+
],
|
|
866
|
+
"options": [
|
|
867
|
+
{
|
|
868
|
+
"name": "baseline",
|
|
869
|
+
"type": "string",
|
|
870
|
+
"required": true,
|
|
871
|
+
"description": "The response the answer is compared against."
|
|
872
|
+
},
|
|
873
|
+
{
|
|
874
|
+
"name": "criteria",
|
|
875
|
+
"type": "string",
|
|
876
|
+
"required": true,
|
|
877
|
+
"description": "What makes one response better than the other."
|
|
878
|
+
},
|
|
879
|
+
{
|
|
880
|
+
"name": "gateway_url",
|
|
881
|
+
"type": "string",
|
|
882
|
+
"required": false,
|
|
883
|
+
"description": "Caveman gateway base URL the judge call goes through; the TypeScript package fails closed without it, the Python service falls back to $CAVE_GATEWAY_URL."
|
|
884
|
+
},
|
|
885
|
+
{
|
|
886
|
+
"name": "model",
|
|
887
|
+
"type": "string",
|
|
888
|
+
"required": false,
|
|
889
|
+
"default": "gpt-5.5",
|
|
890
|
+
"description": "Judge model; pin it for any gate that uses a judge."
|
|
891
|
+
},
|
|
892
|
+
{
|
|
893
|
+
"name": "api_key",
|
|
894
|
+
"type": "string",
|
|
895
|
+
"required": false,
|
|
896
|
+
"description": "Project gateway key for the judge call. Required: a judge never falls back to a service credential."
|
|
897
|
+
},
|
|
898
|
+
{
|
|
899
|
+
"name": "upstream_key",
|
|
900
|
+
"type": "string",
|
|
901
|
+
"required": false,
|
|
902
|
+
"description": "Upstream provider key forwarded to the gateway; leave unset to use the project's stored provider credential."
|
|
903
|
+
},
|
|
904
|
+
{
|
|
905
|
+
"name": "subject_model",
|
|
906
|
+
"type": "string",
|
|
907
|
+
"required": false,
|
|
908
|
+
"description": "Model that produced the answer; the bias guard fails closed when it shares a family with the judge. The TypeScript package takes this from GradeDeps rather than options."
|
|
909
|
+
},
|
|
910
|
+
{
|
|
911
|
+
"name": "timeout_s",
|
|
912
|
+
"type": "number",
|
|
913
|
+
"required": false,
|
|
914
|
+
"default": 15,
|
|
915
|
+
"description": "Judge-call timeout on the Python grade service; the TypeScript package uses its injected fetch instead."
|
|
916
|
+
}
|
|
917
|
+
],
|
|
918
|
+
"calls_model": true,
|
|
919
|
+
"cost": "two_judge_calls"
|
|
920
|
+
},
|
|
921
|
+
{
|
|
922
|
+
"id": "llm_answer_match",
|
|
923
|
+
"kind": "question",
|
|
924
|
+
"name": "LLM answer match",
|
|
925
|
+
"checks": "Asks the project's judge whether the answer conveys the same answer as the expected one, ignoring wording and formatting.",
|
|
926
|
+
"category": "judge",
|
|
927
|
+
"inputs": [
|
|
928
|
+
"output",
|
|
929
|
+
"expected"
|
|
930
|
+
],
|
|
931
|
+
"options": [
|
|
932
|
+
{
|
|
933
|
+
"name": "expected",
|
|
934
|
+
"type": "string",
|
|
935
|
+
"required": false,
|
|
936
|
+
"description": "The answer the response should convey. The TypeScript grader object carries it here; the Python grade service falls back to the case reference when this option is unset, so a suite that sets neither fails closed."
|
|
937
|
+
},
|
|
938
|
+
{
|
|
939
|
+
"name": "gateway_url",
|
|
940
|
+
"type": "string",
|
|
941
|
+
"required": false,
|
|
942
|
+
"description": "Caveman gateway base URL the judge call goes through; the TypeScript package fails closed without it, the Python service falls back to $CAVE_GATEWAY_URL."
|
|
943
|
+
},
|
|
944
|
+
{
|
|
945
|
+
"name": "model",
|
|
946
|
+
"type": "string",
|
|
947
|
+
"required": false,
|
|
948
|
+
"default": "gpt-5.5",
|
|
949
|
+
"description": "Judge model; pin it for any gate that uses a judge."
|
|
950
|
+
},
|
|
951
|
+
{
|
|
952
|
+
"name": "api_key",
|
|
953
|
+
"type": "string",
|
|
954
|
+
"required": false,
|
|
955
|
+
"description": "Project gateway key for the judge call. Required: a judge never falls back to a service credential."
|
|
956
|
+
},
|
|
957
|
+
{
|
|
958
|
+
"name": "upstream_key",
|
|
959
|
+
"type": "string",
|
|
960
|
+
"required": false,
|
|
961
|
+
"description": "Upstream provider key forwarded to the gateway; leave unset to use the project's stored provider credential."
|
|
962
|
+
},
|
|
963
|
+
{
|
|
964
|
+
"name": "subject_model",
|
|
965
|
+
"type": "string",
|
|
966
|
+
"required": false,
|
|
967
|
+
"description": "Model that produced the answer; the bias guard fails closed when it shares a family with the judge. The TypeScript package takes this from GradeDeps rather than options."
|
|
968
|
+
},
|
|
969
|
+
{
|
|
970
|
+
"name": "timeout_s",
|
|
971
|
+
"type": "number",
|
|
972
|
+
"required": false,
|
|
973
|
+
"default": 15,
|
|
974
|
+
"description": "Judge-call timeout on the Python grade service; the TypeScript package uses its injected fetch instead."
|
|
975
|
+
}
|
|
976
|
+
],
|
|
977
|
+
"calls_model": true,
|
|
978
|
+
"cost": "judge_call"
|
|
979
|
+
},
|
|
980
|
+
{
|
|
981
|
+
"id": "called_tool",
|
|
982
|
+
"kind": "assertion",
|
|
983
|
+
"name": "Called a tool",
|
|
984
|
+
"checks": "Passes when the tool was called, with the arguments and result asked for when those are given.",
|
|
985
|
+
"category": "trajectory",
|
|
986
|
+
"inputs": [
|
|
987
|
+
"steps"
|
|
988
|
+
],
|
|
989
|
+
"options": [
|
|
990
|
+
{
|
|
991
|
+
"name": "tool",
|
|
992
|
+
"type": "string",
|
|
993
|
+
"required": true,
|
|
994
|
+
"description": "The tool's name, as the trace records it."
|
|
995
|
+
},
|
|
996
|
+
{
|
|
997
|
+
"name": "input",
|
|
998
|
+
"type": "object",
|
|
999
|
+
"required": false,
|
|
1000
|
+
"description": "Arguments the call must carry: a partial object, matched key by key."
|
|
1001
|
+
},
|
|
1002
|
+
{
|
|
1003
|
+
"name": "output",
|
|
1004
|
+
"type": "any",
|
|
1005
|
+
"required": false,
|
|
1006
|
+
"description": "What the result must hold: a string the result contains, or a JSON object or array the result matches."
|
|
1007
|
+
},
|
|
1008
|
+
{
|
|
1009
|
+
"name": "is_error",
|
|
1010
|
+
"type": "boolean",
|
|
1011
|
+
"required": false,
|
|
1012
|
+
"description": "Whether the call must have failed (true) or succeeded (false)."
|
|
1013
|
+
},
|
|
1014
|
+
{
|
|
1015
|
+
"name": "times",
|
|
1016
|
+
"type": "integer",
|
|
1017
|
+
"required": false,
|
|
1018
|
+
"description": "Exactly how many matching calls there must be. Left out: at least one."
|
|
1019
|
+
}
|
|
1020
|
+
],
|
|
1021
|
+
"calls_model": false,
|
|
1022
|
+
"cost": "free"
|
|
1023
|
+
},
|
|
1024
|
+
{
|
|
1025
|
+
"id": "not_called_tool",
|
|
1026
|
+
"kind": "assertion",
|
|
1027
|
+
"name": "Never called a tool",
|
|
1028
|
+
"checks": "Fails when the tool was called at all, naming each call.",
|
|
1029
|
+
"category": "trajectory",
|
|
1030
|
+
"inputs": [
|
|
1031
|
+
"steps"
|
|
1032
|
+
],
|
|
1033
|
+
"options": [
|
|
1034
|
+
{
|
|
1035
|
+
"name": "tool",
|
|
1036
|
+
"type": "string",
|
|
1037
|
+
"required": true,
|
|
1038
|
+
"description": "The tool's name, as the trace records it."
|
|
1039
|
+
}
|
|
1040
|
+
],
|
|
1041
|
+
"calls_model": false,
|
|
1042
|
+
"cost": "free"
|
|
1043
|
+
},
|
|
1044
|
+
{
|
|
1045
|
+
"id": "tool_order",
|
|
1046
|
+
"kind": "assertion",
|
|
1047
|
+
"name": "Tools in order",
|
|
1048
|
+
"checks": "Passes when the tools were called in this order; other calls may come between.",
|
|
1049
|
+
"category": "trajectory",
|
|
1050
|
+
"inputs": [
|
|
1051
|
+
"steps"
|
|
1052
|
+
],
|
|
1053
|
+
"options": [
|
|
1054
|
+
{
|
|
1055
|
+
"name": "tools",
|
|
1056
|
+
"type": "array",
|
|
1057
|
+
"required": true,
|
|
1058
|
+
"description": "Tool names, first to last."
|
|
1059
|
+
}
|
|
1060
|
+
],
|
|
1061
|
+
"calls_model": false,
|
|
1062
|
+
"cost": "free"
|
|
1063
|
+
},
|
|
1064
|
+
{
|
|
1065
|
+
"id": "max_tool_calls",
|
|
1066
|
+
"kind": "assertion",
|
|
1067
|
+
"name": "At most N tool calls",
|
|
1068
|
+
"checks": "Fails when more tool calls were made than the limit, naming the calls past it.",
|
|
1069
|
+
"category": "trajectory",
|
|
1070
|
+
"inputs": [
|
|
1071
|
+
"steps"
|
|
1072
|
+
],
|
|
1073
|
+
"options": [
|
|
1074
|
+
{
|
|
1075
|
+
"name": "max",
|
|
1076
|
+
"type": "integer",
|
|
1077
|
+
"required": true,
|
|
1078
|
+
"description": "The most calls allowed."
|
|
1079
|
+
},
|
|
1080
|
+
{
|
|
1081
|
+
"name": "tool",
|
|
1082
|
+
"type": "string",
|
|
1083
|
+
"required": false,
|
|
1084
|
+
"description": "Count only this tool's calls. Left out: every tool call."
|
|
1085
|
+
}
|
|
1086
|
+
],
|
|
1087
|
+
"calls_model": false,
|
|
1088
|
+
"cost": "free"
|
|
1089
|
+
},
|
|
1090
|
+
{
|
|
1091
|
+
"id": "used_no_tools",
|
|
1092
|
+
"kind": "assertion",
|
|
1093
|
+
"name": "Used no tools",
|
|
1094
|
+
"checks": "Fails when any tool was called.",
|
|
1095
|
+
"category": "trajectory",
|
|
1096
|
+
"inputs": [
|
|
1097
|
+
"steps"
|
|
1098
|
+
],
|
|
1099
|
+
"options": [],
|
|
1100
|
+
"calls_model": false,
|
|
1101
|
+
"cost": "free"
|
|
1102
|
+
},
|
|
1103
|
+
{
|
|
1104
|
+
"id": "trajectory_match",
|
|
1105
|
+
"kind": "assertion",
|
|
1106
|
+
"name": "Trajectory matches a reference",
|
|
1107
|
+
"checks": "Compares the tool calls made with a reference list of calls.",
|
|
1108
|
+
"category": "trajectory",
|
|
1109
|
+
"inputs": [
|
|
1110
|
+
"steps"
|
|
1111
|
+
],
|
|
1112
|
+
"options": [
|
|
1113
|
+
{
|
|
1114
|
+
"name": "mode",
|
|
1115
|
+
"type": "string",
|
|
1116
|
+
"required": true,
|
|
1117
|
+
"enum": [
|
|
1118
|
+
"strict",
|
|
1119
|
+
"unordered",
|
|
1120
|
+
"subset",
|
|
1121
|
+
"superset"
|
|
1122
|
+
],
|
|
1123
|
+
"description": "strict: the same calls in the same order. unordered: the same calls in any order. subset: only calls from the reference. superset: at least the reference's calls."
|
|
1124
|
+
},
|
|
1125
|
+
{
|
|
1126
|
+
"name": "reference",
|
|
1127
|
+
"type": "array",
|
|
1128
|
+
"required": false,
|
|
1129
|
+
"description": "The reference calls, in order."
|
|
1130
|
+
},
|
|
1131
|
+
{
|
|
1132
|
+
"name": "args_mode",
|
|
1133
|
+
"type": "string",
|
|
1134
|
+
"required": false,
|
|
1135
|
+
"default": "exact",
|
|
1136
|
+
"enum": [
|
|
1137
|
+
"exact",
|
|
1138
|
+
"ignore",
|
|
1139
|
+
"subset",
|
|
1140
|
+
"superset"
|
|
1141
|
+
],
|
|
1142
|
+
"description": "How a call's arguments compare with the reference's: exact equality, ignore (name only), subset (the call's keys within the reference's) or superset (the reference's keys within the call's)."
|
|
1143
|
+
},
|
|
1144
|
+
{
|
|
1145
|
+
"name": "args_overrides",
|
|
1146
|
+
"type": "object",
|
|
1147
|
+
"required": false,
|
|
1148
|
+
"description": "An argument mode per tool name, in place of args_mode."
|
|
1149
|
+
}
|
|
1150
|
+
],
|
|
1151
|
+
"calls_model": false,
|
|
1152
|
+
"cost": "free"
|
|
1153
|
+
},
|
|
1154
|
+
{
|
|
1155
|
+
"id": "loop",
|
|
1156
|
+
"kind": "assertion",
|
|
1157
|
+
"name": "No loop",
|
|
1158
|
+
"checks": "Fails when a tool was called with the same arguments this many times or more.",
|
|
1159
|
+
"category": "trajectory",
|
|
1160
|
+
"inputs": [
|
|
1161
|
+
"steps"
|
|
1162
|
+
],
|
|
1163
|
+
"options": [
|
|
1164
|
+
{
|
|
1165
|
+
"name": "min_repeats",
|
|
1166
|
+
"type": "integer",
|
|
1167
|
+
"required": true,
|
|
1168
|
+
"description": "How many identical calls make a loop."
|
|
1169
|
+
},
|
|
1170
|
+
{
|
|
1171
|
+
"name": "tool",
|
|
1172
|
+
"type": "string",
|
|
1173
|
+
"required": false,
|
|
1174
|
+
"description": "Look at this tool only. Left out: every tool."
|
|
1175
|
+
}
|
|
1176
|
+
],
|
|
1177
|
+
"calls_model": false,
|
|
1178
|
+
"cost": "free"
|
|
1179
|
+
},
|
|
1180
|
+
{
|
|
1181
|
+
"id": "error_unhandled",
|
|
1182
|
+
"kind": "assertion",
|
|
1183
|
+
"name": "No unhandled error",
|
|
1184
|
+
"checks": "Fails when a tool call failed and the agent neither retried it nor answered the failure.",
|
|
1185
|
+
"category": "trajectory",
|
|
1186
|
+
"inputs": [
|
|
1187
|
+
"steps"
|
|
1188
|
+
],
|
|
1189
|
+
"options": [],
|
|
1190
|
+
"calls_model": false,
|
|
1191
|
+
"cost": "free"
|
|
1192
|
+
},
|
|
1193
|
+
{
|
|
1194
|
+
"id": "budget",
|
|
1195
|
+
"kind": "assertion",
|
|
1196
|
+
"name": "Within budget",
|
|
1197
|
+
"checks": "Fails when the unit's cost, tokens, latency or turns pass the limit, naming the step at which it crossed.",
|
|
1198
|
+
"category": "trajectory",
|
|
1199
|
+
"inputs": [
|
|
1200
|
+
"steps"
|
|
1201
|
+
],
|
|
1202
|
+
"options": [
|
|
1203
|
+
{
|
|
1204
|
+
"name": "metric",
|
|
1205
|
+
"type": "string",
|
|
1206
|
+
"required": true,
|
|
1207
|
+
"enum": [
|
|
1208
|
+
"cost_usd",
|
|
1209
|
+
"tokens",
|
|
1210
|
+
"latency_ms",
|
|
1211
|
+
"turns"
|
|
1212
|
+
],
|
|
1213
|
+
"description": "cost_usd and tokens are the model calls' own; latency_ms is wall clock from the first step's start to the last step's end; turns counts model turns."
|
|
1214
|
+
},
|
|
1215
|
+
{
|
|
1216
|
+
"name": "max",
|
|
1217
|
+
"type": "number",
|
|
1218
|
+
"required": true,
|
|
1219
|
+
"description": "The limit. A whole number for tokens and turns."
|
|
1220
|
+
},
|
|
1221
|
+
{
|
|
1222
|
+
"name": "per",
|
|
1223
|
+
"type": "string",
|
|
1224
|
+
"required": false,
|
|
1225
|
+
"enum": [
|
|
1226
|
+
"trace",
|
|
1227
|
+
"task"
|
|
1228
|
+
],
|
|
1229
|
+
"description": "Count per trace of a task, or over the whole task. Left out: the whole unit."
|
|
1230
|
+
}
|
|
1231
|
+
],
|
|
1232
|
+
"calls_model": false,
|
|
1233
|
+
"cost": "free"
|
|
1234
|
+
},
|
|
1235
|
+
{
|
|
1236
|
+
"id": "code",
|
|
1237
|
+
"kind": "code",
|
|
1238
|
+
"name": "Code",
|
|
1239
|
+
"checks": "Your own Python, JavaScript or TypeScript receives the unit and returns a verdict or a score with a reason. It runs in a sandbox with no network.",
|
|
1240
|
+
"category": "code",
|
|
1241
|
+
"inputs": [
|
|
1242
|
+
"question",
|
|
1243
|
+
"output",
|
|
1244
|
+
"expected",
|
|
1245
|
+
"steps"
|
|
1246
|
+
],
|
|
1247
|
+
"options": [
|
|
1248
|
+
{
|
|
1249
|
+
"name": "runtime",
|
|
1250
|
+
"type": "string",
|
|
1251
|
+
"required": true,
|
|
1252
|
+
"enum": [
|
|
1253
|
+
"python",
|
|
1254
|
+
"javascript",
|
|
1255
|
+
"typescript"
|
|
1256
|
+
],
|
|
1257
|
+
"description": "The language the source is written in."
|
|
1258
|
+
},
|
|
1259
|
+
{
|
|
1260
|
+
"name": "source",
|
|
1261
|
+
"type": "string",
|
|
1262
|
+
"required": true,
|
|
1263
|
+
"description": "The code: it declares evaluate(unit)."
|
|
1264
|
+
},
|
|
1265
|
+
{
|
|
1266
|
+
"name": "min_score",
|
|
1267
|
+
"type": "number",
|
|
1268
|
+
"required": false,
|
|
1269
|
+
"default": 0.5,
|
|
1270
|
+
"description": "A returned score passes from this up."
|
|
1271
|
+
}
|
|
1272
|
+
],
|
|
1273
|
+
"calls_model": false,
|
|
1274
|
+
"cost": "sandbox"
|
|
1275
|
+
}
|
|
1276
|
+
],
|
|
1277
|
+
"templates": [
|
|
1278
|
+
{
|
|
1279
|
+
"id": "faithfulness",
|
|
1280
|
+
"name": "Faithful to the context",
|
|
1281
|
+
"checks": "Passes when every factual claim in the answer is supported by the retrieved context; fails when one is not, even if it is true.",
|
|
1282
|
+
"inputs": [
|
|
1283
|
+
"output",
|
|
1284
|
+
"context"
|
|
1285
|
+
],
|
|
1286
|
+
"statement": "Every factual claim in the answer is supported by the retrieved context.",
|
|
1287
|
+
"pass_def": "Each claim is stated in the retrieved passages or follows directly from them. Saying the context does not hold the answer also passes.",
|
|
1288
|
+
"fail_def": "At least one claim is absent from the retrieved passages or contradicts them, whether or not it is true.",
|
|
1289
|
+
"na_def": "No retrieved context is shown, or the answer makes no factual claim.",
|
|
1290
|
+
"example": {
|
|
1291
|
+
"question": "How long do I have to ask for a refund on an annual plan?",
|
|
1292
|
+
"context": [
|
|
1293
|
+
"Annual plans can be refunded within 30 days of purchase.",
|
|
1294
|
+
"Monthly plans are not refundable."
|
|
1295
|
+
],
|
|
1296
|
+
"output": "You can get a refund on an annual plan within 60 days.",
|
|
1297
|
+
"verdict": "failed",
|
|
1298
|
+
"why": "The context says 30 days; 60 days appears in no passage."
|
|
1299
|
+
}
|
|
1300
|
+
},
|
|
1301
|
+
{
|
|
1302
|
+
"id": "context_relevance",
|
|
1303
|
+
"name": "Context is relevant",
|
|
1304
|
+
"checks": "Passes when the retrieved context holds what the question asks for; fails when retrieval brought back something else.",
|
|
1305
|
+
"inputs": [
|
|
1306
|
+
"question",
|
|
1307
|
+
"context"
|
|
1308
|
+
],
|
|
1309
|
+
"statement": "The retrieved context holds the information needed to answer the question.",
|
|
1310
|
+
"pass_def": "At least one retrieved passage holds the fact or instruction the question asks for.",
|
|
1311
|
+
"fail_def": "No retrieved passage holds it: the passages are about something else or stop short of what was asked.",
|
|
1312
|
+
"na_def": "No retrieved context or no question is shown.",
|
|
1313
|
+
"example": {
|
|
1314
|
+
"question": "How long do I have to ask for a refund on an annual plan?",
|
|
1315
|
+
"context": [
|
|
1316
|
+
"Invoices are sent on the first day of each month.",
|
|
1317
|
+
"Annual plans are billed once a year."
|
|
1318
|
+
],
|
|
1319
|
+
"output": "Annual plans are billed once a year.",
|
|
1320
|
+
"verdict": "failed",
|
|
1321
|
+
"why": "Both passages are about billing; neither says how long a refund can be asked for."
|
|
1322
|
+
}
|
|
1323
|
+
},
|
|
1324
|
+
{
|
|
1325
|
+
"id": "answer_relevance",
|
|
1326
|
+
"name": "Answers the question",
|
|
1327
|
+
"checks": "Passes when the answer addresses what was asked; fails when it answers something else, dodges or stops short.",
|
|
1328
|
+
"inputs": [
|
|
1329
|
+
"question",
|
|
1330
|
+
"output"
|
|
1331
|
+
],
|
|
1332
|
+
"statement": "The answer addresses the question that was asked.",
|
|
1333
|
+
"pass_def": "It responds to the question directly and covers what was asked. Saying it cannot answer, and why, also passes.",
|
|
1334
|
+
"fail_def": "It answers a different question, dodges, or leaves out part of what was asked.",
|
|
1335
|
+
"na_def": "No question is shown.",
|
|
1336
|
+
"example": {
|
|
1337
|
+
"question": "How long do I have to ask for a refund on an annual plan?",
|
|
1338
|
+
"context": [
|
|
1339
|
+
"Annual plans can be refunded within 30 days of purchase."
|
|
1340
|
+
],
|
|
1341
|
+
"output": "Annual plans are our best value and include priority support.",
|
|
1342
|
+
"verdict": "failed",
|
|
1343
|
+
"why": "The answer is about the plan's value; it never says how long a refund can be asked for."
|
|
1344
|
+
}
|
|
1345
|
+
},
|
|
1346
|
+
{
|
|
1347
|
+
"id": "cites_sources",
|
|
1348
|
+
"name": "Cites its sources",
|
|
1349
|
+
"checks": "Passes when every factual claim in the answer cites a retrieved passage that supports it; fails on a missing, invented or wrong citation.",
|
|
1350
|
+
"inputs": [
|
|
1351
|
+
"output",
|
|
1352
|
+
"context"
|
|
1353
|
+
],
|
|
1354
|
+
"statement": "Every factual claim in the answer cites a retrieved passage that supports it.",
|
|
1355
|
+
"pass_def": "Each claim carries a citation (a marker, a title or a link) to a retrieved passage, and that passage supports the claim.",
|
|
1356
|
+
"fail_def": "A claim has no citation, cites something that was not retrieved, or cites a passage that does not support it.",
|
|
1357
|
+
"na_def": "No retrieved context is shown, or the answer makes no factual claim.",
|
|
1358
|
+
"example": {
|
|
1359
|
+
"question": "How long do I have to ask for a refund on an annual plan?",
|
|
1360
|
+
"context": [
|
|
1361
|
+
"[1] Annual plans can be refunded within 30 days of purchase.",
|
|
1362
|
+
"[2] Monthly plans are not refundable."
|
|
1363
|
+
],
|
|
1364
|
+
"output": "Annual plans can be refunded within 30 days of purchase [1].",
|
|
1365
|
+
"verdict": "passed",
|
|
1366
|
+
"why": "The one claim cites passage 1, which was retrieved and says the same."
|
|
1367
|
+
}
|
|
1368
|
+
}
|
|
1369
|
+
]
|
|
1370
|
+
}
|