@sanity/ailf 0.5.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -1
- package/config/features.ts +23 -0
- package/config/models.ts +95 -0
- package/config/prompts.ts +16 -0
- package/config/rubrics.ts +225 -0
- package/config/schedules.ts +47 -0
- package/config/sinks.ts +37 -0
- package/config/sources.ts +21 -0
- package/config/thresholds.ts +61 -0
- package/dist/_vendor/ailf-core/config-helpers.d.ts +171 -0
- package/dist/_vendor/ailf-core/config-helpers.js +170 -0
- package/dist/_vendor/ailf-core/env-helper.d.ts +35 -0
- package/dist/_vendor/ailf-core/env-helper.js +45 -0
- package/dist/_vendor/ailf-core/examples/index.d.ts +16 -0
- package/dist/_vendor/ailf-core/examples/index.js +25 -0
- package/dist/_vendor/ailf-core/index.d.ts +3 -0
- package/dist/_vendor/ailf-core/index.js +5 -0
- package/dist/_vendor/ailf-core/ports/context.d.ts +17 -2
- package/dist/_vendor/ailf-core/ports/doc-fetcher.d.ts +2 -2
- package/dist/_vendor/ailf-core/ports/index.d.ts +2 -1
- package/dist/_vendor/ailf-core/ports/mode-handler.d.ts +129 -0
- package/dist/_vendor/ailf-core/ports/mode-handler.js +19 -0
- package/dist/_vendor/ailf-core/ports/task-source.d.ts +16 -122
- package/dist/_vendor/ailf-core/ports/task-source.js +7 -7
- package/dist/_vendor/ailf-core/schemas/eval-config.d.ts +8 -2
- package/dist/_vendor/ailf-core/schemas/eval-config.js +17 -2
- package/dist/_vendor/ailf-core/schemas/pipeline-request.d.ts +9 -3
- package/dist/_vendor/ailf-core/schemas/pipeline-request.js +8 -1
- package/dist/_vendor/ailf-core/schemas/pipeline.d.ts +14 -31
- package/dist/_vendor/ailf-core/schemas/pipeline.js +17 -9
- package/dist/_vendor/ailf-core/schemas/schedules.d.ts +14 -4
- package/dist/_vendor/ailf-core/schemas/schedules.js +6 -2
- package/dist/_vendor/ailf-core/schemas/sinks.d.ts +1 -1
- package/dist/_vendor/ailf-core/services/comparison-formatters.js +57 -19
- package/dist/_vendor/ailf-core/services/index.d.ts +2 -1
- package/dist/_vendor/ailf-core/services/index.js +2 -1
- package/dist/_vendor/ailf-core/services/scoring-engine.d.ts +153 -0
- package/dist/_vendor/ailf-core/services/scoring-engine.js +237 -0
- package/dist/_vendor/ailf-core/services/scoring.d.ts +15 -2
- package/dist/_vendor/ailf-core/services/scoring.js +25 -15
- package/dist/_vendor/ailf-core/types/branded-ids.d.ts +137 -0
- package/dist/_vendor/ailf-core/types/branded-ids.js +136 -0
- package/dist/_vendor/ailf-core/types/eval-mode-config.d.ts +150 -0
- package/dist/_vendor/ailf-core/types/eval-mode-config.js +24 -0
- package/dist/_vendor/ailf-core/types/generalized-task.d.ts +332 -0
- package/dist/_vendor/ailf-core/types/generalized-task.js +13 -0
- package/dist/_vendor/ailf-core/types/index.d.ts +45 -83
- package/dist/_vendor/ailf-core/types/index.js +8 -1
- package/dist/_vendor/ailf-core/types/plugin-registry.d.ts +257 -0
- package/dist/_vendor/ailf-core/types/plugin-registry.js +185 -0
- package/dist/_vendor/ailf-core/types/storage-schema.d.ts +199 -0
- package/dist/_vendor/ailf-core/types/storage-schema.js +39 -0
- package/dist/_vendor/ailf-core/types/task-graph.d.ts +86 -0
- package/dist/_vendor/ailf-core/types/task-graph.js +20 -0
- package/dist/_vendor/ailf-core/types/trace.d.ts +118 -0
- package/dist/_vendor/ailf-core/types/trace.js +18 -0
- package/dist/_vendor/ailf-core/types/variable-envelope.d.ts +80 -0
- package/dist/_vendor/ailf-core/types/variable-envelope.js +16 -0
- package/dist/_vendor/ailf-shared/dimension-names.d.ts +5 -18
- package/dist/_vendor/ailf-shared/dimension-names.js +6 -24
- package/dist/_vendor/ailf-shared/eval-modes.d.ts +38 -6
- package/dist/_vendor/ailf-shared/eval-modes.js +26 -2
- package/dist/_vendor/ailf-shared/index.d.ts +0 -1
- package/dist/_vendor/ailf-shared/index.js +0 -1
- package/dist/adapters/api-client/build-request.js +14 -13
- package/dist/adapters/config-sources/file-config-adapter.d.ts +20 -11
- package/dist/adapters/config-sources/file-config-adapter.js +39 -12
- package/dist/adapters/config-sources/index.d.ts +2 -0
- package/dist/adapters/config-sources/index.js +1 -0
- package/dist/adapters/config-sources/ts-config-loader.d.ts +59 -0
- package/dist/adapters/config-sources/ts-config-loader.js +141 -0
- package/dist/adapters/doc-fetchers/sanity-doc-fetcher.d.ts +3 -2
- package/dist/adapters/doc-fetchers/sanity-doc-fetcher.js +7 -2
- package/dist/adapters/task-sources/composite-task-source.d.ts +3 -3
- package/dist/adapters/task-sources/composite-task-source.js +1 -1
- package/dist/adapters/task-sources/content-lake-task-source.d.ts +7 -6
- package/dist/adapters/task-sources/content-lake-task-source.js +35 -39
- package/dist/adapters/task-sources/index.d.ts +3 -2
- package/dist/adapters/task-sources/index.js +3 -2
- package/dist/adapters/task-sources/repo-schemas.d.ts +218 -16
- package/dist/adapters/task-sources/repo-schemas.js +227 -19
- package/dist/adapters/task-sources/repo-task-source.d.ts +16 -12
- package/dist/adapters/task-sources/repo-task-source.js +92 -80
- package/dist/adapters/task-sources/repo-validation.d.ts +36 -5
- package/dist/adapters/task-sources/repo-validation.js +126 -5
- package/dist/adapters/task-sources/task-file-loader.d.ts +64 -0
- package/dist/adapters/task-sources/task-file-loader.js +83 -0
- package/dist/adapters/task-sources/yaml-task-source.d.ts +6 -6
- package/dist/adapters/task-sources/yaml-task-source.js +19 -16
- package/dist/cli.js +0 -2
- package/dist/commands/baseline.js +4 -1
- package/dist/commands/calculate-scores.js +1 -1
- package/dist/commands/coverage-audit.js +9 -1
- package/dist/commands/explain-handler.js +25 -23
- package/dist/commands/fetch-docs.js +3 -2
- package/dist/commands/generate-configs.js +1 -1
- package/dist/commands/init.d.ts +6 -4
- package/dist/commands/init.js +302 -23
- package/dist/commands/interactive.js +11 -7
- package/dist/commands/pipeline-action.d.ts +2 -0
- package/dist/commands/pipeline-action.js +16 -6
- package/dist/commands/pipeline.d.ts +1 -0
- package/dist/commands/pipeline.js +4 -2
- package/dist/commands/pr-comment.js +1 -1
- package/dist/commands/publish.js +2 -2
- package/dist/commands/readiness-report.js +13 -6
- package/dist/commands/validate-tasks.d.ts +2 -2
- package/dist/commands/validate-tasks.js +26 -15
- package/dist/composition-root.d.ts +13 -1
- package/dist/composition-root.js +99 -4
- package/dist/index.d.ts +41 -0
- package/dist/index.js +48 -0
- package/dist/orchestration/build-app-context.js +1 -0
- package/dist/orchestration/build-step-sequence.js +28 -8
- package/dist/orchestration/steps/calculate-scores-step.js +24 -11
- package/dist/orchestration/steps/fetch-docs-step.js +8 -7
- package/dist/orchestration/steps/gap-analysis-step.js +8 -7
- package/dist/orchestration/steps/generate-configs-step.d.ts +16 -3
- package/dist/orchestration/steps/generate-configs-step.js +261 -51
- package/dist/orchestration/steps/grader-consistency-step.js +7 -4
- package/dist/orchestration/steps/mirror-repo-tasks-step.js +1 -1
- package/dist/orchestration/steps/readiness-step.js +5 -6
- package/dist/orchestration/steps/run-eval-step.d.ts +1 -2
- package/dist/orchestration/steps/run-eval-step.js +8 -7
- package/dist/pipeline/cache.d.ts +1 -1
- package/dist/pipeline/cache.js +36 -8
- package/dist/pipeline/calculate-scores.d.ts +2 -4
- package/dist/pipeline/calculate-scores.js +43 -113
- package/dist/pipeline/checks.js +2 -2
- package/dist/pipeline/compare.js +8 -8
- package/dist/pipeline/compiler/__tests__/agent-harness-handler.test.d.ts +10 -0
- package/dist/pipeline/compiler/__tests__/agent-harness-handler.test.js +288 -0
- package/dist/pipeline/compiler/__tests__/assertion-mapper.test.d.ts +9 -0
- package/dist/pipeline/compiler/__tests__/assertion-mapper.test.js +145 -0
- package/dist/pipeline/compiler/__tests__/knowledge-probe-handler.test.d.ts +10 -0
- package/dist/pipeline/compiler/__tests__/knowledge-probe-handler.test.js +314 -0
- package/dist/pipeline/compiler/__tests__/literacy-handler.test.d.ts +10 -0
- package/dist/pipeline/compiler/__tests__/literacy-handler.test.js +486 -0
- package/dist/pipeline/compiler/__tests__/mcp-server-handler.test.d.ts +10 -0
- package/dist/pipeline/compiler/__tests__/mcp-server-handler.test.js +392 -0
- package/dist/pipeline/compiler/__tests__/promptfoo-compiler.test.d.ts +9 -0
- package/dist/pipeline/compiler/__tests__/promptfoo-compiler.test.js +333 -0
- package/dist/pipeline/compiler/__tests__/sandbox-and-fixtures.test.d.ts +12 -0
- package/dist/pipeline/compiler/__tests__/sandbox-and-fixtures.test.js +210 -0
- package/dist/pipeline/compiler/__tests__/scoring-and-presets.test.d.ts +7 -0
- package/dist/pipeline/compiler/__tests__/scoring-and-presets.test.js +404 -0
- package/dist/pipeline/compiler/__tests__/scoring-bridge.test.d.ts +10 -0
- package/dist/pipeline/compiler/__tests__/scoring-bridge.test.js +184 -0
- package/dist/pipeline/compiler/__tests__/task-graph-builder.test.d.ts +8 -0
- package/dist/pipeline/compiler/__tests__/task-graph-builder.test.js +301 -0
- package/dist/pipeline/compiler/__tests__/telemetry.test.d.ts +9 -0
- package/dist/pipeline/compiler/__tests__/telemetry.test.js +503 -0
- package/dist/pipeline/compiler/assertion-mapper.d.ts +58 -0
- package/dist/pipeline/compiler/assertion-mapper.js +175 -0
- package/dist/pipeline/compiler/compiler-to-yaml.d.ts +51 -0
- package/dist/pipeline/compiler/compiler-to-yaml.js +222 -0
- package/dist/pipeline/compiler/config-loader.d.ts +56 -0
- package/dist/pipeline/compiler/config-loader.js +111 -0
- package/dist/pipeline/compiler/fixture-resolver.d.ts +41 -0
- package/dist/pipeline/compiler/fixture-resolver.js +113 -0
- package/dist/pipeline/compiler/hash.d.ts +11 -0
- package/dist/pipeline/compiler/hash.js +18 -0
- package/dist/pipeline/compiler/ignore-fields.d.ts +53 -0
- package/dist/pipeline/compiler/ignore-fields.js +113 -0
- package/dist/pipeline/compiler/index.d.ts +29 -0
- package/dist/pipeline/compiler/index.js +45 -0
- package/dist/pipeline/compiler/literacy-bridge.d.ts +102 -0
- package/dist/pipeline/compiler/literacy-bridge.js +172 -0
- package/dist/pipeline/compiler/mode-bases/agent-harness.d.ts +10 -0
- package/dist/pipeline/compiler/mode-bases/agent-harness.js +21 -0
- package/dist/pipeline/compiler/mode-bases/index.d.ts +4 -0
- package/dist/pipeline/compiler/mode-bases/index.js +4 -0
- package/dist/pipeline/compiler/mode-bases/knowledge-probe.d.ts +10 -0
- package/dist/pipeline/compiler/mode-bases/knowledge-probe.js +22 -0
- package/dist/pipeline/compiler/mode-bases/literacy.d.ts +12 -0
- package/dist/pipeline/compiler/mode-bases/literacy.js +78 -0
- package/dist/pipeline/compiler/mode-bases/mcp-server.d.ts +10 -0
- package/dist/pipeline/compiler/mode-bases/mcp-server.js +70 -0
- package/dist/pipeline/compiler/mode-handlers/__fixtures__/agent-harness-example-tasks.d.ts +14 -0
- package/dist/pipeline/compiler/mode-handlers/__fixtures__/agent-harness-example-tasks.js +152 -0
- package/dist/pipeline/compiler/mode-handlers/__fixtures__/knowledge-probe-example-tasks.d.ts +32 -0
- package/dist/pipeline/compiler/mode-handlers/__fixtures__/knowledge-probe-example-tasks.js +176 -0
- package/dist/pipeline/compiler/mode-handlers/__fixtures__/mcp-example-tasks.d.ts +49 -0
- package/dist/pipeline/compiler/mode-handlers/__fixtures__/mcp-example-tasks.js +259 -0
- package/dist/pipeline/compiler/mode-handlers/agent-harness/assertions.d.ts +43 -0
- package/dist/pipeline/compiler/mode-handlers/agent-harness/assertions.js +187 -0
- package/dist/pipeline/compiler/mode-handlers/agent-harness/compiler.d.ts +19 -0
- package/dist/pipeline/compiler/mode-handlers/agent-harness/compiler.js +138 -0
- package/dist/pipeline/compiler/mode-handlers/agent-harness/index.d.ts +16 -0
- package/dist/pipeline/compiler/mode-handlers/agent-harness/index.js +43 -0
- package/dist/pipeline/compiler/mode-handlers/agent-harness/prompts.d.ts +9 -0
- package/dist/pipeline/compiler/mode-handlers/agent-harness/prompts.js +29 -0
- package/dist/pipeline/compiler/mode-handlers/agent-harness/sandbox.d.ts +12 -0
- package/dist/pipeline/compiler/mode-handlers/agent-harness/sandbox.js +82 -0
- package/dist/pipeline/compiler/mode-handlers/agent-harness/tool-presets.d.ts +4 -0
- package/dist/pipeline/compiler/mode-handlers/agent-harness/tool-presets.js +19 -0
- package/dist/pipeline/compiler/mode-handlers/agent-harness/types.d.ts +49 -0
- package/dist/pipeline/compiler/mode-handlers/agent-harness/types.js +4 -0
- package/dist/pipeline/compiler/mode-handlers/agent-harness/validation.d.ts +9 -0
- package/dist/pipeline/compiler/mode-handlers/agent-harness/validation.js +16 -0
- package/dist/pipeline/compiler/mode-handlers/index.d.ts +15 -0
- package/dist/pipeline/compiler/mode-handlers/index.js +19 -0
- package/dist/pipeline/compiler/mode-handlers/knowledge-probe/assertions.d.ts +16 -0
- package/dist/pipeline/compiler/mode-handlers/knowledge-probe/assertions.js +61 -0
- package/dist/pipeline/compiler/mode-handlers/knowledge-probe/compiler.d.ts +18 -0
- package/dist/pipeline/compiler/mode-handlers/knowledge-probe/compiler.js +112 -0
- package/dist/pipeline/compiler/mode-handlers/knowledge-probe/index.d.ts +26 -0
- package/dist/pipeline/compiler/mode-handlers/knowledge-probe/index.js +49 -0
- package/dist/pipeline/compiler/mode-handlers/knowledge-probe/prompts.d.ts +9 -0
- package/dist/pipeline/compiler/mode-handlers/knowledge-probe/prompts.js +28 -0
- package/dist/pipeline/compiler/mode-handlers/knowledge-probe/types.d.ts +44 -0
- package/dist/pipeline/compiler/mode-handlers/knowledge-probe/types.js +4 -0
- package/dist/pipeline/compiler/mode-handlers/knowledge-probe/validation.d.ts +9 -0
- package/dist/pipeline/compiler/mode-handlers/knowledge-probe/validation.js +24 -0
- package/dist/pipeline/compiler/mode-handlers/literacy/assertions.d.ts +18 -0
- package/dist/pipeline/compiler/mode-handlers/literacy/assertions.js +118 -0
- package/dist/pipeline/compiler/mode-handlers/literacy/compiler.d.ts +14 -0
- package/dist/pipeline/compiler/mode-handlers/literacy/compiler.js +105 -0
- package/dist/pipeline/compiler/mode-handlers/literacy/index.d.ts +11 -0
- package/dist/pipeline/compiler/mode-handlers/literacy/index.js +38 -0
- package/dist/pipeline/compiler/mode-handlers/literacy/prompts.d.ts +9 -0
- package/dist/pipeline/compiler/mode-handlers/literacy/prompts.js +74 -0
- package/dist/pipeline/compiler/mode-handlers/literacy/types.d.ts +41 -0
- package/dist/pipeline/compiler/mode-handlers/literacy/types.js +4 -0
- package/dist/pipeline/compiler/mode-handlers/literacy/validation.d.ts +12 -0
- package/dist/pipeline/compiler/mode-handlers/literacy/validation.js +28 -0
- package/dist/pipeline/compiler/mode-handlers/mcp-server/assertions.d.ts +42 -0
- package/dist/pipeline/compiler/mode-handlers/mcp-server/assertions.js +334 -0
- package/dist/pipeline/compiler/mode-handlers/mcp-server/compiler.d.ts +19 -0
- package/dist/pipeline/compiler/mode-handlers/mcp-server/compiler.js +100 -0
- package/dist/pipeline/compiler/mode-handlers/mcp-server/index.d.ts +27 -0
- package/dist/pipeline/compiler/mode-handlers/mcp-server/index.js +54 -0
- package/dist/pipeline/compiler/mode-handlers/mcp-server/prompts.d.ts +8 -0
- package/dist/pipeline/compiler/mode-handlers/mcp-server/prompts.js +28 -0
- package/dist/pipeline/compiler/mode-handlers/mcp-server/provider-config.d.ts +28 -0
- package/dist/pipeline/compiler/mode-handlers/mcp-server/provider-config.js +104 -0
- package/dist/pipeline/compiler/mode-handlers/mcp-server/types.d.ts +37 -0
- package/dist/pipeline/compiler/mode-handlers/mcp-server/types.js +4 -0
- package/dist/pipeline/compiler/mode-handlers/mcp-server/validation.d.ts +9 -0
- package/dist/pipeline/compiler/mode-handlers/mcp-server/validation.js +43 -0
- package/dist/pipeline/compiler/mode-handlers/mcp-tool-provider/index.d.ts +33 -0
- package/dist/pipeline/compiler/mode-handlers/mcp-tool-provider/index.js +174 -0
- package/dist/pipeline/compiler/mode-handlers/mcp-tool-provider/mcp-connection.d.ts +19 -0
- package/dist/pipeline/compiler/mode-handlers/mcp-tool-provider/mcp-connection.js +95 -0
- package/dist/pipeline/compiler/mode-handlers/mcp-tool-provider/tool-loop-anthropic.d.ts +19 -0
- package/dist/pipeline/compiler/mode-handlers/mcp-tool-provider/tool-loop-anthropic.js +172 -0
- package/dist/pipeline/compiler/mode-handlers/mcp-tool-provider/tool-loop-openai.d.ts +14 -0
- package/dist/pipeline/compiler/mode-handlers/mcp-tool-provider/tool-loop-openai.js +16 -0
- package/dist/pipeline/compiler/mode-handlers/mcp-tool-provider/types.d.ts +93 -0
- package/dist/pipeline/compiler/mode-handlers/mcp-tool-provider/types.js +4 -0
- package/dist/pipeline/compiler/preset-loader.d.ts +22 -0
- package/dist/pipeline/compiler/preset-loader.js +99 -0
- package/dist/pipeline/compiler/presets/index.d.ts +9 -0
- package/dist/pipeline/compiler/presets/index.js +8 -0
- package/dist/pipeline/compiler/presets/sanity-literacy.d.ts +42 -0
- package/dist/pipeline/compiler/presets/sanity-literacy.js +208 -0
- package/dist/pipeline/compiler/promptfoo-compiler.d.ts +96 -0
- package/dist/pipeline/compiler/promptfoo-compiler.js +230 -0
- package/dist/pipeline/compiler/provider-assembler.d.ts +39 -0
- package/dist/pipeline/compiler/provider-assembler.js +137 -0
- package/dist/pipeline/compiler/sandbox/docker-sandbox.d.ts +21 -0
- package/dist/pipeline/compiler/sandbox/docker-sandbox.js +136 -0
- package/dist/pipeline/compiler/sandbox/fixture-provisioner.d.ts +69 -0
- package/dist/pipeline/compiler/sandbox/fixture-provisioner.js +189 -0
- package/dist/pipeline/compiler/sandbox/git-worktree-sandbox.d.ts +20 -0
- package/dist/pipeline/compiler/sandbox/git-worktree-sandbox.js +114 -0
- package/dist/pipeline/compiler/sandbox/index.d.ts +10 -0
- package/dist/pipeline/compiler/sandbox/index.js +11 -0
- package/dist/pipeline/compiler/sandbox/sandbox-selector.d.ts +35 -0
- package/dist/pipeline/compiler/sandbox/sandbox-selector.js +86 -0
- package/dist/pipeline/compiler/sandbox/sandbox-strategy.d.ts +81 -0
- package/dist/pipeline/compiler/sandbox/sandbox-strategy.js +15 -0
- package/dist/pipeline/compiler/sandbox/tempdir-sandbox.d.ts +20 -0
- package/dist/pipeline/compiler/sandbox/tempdir-sandbox.js +74 -0
- package/dist/pipeline/compiler/scoring-bridge.d.ts +49 -0
- package/dist/pipeline/compiler/scoring-bridge.js +114 -0
- package/dist/pipeline/compiler/task-graph-builder.d.ts +54 -0
- package/dist/pipeline/compiler/task-graph-builder.js +291 -0
- package/dist/pipeline/compiler/telemetry/cost-tracker.d.ts +90 -0
- package/dist/pipeline/compiler/telemetry/cost-tracker.js +146 -0
- package/dist/pipeline/compiler/telemetry/index.d.ts +14 -0
- package/dist/pipeline/compiler/telemetry/index.js +19 -0
- package/dist/pipeline/compiler/telemetry/redactor.d.ts +58 -0
- package/dist/pipeline/compiler/telemetry/redactor.js +222 -0
- package/dist/pipeline/compiler/telemetry/tool-classifier.d.ts +32 -0
- package/dist/pipeline/compiler/telemetry/tool-classifier.js +120 -0
- package/dist/pipeline/compiler/telemetry/trace-collector.d.ts +75 -0
- package/dist/pipeline/compiler/telemetry/trace-collector.js +297 -0
- package/dist/pipeline/compiler/telemetry/trace-store.d.ts +78 -0
- package/dist/pipeline/compiler/telemetry/trace-store.js +85 -0
- package/dist/pipeline/compiler/variable-resolver.d.ts +46 -0
- package/dist/pipeline/compiler/variable-resolver.js +115 -0
- package/dist/pipeline/coverage-audit.d.ts +15 -5
- package/dist/pipeline/coverage-audit.js +41 -22
- package/dist/pipeline/eval-constants.d.ts +16 -6
- package/dist/pipeline/eval-constants.js +25 -4
- package/dist/pipeline/eval-fingerprint.d.ts +2 -2
- package/dist/pipeline/eval-fingerprint.js +8 -9
- package/dist/pipeline/expand-tasks.d.ts +19 -10
- package/dist/pipeline/expand-tasks.js +34 -28
- package/dist/pipeline/gap-analysis.d.ts +1 -1
- package/dist/pipeline/gap-analysis.js +2 -2
- package/dist/pipeline/generate-configs.d.ts +22 -4
- package/dist/pipeline/generate-configs.js +53 -24
- package/dist/pipeline/grader-api.d.ts +3 -3
- package/dist/pipeline/grader-api.js +5 -12
- package/dist/pipeline/grader-compare-runner.js +20 -27
- package/dist/pipeline/grader-comparison.d.ts +4 -8
- package/dist/pipeline/grader-comparison.js +11 -17
- package/dist/pipeline/grader-consistency-runner.d.ts +2 -3
- package/dist/pipeline/grader-consistency-runner.js +16 -20
- package/dist/pipeline/grader-consistency.d.ts +6 -10
- package/dist/pipeline/grader-consistency.js +13 -32
- package/dist/pipeline/grader-sensitivity-runner.js +7 -5
- package/dist/pipeline/grader-sensitivity.d.ts +2 -6
- package/dist/pipeline/grader-sensitivity.js +10 -10
- package/dist/pipeline/grader-validate-runner.js +7 -5
- package/dist/pipeline/grader-validation.d.ts +2 -6
- package/dist/pipeline/grader-validation.js +14 -22
- package/dist/pipeline/map-request-to-config.js +7 -1
- package/dist/pipeline/mirror-repo-tasks.d.ts +13 -13
- package/dist/pipeline/mirror-repo-tasks.js +22 -21
- package/dist/pipeline/normalize-mode.d.ts +49 -0
- package/dist/pipeline/normalize-mode.js +64 -0
- package/dist/pipeline/plan.d.ts +5 -2
- package/dist/pipeline/plan.js +134 -78
- package/dist/pipeline/pr-comment.js +2 -0
- package/dist/pipeline/profile-resolution.d.ts +22 -14
- package/dist/pipeline/profile-resolution.js +41 -19
- package/dist/pipeline/provenance.d.ts +2 -2
- package/dist/pipeline/provenance.js +12 -17
- package/dist/pipeline/release-report.js +4 -4
- package/dist/pipeline/repo-threshold-evaluator.d.ts +1 -1
- package/dist/pipeline/repo-threshold-evaluator.js +1 -1
- package/dist/pipeline/rubric-loader.d.ts +20 -0
- package/dist/pipeline/rubric-loader.js +37 -0
- package/dist/pipeline/validate.d.ts +4 -4
- package/dist/pipeline/validate.js +64 -53
- package/dist/schedules/loader.js +18 -8
- package/dist/scripts/migrate-task-mode.d.ts +24 -0
- package/dist/scripts/migrate-task-mode.js +85 -0
- package/dist/scripts/migrate-tasks-to-content-lake.js +11 -10
- package/dist/scripts/validate-task-sources.d.ts +1 -1
- package/dist/scripts/validate-task-sources.js +15 -15
- package/dist/sinks/loader.js +5 -7
- package/dist/sources.d.ts +7 -7
- package/dist/sources.js +22 -24
- package/dist/webhook/dispatch.js +2 -1
- package/package.json +15 -4
- package/tasks/knowledge-probe/define-type-api.task.ts +55 -0
- package/tasks/knowledge-probe/groq-projections.task.ts +59 -0
- package/tasks/literacy/frameworks.task.ts +128 -0
- package/tasks/literacy/functions.task.ts +69 -0
- package/tasks/literacy/groq.task.ts +258 -0
- package/tasks/literacy/nextjs-live.task.ts +75 -0
- package/tasks/literacy/studio-setup.task.ts +131 -0
- package/tasks/literacy/visual-editing.task.ts +146 -0
- package/config/features.yaml +0 -116
- package/config/models.yaml +0 -116
- package/config/prompts.yaml +0 -75
- package/config/rubrics.yaml +0 -81
- package/config/schedules.yaml +0 -43
- package/config/sinks.yaml +0 -54
- package/config/sources.yaml +0 -51
- package/config/thresholds.yaml +0 -49
- package/dist/_vendor/ailf-tasks/cli.d.ts +0 -8
- package/dist/_vendor/ailf-tasks/cli.js +0 -61
- package/dist/_vendor/ailf-tasks/index.d.ts +0 -13
- package/dist/_vendor/ailf-tasks/index.js +0 -16
- package/dist/_vendor/ailf-tasks/parser.d.ts +0 -27
- package/dist/_vendor/ailf-tasks/parser.js +0 -73
- package/dist/_vendor/ailf-tasks/schemas.d.ts +0 -198
- package/dist/_vendor/ailf-tasks/schemas.js +0 -180
- package/dist/_vendor/ailf-tasks/validation.d.ts +0 -47
- package/dist/_vendor/ailf-tasks/validation.js +0 -162
- package/dist/agent-observer/test-imports.d.ts +0 -7
- package/dist/agent-observer/test-imports.js +0 -185
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* Doc Coverage (0–100) — Did docs provide the needed info?
|
|
10
10
|
*
|
|
11
11
|
* Dimensions are combined into a weighted composite (0–100) using named
|
|
12
|
-
* scoring profiles from config/rubrics.
|
|
12
|
+
* scoring profiles from config/rubrics. Gold (with-docs) entries use
|
|
13
13
|
* the "default" profile; baseline (without-docs) entries use "output-only"
|
|
14
14
|
* which excludes doc-coverage (undefined without docs).
|
|
15
15
|
* See docs/design-docs/named-scoring-profiles.md.
|
|
@@ -29,15 +29,17 @@
|
|
|
29
29
|
*/
|
|
30
30
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
31
31
|
import { join } from "path";
|
|
32
|
+
import { classifyRubric, detectFeatureArea, extractUrlMetadata, mergeScores, parseRubricScore, } from "../_vendor/ailf-core/index.js";
|
|
32
33
|
import { calculateCost } from "../agent-observer/pricing.js";
|
|
33
34
|
import { ConsoleLogger } from "../adapters/loggers/index.js";
|
|
35
|
+
import { analyzeSourceIsolation, } from "../assertions/source-isolation.js";
|
|
34
36
|
import { checkResultsExist } from "./checks.js";
|
|
35
|
-
import { loadRubricTemplates } from "./
|
|
37
|
+
import { loadRubricTemplates } from "./rubric-loader.js";
|
|
36
38
|
import { resolveProfile } from "./profile-resolution.js";
|
|
37
39
|
import { loadSource } from "../sources.js";
|
|
38
|
-
import {
|
|
39
|
-
import {
|
|
40
|
-
// Re-export
|
|
40
|
+
import { LiteracyVariant } from "./normalize-mode.js";
|
|
41
|
+
import { scoreTestGroup } from "./compiler/scoring-bridge.js";
|
|
42
|
+
// Re-export from core for backward compatibility.
|
|
41
43
|
// Existing imports from this file continue to work unchanged.
|
|
42
44
|
export { classifyRubric, detectFeatureArea, extractUrlMetadata, mergeScores, parseRubricScore, } from "../_vendor/ailf-core/index.js";
|
|
43
45
|
/**
|
|
@@ -137,14 +139,8 @@ export function extractGraderJudgments(resultsPath) {
|
|
|
137
139
|
// Not JSON — use raw reason string
|
|
138
140
|
}
|
|
139
141
|
}
|
|
140
|
-
// Map internal dimension names to hyphenated form
|
|
141
|
-
const dimensionMap = {
|
|
142
|
-
codeCorrectness: "code-correctness",
|
|
143
|
-
docCoverage: "doc-coverage",
|
|
144
|
-
taskCompletion: "task-completion",
|
|
145
|
-
};
|
|
146
142
|
judgments.push({
|
|
147
|
-
dimension:
|
|
143
|
+
dimension: kind,
|
|
148
144
|
modelId,
|
|
149
145
|
reason,
|
|
150
146
|
score,
|
|
@@ -281,7 +277,7 @@ function aggregateUrlReferences(resultsPath) {
|
|
|
281
277
|
* verification report.
|
|
282
278
|
*/
|
|
283
279
|
function buildSourceVerification(root, source, verificationCtx) {
|
|
284
|
-
const mode = verificationCtx?.mode ??
|
|
280
|
+
const mode = verificationCtx?.mode ?? LiteracyVariant.STANDARD;
|
|
285
281
|
const sourceUrl = source?.baseUrl ?? "default";
|
|
286
282
|
const searchMode = verificationCtx?.searchMode;
|
|
287
283
|
const allowedOrigins = verificationCtx?.allowedOrigins;
|
|
@@ -493,62 +489,6 @@ function readAndNormalizeResults(resultsPath, log) {
|
|
|
493
489
|
}
|
|
494
490
|
return valid;
|
|
495
491
|
}
|
|
496
|
-
/**
|
|
497
|
-
* Accumulate raw dimension scores across an array of test results.
|
|
498
|
-
* Dimension-agnostic: any dimension returned by classifyRubric() is tracked.
|
|
499
|
-
*/
|
|
500
|
-
function accumulateDimensions(tests) {
|
|
501
|
-
const dimensions = {};
|
|
502
|
-
let totalCost = 0;
|
|
503
|
-
for (const test of tests) {
|
|
504
|
-
totalCost += test.cost;
|
|
505
|
-
for (const comp of test.gradingResult.componentResults) {
|
|
506
|
-
if (comp.assertion?.type !== "llm-rubric")
|
|
507
|
-
continue;
|
|
508
|
-
const score = parseRubricScore(comp);
|
|
509
|
-
const kind = classifyRubric(comp);
|
|
510
|
-
if (kind) {
|
|
511
|
-
dimensions[kind] = (dimensions[kind] ?? 0) + score;
|
|
512
|
-
}
|
|
513
|
-
}
|
|
514
|
-
}
|
|
515
|
-
return { dimensions, totalCost };
|
|
516
|
-
}
|
|
517
|
-
/**
|
|
518
|
-
* Average accumulated dimension scores by a count.
|
|
519
|
-
* Returns a dimension → average score map.
|
|
520
|
-
*/
|
|
521
|
-
function averageDimensions(accumulated, count) {
|
|
522
|
-
const avg = {};
|
|
523
|
-
for (const [dim, total] of Object.entries(accumulated.dimensions)) {
|
|
524
|
-
avg[dim] = total / count;
|
|
525
|
-
}
|
|
526
|
-
return avg;
|
|
527
|
-
}
|
|
528
|
-
/**
|
|
529
|
-
* Compute a weighted composite score from dimension averages and a profile.
|
|
530
|
-
* Only dimensions present in the profile contribute to the composite.
|
|
531
|
-
* Dimensions not in the profile are ignored (e.g., doc-coverage on baseline).
|
|
532
|
-
*
|
|
533
|
-
* The profile maps camelCase dimension names (as returned by classifyRubric)
|
|
534
|
-
* to kebab-case keys (as used in rubrics.yaml). This function handles the
|
|
535
|
-
* mapping internally.
|
|
536
|
-
*/
|
|
537
|
-
function weightedComposite(dimensionAverages, profile) {
|
|
538
|
-
// Map profile keys (kebab-case: "task-completion") to classifyRubric
|
|
539
|
-
// output (camelCase: "taskCompletion")
|
|
540
|
-
const kebabToCamel = {
|
|
541
|
-
"code-correctness": "codeCorrectness",
|
|
542
|
-
"doc-coverage": "docCoverage",
|
|
543
|
-
"task-completion": "taskCompletion",
|
|
544
|
-
};
|
|
545
|
-
let total = 0;
|
|
546
|
-
for (const [profileKey, weight] of Object.entries(profile)) {
|
|
547
|
-
const dimKey = kebabToCamel[profileKey] ?? profileKey;
|
|
548
|
-
total += (dimensionAverages[dimKey] ?? 0) * weight;
|
|
549
|
-
}
|
|
550
|
-
return total;
|
|
551
|
-
}
|
|
552
492
|
/**
|
|
553
493
|
* Core scoring logic: takes a pre-filtered array of TestResult and produces
|
|
554
494
|
* FeatureScore[] grouped by feature area. This is the shared implementation
|
|
@@ -577,35 +517,28 @@ function scoreResults(results, goldProfile, baselineProfile, modelId) {
|
|
|
577
517
|
}
|
|
578
518
|
const scores = [];
|
|
579
519
|
for (const [feature, data] of Object.entries(byFeature)) {
|
|
580
|
-
// --- With docs (gold / ceiling) ---
|
|
581
|
-
const
|
|
582
|
-
let featureCost = goldDims.totalCost;
|
|
583
|
-
const countWithDocs = data.withDocs.length || 1;
|
|
584
|
-
const avgGold = averageDimensions(goldDims, countWithDocs);
|
|
585
|
-
const withDocsTotal = weightedComposite(avgGold, goldProfile);
|
|
520
|
+
// --- With docs (gold / ceiling) — scored via 4-tier engine ---
|
|
521
|
+
const gold = scoreTestGroup(data.withDocs, goldProfile, feature);
|
|
586
522
|
// --- Without docs (baseline / floor) ---
|
|
587
523
|
// Uses the baseline profile (e.g. "output-only") which may exclude
|
|
588
524
|
// dimensions like doc-coverage that are undefined without docs.
|
|
589
525
|
// See docs/design-docs/named-scoring-profiles.md.
|
|
590
|
-
const
|
|
591
|
-
featureCost
|
|
592
|
-
const
|
|
593
|
-
const
|
|
594
|
-
const withoutDocsScore = weightedComposite(avgBaseline, baselineProfile);
|
|
595
|
-
const ceilingScore = Math.round(withDocsTotal);
|
|
596
|
-
const floorScore = Math.round(withoutDocsScore);
|
|
526
|
+
const baseline = scoreTestGroup(data.withoutDocs, baselineProfile, feature);
|
|
527
|
+
const featureCost = gold.totalCost + baseline.totalCost;
|
|
528
|
+
const ceilingScore = gold.composite;
|
|
529
|
+
const floorScore = baseline.composite;
|
|
597
530
|
const docLift = ceilingScore - floorScore;
|
|
598
531
|
const featureScore = {
|
|
599
532
|
ceilingScore,
|
|
600
|
-
codeCorrectness:
|
|
601
|
-
docCoverage:
|
|
533
|
+
codeCorrectness: gold.dimensions.codeCorrectness ?? 0,
|
|
534
|
+
docCoverage: gold.dimensions.docCoverage ?? 0,
|
|
602
535
|
docLift,
|
|
603
536
|
docQualityGap: 100 - ceilingScore,
|
|
604
537
|
feature,
|
|
605
538
|
floorScore,
|
|
606
539
|
...(modelId && { modelId }),
|
|
607
540
|
negativeDocLift: docLift < 0,
|
|
608
|
-
taskCompletion:
|
|
541
|
+
taskCompletion: gold.dimensions.taskCompletion ?? 0,
|
|
609
542
|
testCount: data.withDocs.length,
|
|
610
543
|
totalCost: featureCost,
|
|
611
544
|
totalScore: ceilingScore,
|
|
@@ -638,17 +571,14 @@ export function scoreAgenticResults(resultsPath, profile) {
|
|
|
638
571
|
}
|
|
639
572
|
const entries = {};
|
|
640
573
|
for (const [feature, featureResults] of Object.entries(byFeature)) {
|
|
641
|
-
const
|
|
642
|
-
const accumulated = accumulateDimensions(featureResults);
|
|
643
|
-
const avg = averageDimensions(accumulated, count);
|
|
644
|
-
const actualScore = Math.round(weightedComposite(avg, profile));
|
|
574
|
+
const scored = scoreTestGroup(featureResults, profile, feature);
|
|
645
575
|
entries[feature] = {
|
|
646
|
-
actualScore,
|
|
647
|
-
codeCorrectness:
|
|
648
|
-
docCoverage:
|
|
649
|
-
taskCompletion:
|
|
576
|
+
actualScore: scored.composite,
|
|
577
|
+
codeCorrectness: scored.dimensions.codeCorrectness ?? 0,
|
|
578
|
+
docCoverage: scored.dimensions.docCoverage ?? 0,
|
|
579
|
+
taskCompletion: scored.dimensions.taskCompletion ?? 0,
|
|
650
580
|
testCount: featureResults.length,
|
|
651
|
-
totalCost:
|
|
581
|
+
totalCost: scored.totalCost,
|
|
652
582
|
};
|
|
653
583
|
}
|
|
654
584
|
return entries;
|
|
@@ -677,17 +607,14 @@ export function scoreAgenticResultsPerModel(resultsPath, profile) {
|
|
|
677
607
|
for (const [modelId, features] of Object.entries(byModel)) {
|
|
678
608
|
perModel[modelId] = {};
|
|
679
609
|
for (const [feature, featureResults] of Object.entries(features)) {
|
|
680
|
-
const
|
|
681
|
-
const accumulated = accumulateDimensions(featureResults);
|
|
682
|
-
const avg = averageDimensions(accumulated, count);
|
|
683
|
-
const actualScore = Math.round(weightedComposite(avg, profile));
|
|
610
|
+
const scored = scoreTestGroup(featureResults, profile, feature);
|
|
684
611
|
perModel[modelId][feature] = {
|
|
685
|
-
actualScore,
|
|
686
|
-
codeCorrectness:
|
|
687
|
-
docCoverage:
|
|
688
|
-
taskCompletion:
|
|
612
|
+
actualScore: scored.composite,
|
|
613
|
+
codeCorrectness: scored.dimensions.codeCorrectness ?? 0,
|
|
614
|
+
docCoverage: scored.dimensions.docCoverage ?? 0,
|
|
615
|
+
taskCompletion: scored.dimensions.taskCompletion ?? 0,
|
|
689
616
|
testCount: featureResults.length,
|
|
690
|
-
totalCost:
|
|
617
|
+
totalCost: scored.totalCost,
|
|
691
618
|
};
|
|
692
619
|
}
|
|
693
620
|
}
|
|
@@ -725,7 +652,7 @@ export function calculateAndWriteScores(options) {
|
|
|
725
652
|
}
|
|
726
653
|
}
|
|
727
654
|
// Determine mode — controls which result files are read
|
|
728
|
-
const mode = options.mode ??
|
|
655
|
+
const mode = options.mode ?? LiteracyVariant.STANDARD;
|
|
729
656
|
const baselineResultsPath = options.resultsPath ?? join(ROOT, "results", "latest", "eval-results.json");
|
|
730
657
|
// Agentic results path (only used in full mode)
|
|
731
658
|
const agenticResultsPath = join(ROOT, "results", "latest", "eval-results-agentic.json");
|
|
@@ -747,8 +674,8 @@ export function calculateAndWriteScores(options) {
|
|
|
747
674
|
// Baseline (without-docs) entries use "output-only" (2 dimensions,
|
|
748
675
|
// doc-coverage excluded). See docs/design-docs/named-scoring-profiles.md.
|
|
749
676
|
const rubricConfig = loadRubricTemplates(ROOT);
|
|
750
|
-
const goldProfile = resolveProfile("
|
|
751
|
-
const baselineProfileWeights = resolveProfile("
|
|
677
|
+
const goldProfile = resolveProfile("literacy", "gold", rubricConfig, LiteracyVariant.STANDARD);
|
|
678
|
+
const baselineProfileWeights = resolveProfile("literacy", LiteracyVariant.STANDARD, rubricConfig, LiteracyVariant.STANDARD);
|
|
752
679
|
log.debug("Loaded scoring profiles", {
|
|
753
680
|
gold: goldProfile,
|
|
754
681
|
baseline: baselineProfileWeights,
|
|
@@ -776,9 +703,9 @@ export function calculateAndWriteScores(options) {
|
|
|
776
703
|
let agentBehavior = null;
|
|
777
704
|
let sourceIsolation = null;
|
|
778
705
|
let evaluationMode;
|
|
779
|
-
if (mode ===
|
|
706
|
+
if (mode === LiteracyVariant.FULL && existsSync(agenticResultsPath)) {
|
|
780
707
|
log.info(`\nReading agentic results from: ${agenticResultsPath}`);
|
|
781
|
-
const agenticProfile = resolveProfile("
|
|
708
|
+
const agenticProfile = resolveProfile("literacy", "gold", rubricConfig, LiteracyVariant.AGENTIC);
|
|
782
709
|
const agenticScores = scoreAgenticResults(agenticResultsPath, agenticProfile);
|
|
783
710
|
log.debug("Agentic scores calculated", {
|
|
784
711
|
featureCount: Object.keys(agenticScores).length,
|
|
@@ -789,7 +716,7 @@ export function calculateAndWriteScores(options) {
|
|
|
789
716
|
})),
|
|
790
717
|
});
|
|
791
718
|
scores = mergeScores(baselineScores, agenticScores);
|
|
792
|
-
evaluationMode =
|
|
719
|
+
evaluationMode = LiteracyVariant.FULL;
|
|
793
720
|
// Merge agentic actual scores into the per-model breakdown
|
|
794
721
|
if (perModel) {
|
|
795
722
|
const agenticPerModel = scoreAgenticResultsPerModel(agenticResultsPath, agenticProfile);
|
|
@@ -812,17 +739,20 @@ export function calculateAndWriteScores(options) {
|
|
|
812
739
|
graderCost.completionTokens += agenticGraderCost.completionTokens;
|
|
813
740
|
}
|
|
814
741
|
}
|
|
815
|
-
else if (mode ===
|
|
742
|
+
else if (mode === LiteracyVariant.AGENTIC) {
|
|
816
743
|
scores = baselineScores;
|
|
817
744
|
agentBehavior = aggregateAgentBehavior(baselineResultsPath);
|
|
818
745
|
sourceIsolation = aggregateSourceIsolation(baselineResultsPath, options?.allowedOrigins);
|
|
819
|
-
evaluationMode =
|
|
746
|
+
evaluationMode = LiteracyVariant.AGENTIC;
|
|
820
747
|
}
|
|
821
748
|
else {
|
|
822
749
|
scores = baselineScores;
|
|
823
750
|
agentBehavior = aggregateAgentBehavior(baselineResultsPath);
|
|
824
751
|
sourceIsolation = aggregateSourceIsolation(baselineResultsPath, options?.allowedOrigins);
|
|
825
|
-
evaluationMode =
|
|
752
|
+
evaluationMode =
|
|
753
|
+
mode === LiteracyVariant.OBSERVED
|
|
754
|
+
? LiteracyVariant.OBSERVED
|
|
755
|
+
: LiteracyVariant.STANDARD;
|
|
826
756
|
}
|
|
827
757
|
const summary = printReport(scores, urlRefs, source, agentBehavior, graderCost, perModel, sourceIsolation, sourceVerification, evaluationMode, log);
|
|
828
758
|
// Persist
|
|
@@ -833,7 +763,7 @@ export function calculateAndWriteScores(options) {
|
|
|
833
763
|
// Extract and persist grader judgments (Phase 3a: failure mode extraction)
|
|
834
764
|
const judgments = extractGraderJudgments(baselineResultsPath);
|
|
835
765
|
// In full mode, also extract judgments from agentic results
|
|
836
|
-
if (mode ===
|
|
766
|
+
if (mode === LiteracyVariant.FULL && existsSync(agenticResultsPath)) {
|
|
837
767
|
const agenticJudgments = extractGraderJudgments(agenticResultsPath);
|
|
838
768
|
judgments.push(...agenticJudgments);
|
|
839
769
|
}
|
package/dist/pipeline/checks.js
CHANGED
|
@@ -117,7 +117,7 @@ export function checkGeneratedConfigsExist(rootDir) {
|
|
|
117
117
|
const baselinePath = resolve(rootDir, "promptfooconfig.yaml");
|
|
118
118
|
if (!existsSync(baselinePath)) {
|
|
119
119
|
issues.push({
|
|
120
|
-
message: "Baseline config 'promptfooconfig.yaml' not found. Run
|
|
120
|
+
message: "Baseline config 'promptfooconfig.yaml' not found. Run the pipeline to generate it.",
|
|
121
121
|
path: baselinePath,
|
|
122
122
|
severity: "error",
|
|
123
123
|
source: "checkGeneratedConfigsExist",
|
|
@@ -131,7 +131,7 @@ export function checkGeneratedConfigsExist(rootDir) {
|
|
|
131
131
|
const configPath = resolve(rootDir, name);
|
|
132
132
|
if (!existsSync(configPath)) {
|
|
133
133
|
issues.push({
|
|
134
|
-
message: `Optional config \`${name}\` not found. Run
|
|
134
|
+
message: `Optional config \`${name}\` not found. Run the pipeline to generate it.`,
|
|
135
135
|
path: configPath,
|
|
136
136
|
severity: "warning",
|
|
137
137
|
source: "checkGeneratedConfigsExist",
|
package/dist/pipeline/compare.js
CHANGED
|
@@ -79,14 +79,14 @@ export function compare(baseline, experiment, options) {
|
|
|
79
79
|
// Per-dimension average deltas (only for areas present in both summaries)
|
|
80
80
|
const commonAreas = areas.filter((a) => baselineAreas.has(a.area) && experimentAreas.has(a.area));
|
|
81
81
|
const commonCount = commonAreas.length || 1;
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}
|
|
82
|
+
// Collect all dimension keys from area deltas and average each
|
|
83
|
+
const allDimKeys = new Set(commonAreas.flatMap((a) => Object.keys(a.dimensions)));
|
|
84
|
+
const perDimension = {};
|
|
85
|
+
for (const dim of allDimKeys) {
|
|
86
|
+
perDimension[dim] =
|
|
87
|
+
commonAreas.reduce((s, a) => s + (a.dimensions[dim]?.delta ?? 0), 0) /
|
|
88
|
+
commonCount;
|
|
89
|
+
}
|
|
90
90
|
// Doc Lift average delta (common areas only)
|
|
91
91
|
const docLift = commonAreas.reduce((s, a) => s + a.docLiftDelta, 0) / commonCount;
|
|
92
92
|
// Cost delta (if both summaries have cost data)
|
|
@@ -0,0 +1,10 @@
|
|
|
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
|
+
export {};
|
|
@@ -0,0 +1,288 @@
|
|
|
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 provider", () => {
|
|
91
|
+
const result = compileAgentHarnessTask(makeTask());
|
|
92
|
+
assert.ok(result.providers.length > 0);
|
|
93
|
+
assert.ok(result.providers[0].id.startsWith("agent:"));
|
|
94
|
+
});
|
|
95
|
+
it("resolves coding tool preset", () => {
|
|
96
|
+
const result = compileAgentHarnessTask(makeTask({ tools: ["coding"] }));
|
|
97
|
+
const config = result.providers[0].config;
|
|
98
|
+
const tools = config.allowedTools;
|
|
99
|
+
assert.ok(tools.includes("Bash"));
|
|
100
|
+
assert.ok(tools.includes("Read"));
|
|
101
|
+
assert.ok(tools.includes("Write"));
|
|
102
|
+
assert.ok(tools.includes("Edit"));
|
|
103
|
+
});
|
|
104
|
+
it("resolves read-only tool preset", () => {
|
|
105
|
+
const result = compileAgentHarnessTask(makeTask({ tools: ["read-only"] }));
|
|
106
|
+
const config = result.providers[0].config;
|
|
107
|
+
const tools = config.allowedTools;
|
|
108
|
+
assert.ok(tools.includes("Read"));
|
|
109
|
+
assert.ok(tools.includes("Grep"));
|
|
110
|
+
assert.ok(!tools.includes("Write"), "read-only should not include Write");
|
|
111
|
+
});
|
|
112
|
+
it("mixes preset and explicit tools", () => {
|
|
113
|
+
const result = compileAgentHarnessTask(makeTask({ tools: ["read-only", "WebFetch"] }));
|
|
114
|
+
const config = result.providers[0].config;
|
|
115
|
+
const tools = config.allowedTools;
|
|
116
|
+
assert.ok(tools.includes("Read"));
|
|
117
|
+
assert.ok(tools.includes("WebFetch"));
|
|
118
|
+
});
|
|
119
|
+
it("includes sandbox config in provider", () => {
|
|
120
|
+
const result = compileAgentHarnessTask(makeTask({
|
|
121
|
+
sandbox: { type: "docker", image: "node:22-slim" },
|
|
122
|
+
}));
|
|
123
|
+
const config = result.providers[0].config;
|
|
124
|
+
const sandbox = config.sandbox;
|
|
125
|
+
assert.equal(sandbox.type, "docker");
|
|
126
|
+
assert.equal(sandbox.image, "node:22-slim");
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
// ---------------------------------------------------------------------------
|
|
130
|
+
// compileAgentHarnessTask — test cases
|
|
131
|
+
// ---------------------------------------------------------------------------
|
|
132
|
+
describe("compileAgentHarnessTask — test cases", () => {
|
|
133
|
+
it("produces at least one test case", () => {
|
|
134
|
+
const result = compileAgentHarnessTask(makeTask());
|
|
135
|
+
assert.ok(result.tests.length > 0);
|
|
136
|
+
});
|
|
137
|
+
it("includes task description in vars", () => {
|
|
138
|
+
const result = compileAgentHarnessTask(makeTask({ description: "Do the thing" }));
|
|
139
|
+
assert.equal(result.tests[0].vars.task, "Do the thing");
|
|
140
|
+
});
|
|
141
|
+
it("prefers prompt.vars.task over description", () => {
|
|
142
|
+
const result = compileAgentHarnessTask(makeTask({
|
|
143
|
+
description: "Description",
|
|
144
|
+
prompt: { vars: { task: "Custom prompt" } },
|
|
145
|
+
}));
|
|
146
|
+
assert.equal(result.tests[0].vars.task, "Custom prompt");
|
|
147
|
+
});
|
|
148
|
+
it("creates multi-turn test case", () => {
|
|
149
|
+
const result = compileAgentHarnessTask(makeTask({
|
|
150
|
+
multiTurn: {
|
|
151
|
+
turns: [
|
|
152
|
+
{ role: "user", content: "Hello" },
|
|
153
|
+
{ role: "assistant", content: "Hi" },
|
|
154
|
+
],
|
|
155
|
+
},
|
|
156
|
+
}));
|
|
157
|
+
assert.equal(result.tests.length, 2);
|
|
158
|
+
assert.ok(result.tests[1].description.includes("[multi-turn]"));
|
|
159
|
+
});
|
|
160
|
+
it("sets sandbox metadata in vars", () => {
|
|
161
|
+
const result = compileAgentHarnessTask(makeTask({ sandbox: { type: "docker" } }));
|
|
162
|
+
assert.equal(result.tests[0].vars.__sandboxType, "docker");
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
// ---------------------------------------------------------------------------
|
|
166
|
+
// compileAgentHarnessTask — assertions
|
|
167
|
+
// ---------------------------------------------------------------------------
|
|
168
|
+
describe("compileAgentHarnessTask — assertions", () => {
|
|
169
|
+
it("maps file-exists to 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.ok(assertion.value.includes("sanity.config.ts"));
|
|
177
|
+
});
|
|
178
|
+
it("maps file-contains to javascript assertion", () => {
|
|
179
|
+
const result = compileAgentHarnessTask(makeTask({
|
|
180
|
+
assertions: [
|
|
181
|
+
{
|
|
182
|
+
type: "file-contains",
|
|
183
|
+
value: { path: "config.ts", content: "projectId" },
|
|
184
|
+
},
|
|
185
|
+
],
|
|
186
|
+
}));
|
|
187
|
+
const assertion = result.tests[0].assert?.[0];
|
|
188
|
+
assert.ok(assertion);
|
|
189
|
+
assert.equal(assertion.type, "javascript");
|
|
190
|
+
assert.ok(assertion.value.includes("projectId"));
|
|
191
|
+
});
|
|
192
|
+
it("maps command-succeeds to javascript assertion", () => {
|
|
193
|
+
const result = compileAgentHarnessTask(makeTask({
|
|
194
|
+
assertions: [{ type: "command-succeeds", value: "npx tsc --noEmit" }],
|
|
195
|
+
}));
|
|
196
|
+
const assertion = result.tests[0].assert?.[0];
|
|
197
|
+
assert.ok(assertion);
|
|
198
|
+
assert.equal(assertion.type, "javascript");
|
|
199
|
+
assert.ok(assertion.value.includes("tsc"));
|
|
200
|
+
});
|
|
201
|
+
it("maps diff-matches to javascript assertion", () => {
|
|
202
|
+
const result = compileAgentHarnessTask(makeTask({
|
|
203
|
+
assertions: [{ type: "diff-matches", value: "createClient" }],
|
|
204
|
+
}));
|
|
205
|
+
const assertion = result.tests[0].assert?.[0];
|
|
206
|
+
assert.ok(assertion);
|
|
207
|
+
assert.equal(assertion.type, "javascript");
|
|
208
|
+
assert.ok(assertion.value.includes("git diff"));
|
|
209
|
+
});
|
|
210
|
+
it("passes through standard assertions", () => {
|
|
211
|
+
const result = compileAgentHarnessTask(makeTask({
|
|
212
|
+
assertions: [{ type: "contains", value: "sanity" }],
|
|
213
|
+
}));
|
|
214
|
+
assert.equal(result.tests[0].assert?.[0]?.type, "contains");
|
|
215
|
+
});
|
|
216
|
+
it("sets grader provider on llm-rubric", () => {
|
|
217
|
+
const result = compileAgentHarnessTask(makeTask({
|
|
218
|
+
assertions: [{ type: "llm-rubric", value: "Check quality" }],
|
|
219
|
+
}), { graderProvider: "openai:chat:gpt-5" });
|
|
220
|
+
assert.equal(result.tests[0].assert?.[0]?.provider, "openai:chat:gpt-5");
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
|
+
// ---------------------------------------------------------------------------
|
|
224
|
+
// compileAgentHarnessTask — lifecycle extensions
|
|
225
|
+
// ---------------------------------------------------------------------------
|
|
226
|
+
describe("compileAgentHarnessTask — lifecycle", () => {
|
|
227
|
+
it("produces beforeEach and afterEach extensions", () => {
|
|
228
|
+
const result = compileAgentHarnessTask(makeTask());
|
|
229
|
+
assert.equal(result.extensions.length, 2);
|
|
230
|
+
assert.equal(result.extensions[0].type, "beforeEach");
|
|
231
|
+
assert.equal(result.extensions[1].type, "afterEach");
|
|
232
|
+
});
|
|
233
|
+
it("beforeEach hook creates working directory", () => {
|
|
234
|
+
const result = compileAgentHarnessTask(makeTask());
|
|
235
|
+
assert.ok(result.extensions[0].code.includes("mkdirSync"));
|
|
236
|
+
assert.ok(result.extensions[0].code.includes("__workingDir"));
|
|
237
|
+
});
|
|
238
|
+
it("afterEach hook cleans up", () => {
|
|
239
|
+
const result = compileAgentHarnessTask(makeTask());
|
|
240
|
+
assert.ok(result.extensions[1].code.includes("rmSync"));
|
|
241
|
+
});
|
|
242
|
+
it("sandbox config captures task settings", () => {
|
|
243
|
+
const result = compileAgentHarnessTask(makeTask({
|
|
244
|
+
sandbox: {
|
|
245
|
+
type: "docker",
|
|
246
|
+
image: "node:22",
|
|
247
|
+
limits: { cpus: 2, networkAccess: false },
|
|
248
|
+
},
|
|
249
|
+
fixtures: ["file://schema.ts"],
|
|
250
|
+
}));
|
|
251
|
+
assert.equal(result.sandboxConfig.type, "docker");
|
|
252
|
+
assert.equal(result.sandboxConfig.image, "node:22");
|
|
253
|
+
assert.deepEqual(result.sandboxConfig.fixtures, ["file://schema.ts"]);
|
|
254
|
+
assert.equal(result.sandboxConfig.limits?.cpus, 2);
|
|
255
|
+
assert.equal(result.sandboxConfig.limits?.networkAccess, false);
|
|
256
|
+
});
|
|
257
|
+
});
|
|
258
|
+
// ---------------------------------------------------------------------------
|
|
259
|
+
// Example task compilation (end-to-end)
|
|
260
|
+
// ---------------------------------------------------------------------------
|
|
261
|
+
describe("example agent harness tasks — end-to-end", () => {
|
|
262
|
+
it("compiles all example tasks without errors", () => {
|
|
263
|
+
for (const task of allAgentHarnessExampleTasks) {
|
|
264
|
+
const result = compileAgentHarnessTask(task);
|
|
265
|
+
assert.ok(result.providers.length > 0, `${task.id}: should produce providers`);
|
|
266
|
+
assert.ok(result.tests.length > 0, `${task.id}: should produce test cases`);
|
|
267
|
+
assert.ok(result.extensions.length > 0, `${task.id}: should produce lifecycle extensions`);
|
|
268
|
+
}
|
|
269
|
+
});
|
|
270
|
+
it("scaffold task has file-exists assertions", () => {
|
|
271
|
+
const result = compileAgentHarnessTask(scaffoldProjectTask);
|
|
272
|
+
assert.ok(result.tests[0].assert);
|
|
273
|
+
assert.ok(result.tests[0].assert.length >= 3);
|
|
274
|
+
// First two are file-exists (javascript), third is file-contains, fourth is command-succeeds
|
|
275
|
+
assert.equal(result.tests[0].assert[0].type, "javascript");
|
|
276
|
+
});
|
|
277
|
+
it("modify task has file-contains assertions", () => {
|
|
278
|
+
const result = compileAgentHarnessTask(modifyCodeTask);
|
|
279
|
+
assert.ok(result.tests[0].assert);
|
|
280
|
+
assert.ok(result.tests[0].assert.some((a) => a.type === "javascript" &&
|
|
281
|
+
a.value.includes("useDocumentOperation")));
|
|
282
|
+
});
|
|
283
|
+
it("refactor task has docker sandbox config", () => {
|
|
284
|
+
const result = compileAgentHarnessTask(multiFileRefactorTask);
|
|
285
|
+
assert.equal(result.sandboxConfig.type, "docker");
|
|
286
|
+
assert.equal(result.sandboxConfig.image, "node:22-slim");
|
|
287
|
+
});
|
|
288
|
+
});
|
|
@@ -0,0 +1,9 @@
|
|
|
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 {};
|