@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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orchestrator.mjs","names":["orchestratorAsTool"],"sources":["../../../../../../../@warlock.js/ai/src/orchestrator/orchestrator.ts"],"sourcesContent":["import type { OrchestratorConfig } from \"../contracts/orchestrator/orchestrator-config.type\";\nimport type {\n OrchestratorEventHandler,\n OrchestratorEventName,\n} from \"../contracts/orchestrator/orchestrator-event.type\";\nimport type {\n OrchestratorAsToolOptions,\n OrchestratorContract,\n} from \"../contracts/orchestrator/orchestrator.contract\";\nimport type { OrchestratorCommands } from \"../contracts/orchestrator/orchestrator-commands.type\";\nimport type {\n OrchestratorExecuteOptions,\n OrchestratorResumeOptions,\n} from \"../contracts/orchestrator/orchestrator-execute-options.type\";\nimport type { OrchestratorEvent } from \"../contracts/orchestrator/orchestrator-event.type\";\nimport type { OrchestratorResult } from \"../contracts/result/orchestrator-result.type\";\nimport type { StreamContract } from \"../contracts/stream/stream.contract\";\nimport type { SupervisorIntentValue } from \"../contracts/supervisor/intent-entry.type\";\nimport type { SupervisorInput } from \"../contracts/supervisor/supervisor-input.type\";\nimport { resolveDefaultSnapshotStore } from \"../config\";\nimport { OrchestratorConfigError } from \"../errors/orchestrator-config-error\";\nimport { resolveIntentEntries, type ResolvedIntentEntry } from \"../supervisor/entries\";\nimport { SupervisorFailedError } from \"../errors\";\nimport type { ToolContract } from \"../tool/tool\";\nimport { asTool as orchestratorAsTool } from \"./as-tool\";\nimport { createCommandDispatcher } from \"./commands\";\nimport { OrchestratorEmitter } from \"./emitter\";\nimport { OrchestratorExecution } from \"./execution\";\nimport { createOrchestratorStream } from \"./orchestrator-stream\";\nimport { computeOrchestratorSignature } from \"./signature\";\n\n/**\n * `ai.orchestrator(config)` — construct an {@link OrchestratorContract}:\n * a session-state manager wrapped around a supervisor (orchestrator.md\n * §1, §15). Validates the config at author time (throws\n * {@link OrchestratorConfigError} on bad shape), resolves the intent\n * entries, computes a stable structural signature for drift detection\n * (§10.1), wires the three-tier event emitter, and returns a handle that\n * runs one durable session turn per `execute` / `stream` call, resumes\n * an interrupted `iterate: true` turn via `resume`, and exposes typed\n * built-in commands plus an `asTool` wrapper.\n *\n * The \"what runs\" fields (`intents`, `route` / `router`, `evaluate`,\n * `state`, `output`, `initialAgent`, `maxIterations`) are the\n * supervisor's surface spread directly — the lifecycle builds the\n * supervisor lazily per turn and delegates to it (§3 Phase 5). Users\n * never see the supervisor object.\n *\n * @example\n * const supportBot = ai.orchestrator<SessionState>({\n * name: \"refund-support\",\n * intents: { classify, lookup, process, compose },\n * route: (ctx) => (ctx.iteration === 0 ? \"classify\" : END),\n * iterate: true,\n * checkpointStore: ai.checkpoint.pg({ client: pg }),\n * snapshotStore: ai.snapshot.pg({ client: pg }),\n * });\n *\n * const result = await supportBot.execute(message, { sessionId, history });\n */\nexport function orchestrator<\n TOutput = unknown,\n TState = TOutput,\n TIntents extends Record<string, SupervisorIntentValue> = Record<\n string,\n SupervisorIntentValue\n >,\n>(\n config: OrchestratorConfig<TOutput, TState, TIntents>,\n): OrchestratorContract<TOutput, TState> {\n validateFactoryConfig(config as unknown as OrchestratorConfig<unknown>);\n\n const entries = resolveEntries(config as unknown as OrchestratorConfig<unknown>);\n\n assertInitialAgent(config as unknown as OrchestratorConfig<unknown>, entries);\n\n const signature = computeOrchestratorSignature(\n config as unknown as OrchestratorConfig<unknown>,\n entries,\n );\n const emitter = new OrchestratorEmitter(config.on);\n\n async function execute(\n input: SupervisorInput,\n options: OrchestratorExecuteOptions<TState>,\n ): Promise<OrchestratorResult<TOutput>> {\n const execution = new OrchestratorExecution<TOutput, TState>({\n config: config as unknown as OrchestratorConfig<TOutput, TState>,\n entries,\n signature,\n emitter,\n input,\n options,\n });\n\n return execution.run();\n }\n\n function stream(\n input: SupervisorInput,\n options: OrchestratorExecuteOptions<TState>,\n ): StreamContract<OrchestratorResult<TOutput>, OrchestratorEvent> {\n const { controller, stream: contract } = createOrchestratorStream<\n OrchestratorResult<TOutput>\n >();\n\n const execution = new OrchestratorExecution<TOutput, TState>({\n config: config as unknown as OrchestratorConfig<TOutput, TState>,\n entries,\n signature,\n emitter,\n input,\n options,\n streamController: controller,\n });\n\n void execution.run();\n\n return contract;\n }\n\n async function resume(\n sessionId: string,\n options?: OrchestratorResumeOptions,\n ): Promise<OrchestratorResult<TOutput> | null> {\n const execution = new OrchestratorExecution<TOutput, TState>({\n config: config as unknown as OrchestratorConfig<TOutput, TState>,\n entries,\n signature,\n emitter,\n resumeSessionId: sessionId,\n resumeOptions: options,\n });\n\n return execution.resume();\n }\n\n // The dispatcher owns command ROUTING only; the `compact` handler\n // delegates to the shared compaction code path on the lifecycle engine\n // (§11 / §12.2 — manual compact reuses the post-turn compaction path).\n const command = createCommandDispatcher({\n compact: (args: OrchestratorCommands[\"compact\"][\"args\"]) => {\n const execution = new OrchestratorExecution<TOutput, TState>({\n config: config as unknown as OrchestratorConfig<TOutput, TState>,\n entries,\n signature,\n emitter,\n });\n\n return execution.compact(args);\n },\n });\n\n const instance: OrchestratorContract<TOutput, TState> = {\n name: config.name,\n signature,\n version: config.version,\n execute,\n stream,\n resume,\n command,\n asTool<TToolInput = string>(\n options: OrchestratorAsToolOptions<TToolInput>,\n ): ToolContract<TToolInput, TOutput> {\n return orchestratorAsTool<TOutput, TState, TToolInput>(instance, options);\n },\n on<K extends OrchestratorEventName>(\n event: K,\n handler: OrchestratorEventHandler<K>,\n ): () => void {\n return emitter.on(event, handler);\n },\n off<K extends OrchestratorEventName>(\n event: K,\n handler: OrchestratorEventHandler<K>,\n ): void {\n emitter.off(event, handler);\n },\n };\n\n return instance;\n}\n\n/**\n * Author-time validation (orchestrator.md §17). Enforces the rules that\n * must fail at construction rather than on the first turn:\n *\n * - `name` present and a string.\n * - `intents` present.\n * - `route` XOR `router` (mutually exclusive; at least one required) —\n * the supervisor's dispatch-source rule, surfaced as an orchestrator\n * config error.\n * - `router` is a valid agent contract or `{ agent, ... }` entry.\n * - `maxIterations >= 1` when set.\n * - `snapshotStore` resolvable when `iterate: true` — explicit field or\n * the global `ai.config({ defaultSnapshotStore })` fallback.\n *\n * `initialAgent` membership is checked separately once the intent\n * entries are resolved.\n */\nfunction validateFactoryConfig(config: OrchestratorConfig<unknown>): void {\n if (!config.name || typeof config.name !== \"string\") {\n throw new OrchestratorConfigError(\n \"ai.orchestrator: `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 OrchestratorConfigError(\n `ai.orchestrator(\"${config.name}\"): \\`intents\\` is required`,\n { context: { authoring: true } },\n );\n }\n\n const hasRoute = typeof config.route === \"function\";\n const hasRouter = Boolean(config.router);\n\n if (hasRouter) {\n const router = config.router;\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 OrchestratorConfigError(\n `ai.orchestrator(\"${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 OrchestratorConfigError(\n `ai.orchestrator(\"${config.name}\"): \\`route\\` and \\`router\\` are mutually exclusive — configure exactly one`,\n { context: { authoring: true } },\n );\n }\n\n if (!hasRoute && !hasRouter) {\n throw new OrchestratorConfigError(\n `ai.orchestrator(\"${config.name}\"): one of \\`route\\` or \\`router\\` is required`,\n { context: { authoring: true } },\n );\n }\n\n if (config.maxIterations !== undefined && config.maxIterations < 1) {\n throw new OrchestratorConfigError(\n `ai.orchestrator(\"${config.name}\"): \\`maxIterations\\` must be >= 1`,\n { context: { authoring: true, maxIterations: config.maxIterations } },\n );\n }\n\n if (config.iterate && !config.snapshotStore && !resolveDefaultSnapshotStore()) {\n throw new OrchestratorConfigError(\n `ai.orchestrator(\"${config.name}\"): \\`iterate: true\\` requires a \\`snapshotStore\\` (or \\`ai.config({ defaultSnapshotStore })\\`) for mid-turn resume`,\n { context: { authoring: true } },\n );\n }\n}\n\n/**\n * Resolve the `intents` map into the supervisor's internal entry shape,\n * re-wrapping the supervisor's authoring failure as an\n * {@link OrchestratorConfigError} so misuse surfaces under the\n * orchestrator's error family rather than the supervisor's.\n */\nfunction resolveEntries(\n config: OrchestratorConfig<unknown>,\n): Map<string, ResolvedIntentEntry> {\n try {\n return resolveIntentEntries(config.intents, config.name);\n } catch (error) {\n if (error instanceof SupervisorFailedError) {\n throw new OrchestratorConfigError(error.message, {\n context: { authoring: true },\n cause: error,\n });\n }\n\n throw error;\n }\n}\n\n/**\n * Enforce the `initialAgent` membership rule (§17) once entries are\n * resolved — `initialAgent`, when set, must name a key in `intents`.\n */\nfunction assertInitialAgent(\n config: OrchestratorConfig<unknown>,\n entries: Map<string, ResolvedIntentEntry>,\n): void {\n if (config.initialAgent && !entries.has(config.initialAgent)) {\n throw new OrchestratorConfigError(\n `ai.orchestrator(\"${config.name}\"): \\`initialAgent\\` \"${config.initialAgent}\" is not a key in \\`intents\\``,\n { context: { authoring: true } },\n );\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4DA,SAAgB,aAQd,QACuC;CACvC,sBAAsB,MAAgD;CAEtE,MAAM,UAAU,eAAe,MAAgD;CAE/E,mBAAmB,QAAkD,OAAO;CAE5E,MAAM,YAAY,6BAChB,QACA,OACF;CACA,MAAM,UAAU,IAAI,oBAAoB,OAAO,EAAE;CAEjD,eAAe,QACb,OACA,SACsC;EAUtC,OAAO,IATe,sBAAuC;GACnD;GACR;GACA;GACA;GACA;GACA;EACF,CAEe,CAAC,CAAC,IAAI;CACvB;CAEA,SAAS,OACP,OACA,SACgE;EAChE,MAAM,EAAE,YAAY,QAAQ,aAAa,yBAEvC;EAYF,AAAK,IAViB,sBAAuC;GACnD;GACR;GACA;GACA;GACA;GACA;GACA,kBAAkB;EACpB,CAEa,CAAC,CAAC,IAAI;EAEnB,OAAO;CACT;CAEA,eAAe,OACb,WACA,SAC6C;EAU7C,OAAO,IATe,sBAAuC;GACnD;GACR;GACA;GACA;GACA,iBAAiB;GACjB,eAAe;EACjB,CAEe,CAAC,CAAC,OAAO;CAC1B;CAKA,MAAM,UAAU,wBAAwB,EACtC,UAAU,SAAkD;EAQ1D,OAAO,IAPe,sBAAuC;GACnD;GACR;GACA;GACA;EACF,CAEe,CAAC,CAAC,QAAQ,IAAI;CAC/B,EACF,CAAC;CAED,MAAM,WAAkD;EACtD,MAAM,OAAO;EACb;EACA,SAAS,OAAO;EAChB;EACA;EACA;EACA;EACA,OACE,SACmC;GACnC,OAAOA,OAAgD,UAAU,OAAO;EAC1E;EACA,GACE,OACA,SACY;GACZ,OAAO,QAAQ,GAAG,OAAO,OAAO;EAClC;EACA,IACE,OACA,SACM;GACN,QAAQ,IAAI,OAAO,OAAO;EAC5B;CACF;CAEA,OAAO;AACT;;;;;;;;;;;;;;;;;;AAmBA,SAAS,sBAAsB,QAA2C;CACxE,IAAI,CAAC,OAAO,QAAQ,OAAO,OAAO,SAAS,UACzC,MAAM,IAAI,wBACR,4DACA,EAAE,SAAS,EAAE,WAAW,KAAK,EAAE,CACjC;CAGF,IAAI,CAAC,OAAO,WAAW,OAAO,OAAO,YAAY,UAC/C,MAAM,IAAI,wBACR,oBAAoB,OAAO,KAAK,8BAChC,EAAE,SAAS,EAAE,WAAW,KAAK,EAAE,CACjC;CAGF,MAAM,WAAW,OAAO,OAAO,UAAU;CACzC,MAAM,YAAY,QAAQ,OAAO,MAAM;CAEvC,IAAI,WAAW;EACb,MAAM,SAAS,OAAO;EACtB,MAAM,cAAc,OAAQ,OAAiC,YAAY;EACzE,MAAM,cACJ,CAAC,eACD,OAAQ,OAA6C,UAAU,YAC/D,OAAQ,OAA6C,OAAO,YAAY;EAE1E,IAAI,CAAC,eAAe,CAAC,aACnB,MAAM,IAAI,wBACR,oBAAoB,OAAO,KAAK,2FAChC,EAAE,SAAS,EAAE,WAAW,KAAK,EAAE,CACjC;CAEJ;CAEA,IAAI,YAAY,WACd,MAAM,IAAI,wBACR,oBAAoB,OAAO,KAAK,8EAChC,EAAE,SAAS,EAAE,WAAW,KAAK,EAAE,CACjC;CAGF,IAAI,CAAC,YAAY,CAAC,WAChB,MAAM,IAAI,wBACR,oBAAoB,OAAO,KAAK,iDAChC,EAAE,SAAS,EAAE,WAAW,KAAK,EAAE,CACjC;CAGF,IAAI,OAAO,kBAAkB,UAAa,OAAO,gBAAgB,GAC/D,MAAM,IAAI,wBACR,oBAAoB,OAAO,KAAK,qCAChC,EAAE,SAAS;EAAE,WAAW;EAAM,eAAe,OAAO;CAAc,EAAE,CACtE;CAGF,IAAI,OAAO,WAAW,CAAC,OAAO,iBAAiB,CAAC,4BAA4B,GAC1E,MAAM,IAAI,wBACR,oBAAoB,OAAO,KAAK,sHAChC,EAAE,SAAS,EAAE,WAAW,KAAK,EAAE,CACjC;AAEJ;;;;;;;AAQA,SAAS,eACP,QACkC;CAClC,IAAI;EACF,OAAO,qBAAqB,OAAO,SAAS,OAAO,IAAI;CACzD,SAAS,OAAO;EACd,IAAI,iBAAiB,uBACnB,MAAM,IAAI,wBAAwB,MAAM,SAAS;GAC/C,SAAS,EAAE,WAAW,KAAK;GAC3B,OAAO;EACT,CAAC;EAGH,MAAM;CACR;AACF;;;;;AAMA,SAAS,mBACP,QACA,SACM;CACN,IAAI,OAAO,gBAAgB,CAAC,QAAQ,IAAI,OAAO,YAAY,GACzD,MAAM,IAAI,wBACR,oBAAoB,OAAO,KAAK,wBAAwB,OAAO,aAAa,gCAC5E,EAAE,SAAS,EAAE,WAAW,KAAK,EAAE,CACjC;AAEJ"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { summarizeRoute } from "./checkpoint.mjs";
|
|
2
|
+
import { deriveRunId, dispatchTurn } from "./dispatch.mjs";
|
|
3
|
+
import { loadSession } from "./load.mjs";
|
|
4
|
+
|
|
5
|
+
//#region ../@warlock.js/ai/src/orchestrator/resume.ts
|
|
6
|
+
/**
|
|
7
|
+
* §9 resume protocol. Detects and drains an interrupted `iterate: true`
|
|
8
|
+
* turn:
|
|
9
|
+
*
|
|
10
|
+
* 1. Load the latest checkpoint (§9.1 step 1).
|
|
11
|
+
* 2. Compute the candidate `runId` for the NEXT turn — the one that was
|
|
12
|
+
* in flight — `${sessionId}.${version}.${turn_index + 1}` (§9.1 step 2).
|
|
13
|
+
* 3. Load the supervisor snapshot for that runId (§9.1 step 3).
|
|
14
|
+
* 4. If a still-`running` snapshot exists, resume the supervisor, persist
|
|
15
|
+
* a fresh checkpoint for `turn_index + 1`, and return the result
|
|
16
|
+
* (§9.1 step 4).
|
|
17
|
+
* 5. Otherwise return `null` — nothing in flight; the caller proceeds to
|
|
18
|
+
* `execute()` normally (§9.1 step 5, §9.3 drain idempotency).
|
|
19
|
+
*
|
|
20
|
+
* Runs the same Phase 2 drift check as `execute()` (§9.4). Resume is a
|
|
21
|
+
* no-op for `iterate: false` orchestrators (no SnapshotStore, nothing to
|
|
22
|
+
* resume) — it returns `null`.
|
|
23
|
+
*/
|
|
24
|
+
async function resolveResume(ctx, sessionId, options, hooks) {
|
|
25
|
+
if (!ctx.snapshotStore || ctx.config.iterate !== true) return null;
|
|
26
|
+
const loaded = await loadSession(ctx, sessionId);
|
|
27
|
+
hooks.assertNoDrift(loaded.record?.signature);
|
|
28
|
+
const resumedTurnIndex = (loaded.record?.turn_index ?? -1) + 1;
|
|
29
|
+
const runId = deriveRunId(sessionId, ctx.config.version, resumedTurnIndex);
|
|
30
|
+
const snapshot = await ctx.snapshotStore.load(runId);
|
|
31
|
+
if (!snapshot || snapshot.status !== "running") return null;
|
|
32
|
+
ctx.emitter.emit("orchestrator.turn.starting", {
|
|
33
|
+
sessionId,
|
|
34
|
+
turnIndex: resumedTurnIndex
|
|
35
|
+
});
|
|
36
|
+
const { result, state, turnSnapshot } = await dispatchTurn({
|
|
37
|
+
ctx,
|
|
38
|
+
sessionId,
|
|
39
|
+
input: snapshot.input,
|
|
40
|
+
seedState: loaded.state,
|
|
41
|
+
turnIndex: resumedTurnIndex,
|
|
42
|
+
history: [],
|
|
43
|
+
context: options?.context,
|
|
44
|
+
signal: options?.signal
|
|
45
|
+
});
|
|
46
|
+
const status = result.error ? hooks.deriveStatus(result.report.status) : "awaiting-input";
|
|
47
|
+
if (result.error) {
|
|
48
|
+
const report = hooks.buildReport(resumedTurnIndex, status, turnSnapshot, result.report);
|
|
49
|
+
hooks.emitTerminal(resumedTurnIndex, status);
|
|
50
|
+
return {
|
|
51
|
+
data: result.data,
|
|
52
|
+
error: result.error,
|
|
53
|
+
usage: result.usage,
|
|
54
|
+
report,
|
|
55
|
+
sessionId,
|
|
56
|
+
turnIndex: resumedTurnIndex
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
await hooks.persist(resumedTurnIndex, state, summarizeRoute(turnSnapshot.decision.raw), loaded.record?.summarized_through ?? null);
|
|
60
|
+
const report = hooks.buildReport(resumedTurnIndex, "awaiting-input", turnSnapshot, result.report);
|
|
61
|
+
hooks.emitTerminal(resumedTurnIndex, "awaiting-input");
|
|
62
|
+
return {
|
|
63
|
+
data: result.data,
|
|
64
|
+
error: void 0,
|
|
65
|
+
usage: result.usage,
|
|
66
|
+
report,
|
|
67
|
+
sessionId,
|
|
68
|
+
turnIndex: resumedTurnIndex
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
//#endregion
|
|
73
|
+
export { resolveResume };
|
|
74
|
+
//# sourceMappingURL=resume.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resume.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/orchestrator/resume.ts"],"sourcesContent":["import type { OrchestratorResumeOptions } from \"../contracts/orchestrator/orchestrator-execute-options.type\";\nimport type {\n OrchestratorReport,\n OrchestratorReportStatus,\n OrchestratorResult,\n TurnSnapshot,\n} from \"../contracts/result/orchestrator-result.type\";\nimport type { BaseReport } from \"../contracts/result/base-report.type\";\nimport { summarizeRoute } from \"./checkpoint\";\nimport { deriveRunId, dispatchTurn } from \"./dispatch\";\nimport type { OrchestratorEngineContext } from \"./engine-context.type\";\nimport { loadSession } from \"./load\";\n\n/**\n * Hooks the resume protocol borrows from the execution module so it can\n * reuse the drift check, report assembly, status mapping, terminal\n * event emission, and checkpoint persistence without a circular import\n * (execution.ts owns those; resume.ts is called by it).\n */\nexport type ResumeHooks = {\n assertNoDrift(loadedSignature: string | undefined): void;\n buildReport(\n turnIndex: number,\n status: OrchestratorReportStatus,\n turnSnapshot: TurnSnapshot | undefined,\n childReport: BaseReport | undefined,\n ): OrchestratorReport;\n deriveStatus(childStatus: BaseReport[\"status\"]): OrchestratorReportStatus;\n emitTerminal(turnIndex: number, status: OrchestratorReportStatus): void;\n persist(\n turnIndex: number,\n state: unknown,\n lastRoute: string | string[] | null,\n summarizedThrough: number | null,\n ): Promise<unknown>;\n};\n\n/**\n * §9 resume protocol. Detects and drains an interrupted `iterate: true`\n * turn:\n *\n * 1. Load the latest checkpoint (§9.1 step 1).\n * 2. Compute the candidate `runId` for the NEXT turn — the one that was\n * in flight — `${sessionId}.${version}.${turn_index + 1}` (§9.1 step 2).\n * 3. Load the supervisor snapshot for that runId (§9.1 step 3).\n * 4. If a still-`running` snapshot exists, resume the supervisor, persist\n * a fresh checkpoint for `turn_index + 1`, and return the result\n * (§9.1 step 4).\n * 5. Otherwise return `null` — nothing in flight; the caller proceeds to\n * `execute()` normally (§9.1 step 5, §9.3 drain idempotency).\n *\n * Runs the same Phase 2 drift check as `execute()` (§9.4). Resume is a\n * no-op for `iterate: false` orchestrators (no SnapshotStore, nothing to\n * resume) — it returns `null`.\n */\nexport async function resolveResume<TOutput, TState>(\n ctx: OrchestratorEngineContext<TOutput, TState>,\n sessionId: string,\n options: OrchestratorResumeOptions | undefined,\n hooks: ResumeHooks,\n): Promise<OrchestratorResult<TOutput> | null> {\n if (!ctx.snapshotStore || ctx.config.iterate !== true) {\n return null;\n }\n\n const loaded = await loadSession(ctx, sessionId);\n\n // Drift guard — same as execute() (§9.4).\n hooks.assertNoDrift(loaded.record?.signature);\n\n // The in-flight turn is the one AFTER the last settled checkpoint.\n const resumedTurnIndex = (loaded.record?.turn_index ?? -1) + 1;\n const runId = deriveRunId(sessionId, ctx.config.version, resumedTurnIndex);\n\n const snapshot = await ctx.snapshotStore.load(runId);\n\n if (!snapshot || snapshot.status !== \"running\") {\n return null;\n }\n\n ctx.emitter.emit(\"orchestrator.turn.starting\", {\n sessionId,\n turnIndex: resumedTurnIndex,\n });\n\n // Re-dispatch: dispatchTurn detects the in-flight snapshot for this\n // runId and calls supervisor.resume() rather than execute() (§5 step 5).\n const { result, state, turnSnapshot } = await dispatchTurn<TOutput, TState>({\n ctx,\n sessionId,\n input: snapshot.input,\n seedState: loaded.state,\n turnIndex: resumedTurnIndex,\n history: [],\n context: options?.context,\n signal: options?.signal,\n });\n\n const status = result.error\n ? hooks.deriveStatus(result.report.status)\n : \"awaiting-input\";\n\n if (result.error) {\n const report = hooks.buildReport(\n resumedTurnIndex,\n status,\n turnSnapshot,\n result.report,\n );\n\n hooks.emitTerminal(resumedTurnIndex, status);\n\n return {\n data: result.data,\n error: result.error,\n usage: result.usage,\n report,\n sessionId,\n turnIndex: resumedTurnIndex,\n };\n }\n\n // Finalize: persist a fresh checkpoint for the resumed turn (§9.1 step 4).\n await hooks.persist(\n resumedTurnIndex,\n state,\n summarizeRoute(turnSnapshot.decision.raw as never),\n loaded.record?.summarized_through ?? null,\n );\n\n const report = hooks.buildReport(\n resumedTurnIndex,\n \"awaiting-input\",\n turnSnapshot,\n result.report,\n );\n\n hooks.emitTerminal(resumedTurnIndex, \"awaiting-input\");\n\n return {\n data: result.data,\n error: undefined,\n usage: result.usage,\n report,\n sessionId,\n turnIndex: resumedTurnIndex,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAuDA,eAAsB,cACpB,KACA,WACA,SACA,OAC6C;CAC7C,IAAI,CAAC,IAAI,iBAAiB,IAAI,OAAO,YAAY,MAC/C,OAAO;CAGT,MAAM,SAAS,MAAM,YAAY,KAAK,SAAS;CAG/C,MAAM,cAAc,OAAO,QAAQ,SAAS;CAG5C,MAAM,oBAAoB,OAAO,QAAQ,cAAc,MAAM;CAC7D,MAAM,QAAQ,YAAY,WAAW,IAAI,OAAO,SAAS,gBAAgB;CAEzE,MAAM,WAAW,MAAM,IAAI,cAAc,KAAK,KAAK;CAEnD,IAAI,CAAC,YAAY,SAAS,WAAW,WACnC,OAAO;CAGT,IAAI,QAAQ,KAAK,8BAA8B;EAC7C;EACA,WAAW;CACb,CAAC;CAID,MAAM,EAAE,QAAQ,OAAO,iBAAiB,MAAM,aAA8B;EAC1E;EACA;EACA,OAAO,SAAS;EAChB,WAAW,OAAO;EAClB,WAAW;EACX,SAAS,CAAC;EACV,SAAS,SAAS;EAClB,QAAQ,SAAS;CACnB,CAAC;CAED,MAAM,SAAS,OAAO,QAClB,MAAM,aAAa,OAAO,OAAO,MAAM,IACvC;CAEJ,IAAI,OAAO,OAAO;EAChB,MAAM,SAAS,MAAM,YACnB,kBACA,QACA,cACA,OAAO,MACT;EAEA,MAAM,aAAa,kBAAkB,MAAM;EAE3C,OAAO;GACL,MAAM,OAAO;GACb,OAAO,OAAO;GACd,OAAO,OAAO;GACd;GACA;GACA,WAAW;EACb;CACF;CAGA,MAAM,MAAM,QACV,kBACA,OACA,eAAe,aAAa,SAAS,GAAY,GACjD,OAAO,QAAQ,sBAAsB,IACvC;CAEA,MAAM,SAAS,MAAM,YACnB,kBACA,kBACA,cACA,OAAO,MACT;CAEA,MAAM,aAAa,kBAAkB,gBAAgB;CAErD,OAAO;EACL,MAAM,OAAO;EACb,OAAO;EACP,OAAO,OAAO;EACd;EACA;EACA,WAAW;CACb;AACF"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { OrchestratorConfig } from "../contracts/orchestrator/orchestrator-config.type.mjs";
|
|
2
|
+
import { ResolvedIntentEntry } from "../supervisor/entries.mjs";
|
|
3
|
+
|
|
4
|
+
//#region ../@warlock.js/ai/src/orchestrator/signature.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Deterministic structural fingerprint of an orchestrator definition
|
|
7
|
+
* (orchestrator.md §10.1). Persisted on every checkpoint so Phase 2 can
|
|
8
|
+
* refuse a turn when the live definition no longer matches the saved
|
|
9
|
+
* session shape. Covers exactly the dispatch contract:
|
|
10
|
+
*
|
|
11
|
+
* - `name`.
|
|
12
|
+
* - The `intents` map — each intent key + its resolved description +
|
|
13
|
+
* the underlying unit's stable identity (agent name, workflow name +
|
|
14
|
+
* signature, or a `"callback"` marker for dev-callback intents).
|
|
15
|
+
* Reuses the supervisor's resolved-entry fingerprinting verbatim.
|
|
16
|
+
* - `route` callback presence (its body is code, not data).
|
|
17
|
+
* - `router` agent identity when LLM routing is configured.
|
|
18
|
+
* - `evaluate` callback presence.
|
|
19
|
+
* - `initialAgent` when set.
|
|
20
|
+
* - `maxIterations`.
|
|
21
|
+
* - The `iterate` flag — flipping single-dispatch to delegated
|
|
22
|
+
* iteration is a semantic shape change.
|
|
23
|
+
* - The `historyWindow` config SHAPE — which roles window and whether
|
|
24
|
+
* each is a number or a callback (not the window value itself).
|
|
25
|
+
*
|
|
26
|
+
* Does NOT cover (§10.1): `version` (metadata only), `systemPrompt`
|
|
27
|
+
* text, logger config, store identities, event handlers, or callback
|
|
28
|
+
* function bodies (callbacks fingerprint as their presence/`"callback"`
|
|
29
|
+
* marker only). The orchestrator signature does NOT aggregate the
|
|
30
|
+
* internal supervisor's signature — that is a per-run concern delegated
|
|
31
|
+
* to `supervisor.resume()`'s own drift check on `iterate: true`.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* const signature = computeOrchestratorSignature(config, resolvedEntries);
|
|
35
|
+
* // "1a2b3c4d" — 8-char FNV-1a hex, stable across process restarts.
|
|
36
|
+
*/
|
|
37
|
+
declare function computeOrchestratorSignature(config: OrchestratorConfig<unknown>, entries: Map<string, ResolvedIntentEntry>): string;
|
|
38
|
+
//#endregion
|
|
39
|
+
export { computeOrchestratorSignature };
|
|
40
|
+
//# sourceMappingURL=signature.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signature.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai/src/orchestrator/signature.ts"],"mappings":";;;;;;AA4CA;;;;;;;;;;;;;;AAE2C;;;;;;;;;;;;;;;;iBAF3B,4BAAA,CACd,MAAA,EAAQ,kBAAA,WACR,OAAA,EAAS,GAAA,SAAY,mBAAA"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
//#region ../@warlock.js/ai/src/orchestrator/signature.ts
|
|
2
|
+
/**
|
|
3
|
+
* Deterministic structural fingerprint of an orchestrator definition
|
|
4
|
+
* (orchestrator.md §10.1). Persisted on every checkpoint so Phase 2 can
|
|
5
|
+
* refuse a turn when the live definition no longer matches the saved
|
|
6
|
+
* session shape. Covers exactly the dispatch contract:
|
|
7
|
+
*
|
|
8
|
+
* - `name`.
|
|
9
|
+
* - The `intents` map — each intent key + its resolved description +
|
|
10
|
+
* the underlying unit's stable identity (agent name, workflow name +
|
|
11
|
+
* signature, or a `"callback"` marker for dev-callback intents).
|
|
12
|
+
* Reuses the supervisor's resolved-entry fingerprinting verbatim.
|
|
13
|
+
* - `route` callback presence (its body is code, not data).
|
|
14
|
+
* - `router` agent identity when LLM routing is configured.
|
|
15
|
+
* - `evaluate` callback presence.
|
|
16
|
+
* - `initialAgent` when set.
|
|
17
|
+
* - `maxIterations`.
|
|
18
|
+
* - The `iterate` flag — flipping single-dispatch to delegated
|
|
19
|
+
* iteration is a semantic shape change.
|
|
20
|
+
* - The `historyWindow` config SHAPE — which roles window and whether
|
|
21
|
+
* each is a number or a callback (not the window value itself).
|
|
22
|
+
*
|
|
23
|
+
* Does NOT cover (§10.1): `version` (metadata only), `systemPrompt`
|
|
24
|
+
* text, logger config, store identities, event handlers, or callback
|
|
25
|
+
* function bodies (callbacks fingerprint as their presence/`"callback"`
|
|
26
|
+
* marker only). The orchestrator signature does NOT aggregate the
|
|
27
|
+
* internal supervisor's signature — that is a per-run concern delegated
|
|
28
|
+
* to `supervisor.resume()`'s own drift check on `iterate: true`.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* const signature = computeOrchestratorSignature(config, resolvedEntries);
|
|
32
|
+
* // "1a2b3c4d" — 8-char FNV-1a hex, stable across process restarts.
|
|
33
|
+
*/
|
|
34
|
+
function computeOrchestratorSignature(config, entries) {
|
|
35
|
+
const intentsFingerprint = [...entries.entries()].sort(([first], [second]) => first.localeCompare(second)).map(([intent, entry]) => ({
|
|
36
|
+
k: intent,
|
|
37
|
+
d: entry.description,
|
|
38
|
+
u: fingerprintUnit(entry)
|
|
39
|
+
}));
|
|
40
|
+
const fingerprint = {
|
|
41
|
+
n: config.name,
|
|
42
|
+
a: intentsFingerprint,
|
|
43
|
+
r: resolveRouterName(config.router),
|
|
44
|
+
rc: config.route ? 1 : 0,
|
|
45
|
+
e: config.evaluate ? 1 : 0,
|
|
46
|
+
i: config.initialAgent ?? null,
|
|
47
|
+
m: config.maxIterations ?? null,
|
|
48
|
+
it: config.iterate ? 1 : 0,
|
|
49
|
+
hw: fingerprintHistoryWindow(config.historyWindow)
|
|
50
|
+
};
|
|
51
|
+
return hash(JSON.stringify(fingerprint));
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Router identity for the fingerprint. Accepts both the bare-agent
|
|
55
|
+
* shorthand and the `{ agent, ... }` entry form, returning the agent's
|
|
56
|
+
* name (or `null` when no router is configured). Mirrors the
|
|
57
|
+
* supervisor's `resolveRouterName`.
|
|
58
|
+
*/
|
|
59
|
+
function resolveRouterName(router) {
|
|
60
|
+
if (!router) return null;
|
|
61
|
+
if (typeof router.execute === "function") return router.name ?? null;
|
|
62
|
+
return router.agent?.name ?? null;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Structural fingerprint of the `historyWindow` config. Records the
|
|
66
|
+
* windowing strategy per role (`"number"` / `"callback"` / `null`) so a
|
|
67
|
+
* dev swapping a fixed-size window for a token-counting callback drifts
|
|
68
|
+
* the signature, while tuning the window value (e.g. `5` → `8`) does
|
|
69
|
+
* not. The window value is a runtime knob, not a shape change.
|
|
70
|
+
*/
|
|
71
|
+
function fingerprintHistoryWindow(historyWindow) {
|
|
72
|
+
return {
|
|
73
|
+
router: fingerprintHistoryWindowRole(historyWindow?.router),
|
|
74
|
+
agents: fingerprintHistoryWindowRole(historyWindow?.agents)
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
function fingerprintHistoryWindowRole(window) {
|
|
78
|
+
if (window === void 0) return null;
|
|
79
|
+
if (typeof window === "function") return "callback";
|
|
80
|
+
return "number";
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Stable identity of one resolved intent's underlying unit. Agents
|
|
84
|
+
* fingerprint by name; workflows by name + their own signature;
|
|
85
|
+
* callbacks by a type marker only (their closure can't be hashed
|
|
86
|
+
* deterministically, so drift covers add/remove/rename, not body
|
|
87
|
+
* edits). Identical to the supervisor's `fingerprintUnit`.
|
|
88
|
+
*/
|
|
89
|
+
function fingerprintUnit(entry) {
|
|
90
|
+
if (entry.type === "callback") return { t: "callback" };
|
|
91
|
+
if (entry.type === "workflow") {
|
|
92
|
+
const workflow = entry.unit;
|
|
93
|
+
return {
|
|
94
|
+
t: "workflow",
|
|
95
|
+
n: workflow.name,
|
|
96
|
+
s: workflow.signature
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
t: "agent",
|
|
101
|
+
n: entry.unit.name
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* FNV-1a 32-bit — the same hash `supervisor/signature.ts` and
|
|
106
|
+
* `workflow/signature.ts` use. Deterministic, no crypto dependency,
|
|
107
|
+
* cheap; signatures are 8-char hex.
|
|
108
|
+
*/
|
|
109
|
+
function hash(input) {
|
|
110
|
+
let h = 2166136261;
|
|
111
|
+
for (let i = 0; i < input.length; i++) {
|
|
112
|
+
h ^= input.charCodeAt(i);
|
|
113
|
+
h = h + ((h << 1) + (h << 4) + (h << 7) + (h << 8) + (h << 24)) >>> 0;
|
|
114
|
+
}
|
|
115
|
+
return h.toString(16).padStart(8, "0");
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
//#endregion
|
|
119
|
+
export { computeOrchestratorSignature };
|
|
120
|
+
//# sourceMappingURL=signature.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signature.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/orchestrator/signature.ts"],"sourcesContent":["import type { OrchestratorConfig } from \"../contracts/orchestrator/orchestrator-config.type\";\nimport type { ResolvedIntentEntry } from \"../supervisor/entries\";\n\n/**\n * Shape of the `historyWindow` config a fingerprint records. A number\n * window is recorded as `\"number\"`; a callback window as `\"callback\"`;\n * an absent role as `null`. The window VALUE (the literal `5`, the\n * callback body) is deliberately excluded — only the structural choice\n * of windowing strategy per role drifts the signature (§10.1).\n */\ntype HistoryWindowRoleFingerprint = \"number\" | \"callback\" | null;\n\n/**\n * Deterministic structural fingerprint of an orchestrator definition\n * (orchestrator.md §10.1). Persisted on every checkpoint so Phase 2 can\n * refuse a turn when the live definition no longer matches the saved\n * session shape. Covers exactly the dispatch contract:\n *\n * - `name`.\n * - The `intents` map — each intent key + its resolved description +\n * the underlying unit's stable identity (agent name, workflow name +\n * signature, or a `\"callback\"` marker for dev-callback intents).\n * Reuses the supervisor's resolved-entry fingerprinting verbatim.\n * - `route` callback presence (its body is code, not data).\n * - `router` agent identity when LLM routing is configured.\n * - `evaluate` callback presence.\n * - `initialAgent` when set.\n * - `maxIterations`.\n * - The `iterate` flag — flipping single-dispatch to delegated\n * iteration is a semantic shape change.\n * - The `historyWindow` config SHAPE — which roles window and whether\n * each is a number or a callback (not the window value itself).\n *\n * Does NOT cover (§10.1): `version` (metadata only), `systemPrompt`\n * text, logger config, store identities, event handlers, or callback\n * function bodies (callbacks fingerprint as their presence/`\"callback\"`\n * marker only). The orchestrator signature does NOT aggregate the\n * internal supervisor's signature — that is a per-run concern delegated\n * to `supervisor.resume()`'s own drift check on `iterate: true`.\n *\n * @example\n * const signature = computeOrchestratorSignature(config, resolvedEntries);\n * // \"1a2b3c4d\" — 8-char FNV-1a hex, stable across process restarts.\n */\nexport function computeOrchestratorSignature(\n config: OrchestratorConfig<unknown>,\n entries: Map<string, ResolvedIntentEntry>,\n): string {\n const intentsFingerprint = [...entries.entries()]\n .sort(([first], [second]) => first.localeCompare(second))\n .map(([intent, entry]) => ({\n k: intent,\n d: entry.description,\n u: fingerprintUnit(entry),\n }));\n\n const fingerprint = {\n n: config.name,\n a: intentsFingerprint,\n r: resolveRouterName(config.router),\n rc: config.route ? 1 : 0,\n e: config.evaluate ? 1 : 0,\n i: config.initialAgent ?? null,\n m: config.maxIterations ?? null,\n it: config.iterate ? 1 : 0,\n hw: fingerprintHistoryWindow(config.historyWindow),\n };\n\n return hash(JSON.stringify(fingerprint));\n}\n\n/**\n * Router identity for the fingerprint. Accepts both the bare-agent\n * shorthand and the `{ agent, ... }` entry form, returning the agent's\n * name (or `null` when no router is configured). Mirrors the\n * supervisor's `resolveRouterName`.\n */\nfunction resolveRouterName(router: OrchestratorConfig<unknown>[\"router\"]): string | null {\n if (!router) {\n return null;\n }\n\n if (typeof (router as { execute?: unknown }).execute === \"function\") {\n return (router as { name?: string }).name ?? null;\n }\n\n return (router as { agent?: { name?: string } }).agent?.name ?? null;\n}\n\n/**\n * Structural fingerprint of the `historyWindow` config. Records the\n * windowing strategy per role (`\"number\"` / `\"callback\"` / `null`) so a\n * dev swapping a fixed-size window for a token-counting callback drifts\n * the signature, while tuning the window value (e.g. `5` → `8`) does\n * not. The window value is a runtime knob, not a shape change.\n */\nfunction fingerprintHistoryWindow(\n historyWindow: OrchestratorConfig<unknown>[\"historyWindow\"],\n): { router: HistoryWindowRoleFingerprint; agents: HistoryWindowRoleFingerprint } {\n return {\n router: fingerprintHistoryWindowRole(historyWindow?.router),\n agents: fingerprintHistoryWindowRole(historyWindow?.agents),\n };\n}\n\nfunction fingerprintHistoryWindowRole(\n window: number | ((...args: never[]) => unknown) | undefined,\n): HistoryWindowRoleFingerprint {\n if (window === undefined) {\n return null;\n }\n\n if (typeof window === \"function\") {\n return \"callback\";\n }\n\n return \"number\";\n}\n\n/**\n * Stable identity of one resolved intent's underlying unit. Agents\n * fingerprint by name; workflows by name + their own signature;\n * callbacks by a type marker only (their closure can't be hashed\n * deterministically, so drift covers add/remove/rename, not body\n * edits). Identical to the supervisor's `fingerprintUnit`.\n */\nfunction fingerprintUnit(entry: ResolvedIntentEntry): unknown {\n if (entry.type === \"callback\") {\n return { t: \"callback\" };\n }\n\n if (entry.type === \"workflow\") {\n const workflow = entry.unit;\n return { t: \"workflow\", n: workflow.name, s: workflow.signature };\n }\n\n return { t: \"agent\", n: entry.unit.name };\n}\n\n/**\n * FNV-1a 32-bit — the same hash `supervisor/signature.ts` and\n * `workflow/signature.ts` use. Deterministic, no crypto dependency,\n * cheap; signatures are 8-char hex.\n */\nfunction hash(input: string): string {\n let h = 0x811c9dc5;\n\n for (let i = 0; i < input.length; i++) {\n h ^= input.charCodeAt(i);\n h = (h + ((h << 1) + (h << 4) + (h << 7) + (h << 8) + (h << 24))) >>> 0;\n }\n\n return h.toString(16).padStart(8, \"0\");\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4CA,SAAgB,6BACd,QACA,SACQ;CACR,MAAM,qBAAqB,CAAC,GAAG,QAAQ,QAAQ,CAAC,CAAC,CAC9C,MAAM,CAAC,QAAQ,CAAC,YAAY,MAAM,cAAc,MAAM,CAAC,CAAC,CACxD,KAAK,CAAC,QAAQ,YAAY;EACzB,GAAG;EACH,GAAG,MAAM;EACT,GAAG,gBAAgB,KAAK;CAC1B,EAAE;CAEJ,MAAM,cAAc;EAClB,GAAG,OAAO;EACV,GAAG;EACH,GAAG,kBAAkB,OAAO,MAAM;EAClC,IAAI,OAAO,QAAQ,IAAI;EACvB,GAAG,OAAO,WAAW,IAAI;EACzB,GAAG,OAAO,gBAAgB;EAC1B,GAAG,OAAO,iBAAiB;EAC3B,IAAI,OAAO,UAAU,IAAI;EACzB,IAAI,yBAAyB,OAAO,aAAa;CACnD;CAEA,OAAO,KAAK,KAAK,UAAU,WAAW,CAAC;AACzC;;;;;;;AAQA,SAAS,kBAAkB,QAA8D;CACvF,IAAI,CAAC,QACH,OAAO;CAGT,IAAI,OAAQ,OAAiC,YAAY,YACvD,OAAQ,OAA6B,QAAQ;CAG/C,OAAQ,OAAyC,OAAO,QAAQ;AAClE;;;;;;;;AASA,SAAS,yBACP,eACgF;CAChF,OAAO;EACL,QAAQ,6BAA6B,eAAe,MAAM;EAC1D,QAAQ,6BAA6B,eAAe,MAAM;CAC5D;AACF;AAEA,SAAS,6BACP,QAC8B;CAC9B,IAAI,WAAW,QACb,OAAO;CAGT,IAAI,OAAO,WAAW,YACpB,OAAO;CAGT,OAAO;AACT;;;;;;;;AASA,SAAS,gBAAgB,OAAqC;CAC5D,IAAI,MAAM,SAAS,YACjB,OAAO,EAAE,GAAG,WAAW;CAGzB,IAAI,MAAM,SAAS,YAAY;EAC7B,MAAM,WAAW,MAAM;EACvB,OAAO;GAAE,GAAG;GAAY,GAAG,SAAS;GAAM,GAAG,SAAS;EAAU;CAClE;CAEA,OAAO;EAAE,GAAG;EAAS,GAAG,MAAM,KAAK;CAAK;AAC1C;;;;;;AAOA,SAAS,KAAK,OAAuB;CACnC,IAAI,IAAI;CAER,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;EACrC,KAAK,MAAM,WAAW,CAAC;EACvB,IAAK,MAAM,KAAK,MAAM,KAAK,MAAM,KAAK,MAAM,KAAK,MAAM,KAAK,SAAU;CACxE;CAEA,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,GAAG,GAAG;AACvC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
//#region ../@warlock.js/ai/src/orchestrator/window.ts
|
|
2
|
+
/**
|
|
3
|
+
* Framework-default history windows (orchestrator.md §4 Phase 4 — "5
|
|
4
|
+
* for the router, 15 for intents"). Applied when neither a per-entity
|
|
5
|
+
* override nor a tier default is configured.
|
|
6
|
+
*/
|
|
7
|
+
const DEFAULT_ROUTER_WINDOW = 5;
|
|
8
|
+
const DEFAULT_AGENTS_WINDOW = 15;
|
|
9
|
+
/**
|
|
10
|
+
* Apply a single window to a history array. A number keeps the last N
|
|
11
|
+
* messages (most recent, chronological order preserved); a callback
|
|
12
|
+
* takes full control of the slice (the escape hatch for token-counting
|
|
13
|
+
* or semantic windowing — §4 Phase 4). `N <= 0` keeps nothing.
|
|
14
|
+
*/
|
|
15
|
+
function applyWindow(messages, window) {
|
|
16
|
+
if (typeof window === "function") return window(messages);
|
|
17
|
+
if (window <= 0) return [];
|
|
18
|
+
if (messages.length <= window) return messages.slice();
|
|
19
|
+
return messages.slice(messages.length - window);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Phase 4 — window history (orchestrator.md §3 / §4 Phase 4). Applies
|
|
23
|
+
* the `historyWindow` cascade to the dev-supplied `history` before it
|
|
24
|
+
* is bound into the router and the dispatched agents. Two tiers,
|
|
25
|
+
* evaluated per-role:
|
|
26
|
+
*
|
|
27
|
+
* 1. Tier default — `historyWindow.router` / `historyWindow.agents`.
|
|
28
|
+
* 2. Framework default — `5` for the router, `15` for agents.
|
|
29
|
+
*
|
|
30
|
+
* (The first cascade layer — per-entity overrides on individual
|
|
31
|
+
* intents / the router entry — is the supervisor's concern: it lives
|
|
32
|
+
* on the intent entries the orchestrator spreads into the supervisor,
|
|
33
|
+
* and the supervisor applies it to the agent-windowed slice this phase
|
|
34
|
+
* produces. The orchestrator owns only the two role-level tiers.)
|
|
35
|
+
*
|
|
36
|
+
* Emits `orchestrator.history.windowed` with the agent-slice message
|
|
37
|
+
* count. Pure aside from the event — returns the per-role slices for
|
|
38
|
+
* the dispatch phase to thread through.
|
|
39
|
+
*/
|
|
40
|
+
function windowHistory(ctx, sessionId, history) {
|
|
41
|
+
const config = ctx.config.historyWindow;
|
|
42
|
+
const router = applyWindow(history, config?.router ?? 5);
|
|
43
|
+
const agents = applyWindow(history, config?.agents ?? 15);
|
|
44
|
+
ctx.emitter.emit("orchestrator.history.windowed", {
|
|
45
|
+
sessionId,
|
|
46
|
+
messageCount: agents.length
|
|
47
|
+
});
|
|
48
|
+
return {
|
|
49
|
+
router,
|
|
50
|
+
agents
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
//#endregion
|
|
55
|
+
export { windowHistory };
|
|
56
|
+
//# sourceMappingURL=window.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"window.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/orchestrator/window.ts"],"sourcesContent":["import type { Message } from \"../contracts/conversation-message.type\";\nimport type { OrchestratorEngineContext } from \"./engine-context.type\";\n\n/**\n * Framework-default history windows (orchestrator.md §4 Phase 4 — \"5\n * for the router, 15 for intents\"). Applied when neither a per-entity\n * override nor a tier default is configured.\n */\nexport const DEFAULT_ROUTER_WINDOW = 5;\nexport const DEFAULT_AGENTS_WINDOW = 15;\n\n/** A history window: keep the last N messages, or a custom slicer. */\nexport type HistoryWindowValue =\n | number\n | ((messages: Message[]) => Message[]);\n\n/**\n * The windowed history bound into each consumer for a turn (§4 Phase\n * 4). Applied per-dispatchable, independently: the router can see a\n * different slice than the dispatched agents.\n */\nexport type WindowedHistory = {\n /** Slice bound into the router's context. */\n router: Message[];\n /** Slice forwarded to every dispatched intent/agent. */\n agents: Message[];\n};\n\n/**\n * Apply a single window to a history array. A number keeps the last N\n * messages (most recent, chronological order preserved); a callback\n * takes full control of the slice (the escape hatch for token-counting\n * or semantic windowing — §4 Phase 4). `N <= 0` keeps nothing.\n */\nexport function applyWindow(\n messages: Message[],\n window: HistoryWindowValue,\n): Message[] {\n if (typeof window === \"function\") {\n return window(messages);\n }\n\n if (window <= 0) {\n return [];\n }\n\n if (messages.length <= window) {\n return messages.slice();\n }\n\n return messages.slice(messages.length - window);\n}\n\n/**\n * Phase 4 — window history (orchestrator.md §3 / §4 Phase 4). Applies\n * the `historyWindow` cascade to the dev-supplied `history` before it\n * is bound into the router and the dispatched agents. Two tiers,\n * evaluated per-role:\n *\n * 1. Tier default — `historyWindow.router` / `historyWindow.agents`.\n * 2. Framework default — `5` for the router, `15` for agents.\n *\n * (The first cascade layer — per-entity overrides on individual\n * intents / the router entry — is the supervisor's concern: it lives\n * on the intent entries the orchestrator spreads into the supervisor,\n * and the supervisor applies it to the agent-windowed slice this phase\n * produces. The orchestrator owns only the two role-level tiers.)\n *\n * Emits `orchestrator.history.windowed` with the agent-slice message\n * count. Pure aside from the event — returns the per-role slices for\n * the dispatch phase to thread through.\n */\nexport function windowHistory(\n ctx: OrchestratorEngineContext,\n sessionId: string,\n history: Message[],\n): WindowedHistory {\n const config = ctx.config.historyWindow;\n\n const router = applyWindow(history, config?.router ?? DEFAULT_ROUTER_WINDOW);\n const agents = applyWindow(history, config?.agents ?? DEFAULT_AGENTS_WINDOW);\n\n ctx.emitter.emit(\"orchestrator.history.windowed\", {\n sessionId,\n messageCount: agents.length,\n });\n\n return { router, agents };\n}\n"],"mappings":";;;;;;AAQA,MAAa,wBAAwB;AACrC,MAAa,wBAAwB;;;;;;;AAyBrC,SAAgB,YACd,UACA,QACW;CACX,IAAI,OAAO,WAAW,YACpB,OAAO,OAAO,QAAQ;CAGxB,IAAI,UAAU,GACZ,OAAO,CAAC;CAGV,IAAI,SAAS,UAAU,QACrB,OAAO,SAAS,MAAM;CAGxB,OAAO,SAAS,MAAM,SAAS,SAAS,MAAM;AAChD;;;;;;;;;;;;;;;;;;;;AAqBA,SAAgB,cACd,KACA,WACA,SACiB;CACjB,MAAM,SAAS,IAAI,OAAO;CAE1B,MAAM,SAAS,YAAY,SAAS,QAAQ,WAA+B;CAC3E,MAAM,SAAS,YAAY,SAAS,QAAQ,YAA+B;CAE3E,IAAI,QAAQ,KAAK,iCAAiC;EAChD;EACA,cAAc,OAAO;CACvB,CAAC;CAED,OAAO;EAAE;EAAQ;CAAO;AAC1B"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { SystemPromptContract } from "../contracts/system-prompt.contract.mjs";
|
|
2
|
+
import { PlannerCapability } from "../contracts/planner/planner-capability.type.mjs";
|
|
3
|
+
|
|
4
|
+
//#region ../@warlock.js/ai/src/planner/plan-prompt.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Assemble the plan-generation system prompt: optional caller framing on
|
|
7
|
+
* top, then the mechanical block listing every capability + its
|
|
8
|
+
* description and the rules for emitting an ordered plan.
|
|
9
|
+
*
|
|
10
|
+
* Runs once at factory time (the capability set is fixed for the
|
|
11
|
+
* planner's lifetime) — the produced string is baked onto the internal
|
|
12
|
+
* planning agent.
|
|
13
|
+
*/
|
|
14
|
+
declare function buildPlanSystemPrompt(capabilities: PlannerCapability[], maxSteps: number, prefix: SystemPromptContract | string | undefined): string;
|
|
15
|
+
//#endregion
|
|
16
|
+
export { buildPlanSystemPrompt };
|
|
17
|
+
//# sourceMappingURL=plan-prompt.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan-prompt.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai/src/planner/plan-prompt.ts"],"mappings":";;;;;;AAYA;;;;;;;iBAAgB,qBAAA,CACd,YAAA,EAAc,iBAAA,IACd,QAAA,UACA,MAAA,EAAQ,oBAAoB"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
//#region ../@warlock.js/ai/src/planner/plan-prompt.ts
|
|
2
|
+
/**
|
|
3
|
+
* Assemble the plan-generation system prompt: optional caller framing on
|
|
4
|
+
* top, then the mechanical block listing every capability + its
|
|
5
|
+
* description and the rules for emitting an ordered plan.
|
|
6
|
+
*
|
|
7
|
+
* Runs once at factory time (the capability set is fixed for the
|
|
8
|
+
* planner's lifetime) — the produced string is baked onto the internal
|
|
9
|
+
* planning agent.
|
|
10
|
+
*/
|
|
11
|
+
function buildPlanSystemPrompt(capabilities, maxSteps, prefix) {
|
|
12
|
+
const capabilityLines = capabilities.map((capability) => `- ${capability.name}: ${capability.description}`);
|
|
13
|
+
const sections = [];
|
|
14
|
+
const resolvedPrefix = resolvePrefix(prefix);
|
|
15
|
+
if (resolvedPrefix && resolvedPrefix.trim().length > 0) sections.push(resolvedPrefix.trim(), "");
|
|
16
|
+
sections.push("You are a planner. Break the user's goal into an ordered sequence of steps,", "each one dispatching exactly one of the available capabilities below.", "", "Available capabilities:", ...capabilityLines, "", "Rules:", `- Produce at most ${maxSteps} steps.`, "- Each step's `capability` must be exactly one name from the list above.", "- Each step's `input` is the concrete instruction passed to that capability.", "- Order the steps so each builds on the outputs of the ones before it.", "- Never invent a capability name that is not listed.", "- Keep the plan minimal — only the steps actually needed to satisfy the goal.");
|
|
17
|
+
return sections.join("\n");
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Resolve a caller-supplied `systemPrompt` (string or contract) to plain
|
|
21
|
+
* text. Returns `undefined` when none was supplied.
|
|
22
|
+
*/
|
|
23
|
+
function resolvePrefix(prompt) {
|
|
24
|
+
if (!prompt) return;
|
|
25
|
+
return typeof prompt === "string" ? prompt : prompt.resolve();
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
//#endregion
|
|
29
|
+
export { buildPlanSystemPrompt };
|
|
30
|
+
//# sourceMappingURL=plan-prompt.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan-prompt.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/planner/plan-prompt.ts"],"sourcesContent":["import type { PlannerCapability } from \"../contracts/planner/planner-capability.type\";\nimport type { SystemPromptContract } from \"../contracts/system-prompt.contract\";\n\n/**\n * Assemble the plan-generation system prompt: optional caller framing on\n * top, then the mechanical block listing every capability + its\n * description and the rules for emitting an ordered plan.\n *\n * Runs once at factory time (the capability set is fixed for the\n * planner's lifetime) — the produced string is baked onto the internal\n * planning agent.\n */\nexport function buildPlanSystemPrompt(\n capabilities: PlannerCapability[],\n maxSteps: number,\n prefix: SystemPromptContract | string | undefined,\n): string {\n const capabilityLines = capabilities.map(\n (capability) => `- ${capability.name}: ${capability.description}`,\n );\n\n const sections: string[] = [];\n const resolvedPrefix = resolvePrefix(prefix);\n\n if (resolvedPrefix && resolvedPrefix.trim().length > 0) {\n sections.push(resolvedPrefix.trim(), \"\");\n }\n\n sections.push(\n \"You are a planner. Break the user's goal into an ordered sequence of steps,\",\n \"each one dispatching exactly one of the available capabilities below.\",\n \"\",\n \"Available capabilities:\",\n ...capabilityLines,\n \"\",\n \"Rules:\",\n `- Produce at most ${maxSteps} steps.`,\n \"- Each step's `capability` must be exactly one name from the list above.\",\n \"- Each step's `input` is the concrete instruction passed to that capability.\",\n \"- Order the steps so each builds on the outputs of the ones before it.\",\n \"- Never invent a capability name that is not listed.\",\n \"- Keep the plan minimal — only the steps actually needed to satisfy the goal.\",\n );\n\n return sections.join(\"\\n\");\n}\n\n/**\n * Resolve a caller-supplied `systemPrompt` (string or contract) to plain\n * text. Returns `undefined` when none was supplied.\n */\nfunction resolvePrefix(prompt: SystemPromptContract | string | undefined): string | undefined {\n if (!prompt) {\n return undefined;\n }\n\n return typeof prompt === \"string\" ? prompt : prompt.resolve();\n}\n"],"mappings":";;;;;;;;;;AAYA,SAAgB,sBACd,cACA,UACA,QACQ;CACR,MAAM,kBAAkB,aAAa,KAClC,eAAe,KAAK,WAAW,KAAK,IAAI,WAAW,aACtD;CAEA,MAAM,WAAqB,CAAC;CAC5B,MAAM,iBAAiB,cAAc,MAAM;CAE3C,IAAI,kBAAkB,eAAe,KAAK,CAAC,CAAC,SAAS,GACnD,SAAS,KAAK,eAAe,KAAK,GAAG,EAAE;CAGzC,SAAS,KACP,+EACA,yEACA,IACA,2BACA,GAAG,iBACH,IACA,UACA,qBAAqB,SAAS,UAC9B,4EACA,gFACA,0EACA,wDACA,+EACF;CAEA,OAAO,SAAS,KAAK,IAAI;AAC3B;;;;;AAMA,SAAS,cAAc,QAAuE;CAC5F,IAAI,CAAC,QACH;CAGF,OAAO,OAAO,WAAW,WAAW,SAAS,OAAO,QAAQ;AAC9D"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { PlannerPlan } from "../contracts/planner/planner-plan.type.mjs";
|
|
2
|
+
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
3
|
+
|
|
4
|
+
//#region ../@warlock.js/ai/src/planner/plan-schema.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Build the Standard Schema the planning agent emits — an ordered
|
|
7
|
+
* `{ steps: [...], summary? }` plan whose every step references one of
|
|
8
|
+
* `capabilityNames` via the `capability` field.
|
|
9
|
+
*
|
|
10
|
+
* Mirrors the router's hand-built schema approach
|
|
11
|
+
* (`supervisor/router-factory.ts`): the JSON Schema extension carries
|
|
12
|
+
* the capability names as an `enum` so capable providers enforce the
|
|
13
|
+
* choice natively, while `validate()` still accepts the shape softly so
|
|
14
|
+
* providers without native structured output can pass a parsed object
|
|
15
|
+
* through. Validation is intentionally lenient on `capability` — an
|
|
16
|
+
* unknown name is surfaced later by the planner as a typed
|
|
17
|
+
* `PlannerPlanInvalidError`, with the full forensic context, rather
|
|
18
|
+
* than as an opaque schema issue here.
|
|
19
|
+
*
|
|
20
|
+
* `maxSteps`, when provided, is emitted as the `steps` array's
|
|
21
|
+
* `maxItems` so capable providers refuse to over-produce up front
|
|
22
|
+
* (the planner still truncates the tail to `skipped` defensively).
|
|
23
|
+
*/
|
|
24
|
+
declare function planSchema(capabilityNames: string[], maxSteps?: number): StandardSchemaV1<PlannerPlan>;
|
|
25
|
+
//#endregion
|
|
26
|
+
export { planSchema };
|
|
27
|
+
//# sourceMappingURL=plan-schema.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan-schema.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai/src/planner/plan-schema.ts"],"mappings":";;;;;;AAsBA;;;;;;;;;AAG+B;;;;;;;;iBAHf,UAAA,CACd,eAAA,YACA,QAAA,YACC,gBAAgB,CAAC,WAAA"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
//#region ../@warlock.js/ai/src/planner/plan-schema.ts
|
|
2
|
+
/**
|
|
3
|
+
* Build the Standard Schema the planning agent emits — an ordered
|
|
4
|
+
* `{ steps: [...], summary? }` plan whose every step references one of
|
|
5
|
+
* `capabilityNames` via the `capability` field.
|
|
6
|
+
*
|
|
7
|
+
* Mirrors the router's hand-built schema approach
|
|
8
|
+
* (`supervisor/router-factory.ts`): the JSON Schema extension carries
|
|
9
|
+
* the capability names as an `enum` so capable providers enforce the
|
|
10
|
+
* choice natively, while `validate()` still accepts the shape softly so
|
|
11
|
+
* providers without native structured output can pass a parsed object
|
|
12
|
+
* through. Validation is intentionally lenient on `capability` — an
|
|
13
|
+
* unknown name is surfaced later by the planner as a typed
|
|
14
|
+
* `PlannerPlanInvalidError`, with the full forensic context, rather
|
|
15
|
+
* than as an opaque schema issue here.
|
|
16
|
+
*
|
|
17
|
+
* `maxSteps`, when provided, is emitted as the `steps` array's
|
|
18
|
+
* `maxItems` so capable providers refuse to over-produce up front
|
|
19
|
+
* (the planner still truncates the tail to `skipped` defensively).
|
|
20
|
+
*/
|
|
21
|
+
function planSchema(capabilityNames, maxSteps) {
|
|
22
|
+
const stepsSchema = {
|
|
23
|
+
type: "array",
|
|
24
|
+
minItems: 1,
|
|
25
|
+
description: "Ordered steps to execute, one capability dispatch each.",
|
|
26
|
+
items: stepItemsSchema(capabilityNames)
|
|
27
|
+
};
|
|
28
|
+
if (maxSteps !== void 0) stepsSchema.maxItems = maxSteps;
|
|
29
|
+
const jsonSchema = {
|
|
30
|
+
type: "object",
|
|
31
|
+
properties: {
|
|
32
|
+
summary: {
|
|
33
|
+
type: "string",
|
|
34
|
+
description: "One-line summary of the overall strategy."
|
|
35
|
+
},
|
|
36
|
+
steps: stepsSchema
|
|
37
|
+
},
|
|
38
|
+
required: ["steps"],
|
|
39
|
+
additionalProperties: false
|
|
40
|
+
};
|
|
41
|
+
return { "~standard": {
|
|
42
|
+
version: 1,
|
|
43
|
+
vendor: "warlock-planner",
|
|
44
|
+
jsonSchema: { input: () => jsonSchema },
|
|
45
|
+
validate(value) {
|
|
46
|
+
if (!value || typeof value !== "object") return { issues: [{ message: "plan must be an object" }] };
|
|
47
|
+
const record = value;
|
|
48
|
+
if (!Array.isArray(record.steps) || record.steps.length === 0) return { issues: [{ message: "plan `steps` must be a non-empty array" }] };
|
|
49
|
+
const steps = [];
|
|
50
|
+
for (const raw of record.steps) {
|
|
51
|
+
const normalized = normalizeStep(raw);
|
|
52
|
+
if (!normalized) return { issues: [{ message: "each plan step must carry a string `capability` and `input`" }] };
|
|
53
|
+
steps.push(normalized);
|
|
54
|
+
}
|
|
55
|
+
const summary = typeof record.summary === "string" ? record.summary : void 0;
|
|
56
|
+
return { value: summary !== void 0 ? {
|
|
57
|
+
steps,
|
|
58
|
+
summary
|
|
59
|
+
} : { steps } };
|
|
60
|
+
}
|
|
61
|
+
} };
|
|
62
|
+
}
|
|
63
|
+
/** Per-step JSON Schema object — one capability dispatch. */
|
|
64
|
+
function stepItemsSchema(capabilityNames) {
|
|
65
|
+
return {
|
|
66
|
+
type: "object",
|
|
67
|
+
properties: {
|
|
68
|
+
id: {
|
|
69
|
+
type: "string",
|
|
70
|
+
description: "Stable step id, referenced by dependsOn."
|
|
71
|
+
},
|
|
72
|
+
capability: {
|
|
73
|
+
type: "string",
|
|
74
|
+
enum: capabilityNames,
|
|
75
|
+
description: "Name of the capability to dispatch for this step."
|
|
76
|
+
},
|
|
77
|
+
input: {
|
|
78
|
+
type: "string",
|
|
79
|
+
description: "Concrete input passed to the capability's execute()."
|
|
80
|
+
},
|
|
81
|
+
reason: {
|
|
82
|
+
type: "string",
|
|
83
|
+
description: "Why this step exists."
|
|
84
|
+
},
|
|
85
|
+
dependsOn: {
|
|
86
|
+
type: "array",
|
|
87
|
+
items: { type: "string" },
|
|
88
|
+
description: "Ids of steps this one conceptually follows."
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
required: ["capability", "input"],
|
|
92
|
+
additionalProperties: false
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Coerce one raw step object into a {@link PlannerStep}, returning
|
|
97
|
+
* `undefined` when the mandatory `capability` / `input` strings are
|
|
98
|
+
* missing. Optional fields are copied only when well-typed.
|
|
99
|
+
*/
|
|
100
|
+
function normalizeStep(raw) {
|
|
101
|
+
if (!raw || typeof raw !== "object") return;
|
|
102
|
+
const record = raw;
|
|
103
|
+
if (typeof record.capability !== "string" || record.capability.length === 0) return;
|
|
104
|
+
if (typeof record.input !== "string") return;
|
|
105
|
+
const step = {
|
|
106
|
+
capability: record.capability,
|
|
107
|
+
input: record.input
|
|
108
|
+
};
|
|
109
|
+
if (typeof record.id === "string") step.id = record.id;
|
|
110
|
+
if (typeof record.reason === "string") step.reason = record.reason;
|
|
111
|
+
if (Array.isArray(record.dependsOn) && record.dependsOn.every((entry) => typeof entry === "string")) step.dependsOn = record.dependsOn;
|
|
112
|
+
return step;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
//#endregion
|
|
116
|
+
export { planSchema };
|
|
117
|
+
//# sourceMappingURL=plan-schema.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan-schema.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/planner/plan-schema.ts"],"sourcesContent":["import type { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport type { PlannerPlan, PlannerStep } from \"../contracts/planner/planner-plan.type\";\n\n/**\n * Build the Standard Schema the planning agent emits — an ordered\n * `{ steps: [...], summary? }` plan whose every step references one of\n * `capabilityNames` via the `capability` field.\n *\n * Mirrors the router's hand-built schema approach\n * (`supervisor/router-factory.ts`): the JSON Schema extension carries\n * the capability names as an `enum` so capable providers enforce the\n * choice natively, while `validate()` still accepts the shape softly so\n * providers without native structured output can pass a parsed object\n * through. Validation is intentionally lenient on `capability` — an\n * unknown name is surfaced later by the planner as a typed\n * `PlannerPlanInvalidError`, with the full forensic context, rather\n * than as an opaque schema issue here.\n *\n * `maxSteps`, when provided, is emitted as the `steps` array's\n * `maxItems` so capable providers refuse to over-produce up front\n * (the planner still truncates the tail to `skipped` defensively).\n */\nexport function planSchema(\n capabilityNames: string[],\n maxSteps?: number,\n): StandardSchemaV1<PlannerPlan> {\n const stepsSchema: Record<string, unknown> = {\n type: \"array\",\n minItems: 1,\n description: \"Ordered steps to execute, one capability dispatch each.\",\n items: stepItemsSchema(capabilityNames),\n };\n\n if (maxSteps !== undefined) {\n stepsSchema.maxItems = maxSteps;\n }\n\n const jsonSchema = {\n type: \"object\",\n properties: {\n summary: {\n type: \"string\",\n description: \"One-line summary of the overall strategy.\",\n },\n steps: stepsSchema,\n },\n required: [\"steps\"],\n additionalProperties: false,\n };\n\n return {\n \"~standard\": {\n version: 1,\n vendor: \"warlock-planner\",\n jsonSchema: {\n input: () => jsonSchema,\n },\n validate(value: unknown): StandardSchemaV1.Result<PlannerPlan> {\n if (!value || typeof value !== \"object\") {\n return { issues: [{ message: \"plan must be an object\" }] };\n }\n\n const record = value as { steps?: unknown; summary?: unknown };\n\n if (!Array.isArray(record.steps) || record.steps.length === 0) {\n return { issues: [{ message: \"plan `steps` must be a non-empty array\" }] };\n }\n\n const steps: PlannerStep[] = [];\n\n for (const raw of record.steps) {\n const normalized = normalizeStep(raw);\n\n if (!normalized) {\n return {\n issues: [{ message: \"each plan step must carry a string `capability` and `input`\" }],\n };\n }\n\n steps.push(normalized);\n }\n\n const summary = typeof record.summary === \"string\" ? record.summary : undefined;\n\n return { value: summary !== undefined ? { steps, summary } : { steps } };\n },\n } as StandardSchemaV1<PlannerPlan>[\"~standard\"] & {\n jsonSchema: { input: () => Record<string, unknown> };\n },\n };\n}\n\n/** Per-step JSON Schema object — one capability dispatch. */\nfunction stepItemsSchema(capabilityNames: string[]): Record<string, unknown> {\n return {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Stable step id, referenced by dependsOn.\" },\n capability: {\n type: \"string\",\n enum: capabilityNames,\n description: \"Name of the capability to dispatch for this step.\",\n },\n input: {\n type: \"string\",\n description: \"Concrete input passed to the capability's execute().\",\n },\n reason: { type: \"string\", description: \"Why this step exists.\" },\n dependsOn: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Ids of steps this one conceptually follows.\",\n },\n },\n required: [\"capability\", \"input\"],\n additionalProperties: false,\n };\n}\n\n/**\n * Coerce one raw step object into a {@link PlannerStep}, returning\n * `undefined` when the mandatory `capability` / `input` strings are\n * missing. Optional fields are copied only when well-typed.\n */\nfunction normalizeStep(raw: unknown): PlannerStep | undefined {\n if (!raw || typeof raw !== \"object\") {\n return undefined;\n }\n\n const record = raw as {\n id?: unknown;\n capability?: unknown;\n input?: unknown;\n reason?: unknown;\n dependsOn?: unknown;\n };\n\n if (typeof record.capability !== \"string\" || record.capability.length === 0) {\n return undefined;\n }\n\n if (typeof record.input !== \"string\") {\n return undefined;\n }\n\n const step: PlannerStep = {\n capability: record.capability,\n input: record.input,\n };\n\n if (typeof record.id === \"string\") {\n step.id = record.id;\n }\n\n if (typeof record.reason === \"string\") {\n step.reason = record.reason;\n }\n\n if (Array.isArray(record.dependsOn) && record.dependsOn.every((entry) => typeof entry === \"string\")) {\n step.dependsOn = record.dependsOn as string[];\n }\n\n return step;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAsBA,SAAgB,WACd,iBACA,UAC+B;CAC/B,MAAM,cAAuC;EAC3C,MAAM;EACN,UAAU;EACV,aAAa;EACb,OAAO,gBAAgB,eAAe;CACxC;CAEA,IAAI,aAAa,QACf,YAAY,WAAW;CAGzB,MAAM,aAAa;EACjB,MAAM;EACN,YAAY;GACV,SAAS;IACP,MAAM;IACN,aAAa;GACf;GACA,OAAO;EACT;EACA,UAAU,CAAC,OAAO;EAClB,sBAAsB;CACxB;CAEA,OAAO,EACL,aAAa;EACX,SAAS;EACT,QAAQ;EACR,YAAY,EACV,aAAa,WACf;EACA,SAAS,OAAsD;GAC7D,IAAI,CAAC,SAAS,OAAO,UAAU,UAC7B,OAAO,EAAE,QAAQ,CAAC,EAAE,SAAS,yBAAyB,CAAC,EAAE;GAG3D,MAAM,SAAS;GAEf,IAAI,CAAC,MAAM,QAAQ,OAAO,KAAK,KAAK,OAAO,MAAM,WAAW,GAC1D,OAAO,EAAE,QAAQ,CAAC,EAAE,SAAS,yCAAyC,CAAC,EAAE;GAG3E,MAAM,QAAuB,CAAC;GAE9B,KAAK,MAAM,OAAO,OAAO,OAAO;IAC9B,MAAM,aAAa,cAAc,GAAG;IAEpC,IAAI,CAAC,YACH,OAAO,EACL,QAAQ,CAAC,EAAE,SAAS,8DAA8D,CAAC,EACrF;IAGF,MAAM,KAAK,UAAU;GACvB;GAEA,MAAM,UAAU,OAAO,OAAO,YAAY,WAAW,OAAO,UAAU;GAEtE,OAAO,EAAE,OAAO,YAAY,SAAY;IAAE;IAAO;GAAQ,IAAI,EAAE,MAAM,EAAE;EACzE;CACF,EAGF;AACF;;AAGA,SAAS,gBAAgB,iBAAoD;CAC3E,OAAO;EACL,MAAM;EACN,YAAY;GACV,IAAI;IAAE,MAAM;IAAU,aAAa;GAA2C;GAC9E,YAAY;IACV,MAAM;IACN,MAAM;IACN,aAAa;GACf;GACA,OAAO;IACL,MAAM;IACN,aAAa;GACf;GACA,QAAQ;IAAE,MAAM;IAAU,aAAa;GAAwB;GAC/D,WAAW;IACT,MAAM;IACN,OAAO,EAAE,MAAM,SAAS;IACxB,aAAa;GACf;EACF;EACA,UAAU,CAAC,cAAc,OAAO;EAChC,sBAAsB;CACxB;AACF;;;;;;AAOA,SAAS,cAAc,KAAuC;CAC5D,IAAI,CAAC,OAAO,OAAO,QAAQ,UACzB;CAGF,MAAM,SAAS;CAQf,IAAI,OAAO,OAAO,eAAe,YAAY,OAAO,WAAW,WAAW,GACxE;CAGF,IAAI,OAAO,OAAO,UAAU,UAC1B;CAGF,MAAM,OAAoB;EACxB,YAAY,OAAO;EACnB,OAAO,OAAO;CAChB;CAEA,IAAI,OAAO,OAAO,OAAO,UACvB,KAAK,KAAK,OAAO;CAGnB,IAAI,OAAO,OAAO,WAAW,UAC3B,KAAK,SAAS,OAAO;CAGvB,IAAI,MAAM,QAAQ,OAAO,SAAS,KAAK,OAAO,UAAU,OAAO,UAAU,OAAO,UAAU,QAAQ,GAChG,KAAK,YAAY,OAAO;CAG1B,OAAO;AACT"}
|