@warlock.js/ai 4.2.10 → 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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"supervisor.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/supervisor/supervisor.ts"],"sourcesContent":["import type { SupervisorEventMap } from \"../contracts/events/event-map.type\";\nimport type { SupervisorResult } from \"../contracts/result/supervisor-result.type\";\nimport type { StreamContract } from \"../contracts/stream/stream.contract\";\nimport type { SupervisorIntentValue } from \"../contracts/supervisor/intent-entry.type\";\nimport type {\n SupervisorConfig,\n SupervisorEventHandler,\n} from \"../contracts/supervisor/supervisor-config.type\";\nimport type {\n SupervisorExecuteOptions,\n SupervisorResumeOptions,\n} from \"../contracts/supervisor/supervisor-execute-options.type\";\nimport type { SupervisorInput } from \"../contracts/supervisor/supervisor-input.type\";\nimport type { SupervisorStreamEvent } from \"../contracts/supervisor/supervisor-stream-event.type\";\nimport type {\n SupervisorAsToolOptions,\n SupervisorContract,\n} from \"../contracts/supervisor/supervisor.contract\";\nimport { SupervisorFailedError } from \"../errors\";\nimport type { ToolContract } from \"../tool/tool\";\nimport { asTool } from \"./as-tool\";\nimport { SupervisorEmitter } from \"./emitter\";\nimport { assertRouterDescriptions, resolveIntentEntries } from \"./entries\";\nimport { SupervisorExecution } from \"./execution\";\nimport { computeSignature } from \"./signature\";\nimport { loadSnapshotForResume } from \"./snapshot\";\nimport { createSupervisorStream } from \"./supervisor-stream\";\n\n/**\n * `ai.supervisor(config)` — construct a `SupervisorContract`. Validates\n * the config at author time (throws `SupervisorFailedError` on bad\n * shape), resolves agent entries, computes a stable structural\n * signature, wires the three-tier event emitter, and returns an\n * instance that satisfies `ExecutableContract` so it can compose into\n * tools, outer agents, and (future) orchestrators uniformly.\n *\n * @example\n * const support = ai.supervisor({\n * name: \"customer-support\",\n * router: routerAgent,\n * intents: { triage, orderLookup, billingLookup, resolver },\n * evaluate: (ctx) => ctx.result.resolver?.output ? { satisfied: true } : undefined,\n * output: z.object({ response: z.string(), refund: z.boolean() }),\n * maxIterations: 6,\n * });\n */\nexport function supervisor<\n TOutput = unknown,\n TState = TOutput,\n TIntents extends Record<string, SupervisorIntentValue> = Record<string, SupervisorIntentValue>,\n TArtifacts = Record<string, unknown>,\n>(config: SupervisorConfig<TOutput, TState, TIntents, TArtifacts>): SupervisorContract<TOutput> {\n validateFactoryConfig(config as unknown as SupervisorConfig<TOutput>);\n\n const entries = resolveIntentEntries(config.intents, config.name);\n\n assertRouterDescriptions(config as SupervisorConfig<unknown>, entries);\n\n if (config.initialAgent && !entries.has(config.initialAgent)) {\n throw new SupervisorFailedError(\n `ai.supervisor(\"${config.name}\"): \\`initialAgent\\` \"${config.initialAgent}\" is not a key in \\`intents\\``,\n { context: { authoring: true } },\n );\n }\n\n const signature = computeSignature(config as SupervisorConfig<unknown>, entries);\n const emitter = new SupervisorEmitter(config.on);\n\n async function execute(\n input: SupervisorInput,\n options?: SupervisorExecuteOptions,\n ): Promise<SupervisorResult<TOutput>> {\n const runId = options?.runId ?? generateRunId();\n\n const execution = new SupervisorExecution<TOutput>({\n config: config as unknown as SupervisorConfig<TOutput>,\n entries,\n signature,\n emitter,\n input,\n runId,\n options,\n });\n\n return execution.run();\n }\n\n function stream(\n input: SupervisorInput,\n options?: SupervisorExecuteOptions,\n ): StreamContract<SupervisorResult<TOutput>, SupervisorStreamEvent> {\n const runId = options?.runId ?? generateRunId();\n const { controller, stream: contract } = createSupervisorStream<SupervisorResult<TOutput>>();\n\n const execution = new SupervisorExecution<TOutput>({\n config: config as unknown as SupervisorConfig<TOutput>,\n entries,\n signature,\n emitter,\n input,\n runId,\n options,\n streamController: controller,\n });\n\n void execution.run();\n\n return contract;\n }\n\n async function resume(\n runId: string,\n options?: SupervisorResumeOptions,\n ): Promise<SupervisorResult<TOutput>> {\n const snapshot = await loadSnapshotForResume({\n config: config as SupervisorConfig<unknown>,\n signature,\n runId,\n options,\n });\n\n const execution = new SupervisorExecution<TOutput>({\n config: config as unknown as SupervisorConfig<TOutput>,\n entries,\n signature,\n emitter,\n input: snapshot.input,\n runId,\n options,\n resumeFrom: snapshot,\n });\n\n return execution.run();\n }\n\n const instance: SupervisorContract<TOutput> = {\n name: config.name,\n signature,\n execute,\n stream,\n resume,\n on<K extends keyof SupervisorEventMap>(\n event: K,\n handler: SupervisorEventHandler<K>,\n ): () => void {\n return emitter.on(event, handler);\n },\n off<K extends keyof SupervisorEventMap>(event: K, handler: SupervisorEventHandler<K>): void {\n emitter.off(event, handler);\n },\n asTool<TToolInput = string>(\n options: SupervisorAsToolOptions<TToolInput>,\n ): ToolContract<TToolInput, TOutput> {\n return asTool<TOutput, TToolInput>(instance, options);\n },\n };\n\n return instance;\n}\n\n/**\n * Factory-time validation. Enforces the XOR + pairing rules the design\n * locked in §2 and surfaces any violation as a typed\n * `SupervisorFailedError` tagged `authoring: true`.\n */\nfunction validateFactoryConfig<T>(config: SupervisorConfig<T>): void {\n if (!config.name || typeof config.name !== \"string\") {\n throw new SupervisorFailedError(\"ai.supervisor: `name` is required and must be a string\", {\n context: { authoring: true },\n });\n }\n\n if (!config.intents || typeof config.intents !== \"object\") {\n throw new SupervisorFailedError(`ai.supervisor(\"${config.name}\"): \\`intents\\` is required`, {\n context: { authoring: true },\n });\n }\n\n const hasRoute = typeof config.route === \"function\";\n const hasRouter = !!config.router;\n\n if (hasRouter) {\n const router = config.router as { execute?: unknown } | { agent?: { execute?: unknown } };\n const isBareAgent = typeof (router as { execute?: unknown }).execute === \"function\";\n const isEntryForm =\n !isBareAgent &&\n typeof (router as { agent?: { execute?: unknown } }).agent === \"object\" &&\n typeof (router as { agent?: { execute?: unknown } }).agent?.execute === \"function\";\n\n if (!isBareAgent && !isEntryForm) {\n throw new SupervisorFailedError(\n `ai.supervisor(\"${config.name}\"): \\`router\\` must be an agent contract or a \\`{ agent, placeholders?, input? }\\` entry`,\n { context: { authoring: true } },\n );\n }\n }\n\n if (hasRoute && hasRouter) {\n throw new SupervisorFailedError(\n `ai.supervisor(\"${config.name}\"): \\`route\\` and \\`router\\` are mutually exclusive — configure exactly one`,\n { context: { authoring: true } },\n );\n }\n\n // Phase 7 / decisions §37 — `classifier` is the iter-0 prelude;\n // satisfies the \"must have a dispatch source\" rule on its own.\n // Composes with router/route (classifier drives iter 0; router/route\n // takes iter 1+). When configured alone, supervisor terminates after\n // iter 0's branch settles.\n const hasClassifier = config.classifier !== undefined;\n\n if (!hasRoute && !hasRouter && !hasClassifier) {\n throw new SupervisorFailedError(\n `ai.supervisor(\"${config.name}\"): one of \\`route\\`, \\`router\\`, or \\`classifier\\` is required`,\n { context: { authoring: true } },\n );\n }\n\n // Phase 7 — classifier and initialAgent both decide what runs first.\n // Coexistence is meaningless; throw loudly.\n if (hasClassifier && config.initialAgent) {\n throw new SupervisorFailedError(\n `ai.supervisor(\"${config.name}\"): \\`classifier\\` and \\`initialAgent\\` are mutually exclusive — both decide which intent runs first. Pick one.`,\n { context: { authoring: true } },\n );\n }\n\n // Phase 3.4 (Q9) — evaluate now pairs with both `route` and\n // `router`. State-driven termination is useful in either dispatch\n // mode; the historical router-only restriction was incidental,\n // not principled.\n\n if (config.ack !== undefined) {\n const ack = config.ack;\n const isCallback = typeof ack === \"function\";\n const isAgentEntry =\n typeof ack === \"object\" &&\n ack !== null &&\n typeof (ack as { agent?: { execute?: unknown } }).agent?.execute === \"function\";\n const isRunEntry =\n typeof ack === \"object\" &&\n ack !== null &&\n typeof (ack as { run?: unknown }).run === \"function\";\n\n if (!isCallback && !isAgentEntry && !isRunEntry) {\n throw new SupervisorFailedError(\n `ai.supervisor(\"${config.name}\"): \\`ack\\` must be an \\`{ agent, ... }\\` entry, an \\`{ run, ... }\\` entry, or a bare callback function`,\n { context: { authoring: true } },\n );\n }\n\n if (isAgentEntry && isRunEntry) {\n throw new SupervisorFailedError(\n `ai.supervisor(\"${config.name}\"): \\`ack\\` cannot declare both \\`agent\\` and \\`run\\` — pick one`,\n { context: { authoring: true } },\n );\n }\n }\n\n if (config.maxIterations !== undefined && config.maxIterations < 1) {\n throw new SupervisorFailedError(\n `ai.supervisor(\"${config.name}\"): \\`maxIterations\\` must be >= 1`,\n { context: { authoring: true, maxIterations: config.maxIterations } },\n );\n }\n}\n\nfunction generateRunId(): string {\n return `sup_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"supervisor.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/supervisor/supervisor.ts"],"sourcesContent":["import type { SupervisorEventMap } from \"../contracts/events/event-map.type\";\nimport type { SupervisorResult } from \"../contracts/result/supervisor-result.type\";\nimport type { StreamContract } from \"../contracts/stream/stream.contract\";\nimport type { SupervisorIntentValue } from \"../contracts/supervisor/intent-entry.type\";\nimport type {\n SupervisorConfig,\n SupervisorEventHandler,\n} from \"../contracts/supervisor/supervisor-config.type\";\nimport type {\n SupervisorExecuteOptions,\n SupervisorResumeOptions,\n} from \"../contracts/supervisor/supervisor-execute-options.type\";\nimport type { SupervisorInput } from \"../contracts/supervisor/supervisor-input.type\";\nimport type { SupervisorStreamEvent } from \"../contracts/supervisor/supervisor-stream-event.type\";\nimport type {\n SupervisorAsToolOptions,\n SupervisorContract,\n} from \"../contracts/supervisor/supervisor.contract\";\nimport { SupervisorFailedError } from \"../errors\";\nimport type { ToolContract } from \"../tool/tool\";\nimport { asTool } from \"./as-tool\";\nimport { SupervisorEmitter } from \"./emitter\";\nimport { assertRouterDescriptions, resolveIntentEntries } from \"./entries\";\nimport { SupervisorExecution } from \"./execution\";\nimport { computeSignature } from \"./signature\";\nimport { loadSnapshotForResume } from \"./snapshot\";\nimport { createSupervisorStream } from \"./supervisor-stream\";\n\n/**\n * `ai.supervisor(config)` — construct a `SupervisorContract`. Validates\n * the config at author time (throws `SupervisorFailedError` on bad\n * shape), resolves agent entries, computes a stable structural\n * signature, wires the three-tier event emitter, and returns an\n * instance that satisfies `ExecutableContract` so it can compose into\n * tools, outer agents, and (future) orchestrators uniformly.\n *\n * @example\n * const support = ai.supervisor({\n * name: \"customer-support\",\n * router: routerAgent,\n * intents: { triage, orderLookup, billingLookup, resolver },\n * evaluate: (ctx) => ctx.result.resolver?.output ? { satisfied: true } : undefined,\n * output: z.object({ response: z.string(), refund: z.boolean() }),\n * maxIterations: 6,\n * });\n */\nexport function supervisor<\n TOutput = unknown,\n TState = TOutput,\n TIntents extends Record<string, SupervisorIntentValue> = Record<string, SupervisorIntentValue>,\n TArtifacts = Record<string, unknown>,\n>(config: SupervisorConfig<TOutput, TState, TIntents, TArtifacts>): SupervisorContract<TOutput> {\n validateFactoryConfig(config as unknown as SupervisorConfig<TOutput>);\n\n const entries = resolveIntentEntries(config.intents, config.name);\n\n assertRouterDescriptions(config as SupervisorConfig<unknown>, entries);\n\n if (config.initialAgent && !entries.has(config.initialAgent)) {\n throw new SupervisorFailedError(\n `ai.supervisor(\"${config.name}\"): \\`initialAgent\\` \"${config.initialAgent}\" is not a key in \\`intents\\``,\n { context: { authoring: true } },\n );\n }\n\n const signature = computeSignature(config as SupervisorConfig<unknown>, entries);\n const emitter = new SupervisorEmitter(config.on);\n\n async function execute(\n input: SupervisorInput,\n options?: SupervisorExecuteOptions,\n ): Promise<SupervisorResult<TOutput>> {\n const runId = options?.runId ?? generateRunId();\n\n const execution = new SupervisorExecution<TOutput>({\n config: config as unknown as SupervisorConfig<TOutput>,\n entries,\n signature,\n emitter,\n input,\n runId,\n options,\n });\n\n return execution.run();\n }\n\n function stream(\n input: SupervisorInput,\n options?: SupervisorExecuteOptions,\n ): StreamContract<SupervisorResult<TOutput>, SupervisorStreamEvent> {\n const runId = options?.runId ?? generateRunId();\n const { controller, stream: contract } = createSupervisorStream<SupervisorResult<TOutput>>();\n\n const execution = new SupervisorExecution<TOutput>({\n config: config as unknown as SupervisorConfig<TOutput>,\n entries,\n signature,\n emitter,\n input,\n runId,\n options,\n streamController: controller,\n });\n\n void execution.run();\n\n return contract;\n }\n\n async function resume(\n runId: string,\n options?: SupervisorResumeOptions,\n ): Promise<SupervisorResult<TOutput>> {\n const snapshot = await loadSnapshotForResume({\n config: config as SupervisorConfig<unknown>,\n signature,\n runId,\n options,\n });\n\n const execution = new SupervisorExecution<TOutput>({\n config: config as unknown as SupervisorConfig<TOutput>,\n entries,\n signature,\n emitter,\n input: snapshot.input,\n runId,\n options,\n resumeFrom: snapshot,\n });\n\n return execution.run();\n }\n\n const instance: SupervisorContract<TOutput> = {\n name: config.name,\n inputSchema: config.inputSchema,\n signature,\n execute,\n stream,\n resume,\n on<K extends keyof SupervisorEventMap>(\n event: K,\n handler: SupervisorEventHandler<K>,\n ): () => void {\n return emitter.on(event, handler);\n },\n off<K extends keyof SupervisorEventMap>(event: K, handler: SupervisorEventHandler<K>): void {\n emitter.off(event, handler);\n },\n asTool<TToolInput = string>(\n options: SupervisorAsToolOptions<TToolInput>,\n ): ToolContract<TToolInput, TOutput> {\n return asTool<TOutput, TToolInput>(instance, options);\n },\n };\n\n return instance;\n}\n\n/**\n * Factory-time validation. Enforces the XOR + pairing rules the design\n * locked in §2 and surfaces any violation as a typed\n * `SupervisorFailedError` tagged `authoring: true`.\n */\nfunction validateFactoryConfig<T>(config: SupervisorConfig<T>): void {\n if (!config.name || typeof config.name !== \"string\") {\n throw new SupervisorFailedError(\"ai.supervisor: `name` is required and must be a string\", {\n context: { authoring: true },\n });\n }\n\n if (!config.intents || typeof config.intents !== \"object\") {\n throw new SupervisorFailedError(`ai.supervisor(\"${config.name}\"): \\`intents\\` is required`, {\n context: { authoring: true },\n });\n }\n\n const hasRoute = typeof config.route === \"function\";\n const hasRouter = !!config.router;\n\n if (hasRouter) {\n const router = config.router as { execute?: unknown } | { agent?: { execute?: unknown } };\n const isBareAgent = typeof (router as { execute?: unknown }).execute === \"function\";\n const isEntryForm =\n !isBareAgent &&\n typeof (router as { agent?: { execute?: unknown } }).agent === \"object\" &&\n typeof (router as { agent?: { execute?: unknown } }).agent?.execute === \"function\";\n\n if (!isBareAgent && !isEntryForm) {\n throw new SupervisorFailedError(\n `ai.supervisor(\"${config.name}\"): \\`router\\` must be an agent contract or a \\`{ agent, placeholders?, input? }\\` entry`,\n { context: { authoring: true } },\n );\n }\n }\n\n if (hasRoute && hasRouter) {\n throw new SupervisorFailedError(\n `ai.supervisor(\"${config.name}\"): \\`route\\` and \\`router\\` are mutually exclusive — configure exactly one`,\n { context: { authoring: true } },\n );\n }\n\n // Phase 7 / decisions §37 — `classifier` is the iter-0 prelude;\n // satisfies the \"must have a dispatch source\" rule on its own.\n // Composes with router/route (classifier drives iter 0; router/route\n // takes iter 1+). When configured alone, supervisor terminates after\n // iter 0's branch settles.\n const hasClassifier = config.classifier !== undefined;\n\n if (!hasRoute && !hasRouter && !hasClassifier) {\n throw new SupervisorFailedError(\n `ai.supervisor(\"${config.name}\"): one of \\`route\\`, \\`router\\`, or \\`classifier\\` is required`,\n { context: { authoring: true } },\n );\n }\n\n // Phase 7 — classifier and initialAgent both decide what runs first.\n // Coexistence is meaningless; throw loudly.\n if (hasClassifier && config.initialAgent) {\n throw new SupervisorFailedError(\n `ai.supervisor(\"${config.name}\"): \\`classifier\\` and \\`initialAgent\\` are mutually exclusive — both decide which intent runs first. Pick one.`,\n { context: { authoring: true } },\n );\n }\n\n // Phase 3.4 (Q9) — evaluate now pairs with both `route` and\n // `router`. State-driven termination is useful in either dispatch\n // mode; the historical router-only restriction was incidental,\n // not principled.\n\n if (config.ack !== undefined) {\n const ack = config.ack;\n const isCallback = typeof ack === \"function\";\n const isAgentEntry =\n typeof ack === \"object\" &&\n ack !== null &&\n typeof (ack as { agent?: { execute?: unknown } }).agent?.execute === \"function\";\n const isRunEntry =\n typeof ack === \"object\" &&\n ack !== null &&\n typeof (ack as { run?: unknown }).run === \"function\";\n\n if (!isCallback && !isAgentEntry && !isRunEntry) {\n throw new SupervisorFailedError(\n `ai.supervisor(\"${config.name}\"): \\`ack\\` must be an \\`{ agent, ... }\\` entry, an \\`{ run, ... }\\` entry, or a bare callback function`,\n { context: { authoring: true } },\n );\n }\n\n if (isAgentEntry && isRunEntry) {\n throw new SupervisorFailedError(\n `ai.supervisor(\"${config.name}\"): \\`ack\\` cannot declare both \\`agent\\` and \\`run\\` — pick one`,\n { context: { authoring: true } },\n );\n }\n }\n\n if (config.maxIterations !== undefined && config.maxIterations < 1) {\n throw new SupervisorFailedError(\n `ai.supervisor(\"${config.name}\"): \\`maxIterations\\` must be >= 1`,\n { context: { authoring: true, maxIterations: config.maxIterations } },\n );\n }\n}\n\nfunction generateRunId(): string {\n return `sup_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;\n}\n"],"mappings":"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"}
|
|
@@ -54,6 +54,32 @@ import { InstructionContract, PersonaContract, SystemPromptBlockContract, System
|
|
|
54
54
|
declare class SystemPrompt implements SystemPromptContract {
|
|
55
55
|
readonly blocks: readonly SystemPromptBlockContract[];
|
|
56
56
|
constructor(blocks?: readonly SystemPromptBlockContract[]);
|
|
57
|
+
/**
|
|
58
|
+
* Build a system prompt by reading the file at `path` once, synchronously,
|
|
59
|
+
* at construction time. The file's UTF-8 contents seed a single instruction
|
|
60
|
+
* block — the same semantics as the string-seed form of `systemPrompt()` —
|
|
61
|
+
* so placeholders inside the file (`{{language|English}}`) resolve at
|
|
62
|
+
* `resolve()` time and the result can be forked with further
|
|
63
|
+
* `.persona()` / `.instruction()` calls.
|
|
64
|
+
*
|
|
65
|
+
* One-shot by design: the file is read exactly once here, never re-read on
|
|
66
|
+
* `resolve()`. Reads are synchronous so the call stays a drop-in for the
|
|
67
|
+
* synchronous `systemPrompt()` factory and the synchronous `resolve()` API.
|
|
68
|
+
*
|
|
69
|
+
* Throws `InvalidRequestError` when the file cannot be read (missing path,
|
|
70
|
+
* permission denied) — surfacing the underlying cause so a typo in the
|
|
71
|
+
* prompt path fails loudly at construction instead of silently producing an
|
|
72
|
+
* empty prompt.
|
|
73
|
+
*
|
|
74
|
+
* @param path - Filesystem path to the prompt template file.
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* const prompt = SystemPrompt.fromFile("./prompts/support-agent.md");
|
|
78
|
+
*
|
|
79
|
+
* const localized = prompt.instruction("Respond in {{language|English}}.");
|
|
80
|
+
* localized.resolve({ language: "Arabic" });
|
|
81
|
+
*/
|
|
82
|
+
static fromFile(path: string): SystemPrompt;
|
|
57
83
|
/**
|
|
58
84
|
* Return a new builder with the persona block set. If a persona already
|
|
59
85
|
* exists it's replaced in place (preserving its position in `blocks`);
|
|
@@ -78,6 +104,23 @@ declare class SystemPrompt implements SystemPromptContract {
|
|
|
78
104
|
*/
|
|
79
105
|
resolve(placeholders?: Placeholders): string;
|
|
80
106
|
}
|
|
107
|
+
/**
|
|
108
|
+
* Public factory for `SystemPrompt`, callable directly or via its
|
|
109
|
+
* `fromFile` static. Exists as a named interface so the callable signature
|
|
110
|
+
* and the `fromFile` attachment travel together as one public type.
|
|
111
|
+
*/
|
|
112
|
+
interface SystemPromptFactory {
|
|
113
|
+
(input?: string | ReadonlyArray<SystemPromptBlockContract>): SystemPrompt;
|
|
114
|
+
/**
|
|
115
|
+
* Build a system prompt from a file read once at construction. Delegates
|
|
116
|
+
* to {@link SystemPrompt.fromFile}, so `ai.systemPrompt.fromFile(path)` and
|
|
117
|
+
* `SystemPrompt.fromFile(path)` behave identically.
|
|
118
|
+
*
|
|
119
|
+
* @example
|
|
120
|
+
* const prompt = ai.systemPrompt.fromFile("./prompts/support-agent.md");
|
|
121
|
+
*/
|
|
122
|
+
fromFile(path: string): SystemPrompt;
|
|
123
|
+
}
|
|
81
124
|
/**
|
|
82
125
|
* Create a new immutable system-prompt builder.
|
|
83
126
|
*
|
|
@@ -85,10 +128,11 @@ declare class SystemPrompt implements SystemPromptContract {
|
|
|
85
128
|
* free of `new` and consistent with `ai.tool()`, `ai.agent()`,
|
|
86
129
|
* `ai.persona()`, `ai.instruction()`.
|
|
87
130
|
*
|
|
88
|
-
*
|
|
131
|
+
* Input forms:
|
|
89
132
|
* - No argument → empty builder, chain `.persona()` / `.instruction()`
|
|
90
133
|
* - Single string → seeded with one instruction for quick one-shot prompts
|
|
91
134
|
* - Array of blocks → used verbatim, preserving insertion order
|
|
135
|
+
* - `.fromFile(path)` → seeded from a file read once at construction
|
|
92
136
|
*
|
|
93
137
|
* @example
|
|
94
138
|
* // Composed builder
|
|
@@ -104,6 +148,10 @@ declare class SystemPrompt implements SystemPromptContract {
|
|
|
104
148
|
* const prompt = systemPrompt("Answer only with JSON matching the schema.");
|
|
105
149
|
*
|
|
106
150
|
* @example
|
|
151
|
+
* // From a file, read once at construction
|
|
152
|
+
* const prompt = systemPrompt.fromFile("./prompts/support-agent.md");
|
|
153
|
+
*
|
|
154
|
+
* @example
|
|
107
155
|
* // Array form — fully declarative
|
|
108
156
|
* const prompt = systemPrompt([
|
|
109
157
|
* ai.persona("You are Alex."),
|
|
@@ -111,7 +159,7 @@ declare class SystemPrompt implements SystemPromptContract {
|
|
|
111
159
|
* ai.instruction("Respond in {{language|English}}."),
|
|
112
160
|
* ]);
|
|
113
161
|
*/
|
|
114
|
-
declare
|
|
162
|
+
declare const systemPrompt: SystemPromptFactory;
|
|
115
163
|
//#endregion
|
|
116
|
-
export { SystemPrompt, systemPrompt };
|
|
164
|
+
export { SystemPrompt, SystemPromptFactory, systemPrompt };
|
|
117
165
|
//# sourceMappingURL=system-prompt.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system-prompt.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai/src/system-prompt/system-prompt.ts"],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"system-prompt.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai/src/system-prompt/system-prompt.ts"],"mappings":";;;;;;AA6DA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2F4C;AAa5C;;;;;;;;;;;cAxGa,YAAA,YAAwB,oBAAA;EAAA,SAEjB,MAAA,WAAiB,yBAAA;cAAjB,MAAA,YAAiB,yBAAA;EAiH1B;;;AAA2B;AAuDtC;;;;AAGC;;;;;;;;;;;;;;;;;EA1DU,OArFK,QAAA,CAAS,IAAA,WAAe,YAAA;;;;;;;;;EAyB/B,OAAA,CAAQ,KAAA,EAAO,eAAA,YAA2B,oBAAA;;;;;;;EAsB1C,WAAA,CACL,KAAA,EAAO,mBAAA,YACN,oBAAA;;;;;;;EAYI,OAAA,CAAQ,YAAA,GAAe,YAAA;AAAA;;;;;;UAaf,mBAAA;EAAA,CACd,KAAA,YAAiB,aAAA,CAAc,yBAAA,IAA6B,YAAA;;;;;;;;;EAU7D,QAAA,CAAS,IAAA,WAAe,YAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAuDb,YAAA,EAAc,mBAG1B"}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
import { InvalidRequestError } from "../errors/invalid-request-error.mjs";
|
|
2
|
+
import "../errors/index.mjs";
|
|
1
3
|
import { Instruction } from "./instruction.mjs";
|
|
2
4
|
import { Persona } from "./persona.mjs";
|
|
5
|
+
import { readFileSync } from "node:fs";
|
|
3
6
|
|
|
4
7
|
//#region ../@warlock.js/ai/src/system-prompt/system-prompt.ts
|
|
5
8
|
/**
|
|
@@ -56,6 +59,43 @@ var SystemPrompt = class SystemPrompt {
|
|
|
56
59
|
this.blocks = blocks;
|
|
57
60
|
}
|
|
58
61
|
/**
|
|
62
|
+
* Build a system prompt by reading the file at `path` once, synchronously,
|
|
63
|
+
* at construction time. The file's UTF-8 contents seed a single instruction
|
|
64
|
+
* block — the same semantics as the string-seed form of `systemPrompt()` —
|
|
65
|
+
* so placeholders inside the file (`{{language|English}}`) resolve at
|
|
66
|
+
* `resolve()` time and the result can be forked with further
|
|
67
|
+
* `.persona()` / `.instruction()` calls.
|
|
68
|
+
*
|
|
69
|
+
* One-shot by design: the file is read exactly once here, never re-read on
|
|
70
|
+
* `resolve()`. Reads are synchronous so the call stays a drop-in for the
|
|
71
|
+
* synchronous `systemPrompt()` factory and the synchronous `resolve()` API.
|
|
72
|
+
*
|
|
73
|
+
* Throws `InvalidRequestError` when the file cannot be read (missing path,
|
|
74
|
+
* permission denied) — surfacing the underlying cause so a typo in the
|
|
75
|
+
* prompt path fails loudly at construction instead of silently producing an
|
|
76
|
+
* empty prompt.
|
|
77
|
+
*
|
|
78
|
+
* @param path - Filesystem path to the prompt template file.
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* const prompt = SystemPrompt.fromFile("./prompts/support-agent.md");
|
|
82
|
+
*
|
|
83
|
+
* const localized = prompt.instruction("Respond in {{language|English}}.");
|
|
84
|
+
* localized.resolve({ language: "Arabic" });
|
|
85
|
+
*/
|
|
86
|
+
static fromFile(path) {
|
|
87
|
+
let contents;
|
|
88
|
+
try {
|
|
89
|
+
contents = readFileSync(path, "utf8");
|
|
90
|
+
} catch (error) {
|
|
91
|
+
throw new InvalidRequestError(`Failed to read system prompt file "${path}" — ${error instanceof Error ? error.message : String(error)}`, {
|
|
92
|
+
context: { path },
|
|
93
|
+
cause: error
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
return new SystemPrompt([new Instruction(contents)]);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
59
99
|
* Return a new builder with the persona block set. If a persona already
|
|
60
100
|
* exists it's replaced in place (preserving its position in `blocks`);
|
|
61
101
|
* otherwise the new persona is prepended so persona-first remains the
|
|
@@ -93,6 +133,11 @@ var SystemPrompt = class SystemPrompt {
|
|
|
93
133
|
return this.blocks.map((block) => block.resolve(placeholders)).join("\n\n").trim();
|
|
94
134
|
}
|
|
95
135
|
};
|
|
136
|
+
function systemPromptFactory(input) {
|
|
137
|
+
if (input === void 0) return new SystemPrompt();
|
|
138
|
+
if (typeof input === "string") return new SystemPrompt([new Instruction(input)]);
|
|
139
|
+
return new SystemPrompt([...input]);
|
|
140
|
+
}
|
|
96
141
|
/**
|
|
97
142
|
* Create a new immutable system-prompt builder.
|
|
98
143
|
*
|
|
@@ -100,10 +145,11 @@ var SystemPrompt = class SystemPrompt {
|
|
|
100
145
|
* free of `new` and consistent with `ai.tool()`, `ai.agent()`,
|
|
101
146
|
* `ai.persona()`, `ai.instruction()`.
|
|
102
147
|
*
|
|
103
|
-
*
|
|
148
|
+
* Input forms:
|
|
104
149
|
* - No argument → empty builder, chain `.persona()` / `.instruction()`
|
|
105
150
|
* - Single string → seeded with one instruction for quick one-shot prompts
|
|
106
151
|
* - Array of blocks → used verbatim, preserving insertion order
|
|
152
|
+
* - `.fromFile(path)` → seeded from a file read once at construction
|
|
107
153
|
*
|
|
108
154
|
* @example
|
|
109
155
|
* // Composed builder
|
|
@@ -119,6 +165,10 @@ var SystemPrompt = class SystemPrompt {
|
|
|
119
165
|
* const prompt = systemPrompt("Answer only with JSON matching the schema.");
|
|
120
166
|
*
|
|
121
167
|
* @example
|
|
168
|
+
* // From a file, read once at construction
|
|
169
|
+
* const prompt = systemPrompt.fromFile("./prompts/support-agent.md");
|
|
170
|
+
*
|
|
171
|
+
* @example
|
|
122
172
|
* // Array form — fully declarative
|
|
123
173
|
* const prompt = systemPrompt([
|
|
124
174
|
* ai.persona("You are Alex."),
|
|
@@ -126,11 +176,7 @@ var SystemPrompt = class SystemPrompt {
|
|
|
126
176
|
* ai.instruction("Respond in {{language|English}}."),
|
|
127
177
|
* ]);
|
|
128
178
|
*/
|
|
129
|
-
|
|
130
|
-
if (input === void 0) return new SystemPrompt();
|
|
131
|
-
if (typeof input === "string") return new SystemPrompt([new Instruction(input)]);
|
|
132
|
-
return new SystemPrompt([...input]);
|
|
133
|
-
}
|
|
179
|
+
const systemPrompt = Object.assign(systemPromptFactory, { fromFile: SystemPrompt.fromFile });
|
|
134
180
|
|
|
135
181
|
//#endregion
|
|
136
182
|
export { SystemPrompt, systemPrompt };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system-prompt.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/system-prompt/system-prompt.ts"],"sourcesContent":["import type { Placeholders } from \"../contracts/placeholders.type\";\nimport type {\n InstructionContract,\n PersonaContract,\n SystemPromptBlockContract,\n SystemPromptContract,\n} from \"../contracts/system-prompt.contract\";\nimport { Instruction } from \"./instruction\";\nimport { Persona } from \"./persona\";\n\n/**\n * Concrete `SystemPromptContract` — an immutable layered prompt builder.\n *\n * **Role.** The top-level composer for a system prompt: it holds an ordered\n * list of typed blocks (persona + instructions) and resolves the whole\n * stack into one final string when the agent is about to call the model.\n *\n * **Responsibility.**\n * - Owns: the ordered `blocks` list and the block-join rules (insertion\n * order, blank-line separator, trim).\n * - Does NOT own: how any individual block is rendered (delegated to each\n * block's `resolve()`), the placeholder syntax (delegated to\n * `renderPlaceholders`), or any knowledge of the agent, model, or\n * session consuming the resolved text.\n *\n * Blocks are discriminated by a string `type` tag (`\"persona\"` /\n * `\"instruction\"`) rather than `instanceof`, so user-supplied blocks that\n * implement `SystemPromptBlockContract` interoperate seamlessly with blocks\n * built via `ai.persona()` / `ai.instruction()` — even across duplicate\n * package copies or bundler scope boundaries.\n *\n * The builder is **immutable** — every `.persona()` / `.instruction()`\n * call returns a fresh `SystemPrompt` instance sharing nothing mutable\n * with its parent. This makes forking a base prompt into specialized\n * variants a safe, side-effect-free operation.\n *\n * Users construct via the `ai.systemPrompt()` factory — `new SystemPrompt()`\n * is not the public API (see §4.2 of code-style.md). Modeled as a class so\n * that methods live on the prototype (one copy shared across every forked\n * instance) and downstream code can branch via `instanceof SystemPrompt`.\n *\n * @example\n * // Chainable form\n * const alex = ai.persona(\"You are Alex, a TypeScript expert.\");\n * const replyIn = ai.instruction(\"Respond in {{language|English}}.\");\n *\n * const base = ai.systemPrompt().persona(alex).instruction(replyIn);\n * const arabicVariant = base.instruction(\"Prefer Arabic comments.\");\n *\n * base.resolve({ language: \"English\" });\n * arabicVariant.resolve({ language: \"Arabic\" });\n *\n * @example\n * // Array form — insertion order is preserved exactly\n * const prompt = ai.systemPrompt([\n * ai.persona(\"You are Alex, a TypeScript expert.\"),\n * ai.instruction(\"Respond in {{language|English}}.\"),\n * ]);\n */\nexport class SystemPrompt implements SystemPromptContract {\n public constructor(\n public readonly blocks: readonly SystemPromptBlockContract[] = [],\n ) {}\n\n /**\n * Return a new builder with the persona block set. If a persona already\n * exists it's replaced in place (preserving its position in `blocks`);\n * otherwise the new persona is prepended so persona-first remains the\n * default for chain-built prompts. Accepts either raw text (auto-wrapped\n * via `new Persona`) or an existing `PersonaContract` instance for reuse\n * across prompts.\n */\n public persona(value: PersonaContract | string): SystemPromptContract {\n const block = typeof value === \"string\" ? new Persona(value) : value;\n const existingIndex = this.blocks.findIndex(\n candidate => candidate.type === \"persona\",\n );\n\n if (existingIndex >= 0) {\n const next = [...this.blocks];\n next[existingIndex] = block;\n\n return new SystemPrompt(next) as this;\n }\n\n return new SystemPrompt([block, ...this.blocks]);\n }\n\n /**\n * Return a new builder with the given instruction appended. Instructions\n * render in insertion order. Accepts either raw text (auto-wrapped via\n * `new Instruction`) or an existing `InstructionContract` instance for\n * cross-prompt reuse.\n */\n public instruction(\n value: InstructionContract | string,\n ): SystemPromptContract {\n const block = typeof value === \"string\" ? new Instruction(value) : value;\n\n return new SystemPrompt([...this.blocks, block]);\n }\n\n /**\n * Resolve every block against the placeholder map, join the results with\n * blank-line separators (in insertion order), and trim. Returns an empty\n * string when no blocks are present — callers treat that as \"no system\n * message\".\n */\n public resolve(placeholders?: Placeholders): string {\n return this.blocks\n .map(block => block.resolve(placeholders))\n .join(\"\\n\\n\")\n .trim();\n }\n}\n\n/**\n * Create a new immutable system-prompt builder.\n *\n * **Role.** Public factory for `SystemPrompt` — keeps user-facing code\n * free of `new` and consistent with `ai.tool()`, `ai.agent()`,\n * `ai.persona()`, `ai.instruction()`.\n *\n * Three input forms:\n * - No argument → empty builder, chain `.persona()` / `.instruction()`\n * - Single string → seeded with one instruction for quick one-shot prompts\n * - Array of blocks → used verbatim, preserving insertion order\n *\n * @example\n * // Composed builder\n * const prompt = systemPrompt()\n * .persona(\"You are Alex, a senior TypeScript engineer.\")\n * .instruction(\"Always include working code examples.\")\n * .instruction(\"Respond in {{language|English}}.\");\n *\n * prompt.resolve({ language: \"Arabic\" });\n *\n * @example\n * // One-shot seed\n * const prompt = systemPrompt(\"Answer only with JSON matching the schema.\");\n *\n * @example\n * // Array form — fully declarative\n * const prompt = systemPrompt([\n * ai.persona(\"You are Alex.\"),\n * ai.instruction(\"Always cite sources.\"),\n * ai.instruction(\"Respond in {{language|English}}.\"),\n * ]);\n */\nexport function systemPrompt(\n input?: string | ReadonlyArray<SystemPromptBlockContract>,\n): SystemPrompt {\n if (input === undefined) {\n return new SystemPrompt();\n }\n\n if (typeof input === \"string\") {\n return new SystemPrompt([new Instruction(input)]);\n }\n\n return new SystemPrompt([...input]);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2DA,IAAa,eAAb,MAAa,aAA6C;CACxD,AAAO,YACL,AAAgB,SAA+C,CAAC,GAChE;EADgB;CACf;;;;;;;;;CAUH,AAAO,QAAQ,OAAuD;EACpE,MAAM,QAAQ,OAAO,UAAU,WAAW,IAAI,QAAQ,KAAK,IAAI;EAC/D,MAAM,gBAAgB,KAAK,OAAO,WAChC,cAAa,UAAU,SAAS,SAClC;EAEA,IAAI,iBAAiB,GAAG;GACtB,MAAM,OAAO,CAAC,GAAG,KAAK,MAAM;GAC5B,KAAK,iBAAiB;GAEtB,OAAO,IAAI,aAAa,IAAI;EAC9B;EAEA,OAAO,IAAI,aAAa,CAAC,OAAO,GAAG,KAAK,MAAM,CAAC;CACjD;;;;;;;CAQA,AAAO,YACL,OACsB;EACtB,MAAM,QAAQ,OAAO,UAAU,WAAW,IAAI,YAAY,KAAK,IAAI;EAEnE,OAAO,IAAI,aAAa,CAAC,GAAG,KAAK,QAAQ,KAAK,CAAC;CACjD;;;;;;;CAQA,AAAO,QAAQ,cAAqC;EAClD,OAAO,KAAK,OACT,KAAI,UAAS,MAAM,QAAQ,YAAY,CAAC,CAAC,CACzC,KAAK,MAAM,CAAC,CACZ,KAAK;CACV;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmCA,SAAgB,aACd,OACc;CACd,IAAI,UAAU,QACZ,OAAO,IAAI,aAAa;CAG1B,IAAI,OAAO,UAAU,UACnB,OAAO,IAAI,aAAa,CAAC,IAAI,YAAY,KAAK,CAAC,CAAC;CAGlD,OAAO,IAAI,aAAa,CAAC,GAAG,KAAK,CAAC;AACpC"}
|
|
1
|
+
{"version":3,"file":"system-prompt.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/system-prompt/system-prompt.ts"],"sourcesContent":["import { readFileSync } from \"node:fs\";\nimport type { Placeholders } from \"../contracts/placeholders.type\";\nimport type {\n InstructionContract,\n PersonaContract,\n SystemPromptBlockContract,\n SystemPromptContract,\n} from \"../contracts/system-prompt.contract\";\nimport { InvalidRequestError } from \"../errors\";\nimport { Instruction } from \"./instruction\";\nimport { Persona } from \"./persona\";\n\n/**\n * Concrete `SystemPromptContract` — an immutable layered prompt builder.\n *\n * **Role.** The top-level composer for a system prompt: it holds an ordered\n * list of typed blocks (persona + instructions) and resolves the whole\n * stack into one final string when the agent is about to call the model.\n *\n * **Responsibility.**\n * - Owns: the ordered `blocks` list and the block-join rules (insertion\n * order, blank-line separator, trim).\n * - Does NOT own: how any individual block is rendered (delegated to each\n * block's `resolve()`), the placeholder syntax (delegated to\n * `renderPlaceholders`), or any knowledge of the agent, model, or\n * session consuming the resolved text.\n *\n * Blocks are discriminated by a string `type` tag (`\"persona\"` /\n * `\"instruction\"`) rather than `instanceof`, so user-supplied blocks that\n * implement `SystemPromptBlockContract` interoperate seamlessly with blocks\n * built via `ai.persona()` / `ai.instruction()` — even across duplicate\n * package copies or bundler scope boundaries.\n *\n * The builder is **immutable** — every `.persona()` / `.instruction()`\n * call returns a fresh `SystemPrompt` instance sharing nothing mutable\n * with its parent. This makes forking a base prompt into specialized\n * variants a safe, side-effect-free operation.\n *\n * Users construct via the `ai.systemPrompt()` factory — `new SystemPrompt()`\n * is not the public API (see §4.2 of code-style.md). Modeled as a class so\n * that methods live on the prototype (one copy shared across every forked\n * instance) and downstream code can branch via `instanceof SystemPrompt`.\n *\n * @example\n * // Chainable form\n * const alex = ai.persona(\"You are Alex, a TypeScript expert.\");\n * const replyIn = ai.instruction(\"Respond in {{language|English}}.\");\n *\n * const base = ai.systemPrompt().persona(alex).instruction(replyIn);\n * const arabicVariant = base.instruction(\"Prefer Arabic comments.\");\n *\n * base.resolve({ language: \"English\" });\n * arabicVariant.resolve({ language: \"Arabic\" });\n *\n * @example\n * // Array form — insertion order is preserved exactly\n * const prompt = ai.systemPrompt([\n * ai.persona(\"You are Alex, a TypeScript expert.\"),\n * ai.instruction(\"Respond in {{language|English}}.\"),\n * ]);\n */\nexport class SystemPrompt implements SystemPromptContract {\n public constructor(\n public readonly blocks: readonly SystemPromptBlockContract[] = [],\n ) {}\n\n /**\n * Build a system prompt by reading the file at `path` once, synchronously,\n * at construction time. The file's UTF-8 contents seed a single instruction\n * block — the same semantics as the string-seed form of `systemPrompt()` —\n * so placeholders inside the file (`{{language|English}}`) resolve at\n * `resolve()` time and the result can be forked with further\n * `.persona()` / `.instruction()` calls.\n *\n * One-shot by design: the file is read exactly once here, never re-read on\n * `resolve()`. Reads are synchronous so the call stays a drop-in for the\n * synchronous `systemPrompt()` factory and the synchronous `resolve()` API.\n *\n * Throws `InvalidRequestError` when the file cannot be read (missing path,\n * permission denied) — surfacing the underlying cause so a typo in the\n * prompt path fails loudly at construction instead of silently producing an\n * empty prompt.\n *\n * @param path - Filesystem path to the prompt template file.\n *\n * @example\n * const prompt = SystemPrompt.fromFile(\"./prompts/support-agent.md\");\n *\n * const localized = prompt.instruction(\"Respond in {{language|English}}.\");\n * localized.resolve({ language: \"Arabic\" });\n */\n public static fromFile(path: string): SystemPrompt {\n let contents: string;\n\n try {\n contents = readFileSync(path, \"utf8\");\n } catch (error) {\n throw new InvalidRequestError(\n `Failed to read system prompt file \"${path}\" — ${\n error instanceof Error ? error.message : String(error)\n }`,\n { context: { path }, cause: error },\n );\n }\n\n return new SystemPrompt([new Instruction(contents)]);\n }\n\n /**\n * Return a new builder with the persona block set. If a persona already\n * exists it's replaced in place (preserving its position in `blocks`);\n * otherwise the new persona is prepended so persona-first remains the\n * default for chain-built prompts. Accepts either raw text (auto-wrapped\n * via `new Persona`) or an existing `PersonaContract` instance for reuse\n * across prompts.\n */\n public persona(value: PersonaContract | string): SystemPromptContract {\n const block = typeof value === \"string\" ? new Persona(value) : value;\n const existingIndex = this.blocks.findIndex(\n candidate => candidate.type === \"persona\",\n );\n\n if (existingIndex >= 0) {\n const next = [...this.blocks];\n next[existingIndex] = block;\n\n return new SystemPrompt(next) as this;\n }\n\n return new SystemPrompt([block, ...this.blocks]);\n }\n\n /**\n * Return a new builder with the given instruction appended. Instructions\n * render in insertion order. Accepts either raw text (auto-wrapped via\n * `new Instruction`) or an existing `InstructionContract` instance for\n * cross-prompt reuse.\n */\n public instruction(\n value: InstructionContract | string,\n ): SystemPromptContract {\n const block = typeof value === \"string\" ? new Instruction(value) : value;\n\n return new SystemPrompt([...this.blocks, block]);\n }\n\n /**\n * Resolve every block against the placeholder map, join the results with\n * blank-line separators (in insertion order), and trim. Returns an empty\n * string when no blocks are present — callers treat that as \"no system\n * message\".\n */\n public resolve(placeholders?: Placeholders): string {\n return this.blocks\n .map(block => block.resolve(placeholders))\n .join(\"\\n\\n\")\n .trim();\n }\n}\n\n/**\n * Public factory for `SystemPrompt`, callable directly or via its\n * `fromFile` static. Exists as a named interface so the callable signature\n * and the `fromFile` attachment travel together as one public type.\n */\nexport interface SystemPromptFactory {\n (input?: string | ReadonlyArray<SystemPromptBlockContract>): SystemPrompt;\n\n /**\n * Build a system prompt from a file read once at construction. Delegates\n * to {@link SystemPrompt.fromFile}, so `ai.systemPrompt.fromFile(path)` and\n * `SystemPrompt.fromFile(path)` behave identically.\n *\n * @example\n * const prompt = ai.systemPrompt.fromFile(\"./prompts/support-agent.md\");\n */\n fromFile(path: string): SystemPrompt;\n}\n\nfunction systemPromptFactory(\n input?: string | ReadonlyArray<SystemPromptBlockContract>,\n): SystemPrompt {\n if (input === undefined) {\n return new SystemPrompt();\n }\n\n if (typeof input === \"string\") {\n return new SystemPrompt([new Instruction(input)]);\n }\n\n return new SystemPrompt([...input]);\n}\n\n/**\n * Create a new immutable system-prompt builder.\n *\n * **Role.** Public factory for `SystemPrompt` — keeps user-facing code\n * free of `new` and consistent with `ai.tool()`, `ai.agent()`,\n * `ai.persona()`, `ai.instruction()`.\n *\n * Input forms:\n * - No argument → empty builder, chain `.persona()` / `.instruction()`\n * - Single string → seeded with one instruction for quick one-shot prompts\n * - Array of blocks → used verbatim, preserving insertion order\n * - `.fromFile(path)` → seeded from a file read once at construction\n *\n * @example\n * // Composed builder\n * const prompt = systemPrompt()\n * .persona(\"You are Alex, a senior TypeScript engineer.\")\n * .instruction(\"Always include working code examples.\")\n * .instruction(\"Respond in {{language|English}}.\");\n *\n * prompt.resolve({ language: \"Arabic\" });\n *\n * @example\n * // One-shot seed\n * const prompt = systemPrompt(\"Answer only with JSON matching the schema.\");\n *\n * @example\n * // From a file, read once at construction\n * const prompt = systemPrompt.fromFile(\"./prompts/support-agent.md\");\n *\n * @example\n * // Array form — fully declarative\n * const prompt = systemPrompt([\n * ai.persona(\"You are Alex.\"),\n * ai.instruction(\"Always cite sources.\"),\n * ai.instruction(\"Respond in {{language|English}}.\"),\n * ]);\n */\nexport const systemPrompt: SystemPromptFactory = Object.assign(\n systemPromptFactory,\n { fromFile: SystemPrompt.fromFile },\n);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6DA,IAAa,eAAb,MAAa,aAA6C;CACxD,AAAO,YACL,AAAgB,SAA+C,CAAC,GAChE;EADgB;CACf;;;;;;;;;;;;;;;;;;;;;;;;;;CA2BH,OAAc,SAAS,MAA4B;EACjD,IAAI;EAEJ,IAAI;GACF,WAAW,aAAa,MAAM,MAAM;EACtC,SAAS,OAAO;GACd,MAAM,IAAI,oBACR,sCAAsC,KAAK,MACzC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,KAEvD;IAAE,SAAS,EAAE,KAAK;IAAG,OAAO;GAAM,CACpC;EACF;EAEA,OAAO,IAAI,aAAa,CAAC,IAAI,YAAY,QAAQ,CAAC,CAAC;CACrD;;;;;;;;;CAUA,AAAO,QAAQ,OAAuD;EACpE,MAAM,QAAQ,OAAO,UAAU,WAAW,IAAI,QAAQ,KAAK,IAAI;EAC/D,MAAM,gBAAgB,KAAK,OAAO,WAChC,cAAa,UAAU,SAAS,SAClC;EAEA,IAAI,iBAAiB,GAAG;GACtB,MAAM,OAAO,CAAC,GAAG,KAAK,MAAM;GAC5B,KAAK,iBAAiB;GAEtB,OAAO,IAAI,aAAa,IAAI;EAC9B;EAEA,OAAO,IAAI,aAAa,CAAC,OAAO,GAAG,KAAK,MAAM,CAAC;CACjD;;;;;;;CAQA,AAAO,YACL,OACsB;EACtB,MAAM,QAAQ,OAAO,UAAU,WAAW,IAAI,YAAY,KAAK,IAAI;EAEnE,OAAO,IAAI,aAAa,CAAC,GAAG,KAAK,QAAQ,KAAK,CAAC;CACjD;;;;;;;CAQA,AAAO,QAAQ,cAAqC;EAClD,OAAO,KAAK,OACT,KAAI,UAAS,MAAM,QAAQ,YAAY,CAAC,CAAC,CACzC,KAAK,MAAM,CAAC,CACZ,KAAK;CACV;AACF;AAqBA,SAAS,oBACP,OACc;CACd,IAAI,UAAU,QACZ,OAAO,IAAI,aAAa;CAG1B,IAAI,OAAO,UAAU,UACnB,OAAO,IAAI,aAAa,CAAC,IAAI,YAAY,KAAK,CAAC,CAAC;CAGlD,OAAO,IAAI,aAAa,CAAC,GAAG,KAAK,CAAC;AACpC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwCA,MAAa,eAAoC,OAAO,OACtD,qBACA,EAAE,UAAU,aAAa,SAAS,CACpC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { BaseReport } from "../contracts/result/base-report.type.mjs";
|
|
2
|
+
import { END } from "../contracts/end.type.mjs";
|
|
3
|
+
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
4
|
+
|
|
5
|
+
//#region ../@warlock.js/ai/src/testing/matcher-logic.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* Normalized matcher verdict — the library-agnostic shape every
|
|
8
|
+
* matcher in this module returns. Vitest's `expect.extend` consumes
|
|
9
|
+
* the same `{ pass, message }` contract, so the registration layer
|
|
10
|
+
* forwards these verbatim.
|
|
11
|
+
*/
|
|
12
|
+
type MatcherVerdict = {
|
|
13
|
+
/** Whether the assertion passed. */pass: boolean; /** Lazy message factory — Vitest calls it only when reporting. */
|
|
14
|
+
message: () => string;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Any unified result envelope a matcher can be handed. Accepts the
|
|
18
|
+
* full `{ report, ... }` result or a bare `BaseReport` so callers can
|
|
19
|
+
* assert against either `await x.execute()` or `result.report`.
|
|
20
|
+
*/
|
|
21
|
+
type ReportLike = BaseReport | {
|
|
22
|
+
report: BaseReport;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Assert that a supervisor routed to (dispatched) the named intent at
|
|
26
|
+
* least once across its iterations. Targets a `SupervisorResult` or a
|
|
27
|
+
* `SupervisorReport`.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* expect(await supervisor.execute(input)).toRouteTo("critic");
|
|
31
|
+
*/
|
|
32
|
+
declare function matchRouteTo(received: ReportLike, intent: string): MatcherVerdict;
|
|
33
|
+
/**
|
|
34
|
+
* Assert that a supervisor converged — terminated on its own decision
|
|
35
|
+
* (`router` / `route` / `evaluate` / `classifier`) with a
|
|
36
|
+
* `"completed"` status, rather than hitting the iteration cap, being
|
|
37
|
+
* cancelled, or erroring. Targets a `SupervisorResult` or
|
|
38
|
+
* `SupervisorReport`.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* expect(await supervisor.execute(input)).toConverge();
|
|
42
|
+
*/
|
|
43
|
+
declare function matchConverge(received: ReportLike): MatcherVerdict;
|
|
44
|
+
/**
|
|
45
|
+
* Assert that a workflow step completed successfully. Targets a
|
|
46
|
+
* `WorkflowResult` or `WorkflowReport`; looks the step up by name in
|
|
47
|
+
* `report.steps` and checks its status is `"completed"`.
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* expect(await workflow.execute(input)).toPassStep("draft");
|
|
51
|
+
*/
|
|
52
|
+
declare function matchPassStep(received: ReportLike, stepName: string): MatcherVerdict;
|
|
53
|
+
/**
|
|
54
|
+
* Result envelope carrying a typed `data` payload — what
|
|
55
|
+
* `matchOutputShape` validates against a schema.
|
|
56
|
+
*/
|
|
57
|
+
type DataResult = {
|
|
58
|
+
data?: unknown;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Assert that a result's `data` validates against a Standard Schema.
|
|
62
|
+
* Targets any result envelope with a `data` field (agent / workflow /
|
|
63
|
+
* supervisor). Runs the schema's `~standard.validate` and passes only
|
|
64
|
+
* when it reports no issues.
|
|
65
|
+
*
|
|
66
|
+
* Synchronous-only: a schema whose `validate` returns a Promise is
|
|
67
|
+
* rejected with a clear message rather than silently passing — the
|
|
68
|
+
* async variant belongs on a dedicated async matcher if needed.
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* expect(await agent.execute(input, { output: schema })).toOutputShape(schema);
|
|
72
|
+
*/
|
|
73
|
+
declare function matchOutputShape(received: DataResult, schema: StandardSchemaV1): MatcherVerdict;
|
|
74
|
+
//#endregion
|
|
75
|
+
export { MatcherVerdict, matchConverge, matchOutputShape, matchPassStep, matchRouteTo };
|
|
76
|
+
//# sourceMappingURL=matcher-logic.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"matcher-logic.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai/src/testing/matcher-logic.ts"],"mappings":";;;;;;;AAYA;;;;KAAY,cAAA;EAYP,oCAVH,IAAA;EAEA,OAAO;AAAA;;;;AAQ0C;AAgDnD;KAhDK,UAAA,GAAa,UAAA;EAAe,MAAA,EAAQ,UAAU;AAAA;;;;;;AAgD+B;AAkClF;;iBAlCgB,YAAA,CAAa,QAAA,EAAU,UAAA,EAAY,MAAA,WAAiB,cAAc;;;;;;AAkCf;AAkCnE;;;;iBAlCgB,aAAA,CAAc,QAAA,EAAU,UAAA,GAAa,cAAc;;;;;AAkCkB;AAgCpF;;;iBAhCe,aAAA,CAAc,QAAA,EAAU,UAAA,EAAY,QAAA,WAAmB,cAAc;AAsC7D;AAexB;;;AAfwB,KAAnB,UAAA;EAAe,IAAI;AAAA;;;;;;;;;AAkBP;;;;;iBAHD,gBAAA,CACd,QAAA,EAAU,UAAA,EACV,MAAA,EAAQ,gBAAA,GACP,cAAA"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { END } from "../contracts/end.type.mjs";
|
|
2
|
+
|
|
3
|
+
//#region ../@warlock.js/ai/src/testing/matcher-logic.ts
|
|
4
|
+
/**
|
|
5
|
+
* Coerce a matcher target into its `BaseReport`. Accepts the result
|
|
6
|
+
* envelope (`{ report }`) or a report directly.
|
|
7
|
+
*/
|
|
8
|
+
function toReport(received) {
|
|
9
|
+
if ("report" in received && received.report) return received.report;
|
|
10
|
+
return received;
|
|
11
|
+
}
|
|
12
|
+
/** Narrow a `BaseReport` to a `SupervisorReport` by its discriminator. */
|
|
13
|
+
function asSupervisorReport(report) {
|
|
14
|
+
return report.type === "supervisor" ? report : void 0;
|
|
15
|
+
}
|
|
16
|
+
/** Narrow a `BaseReport` to a `WorkflowReport` by its discriminator. */
|
|
17
|
+
function asWorkflowReport(report) {
|
|
18
|
+
return report.type === "workflow" ? report : void 0;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Collect every intent name dispatched by a supervisor across all
|
|
22
|
+
* iterations — the keys of each iteration snapshot's `result` record.
|
|
23
|
+
*/
|
|
24
|
+
function dispatchedIntents(report) {
|
|
25
|
+
const intents = /* @__PURE__ */ new Set();
|
|
26
|
+
for (const snapshot of report.snapshots) for (const intent of Object.keys(snapshot.result)) intents.add(intent);
|
|
27
|
+
return [...intents];
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Assert that a supervisor routed to (dispatched) the named intent at
|
|
31
|
+
* least once across its iterations. Targets a `SupervisorResult` or a
|
|
32
|
+
* `SupervisorReport`.
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* expect(await supervisor.execute(input)).toRouteTo("critic");
|
|
36
|
+
*/
|
|
37
|
+
function matchRouteTo(received, intent) {
|
|
38
|
+
const report = toReport(received);
|
|
39
|
+
const supervisorReport = asSupervisorReport(report);
|
|
40
|
+
if (!supervisorReport) return {
|
|
41
|
+
pass: false,
|
|
42
|
+
message: () => `toRouteTo expects a supervisor result, but received a "${report.type}" report`
|
|
43
|
+
};
|
|
44
|
+
const intents = dispatchedIntents(supervisorReport);
|
|
45
|
+
const pass = intents.includes(intent);
|
|
46
|
+
return {
|
|
47
|
+
pass,
|
|
48
|
+
message: () => pass ? `expected supervisor not to route to "${intent}", but it did` : `expected supervisor to route to "${intent}", but it routed to [${intents.join(", ")}]`
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Assert that a supervisor converged — terminated on its own decision
|
|
53
|
+
* (`router` / `route` / `evaluate` / `classifier`) with a
|
|
54
|
+
* `"completed"` status, rather than hitting the iteration cap, being
|
|
55
|
+
* cancelled, or erroring. Targets a `SupervisorResult` or
|
|
56
|
+
* `SupervisorReport`.
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* expect(await supervisor.execute(input)).toConverge();
|
|
60
|
+
*/
|
|
61
|
+
function matchConverge(received) {
|
|
62
|
+
const report = toReport(received);
|
|
63
|
+
const supervisorReport = asSupervisorReport(report);
|
|
64
|
+
if (!supervisorReport) return {
|
|
65
|
+
pass: false,
|
|
66
|
+
message: () => `toConverge expects a supervisor result, but received a "${report.type}" report`
|
|
67
|
+
};
|
|
68
|
+
const nonConvergent = new Set([
|
|
69
|
+
"max-iterations",
|
|
70
|
+
"cancelled",
|
|
71
|
+
"error"
|
|
72
|
+
]);
|
|
73
|
+
const pass = supervisorReport.status === "completed" && !nonConvergent.has(supervisorReport.terminatedBy);
|
|
74
|
+
return {
|
|
75
|
+
pass,
|
|
76
|
+
message: () => pass ? `expected supervisor not to converge, but it terminated via "${supervisorReport.terminatedBy}"` : `expected supervisor to converge, but status="${supervisorReport.status}" terminatedBy="${supervisorReport.terminatedBy}" after ${supervisorReport.iterations} iteration(s)`
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Assert that a workflow step completed successfully. Targets a
|
|
81
|
+
* `WorkflowResult` or `WorkflowReport`; looks the step up by name in
|
|
82
|
+
* `report.steps` and checks its status is `"completed"`.
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* expect(await workflow.execute(input)).toPassStep("draft");
|
|
86
|
+
*/
|
|
87
|
+
function matchPassStep(received, stepName) {
|
|
88
|
+
const report = toReport(received);
|
|
89
|
+
const workflowReport = asWorkflowReport(report);
|
|
90
|
+
if (!workflowReport) return {
|
|
91
|
+
pass: false,
|
|
92
|
+
message: () => `toPassStep expects a workflow result, but received a "${report.type}" report`
|
|
93
|
+
};
|
|
94
|
+
const step = workflowReport.steps[stepName];
|
|
95
|
+
if (!step) {
|
|
96
|
+
const known = Object.keys(workflowReport.steps).join(", ");
|
|
97
|
+
return {
|
|
98
|
+
pass: false,
|
|
99
|
+
message: () => `expected workflow to have a step "${stepName}", but steps are [${known}]`
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
const pass = step.status === "completed";
|
|
103
|
+
return {
|
|
104
|
+
pass,
|
|
105
|
+
message: () => pass ? `expected step "${stepName}" not to pass, but it completed` : `expected step "${stepName}" to pass, but its status was "${step.status}"`
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Assert that a result's `data` validates against a Standard Schema.
|
|
110
|
+
* Targets any result envelope with a `data` field (agent / workflow /
|
|
111
|
+
* supervisor). Runs the schema's `~standard.validate` and passes only
|
|
112
|
+
* when it reports no issues.
|
|
113
|
+
*
|
|
114
|
+
* Synchronous-only: a schema whose `validate` returns a Promise is
|
|
115
|
+
* rejected with a clear message rather than silently passing — the
|
|
116
|
+
* async variant belongs on a dedicated async matcher if needed.
|
|
117
|
+
*
|
|
118
|
+
* @example
|
|
119
|
+
* expect(await agent.execute(input, { output: schema })).toOutputShape(schema);
|
|
120
|
+
*/
|
|
121
|
+
function matchOutputShape(received, schema) {
|
|
122
|
+
const data = received.data;
|
|
123
|
+
if (data === void 0) return {
|
|
124
|
+
pass: false,
|
|
125
|
+
message: () => "toOutputShape expected result.data to be defined, but it was undefined"
|
|
126
|
+
};
|
|
127
|
+
const validation = schema["~standard"].validate(data);
|
|
128
|
+
if (validation instanceof Promise) return {
|
|
129
|
+
pass: false,
|
|
130
|
+
message: () => "toOutputShape received an async schema; use a synchronous Standard Schema for this matcher"
|
|
131
|
+
};
|
|
132
|
+
const pass = validation.issues === void 0;
|
|
133
|
+
return {
|
|
134
|
+
pass,
|
|
135
|
+
message: () => {
|
|
136
|
+
if (pass) return "expected result.data not to match the schema, but it did";
|
|
137
|
+
return `expected result.data to match the schema, but validation failed: ${(validation.issues ?? []).map((issue) => issue.message).join("; ")}`;
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
//#endregion
|
|
143
|
+
export { matchConverge, matchOutputShape, matchPassStep, matchRouteTo };
|
|
144
|
+
//# sourceMappingURL=matcher-logic.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"matcher-logic.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/testing/matcher-logic.ts"],"sourcesContent":["import type { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport { END } from \"../contracts/end.type\";\nimport type { BaseReport } from \"../contracts/result/base-report.type\";\nimport type { SupervisorReport } from \"../contracts/result/supervisor-result.type\";\nimport type { WorkflowReport } from \"../contracts/result/workflow-result.type\";\n\n/**\n * Normalized matcher verdict — the library-agnostic shape every\n * matcher in this module returns. Vitest's `expect.extend` consumes\n * the same `{ pass, message }` contract, so the registration layer\n * forwards these verbatim.\n */\nexport type MatcherVerdict = {\n /** Whether the assertion passed. */\n pass: boolean;\n /** Lazy message factory — Vitest calls it only when reporting. */\n message: () => string;\n};\n\n/**\n * Any unified result envelope a matcher can be handed. Accepts the\n * full `{ report, ... }` result or a bare `BaseReport` so callers can\n * assert against either `await x.execute()` or `result.report`.\n */\ntype ReportLike = BaseReport | { report: BaseReport };\n\n/**\n * Coerce a matcher target into its `BaseReport`. Accepts the result\n * envelope (`{ report }`) or a report directly.\n */\nfunction toReport(received: ReportLike): BaseReport {\n if (\"report\" in received && received.report) {\n return received.report;\n }\n\n return received as BaseReport;\n}\n\n/** Narrow a `BaseReport` to a `SupervisorReport` by its discriminator. */\nfunction asSupervisorReport(report: BaseReport): SupervisorReport | undefined {\n return report.type === \"supervisor\" ? (report as SupervisorReport) : undefined;\n}\n\n/** Narrow a `BaseReport` to a `WorkflowReport` by its discriminator. */\nfunction asWorkflowReport(report: BaseReport): WorkflowReport | undefined {\n return report.type === \"workflow\" ? (report as WorkflowReport) : undefined;\n}\n\n/**\n * Collect every intent name dispatched by a supervisor across all\n * iterations — the keys of each iteration snapshot's `result` record.\n */\nfunction dispatchedIntents(report: SupervisorReport): string[] {\n const intents = new Set<string>();\n\n for (const snapshot of report.snapshots) {\n for (const intent of Object.keys(snapshot.result)) {\n intents.add(intent);\n }\n }\n\n return [...intents];\n}\n\n/**\n * Assert that a supervisor routed to (dispatched) the named intent at\n * least once across its iterations. Targets a `SupervisorResult` or a\n * `SupervisorReport`.\n *\n * @example\n * expect(await supervisor.execute(input)).toRouteTo(\"critic\");\n */\nexport function matchRouteTo(received: ReportLike, intent: string): MatcherVerdict {\n const report = toReport(received);\n const supervisorReport = asSupervisorReport(report);\n\n if (!supervisorReport) {\n return {\n pass: false,\n message: () =>\n `toRouteTo expects a supervisor result, but received a \"${report.type}\" report`,\n };\n }\n\n const intents = dispatchedIntents(supervisorReport);\n const pass = intents.includes(intent);\n\n return {\n pass,\n message: () =>\n pass\n ? `expected supervisor not to route to \"${intent}\", but it did`\n : `expected supervisor to route to \"${intent}\", but it routed to [${intents.join(\", \")}]`,\n };\n}\n\n/**\n * Assert that a supervisor converged — terminated on its own decision\n * (`router` / `route` / `evaluate` / `classifier`) with a\n * `\"completed\"` status, rather than hitting the iteration cap, being\n * cancelled, or erroring. Targets a `SupervisorResult` or\n * `SupervisorReport`.\n *\n * @example\n * expect(await supervisor.execute(input)).toConverge();\n */\nexport function matchConverge(received: ReportLike): MatcherVerdict {\n const report = toReport(received);\n const supervisorReport = asSupervisorReport(report);\n\n if (!supervisorReport) {\n return {\n pass: false,\n message: () =>\n `toConverge expects a supervisor result, but received a \"${report.type}\" report`,\n };\n }\n\n const nonConvergent = new Set([\"max-iterations\", \"cancelled\", \"error\"]);\n const pass =\n supervisorReport.status === \"completed\" &&\n !nonConvergent.has(supervisorReport.terminatedBy);\n\n return {\n pass,\n message: () =>\n pass\n ? `expected supervisor not to converge, but it terminated via \"${supervisorReport.terminatedBy}\"`\n : `expected supervisor to converge, but status=\"${supervisorReport.status}\" terminatedBy=\"${supervisorReport.terminatedBy}\" after ${supervisorReport.iterations} iteration(s)`,\n };\n}\n\n/**\n * Assert that a workflow step completed successfully. Targets a\n * `WorkflowResult` or `WorkflowReport`; looks the step up by name in\n * `report.steps` and checks its status is `\"completed\"`.\n *\n * @example\n * expect(await workflow.execute(input)).toPassStep(\"draft\");\n */\nexport function matchPassStep(received: ReportLike, stepName: string): MatcherVerdict {\n const report = toReport(received);\n const workflowReport = asWorkflowReport(report);\n\n if (!workflowReport) {\n return {\n pass: false,\n message: () =>\n `toPassStep expects a workflow result, but received a \"${report.type}\" report`,\n };\n }\n\n const step = workflowReport.steps[stepName];\n\n if (!step) {\n const known = Object.keys(workflowReport.steps).join(\", \");\n return {\n pass: false,\n message: () =>\n `expected workflow to have a step \"${stepName}\", but steps are [${known}]`,\n };\n }\n\n const pass = step.status === \"completed\";\n\n return {\n pass,\n message: () =>\n pass\n ? `expected step \"${stepName}\" not to pass, but it completed`\n : `expected step \"${stepName}\" to pass, but its status was \"${step.status}\"`,\n };\n}\n\n/**\n * Result envelope carrying a typed `data` payload — what\n * `matchOutputShape` validates against a schema.\n */\ntype DataResult = { data?: unknown };\n\n/**\n * Assert that a result's `data` validates against a Standard Schema.\n * Targets any result envelope with a `data` field (agent / workflow /\n * supervisor). Runs the schema's `~standard.validate` and passes only\n * when it reports no issues.\n *\n * Synchronous-only: a schema whose `validate` returns a Promise is\n * rejected with a clear message rather than silently passing — the\n * async variant belongs on a dedicated async matcher if needed.\n *\n * @example\n * expect(await agent.execute(input, { output: schema })).toOutputShape(schema);\n */\nexport function matchOutputShape(\n received: DataResult,\n schema: StandardSchemaV1,\n): MatcherVerdict {\n const data = received.data;\n\n if (data === undefined) {\n return {\n pass: false,\n message: () => \"toOutputShape expected result.data to be defined, but it was undefined\",\n };\n }\n\n const validation = schema[\"~standard\"].validate(data);\n\n if (validation instanceof Promise) {\n return {\n pass: false,\n message: () =>\n \"toOutputShape received an async schema; use a synchronous Standard Schema for this matcher\",\n };\n }\n\n const pass = validation.issues === undefined;\n\n return {\n pass,\n message: () => {\n if (pass) {\n return \"expected result.data not to match the schema, but it did\";\n }\n\n const summary = (validation.issues ?? []).map((issue) => issue.message).join(\"; \");\n return `expected result.data to match the schema, but validation failed: ${summary}`;\n },\n };\n}\n\n// Re-exported so matcher consumers and tests can reference the\n// termination sentinel without reaching into contracts.\nexport { END };\n"],"mappings":";;;;;;;AA8BA,SAAS,SAAS,UAAkC;CAClD,IAAI,YAAY,YAAY,SAAS,QACnC,OAAO,SAAS;CAGlB,OAAO;AACT;;AAGA,SAAS,mBAAmB,QAAkD;CAC5E,OAAO,OAAO,SAAS,eAAgB,SAA8B;AACvE;;AAGA,SAAS,iBAAiB,QAAgD;CACxE,OAAO,OAAO,SAAS,aAAc,SAA4B;AACnE;;;;;AAMA,SAAS,kBAAkB,QAAoC;CAC7D,MAAM,0BAAU,IAAI,IAAY;CAEhC,KAAK,MAAM,YAAY,OAAO,WAC5B,KAAK,MAAM,UAAU,OAAO,KAAK,SAAS,MAAM,GAC9C,QAAQ,IAAI,MAAM;CAItB,OAAO,CAAC,GAAG,OAAO;AACpB;;;;;;;;;AAUA,SAAgB,aAAa,UAAsB,QAAgC;CACjF,MAAM,SAAS,SAAS,QAAQ;CAChC,MAAM,mBAAmB,mBAAmB,MAAM;CAElD,IAAI,CAAC,kBACH,OAAO;EACL,MAAM;EACN,eACE,0DAA0D,OAAO,KAAK;CAC1E;CAGF,MAAM,UAAU,kBAAkB,gBAAgB;CAClD,MAAM,OAAO,QAAQ,SAAS,MAAM;CAEpC,OAAO;EACL;EACA,eACE,OACI,wCAAwC,OAAO,iBAC/C,oCAAoC,OAAO,uBAAuB,QAAQ,KAAK,IAAI,EAAE;CAC7F;AACF;;;;;;;;;;;AAYA,SAAgB,cAAc,UAAsC;CAClE,MAAM,SAAS,SAAS,QAAQ;CAChC,MAAM,mBAAmB,mBAAmB,MAAM;CAElD,IAAI,CAAC,kBACH,OAAO;EACL,MAAM;EACN,eACE,2DAA2D,OAAO,KAAK;CAC3E;CAGF,MAAM,gBAAgB,IAAI,IAAI;EAAC;EAAkB;EAAa;CAAO,CAAC;CACtE,MAAM,OACJ,iBAAiB,WAAW,eAC5B,CAAC,cAAc,IAAI,iBAAiB,YAAY;CAElD,OAAO;EACL;EACA,eACE,OACI,+DAA+D,iBAAiB,aAAa,KAC7F,gDAAgD,iBAAiB,OAAO,kBAAkB,iBAAiB,aAAa,UAAU,iBAAiB,WAAW;CACtK;AACF;;;;;;;;;AAUA,SAAgB,cAAc,UAAsB,UAAkC;CACpF,MAAM,SAAS,SAAS,QAAQ;CAChC,MAAM,iBAAiB,iBAAiB,MAAM;CAE9C,IAAI,CAAC,gBACH,OAAO;EACL,MAAM;EACN,eACE,yDAAyD,OAAO,KAAK;CACzE;CAGF,MAAM,OAAO,eAAe,MAAM;CAElC,IAAI,CAAC,MAAM;EACT,MAAM,QAAQ,OAAO,KAAK,eAAe,KAAK,CAAC,CAAC,KAAK,IAAI;EACzD,OAAO;GACL,MAAM;GACN,eACE,qCAAqC,SAAS,oBAAoB,MAAM;EAC5E;CACF;CAEA,MAAM,OAAO,KAAK,WAAW;CAE7B,OAAO;EACL;EACA,eACE,OACI,kBAAkB,SAAS,mCAC3B,kBAAkB,SAAS,iCAAiC,KAAK,OAAO;CAChF;AACF;;;;;;;;;;;;;;AAqBA,SAAgB,iBACd,UACA,QACgB;CAChB,MAAM,OAAO,SAAS;CAEtB,IAAI,SAAS,QACX,OAAO;EACL,MAAM;EACN,eAAe;CACjB;CAGF,MAAM,aAAa,OAAO,YAAY,CAAC,SAAS,IAAI;CAEpD,IAAI,sBAAsB,SACxB,OAAO;EACL,MAAM;EACN,eACE;CACJ;CAGF,MAAM,OAAO,WAAW,WAAW;CAEnC,OAAO;EACL;EACA,eAAe;GACb,IAAI,MACF,OAAO;GAIT,OAAO,qEADU,WAAW,UAAU,CAAC,EAAC,CAAE,KAAK,UAAU,MAAM,OAAO,CAAC,CAAC,KAAK,IACI;EACnF;CACF;AACF"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
2
|
+
|
|
3
|
+
//#region ../@warlock.js/ai/src/testing/matchers.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Custom Vitest matchers over the unified `@warlock.js/ai` report tree.
|
|
6
|
+
*
|
|
7
|
+
* - `toRouteTo(intent)` — a supervisor dispatched the named intent.
|
|
8
|
+
* - `toConverge()` — a supervisor terminated cleanly on its own
|
|
9
|
+
* decision (not max-iterations / cancelled / error).
|
|
10
|
+
* - `toPassStep(name)` — a workflow step completed successfully.
|
|
11
|
+
* - `toOutputShape(schema)` — a result's `data` validates against a
|
|
12
|
+
* Standard Schema.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* import { registerAiMatchers } from "@warlock.js/ai";
|
|
16
|
+
* registerAiMatchers();
|
|
17
|
+
*
|
|
18
|
+
* expect(await supervisor.execute(input)).toRouteTo("critic");
|
|
19
|
+
* expect(await supervisor.execute(input)).toConverge();
|
|
20
|
+
* expect(await workflow.execute(input)).toPassStep("draft");
|
|
21
|
+
* expect(await agent.execute(input, { output: schema })).toOutputShape(schema);
|
|
22
|
+
*/
|
|
23
|
+
interface AiMatchers<R = unknown> {
|
|
24
|
+
/** Assert a supervisor dispatched the named intent across its run. */
|
|
25
|
+
toRouteTo(intent: string): R;
|
|
26
|
+
/** Assert a supervisor terminated cleanly on its own decision. */
|
|
27
|
+
toConverge(): R;
|
|
28
|
+
/** Assert a named workflow step completed successfully. */
|
|
29
|
+
toPassStep(stepName: string): R;
|
|
30
|
+
/** Assert a result's `data` validates against a Standard Schema. */
|
|
31
|
+
toOutputShape(schema: StandardSchemaV1): R;
|
|
32
|
+
}
|
|
33
|
+
declare module "vitest" {
|
|
34
|
+
interface Matchers<T = any> extends AiMatchers<T> {}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Register the `@warlock.js/ai` custom matchers on Vitest's global
|
|
38
|
+
* `expect`. Call once per test file (or in a shared import) before
|
|
39
|
+
* using `toRouteTo` / `toConverge` / `toPassStep` / `toOutputShape`.
|
|
40
|
+
* Idempotent — repeated calls are a no-op.
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* import { registerAiMatchers } from "@warlock.js/ai";
|
|
44
|
+
* registerAiMatchers();
|
|
45
|
+
*/
|
|
46
|
+
//#endregion
|
|
47
|
+
export { AiMatchers };
|
|
48
|
+
//# sourceMappingURL=matchers.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"matchers.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai/src/testing/matchers.ts"],"mappings":";;;;;AA4BA;;;;;;;;;;;;;;;;;UAAiB,UAAA;EAMe;EAJ9B,SAAA,CAAU,MAAA,WAAiB,CAAA;EAML;EAJtB,UAAA,IAAc,CAAA;EAI2B;EAFzC,UAAA,CAAW,QAAA,WAAmB,CAAA;EAEY;EAA1C,aAAA,CAAc,MAAA,EAAQ,gBAAA,GAAmB,CAAA;AAAA;AAAA;EAAA,UAQ/B,QAAA,kBAA0B,UAAU,CAAC,CAAA;AAAA;;;;;AAAC"}
|