@warlock.js/ai 4.2.11 → 4.3.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/CHANGELOG.md +61 -1
- package/cjs/index.cjs +10151 -4625
- package/cjs/index.cjs.map +1 -1
- package/cjs/magic-string.es-BtxW4VqG.cjs +1015 -0
- package/cjs/magic-string.es-BtxW4VqG.cjs.map +1 -0
- package/cjs/matcher-logic-SBnzYohQ.cjs +217 -0
- package/cjs/matcher-logic-SBnzYohQ.cjs.map +1 -0
- package/cjs/matchers-BBh3gyB-.cjs +13739 -0
- package/cjs/matchers-BBh3gyB-.cjs.map +1 -0
- package/esm/agent/agent-config.type.d.mts +19 -6
- package/esm/agent/agent-config.type.d.mts.map +1 -1
- package/esm/agent/agent.d.mts.map +1 -1
- package/esm/agent/agent.mjs +17 -6
- package/esm/agent/agent.mjs.map +1 -1
- package/esm/agent/index.d.mts +2 -1
- package/esm/agent/index.mjs +1 -0
- package/esm/agent/spawn-sub-agent.d.mts +87 -0
- package/esm/agent/spawn-sub-agent.d.mts.map +1 -0
- package/esm/agent/spawn-sub-agent.mjs +68 -0
- package/esm/agent/spawn-sub-agent.mjs.map +1 -0
- package/esm/ai.d.mts +58 -3
- package/esm/ai.d.mts.map +1 -1
- package/esm/ai.mjs +58 -3
- package/esm/ai.mjs.map +1 -1
- package/esm/batch/batch.d.mts +43 -0
- package/esm/batch/batch.d.mts.map +1 -0
- package/esm/batch/batch.mjs +179 -0
- package/esm/batch/batch.mjs.map +1 -0
- package/esm/batch/batch.type.d.mts +144 -0
- package/esm/batch/batch.type.d.mts.map +1 -0
- package/esm/batch/index.mjs +3 -0
- package/esm/batch/run-batch-item.mjs +100 -0
- package/esm/batch/run-batch-item.mjs.map +1 -0
- package/esm/batch/run-with-concurrency.mjs +39 -0
- package/esm/batch/run-with-concurrency.mjs.map +1 -0
- package/esm/checkpoint/index.d.mts +3 -0
- package/esm/checkpoint/memory.d.mts +21 -0
- package/esm/checkpoint/memory.d.mts.map +1 -0
- package/esm/checkpoint/memory.mjs +0 -0
- package/esm/checkpoint/memory.mjs.map +1 -0
- package/esm/checkpoint/pg.d.mts +37 -0
- package/esm/checkpoint/pg.d.mts.map +1 -0
- package/esm/checkpoint/pg.mjs +265 -0
- package/esm/checkpoint/pg.mjs.map +1 -0
- package/esm/checkpoint/redis.d.mts +39 -0
- package/esm/checkpoint/redis.d.mts.map +1 -0
- package/esm/checkpoint/redis.mjs +200 -0
- package/esm/checkpoint/redis.mjs.map +1 -0
- package/esm/config.d.mts +61 -14
- package/esm/config.d.mts.map +1 -1
- package/esm/config.mjs +25 -6
- package/esm/config.mjs.map +1 -1
- package/esm/contracts/agent/agent.contract.d.mts +43 -0
- package/esm/contracts/agent/agent.contract.d.mts.map +1 -1
- package/esm/contracts/agent/eval.type.d.mts +143 -0
- package/esm/contracts/agent/eval.type.d.mts.map +1 -0
- package/esm/contracts/agent/index.d.mts +1 -0
- package/esm/contracts/events/supervisor-events.type.d.mts +3 -3
- package/esm/contracts/fallback-model.contract.d.mts +65 -0
- package/esm/contracts/fallback-model.contract.d.mts.map +1 -0
- package/esm/contracts/index.d.mts +32 -12
- package/esm/contracts/memory/index.d.mts +4 -0
- package/esm/contracts/memory/memory-config.type.d.mts +150 -0
- package/esm/contracts/memory/memory-config.type.d.mts.map +1 -0
- package/esm/contracts/memory/memory-item.type.d.mts +64 -0
- package/esm/contracts/memory/memory-item.type.d.mts.map +1 -0
- package/esm/contracts/memory/memory.contract.d.mts +87 -0
- package/esm/contracts/memory/memory.contract.d.mts.map +1 -0
- package/esm/contracts/memory/recall-options.type.d.mts +33 -0
- package/esm/contracts/memory/recall-options.type.d.mts.map +1 -0
- package/esm/contracts/middleware/index.d.mts +2 -2
- package/esm/contracts/middleware/middleware-context.type.d.mts +42 -2
- package/esm/contracts/middleware/middleware-context.type.d.mts.map +1 -1
- package/esm/contracts/middleware/middleware.contract.d.mts +46 -2
- package/esm/contracts/middleware/middleware.contract.d.mts.map +1 -1
- package/esm/contracts/model.contract.d.mts +63 -2
- package/esm/contracts/model.contract.d.mts.map +1 -1
- package/esm/contracts/orchestrator/checkpoint-store.contract.d.mts +91 -0
- package/esm/contracts/orchestrator/checkpoint-store.contract.d.mts.map +1 -0
- package/esm/contracts/orchestrator/index.d.mts +8 -0
- package/esm/contracts/orchestrator/orchestrator-commands.type.d.mts +43 -0
- package/esm/contracts/orchestrator/orchestrator-commands.type.d.mts.map +1 -0
- package/esm/contracts/orchestrator/orchestrator-config.type.d.mts +170 -0
- package/esm/contracts/orchestrator/orchestrator-config.type.d.mts.map +1 -0
- package/esm/contracts/orchestrator/orchestrator-event.type.d.mts +118 -0
- package/esm/contracts/orchestrator/orchestrator-event.type.d.mts.map +1 -0
- package/esm/contracts/orchestrator/orchestrator-execute-options.type.d.mts +44 -0
- package/esm/contracts/orchestrator/orchestrator-execute-options.type.d.mts.map +1 -0
- package/esm/contracts/orchestrator/orchestrator.contract.d.mts +129 -0
- package/esm/contracts/orchestrator/orchestrator.contract.d.mts.map +1 -0
- package/esm/contracts/orchestrator/session.contract.d.mts +26 -0
- package/esm/contracts/orchestrator/session.contract.d.mts.map +1 -0
- package/esm/contracts/orchestrator/snapshot-store.contract.d.mts +89 -0
- package/esm/contracts/orchestrator/snapshot-store.contract.d.mts.map +1 -0
- package/esm/contracts/planner/index.d.mts +6 -0
- package/esm/contracts/planner/planner-capability.type.d.mts +39 -0
- package/esm/contracts/planner/planner-capability.type.d.mts.map +1 -0
- package/esm/contracts/planner/planner-config.type.d.mts +78 -0
- package/esm/contracts/planner/planner-config.type.d.mts.map +1 -0
- package/esm/contracts/planner/planner-execute-options.type.d.mts +43 -0
- package/esm/contracts/planner/planner-execute-options.type.d.mts.map +1 -0
- package/esm/contracts/planner/planner-plan.type.d.mts +48 -0
- package/esm/contracts/planner/planner-plan.type.d.mts.map +1 -0
- package/esm/contracts/planner/planner-result.type.d.mts +82 -0
- package/esm/contracts/planner/planner-result.type.d.mts.map +1 -0
- package/esm/contracts/planner/planner.contract.d.mts +60 -0
- package/esm/contracts/planner/planner.contract.d.mts.map +1 -0
- package/esm/contracts/result/base-report.type.d.mts +7 -2
- package/esm/contracts/result/base-report.type.d.mts.map +1 -1
- package/esm/contracts/result/base-report.type.mjs.map +1 -1
- package/esm/contracts/result/index.d.mts +2 -1
- package/esm/contracts/result/model-pricing.type.d.mts +10 -0
- package/esm/contracts/result/model-pricing.type.d.mts.map +1 -1
- package/esm/contracts/result/orchestrator-result.type.d.mts +139 -0
- package/esm/contracts/result/orchestrator-result.type.d.mts.map +1 -0
- package/esm/contracts/result/session-send-result.type.d.mts +12 -3
- package/esm/contracts/result/session-send-result.type.d.mts.map +1 -1
- package/esm/contracts/result/supervisor-result.type.d.mts +1 -1
- package/esm/contracts/result/usage.type.d.mts +24 -0
- package/esm/contracts/result/usage.type.d.mts.map +1 -1
- package/esm/contracts/sdk-adapter.contract.d.mts +1 -1
- package/esm/contracts/supervisor/dispatch-context.type.d.mts +3 -3
- package/esm/contracts/supervisor/evaluate-context.type.d.mts +1 -1
- package/esm/contracts/supervisor/index.d.mts +5 -5
- package/esm/contracts/supervisor/route-context.type.d.mts +2 -2
- package/esm/contracts/supervisor/supervisor-config.type.d.mts +55 -13
- package/esm/contracts/supervisor/supervisor-config.type.d.mts.map +1 -1
- package/esm/contracts/supervisor/supervisor-snapshot.type.d.mts +1 -1
- package/esm/contracts/supervisor/supervisor.contract.d.mts +9 -2
- package/esm/contracts/supervisor/supervisor.contract.d.mts.map +1 -1
- package/esm/contracts/workflow/index.d.mts +2 -2
- package/esm/contracts/workflow/workflow.contract.d.mts +28 -7
- package/esm/contracts/workflow/workflow.contract.d.mts.map +1 -1
- package/esm/errors/error-code.type.d.mts +1 -1
- package/esm/errors/index.d.mts +7 -0
- package/esm/errors/index.mjs +7 -0
- package/esm/errors/orchestrator-cancelled-error.d.mts +32 -0
- package/esm/errors/orchestrator-cancelled-error.d.mts.map +1 -0
- package/esm/errors/orchestrator-cancelled-error.mjs +31 -0
- package/esm/errors/orchestrator-cancelled-error.mjs.map +1 -0
- package/esm/errors/orchestrator-config-error.d.mts +26 -0
- package/esm/errors/orchestrator-config-error.d.mts.map +1 -0
- package/esm/errors/orchestrator-config-error.mjs +30 -0
- package/esm/errors/orchestrator-config-error.mjs.map +1 -0
- package/esm/errors/orchestrator-drift-error.d.mts +38 -0
- package/esm/errors/orchestrator-drift-error.d.mts.map +1 -0
- package/esm/errors/orchestrator-drift-error.mjs +37 -0
- package/esm/errors/orchestrator-drift-error.mjs.map +1 -0
- package/esm/errors/orchestrator-failed-error.d.mts +33 -0
- package/esm/errors/orchestrator-failed-error.d.mts.map +1 -0
- package/esm/errors/orchestrator-failed-error.mjs +36 -0
- package/esm/errors/orchestrator-failed-error.mjs.map +1 -0
- package/esm/errors/planner-cancelled-error.d.mts +33 -0
- package/esm/errors/planner-cancelled-error.d.mts.map +1 -0
- package/esm/errors/planner-cancelled-error.mjs +29 -0
- package/esm/errors/planner-cancelled-error.mjs.map +1 -0
- package/esm/errors/planner-failed-error.d.mts +40 -0
- package/esm/errors/planner-failed-error.d.mts.map +1 -0
- package/esm/errors/planner-failed-error.mjs +37 -0
- package/esm/errors/planner-failed-error.mjs.map +1 -0
- package/esm/errors/planner-plan-invalid-error.d.mts +21 -0
- package/esm/errors/planner-plan-invalid-error.d.mts.map +1 -0
- package/esm/errors/planner-plan-invalid-error.mjs +25 -0
- package/esm/errors/planner-plan-invalid-error.mjs.map +1 -0
- package/esm/eval/eval-runner.d.mts +17 -0
- package/esm/eval/eval-runner.d.mts.map +1 -0
- package/esm/eval/eval-runner.mjs +121 -0
- package/esm/eval/eval-runner.mjs.map +1 -0
- package/esm/eval/index.d.mts +29 -0
- package/esm/eval/index.d.mts.map +1 -0
- package/esm/eval/index.mjs +30 -0
- package/esm/eval/index.mjs.map +1 -0
- package/esm/eval/judge-scorer.d.mts +21 -0
- package/esm/eval/judge-scorer.d.mts.map +1 -0
- package/esm/eval/judge-scorer.mjs +87 -0
- package/esm/eval/judge-scorer.mjs.map +1 -0
- package/esm/eval/scorers.d.mts +50 -0
- package/esm/eval/scorers.d.mts.map +1 -0
- package/esm/eval/scorers.mjs +101 -0
- package/esm/eval/scorers.mjs.map +1 -0
- package/esm/index.d.mts +95 -30
- package/esm/index.mjs +66 -22
- package/esm/memory/derive-id.mjs +24 -0
- package/esm/memory/derive-id.mjs.map +1 -0
- package/esm/memory/episodic-memory.mjs +106 -0
- package/esm/memory/episodic-memory.mjs.map +1 -0
- package/esm/memory/index.d.mts +5 -0
- package/esm/memory/memory.d.mts +42 -0
- package/esm/memory/memory.d.mts.map +1 -0
- package/esm/memory/memory.mjs +166 -0
- package/esm/memory/memory.mjs.map +1 -0
- package/esm/memory/procedural-memory.mjs +103 -0
- package/esm/memory/procedural-memory.mjs.map +1 -0
- package/esm/memory/semantic-memory.mjs +80 -0
- package/esm/memory/semantic-memory.mjs.map +1 -0
- package/esm/memory/working-memory.mjs +62 -0
- package/esm/memory/working-memory.mjs.map +1 -0
- package/esm/middleware/builtins/budget-contract.type.d.mts +126 -0
- package/esm/middleware/builtins/budget-contract.type.d.mts.map +1 -0
- package/esm/middleware/builtins/budget.d.mts +71 -1
- package/esm/middleware/builtins/budget.d.mts.map +1 -1
- package/esm/middleware/builtins/budget.mjs +119 -4
- package/esm/middleware/builtins/budget.mjs.map +1 -1
- package/esm/middleware/builtins/semantic-cache.d.mts +1 -1
- package/esm/middleware/index.d.mts +2 -1
- package/esm/middleware/index.mjs +1 -1
- package/esm/middleware/pipeline.d.mts +9 -6
- package/esm/middleware/pipeline.d.mts.map +1 -1
- package/esm/middleware/pipeline.mjs.map +1 -1
- package/esm/mock/index.d.mts +1 -0
- package/esm/mock/index.mjs +1 -0
- package/esm/mock/mock-router.d.mts +63 -0
- package/esm/mock/mock-router.d.mts.map +1 -0
- package/esm/mock/mock-router.mjs +58 -0
- package/esm/mock/mock-router.mjs.map +1 -0
- package/esm/model/fallback-model.d.mts +45 -0
- package/esm/model/fallback-model.d.mts.map +1 -0
- package/esm/model/fallback-model.mjs +218 -0
- package/esm/model/fallback-model.mjs.map +1 -0
- package/esm/model/index.d.mts +2 -0
- package/esm/model/index.mjs +3 -0
- package/esm/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs +78 -0
- package/esm/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs.map +1 -0
- package/esm/node_modules/@vitest/expect/dist/index.mjs +1473 -0
- package/esm/node_modules/@vitest/expect/dist/index.mjs.map +1 -0
- package/esm/node_modules/@vitest/pretty-format/dist/index.mjs +888 -0
- package/esm/node_modules/@vitest/pretty-format/dist/index.mjs.map +1 -0
- package/esm/node_modules/@vitest/runner/dist/chunk-artifact.mjs +1533 -0
- package/esm/node_modules/@vitest/runner/dist/chunk-artifact.mjs.map +1 -0
- package/esm/node_modules/@vitest/runner/dist/index.mjs +3 -0
- package/esm/node_modules/@vitest/runner/dist/utils.mjs +3 -0
- package/esm/node_modules/@vitest/snapshot/dist/index.mjs +922 -0
- package/esm/node_modules/@vitest/snapshot/dist/index.mjs.map +1 -0
- package/esm/node_modules/@vitest/spy/dist/index.mjs +386 -0
- package/esm/node_modules/@vitest/spy/dist/index.mjs.map +1 -0
- package/esm/node_modules/@vitest/utils/dist/chunk-pathe.M-eThtNZ.mjs +82 -0
- package/esm/node_modules/@vitest/utils/dist/chunk-pathe.M-eThtNZ.mjs.map +1 -0
- package/esm/node_modules/@vitest/utils/dist/diff.mjs +1357 -0
- package/esm/node_modules/@vitest/utils/dist/diff.mjs.map +1 -0
- package/esm/node_modules/@vitest/utils/dist/display.mjs +559 -0
- package/esm/node_modules/@vitest/utils/dist/display.mjs.map +1 -0
- package/esm/node_modules/@vitest/utils/dist/error.mjs +38 -0
- package/esm/node_modules/@vitest/utils/dist/error.mjs.map +1 -0
- package/esm/node_modules/@vitest/utils/dist/helpers.mjs +181 -0
- package/esm/node_modules/@vitest/utils/dist/helpers.mjs.map +1 -0
- package/esm/node_modules/@vitest/utils/dist/offset.mjs +27 -0
- package/esm/node_modules/@vitest/utils/dist/offset.mjs.map +1 -0
- package/esm/node_modules/@vitest/utils/dist/serialize.mjs +77 -0
- package/esm/node_modules/@vitest/utils/dist/serialize.mjs.map +1 -0
- package/esm/node_modules/@vitest/utils/dist/source-map.mjs +374 -0
- package/esm/node_modules/@vitest/utils/dist/source-map.mjs.map +1 -0
- package/esm/node_modules/@vitest/utils/dist/timers.mjs +37 -0
- package/esm/node_modules/@vitest/utils/dist/timers.mjs.map +1 -0
- package/esm/node_modules/chai/index.mjs +2973 -0
- package/esm/node_modules/chai/index.mjs.map +1 -0
- package/esm/node_modules/magic-string/dist/magic-string.es.mjs +940 -0
- package/esm/node_modules/magic-string/dist/magic-string.es.mjs.map +1 -0
- package/esm/node_modules/tinyrainbow/dist/index.mjs +87 -0
- package/esm/node_modules/tinyrainbow/dist/index.mjs.map +1 -0
- package/esm/node_modules/vitest/dist/chunks/_commonjsHelpers.D26ty3Ew.mjs +6 -0
- package/esm/node_modules/vitest/dist/chunks/_commonjsHelpers.D26ty3Ew.mjs.map +1 -0
- package/esm/node_modules/vitest/dist/chunks/rpc.MzXet3jl.mjs +52 -0
- package/esm/node_modules/vitest/dist/chunks/rpc.MzXet3jl.mjs.map +1 -0
- package/esm/node_modules/vitest/dist/chunks/test.DNmyFkvJ.mjs +2697 -0
- package/esm/node_modules/vitest/dist/chunks/test.DNmyFkvJ.mjs.map +1 -0
- package/esm/node_modules/vitest/dist/chunks/utils.BX5Fg8C4.mjs +45 -0
- package/esm/node_modules/vitest/dist/chunks/utils.BX5Fg8C4.mjs.map +1 -0
- package/esm/orchestrator/as-tool.d.mts +42 -0
- package/esm/orchestrator/as-tool.d.mts.map +1 -0
- package/esm/orchestrator/as-tool.mjs +98 -0
- package/esm/orchestrator/as-tool.mjs.map +1 -0
- package/esm/orchestrator/checkpoint.mjs +75 -0
- package/esm/orchestrator/checkpoint.mjs.map +1 -0
- package/esm/orchestrator/commands.d.mts +38 -0
- package/esm/orchestrator/commands.d.mts.map +1 -0
- package/esm/orchestrator/commands.mjs +34 -0
- package/esm/orchestrator/commands.mjs.map +1 -0
- package/esm/orchestrator/compaction.mjs +206 -0
- package/esm/orchestrator/compaction.mjs.map +1 -0
- package/esm/orchestrator/dispatch.mjs +171 -0
- package/esm/orchestrator/dispatch.mjs.map +1 -0
- package/esm/orchestrator/emitter-port.type.d.mts +31 -0
- package/esm/orchestrator/emitter-port.type.d.mts.map +1 -0
- package/esm/orchestrator/emitter.d.mts +56 -0
- package/esm/orchestrator/emitter.d.mts.map +1 -0
- package/esm/orchestrator/emitter.mjs +85 -0
- package/esm/orchestrator/emitter.mjs.map +1 -0
- package/esm/orchestrator/engine-context.type.d.mts +56 -0
- package/esm/orchestrator/engine-context.type.d.mts.map +1 -0
- package/esm/orchestrator/execution.d.mts +116 -0
- package/esm/orchestrator/execution.d.mts.map +1 -0
- package/esm/orchestrator/execution.mjs +406 -0
- package/esm/orchestrator/execution.mjs.map +1 -0
- package/esm/orchestrator/index.d.mts +8 -0
- package/esm/orchestrator/index.mjs +10 -0
- package/esm/orchestrator/load.mjs +49 -0
- package/esm/orchestrator/load.mjs.map +1 -0
- package/esm/orchestrator/lock.mjs +75 -0
- package/esm/orchestrator/lock.mjs.map +1 -0
- package/esm/orchestrator/memory.d.mts +84 -0
- package/esm/orchestrator/memory.d.mts.map +1 -0
- package/esm/orchestrator/memory.mjs +141 -0
- package/esm/orchestrator/memory.mjs.map +1 -0
- package/esm/orchestrator/orchestrator-stream.d.mts +42 -0
- package/esm/orchestrator/orchestrator-stream.d.mts.map +1 -0
- package/esm/orchestrator/orchestrator-stream.mjs +98 -0
- package/esm/orchestrator/orchestrator-stream.mjs.map +1 -0
- package/esm/orchestrator/orchestrator.d.mts +38 -0
- package/esm/orchestrator/orchestrator.d.mts.map +1 -0
- package/esm/orchestrator/orchestrator.mjs +173 -0
- package/esm/orchestrator/orchestrator.mjs.map +1 -0
- package/esm/orchestrator/resume.mjs +74 -0
- package/esm/orchestrator/resume.mjs.map +1 -0
- package/esm/orchestrator/signature.d.mts +40 -0
- package/esm/orchestrator/signature.d.mts.map +1 -0
- package/esm/orchestrator/signature.mjs +120 -0
- package/esm/orchestrator/signature.mjs.map +1 -0
- package/esm/orchestrator/window.mjs +56 -0
- package/esm/orchestrator/window.mjs.map +1 -0
- package/esm/planner/index.d.mts +5 -0
- package/esm/planner/index.mjs +6 -0
- package/esm/planner/plan-prompt.d.mts +17 -0
- package/esm/planner/plan-prompt.d.mts.map +1 -0
- package/esm/planner/plan-prompt.mjs +30 -0
- package/esm/planner/plan-prompt.mjs.map +1 -0
- package/esm/planner/plan-schema.d.mts +27 -0
- package/esm/planner/plan-schema.d.mts.map +1 -0
- package/esm/planner/plan-schema.mjs +117 -0
- package/esm/planner/plan-schema.mjs.map +1 -0
- package/esm/planner/planner-run.d.mts +23 -0
- package/esm/planner/planner-run.d.mts.map +1 -0
- package/esm/planner/planner-run.mjs +344 -0
- package/esm/planner/planner-run.mjs.map +1 -0
- package/esm/planner/planner.d.mts +37 -0
- package/esm/planner/planner.d.mts.map +1 -0
- package/esm/planner/planner.mjs +120 -0
- package/esm/planner/planner.mjs.map +1 -0
- package/esm/planner/signature.d.mts +18 -0
- package/esm/planner/signature.d.mts.map +1 -0
- package/esm/planner/signature.mjs +27 -0
- package/esm/planner/signature.mjs.map +1 -0
- package/esm/snapshot/index.d.mts +3 -0
- package/esm/snapshot/memory.d.mts +26 -0
- package/esm/snapshot/memory.d.mts.map +1 -0
- package/esm/snapshot/memory.mjs +81 -0
- package/esm/snapshot/memory.mjs.map +1 -0
- package/esm/snapshot/pg.d.mts +41 -0
- package/esm/snapshot/pg.d.mts.map +1 -0
- package/esm/snapshot/pg.mjs +146 -0
- package/esm/snapshot/pg.mjs.map +1 -0
- package/esm/snapshot/redis.d.mts +42 -0
- package/esm/snapshot/redis.d.mts.map +1 -0
- package/esm/snapshot/redis.mjs +101 -0
- package/esm/snapshot/redis.mjs.map +1 -0
- package/esm/supervisor/as-tool.d.mts +0 -6
- package/esm/supervisor/as-tool.d.mts.map +1 -1
- package/esm/supervisor/as-tool.mjs +0 -6
- package/esm/supervisor/as-tool.mjs.map +1 -1
- package/esm/supervisor/execution.d.mts +43 -8
- package/esm/supervisor/execution.d.mts.map +1 -1
- package/esm/supervisor/execution.mjs +66 -16
- package/esm/supervisor/execution.mjs.map +1 -1
- package/esm/supervisor/fan-out.d.mts +65 -0
- package/esm/supervisor/fan-out.d.mts.map +1 -0
- package/esm/supervisor/fan-out.mjs +65 -0
- package/esm/supervisor/fan-out.mjs.map +1 -0
- package/esm/supervisor/index.d.mts +5 -3
- package/esm/supervisor/index.mjs +3 -1
- package/esm/supervisor/router-factory.d.mts +110 -0
- package/esm/supervisor/router-factory.d.mts.map +1 -0
- package/esm/supervisor/router-factory.mjs +141 -0
- package/esm/supervisor/router-factory.mjs.map +1 -0
- package/esm/supervisor/router-prompt.d.mts +1 -1
- package/esm/supervisor/snapshot.d.mts +4 -10
- package/esm/supervisor/snapshot.d.mts.map +1 -1
- package/esm/supervisor/snapshot.mjs +8 -16
- package/esm/supervisor/snapshot.mjs.map +1 -1
- package/esm/supervisor/supervisor.mjs +1 -0
- package/esm/supervisor/supervisor.mjs.map +1 -1
- package/esm/system-prompt/index.mjs +6 -0
- package/esm/system-prompt/system-prompt.d.mts +51 -3
- package/esm/system-prompt/system-prompt.d.mts.map +1 -1
- package/esm/system-prompt/system-prompt.mjs +52 -6
- package/esm/system-prompt/system-prompt.mjs.map +1 -1
- package/esm/testing/matcher-logic.d.mts +76 -0
- package/esm/testing/matcher-logic.d.mts.map +1 -0
- package/esm/testing/matcher-logic.mjs +144 -0
- package/esm/testing/matcher-logic.mjs.map +1 -0
- package/esm/testing/matchers.d.mts +48 -0
- package/esm/testing/matchers.d.mts.map +1 -0
- package/esm/testing/matchers.mjs +37 -0
- package/esm/testing/matchers.mjs.map +1 -0
- package/esm/testing/register-lazy.d.mts +20 -0
- package/esm/testing/register-lazy.d.mts.map +1 -0
- package/esm/testing/register-lazy.mjs +24 -0
- package/esm/testing/register-lazy.mjs.map +1 -0
- package/esm/tool/executable-as-tool.d.mts +87 -0
- package/esm/tool/executable-as-tool.d.mts.map +1 -0
- package/esm/tool/executable-as-tool.mjs +81 -0
- package/esm/tool/executable-as-tool.mjs.map +1 -0
- package/esm/tool/index.d.mts +2 -1
- package/esm/tool/index.mjs +1 -0
- package/esm/workflow/as-tool.mjs +0 -6
- package/esm/workflow/as-tool.mjs.map +1 -1
- package/esm/workflow/engine.mjs +2 -2
- package/esm/workflow/snapshot.mjs +13 -7
- package/esm/workflow/snapshot.mjs.map +1 -1
- package/esm/workflow/step-runner.mjs +1 -1
- package/esm/workflow/workflow.mjs +1 -0
- package/esm/workflow/workflow.mjs.map +1 -1
- package/llms-full.txt +947 -42
- package/llms.txt +13 -8
- package/package.json +3 -3
- package/skills/README.md +25 -5
- package/skills/ai-basics/SKILL.md +18 -7
- package/skills/ai-dx-helpers/SKILL.md +180 -0
- package/skills/attach-ai-middleware/SKILL.md +32 -3
- package/skills/handle-ai-errors/SKILL.md +20 -6
- package/skills/manage-ai-stores/SKILL.md +127 -0
- package/skills/persist-ai-data/SKILL.md +21 -10
- package/skills/pick-ai-provider/SKILL.md +46 -12
- package/skills/run-ai-agent/SKILL.md +51 -2
- package/skills/run-orchestrator/SKILL.md +198 -0
- package/skills/run-planner/SKILL.md +68 -0
- package/skills/run-supervisor/SKILL.md +47 -2
- package/skills/use-ai-memory/SKILL.md +124 -0
- package/skills/write-system-prompt/SKILL.md +14 -1
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ErrorCategory } from "./error-category.type.mjs";
|
|
2
|
+
import { AIErrorOptions } from "./ai-error.mjs";
|
|
3
|
+
import { PlannerFailedError } from "./planner-failed-error.mjs";
|
|
4
|
+
|
|
5
|
+
//#region ../@warlock.js/ai/src/errors/planner-plan-invalid-error.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* The planner asked the LLM for an execution plan but the response
|
|
8
|
+
* could not be parsed / validated into a usable {@link PlannerPlan},
|
|
9
|
+
* or it referenced a capability that was never registered.
|
|
10
|
+
*
|
|
11
|
+
* Surfaced on `result.error` with `report.status === "failed"` — the
|
|
12
|
+
* planner returns normally rather than throwing, so callers branch on
|
|
13
|
+
* the typed envelope like every other primitive.
|
|
14
|
+
*/
|
|
15
|
+
declare class PlannerPlanInvalidError extends PlannerFailedError {
|
|
16
|
+
static readonly defaultCategory: ErrorCategory;
|
|
17
|
+
constructor(message: string, options?: AIErrorOptions);
|
|
18
|
+
}
|
|
19
|
+
//#endregion
|
|
20
|
+
export { PlannerPlanInvalidError };
|
|
21
|
+
//# sourceMappingURL=planner-plan-invalid-error.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"planner-plan-invalid-error.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai/src/errors/planner-plan-invalid-error.ts"],"mappings":";;;;;;;AAaA;;;;;;;cAAa,uBAAA,SAAgC,kBAAA;EAAA,gBACpB,eAAA,EAAiB,aAAA;cAErB,OAAA,UAAiB,OAAA,GAAU,cAAA;AAAA"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { PlannerFailedError } from "./planner-failed-error.mjs";
|
|
2
|
+
|
|
3
|
+
//#region ../@warlock.js/ai/src/errors/planner-plan-invalid-error.ts
|
|
4
|
+
/**
|
|
5
|
+
* The planner asked the LLM for an execution plan but the response
|
|
6
|
+
* could not be parsed / validated into a usable {@link PlannerPlan},
|
|
7
|
+
* or it referenced a capability that was never registered.
|
|
8
|
+
*
|
|
9
|
+
* Surfaced on `result.error` with `report.status === "failed"` — the
|
|
10
|
+
* planner returns normally rather than throwing, so callers branch on
|
|
11
|
+
* the typed envelope like every other primitive.
|
|
12
|
+
*/
|
|
13
|
+
var PlannerPlanInvalidError = class extends PlannerFailedError {
|
|
14
|
+
static {
|
|
15
|
+
this.defaultCategory = "schema";
|
|
16
|
+
}
|
|
17
|
+
constructor(message, options) {
|
|
18
|
+
super(message, options, "PLANNER_PLAN_INVALID");
|
|
19
|
+
this.name = "PlannerPlanInvalidError";
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
//#endregion
|
|
24
|
+
export { PlannerPlanInvalidError };
|
|
25
|
+
//# sourceMappingURL=planner-plan-invalid-error.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"planner-plan-invalid-error.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/errors/planner-plan-invalid-error.ts"],"sourcesContent":["import type { AIErrorOptions } from \"./ai-error\";\nimport type { ErrorCategory } from \"./error-category.type\";\nimport { PlannerFailedError } from \"./planner-failed-error\";\n\n/**\n * The planner asked the LLM for an execution plan but the response\n * could not be parsed / validated into a usable {@link PlannerPlan},\n * or it referenced a capability that was never registered.\n *\n * Surfaced on `result.error` with `report.status === \"failed\"` — the\n * planner returns normally rather than throwing, so callers branch on\n * the typed envelope like every other primitive.\n */\nexport class PlannerPlanInvalidError extends PlannerFailedError {\n public static readonly defaultCategory: ErrorCategory = \"schema\";\n\n public constructor(message: string, options?: AIErrorOptions) {\n super(message, options, \"PLANNER_PLAN_INVALID\");\n this.name = \"PlannerPlanInvalidError\";\n }\n}\n"],"mappings":";;;;;;;;;;;;AAaA,IAAa,0BAAb,cAA6C,mBAAmB;;yBACN;;CAExD,AAAO,YAAY,SAAiB,SAA0B;EAC5D,MAAM,SAAS,SAAS,sBAAsB;EAC9C,KAAK,OAAO;CACd;AACF"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { EvalOptions, EvalReport } from "../contracts/agent/eval.type.mjs";
|
|
2
|
+
import { AgentContract } from "../contracts/agent/agent.contract.mjs";
|
|
3
|
+
|
|
4
|
+
//#region ../@warlock.js/ai/src/eval/eval-runner.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Core implementation of `agent.eval`. Runs every case sequentially
|
|
7
|
+
* (cases share the agent and may carry side effects — ordering must be
|
|
8
|
+
* deterministic), scores each, fires `onFailure` for failed cases, and
|
|
9
|
+
* assembles the aggregate {@link EvalReport}.
|
|
10
|
+
*
|
|
11
|
+
* Never throws on a case-level failure; the only throw is the
|
|
12
|
+
* authoring-time "no scorer" guard from {@link resolveScorers}.
|
|
13
|
+
*/
|
|
14
|
+
declare function runEval<TOutput>(agent: AgentContract<TOutput>, options: EvalOptions<TOutput>): Promise<EvalReport<TOutput>>;
|
|
15
|
+
//#endregion
|
|
16
|
+
export { runEval };
|
|
17
|
+
//# sourceMappingURL=eval-runner.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eval-runner.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai/src/eval/eval-runner.ts"],"mappings":";;;;;;AAmIA;;;;;;;iBAAsB,OAAA,UACpB,KAAA,EAAO,aAAA,CAAc,OAAA,GACrB,OAAA,EAAS,WAAA,CAAY,OAAA,IACpB,OAAA,CAAQ,UAAA,CAAW,OAAA"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { AgentExecutionError } from "../errors/agent-execution-error.mjs";
|
|
2
|
+
import "../errors/index.mjs";
|
|
3
|
+
import { judge } from "./judge-scorer.mjs";
|
|
4
|
+
import { log } from "@warlock.js/logger";
|
|
5
|
+
|
|
6
|
+
//#region ../@warlock.js/ai/src/eval/eval-runner.ts
|
|
7
|
+
const LOG_MODULE = "ai.eval";
|
|
8
|
+
const DEFAULT_PASS_THRESHOLD = .5;
|
|
9
|
+
/**
|
|
10
|
+
* Resolve the scorer list for a single case. Precedence: the case's
|
|
11
|
+
* own `scorers` → the suite `scorers` → a synthesized judge scorer
|
|
12
|
+
* when `judge` is configured. Throws an authoring-time
|
|
13
|
+
* `AgentExecutionError` when a case can resolve none — an eval suite
|
|
14
|
+
* with no way to score a case is a config bug worth surfacing at the
|
|
15
|
+
* call site, not a silent pass.
|
|
16
|
+
*/
|
|
17
|
+
function resolveScorers(evalCase, options, passThreshold) {
|
|
18
|
+
if (evalCase.scorers && evalCase.scorers.length > 0) return evalCase.scorers;
|
|
19
|
+
if (options.scorers && options.scorers.length > 0) return options.scorers;
|
|
20
|
+
if (options.judge) return [judge(options.judge, passThreshold)];
|
|
21
|
+
throw new AgentExecutionError(`eval case "${evalCase.name}" has no scorer — supply per-case "scorers", suite "scorers", or a "judge"`, { context: {
|
|
22
|
+
authoring: true,
|
|
23
|
+
case: evalCase.name
|
|
24
|
+
} });
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Decide a single scorer verdict's pass/fail. Honors an explicit
|
|
28
|
+
* `passed` from the scorer; otherwise derives it from
|
|
29
|
+
* `score >= passThreshold`.
|
|
30
|
+
*/
|
|
31
|
+
function isScorePassing(score, passThreshold) {
|
|
32
|
+
if (typeof score.passed === "boolean") return score.passed;
|
|
33
|
+
return score.score >= passThreshold;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Merge suite-level execute options with the case's own override.
|
|
37
|
+
* Per-case wins on conflict (shallow merge).
|
|
38
|
+
*/
|
|
39
|
+
function mergeOptions(suite, perCase) {
|
|
40
|
+
if (!suite) return perCase;
|
|
41
|
+
if (!perCase) return suite;
|
|
42
|
+
return {
|
|
43
|
+
...suite,
|
|
44
|
+
...perCase
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Run one case end-to-end: execute the agent, run every resolved
|
|
49
|
+
* scorer, aggregate into an {@link EvalCaseResult}. A case passes only
|
|
50
|
+
* when the agent did not error AND every scorer passed.
|
|
51
|
+
*/
|
|
52
|
+
async function runCase(agent, evalCase, options, passThreshold) {
|
|
53
|
+
const scorers = resolveScorers(evalCase, options, passThreshold);
|
|
54
|
+
const executeOptions = mergeOptions(options.executeOptions, evalCase.options);
|
|
55
|
+
const start = performance.now();
|
|
56
|
+
const result = await agent.execute(evalCase.input, executeOptions);
|
|
57
|
+
const duration = performance.now() - start;
|
|
58
|
+
const context = {
|
|
59
|
+
case: evalCase,
|
|
60
|
+
result,
|
|
61
|
+
output: result.data,
|
|
62
|
+
text: result.text
|
|
63
|
+
};
|
|
64
|
+
const scores = [];
|
|
65
|
+
for (const scorer of scorers) scores.push(await scorer(context));
|
|
66
|
+
const meanScore = scores.length > 0 ? scores.reduce((sum, score) => sum + score.score, 0) / scores.length : 0;
|
|
67
|
+
const allScorersPassed = scores.every((score) => isScorePassing(score, passThreshold));
|
|
68
|
+
return {
|
|
69
|
+
case: evalCase,
|
|
70
|
+
result,
|
|
71
|
+
scores,
|
|
72
|
+
score: meanScore,
|
|
73
|
+
passed: result.error === void 0 && allScorersPassed,
|
|
74
|
+
duration
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Core implementation of `agent.eval`. Runs every case sequentially
|
|
79
|
+
* (cases share the agent and may carry side effects — ordering must be
|
|
80
|
+
* deterministic), scores each, fires `onFailure` for failed cases, and
|
|
81
|
+
* assembles the aggregate {@link EvalReport}.
|
|
82
|
+
*
|
|
83
|
+
* Never throws on a case-level failure; the only throw is the
|
|
84
|
+
* authoring-time "no scorer" guard from {@link resolveScorers}.
|
|
85
|
+
*/
|
|
86
|
+
async function runEval(agent, options) {
|
|
87
|
+
const passThreshold = options.passThreshold ?? DEFAULT_PASS_THRESHOLD;
|
|
88
|
+
const start = performance.now();
|
|
89
|
+
const cases = [];
|
|
90
|
+
for (const evalCase of options.cases) {
|
|
91
|
+
const caseResult = await runCase(agent, evalCase, options, passThreshold);
|
|
92
|
+
cases.push(caseResult);
|
|
93
|
+
if (!caseResult.passed && options.onFailure) try {
|
|
94
|
+
await options.onFailure(caseResult);
|
|
95
|
+
} catch (error) {
|
|
96
|
+
log.warn(LOG_MODULE, "onFailure.hook.error", "eval onFailure handler threw", {
|
|
97
|
+
agent: agent.name,
|
|
98
|
+
case: evalCase.name,
|
|
99
|
+
error: error instanceof Error ? error.message : String(error)
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
const passedCount = cases.filter((entry) => entry.passed).length;
|
|
104
|
+
const total = cases.length;
|
|
105
|
+
const meanScore = total > 0 ? cases.reduce((sum, entry) => sum + entry.score, 0) / total : 0;
|
|
106
|
+
return {
|
|
107
|
+
agentName: agent.name,
|
|
108
|
+
total,
|
|
109
|
+
passedCount,
|
|
110
|
+
failedCount: total - passedCount,
|
|
111
|
+
passRate: total > 0 ? passedCount / total : 0,
|
|
112
|
+
meanScore,
|
|
113
|
+
passed: total > 0 && passedCount === total,
|
|
114
|
+
cases,
|
|
115
|
+
duration: performance.now() - start
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
//#endregion
|
|
120
|
+
export { runEval };
|
|
121
|
+
//# sourceMappingURL=eval-runner.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eval-runner.mjs","names":["judgeScorer"],"sources":["../../../../../../../@warlock.js/ai/src/eval/eval-runner.ts"],"sourcesContent":["import type { AgentContract } from \"../contracts/agent/agent.contract\";\nimport type { AgentExecuteOptions } from \"../contracts/agent/agent-options.type\";\nimport type {\n EvalCase,\n EvalCaseResult,\n EvalOptions,\n EvalReport,\n EvalScore,\n EvalScorer,\n EvalScorerContext,\n} from \"../contracts/agent/eval.type\";\nimport { AgentExecutionError } from \"../errors\";\nimport { log } from \"@warlock.js/logger\";\nimport { judge as judgeScorer } from \"./judge-scorer\";\n\nconst LOG_MODULE = \"ai.eval\";\nconst DEFAULT_PASS_THRESHOLD = 0.5;\n\n/**\n * Resolve the scorer list for a single case. Precedence: the case's\n * own `scorers` → the suite `scorers` → a synthesized judge scorer\n * when `judge` is configured. Throws an authoring-time\n * `AgentExecutionError` when a case can resolve none — an eval suite\n * with no way to score a case is a config bug worth surfacing at the\n * call site, not a silent pass.\n */\nfunction resolveScorers<TOutput>(\n evalCase: EvalCase<TOutput>,\n options: EvalOptions<TOutput>,\n passThreshold: number,\n): EvalScorer<TOutput>[] {\n if (evalCase.scorers && evalCase.scorers.length > 0) {\n return evalCase.scorers;\n }\n\n if (options.scorers && options.scorers.length > 0) {\n return options.scorers;\n }\n\n if (options.judge) {\n return [judgeScorer<TOutput>(options.judge, passThreshold)];\n }\n\n throw new AgentExecutionError(\n `eval case \"${evalCase.name}\" has no scorer — supply per-case \"scorers\", suite \"scorers\", or a \"judge\"`,\n { context: { authoring: true, case: evalCase.name } },\n );\n}\n\n/**\n * Decide a single scorer verdict's pass/fail. Honors an explicit\n * `passed` from the scorer; otherwise derives it from\n * `score >= passThreshold`.\n */\nfunction isScorePassing(score: EvalScore, passThreshold: number): boolean {\n if (typeof score.passed === \"boolean\") {\n return score.passed;\n }\n\n return score.score >= passThreshold;\n}\n\n/**\n * Merge suite-level execute options with the case's own override.\n * Per-case wins on conflict (shallow merge).\n */\nfunction mergeOptions<TOutput>(\n suite: AgentExecuteOptions<TOutput> | undefined,\n perCase: AgentExecuteOptions<TOutput> | undefined,\n): AgentExecuteOptions<TOutput> | undefined {\n if (!suite) return perCase;\n if (!perCase) return suite;\n return { ...suite, ...perCase };\n}\n\n/**\n * Run one case end-to-end: execute the agent, run every resolved\n * scorer, aggregate into an {@link EvalCaseResult}. A case passes only\n * when the agent did not error AND every scorer passed.\n */\nasync function runCase<TOutput>(\n agent: AgentContract<TOutput>,\n evalCase: EvalCase<TOutput>,\n options: EvalOptions<TOutput>,\n passThreshold: number,\n): Promise<EvalCaseResult<TOutput>> {\n const scorers = resolveScorers(evalCase, options, passThreshold);\n const executeOptions = mergeOptions(options.executeOptions, evalCase.options);\n\n const start = performance.now();\n const result = await agent.execute(evalCase.input, executeOptions);\n const duration = performance.now() - start;\n\n const context: EvalScorerContext<TOutput> = {\n case: evalCase,\n result,\n output: result.data,\n text: result.text,\n };\n\n const scores: EvalScore[] = [];\n\n for (const scorer of scorers) {\n scores.push(await scorer(context));\n }\n\n const meanScore =\n scores.length > 0 ? scores.reduce((sum, score) => sum + score.score, 0) / scores.length : 0;\n\n const allScorersPassed = scores.every((score) => isScorePassing(score, passThreshold));\n const passed = result.error === undefined && allScorersPassed;\n\n return {\n case: evalCase,\n result,\n scores,\n score: meanScore,\n passed,\n duration,\n };\n}\n\n/**\n * Core implementation of `agent.eval`. Runs every case sequentially\n * (cases share the agent and may carry side effects — ordering must be\n * deterministic), scores each, fires `onFailure` for failed cases, and\n * assembles the aggregate {@link EvalReport}.\n *\n * Never throws on a case-level failure; the only throw is the\n * authoring-time \"no scorer\" guard from {@link resolveScorers}.\n */\nexport async function runEval<TOutput>(\n agent: AgentContract<TOutput>,\n options: EvalOptions<TOutput>,\n): Promise<EvalReport<TOutput>> {\n const passThreshold = options.passThreshold ?? DEFAULT_PASS_THRESHOLD;\n const start = performance.now();\n\n const cases: EvalCaseResult<TOutput>[] = [];\n\n for (const evalCase of options.cases) {\n const caseResult = await runCase(agent, evalCase, options, passThreshold);\n\n cases.push(caseResult);\n\n if (!caseResult.passed && options.onFailure) {\n try {\n await options.onFailure(caseResult);\n } catch (error) {\n log.warn(LOG_MODULE, \"onFailure.hook.error\", \"eval onFailure handler threw\", {\n agent: agent.name,\n case: evalCase.name,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n }\n\n const passedCount = cases.filter((entry) => entry.passed).length;\n const total = cases.length;\n const meanScore =\n total > 0 ? cases.reduce((sum, entry) => sum + entry.score, 0) / total : 0;\n\n return {\n agentName: agent.name,\n total,\n passedCount,\n failedCount: total - passedCount,\n passRate: total > 0 ? passedCount / total : 0,\n meanScore,\n passed: total > 0 && passedCount === total,\n cases,\n duration: performance.now() - start,\n };\n}\n"],"mappings":";;;;;;AAeA,MAAM,aAAa;AACnB,MAAM,yBAAyB;;;;;;;;;AAU/B,SAAS,eACP,UACA,SACA,eACuB;CACvB,IAAI,SAAS,WAAW,SAAS,QAAQ,SAAS,GAChD,OAAO,SAAS;CAGlB,IAAI,QAAQ,WAAW,QAAQ,QAAQ,SAAS,GAC9C,OAAO,QAAQ;CAGjB,IAAI,QAAQ,OACV,OAAO,CAACA,MAAqB,QAAQ,OAAO,aAAa,CAAC;CAG5D,MAAM,IAAI,oBACR,cAAc,SAAS,KAAK,6EAC5B,EAAE,SAAS;EAAE,WAAW;EAAM,MAAM,SAAS;CAAK,EAAE,CACtD;AACF;;;;;;AAOA,SAAS,eAAe,OAAkB,eAAgC;CACxE,IAAI,OAAO,MAAM,WAAW,WAC1B,OAAO,MAAM;CAGf,OAAO,MAAM,SAAS;AACxB;;;;;AAMA,SAAS,aACP,OACA,SAC0C;CAC1C,IAAI,CAAC,OAAO,OAAO;CACnB,IAAI,CAAC,SAAS,OAAO;CACrB,OAAO;EAAE,GAAG;EAAO,GAAG;CAAQ;AAChC;;;;;;AAOA,eAAe,QACb,OACA,UACA,SACA,eACkC;CAClC,MAAM,UAAU,eAAe,UAAU,SAAS,aAAa;CAC/D,MAAM,iBAAiB,aAAa,QAAQ,gBAAgB,SAAS,OAAO;CAE5E,MAAM,QAAQ,YAAY,IAAI;CAC9B,MAAM,SAAS,MAAM,MAAM,QAAQ,SAAS,OAAO,cAAc;CACjE,MAAM,WAAW,YAAY,IAAI,IAAI;CAErC,MAAM,UAAsC;EAC1C,MAAM;EACN;EACA,QAAQ,OAAO;EACf,MAAM,OAAO;CACf;CAEA,MAAM,SAAsB,CAAC;CAE7B,KAAK,MAAM,UAAU,SACnB,OAAO,KAAK,MAAM,OAAO,OAAO,CAAC;CAGnC,MAAM,YACJ,OAAO,SAAS,IAAI,OAAO,QAAQ,KAAK,UAAU,MAAM,MAAM,OAAO,CAAC,IAAI,OAAO,SAAS;CAE5F,MAAM,mBAAmB,OAAO,OAAO,UAAU,eAAe,OAAO,aAAa,CAAC;CAGrF,OAAO;EACL,MAAM;EACN;EACA;EACA,OAAO;EACP,QAPa,OAAO,UAAU,UAAa;EAQ3C;CACF;AACF;;;;;;;;;;AAWA,eAAsB,QACpB,OACA,SAC8B;CAC9B,MAAM,gBAAgB,QAAQ,iBAAiB;CAC/C,MAAM,QAAQ,YAAY,IAAI;CAE9B,MAAM,QAAmC,CAAC;CAE1C,KAAK,MAAM,YAAY,QAAQ,OAAO;EACpC,MAAM,aAAa,MAAM,QAAQ,OAAO,UAAU,SAAS,aAAa;EAExE,MAAM,KAAK,UAAU;EAErB,IAAI,CAAC,WAAW,UAAU,QAAQ,WAChC,IAAI;GACF,MAAM,QAAQ,UAAU,UAAU;EACpC,SAAS,OAAO;GACd,IAAI,KAAK,YAAY,wBAAwB,gCAAgC;IAC3E,OAAO,MAAM;IACb,MAAM,SAAS;IACf,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;GAC9D,CAAC;EACH;CAEJ;CAEA,MAAM,cAAc,MAAM,QAAQ,UAAU,MAAM,MAAM,CAAC,CAAC;CAC1D,MAAM,QAAQ,MAAM;CACpB,MAAM,YACJ,QAAQ,IAAI,MAAM,QAAQ,KAAK,UAAU,MAAM,MAAM,OAAO,CAAC,IAAI,QAAQ;CAE3E,OAAO;EACL,WAAW,MAAM;EACjB;EACA;EACA,aAAa,QAAQ;EACrB,UAAU,QAAQ,IAAI,cAAc,QAAQ;EAC5C;EACA,QAAQ,QAAQ,KAAK,gBAAgB;EACrC;EACA,UAAU,YAAY,IAAI,IAAI;CAChC;AACF"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { judge } from "./judge-scorer.mjs";
|
|
2
|
+
import { EvalPredicate, contains, exact, predicate } from "./scorers.mjs";
|
|
3
|
+
import { runEval } from "./eval-runner.mjs";
|
|
4
|
+
|
|
5
|
+
//#region ../@warlock.js/ai/src/eval/index.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* Built-in eval scorer factories, surfaced on `ai.eval.*`.
|
|
8
|
+
*
|
|
9
|
+
* - `exact()` — pass when output equals the case `expected` (trimmed,
|
|
10
|
+
* case-insensitive; structured values compared by canonical JSON).
|
|
11
|
+
* - `contains()` — pass when `expected` appears as a substring.
|
|
12
|
+
* - `predicate(fn)` — wrap an arbitrary boolean assertion.
|
|
13
|
+
* - `judge(config)` — LLM-as-judge scoring against a rubric.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* await myAgent.eval({
|
|
17
|
+
* cases: [{ name: "q", input: "Capital of Egypt?", expected: "Cairo" }],
|
|
18
|
+
* scorers: [ai.eval.contains()],
|
|
19
|
+
* });
|
|
20
|
+
*/
|
|
21
|
+
declare const evalScorers: {
|
|
22
|
+
exact: typeof exact;
|
|
23
|
+
contains: typeof contains;
|
|
24
|
+
predicate: typeof predicate;
|
|
25
|
+
judge: typeof judge;
|
|
26
|
+
};
|
|
27
|
+
//#endregion
|
|
28
|
+
export { evalScorers };
|
|
29
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai/src/eval/index.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;cA0Ba,WAAA"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { judge } from "./judge-scorer.mjs";
|
|
2
|
+
import { runEval } from "./eval-runner.mjs";
|
|
3
|
+
import { contains, exact, predicate } from "./scorers.mjs";
|
|
4
|
+
|
|
5
|
+
//#region ../@warlock.js/ai/src/eval/index.ts
|
|
6
|
+
/**
|
|
7
|
+
* Built-in eval scorer factories, surfaced on `ai.eval.*`.
|
|
8
|
+
*
|
|
9
|
+
* - `exact()` — pass when output equals the case `expected` (trimmed,
|
|
10
|
+
* case-insensitive; structured values compared by canonical JSON).
|
|
11
|
+
* - `contains()` — pass when `expected` appears as a substring.
|
|
12
|
+
* - `predicate(fn)` — wrap an arbitrary boolean assertion.
|
|
13
|
+
* - `judge(config)` — LLM-as-judge scoring against a rubric.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* await myAgent.eval({
|
|
17
|
+
* cases: [{ name: "q", input: "Capital of Egypt?", expected: "Cairo" }],
|
|
18
|
+
* scorers: [ai.eval.contains()],
|
|
19
|
+
* });
|
|
20
|
+
*/
|
|
21
|
+
const evalScorers = {
|
|
22
|
+
exact,
|
|
23
|
+
contains,
|
|
24
|
+
predicate,
|
|
25
|
+
judge
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
//#endregion
|
|
29
|
+
export { evalScorers };
|
|
30
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/eval/index.ts"],"sourcesContent":["import { judge } from \"./judge-scorer\";\nimport { contains, exact, predicate } from \"./scorers\";\n\n// Runner — wired into AgentContract.eval() by the agent factory.\nexport { runEval } from \"./eval-runner\";\n\n// Scorer factories — re-exported individually for direct import.\nexport { contains, exact, predicate } from \"./scorers\";\nexport type { EvalPredicate } from \"./scorers\";\nexport { judge } from \"./judge-scorer\";\n\n/**\n * Built-in eval scorer factories, surfaced on `ai.eval.*`.\n *\n * - `exact()` — pass when output equals the case `expected` (trimmed,\n * case-insensitive; structured values compared by canonical JSON).\n * - `contains()` — pass when `expected` appears as a substring.\n * - `predicate(fn)` — wrap an arbitrary boolean assertion.\n * - `judge(config)` — LLM-as-judge scoring against a rubric.\n *\n * @example\n * await myAgent.eval({\n * cases: [{ name: \"q\", input: \"Capital of Egypt?\", expected: \"Cairo\" }],\n * scorers: [ai.eval.contains()],\n * });\n */\nexport const evalScorers = {\n exact,\n contains,\n predicate,\n judge,\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AA0BA,MAAa,cAAc;CACzB;CACA;CACA;CACA;AACF"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { EvalJudge, EvalScorer } from "../contracts/agent/eval.type.mjs";
|
|
2
|
+
|
|
3
|
+
//#region ../@warlock.js/ai/src/eval/judge-scorer.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* LLM-as-judge scorer. Runs the judge agent on a prompt built from the
|
|
6
|
+
* case (question + expected + actual answer + rubric) and parses its
|
|
7
|
+
* `{ score, passed?, reason? }` verdict.
|
|
8
|
+
*
|
|
9
|
+
* Verdict source order: `result.data` (when the judge declares an
|
|
10
|
+
* output schema), then `result.text` parsed as JSON. A judge that
|
|
11
|
+
* errors or returns unparseable text scores `0` with the failure
|
|
12
|
+
* reason attached — a broken judge fails the case rather than crashing
|
|
13
|
+
* the suite.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* scorers: [judge({ agent: judgeAgent, rubric: "Cite a source for full marks." })]
|
|
17
|
+
*/
|
|
18
|
+
declare function judge<TOutput = unknown>(config: EvalJudge, passThreshold?: number): EvalScorer<TOutput>;
|
|
19
|
+
//#endregion
|
|
20
|
+
export { judge };
|
|
21
|
+
//# sourceMappingURL=judge-scorer.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"judge-scorer.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai/src/eval/judge-scorer.ts"],"mappings":";;;;;AA4FA;;;;;;;;;;;;iBAAgB,KAAA,oBACd,MAAA,EAAQ,SAAA,EACR,aAAA,YACC,UAAA,CAAW,OAAA"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { extractJsonPayload } from "../utils/extract-json-payload.mjs";
|
|
2
|
+
import { safeJsonParse } from "../utils/safe-json-parse.mjs";
|
|
3
|
+
import "../utils/index.mjs";
|
|
4
|
+
|
|
5
|
+
//#region ../@warlock.js/ai/src/eval/judge-scorer.ts
|
|
6
|
+
/** Clamp an arbitrary numeric value into the `[0, 1]` score range. */
|
|
7
|
+
function clampScore(value) {
|
|
8
|
+
if (Number.isNaN(value)) return 0;
|
|
9
|
+
if (value < 0) return 0;
|
|
10
|
+
if (value > 1) return 1;
|
|
11
|
+
return value;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Render the prompt the judge agent receives for one case. Includes
|
|
15
|
+
* the rubric (if any), the original question, the expected reference
|
|
16
|
+
* (when supplied), and the actual answer — then asks for a strict JSON
|
|
17
|
+
* verdict so the response is machine-parseable even without an output
|
|
18
|
+
* schema.
|
|
19
|
+
*/
|
|
20
|
+
function buildJudgePrompt(context, judge) {
|
|
21
|
+
const lines = [];
|
|
22
|
+
if (judge.rubric) lines.push(`Grading rubric:\n${judge.rubric}`, "");
|
|
23
|
+
lines.push(`Question:\n${context.case.input}`, "");
|
|
24
|
+
if (context.case.expected !== void 0) {
|
|
25
|
+
const expectedText = typeof context.case.expected === "string" ? context.case.expected : JSON.stringify(context.case.expected);
|
|
26
|
+
lines.push(`Reference answer:\n${expectedText}`, "");
|
|
27
|
+
}
|
|
28
|
+
const actual = context.text ?? JSON.stringify(context.output ?? null);
|
|
29
|
+
lines.push(`Answer to grade:\n${actual}`, "");
|
|
30
|
+
lines.push("Respond with JSON only: { \"score\": <0..1>, \"passed\": <true|false>, \"reason\": \"<short explanation>\" }.");
|
|
31
|
+
return lines.join("\n");
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Coerce the judge agent's parsed/extracted verdict into a normalized
|
|
35
|
+
* {@link EvalScore}. Defends against a judge that returns a string
|
|
36
|
+
* score or omits `passed` — the caller-supplied `passThreshold`
|
|
37
|
+
* derives `passed` from `score` when the judge didn't decide.
|
|
38
|
+
*/
|
|
39
|
+
function toEvalScore(verdict, passThreshold) {
|
|
40
|
+
const rawScore = typeof verdict.score === "string" ? Number(verdict.score) : verdict.score;
|
|
41
|
+
const score = clampScore(typeof rawScore === "number" ? rawScore : 0);
|
|
42
|
+
return {
|
|
43
|
+
score,
|
|
44
|
+
passed: typeof verdict.passed === "boolean" ? verdict.passed : score >= passThreshold,
|
|
45
|
+
reason: typeof verdict.reason === "string" ? verdict.reason : void 0
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* LLM-as-judge scorer. Runs the judge agent on a prompt built from the
|
|
50
|
+
* case (question + expected + actual answer + rubric) and parses its
|
|
51
|
+
* `{ score, passed?, reason? }` verdict.
|
|
52
|
+
*
|
|
53
|
+
* Verdict source order: `result.data` (when the judge declares an
|
|
54
|
+
* output schema), then `result.text` parsed as JSON. A judge that
|
|
55
|
+
* errors or returns unparseable text scores `0` with the failure
|
|
56
|
+
* reason attached — a broken judge fails the case rather than crashing
|
|
57
|
+
* the suite.
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* scorers: [judge({ agent: judgeAgent, rubric: "Cite a source for full marks." })]
|
|
61
|
+
*/
|
|
62
|
+
function judge(config, passThreshold = .5) {
|
|
63
|
+
const threshold = config.passThreshold ?? passThreshold;
|
|
64
|
+
return async (context) => {
|
|
65
|
+
const prompt = buildJudgePrompt(context, config);
|
|
66
|
+
const verdictResult = await config.agent.execute(prompt);
|
|
67
|
+
if (verdictResult.error) return {
|
|
68
|
+
score: 0,
|
|
69
|
+
passed: false,
|
|
70
|
+
reason: `judge failed: ${verdictResult.error.message}`
|
|
71
|
+
};
|
|
72
|
+
if (verdictResult.data && typeof verdictResult.data === "object") return toEvalScore(verdictResult.data, threshold);
|
|
73
|
+
const text = verdictResult.text ?? "";
|
|
74
|
+
const sentinel = Symbol("judge-parse-failed");
|
|
75
|
+
const parsed = safeJsonParse(extractJsonPayload(text), sentinel);
|
|
76
|
+
if (parsed === sentinel || parsed === null || typeof parsed !== "object") return {
|
|
77
|
+
score: 0,
|
|
78
|
+
passed: false,
|
|
79
|
+
reason: "judge returned no parseable verdict"
|
|
80
|
+
};
|
|
81
|
+
return toEvalScore(parsed, threshold);
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
//#endregion
|
|
86
|
+
export { judge };
|
|
87
|
+
//# sourceMappingURL=judge-scorer.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"judge-scorer.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/eval/judge-scorer.ts"],"sourcesContent":["import type {\n EvalJudge,\n EvalScore,\n EvalScorer,\n EvalScorerContext,\n} from \"../contracts/agent/eval.type\";\nimport { extractJsonPayload, safeJsonParse } from \"../utils\";\n\n/**\n * Raw shape the judge agent is expected to return — either parsed from\n * `result.data` (when the judge has an output schema) or extracted\n * from `result.text`.\n */\ntype JudgeVerdict = {\n score?: unknown;\n passed?: unknown;\n reason?: unknown;\n};\n\n/** Clamp an arbitrary numeric value into the `[0, 1]` score range. */\nfunction clampScore(value: number): number {\n if (Number.isNaN(value)) return 0;\n if (value < 0) return 0;\n if (value > 1) return 1;\n return value;\n}\n\n/**\n * Render the prompt the judge agent receives for one case. Includes\n * the rubric (if any), the original question, the expected reference\n * (when supplied), and the actual answer — then asks for a strict JSON\n * verdict so the response is machine-parseable even without an output\n * schema.\n */\nfunction buildJudgePrompt(context: EvalScorerContext, judge: EvalJudge): string {\n const lines: string[] = [];\n\n if (judge.rubric) {\n lines.push(`Grading rubric:\\n${judge.rubric}`, \"\");\n }\n\n lines.push(`Question:\\n${context.case.input}`, \"\");\n\n if (context.case.expected !== undefined) {\n const expectedText =\n typeof context.case.expected === \"string\"\n ? context.case.expected\n : JSON.stringify(context.case.expected);\n lines.push(`Reference answer:\\n${expectedText}`, \"\");\n }\n\n const actual = context.text ?? JSON.stringify(context.output ?? null);\n lines.push(`Answer to grade:\\n${actual}`, \"\");\n\n lines.push(\n 'Respond with JSON only: { \"score\": <0..1>, \"passed\": <true|false>, \"reason\": \"<short explanation>\" }.',\n );\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Coerce the judge agent's parsed/extracted verdict into a normalized\n * {@link EvalScore}. Defends against a judge that returns a string\n * score or omits `passed` — the caller-supplied `passThreshold`\n * derives `passed` from `score` when the judge didn't decide.\n */\nfunction toEvalScore(verdict: JudgeVerdict, passThreshold: number): EvalScore {\n const rawScore = typeof verdict.score === \"string\" ? Number(verdict.score) : verdict.score;\n const score = clampScore(typeof rawScore === \"number\" ? rawScore : 0);\n\n const passed = typeof verdict.passed === \"boolean\" ? verdict.passed : score >= passThreshold;\n\n const reason = typeof verdict.reason === \"string\" ? verdict.reason : undefined;\n\n return { score, passed, reason };\n}\n\n/**\n * LLM-as-judge scorer. Runs the judge agent on a prompt built from the\n * case (question + expected + actual answer + rubric) and parses its\n * `{ score, passed?, reason? }` verdict.\n *\n * Verdict source order: `result.data` (when the judge declares an\n * output schema), then `result.text` parsed as JSON. A judge that\n * errors or returns unparseable text scores `0` with the failure\n * reason attached — a broken judge fails the case rather than crashing\n * the suite.\n *\n * @example\n * scorers: [judge({ agent: judgeAgent, rubric: \"Cite a source for full marks.\" })]\n */\nexport function judge<TOutput = unknown>(\n config: EvalJudge,\n passThreshold = 0.5,\n): EvalScorer<TOutput> {\n const threshold = config.passThreshold ?? passThreshold;\n\n return async (context: EvalScorerContext<TOutput>): Promise<EvalScore> => {\n const prompt = buildJudgePrompt(context as EvalScorerContext, config);\n\n const verdictResult = await config.agent.execute(prompt);\n\n if (verdictResult.error) {\n return {\n score: 0,\n passed: false,\n reason: `judge failed: ${verdictResult.error.message}`,\n };\n }\n\n if (verdictResult.data && typeof verdictResult.data === \"object\") {\n return toEvalScore(verdictResult.data as JudgeVerdict, threshold);\n }\n\n const text = verdictResult.text ?? \"\";\n const sentinel = Symbol(\"judge-parse-failed\");\n const parsed = safeJsonParse<unknown>(extractJsonPayload(text), sentinel);\n\n if (parsed === sentinel || parsed === null || typeof parsed !== \"object\") {\n return {\n score: 0,\n passed: false,\n reason: \"judge returned no parseable verdict\",\n };\n }\n\n return toEvalScore(parsed as JudgeVerdict, threshold);\n };\n}\n"],"mappings":";;;;;;AAoBA,SAAS,WAAW,OAAuB;CACzC,IAAI,OAAO,MAAM,KAAK,GAAG,OAAO;CAChC,IAAI,QAAQ,GAAG,OAAO;CACtB,IAAI,QAAQ,GAAG,OAAO;CACtB,OAAO;AACT;;;;;;;;AASA,SAAS,iBAAiB,SAA4B,OAA0B;CAC9E,MAAM,QAAkB,CAAC;CAEzB,IAAI,MAAM,QACR,MAAM,KAAK,oBAAoB,MAAM,UAAU,EAAE;CAGnD,MAAM,KAAK,cAAc,QAAQ,KAAK,SAAS,EAAE;CAEjD,IAAI,QAAQ,KAAK,aAAa,QAAW;EACvC,MAAM,eACJ,OAAO,QAAQ,KAAK,aAAa,WAC7B,QAAQ,KAAK,WACb,KAAK,UAAU,QAAQ,KAAK,QAAQ;EAC1C,MAAM,KAAK,sBAAsB,gBAAgB,EAAE;CACrD;CAEA,MAAM,SAAS,QAAQ,QAAQ,KAAK,UAAU,QAAQ,UAAU,IAAI;CACpE,MAAM,KAAK,qBAAqB,UAAU,EAAE;CAE5C,MAAM,KACJ,+GACF;CAEA,OAAO,MAAM,KAAK,IAAI;AACxB;;;;;;;AAQA,SAAS,YAAY,SAAuB,eAAkC;CAC5E,MAAM,WAAW,OAAO,QAAQ,UAAU,WAAW,OAAO,QAAQ,KAAK,IAAI,QAAQ;CACrF,MAAM,QAAQ,WAAW,OAAO,aAAa,WAAW,WAAW,CAAC;CAMpE,OAAO;EAAE;EAAO,QAJD,OAAO,QAAQ,WAAW,YAAY,QAAQ,SAAS,SAAS;EAIvD,QAFT,OAAO,QAAQ,WAAW,WAAW,QAAQ,SAAS;CAEtC;AACjC;;;;;;;;;;;;;;;AAgBA,SAAgB,MACd,QACA,gBAAgB,IACK;CACrB,MAAM,YAAY,OAAO,iBAAiB;CAE1C,OAAO,OAAO,YAA4D;EACxE,MAAM,SAAS,iBAAiB,SAA8B,MAAM;EAEpE,MAAM,gBAAgB,MAAM,OAAO,MAAM,QAAQ,MAAM;EAEvD,IAAI,cAAc,OAChB,OAAO;GACL,OAAO;GACP,QAAQ;GACR,QAAQ,iBAAiB,cAAc,MAAM;EAC/C;EAGF,IAAI,cAAc,QAAQ,OAAO,cAAc,SAAS,UACtD,OAAO,YAAY,cAAc,MAAsB,SAAS;EAGlE,MAAM,OAAO,cAAc,QAAQ;EACnC,MAAM,WAAW,OAAO,oBAAoB;EAC5C,MAAM,SAAS,cAAuB,mBAAmB,IAAI,GAAG,QAAQ;EAExE,IAAI,WAAW,YAAY,WAAW,QAAQ,OAAO,WAAW,UAC9D,OAAO;GACL,OAAO;GACP,QAAQ;GACR,QAAQ;EACV;EAGF,OAAO,YAAY,QAAwB,SAAS;CACtD;AACF"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { EvalScorer, EvalScorerContext } from "../contracts/agent/eval.type.mjs";
|
|
2
|
+
|
|
3
|
+
//#region ../@warlock.js/ai/src/eval/scorers.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Predicate signature for {@link predicate}. Receives the same context
|
|
6
|
+
* a full scorer does and returns a boolean (sync or async). A `true`
|
|
7
|
+
* verdict scores `1`, `false` scores `0`.
|
|
8
|
+
*/
|
|
9
|
+
type EvalPredicate<TOutput = unknown> = (context: EvalScorerContext<TOutput>) => boolean | Promise<boolean>;
|
|
10
|
+
/**
|
|
11
|
+
* Exact-match scorer. Compares the agent's output against the case's
|
|
12
|
+
* `expected` reference. Prefers `result.data` (parsed structured
|
|
13
|
+
* output) when present, falling back to `result.text`. Comparison is
|
|
14
|
+
* trimmed and case-insensitive; structured values are compared by
|
|
15
|
+
* canonical JSON.
|
|
16
|
+
*
|
|
17
|
+
* Scores `1` / `passed: true` on a match, `0` / `passed: false`
|
|
18
|
+
* otherwise. A case with no `expected` always scores `0` — exact
|
|
19
|
+
* matching is meaningless without a reference.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* const report = await agent.eval({
|
|
23
|
+
* cases: [{ name: "q", input: "2+2?", expected: "4" }],
|
|
24
|
+
* scorers: [exact()],
|
|
25
|
+
* });
|
|
26
|
+
*/
|
|
27
|
+
declare function exact<TOutput = unknown>(): EvalScorer<TOutput>;
|
|
28
|
+
/**
|
|
29
|
+
* Substring / contains scorer. Passes when the normalized `expected`
|
|
30
|
+
* string appears anywhere in the agent's normalized output. Useful
|
|
31
|
+
* when the agent's phrasing varies but a key fact must be present.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* scorers: [contains()] // expected "Cairo" passes "The capital is Cairo."
|
|
35
|
+
*/
|
|
36
|
+
declare function contains<TOutput = unknown>(): EvalScorer<TOutput>;
|
|
37
|
+
/**
|
|
38
|
+
* Predicate scorer. Wraps a boolean-returning callback into a scorer —
|
|
39
|
+
* `true` scores `1` / `passed`, `false` scores `0` / fails. The
|
|
40
|
+
* escape hatch for arbitrary assertions ("output is valid JSON", "no
|
|
41
|
+
* tool errored", "duration under budget") that don't fit exact or
|
|
42
|
+
* judge scoring.
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* scorers: [predicate((ctx) => ctx.result.report.children.every(c => c.status === "completed"))]
|
|
46
|
+
*/
|
|
47
|
+
declare function predicate<TOutput = unknown>(fn: EvalPredicate<TOutput>): EvalScorer<TOutput>;
|
|
48
|
+
//#endregion
|
|
49
|
+
export { EvalPredicate, contains, exact, predicate };
|
|
50
|
+
//# sourceMappingURL=scorers.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scorers.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai/src/eval/scorers.ts"],"mappings":";;;;;AAWA;;;KAAY,aAAA,uBACV,OAAA,EAAS,iBAAA,CAAkB,OAAA,gBACd,OAAA;;;;;;;;;;;AAAO;AA8BtB;;;;;;iBAAgB,KAAA,uBAA4B,UAAU,CAAC,OAAA;;AAAO;AAmC9D;;;;;;iBAAgB,QAAA,uBAA+B,UAAU,CAAC,OAAA;;AAAO;AAsCjE;;;;;;;;iBAAgB,SAAA,oBACd,EAAA,EAAI,aAAA,CAAc,OAAA,IACjB,UAAA,CAAW,OAAA"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
//#region ../@warlock.js/ai/src/eval/scorers.ts
|
|
2
|
+
/**
|
|
3
|
+
* Normalize a value for case-insensitive, whitespace-trimmed string
|
|
4
|
+
* comparison. Non-string values are JSON-serialized first so a
|
|
5
|
+
* structured `expected` can still be matched against structured
|
|
6
|
+
* `output`.
|
|
7
|
+
*/
|
|
8
|
+
function normalizeForComparison(value) {
|
|
9
|
+
return (typeof value === "string" ? value : JSON.stringify(value)).trim().toLowerCase();
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Exact-match scorer. Compares the agent's output against the case's
|
|
13
|
+
* `expected` reference. Prefers `result.data` (parsed structured
|
|
14
|
+
* output) when present, falling back to `result.text`. Comparison is
|
|
15
|
+
* trimmed and case-insensitive; structured values are compared by
|
|
16
|
+
* canonical JSON.
|
|
17
|
+
*
|
|
18
|
+
* Scores `1` / `passed: true` on a match, `0` / `passed: false`
|
|
19
|
+
* otherwise. A case with no `expected` always scores `0` — exact
|
|
20
|
+
* matching is meaningless without a reference.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* const report = await agent.eval({
|
|
24
|
+
* cases: [{ name: "q", input: "2+2?", expected: "4" }],
|
|
25
|
+
* scorers: [exact()],
|
|
26
|
+
* });
|
|
27
|
+
*/
|
|
28
|
+
function exact() {
|
|
29
|
+
return (context) => {
|
|
30
|
+
if (context.case.expected === void 0) return {
|
|
31
|
+
score: 0,
|
|
32
|
+
passed: false,
|
|
33
|
+
reason: "no expected value supplied for exact match"
|
|
34
|
+
};
|
|
35
|
+
const actual = context.output ?? context.text;
|
|
36
|
+
if (actual === void 0) return {
|
|
37
|
+
score: 0,
|
|
38
|
+
passed: false,
|
|
39
|
+
reason: "agent produced no output"
|
|
40
|
+
};
|
|
41
|
+
const matches = normalizeForComparison(actual) === normalizeForComparison(context.case.expected);
|
|
42
|
+
return {
|
|
43
|
+
score: matches ? 1 : 0,
|
|
44
|
+
passed: matches,
|
|
45
|
+
reason: matches ? "exact match" : "output did not match expected"
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Substring / contains scorer. Passes when the normalized `expected`
|
|
51
|
+
* string appears anywhere in the agent's normalized output. Useful
|
|
52
|
+
* when the agent's phrasing varies but a key fact must be present.
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* scorers: [contains()] // expected "Cairo" passes "The capital is Cairo."
|
|
56
|
+
*/
|
|
57
|
+
function contains() {
|
|
58
|
+
return (context) => {
|
|
59
|
+
if (context.case.expected === void 0) return {
|
|
60
|
+
score: 0,
|
|
61
|
+
passed: false,
|
|
62
|
+
reason: "no expected value supplied for contains match"
|
|
63
|
+
};
|
|
64
|
+
const actual = context.output ?? context.text;
|
|
65
|
+
if (actual === void 0) return {
|
|
66
|
+
score: 0,
|
|
67
|
+
passed: false,
|
|
68
|
+
reason: "agent produced no output"
|
|
69
|
+
};
|
|
70
|
+
const found = normalizeForComparison(actual).includes(normalizeForComparison(context.case.expected));
|
|
71
|
+
return {
|
|
72
|
+
score: found ? 1 : 0,
|
|
73
|
+
passed: found,
|
|
74
|
+
reason: found ? "expected substring found" : "expected substring not found"
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Predicate scorer. Wraps a boolean-returning callback into a scorer —
|
|
80
|
+
* `true` scores `1` / `passed`, `false` scores `0` / fails. The
|
|
81
|
+
* escape hatch for arbitrary assertions ("output is valid JSON", "no
|
|
82
|
+
* tool errored", "duration under budget") that don't fit exact or
|
|
83
|
+
* judge scoring.
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* scorers: [predicate((ctx) => ctx.result.report.children.every(c => c.status === "completed"))]
|
|
87
|
+
*/
|
|
88
|
+
function predicate(fn) {
|
|
89
|
+
return async (context) => {
|
|
90
|
+
const result = await fn(context);
|
|
91
|
+
return {
|
|
92
|
+
score: result ? 1 : 0,
|
|
93
|
+
passed: result,
|
|
94
|
+
reason: result ? "predicate passed" : "predicate failed"
|
|
95
|
+
};
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
//#endregion
|
|
100
|
+
export { contains, exact, predicate };
|
|
101
|
+
//# sourceMappingURL=scorers.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scorers.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/eval/scorers.ts"],"sourcesContent":["import type {\n EvalScore,\n EvalScorer,\n EvalScorerContext,\n} from \"../contracts/agent/eval.type\";\n\n/**\n * Predicate signature for {@link predicate}. Receives the same context\n * a full scorer does and returns a boolean (sync or async). A `true`\n * verdict scores `1`, `false` scores `0`.\n */\nexport type EvalPredicate<TOutput = unknown> = (\n context: EvalScorerContext<TOutput>,\n) => boolean | Promise<boolean>;\n\n/**\n * Normalize a value for case-insensitive, whitespace-trimmed string\n * comparison. Non-string values are JSON-serialized first so a\n * structured `expected` can still be matched against structured\n * `output`.\n */\nfunction normalizeForComparison(value: unknown): string {\n const text = typeof value === \"string\" ? value : JSON.stringify(value);\n return text.trim().toLowerCase();\n}\n\n/**\n * Exact-match scorer. Compares the agent's output against the case's\n * `expected` reference. Prefers `result.data` (parsed structured\n * output) when present, falling back to `result.text`. Comparison is\n * trimmed and case-insensitive; structured values are compared by\n * canonical JSON.\n *\n * Scores `1` / `passed: true` on a match, `0` / `passed: false`\n * otherwise. A case with no `expected` always scores `0` — exact\n * matching is meaningless without a reference.\n *\n * @example\n * const report = await agent.eval({\n * cases: [{ name: \"q\", input: \"2+2?\", expected: \"4\" }],\n * scorers: [exact()],\n * });\n */\nexport function exact<TOutput = unknown>(): EvalScorer<TOutput> {\n return (context: EvalScorerContext<TOutput>): EvalScore => {\n if (context.case.expected === undefined) {\n return {\n score: 0,\n passed: false,\n reason: \"no expected value supplied for exact match\",\n };\n }\n\n const actual = context.output ?? context.text;\n\n if (actual === undefined) {\n return { score: 0, passed: false, reason: \"agent produced no output\" };\n }\n\n const matches =\n normalizeForComparison(actual) === normalizeForComparison(context.case.expected);\n\n return {\n score: matches ? 1 : 0,\n passed: matches,\n reason: matches ? \"exact match\" : \"output did not match expected\",\n };\n };\n}\n\n/**\n * Substring / contains scorer. Passes when the normalized `expected`\n * string appears anywhere in the agent's normalized output. Useful\n * when the agent's phrasing varies but a key fact must be present.\n *\n * @example\n * scorers: [contains()] // expected \"Cairo\" passes \"The capital is Cairo.\"\n */\nexport function contains<TOutput = unknown>(): EvalScorer<TOutput> {\n return (context: EvalScorerContext<TOutput>): EvalScore => {\n if (context.case.expected === undefined) {\n return {\n score: 0,\n passed: false,\n reason: \"no expected value supplied for contains match\",\n };\n }\n\n const actual = context.output ?? context.text;\n\n if (actual === undefined) {\n return { score: 0, passed: false, reason: \"agent produced no output\" };\n }\n\n const found = normalizeForComparison(actual).includes(\n normalizeForComparison(context.case.expected),\n );\n\n return {\n score: found ? 1 : 0,\n passed: found,\n reason: found ? \"expected substring found\" : \"expected substring not found\",\n };\n };\n}\n\n/**\n * Predicate scorer. Wraps a boolean-returning callback into a scorer —\n * `true` scores `1` / `passed`, `false` scores `0` / fails. The\n * escape hatch for arbitrary assertions (\"output is valid JSON\", \"no\n * tool errored\", \"duration under budget\") that don't fit exact or\n * judge scoring.\n *\n * @example\n * scorers: [predicate((ctx) => ctx.result.report.children.every(c => c.status === \"completed\"))]\n */\nexport function predicate<TOutput = unknown>(\n fn: EvalPredicate<TOutput>,\n): EvalScorer<TOutput> {\n return async (context: EvalScorerContext<TOutput>): Promise<EvalScore> => {\n const result = await fn(context);\n\n return {\n score: result ? 1 : 0,\n passed: result,\n reason: result ? \"predicate passed\" : \"predicate failed\",\n };\n };\n}\n"],"mappings":";;;;;;;AAqBA,SAAS,uBAAuB,OAAwB;CAEtD,QADa,OAAO,UAAU,WAAW,QAAQ,KAAK,UAAU,KAAK,EAC1D,CAAC,KAAK,CAAC,CAAC,YAAY;AACjC;;;;;;;;;;;;;;;;;;AAmBA,SAAgB,QAAgD;CAC9D,QAAQ,YAAmD;EACzD,IAAI,QAAQ,KAAK,aAAa,QAC5B,OAAO;GACL,OAAO;GACP,QAAQ;GACR,QAAQ;EACV;EAGF,MAAM,SAAS,QAAQ,UAAU,QAAQ;EAEzC,IAAI,WAAW,QACb,OAAO;GAAE,OAAO;GAAG,QAAQ;GAAO,QAAQ;EAA2B;EAGvE,MAAM,UACJ,uBAAuB,MAAM,MAAM,uBAAuB,QAAQ,KAAK,QAAQ;EAEjF,OAAO;GACL,OAAO,UAAU,IAAI;GACrB,QAAQ;GACR,QAAQ,UAAU,gBAAgB;EACpC;CACF;AACF;;;;;;;;;AAUA,SAAgB,WAAmD;CACjE,QAAQ,YAAmD;EACzD,IAAI,QAAQ,KAAK,aAAa,QAC5B,OAAO;GACL,OAAO;GACP,QAAQ;GACR,QAAQ;EACV;EAGF,MAAM,SAAS,QAAQ,UAAU,QAAQ;EAEzC,IAAI,WAAW,QACb,OAAO;GAAE,OAAO;GAAG,QAAQ;GAAO,QAAQ;EAA2B;EAGvE,MAAM,QAAQ,uBAAuB,MAAM,CAAC,CAAC,SAC3C,uBAAuB,QAAQ,KAAK,QAAQ,CAC9C;EAEA,OAAO;GACL,OAAO,QAAQ,IAAI;GACnB,QAAQ;GACR,QAAQ,QAAQ,6BAA6B;EAC/C;CACF;AACF;;;;;;;;;;;AAYA,SAAgB,UACd,IACqB;CACrB,OAAO,OAAO,YAA4D;EACxE,MAAM,SAAS,MAAM,GAAG,OAAO;EAE/B,OAAO;GACL,OAAO,SAAS,IAAI;GACpB,QAAQ;GACR,QAAQ,SAAS,qBAAqB;EACxC;CACF;AACF"}
|