@sanity/ailf 3.8.0 → 3.8.1

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 (32) hide show
  1. package/dist/adapters/config-sources/file-config-adapter.js +4 -5
  2. package/dist/adapters/task-sources/repo-schemas.d.ts +3 -3
  3. package/dist/cli-program.d.ts +39 -0
  4. package/dist/cli-program.js +137 -0
  5. package/dist/cli.d.ts +6 -0
  6. package/dist/cli.js +12 -122
  7. package/dist/pipeline/mirror-repo-tasks.d.ts +1 -1
  8. package/package.json +5 -3
  9. package/dist/pipeline/compiler/__tests__/agent-harness-handler.test.d.ts +0 -10
  10. package/dist/pipeline/compiler/__tests__/agent-harness-handler.test.js +0 -366
  11. package/dist/pipeline/compiler/__tests__/assertion-mapper.test.d.ts +0 -9
  12. package/dist/pipeline/compiler/__tests__/assertion-mapper.test.js +0 -145
  13. package/dist/pipeline/compiler/__tests__/knowledge-probe-handler.test.d.ts +0 -10
  14. package/dist/pipeline/compiler/__tests__/knowledge-probe-handler.test.js +0 -314
  15. package/dist/pipeline/compiler/__tests__/literacy-handler.test.d.ts +0 -10
  16. package/dist/pipeline/compiler/__tests__/literacy-handler.test.js +0 -486
  17. package/dist/pipeline/compiler/__tests__/mcp-server-handler.test.d.ts +0 -10
  18. package/dist/pipeline/compiler/__tests__/mcp-server-handler.test.js +0 -425
  19. package/dist/pipeline/compiler/__tests__/promptfoo-compiler.test.d.ts +0 -9
  20. package/dist/pipeline/compiler/__tests__/promptfoo-compiler.test.js +0 -332
  21. package/dist/pipeline/compiler/__tests__/sandbox-and-fixtures.test.d.ts +0 -12
  22. package/dist/pipeline/compiler/__tests__/sandbox-and-fixtures.test.js +0 -210
  23. package/dist/pipeline/compiler/__tests__/scoring-and-presets.test.d.ts +0 -7
  24. package/dist/pipeline/compiler/__tests__/scoring-and-presets.test.js +0 -404
  25. package/dist/pipeline/compiler/__tests__/scoring-bridge.test.d.ts +0 -10
  26. package/dist/pipeline/compiler/__tests__/scoring-bridge.test.js +0 -184
  27. package/dist/pipeline/compiler/__tests__/task-graph-builder.test.d.ts +0 -8
  28. package/dist/pipeline/compiler/__tests__/task-graph-builder.test.js +0 -301
  29. package/dist/pipeline/compiler/__tests__/telemetry.test.d.ts +0 -9
  30. package/dist/pipeline/compiler/__tests__/telemetry.test.js +0 -503
  31. package/dist/pipeline/compiler/__tests__/tool-loop-openai.test.d.ts +0 -10
  32. package/dist/pipeline/compiler/__tests__/tool-loop-openai.test.js +0 -509
@@ -1,366 +0,0 @@
1
- /**
2
- * agent-harness-handler.test.ts — Tests for agent harness mode compilation.
3
- *
4
- * Tests validation, provider assembly, tool permission resolution,
5
- * assertion mapping, sandbox config, lifecycle extensions, and
6
- * end-to-end compilation of example tasks.
7
- *
8
- * Run: npx tsx --test src/pipeline/compiler/__tests__/agent-harness-handler.test.ts
9
- */
10
- import assert from "node:assert/strict";
11
- import { describe, it } from "node:test";
12
- import { LiteracyVariant } from "../../normalize-mode.js";
13
- import { compileAgentHarnessTask, AGENT_HARNESS_PROMPT_TEMPLATES, handler as agentHandler, validateAgentHarnessTask, } from "../mode-handlers/agent-harness/index.js";
14
- import { allAgentHarnessExampleTasks, scaffoldProjectTask, modifyCodeTask, multiFileRefactorTask, } from "../mode-handlers/__fixtures__/agent-harness-example-tasks.js";
15
- // ---------------------------------------------------------------------------
16
- // Helpers
17
- // ---------------------------------------------------------------------------
18
- function makeTask(overrides) {
19
- return {
20
- mode: "agent-harness",
21
- id: "test-agent-task",
22
- title: "Test Agent Task",
23
- description: "A test agent harness task",
24
- area: "studio",
25
- ...overrides,
26
- };
27
- }
28
- // ---------------------------------------------------------------------------
29
- // handler.getPrompts() — prompt template ownership
30
- // ---------------------------------------------------------------------------
31
- describe("AgentHarnessHandler.getPrompts", () => {
32
- it("returns prompt templates", () => {
33
- const prompts = agentHandler.getPrompts();
34
- assert.ok(prompts, "getPrompts() should return a record");
35
- assert.ok(Object.keys(prompts).length > 0, "should return at least one template");
36
- });
37
- it("returns templates keyed by agent-specific IDs (not literacy names)", () => {
38
- const prompts = agentHandler.getPrompts();
39
- const keys = Object.keys(prompts);
40
- // Must not use literacy template names
41
- assert.ok(!keys.includes("with-docs"), "should not use literacy key 'with-docs'");
42
- assert.ok(!keys.includes("without-docs"), "should not use literacy key 'without-docs'");
43
- assert.ok(!keys.includes(LiteracyVariant.AGENTIC), "should not use literacy key 'agentic'");
44
- // Must have agent-appropriate key(s)
45
- assert.ok(keys.includes("agent-harness"), "should include 'agent-harness' template");
46
- });
47
- it("agent-harness template describes task for agent execution", () => {
48
- const prompts = agentHandler.getPrompts();
49
- const template = prompts["agent-harness"];
50
- assert.ok(template, "agent-harness template should exist");
51
- assert.ok(template.template.includes("{{task}}"), "should include {{task}} placeholder");
52
- // Should reference agent / sandbox / tool execution context
53
- assert.ok(/sandbox|file|tool|implement|code/i.test(template.template), "template should reference agent execution concepts");
54
- });
55
- it("template has correct PromptTemplate shape", () => {
56
- const prompts = agentHandler.getPrompts();
57
- const template = prompts["agent-harness"];
58
- assert.equal(template.id, "agent-harness");
59
- assert.ok(template.label, "should have a human-readable label");
60
- assert.ok(template.template, "should have a template string");
61
- assert.ok(Array.isArray(template.variables), "should declare variables");
62
- assert.ok(template.variables.includes("task"), "variables should include 'task'");
63
- });
64
- it("exported AGENT_HARNESS_PROMPT_TEMPLATES matches handler.getPrompts()", () => {
65
- const fromHandler = agentHandler.getPrompts();
66
- assert.deepEqual(fromHandler, AGENT_HARNESS_PROMPT_TEMPLATES);
67
- });
68
- });
69
- // ---------------------------------------------------------------------------
70
- // validateAgentHarnessTask
71
- // ---------------------------------------------------------------------------
72
- describe("validateAgentHarnessTask", () => {
73
- it("passes for a valid minimal task", () => {
74
- const errors = validateAgentHarnessTask(makeTask());
75
- assert.equal(errors.length, 0);
76
- });
77
- it("errors on missing ID", () => {
78
- const errors = validateAgentHarnessTask(makeTask({ id: "" }));
79
- assert.ok(errors.some((e) => e.field === "id"));
80
- });
81
- it("errors on missing title", () => {
82
- const errors = validateAgentHarnessTask(makeTask({ title: "" }));
83
- assert.ok(errors.some((e) => e.field === "title"));
84
- });
85
- });
86
- // ---------------------------------------------------------------------------
87
- // compileAgentHarnessTask — provider assembly
88
- // ---------------------------------------------------------------------------
89
- describe("compileAgentHarnessTask — providers", () => {
90
- it("produces a Claude Agent SDK provider", () => {
91
- const result = compileAgentHarnessTask(makeTask());
92
- assert.ok(result.providers.length > 0);
93
- assert.equal(result.providers[0].id, "anthropic:claude-agent-sdk");
94
- });
95
- it("sets default agent config", () => {
96
- const result = compileAgentHarnessTask(makeTask());
97
- const config = result.providers[0].config;
98
- assert.ok(config.model, "should set a model");
99
- assert.ok(config.max_turns, "should set max_turns");
100
- assert.ok(config.max_budget_usd, "should set budget cap");
101
- assert.equal(config.permission_mode, "bypassPermissions");
102
- });
103
- it("resolves coding tool preset into custom_allowed_tools", () => {
104
- const result = compileAgentHarnessTask(makeTask({ tools: ["coding"] }));
105
- const config = result.providers[0].config;
106
- const tools = config.custom_allowed_tools;
107
- assert.ok(tools.includes("Bash"));
108
- assert.ok(tools.includes("Read"));
109
- assert.ok(tools.includes("Write"));
110
- assert.ok(tools.includes("Edit"));
111
- });
112
- it("resolves read-only tool preset", () => {
113
- const result = compileAgentHarnessTask(makeTask({ tools: ["read-only"] }));
114
- const config = result.providers[0].config;
115
- const tools = config.custom_allowed_tools;
116
- assert.ok(tools.includes("Read"));
117
- assert.ok(tools.includes("Grep"));
118
- assert.ok(!tools.includes("Write"), "read-only should not include Write");
119
- });
120
- it("mixes preset and explicit tools", () => {
121
- const result = compileAgentHarnessTask(makeTask({ tools: ["read-only", "WebFetch"] }));
122
- const config = result.providers[0].config;
123
- const tools = config.custom_allowed_tools;
124
- assert.ok(tools.includes("Read"));
125
- assert.ok(tools.includes("WebFetch"));
126
- });
127
- });
128
- // ---------------------------------------------------------------------------
129
- // compileAgentHarnessTask — test cases
130
- // ---------------------------------------------------------------------------
131
- describe("compileAgentHarnessTask — test cases", () => {
132
- it("produces at least one test case", () => {
133
- const result = compileAgentHarnessTask(makeTask());
134
- assert.ok(result.tests.length > 0);
135
- });
136
- it("includes task description in vars", () => {
137
- const result = compileAgentHarnessTask(makeTask({ description: "Do the thing" }));
138
- assert.equal(result.tests[0].vars.task, "Do the thing");
139
- });
140
- it("prefers prompt.vars.task over description", () => {
141
- const result = compileAgentHarnessTask(makeTask({
142
- description: "Description",
143
- prompt: { vars: { task: "Custom prompt" } },
144
- }));
145
- assert.equal(result.tests[0].vars.task, "Custom prompt");
146
- });
147
- it("creates multi-turn test case", () => {
148
- const result = compileAgentHarnessTask(makeTask({
149
- multiTurn: {
150
- turns: [
151
- { role: "user", content: "Hello" },
152
- { role: "assistant", content: "Hi" },
153
- ],
154
- },
155
- }));
156
- assert.equal(result.tests.length, 2);
157
- assert.ok(result.tests[1].description.includes("[multi-turn]"));
158
- });
159
- it("sets sandbox metadata in vars", () => {
160
- const result = compileAgentHarnessTask(makeTask({ sandbox: { type: "docker" } }));
161
- assert.equal(result.tests[0].vars.__sandboxType, "docker");
162
- });
163
- });
164
- // ---------------------------------------------------------------------------
165
- // compileAgentHarnessTask — assertions
166
- // ---------------------------------------------------------------------------
167
- describe("compileAgentHarnessTask — assertions", () => {
168
- const RUNTIME = "file://dist/agent-harness/assertions-runtime.js";
169
- it("maps file-exists to file-based javascript assertion", () => {
170
- const result = compileAgentHarnessTask(makeTask({
171
- assertions: [{ type: "file-exists", value: "sanity.config.ts" }],
172
- }));
173
- const assertion = result.tests[0].assert?.[0];
174
- assert.ok(assertion);
175
- assert.equal(assertion.type, "javascript");
176
- assert.equal(assertion.value, `${RUNTIME}:fileExists`);
177
- assert.deepEqual(assertion.config, {
178
- filePath: "sanity.config.ts",
179
- });
180
- });
181
- it("maps file-contains to file-based javascript assertion", () => {
182
- const result = compileAgentHarnessTask(makeTask({
183
- assertions: [
184
- {
185
- type: "file-contains",
186
- value: { path: "config.ts", content: "projectId" },
187
- },
188
- ],
189
- }));
190
- const assertion = result.tests[0].assert?.[0];
191
- assert.ok(assertion);
192
- assert.equal(assertion.type, "javascript");
193
- assert.equal(assertion.value, `${RUNTIME}:fileContains`);
194
- assert.deepEqual(assertion.config, {
195
- filePath: "config.ts",
196
- content: "projectId",
197
- });
198
- });
199
- it("maps command-succeeds to file-based javascript assertion", () => {
200
- const result = compileAgentHarnessTask(makeTask({
201
- assertions: [{ type: "command-succeeds", value: "npx tsc --noEmit" }],
202
- }));
203
- const assertion = result.tests[0].assert?.[0];
204
- assert.ok(assertion);
205
- assert.equal(assertion.type, "javascript");
206
- assert.equal(assertion.value, `${RUNTIME}:commandSucceeds`);
207
- assert.deepEqual(assertion.config, {
208
- command: "npx tsc --noEmit",
209
- });
210
- });
211
- it("maps diff-matches to file-based javascript assertion", () => {
212
- const result = compileAgentHarnessTask(makeTask({
213
- assertions: [{ type: "diff-matches", value: "createClient" }],
214
- }));
215
- const assertion = result.tests[0].assert?.[0];
216
- assert.ok(assertion);
217
- assert.equal(assertion.type, "javascript");
218
- assert.equal(assertion.value, `${RUNTIME}:diffMatches`);
219
- assert.deepEqual(assertion.config, {
220
- expected: "createClient",
221
- });
222
- });
223
- it("passes through standard assertions", () => {
224
- const result = compileAgentHarnessTask(makeTask({
225
- assertions: [{ type: "contains", value: "sanity" }],
226
- }));
227
- assert.equal(result.tests[0].assert?.[0]?.type, "contains");
228
- });
229
- it("sets grader provider on llm-rubric", () => {
230
- const result = compileAgentHarnessTask(makeTask({
231
- assertions: [{ type: "llm-rubric", value: "Check quality" }],
232
- }), { graderProvider: "openai:chat:gpt-5" });
233
- assert.equal(result.tests[0].assert?.[0]?.provider, "openai:chat:gpt-5");
234
- });
235
- it("resolves templated llm-rubric with rubric text and dimension metadata", () => {
236
- const rubricConfig = {
237
- templates: {
238
- "agent-output": {
239
- dimension: "agent-output",
240
- header: "Score the agent's final output from 0 to 100:",
241
- scale: ["0: Failed", "50: Partial", "100: Complete"],
242
- criteria_label: "Check for:",
243
- },
244
- },
245
- };
246
- const result = compileAgentHarnessTask(makeTask({
247
- assertions: [
248
- {
249
- type: "llm-rubric",
250
- template: "agent-output",
251
- criteria: ["File created", "Correct content"],
252
- },
253
- ],
254
- }), { rubricConfig, graderProvider: "anthropic:messages:claude-opus-4-5" });
255
- const assertion = result.tests[0].assert?.[0];
256
- assert.ok(assertion, "should produce an assertion");
257
- assert.equal(assertion.type, "llm-rubric");
258
- // Rubric text should be fully rendered (not empty)
259
- assert.ok(assertion.value.includes("Score the agent"), "should contain rendered rubric header");
260
- assert.ok(assertion.value.includes("File created"), "should contain task-specific criteria");
261
- // Dimension metadata should be attached
262
- const metadata = assertion.metadata;
263
- assert.ok(metadata, "should have metadata");
264
- assert.equal(metadata.dimension, "agent-output");
265
- assert.equal(metadata.maxScore, 100);
266
- // Grader provider should be set
267
- assert.equal(assertion.provider, "anthropic:messages:claude-opus-4-5");
268
- });
269
- it("warns when rubric template is unknown", () => {
270
- const rubricConfig = { templates: {} };
271
- const result = compileAgentHarnessTask(makeTask({
272
- assertions: [
273
- {
274
- type: "llm-rubric",
275
- template: "nonexistent-template",
276
- criteria: ["Something"],
277
- },
278
- ],
279
- }), { rubricConfig });
280
- // Unknown template produces a warning and no assertion
281
- assert.ok(result.warnings.some((w) => w.includes("nonexistent-template")), "should warn about unknown template");
282
- // The assertion should be null (filtered out)
283
- assert.equal(result.tests[0].assert?.length ?? 0, 0, "should not produce an assertion for unknown template");
284
- });
285
- it("warns when rubricConfig is not provided for templated assertion", () => {
286
- const result = compileAgentHarnessTask(makeTask({
287
- assertions: [
288
- {
289
- type: "llm-rubric",
290
- template: "agent-output",
291
- criteria: ["Something"],
292
- },
293
- ],
294
- })
295
- // No rubricConfig in options
296
- );
297
- assert.ok(result.warnings.some((w) => w.includes("No rubric config")), "should warn about missing rubric config");
298
- });
299
- });
300
- // ---------------------------------------------------------------------------
301
- // compileAgentHarnessTask — lifecycle extensions
302
- // ---------------------------------------------------------------------------
303
- describe("compileAgentHarnessTask — lifecycle", () => {
304
- it("produces beforeEach and afterEach extensions", () => {
305
- const result = compileAgentHarnessTask(makeTask());
306
- assert.equal(result.extensions.length, 2);
307
- assert.equal(result.extensions[0].type, "beforeEach");
308
- assert.equal(result.extensions[1].type, "afterEach");
309
- });
310
- it("beforeEach hook creates working directory", () => {
311
- const result = compileAgentHarnessTask(makeTask());
312
- assert.ok(result.extensions[0].code.includes("mkdirSync"));
313
- assert.ok(result.extensions[0].code.includes("__workingDir"));
314
- });
315
- it("afterEach hook cleans up", () => {
316
- const result = compileAgentHarnessTask(makeTask());
317
- assert.ok(result.extensions[1].code.includes("rmSync"));
318
- });
319
- it("sandbox config captures task settings", () => {
320
- const result = compileAgentHarnessTask(makeTask({
321
- sandbox: {
322
- type: "docker",
323
- image: "node:22",
324
- limits: { cpus: 2, networkAccess: false },
325
- },
326
- fixtures: ["file://schema.ts"],
327
- }));
328
- assert.equal(result.sandboxConfig.type, "docker");
329
- assert.equal(result.sandboxConfig.image, "node:22");
330
- assert.deepEqual(result.sandboxConfig.fixtures, ["schema.ts"]);
331
- assert.equal(result.sandboxConfig.limits?.cpus, 2);
332
- assert.equal(result.sandboxConfig.limits?.networkAccess, false);
333
- });
334
- });
335
- // ---------------------------------------------------------------------------
336
- // Example task compilation (end-to-end)
337
- // ---------------------------------------------------------------------------
338
- describe("example agent harness tasks — end-to-end", () => {
339
- it("compiles all example tasks without errors", () => {
340
- for (const task of allAgentHarnessExampleTasks) {
341
- const result = compileAgentHarnessTask(task);
342
- assert.ok(result.providers.length > 0, `${task.id}: should produce providers`);
343
- assert.ok(result.tests.length > 0, `${task.id}: should produce test cases`);
344
- assert.ok(result.extensions.length > 0, `${task.id}: should produce lifecycle extensions`);
345
- }
346
- });
347
- it("scaffold task has file-exists assertions", () => {
348
- const result = compileAgentHarnessTask(scaffoldProjectTask);
349
- assert.ok(result.tests[0].assert);
350
- assert.ok(result.tests[0].assert.length >= 3);
351
- // First two are file-exists (javascript), third is file-contains, fourth is command-succeeds
352
- assert.equal(result.tests[0].assert[0].type, "javascript");
353
- });
354
- it("modify task has file-contains assertions", () => {
355
- const result = compileAgentHarnessTask(modifyCodeTask);
356
- assert.ok(result.tests[0].assert);
357
- assert.ok(result.tests[0].assert.some((a) => a.type === "javascript" &&
358
- a.value.includes("fileContains") &&
359
- a.config != null));
360
- });
361
- it("refactor task has docker sandbox config", () => {
362
- const result = compileAgentHarnessTask(multiFileRefactorTask);
363
- assert.equal(result.sandboxConfig.type, "docker");
364
- assert.equal(result.sandboxConfig.image, "node:22-slim");
365
- });
366
- });
@@ -1,9 +0,0 @@
1
- /**
2
- * assertion-mapper.test.ts — Unit tests for the assertion type mapper.
3
- *
4
- * Tests mapping of AILF assertion types to Promptfoo assertion types,
5
- * mode compatibility checking, negation support, and templated assertions.
6
- *
7
- * Run: npx tsx --test src/pipeline/compiler/__tests__/assertion-mapper.test.ts
8
- */
9
- export {};
@@ -1,145 +0,0 @@
1
- /**
2
- * assertion-mapper.test.ts — Unit tests for the assertion type mapper.
3
- *
4
- * Tests mapping of AILF assertion types to Promptfoo assertion types,
5
- * mode compatibility checking, negation support, and templated assertions.
6
- *
7
- * Run: npx tsx --test src/pipeline/compiler/__tests__/assertion-mapper.test.ts
8
- */
9
- import assert from "node:assert/strict";
10
- import { describe, it } from "node:test";
11
- import { isAssertionCompatibleWithMode, isValidAssertionType, mapAssertions, } from "../assertion-mapper.js";
12
- // ---------------------------------------------------------------------------
13
- // isValidAssertionType
14
- // ---------------------------------------------------------------------------
15
- describe("isValidAssertionType", () => {
16
- it("recognizes known deterministic types", () => {
17
- assert.equal(isValidAssertionType("contains"), true);
18
- assert.equal(isValidAssertionType("equals"), true);
19
- assert.equal(isValidAssertionType("regex"), true);
20
- assert.equal(isValidAssertionType("is-json"), true);
21
- });
22
- it("recognizes LLM-graded types", () => {
23
- assert.equal(isValidAssertionType("llm-rubric"), true);
24
- assert.equal(isValidAssertionType("model-graded-closedqa"), true);
25
- assert.equal(isValidAssertionType("model-graded-factuality"), true);
26
- assert.equal(isValidAssertionType("g-eval"), true);
27
- assert.equal(isValidAssertionType("similar"), true);
28
- });
29
- it("recognizes programmatic types", () => {
30
- assert.equal(isValidAssertionType("javascript"), true);
31
- assert.equal(isValidAssertionType("python"), true);
32
- });
33
- it("recognizes tool-use types", () => {
34
- assert.equal(isValidAssertionType("tool-called"), true);
35
- assert.equal(isValidAssertionType("tool-call-f1"), true);
36
- assert.equal(isValidAssertionType("skill-used"), true);
37
- });
38
- it("recognizes negated types", () => {
39
- assert.equal(isValidAssertionType("not-contains"), true);
40
- assert.equal(isValidAssertionType("not-equals"), true);
41
- });
42
- it("rejects unknown types", () => {
43
- assert.equal(isValidAssertionType("nonexistent"), false);
44
- });
45
- });
46
- // ---------------------------------------------------------------------------
47
- // isAssertionCompatibleWithMode
48
- // ---------------------------------------------------------------------------
49
- describe("isAssertionCompatibleWithMode", () => {
50
- it("allows deterministic types in any mode", () => {
51
- assert.equal(isAssertionCompatibleWithMode("contains", "literacy"), true);
52
- assert.equal(isAssertionCompatibleWithMode("contains", "agent-harness"), true);
53
- assert.equal(isAssertionCompatibleWithMode("contains", "knowledge-probe"), true);
54
- });
55
- it("restricts tool-use types to appropriate modes", () => {
56
- assert.equal(isAssertionCompatibleWithMode("tool-called", "agent-harness"), true);
57
- assert.equal(isAssertionCompatibleWithMode("tool-called", "mcp-server"), true);
58
- assert.equal(isAssertionCompatibleWithMode("tool-called", "literacy"), true);
59
- assert.equal(isAssertionCompatibleWithMode("tool-called", "knowledge-probe"), false);
60
- });
61
- it("handles negated types", () => {
62
- assert.equal(isAssertionCompatibleWithMode("not-contains", "literacy"), true);
63
- });
64
- });
65
- // ---------------------------------------------------------------------------
66
- // mapAssertions
67
- // ---------------------------------------------------------------------------
68
- describe("mapAssertions", () => {
69
- it("maps a simple contains assertion", () => {
70
- const { mapped, warnings } = mapAssertions([
71
- { type: "contains", value: "defineType" },
72
- ]);
73
- assert.equal(mapped.length, 1);
74
- assert.equal(mapped[0].type, "contains");
75
- assert.equal(mapped[0].value, "defineType");
76
- assert.equal(warnings.length, 0);
77
- });
78
- it("maps an llm-rubric assertion with template and criteria", () => {
79
- const { mapped } = mapAssertions([
80
- {
81
- type: "llm-rubric",
82
- template: "task-completion",
83
- criteria: ["Uses projection syntax", "Demonstrates spread operator"],
84
- },
85
- ]);
86
- assert.equal(mapped.length, 1);
87
- assert.equal(mapped[0].type, "llm-rubric");
88
- assert.ok(mapped[0].value.includes("task-completion"), "Should include template name");
89
- });
90
- it("preserves weight on assertions", () => {
91
- const { mapped } = mapAssertions([
92
- { type: "contains", value: "test", weight: 0.5 },
93
- ]);
94
- assert.equal(mapped[0].weight, 0.5);
95
- });
96
- it("maps negated assertions", () => {
97
- const { mapped } = mapAssertions([
98
- { type: "not-contains", value: "deprecated" },
99
- ]);
100
- assert.equal(mapped.length, 1);
101
- assert.equal(mapped[0].type, "not-contains");
102
- });
103
- it("skips incompatible tool-use assertions with warning", () => {
104
- const { mapped, warnings } = mapAssertions([{ type: "tool-called", value: "WebSearch" }], { mode: "knowledge-probe" });
105
- assert.equal(mapped.length, 0);
106
- assert.equal(warnings.length, 1);
107
- assert.ok(warnings[0].includes("not compatible"));
108
- });
109
- it("warns about unknown assertion types but passes through", () => {
110
- const { mapped, warnings } = mapAssertions([
111
- { type: "custom-check", value: "something" },
112
- ]);
113
- assert.equal(mapped.length, 1);
114
- assert.equal(mapped[0].type, "custom-check");
115
- assert.ok(warnings.some((w) => w.includes("Unknown")));
116
- });
117
- it("skips non-negatable assertion types", () => {
118
- const { mapped, warnings } = mapAssertions([
119
- { type: "not-javascript", value: "return true" },
120
- ]);
121
- assert.equal(mapped.length, 0);
122
- assert.ok(warnings.some((w) => w.includes("negation")));
123
- });
124
- it("sets grader provider on LLM-graded assertions", () => {
125
- const { mapped } = mapAssertions([
126
- {
127
- type: "llm-rubric",
128
- template: "code-correctness",
129
- criteria: ["Valid GROQ"],
130
- },
131
- ], { graderProvider: "openai:chat:gpt-5" });
132
- assert.equal(mapped[0].provider, "openai:chat:gpt-5");
133
- });
134
- it("maps multiple assertions in order", () => {
135
- const { mapped } = mapAssertions([
136
- { type: "contains", value: "first" },
137
- { type: "equals", value: "second" },
138
- { type: "regex", value: "third.*pattern" },
139
- ]);
140
- assert.equal(mapped.length, 3);
141
- assert.equal(mapped[0].type, "contains");
142
- assert.equal(mapped[1].type, "equals");
143
- assert.equal(mapped[2].type, "regex");
144
- });
145
- });
@@ -1,10 +0,0 @@
1
- /**
2
- * knowledge-probe-handler.test.ts — Tests for knowledge probe mode compilation.
3
- *
4
- * Tests validation, provider assembly, prompt generation, assertion mapping
5
- * (including rejection of tool-use assertions), metadata generation, and
6
- * end-to-end compilation of example tasks.
7
- *
8
- * Run: npx tsx --test src/pipeline/compiler/__tests__/knowledge-probe-handler.test.ts
9
- */
10
- export {};