@warlock.js/ai 4.2.11 → 4.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +61 -1
- package/cjs/index.cjs +10151 -4625
- package/cjs/index.cjs.map +1 -1
- package/cjs/magic-string.es-BtxW4VqG.cjs +1015 -0
- package/cjs/magic-string.es-BtxW4VqG.cjs.map +1 -0
- package/cjs/matcher-logic-SBnzYohQ.cjs +217 -0
- package/cjs/matcher-logic-SBnzYohQ.cjs.map +1 -0
- package/cjs/matchers-BBh3gyB-.cjs +13739 -0
- package/cjs/matchers-BBh3gyB-.cjs.map +1 -0
- package/esm/agent/agent-config.type.d.mts +19 -6
- package/esm/agent/agent-config.type.d.mts.map +1 -1
- package/esm/agent/agent.d.mts.map +1 -1
- package/esm/agent/agent.mjs +17 -6
- package/esm/agent/agent.mjs.map +1 -1
- package/esm/agent/index.d.mts +2 -1
- package/esm/agent/index.mjs +1 -0
- package/esm/agent/spawn-sub-agent.d.mts +87 -0
- package/esm/agent/spawn-sub-agent.d.mts.map +1 -0
- package/esm/agent/spawn-sub-agent.mjs +68 -0
- package/esm/agent/spawn-sub-agent.mjs.map +1 -0
- package/esm/ai.d.mts +58 -3
- package/esm/ai.d.mts.map +1 -1
- package/esm/ai.mjs +58 -3
- package/esm/ai.mjs.map +1 -1
- package/esm/batch/batch.d.mts +43 -0
- package/esm/batch/batch.d.mts.map +1 -0
- package/esm/batch/batch.mjs +179 -0
- package/esm/batch/batch.mjs.map +1 -0
- package/esm/batch/batch.type.d.mts +144 -0
- package/esm/batch/batch.type.d.mts.map +1 -0
- package/esm/batch/index.mjs +3 -0
- package/esm/batch/run-batch-item.mjs +100 -0
- package/esm/batch/run-batch-item.mjs.map +1 -0
- package/esm/batch/run-with-concurrency.mjs +39 -0
- package/esm/batch/run-with-concurrency.mjs.map +1 -0
- package/esm/checkpoint/index.d.mts +3 -0
- package/esm/checkpoint/memory.d.mts +21 -0
- package/esm/checkpoint/memory.d.mts.map +1 -0
- package/esm/checkpoint/memory.mjs +0 -0
- package/esm/checkpoint/memory.mjs.map +1 -0
- package/esm/checkpoint/pg.d.mts +37 -0
- package/esm/checkpoint/pg.d.mts.map +1 -0
- package/esm/checkpoint/pg.mjs +265 -0
- package/esm/checkpoint/pg.mjs.map +1 -0
- package/esm/checkpoint/redis.d.mts +39 -0
- package/esm/checkpoint/redis.d.mts.map +1 -0
- package/esm/checkpoint/redis.mjs +200 -0
- package/esm/checkpoint/redis.mjs.map +1 -0
- package/esm/config.d.mts +61 -14
- package/esm/config.d.mts.map +1 -1
- package/esm/config.mjs +25 -6
- package/esm/config.mjs.map +1 -1
- package/esm/contracts/agent/agent.contract.d.mts +43 -0
- package/esm/contracts/agent/agent.contract.d.mts.map +1 -1
- package/esm/contracts/agent/eval.type.d.mts +143 -0
- package/esm/contracts/agent/eval.type.d.mts.map +1 -0
- package/esm/contracts/agent/index.d.mts +1 -0
- package/esm/contracts/events/supervisor-events.type.d.mts +3 -3
- package/esm/contracts/fallback-model.contract.d.mts +65 -0
- package/esm/contracts/fallback-model.contract.d.mts.map +1 -0
- package/esm/contracts/index.d.mts +32 -12
- package/esm/contracts/memory/index.d.mts +4 -0
- package/esm/contracts/memory/memory-config.type.d.mts +150 -0
- package/esm/contracts/memory/memory-config.type.d.mts.map +1 -0
- package/esm/contracts/memory/memory-item.type.d.mts +64 -0
- package/esm/contracts/memory/memory-item.type.d.mts.map +1 -0
- package/esm/contracts/memory/memory.contract.d.mts +87 -0
- package/esm/contracts/memory/memory.contract.d.mts.map +1 -0
- package/esm/contracts/memory/recall-options.type.d.mts +33 -0
- package/esm/contracts/memory/recall-options.type.d.mts.map +1 -0
- package/esm/contracts/middleware/index.d.mts +2 -2
- package/esm/contracts/middleware/middleware-context.type.d.mts +42 -2
- package/esm/contracts/middleware/middleware-context.type.d.mts.map +1 -1
- package/esm/contracts/middleware/middleware.contract.d.mts +46 -2
- package/esm/contracts/middleware/middleware.contract.d.mts.map +1 -1
- package/esm/contracts/model.contract.d.mts +63 -2
- package/esm/contracts/model.contract.d.mts.map +1 -1
- package/esm/contracts/orchestrator/checkpoint-store.contract.d.mts +91 -0
- package/esm/contracts/orchestrator/checkpoint-store.contract.d.mts.map +1 -0
- package/esm/contracts/orchestrator/index.d.mts +8 -0
- package/esm/contracts/orchestrator/orchestrator-commands.type.d.mts +43 -0
- package/esm/contracts/orchestrator/orchestrator-commands.type.d.mts.map +1 -0
- package/esm/contracts/orchestrator/orchestrator-config.type.d.mts +170 -0
- package/esm/contracts/orchestrator/orchestrator-config.type.d.mts.map +1 -0
- package/esm/contracts/orchestrator/orchestrator-event.type.d.mts +118 -0
- package/esm/contracts/orchestrator/orchestrator-event.type.d.mts.map +1 -0
- package/esm/contracts/orchestrator/orchestrator-execute-options.type.d.mts +44 -0
- package/esm/contracts/orchestrator/orchestrator-execute-options.type.d.mts.map +1 -0
- package/esm/contracts/orchestrator/orchestrator.contract.d.mts +129 -0
- package/esm/contracts/orchestrator/orchestrator.contract.d.mts.map +1 -0
- package/esm/contracts/orchestrator/session.contract.d.mts +26 -0
- package/esm/contracts/orchestrator/session.contract.d.mts.map +1 -0
- package/esm/contracts/orchestrator/snapshot-store.contract.d.mts +89 -0
- package/esm/contracts/orchestrator/snapshot-store.contract.d.mts.map +1 -0
- package/esm/contracts/planner/index.d.mts +6 -0
- package/esm/contracts/planner/planner-capability.type.d.mts +39 -0
- package/esm/contracts/planner/planner-capability.type.d.mts.map +1 -0
- package/esm/contracts/planner/planner-config.type.d.mts +78 -0
- package/esm/contracts/planner/planner-config.type.d.mts.map +1 -0
- package/esm/contracts/planner/planner-execute-options.type.d.mts +43 -0
- package/esm/contracts/planner/planner-execute-options.type.d.mts.map +1 -0
- package/esm/contracts/planner/planner-plan.type.d.mts +48 -0
- package/esm/contracts/planner/planner-plan.type.d.mts.map +1 -0
- package/esm/contracts/planner/planner-result.type.d.mts +82 -0
- package/esm/contracts/planner/planner-result.type.d.mts.map +1 -0
- package/esm/contracts/planner/planner.contract.d.mts +60 -0
- package/esm/contracts/planner/planner.contract.d.mts.map +1 -0
- package/esm/contracts/result/base-report.type.d.mts +7 -2
- package/esm/contracts/result/base-report.type.d.mts.map +1 -1
- package/esm/contracts/result/base-report.type.mjs.map +1 -1
- package/esm/contracts/result/index.d.mts +2 -1
- package/esm/contracts/result/model-pricing.type.d.mts +10 -0
- package/esm/contracts/result/model-pricing.type.d.mts.map +1 -1
- package/esm/contracts/result/orchestrator-result.type.d.mts +139 -0
- package/esm/contracts/result/orchestrator-result.type.d.mts.map +1 -0
- package/esm/contracts/result/session-send-result.type.d.mts +12 -3
- package/esm/contracts/result/session-send-result.type.d.mts.map +1 -1
- package/esm/contracts/result/supervisor-result.type.d.mts +1 -1
- package/esm/contracts/result/usage.type.d.mts +24 -0
- package/esm/contracts/result/usage.type.d.mts.map +1 -1
- package/esm/contracts/sdk-adapter.contract.d.mts +1 -1
- package/esm/contracts/supervisor/dispatch-context.type.d.mts +3 -3
- package/esm/contracts/supervisor/evaluate-context.type.d.mts +1 -1
- package/esm/contracts/supervisor/index.d.mts +5 -5
- package/esm/contracts/supervisor/route-context.type.d.mts +2 -2
- package/esm/contracts/supervisor/supervisor-config.type.d.mts +55 -13
- package/esm/contracts/supervisor/supervisor-config.type.d.mts.map +1 -1
- package/esm/contracts/supervisor/supervisor-snapshot.type.d.mts +1 -1
- package/esm/contracts/supervisor/supervisor.contract.d.mts +9 -2
- package/esm/contracts/supervisor/supervisor.contract.d.mts.map +1 -1
- package/esm/contracts/workflow/index.d.mts +2 -2
- package/esm/contracts/workflow/workflow.contract.d.mts +28 -7
- package/esm/contracts/workflow/workflow.contract.d.mts.map +1 -1
- package/esm/errors/error-code.type.d.mts +1 -1
- package/esm/errors/index.d.mts +7 -0
- package/esm/errors/index.mjs +7 -0
- package/esm/errors/orchestrator-cancelled-error.d.mts +32 -0
- package/esm/errors/orchestrator-cancelled-error.d.mts.map +1 -0
- package/esm/errors/orchestrator-cancelled-error.mjs +31 -0
- package/esm/errors/orchestrator-cancelled-error.mjs.map +1 -0
- package/esm/errors/orchestrator-config-error.d.mts +26 -0
- package/esm/errors/orchestrator-config-error.d.mts.map +1 -0
- package/esm/errors/orchestrator-config-error.mjs +30 -0
- package/esm/errors/orchestrator-config-error.mjs.map +1 -0
- package/esm/errors/orchestrator-drift-error.d.mts +38 -0
- package/esm/errors/orchestrator-drift-error.d.mts.map +1 -0
- package/esm/errors/orchestrator-drift-error.mjs +37 -0
- package/esm/errors/orchestrator-drift-error.mjs.map +1 -0
- package/esm/errors/orchestrator-failed-error.d.mts +33 -0
- package/esm/errors/orchestrator-failed-error.d.mts.map +1 -0
- package/esm/errors/orchestrator-failed-error.mjs +36 -0
- package/esm/errors/orchestrator-failed-error.mjs.map +1 -0
- package/esm/errors/planner-cancelled-error.d.mts +33 -0
- package/esm/errors/planner-cancelled-error.d.mts.map +1 -0
- package/esm/errors/planner-cancelled-error.mjs +29 -0
- package/esm/errors/planner-cancelled-error.mjs.map +1 -0
- package/esm/errors/planner-failed-error.d.mts +40 -0
- package/esm/errors/planner-failed-error.d.mts.map +1 -0
- package/esm/errors/planner-failed-error.mjs +37 -0
- package/esm/errors/planner-failed-error.mjs.map +1 -0
- package/esm/errors/planner-plan-invalid-error.d.mts +21 -0
- package/esm/errors/planner-plan-invalid-error.d.mts.map +1 -0
- package/esm/errors/planner-plan-invalid-error.mjs +25 -0
- package/esm/errors/planner-plan-invalid-error.mjs.map +1 -0
- package/esm/eval/eval-runner.d.mts +17 -0
- package/esm/eval/eval-runner.d.mts.map +1 -0
- package/esm/eval/eval-runner.mjs +121 -0
- package/esm/eval/eval-runner.mjs.map +1 -0
- package/esm/eval/index.d.mts +29 -0
- package/esm/eval/index.d.mts.map +1 -0
- package/esm/eval/index.mjs +30 -0
- package/esm/eval/index.mjs.map +1 -0
- package/esm/eval/judge-scorer.d.mts +21 -0
- package/esm/eval/judge-scorer.d.mts.map +1 -0
- package/esm/eval/judge-scorer.mjs +87 -0
- package/esm/eval/judge-scorer.mjs.map +1 -0
- package/esm/eval/scorers.d.mts +50 -0
- package/esm/eval/scorers.d.mts.map +1 -0
- package/esm/eval/scorers.mjs +101 -0
- package/esm/eval/scorers.mjs.map +1 -0
- package/esm/index.d.mts +95 -30
- package/esm/index.mjs +66 -22
- package/esm/memory/derive-id.mjs +24 -0
- package/esm/memory/derive-id.mjs.map +1 -0
- package/esm/memory/episodic-memory.mjs +106 -0
- package/esm/memory/episodic-memory.mjs.map +1 -0
- package/esm/memory/index.d.mts +5 -0
- package/esm/memory/memory.d.mts +42 -0
- package/esm/memory/memory.d.mts.map +1 -0
- package/esm/memory/memory.mjs +166 -0
- package/esm/memory/memory.mjs.map +1 -0
- package/esm/memory/procedural-memory.mjs +103 -0
- package/esm/memory/procedural-memory.mjs.map +1 -0
- package/esm/memory/semantic-memory.mjs +80 -0
- package/esm/memory/semantic-memory.mjs.map +1 -0
- package/esm/memory/working-memory.mjs +62 -0
- package/esm/memory/working-memory.mjs.map +1 -0
- package/esm/middleware/builtins/budget-contract.type.d.mts +126 -0
- package/esm/middleware/builtins/budget-contract.type.d.mts.map +1 -0
- package/esm/middleware/builtins/budget.d.mts +71 -1
- package/esm/middleware/builtins/budget.d.mts.map +1 -1
- package/esm/middleware/builtins/budget.mjs +119 -4
- package/esm/middleware/builtins/budget.mjs.map +1 -1
- package/esm/middleware/builtins/semantic-cache.d.mts +1 -1
- package/esm/middleware/index.d.mts +2 -1
- package/esm/middleware/index.mjs +1 -1
- package/esm/middleware/pipeline.d.mts +9 -6
- package/esm/middleware/pipeline.d.mts.map +1 -1
- package/esm/middleware/pipeline.mjs.map +1 -1
- package/esm/mock/index.d.mts +1 -0
- package/esm/mock/index.mjs +1 -0
- package/esm/mock/mock-router.d.mts +63 -0
- package/esm/mock/mock-router.d.mts.map +1 -0
- package/esm/mock/mock-router.mjs +58 -0
- package/esm/mock/mock-router.mjs.map +1 -0
- package/esm/model/fallback-model.d.mts +45 -0
- package/esm/model/fallback-model.d.mts.map +1 -0
- package/esm/model/fallback-model.mjs +218 -0
- package/esm/model/fallback-model.mjs.map +1 -0
- package/esm/model/index.d.mts +2 -0
- package/esm/model/index.mjs +3 -0
- package/esm/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs +78 -0
- package/esm/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs.map +1 -0
- package/esm/node_modules/@vitest/expect/dist/index.mjs +1473 -0
- package/esm/node_modules/@vitest/expect/dist/index.mjs.map +1 -0
- package/esm/node_modules/@vitest/pretty-format/dist/index.mjs +888 -0
- package/esm/node_modules/@vitest/pretty-format/dist/index.mjs.map +1 -0
- package/esm/node_modules/@vitest/runner/dist/chunk-artifact.mjs +1533 -0
- package/esm/node_modules/@vitest/runner/dist/chunk-artifact.mjs.map +1 -0
- package/esm/node_modules/@vitest/runner/dist/index.mjs +3 -0
- package/esm/node_modules/@vitest/runner/dist/utils.mjs +3 -0
- package/esm/node_modules/@vitest/snapshot/dist/index.mjs +922 -0
- package/esm/node_modules/@vitest/snapshot/dist/index.mjs.map +1 -0
- package/esm/node_modules/@vitest/spy/dist/index.mjs +386 -0
- package/esm/node_modules/@vitest/spy/dist/index.mjs.map +1 -0
- package/esm/node_modules/@vitest/utils/dist/chunk-pathe.M-eThtNZ.mjs +82 -0
- package/esm/node_modules/@vitest/utils/dist/chunk-pathe.M-eThtNZ.mjs.map +1 -0
- package/esm/node_modules/@vitest/utils/dist/diff.mjs +1357 -0
- package/esm/node_modules/@vitest/utils/dist/diff.mjs.map +1 -0
- package/esm/node_modules/@vitest/utils/dist/display.mjs +559 -0
- package/esm/node_modules/@vitest/utils/dist/display.mjs.map +1 -0
- package/esm/node_modules/@vitest/utils/dist/error.mjs +38 -0
- package/esm/node_modules/@vitest/utils/dist/error.mjs.map +1 -0
- package/esm/node_modules/@vitest/utils/dist/helpers.mjs +181 -0
- package/esm/node_modules/@vitest/utils/dist/helpers.mjs.map +1 -0
- package/esm/node_modules/@vitest/utils/dist/offset.mjs +27 -0
- package/esm/node_modules/@vitest/utils/dist/offset.mjs.map +1 -0
- package/esm/node_modules/@vitest/utils/dist/serialize.mjs +77 -0
- package/esm/node_modules/@vitest/utils/dist/serialize.mjs.map +1 -0
- package/esm/node_modules/@vitest/utils/dist/source-map.mjs +374 -0
- package/esm/node_modules/@vitest/utils/dist/source-map.mjs.map +1 -0
- package/esm/node_modules/@vitest/utils/dist/timers.mjs +37 -0
- package/esm/node_modules/@vitest/utils/dist/timers.mjs.map +1 -0
- package/esm/node_modules/chai/index.mjs +2973 -0
- package/esm/node_modules/chai/index.mjs.map +1 -0
- package/esm/node_modules/magic-string/dist/magic-string.es.mjs +940 -0
- package/esm/node_modules/magic-string/dist/magic-string.es.mjs.map +1 -0
- package/esm/node_modules/tinyrainbow/dist/index.mjs +87 -0
- package/esm/node_modules/tinyrainbow/dist/index.mjs.map +1 -0
- package/esm/node_modules/vitest/dist/chunks/_commonjsHelpers.D26ty3Ew.mjs +6 -0
- package/esm/node_modules/vitest/dist/chunks/_commonjsHelpers.D26ty3Ew.mjs.map +1 -0
- package/esm/node_modules/vitest/dist/chunks/rpc.MzXet3jl.mjs +52 -0
- package/esm/node_modules/vitest/dist/chunks/rpc.MzXet3jl.mjs.map +1 -0
- package/esm/node_modules/vitest/dist/chunks/test.DNmyFkvJ.mjs +2697 -0
- package/esm/node_modules/vitest/dist/chunks/test.DNmyFkvJ.mjs.map +1 -0
- package/esm/node_modules/vitest/dist/chunks/utils.BX5Fg8C4.mjs +45 -0
- package/esm/node_modules/vitest/dist/chunks/utils.BX5Fg8C4.mjs.map +1 -0
- package/esm/orchestrator/as-tool.d.mts +42 -0
- package/esm/orchestrator/as-tool.d.mts.map +1 -0
- package/esm/orchestrator/as-tool.mjs +98 -0
- package/esm/orchestrator/as-tool.mjs.map +1 -0
- package/esm/orchestrator/checkpoint.mjs +75 -0
- package/esm/orchestrator/checkpoint.mjs.map +1 -0
- package/esm/orchestrator/commands.d.mts +38 -0
- package/esm/orchestrator/commands.d.mts.map +1 -0
- package/esm/orchestrator/commands.mjs +34 -0
- package/esm/orchestrator/commands.mjs.map +1 -0
- package/esm/orchestrator/compaction.mjs +206 -0
- package/esm/orchestrator/compaction.mjs.map +1 -0
- package/esm/orchestrator/dispatch.mjs +171 -0
- package/esm/orchestrator/dispatch.mjs.map +1 -0
- package/esm/orchestrator/emitter-port.type.d.mts +31 -0
- package/esm/orchestrator/emitter-port.type.d.mts.map +1 -0
- package/esm/orchestrator/emitter.d.mts +56 -0
- package/esm/orchestrator/emitter.d.mts.map +1 -0
- package/esm/orchestrator/emitter.mjs +85 -0
- package/esm/orchestrator/emitter.mjs.map +1 -0
- package/esm/orchestrator/engine-context.type.d.mts +56 -0
- package/esm/orchestrator/engine-context.type.d.mts.map +1 -0
- package/esm/orchestrator/execution.d.mts +116 -0
- package/esm/orchestrator/execution.d.mts.map +1 -0
- package/esm/orchestrator/execution.mjs +406 -0
- package/esm/orchestrator/execution.mjs.map +1 -0
- package/esm/orchestrator/index.d.mts +8 -0
- package/esm/orchestrator/index.mjs +10 -0
- package/esm/orchestrator/load.mjs +49 -0
- package/esm/orchestrator/load.mjs.map +1 -0
- package/esm/orchestrator/lock.mjs +75 -0
- package/esm/orchestrator/lock.mjs.map +1 -0
- package/esm/orchestrator/memory.d.mts +84 -0
- package/esm/orchestrator/memory.d.mts.map +1 -0
- package/esm/orchestrator/memory.mjs +141 -0
- package/esm/orchestrator/memory.mjs.map +1 -0
- package/esm/orchestrator/orchestrator-stream.d.mts +42 -0
- package/esm/orchestrator/orchestrator-stream.d.mts.map +1 -0
- package/esm/orchestrator/orchestrator-stream.mjs +98 -0
- package/esm/orchestrator/orchestrator-stream.mjs.map +1 -0
- package/esm/orchestrator/orchestrator.d.mts +38 -0
- package/esm/orchestrator/orchestrator.d.mts.map +1 -0
- package/esm/orchestrator/orchestrator.mjs +173 -0
- package/esm/orchestrator/orchestrator.mjs.map +1 -0
- package/esm/orchestrator/resume.mjs +74 -0
- package/esm/orchestrator/resume.mjs.map +1 -0
- package/esm/orchestrator/signature.d.mts +40 -0
- package/esm/orchestrator/signature.d.mts.map +1 -0
- package/esm/orchestrator/signature.mjs +120 -0
- package/esm/orchestrator/signature.mjs.map +1 -0
- package/esm/orchestrator/window.mjs +56 -0
- package/esm/orchestrator/window.mjs.map +1 -0
- package/esm/planner/index.d.mts +5 -0
- package/esm/planner/index.mjs +6 -0
- package/esm/planner/plan-prompt.d.mts +17 -0
- package/esm/planner/plan-prompt.d.mts.map +1 -0
- package/esm/planner/plan-prompt.mjs +30 -0
- package/esm/planner/plan-prompt.mjs.map +1 -0
- package/esm/planner/plan-schema.d.mts +27 -0
- package/esm/planner/plan-schema.d.mts.map +1 -0
- package/esm/planner/plan-schema.mjs +117 -0
- package/esm/planner/plan-schema.mjs.map +1 -0
- package/esm/planner/planner-run.d.mts +23 -0
- package/esm/planner/planner-run.d.mts.map +1 -0
- package/esm/planner/planner-run.mjs +344 -0
- package/esm/planner/planner-run.mjs.map +1 -0
- package/esm/planner/planner.d.mts +37 -0
- package/esm/planner/planner.d.mts.map +1 -0
- package/esm/planner/planner.mjs +120 -0
- package/esm/planner/planner.mjs.map +1 -0
- package/esm/planner/signature.d.mts +18 -0
- package/esm/planner/signature.d.mts.map +1 -0
- package/esm/planner/signature.mjs +27 -0
- package/esm/planner/signature.mjs.map +1 -0
- package/esm/snapshot/index.d.mts +3 -0
- package/esm/snapshot/memory.d.mts +26 -0
- package/esm/snapshot/memory.d.mts.map +1 -0
- package/esm/snapshot/memory.mjs +81 -0
- package/esm/snapshot/memory.mjs.map +1 -0
- package/esm/snapshot/pg.d.mts +41 -0
- package/esm/snapshot/pg.d.mts.map +1 -0
- package/esm/snapshot/pg.mjs +146 -0
- package/esm/snapshot/pg.mjs.map +1 -0
- package/esm/snapshot/redis.d.mts +42 -0
- package/esm/snapshot/redis.d.mts.map +1 -0
- package/esm/snapshot/redis.mjs +101 -0
- package/esm/snapshot/redis.mjs.map +1 -0
- package/esm/supervisor/as-tool.d.mts +0 -6
- package/esm/supervisor/as-tool.d.mts.map +1 -1
- package/esm/supervisor/as-tool.mjs +0 -6
- package/esm/supervisor/as-tool.mjs.map +1 -1
- package/esm/supervisor/execution.d.mts +43 -8
- package/esm/supervisor/execution.d.mts.map +1 -1
- package/esm/supervisor/execution.mjs +66 -16
- package/esm/supervisor/execution.mjs.map +1 -1
- package/esm/supervisor/fan-out.d.mts +65 -0
- package/esm/supervisor/fan-out.d.mts.map +1 -0
- package/esm/supervisor/fan-out.mjs +65 -0
- package/esm/supervisor/fan-out.mjs.map +1 -0
- package/esm/supervisor/index.d.mts +5 -3
- package/esm/supervisor/index.mjs +3 -1
- package/esm/supervisor/router-factory.d.mts +110 -0
- package/esm/supervisor/router-factory.d.mts.map +1 -0
- package/esm/supervisor/router-factory.mjs +141 -0
- package/esm/supervisor/router-factory.mjs.map +1 -0
- package/esm/supervisor/router-prompt.d.mts +1 -1
- package/esm/supervisor/snapshot.d.mts +4 -10
- package/esm/supervisor/snapshot.d.mts.map +1 -1
- package/esm/supervisor/snapshot.mjs +8 -16
- package/esm/supervisor/snapshot.mjs.map +1 -1
- package/esm/supervisor/supervisor.mjs +1 -0
- package/esm/supervisor/supervisor.mjs.map +1 -1
- package/esm/system-prompt/index.mjs +6 -0
- package/esm/system-prompt/system-prompt.d.mts +51 -3
- package/esm/system-prompt/system-prompt.d.mts.map +1 -1
- package/esm/system-prompt/system-prompt.mjs +52 -6
- package/esm/system-prompt/system-prompt.mjs.map +1 -1
- package/esm/testing/matcher-logic.d.mts +76 -0
- package/esm/testing/matcher-logic.d.mts.map +1 -0
- package/esm/testing/matcher-logic.mjs +144 -0
- package/esm/testing/matcher-logic.mjs.map +1 -0
- package/esm/testing/matchers.d.mts +48 -0
- package/esm/testing/matchers.d.mts.map +1 -0
- package/esm/testing/matchers.mjs +37 -0
- package/esm/testing/matchers.mjs.map +1 -0
- package/esm/testing/register-lazy.d.mts +20 -0
- package/esm/testing/register-lazy.d.mts.map +1 -0
- package/esm/testing/register-lazy.mjs +24 -0
- package/esm/testing/register-lazy.mjs.map +1 -0
- package/esm/tool/executable-as-tool.d.mts +87 -0
- package/esm/tool/executable-as-tool.d.mts.map +1 -0
- package/esm/tool/executable-as-tool.mjs +81 -0
- package/esm/tool/executable-as-tool.mjs.map +1 -0
- package/esm/tool/index.d.mts +2 -1
- package/esm/tool/index.mjs +1 -0
- package/esm/workflow/as-tool.mjs +0 -6
- package/esm/workflow/as-tool.mjs.map +1 -1
- package/esm/workflow/engine.mjs +2 -2
- package/esm/workflow/snapshot.mjs +13 -7
- package/esm/workflow/snapshot.mjs.map +1 -1
- package/esm/workflow/step-runner.mjs +1 -1
- package/esm/workflow/workflow.mjs +1 -0
- package/esm/workflow/workflow.mjs.map +1 -1
- package/llms-full.txt +947 -42
- package/llms.txt +13 -8
- package/package.json +3 -3
- package/skills/README.md +25 -5
- package/skills/ai-basics/SKILL.md +18 -7
- package/skills/ai-dx-helpers/SKILL.md +180 -0
- package/skills/attach-ai-middleware/SKILL.md +32 -3
- package/skills/handle-ai-errors/SKILL.md +20 -6
- package/skills/manage-ai-stores/SKILL.md +127 -0
- package/skills/persist-ai-data/SKILL.md +21 -10
- package/skills/pick-ai-provider/SKILL.md +46 -12
- package/skills/run-ai-agent/SKILL.md +51 -2
- package/skills/run-orchestrator/SKILL.md +198 -0
- package/skills/run-planner/SKILL.md +68 -0
- package/skills/run-supervisor/SKILL.md +47 -2
- package/skills/use-ai-memory/SKILL.md +124 -0
- package/skills/write-system-prompt/SKILL.md +14 -1
|
@@ -0,0 +1,406 @@
|
|
|
1
|
+
import { OrchestratorConfigError } from "../errors/orchestrator-config-error.mjs";
|
|
2
|
+
import { OrchestratorDriftError } from "../errors/orchestrator-drift-error.mjs";
|
|
3
|
+
import "../errors/index.mjs";
|
|
4
|
+
import { generateRunId } from "../utils/generate-run-id.mjs";
|
|
5
|
+
import { REPORT_SCHEMA_VERSION } from "../contracts/result/base-report.type.mjs";
|
|
6
|
+
import { resolveDefaultCheckpointStore, resolveDefaultSnapshotStore } from "../config.mjs";
|
|
7
|
+
import { injectMemories, outcomeTextFromTurn, recallForTurn, rememberTurnOutcome, resolveOrchestratorMemory } from "./memory.mjs";
|
|
8
|
+
import { persistCheckpoint, summarizeRoute } from "./checkpoint.mjs";
|
|
9
|
+
import { acquireLock } from "./lock.mjs";
|
|
10
|
+
import { runCompaction, runManualCompaction, shouldCompact } from "./compaction.mjs";
|
|
11
|
+
import { deriveRunId, dispatchTurn } from "./dispatch.mjs";
|
|
12
|
+
import { loadSession } from "./load.mjs";
|
|
13
|
+
import { resolveResume } from "./resume.mjs";
|
|
14
|
+
import { windowHistory } from "./window.mjs";
|
|
15
|
+
|
|
16
|
+
//#region ../@warlock.js/ai/src/orchestrator/execution.ts
|
|
17
|
+
/** Empty rolled-up usage for turns that never dispatched (drift/seed). */
|
|
18
|
+
const ZERO_USAGE = {
|
|
19
|
+
input: 0,
|
|
20
|
+
output: 0,
|
|
21
|
+
total: 0
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Per-call lifecycle engine — the single object the C1 factory
|
|
25
|
+
* constructs and drives. Owns the 7-phase lifecycle (orchestrator.md §3:
|
|
26
|
+
* load → drift → lock → window → dispatch → persist → compaction),
|
|
27
|
+
* resolving the durable stores (own config field → `ai.config` default)
|
|
28
|
+
* and adapting C1's three-tier {@link OrchestratorEmitter} to the
|
|
29
|
+
* {@link OrchestratorEmitterLike} port the phase modules call.
|
|
30
|
+
*
|
|
31
|
+
* The factory creates a fresh instance per `execute` / `stream` /
|
|
32
|
+
* `resume` / `command` call (single-call lifecycle invariant — §18.8);
|
|
33
|
+
* the heavy lifting lives in the standalone phase functions
|
|
34
|
+
* ({@link runTurn} / {@link runResume}) which this class delegates to.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* const execution = new OrchestratorExecution({
|
|
38
|
+
* config, entries, signature, emitter, input, options,
|
|
39
|
+
* });
|
|
40
|
+
* const result = await execution.run();
|
|
41
|
+
*/
|
|
42
|
+
var OrchestratorExecution = class {
|
|
43
|
+
constructor(params) {
|
|
44
|
+
this.params = params;
|
|
45
|
+
this.streamController = params.streamController;
|
|
46
|
+
this.ctx = {
|
|
47
|
+
config: params.config,
|
|
48
|
+
signature: params.signature,
|
|
49
|
+
checkpointStore: resolveCheckpointStore(params.config),
|
|
50
|
+
snapshotStore: resolveSnapshotStore(params.config),
|
|
51
|
+
emitter: adaptEmitter(params.emitter, generateRunId("orchestrator"), this.streamController),
|
|
52
|
+
memory: resolveOrchestratorMemory(params.config.memory)
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* `execute()` / `stream()` entry — run one turn through the 7-phase
|
|
57
|
+
* lifecycle. When a `streamController` was supplied, the adapter mirrors
|
|
58
|
+
* every emitted event into the stream and the controller is settled
|
|
59
|
+
* (`end` / `fail`) once the result resolves.
|
|
60
|
+
*/
|
|
61
|
+
async run() {
|
|
62
|
+
if (this.params.input === void 0 || !this.params.options) throw new OrchestratorConfigError(`ai.orchestrator("${this.params.config.name}"): internal — run() invoked without input/options`);
|
|
63
|
+
try {
|
|
64
|
+
const result = await runTurn(this.ctx, this.params.input, this.params.options);
|
|
65
|
+
this.streamController?.end(result);
|
|
66
|
+
return result;
|
|
67
|
+
} catch (error) {
|
|
68
|
+
this.streamController?.fail(error);
|
|
69
|
+
throw error;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* `resume()` entry — drain an interrupted `iterate: true` turn (§9).
|
|
74
|
+
* Returns `null` when nothing is in flight.
|
|
75
|
+
*/
|
|
76
|
+
async resume() {
|
|
77
|
+
if (!this.params.resumeSessionId) throw new OrchestratorConfigError(`ai.orchestrator("${this.params.config.name}"): internal — resume() invoked without a sessionId`);
|
|
78
|
+
return runResume(this.ctx, this.params.resumeSessionId, this.params.resumeOptions);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* `command("compact")` entry — run a manual compaction on demand (§11 /
|
|
82
|
+
* §12.1). Reuses the post-turn compaction code path against the
|
|
83
|
+
* caller-supplied history and returns the raw {@link CompactionResult}.
|
|
84
|
+
*/
|
|
85
|
+
async compact(args) {
|
|
86
|
+
return runManualCompaction(this.ctx, args.history);
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* Resolve the durable checkpoint store: the config's own field, falling
|
|
91
|
+
* back to `ai.config({ defaultCheckpointStore })`. Throws
|
|
92
|
+
* {@link OrchestratorConfigError} when neither resolves — persistence is
|
|
93
|
+
* always on (§8.1), so a turn can never run without a checkpoint store.
|
|
94
|
+
*/
|
|
95
|
+
function resolveCheckpointStore(config) {
|
|
96
|
+
const store = config.checkpointStore ?? resolveDefaultCheckpointStore();
|
|
97
|
+
if (!store) throw new OrchestratorConfigError(`ai.orchestrator("${config.name}"): a \`checkpointStore\` is required (set one on the config or via \`ai.config({ defaultCheckpointStore })\`)`);
|
|
98
|
+
return store;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Resolve the internal-supervisor snapshot store for `iterate: true`
|
|
102
|
+
* turns: the config's own field, falling back to
|
|
103
|
+
* `ai.config({ defaultSnapshotStore })`. Returns `undefined` for
|
|
104
|
+
* `iterate: false` orchestrators (no mid-turn resume — nothing to
|
|
105
|
+
* snapshot). The factory already guarantees presence when
|
|
106
|
+
* `iterate: true`, so the engine never asserts here.
|
|
107
|
+
*/
|
|
108
|
+
function resolveSnapshotStore(config) {
|
|
109
|
+
if (config.iterate !== true) return;
|
|
110
|
+
return config.snapshotStore ?? resolveDefaultSnapshotStore();
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Adapt C1's three-tier {@link OrchestratorEmitter} (whose `emit` takes
|
|
114
|
+
* `event, payload, identity, perCallHandlers?`) to the
|
|
115
|
+
* {@link OrchestratorEmitterLike} port the phase modules call (a 2-arg
|
|
116
|
+
* `emit(event, payload)` plus `bindPerCall`).
|
|
117
|
+
*
|
|
118
|
+
* The adapter injects the run identity centrally and, when a stream
|
|
119
|
+
* controller is present, mirrors every fully-stamped event into the
|
|
120
|
+
* stream pipe (§14.1 — the orchestrator's own events surface on the
|
|
121
|
+
* stream alongside the bubbled child events). `bindPerCall` registers
|
|
122
|
+
* the per-call `options.on` bag for the turn's duration and returns a
|
|
123
|
+
* disposer that clears it.
|
|
124
|
+
*/
|
|
125
|
+
function adaptEmitter(emitter, runId, streamController) {
|
|
126
|
+
const fullIdentity = {
|
|
127
|
+
runId,
|
|
128
|
+
rootRunId: runId
|
|
129
|
+
};
|
|
130
|
+
let perCall;
|
|
131
|
+
return {
|
|
132
|
+
emit(event, payload) {
|
|
133
|
+
const fullPayload = emitter.emit(event, payload, fullIdentity, perCall);
|
|
134
|
+
streamController?.push({
|
|
135
|
+
type: event,
|
|
136
|
+
...fullPayload
|
|
137
|
+
});
|
|
138
|
+
},
|
|
139
|
+
bindPerCall(handlers) {
|
|
140
|
+
perCall = handlers;
|
|
141
|
+
return () => {
|
|
142
|
+
perCall = void 0;
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Phase 2 — drift check (orchestrator.md §3 / §4 Phase 2). Compares the
|
|
149
|
+
* loaded checkpoint's `signature` against the current definition's.
|
|
150
|
+
* Mismatch throws `OrchestratorDriftError` synchronously unless
|
|
151
|
+
* `force` is set. Emits `orchestrator.drift.checked` either way. A new
|
|
152
|
+
* session (no loaded signature) never drifts.
|
|
153
|
+
*/
|
|
154
|
+
function assertNoDrift(ctx, sessionId, loadedSignature, force) {
|
|
155
|
+
const drifted = loadedSignature !== void 0 && loadedSignature !== ctx.signature;
|
|
156
|
+
ctx.emitter.emit("orchestrator.drift.checked", {
|
|
157
|
+
sessionId,
|
|
158
|
+
signature: ctx.signature,
|
|
159
|
+
drifted
|
|
160
|
+
});
|
|
161
|
+
if (drifted && !force) throw new OrchestratorDriftError(`orchestrator "${ctx.config.name}": signature drift on session "${sessionId}" — the definition changed since this session was last persisted. Pass { force: true } only after reviewing the change, or discard / migrate the session.`, {
|
|
162
|
+
savedSignature: loadedSignature,
|
|
163
|
+
currentSignature: ctx.signature,
|
|
164
|
+
sessionId
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Shallow-merge the per-call `state` patch (§5 — partial state
|
|
169
|
+
* override) over the loaded session-state seed. The merged value
|
|
170
|
+
* becomes the supervisor's seed for this turn.
|
|
171
|
+
*/
|
|
172
|
+
function applyStatePatch(seed, patch) {
|
|
173
|
+
if (!patch) return seed;
|
|
174
|
+
return {
|
|
175
|
+
...seed,
|
|
176
|
+
...patch
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Assemble the orchestrator-scope {@link OrchestratorReport} from the
|
|
181
|
+
* dispatched turn's child report and the turn snapshot. Wraps the
|
|
182
|
+
* child supervisor/agent report tree as `children[0]` (§15.6 —
|
|
183
|
+
* `children[]` carries only the CURRENT turn's dispatched primitive
|
|
184
|
+
* reports) while the per-turn forensic record lives on `turns[]`.
|
|
185
|
+
*/
|
|
186
|
+
function buildReport(ctx, sessionId, turnIndex, status, turnSnapshot, childReport) {
|
|
187
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
188
|
+
const usage = turnSnapshot?.usage ?? childReport?.usage ?? ZERO_USAGE;
|
|
189
|
+
return {
|
|
190
|
+
runId: deriveRunId(sessionId, ctx.config.version, turnIndex),
|
|
191
|
+
rootRunId: deriveRunId(sessionId, ctx.config.version, turnIndex),
|
|
192
|
+
name: ctx.config.name,
|
|
193
|
+
version: ctx.config.version,
|
|
194
|
+
sessionId,
|
|
195
|
+
type: "orchestrator",
|
|
196
|
+
status,
|
|
197
|
+
startedAt: turnSnapshot?.startedAt ?? now,
|
|
198
|
+
endedAt: turnSnapshot?.endedAt ?? now,
|
|
199
|
+
duration: turnSnapshot?.duration ?? 0,
|
|
200
|
+
usage,
|
|
201
|
+
children: childReport ? [childReport] : [],
|
|
202
|
+
reportSchemaVersion: 1,
|
|
203
|
+
turnIndex,
|
|
204
|
+
signature: ctx.signature,
|
|
205
|
+
turns: turnSnapshot ? [turnSnapshot] : []
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Map the dispatched supervisor result's report status onto the
|
|
210
|
+
* orchestrator's status surface (§15.6). A clean completion that is
|
|
211
|
+
* still mid-conversation reports `"awaiting-input"` (the session
|
|
212
|
+
* continues) rather than `"completed"`; failures and cancellations
|
|
213
|
+
* pass through.
|
|
214
|
+
*/
|
|
215
|
+
function deriveStatus(childStatus) {
|
|
216
|
+
if (childStatus === "completed") return "awaiting-input";
|
|
217
|
+
return childStatus;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Emit the terminal turn event matching the report status (§14.1).
|
|
221
|
+
*/
|
|
222
|
+
function emitTerminal(ctx, sessionId, turnIndex, status) {
|
|
223
|
+
if (status === "cancelled") {
|
|
224
|
+
ctx.emitter.emit("orchestrator.turn.cancelled", {
|
|
225
|
+
sessionId,
|
|
226
|
+
turnIndex
|
|
227
|
+
});
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
if (status === "failed" || status === "max-iterations") {
|
|
231
|
+
ctx.emitter.emit("orchestrator.turn.failed", {
|
|
232
|
+
sessionId,
|
|
233
|
+
turnIndex
|
|
234
|
+
});
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
if (status === "awaiting-input") {
|
|
238
|
+
ctx.emitter.emit("orchestrator.turn.awaiting-input", {
|
|
239
|
+
sessionId,
|
|
240
|
+
turnIndex
|
|
241
|
+
});
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
ctx.emitter.emit("orchestrator.turn.completed", {
|
|
245
|
+
sessionId,
|
|
246
|
+
turnIndex
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Run one turn end-to-end through the 7-phase lifecycle (orchestrator
|
|
251
|
+
* .md §3). The single entry the C1 factory's `execute()` delegates to.
|
|
252
|
+
*
|
|
253
|
+
* Phase order is the diagram's contract: load → drift → lock → window
|
|
254
|
+
* → dispatch → persist → compaction. Drift / config misuse throw;
|
|
255
|
+
* every other failure surfaces on `result.error` (the contract: the
|
|
256
|
+
* orchestrator never throws on runtime failure). Cancellation and
|
|
257
|
+
* failure do NOT persist a fresh checkpoint (§17 — state reverts to the
|
|
258
|
+
* pre-turn checkpoint).
|
|
259
|
+
*/
|
|
260
|
+
async function runTurn(ctx, input, options) {
|
|
261
|
+
const sessionId = options.sessionId;
|
|
262
|
+
const disposePerCall = ctx.emitter.bindPerCall(options.on);
|
|
263
|
+
try {
|
|
264
|
+
const loaded = await loadSession(ctx, sessionId);
|
|
265
|
+
ctx.emitter.emit("orchestrator.turn.starting", {
|
|
266
|
+
sessionId,
|
|
267
|
+
turnIndex: loaded.turnIndex
|
|
268
|
+
});
|
|
269
|
+
ctx.emitter.emit("orchestrator.session.loaded", {
|
|
270
|
+
sessionId,
|
|
271
|
+
turnIndex: loaded.turnIndex,
|
|
272
|
+
found: loaded.found
|
|
273
|
+
});
|
|
274
|
+
assertNoDrift(ctx, sessionId, loaded.record?.signature, options.force);
|
|
275
|
+
await acquireLock(ctx, sessionId, loaded.record);
|
|
276
|
+
const windowed = windowHistory(ctx, sessionId, options.history);
|
|
277
|
+
const seedState = applyStatePatch(loaded.state, options.state);
|
|
278
|
+
let turnContext = options.context;
|
|
279
|
+
if (ctx.memory) {
|
|
280
|
+
const recalled = await recallForTurn(ctx.memory, input);
|
|
281
|
+
turnContext = injectMemories(turnContext, ctx.memory, recalled);
|
|
282
|
+
}
|
|
283
|
+
const { result, state, turnSnapshot } = await dispatchTurn({
|
|
284
|
+
ctx,
|
|
285
|
+
sessionId,
|
|
286
|
+
input,
|
|
287
|
+
seedState,
|
|
288
|
+
turnIndex: loaded.turnIndex,
|
|
289
|
+
history: windowed.agents,
|
|
290
|
+
context: turnContext,
|
|
291
|
+
signal: options.signal
|
|
292
|
+
});
|
|
293
|
+
ctx.emitter.emit("orchestrator.turn.routed", {
|
|
294
|
+
sessionId,
|
|
295
|
+
turnIndex: loaded.turnIndex,
|
|
296
|
+
source: turnSnapshot.decision.source,
|
|
297
|
+
raw: turnSnapshot.decision.raw
|
|
298
|
+
});
|
|
299
|
+
const status = result.error ? deriveStatus(result.report.status) : "awaiting-input";
|
|
300
|
+
if (result.error) {
|
|
301
|
+
const report = buildReport(ctx, sessionId, loaded.turnIndex, status, turnSnapshot, result.report);
|
|
302
|
+
emitTerminal(ctx, sessionId, loaded.turnIndex, status);
|
|
303
|
+
return {
|
|
304
|
+
data: result.data,
|
|
305
|
+
error: result.error,
|
|
306
|
+
usage: result.usage,
|
|
307
|
+
report,
|
|
308
|
+
sessionId,
|
|
309
|
+
turnIndex: loaded.turnIndex
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
await persistCheckpoint({
|
|
313
|
+
ctx,
|
|
314
|
+
sessionId,
|
|
315
|
+
turnIndex: loaded.turnIndex,
|
|
316
|
+
state,
|
|
317
|
+
lastRoute: summarizeRoute(turnSnapshot.decision.raw),
|
|
318
|
+
summarizedThrough: loaded.record?.summarized_through ?? null
|
|
319
|
+
});
|
|
320
|
+
if (ctx.memory) await rememberTurnOutcome(ctx.memory, input, outcomeTextFromTurn(result.data, turnSnapshot));
|
|
321
|
+
let compaction;
|
|
322
|
+
if (shouldCompact(ctx, loaded.turnIndex)) {
|
|
323
|
+
const outcome = await runCompaction(ctx, sessionId, options.history);
|
|
324
|
+
if (outcome) {
|
|
325
|
+
compaction = outcome.compaction;
|
|
326
|
+
if (outcome.applied) await advanceSummarizedThrough(ctx, sessionId, outcome.compaction.replacesToIndex);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
const report = buildReport(ctx, sessionId, loaded.turnIndex, "awaiting-input", turnSnapshot, result.report);
|
|
330
|
+
emitTerminal(ctx, sessionId, loaded.turnIndex, "awaiting-input");
|
|
331
|
+
return {
|
|
332
|
+
data: result.data,
|
|
333
|
+
error: void 0,
|
|
334
|
+
usage: result.usage,
|
|
335
|
+
report,
|
|
336
|
+
sessionId,
|
|
337
|
+
turnIndex: loaded.turnIndex,
|
|
338
|
+
compaction
|
|
339
|
+
};
|
|
340
|
+
} finally {
|
|
341
|
+
disposePerCall();
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* After a framework-applied compaction (`onCompact` succeeded), advance
|
|
346
|
+
* the persisted `summarized_through` to the compaction's
|
|
347
|
+
* `replacesToIndex` (§12.2 step 4). Re-saves the latest row with the
|
|
348
|
+
* updated marker (append-only stores keep the prior row).
|
|
349
|
+
*/
|
|
350
|
+
async function advanceSummarizedThrough(ctx, sessionId, replacesToIndex) {
|
|
351
|
+
const latest = await ctx.checkpointStore.load(ctx.config.name, sessionId);
|
|
352
|
+
if (!latest) return;
|
|
353
|
+
await ctx.checkpointStore.save({
|
|
354
|
+
...latest,
|
|
355
|
+
summarized_through: replacesToIndex,
|
|
356
|
+
saved_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* §9 resume protocol entry the C1 factory's `resume()` delegates to.
|
|
361
|
+
* Returns `null` when no in-flight `iterate: true` turn is detected;
|
|
362
|
+
* otherwise drains the interrupted supervisor run, persists a fresh
|
|
363
|
+
* checkpoint for the resumed turn, and returns the completed result.
|
|
364
|
+
*
|
|
365
|
+
* Runs the same Phase 2 drift check as `runTurn` (§9.4). The heavy
|
|
366
|
+
* lifting lives in `resume.ts`; this wrapper threads the engine
|
|
367
|
+
* context.
|
|
368
|
+
*/
|
|
369
|
+
async function runResume(ctx, sessionId, options) {
|
|
370
|
+
const disposePerCall = ctx.emitter.bindPerCall(options?.on);
|
|
371
|
+
try {
|
|
372
|
+
return await resolveResume(ctx, sessionId, options, {
|
|
373
|
+
assertNoDrift: (loadedSignature) => assertNoDrift(ctx, sessionId, loadedSignature, options?.force),
|
|
374
|
+
buildReport: (turnIndex, status, turnSnapshot, childReport) => buildReport(ctx, sessionId, turnIndex, status, turnSnapshot, childReport),
|
|
375
|
+
deriveStatus,
|
|
376
|
+
emitTerminal: (turnIndex, status) => emitTerminal(ctx, sessionId, turnIndex, status),
|
|
377
|
+
persist: (turnIndex, state, lastRoute, summarizedThrough) => persistCheckpoint({
|
|
378
|
+
ctx,
|
|
379
|
+
sessionId,
|
|
380
|
+
turnIndex,
|
|
381
|
+
state,
|
|
382
|
+
lastRoute,
|
|
383
|
+
summarizedThrough
|
|
384
|
+
})
|
|
385
|
+
});
|
|
386
|
+
} finally {
|
|
387
|
+
disposePerCall();
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* The `stream()` entry. The orchestrator's streaming surface bubbles
|
|
392
|
+
* child agent/supervisor events under their own namespace (§14.2); the
|
|
393
|
+
* C1 stream controller owns the `StreamContract` wiring. This engine
|
|
394
|
+
* entry runs the same lifecycle as `runTurn` — the C1 factory passes a
|
|
395
|
+
* per-call `on` bag wired to the stream controller, so the engine needs
|
|
396
|
+
* no streaming-specific branch. Exposed as a distinct name for the
|
|
397
|
+
* factory to call, returning the same `OrchestratorResult` the stream's
|
|
398
|
+
* `.result` resolves to.
|
|
399
|
+
*/
|
|
400
|
+
async function streamTurn(ctx, input, options) {
|
|
401
|
+
return runTurn(ctx, input, options);
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
//#endregion
|
|
405
|
+
export { OrchestratorExecution, runResume, runTurn, streamTurn };
|
|
406
|
+
//# sourceMappingURL=execution.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execution.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/orchestrator/execution.ts"],"sourcesContent":["import type { Message } from \"../contracts/conversation-message.type\";\nimport type { OrchestratorCommands } from \"../contracts/orchestrator/orchestrator-commands.type\";\nimport type { OrchestratorConfig } from \"../contracts/orchestrator/orchestrator-config.type\";\nimport type {\n OrchestratorEvent,\n OrchestratorEventHandlers,\n OrchestratorEventMap,\n OrchestratorEventName,\n} from \"../contracts/orchestrator/orchestrator-event.type\";\nimport type {\n OrchestratorExecuteOptions,\n OrchestratorResumeOptions,\n} from \"../contracts/orchestrator/orchestrator-execute-options.type\";\nimport type {\n CompactionResult,\n OrchestratorReport,\n OrchestratorReportStatus,\n OrchestratorResult,\n TurnSnapshot,\n} from \"../contracts/result/orchestrator-result.type\";\nimport { REPORT_SCHEMA_VERSION } from \"../contracts/result/base-report.type\";\nimport type { BaseReport } from \"../contracts/result/base-report.type\";\nimport type { Usage } from \"../contracts/result/usage.type\";\nimport type { SupervisorInput } from \"../contracts/supervisor/supervisor-input.type\";\nimport type { EventIdentity } from \"../contracts/events/event-identity.type\";\nimport {\n resolveDefaultCheckpointStore,\n resolveDefaultSnapshotStore,\n} from \"../config\";\nimport { OrchestratorConfigError, OrchestratorDriftError } from \"../errors\";\nimport type { ResolvedIntentEntry } from \"../supervisor/entries\";\nimport { generateRunId } from \"../utils/generate-run-id\";\nimport { persistCheckpoint, summarizeRoute } from \"./checkpoint\";\nimport { runCompaction, runManualCompaction, shouldCompact } from \"./compaction\";\nimport { deriveRunId, dispatchTurn } from \"./dispatch\";\nimport type { OrchestratorEmitter } from \"./emitter\";\nimport type { OrchestratorEmitterLike } from \"./emitter-port.type\";\nimport type { OrchestratorEngineContext } from \"./engine-context.type\";\nimport { acquireLock } from \"./lock\";\nimport { loadSession } from \"./load\";\nimport {\n injectMemories,\n outcomeTextFromTurn,\n recallForTurn,\n rememberTurnOutcome,\n resolveOrchestratorMemory,\n} from \"./memory\";\nimport type { OrchestratorStreamController } from \"./orchestrator-stream\";\nimport { resolveResume } from \"./resume\";\nimport { windowHistory } from \"./window\";\n\n/** Empty rolled-up usage for turns that never dispatched (drift/seed). */\nconst ZERO_USAGE: Usage = { input: 0, output: 0, total: 0 };\n\n/**\n * Constructor params the C1 factory passes when building an\n * {@link OrchestratorExecution} per call. The factory owns author-time\n * validation, intent-entry resolution, and signature computation; it\n * hands the engine the validated `config`, the resolved `entries`, the\n * computed `signature`, and the shared three-tier `emitter`. The\n * per-call inputs vary by entry point:\n *\n * - `execute` / `stream` — `input` + `options` (and `streamController`\n * for `stream`).\n * - `resume` — `resumeSessionId` + `resumeOptions`.\n * - `command(\"compact\")` — neither; `compact(args)` carries its own.\n */\nexport type OrchestratorExecutionParams<TOutput, TState> = {\n config: OrchestratorConfig<TOutput, TState>;\n /** Resolved intent entries (validated by C1; the engine delegates dispatch to the supervisor). */\n entries?: Map<string, ResolvedIntentEntry>;\n signature: string;\n emitter: OrchestratorEmitter;\n input?: SupervisorInput;\n options?: OrchestratorExecuteOptions<TState>;\n streamController?: OrchestratorStreamController<OrchestratorResult<TOutput>>;\n resumeSessionId?: string;\n resumeOptions?: OrchestratorResumeOptions;\n};\n\n/**\n * Per-call lifecycle engine — the single object the C1 factory\n * constructs and drives. Owns the 7-phase lifecycle (orchestrator.md §3:\n * load → drift → lock → window → dispatch → persist → compaction),\n * resolving the durable stores (own config field → `ai.config` default)\n * and adapting C1's three-tier {@link OrchestratorEmitter} to the\n * {@link OrchestratorEmitterLike} port the phase modules call.\n *\n * The factory creates a fresh instance per `execute` / `stream` /\n * `resume` / `command` call (single-call lifecycle invariant — §18.8);\n * the heavy lifting lives in the standalone phase functions\n * ({@link runTurn} / {@link runResume}) which this class delegates to.\n *\n * @example\n * const execution = new OrchestratorExecution({\n * config, entries, signature, emitter, input, options,\n * });\n * const result = await execution.run();\n */\nexport class OrchestratorExecution<TOutput, TState> {\n private readonly params: OrchestratorExecutionParams<TOutput, TState>;\n private readonly ctx: OrchestratorEngineContext<TOutput, TState>;\n private readonly streamController?: OrchestratorStreamController<\n OrchestratorResult<TOutput>\n >;\n\n public constructor(params: OrchestratorExecutionParams<TOutput, TState>) {\n this.params = params;\n this.streamController = params.streamController;\n this.ctx = {\n config: params.config,\n signature: params.signature,\n checkpointStore: resolveCheckpointStore(params.config),\n snapshotStore: resolveSnapshotStore(params.config),\n emitter: adaptEmitter(\n params.emitter,\n generateRunId(\"orchestrator\"),\n this.streamController as\n | OrchestratorStreamController<unknown>\n | undefined,\n ),\n memory: resolveOrchestratorMemory(params.config.memory),\n };\n }\n\n /**\n * `execute()` / `stream()` entry — run one turn through the 7-phase\n * lifecycle. When a `streamController` was supplied, the adapter mirrors\n * every emitted event into the stream and the controller is settled\n * (`end` / `fail`) once the result resolves.\n */\n public async run(): Promise<OrchestratorResult<TOutput>> {\n if (this.params.input === undefined || !this.params.options) {\n throw new OrchestratorConfigError(\n `ai.orchestrator(\"${this.params.config.name}\"): internal — run() invoked without input/options`,\n );\n }\n\n try {\n const result = await runTurn(\n this.ctx,\n this.params.input,\n this.params.options,\n );\n\n this.streamController?.end(result);\n\n return result;\n } catch (error) {\n this.streamController?.fail(error as Error);\n\n throw error;\n }\n }\n\n /**\n * `resume()` entry — drain an interrupted `iterate: true` turn (§9).\n * Returns `null` when nothing is in flight.\n */\n public async resume(): Promise<OrchestratorResult<TOutput> | null> {\n if (!this.params.resumeSessionId) {\n throw new OrchestratorConfigError(\n `ai.orchestrator(\"${this.params.config.name}\"): internal — resume() invoked without a sessionId`,\n );\n }\n\n return runResume(this.ctx, this.params.resumeSessionId, this.params.resumeOptions);\n }\n\n /**\n * `command(\"compact\")` entry — run a manual compaction on demand (§11 /\n * §12.1). Reuses the post-turn compaction code path against the\n * caller-supplied history and returns the raw {@link CompactionResult}.\n */\n public async compact(\n args: OrchestratorCommands[\"compact\"][\"args\"],\n ): Promise<OrchestratorCommands[\"compact\"][\"result\"]> {\n return runManualCompaction(\n this.ctx as OrchestratorEngineContext<unknown, TState>,\n args.history,\n );\n }\n}\n\n/**\n * Resolve the durable checkpoint store: the config's own field, falling\n * back to `ai.config({ defaultCheckpointStore })`. Throws\n * {@link OrchestratorConfigError} when neither resolves — persistence is\n * always on (§8.1), so a turn can never run without a checkpoint store.\n */\nfunction resolveCheckpointStore<TOutput, TState>(\n config: OrchestratorConfig<TOutput, TState>,\n) {\n const store = config.checkpointStore ?? resolveDefaultCheckpointStore();\n\n if (!store) {\n throw new OrchestratorConfigError(\n `ai.orchestrator(\"${config.name}\"): a \\`checkpointStore\\` is required ` +\n `(set one on the config or via \\`ai.config({ defaultCheckpointStore })\\`)`,\n );\n }\n\n return store;\n}\n\n/**\n * Resolve the internal-supervisor snapshot store for `iterate: true`\n * turns: the config's own field, falling back to\n * `ai.config({ defaultSnapshotStore })`. Returns `undefined` for\n * `iterate: false` orchestrators (no mid-turn resume — nothing to\n * snapshot). The factory already guarantees presence when\n * `iterate: true`, so the engine never asserts here.\n */\nfunction resolveSnapshotStore<TOutput, TState>(\n config: OrchestratorConfig<TOutput, TState>,\n) {\n if (config.iterate !== true) {\n return undefined;\n }\n\n return config.snapshotStore ?? resolveDefaultSnapshotStore();\n}\n\n/**\n * Adapt C1's three-tier {@link OrchestratorEmitter} (whose `emit` takes\n * `event, payload, identity, perCallHandlers?`) to the\n * {@link OrchestratorEmitterLike} port the phase modules call (a 2-arg\n * `emit(event, payload)` plus `bindPerCall`).\n *\n * The adapter injects the run identity centrally and, when a stream\n * controller is present, mirrors every fully-stamped event into the\n * stream pipe (§14.1 — the orchestrator's own events surface on the\n * stream alongside the bubbled child events). `bindPerCall` registers\n * the per-call `options.on` bag for the turn's duration and returns a\n * disposer that clears it.\n */\nfunction adaptEmitter(\n emitter: OrchestratorEmitter,\n runId: string,\n streamController: OrchestratorStreamController<unknown> | undefined,\n): OrchestratorEmitterLike {\n // `rootRunId === runId` for a standalone run; nested propagation lands\n // in a follow-up (see `EventIdentity`).\n const fullIdentity: EventIdentity = { runId, rootRunId: runId };\n\n let perCall: OrchestratorEventHandlers | undefined;\n\n return {\n emit<K extends OrchestratorEventName>(\n event: K,\n payload: OrchestratorEventMap[K],\n ): void {\n const fullPayload = emitter.emit(event, payload, fullIdentity, perCall);\n\n // The discriminated-union correlation between `type` and the\n // matching payload variant can't be expressed structurally — the\n // cast mirrors the supervisor stream's established pattern.\n streamController?.push({ type: event, ...fullPayload } as OrchestratorEvent);\n },\n bindPerCall(handlers: OrchestratorEventHandlers | undefined): () => void {\n perCall = handlers;\n\n return () => {\n perCall = undefined;\n };\n },\n };\n}\n\n/**\n * Phase 2 — drift check (orchestrator.md §3 / §4 Phase 2). Compares the\n * loaded checkpoint's `signature` against the current definition's.\n * Mismatch throws `OrchestratorDriftError` synchronously unless\n * `force` is set. Emits `orchestrator.drift.checked` either way. A new\n * session (no loaded signature) never drifts.\n */\nfunction assertNoDrift(\n ctx: OrchestratorEngineContext,\n sessionId: string,\n loadedSignature: string | undefined,\n force: boolean | undefined,\n): void {\n const drifted =\n loadedSignature !== undefined && loadedSignature !== ctx.signature;\n\n ctx.emitter.emit(\"orchestrator.drift.checked\", {\n sessionId,\n signature: ctx.signature,\n drifted,\n });\n\n if (drifted && !force) {\n throw new OrchestratorDriftError(\n `orchestrator \"${ctx.config.name}\": signature drift on session \"${sessionId}\" — ` +\n `the definition changed since this session was last persisted. ` +\n `Pass { force: true } only after reviewing the change, or discard / migrate the session.`,\n {\n savedSignature: loadedSignature as string,\n currentSignature: ctx.signature,\n sessionId,\n },\n );\n }\n}\n\n/**\n * Shallow-merge the per-call `state` patch (§5 — partial state\n * override) over the loaded session-state seed. The merged value\n * becomes the supervisor's seed for this turn.\n */\nfunction applyStatePatch<TState>(\n seed: TState,\n patch: Partial<TState> | undefined,\n): TState {\n if (!patch) {\n return seed;\n }\n\n return { ...seed, ...patch } as TState;\n}\n\n/**\n * Assemble the orchestrator-scope {@link OrchestratorReport} from the\n * dispatched turn's child report and the turn snapshot. Wraps the\n * child supervisor/agent report tree as `children[0]` (§15.6 —\n * `children[]` carries only the CURRENT turn's dispatched primitive\n * reports) while the per-turn forensic record lives on `turns[]`.\n */\nfunction buildReport(\n ctx: OrchestratorEngineContext,\n sessionId: string,\n turnIndex: number,\n status: OrchestratorReportStatus,\n turnSnapshot: TurnSnapshot | undefined,\n childReport: BaseReport | undefined,\n): OrchestratorReport {\n const now = new Date().toISOString();\n const usage = turnSnapshot?.usage ?? childReport?.usage ?? ZERO_USAGE;\n\n return {\n runId: deriveRunId(sessionId, ctx.config.version, turnIndex),\n rootRunId: deriveRunId(sessionId, ctx.config.version, turnIndex),\n name: ctx.config.name,\n version: ctx.config.version,\n sessionId,\n type: \"orchestrator\",\n status,\n startedAt: turnSnapshot?.startedAt ?? now,\n endedAt: turnSnapshot?.endedAt ?? now,\n duration: turnSnapshot?.duration ?? 0,\n usage,\n children: childReport ? [childReport] : [],\n reportSchemaVersion: REPORT_SCHEMA_VERSION,\n turnIndex,\n signature: ctx.signature,\n turns: turnSnapshot ? [turnSnapshot] : [],\n };\n}\n\n/**\n * Map the dispatched supervisor result's report status onto the\n * orchestrator's status surface (§15.6). A clean completion that is\n * still mid-conversation reports `\"awaiting-input\"` (the session\n * continues) rather than `\"completed\"`; failures and cancellations\n * pass through.\n */\nfunction deriveStatus(childStatus: BaseReport[\"status\"]): OrchestratorReportStatus {\n if (childStatus === \"completed\") {\n return \"awaiting-input\";\n }\n\n return childStatus;\n}\n\n/**\n * Emit the terminal turn event matching the report status (§14.1).\n */\nfunction emitTerminal(\n ctx: OrchestratorEngineContext,\n sessionId: string,\n turnIndex: number,\n status: OrchestratorReportStatus,\n): void {\n if (status === \"cancelled\") {\n ctx.emitter.emit(\"orchestrator.turn.cancelled\", { sessionId, turnIndex });\n\n return;\n }\n\n if (status === \"failed\" || status === \"max-iterations\") {\n ctx.emitter.emit(\"orchestrator.turn.failed\", { sessionId, turnIndex });\n\n return;\n }\n\n if (status === \"awaiting-input\") {\n ctx.emitter.emit(\"orchestrator.turn.awaiting-input\", {\n sessionId,\n turnIndex,\n });\n\n return;\n }\n\n ctx.emitter.emit(\"orchestrator.turn.completed\", { sessionId, turnIndex });\n}\n\n/**\n * Run one turn end-to-end through the 7-phase lifecycle (orchestrator\n * .md §3). The single entry the C1 factory's `execute()` delegates to.\n *\n * Phase order is the diagram's contract: load → drift → lock → window\n * → dispatch → persist → compaction. Drift / config misuse throw;\n * every other failure surfaces on `result.error` (the contract: the\n * orchestrator never throws on runtime failure). Cancellation and\n * failure do NOT persist a fresh checkpoint (§17 — state reverts to the\n * pre-turn checkpoint).\n */\nexport async function runTurn<TOutput, TState>(\n ctx: OrchestratorEngineContext<TOutput, TState>,\n input: SupervisorInput,\n options: OrchestratorExecuteOptions<TState>,\n): Promise<OrchestratorResult<TOutput>> {\n const sessionId = options.sessionId;\n const disposePerCall = ctx.emitter.bindPerCall(options.on);\n\n try {\n // Phase 1 — load session.\n const loaded = await loadSession(ctx, sessionId);\n\n ctx.emitter.emit(\"orchestrator.turn.starting\", {\n sessionId,\n turnIndex: loaded.turnIndex,\n });\n\n ctx.emitter.emit(\"orchestrator.session.loaded\", {\n sessionId,\n turnIndex: loaded.turnIndex,\n found: loaded.found,\n });\n\n // Phase 2 — drift check.\n assertNoDrift(\n ctx as OrchestratorEngineContext,\n sessionId,\n loaded.record?.signature,\n options.force,\n );\n\n // Phase 3 — lock check (cooperative, fail-open).\n await acquireLock(ctx, sessionId, loaded.record);\n\n // Phase 4 — window history.\n const windowed = windowHistory(\n ctx as OrchestratorEngineContext,\n sessionId,\n options.history,\n );\n\n // Phase 5 — dispatch. When memory is configured, recall the\n // turn-relevant memories and inject them into the request-scoped\n // context bag so every route / router / evaluate / dispatch callback\n // surfaces them at `ctx.context[injectKey]` before routing runs.\n const seedState = applyStatePatch(loaded.state, options.state);\n\n let turnContext = options.context;\n\n if (ctx.memory) {\n const recalled = await recallForTurn(ctx.memory, input);\n turnContext = injectMemories(turnContext, ctx.memory, recalled);\n }\n\n const { result, state, turnSnapshot } = await dispatchTurn<TOutput, TState>({\n ctx,\n sessionId,\n input,\n seedState,\n turnIndex: loaded.turnIndex,\n history: windowed.agents,\n context: turnContext,\n signal: options.signal,\n });\n\n ctx.emitter.emit(\"orchestrator.turn.routed\", {\n sessionId,\n turnIndex: loaded.turnIndex,\n source: turnSnapshot.decision.source,\n raw: turnSnapshot.decision.raw,\n });\n\n const status = result.error\n ? deriveStatus(result.report.status)\n : \"awaiting-input\";\n\n // Cancelled / failed turns revert: no fresh checkpoint, no compaction.\n if (result.error) {\n const report = buildReport(\n ctx as OrchestratorEngineContext,\n sessionId,\n loaded.turnIndex,\n status,\n turnSnapshot,\n result.report,\n );\n\n emitTerminal(ctx as OrchestratorEngineContext, sessionId, loaded.turnIndex, status);\n\n return {\n data: result.data,\n error: result.error,\n usage: result.usage,\n report,\n sessionId,\n turnIndex: loaded.turnIndex,\n };\n }\n\n // Phase 6 — persist checkpoint.\n await persistCheckpoint({\n ctx,\n sessionId,\n turnIndex: loaded.turnIndex,\n state,\n lastRoute: summarizeRoute(turnSnapshot.decision.raw as never),\n summarizedThrough: loaded.record?.summarized_through ?? null,\n });\n\n // Memory write-back (memory core M2). The turn settled cleanly (the\n // `result.error` branch above already returned for cancelled /\n // failed turns, which revert and never remember — §17), so remember\n // the input + its outcome for later recall.\n if (ctx.memory) {\n await rememberTurnOutcome(\n ctx.memory,\n input,\n outcomeTextFromTurn(result.data, turnSnapshot),\n );\n }\n\n // Phase 7 — post-turn compaction (only when triggered).\n let compaction: CompactionResult | undefined;\n\n if (shouldCompact(ctx as OrchestratorEngineContext, loaded.turnIndex)) {\n const outcome = await runCompaction(\n ctx as OrchestratorEngineContext<unknown, TState>,\n sessionId,\n options.history,\n );\n\n if (outcome) {\n compaction = outcome.compaction;\n\n if (outcome.applied) {\n await advanceSummarizedThrough(\n ctx as OrchestratorEngineContext<unknown, TState>,\n sessionId,\n outcome.compaction.replacesToIndex,\n );\n }\n }\n }\n\n const report = buildReport(\n ctx as OrchestratorEngineContext,\n sessionId,\n loaded.turnIndex,\n \"awaiting-input\",\n turnSnapshot,\n result.report,\n );\n\n emitTerminal(ctx as OrchestratorEngineContext, sessionId, loaded.turnIndex, \"awaiting-input\");\n\n return {\n data: result.data,\n error: undefined,\n usage: result.usage,\n report,\n sessionId,\n turnIndex: loaded.turnIndex,\n compaction,\n };\n } finally {\n disposePerCall();\n }\n}\n\n/**\n * After a framework-applied compaction (`onCompact` succeeded), advance\n * the persisted `summarized_through` to the compaction's\n * `replacesToIndex` (§12.2 step 4). Re-saves the latest row with the\n * updated marker (append-only stores keep the prior row).\n */\nasync function advanceSummarizedThrough<TState>(\n ctx: OrchestratorEngineContext<unknown, TState>,\n sessionId: string,\n replacesToIndex: number,\n): Promise<void> {\n const latest = await ctx.checkpointStore.load(ctx.config.name, sessionId);\n\n if (!latest) {\n return;\n }\n\n await ctx.checkpointStore.save({\n ...latest,\n summarized_through: replacesToIndex,\n saved_at: new Date().toISOString(),\n });\n}\n\n/**\n * §9 resume protocol entry the C1 factory's `resume()` delegates to.\n * Returns `null` when no in-flight `iterate: true` turn is detected;\n * otherwise drains the interrupted supervisor run, persists a fresh\n * checkpoint for the resumed turn, and returns the completed result.\n *\n * Runs the same Phase 2 drift check as `runTurn` (§9.4). The heavy\n * lifting lives in `resume.ts`; this wrapper threads the engine\n * context.\n */\nexport async function runResume<TOutput, TState>(\n ctx: OrchestratorEngineContext<TOutput, TState>,\n sessionId: string,\n options?: OrchestratorResumeOptions,\n): Promise<OrchestratorResult<TOutput> | null> {\n const disposePerCall = ctx.emitter.bindPerCall(options?.on);\n\n try {\n return await resolveResume(ctx, sessionId, options, {\n assertNoDrift: (loadedSignature) =>\n assertNoDrift(\n ctx as OrchestratorEngineContext,\n sessionId,\n loadedSignature,\n options?.force,\n ),\n buildReport: (turnIndex, status, turnSnapshot, childReport) =>\n buildReport(\n ctx as OrchestratorEngineContext,\n sessionId,\n turnIndex,\n status,\n turnSnapshot,\n childReport,\n ),\n deriveStatus,\n emitTerminal: (turnIndex, status) =>\n emitTerminal(ctx as OrchestratorEngineContext, sessionId, turnIndex, status),\n persist: (turnIndex, state, lastRoute, summarizedThrough) =>\n persistCheckpoint({\n ctx,\n sessionId,\n turnIndex,\n state,\n lastRoute,\n summarizedThrough,\n }),\n });\n } finally {\n disposePerCall();\n }\n}\n\n/**\n * The `stream()` entry. The orchestrator's streaming surface bubbles\n * child agent/supervisor events under their own namespace (§14.2); the\n * C1 stream controller owns the `StreamContract` wiring. This engine\n * entry runs the same lifecycle as `runTurn` — the C1 factory passes a\n * per-call `on` bag wired to the stream controller, so the engine needs\n * no streaming-specific branch. Exposed as a distinct name for the\n * factory to call, returning the same `OrchestratorResult` the stream's\n * `.result` resolves to.\n */\nexport async function streamTurn<TOutput, TState>(\n ctx: OrchestratorEngineContext<TOutput, TState>,\n input: SupervisorInput,\n options: OrchestratorExecuteOptions<TState>,\n): Promise<OrchestratorResult<TOutput>> {\n return runTurn(ctx, input, options);\n}\n\nexport type { OrchestratorEngineContext } from \"./engine-context.type\";\nexport type { Message };\n"],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { asTool } from "./as-tool.mjs";
|
|
2
|
+
import { OrchestratorCommandHandlers, createCommandDispatcher } from "./commands.mjs";
|
|
3
|
+
import { OrchestratorEmitter } from "./emitter.mjs";
|
|
4
|
+
import { ResolvedOrchestratorMemory, injectMemories, memoryQueryFromInput, outcomeTextFromTurn, recallForTurn, rememberTurnOutcome, resolveOrchestratorMemory } from "./memory.mjs";
|
|
5
|
+
import { OrchestratorStreamController, createOrchestratorStream } from "./orchestrator-stream.mjs";
|
|
6
|
+
import { OrchestratorExecution, OrchestratorExecutionParams, runResume, runTurn, streamTurn } from "./execution.mjs";
|
|
7
|
+
import { orchestrator } from "./orchestrator.mjs";
|
|
8
|
+
import { computeOrchestratorSignature } from "./signature.mjs";
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { asTool } from "./as-tool.mjs";
|
|
2
|
+
import { createCommandDispatcher } from "./commands.mjs";
|
|
3
|
+
import { OrchestratorEmitter } from "./emitter.mjs";
|
|
4
|
+
import { injectMemories, memoryQueryFromInput, outcomeTextFromTurn, recallForTurn, rememberTurnOutcome, resolveOrchestratorMemory } from "./memory.mjs";
|
|
5
|
+
import { OrchestratorExecution, runResume, runTurn, streamTurn } from "./execution.mjs";
|
|
6
|
+
import { createOrchestratorStream } from "./orchestrator-stream.mjs";
|
|
7
|
+
import { computeOrchestratorSignature } from "./signature.mjs";
|
|
8
|
+
import { orchestrator } from "./orchestrator.mjs";
|
|
9
|
+
|
|
10
|
+
export { };
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
//#region ../@warlock.js/ai/src/orchestrator/load.ts
|
|
2
|
+
/**
|
|
3
|
+
* Deep-clone a JSON-serializable value so a rehydrated checkpoint's
|
|
4
|
+
* `state` can be mutated by the turn without aliasing the stored row
|
|
5
|
+
* (the in-memory store hands back live references). Mirrors the
|
|
6
|
+
* round-trip semantics the design mandates for state (§5 — "JSON-
|
|
7
|
+
* serializable only", `JSON.parse(JSON.stringify(...))`-equivalent).
|
|
8
|
+
*/
|
|
9
|
+
function cloneState(state) {
|
|
10
|
+
if (state === void 0 || state === null) return {};
|
|
11
|
+
return JSON.parse(JSON.stringify(state));
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Phase 1 — load session. Reads the latest checkpoint for the session
|
|
15
|
+
* and resolves the starting state accumulator + the turn index about
|
|
16
|
+
* to run.
|
|
17
|
+
*
|
|
18
|
+
* First-call seeding (Q2): when no checkpoint exists this is the
|
|
19
|
+
* session's birth — `state` defaults to `config.state ?? {}` and
|
|
20
|
+
* `turnIndex` is 0. Subsequent calls rehydrate the persisted `state`
|
|
21
|
+
* and advance the turn index. The dev-passed `options.history` is the
|
|
22
|
+
* per-call seed (Path 2 — the framework never persists messages), so
|
|
23
|
+
* load does not touch history.
|
|
24
|
+
*
|
|
25
|
+
* Does NOT apply the per-call `state` patch — that shallow-merges over
|
|
26
|
+
* this result in the dispatch phase (§5), where the supervisor seed is
|
|
27
|
+
* assembled.
|
|
28
|
+
*/
|
|
29
|
+
async function loadSession(ctx, sessionId) {
|
|
30
|
+
const record = await ctx.checkpointStore.load(ctx.config.name, sessionId);
|
|
31
|
+
if (!record) return {
|
|
32
|
+
record: void 0,
|
|
33
|
+
found: false,
|
|
34
|
+
state: cloneState(ctx.config.state),
|
|
35
|
+
turnIndex: 0,
|
|
36
|
+
previousTurnIndex: -1
|
|
37
|
+
};
|
|
38
|
+
return {
|
|
39
|
+
record,
|
|
40
|
+
found: true,
|
|
41
|
+
state: cloneState(record.state),
|
|
42
|
+
turnIndex: record.turn_index + 1,
|
|
43
|
+
previousTurnIndex: record.turn_index
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
//#endregion
|
|
48
|
+
export { loadSession };
|
|
49
|
+
//# sourceMappingURL=load.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/orchestrator/load.ts"],"sourcesContent":["import type { CheckpointRecord } from \"../contracts/orchestrator/checkpoint-store.contract\";\nimport type { OrchestratorEngineContext } from \"./engine-context.type\";\n\n/**\n * Outcome of Phase 1 — load session (orchestrator.md §4 Phase 1).\n *\n * `record` is the latest persisted checkpoint, or `undefined` for a\n * brand-new session. `state` is the starting accumulator the turn\n * mutates: the rehydrated `state` on a subsequent call, or the\n * `config.state ?? {}` seed on first call (the framework never\n * re-seeds from `config.state` once a session exists — §4 Phase 1).\n * `turnIndex` is the index of the turn ABOUT to run (loaded + 1, or 0\n * on first call). `previousTurnIndex` is the loaded value (or -1 when\n * none) — needed by resume's `runId` derivation (§9.1).\n */\nexport type LoadedSession<TState> = {\n /** Latest persisted checkpoint, or `undefined` for a new session. */\n record: CheckpointRecord | undefined;\n /** Whether a prior checkpoint existed (drives `session.loaded.found`). */\n found: boolean;\n /** Starting state accumulator for this turn. */\n state: TState;\n /** Index of the turn about to run. */\n turnIndex: number;\n /** Index of the last settled turn (-1 when the session is new). */\n previousTurnIndex: number;\n};\n\n/**\n * Deep-clone a JSON-serializable value so a rehydrated checkpoint's\n * `state` can be mutated by the turn without aliasing the stored row\n * (the in-memory store hands back live references). Mirrors the\n * round-trip semantics the design mandates for state (§5 — \"JSON-\n * serializable only\", `JSON.parse(JSON.stringify(...))`-equivalent).\n */\nfunction cloneState<TState>(state: unknown): TState {\n if (state === undefined || state === null) {\n return {} as TState;\n }\n\n return JSON.parse(JSON.stringify(state)) as TState;\n}\n\n/**\n * Phase 1 — load session. Reads the latest checkpoint for the session\n * and resolves the starting state accumulator + the turn index about\n * to run.\n *\n * First-call seeding (Q2): when no checkpoint exists this is the\n * session's birth — `state` defaults to `config.state ?? {}` and\n * `turnIndex` is 0. Subsequent calls rehydrate the persisted `state`\n * and advance the turn index. The dev-passed `options.history` is the\n * per-call seed (Path 2 — the framework never persists messages), so\n * load does not touch history.\n *\n * Does NOT apply the per-call `state` patch — that shallow-merges over\n * this result in the dispatch phase (§5), where the supervisor seed is\n * assembled.\n */\nexport async function loadSession<TState>(\n ctx: OrchestratorEngineContext<unknown, TState>,\n sessionId: string,\n): Promise<LoadedSession<TState>> {\n const record = await ctx.checkpointStore.load(ctx.config.name, sessionId);\n\n if (!record) {\n return {\n record: undefined,\n found: false,\n state: cloneState<TState>(ctx.config.state),\n turnIndex: 0,\n previousTurnIndex: -1,\n };\n }\n\n return {\n record,\n found: true,\n state: cloneState<TState>(record.state),\n turnIndex: record.turn_index + 1,\n previousTurnIndex: record.turn_index,\n };\n}\n"],"mappings":";;;;;;;;AAmCA,SAAS,WAAmB,OAAwB;CAClD,IAAI,UAAU,UAAa,UAAU,MACnC,OAAO,CAAC;CAGV,OAAO,KAAK,MAAM,KAAK,UAAU,KAAK,CAAC;AACzC;;;;;;;;;;;;;;;;;AAkBA,eAAsB,YACpB,KACA,WACgC;CAChC,MAAM,SAAS,MAAM,IAAI,gBAAgB,KAAK,IAAI,OAAO,MAAM,SAAS;CAExE,IAAI,CAAC,QACH,OAAO;EACL,QAAQ;EACR,OAAO;EACP,OAAO,WAAmB,IAAI,OAAO,KAAK;EAC1C,WAAW;EACX,mBAAmB;CACrB;CAGF,OAAO;EACL;EACA,OAAO;EACP,OAAO,WAAmB,OAAO,KAAK;EACtC,WAAW,OAAO,aAAa;EAC/B,mBAAmB,OAAO;CAC5B;AACF"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
//#region ../@warlock.js/ai/src/orchestrator/lock.ts
|
|
2
|
+
/** Framework default for the compaction-lock wait, in ms (§3 / §12.3). */
|
|
3
|
+
const DEFAULT_LOCK_MAX_WAIT = 3e4;
|
|
4
|
+
/** Poll interval while waiting on a held lock, in ms. */
|
|
5
|
+
const LOCK_POLL_INTERVAL = 100;
|
|
6
|
+
/**
|
|
7
|
+
* Resolve the configured `summarize.lock.maxWait`, falling back to the
|
|
8
|
+
* framework default. The callback form of `summarize` carries no lock
|
|
9
|
+
* config, so it uses the default.
|
|
10
|
+
*/
|
|
11
|
+
function resolveMaxWait(ctx) {
|
|
12
|
+
const summarize = ctx.config.summarize;
|
|
13
|
+
if (typeof summarize === "function" || summarize === void 0) return DEFAULT_LOCK_MAX_WAIT;
|
|
14
|
+
return summarize.lock?.maxWait ?? 3e4;
|
|
15
|
+
}
|
|
16
|
+
/** Whether a checkpoint's lock is still held relative to `now`. */
|
|
17
|
+
function isLocked(record, now) {
|
|
18
|
+
if (!record.lock_expires_at) return false;
|
|
19
|
+
const expiresAt = Date.parse(record.lock_expires_at);
|
|
20
|
+
return Number.isFinite(expiresAt) && expiresAt > now;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Phase 3 — lock check (orchestrator.md §3 / §4 Phase 3). The loaded
|
|
24
|
+
* checkpoint may carry a compaction lock written by a prior turn's
|
|
25
|
+
* Phase 7 (or by `command("compact")`). When the lock is still live,
|
|
26
|
+
* wait up to `summarize.lock.maxWait` (default 30s), re-loading the
|
|
27
|
+
* latest checkpoint each poll, then **fail open** — proceed without
|
|
28
|
+
* the lock.
|
|
29
|
+
*
|
|
30
|
+
* Emits `orchestrator.lock.waiting` once, only when a held lock is
|
|
31
|
+
* observed (§14.1 — "only when locked"). The dispatch then runs
|
|
32
|
+
* against whatever state was written before the lock was taken (§3).
|
|
33
|
+
*
|
|
34
|
+
* A new session (`loaded === undefined`) is never locked, so this
|
|
35
|
+
* returns immediately.
|
|
36
|
+
*/
|
|
37
|
+
async function acquireLock(ctx, sessionId, loaded) {
|
|
38
|
+
if (!loaded || !isLocked(loaded, Date.now())) return {
|
|
39
|
+
waited: false,
|
|
40
|
+
waitedMs: 0,
|
|
41
|
+
failedOpen: false
|
|
42
|
+
};
|
|
43
|
+
const maxWait = resolveMaxWait(ctx);
|
|
44
|
+
const startedAt = Date.now();
|
|
45
|
+
ctx.emitter.emit("orchestrator.lock.waiting", {
|
|
46
|
+
sessionId,
|
|
47
|
+
waitedMs: 0
|
|
48
|
+
});
|
|
49
|
+
let latest = loaded;
|
|
50
|
+
while (latest && isLocked(latest, Date.now())) {
|
|
51
|
+
const waitedMs = Date.now() - startedAt;
|
|
52
|
+
if (waitedMs >= maxWait) return {
|
|
53
|
+
waited: true,
|
|
54
|
+
waitedMs,
|
|
55
|
+
failedOpen: true
|
|
56
|
+
};
|
|
57
|
+
await delay(Math.min(LOCK_POLL_INTERVAL, maxWait - waitedMs));
|
|
58
|
+
latest = await ctx.checkpointStore.load(ctx.config.name, sessionId);
|
|
59
|
+
}
|
|
60
|
+
return {
|
|
61
|
+
waited: true,
|
|
62
|
+
waitedMs: Date.now() - startedAt,
|
|
63
|
+
failedOpen: false
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
/** Promise-based sleep used by the cooperative wait loop. */
|
|
67
|
+
function delay(ms) {
|
|
68
|
+
return new Promise((resolve) => {
|
|
69
|
+
setTimeout(resolve, ms);
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
//#endregion
|
|
74
|
+
export { DEFAULT_LOCK_MAX_WAIT, acquireLock };
|
|
75
|
+
//# sourceMappingURL=lock.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lock.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/orchestrator/lock.ts"],"sourcesContent":["import type { CheckpointRecord } from \"../contracts/orchestrator/checkpoint-store.contract\";\nimport type { SummarizeConfig } from \"../contracts/orchestrator/orchestrator-config.type\";\nimport type { OrchestratorEngineContext } from \"./engine-context.type\";\n\n/** Framework default for the compaction-lock wait, in ms (§3 / §12.3). */\nexport const DEFAULT_LOCK_MAX_WAIT = 30_000;\n\n/** Poll interval while waiting on a held lock, in ms. */\nconst LOCK_POLL_INTERVAL = 100;\n\n/**\n * Resolve the configured `summarize.lock.maxWait`, falling back to the\n * framework default. The callback form of `summarize` carries no lock\n * config, so it uses the default.\n */\nfunction resolveMaxWait(ctx: OrchestratorEngineContext): number {\n const summarize = ctx.config.summarize;\n\n if (typeof summarize === \"function\" || summarize === undefined) {\n return DEFAULT_LOCK_MAX_WAIT;\n }\n\n return (summarize as SummarizeConfig).lock?.maxWait ?? DEFAULT_LOCK_MAX_WAIT;\n}\n\n/** Whether a checkpoint's lock is still held relative to `now`. */\nfunction isLocked(record: CheckpointRecord, now: number): boolean {\n if (!record.lock_expires_at) {\n return false;\n }\n\n const expiresAt = Date.parse(record.lock_expires_at);\n\n return Number.isFinite(expiresAt) && expiresAt > now;\n}\n\n/**\n * Outcome of Phase 3. `waited` is true when the turn observed a held\n * lock and spent time waiting; `waitedMs` is how long. `failedOpen` is\n * true when the wait timed out and the turn proceeds without the lock\n * (orchestrator.md §3 / §12.3 — a stuck summarizer must never block a\n * session forever).\n */\nexport type LockOutcome = {\n waited: boolean;\n waitedMs: number;\n failedOpen: boolean;\n};\n\n/**\n * Phase 3 — lock check (orchestrator.md §3 / §4 Phase 3). The loaded\n * checkpoint may carry a compaction lock written by a prior turn's\n * Phase 7 (or by `command(\"compact\")`). When the lock is still live,\n * wait up to `summarize.lock.maxWait` (default 30s), re-loading the\n * latest checkpoint each poll, then **fail open** — proceed without\n * the lock.\n *\n * Emits `orchestrator.lock.waiting` once, only when a held lock is\n * observed (§14.1 — \"only when locked\"). The dispatch then runs\n * against whatever state was written before the lock was taken (§3).\n *\n * A new session (`loaded === undefined`) is never locked, so this\n * returns immediately.\n */\nexport async function acquireLock<TState>(\n ctx: OrchestratorEngineContext<unknown, TState>,\n sessionId: string,\n loaded: CheckpointRecord | undefined,\n): Promise<LockOutcome> {\n if (!loaded || !isLocked(loaded, Date.now())) {\n return { waited: false, waitedMs: 0, failedOpen: false };\n }\n\n const maxWait = resolveMaxWait(ctx as OrchestratorEngineContext);\n const startedAt = Date.now();\n\n ctx.emitter.emit(\"orchestrator.lock.waiting\", { sessionId, waitedMs: 0 });\n\n let latest: CheckpointRecord | undefined = loaded;\n\n while (latest && isLocked(latest, Date.now())) {\n const waitedMs = Date.now() - startedAt;\n\n if (waitedMs >= maxWait) {\n return { waited: true, waitedMs, failedOpen: true };\n }\n\n await delay(Math.min(LOCK_POLL_INTERVAL, maxWait - waitedMs));\n\n latest = await ctx.checkpointStore.load(ctx.config.name, sessionId);\n }\n\n return { waited: true, waitedMs: Date.now() - startedAt, failedOpen: false };\n}\n\n/** Promise-based sleep used by the cooperative wait loop. */\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => {\n setTimeout(resolve, ms);\n });\n}\n"],"mappings":";;AAKA,MAAa,wBAAwB;;AAGrC,MAAM,qBAAqB;;;;;;AAO3B,SAAS,eAAe,KAAwC;CAC9D,MAAM,YAAY,IAAI,OAAO;CAE7B,IAAI,OAAO,cAAc,cAAc,cAAc,QACnD,OAAO;CAGT,OAAQ,UAA8B,MAAM;AAC9C;;AAGA,SAAS,SAAS,QAA0B,KAAsB;CAChE,IAAI,CAAC,OAAO,iBACV,OAAO;CAGT,MAAM,YAAY,KAAK,MAAM,OAAO,eAAe;CAEnD,OAAO,OAAO,SAAS,SAAS,KAAK,YAAY;AACnD;;;;;;;;;;;;;;;;AA8BA,eAAsB,YACpB,KACA,WACA,QACsB;CACtB,IAAI,CAAC,UAAU,CAAC,SAAS,QAAQ,KAAK,IAAI,CAAC,GACzC,OAAO;EAAE,QAAQ;EAAO,UAAU;EAAG,YAAY;CAAM;CAGzD,MAAM,UAAU,eAAe,GAAgC;CAC/D,MAAM,YAAY,KAAK,IAAI;CAE3B,IAAI,QAAQ,KAAK,6BAA6B;EAAE;EAAW,UAAU;CAAE,CAAC;CAExE,IAAI,SAAuC;CAE3C,OAAO,UAAU,SAAS,QAAQ,KAAK,IAAI,CAAC,GAAG;EAC7C,MAAM,WAAW,KAAK,IAAI,IAAI;EAE9B,IAAI,YAAY,SACd,OAAO;GAAE,QAAQ;GAAM;GAAU,YAAY;EAAK;EAGpD,MAAM,MAAM,KAAK,IAAI,oBAAoB,UAAU,QAAQ,CAAC;EAE5D,SAAS,MAAM,IAAI,gBAAgB,KAAK,IAAI,OAAO,MAAM,SAAS;CACpE;CAEA,OAAO;EAAE,QAAQ;EAAM,UAAU,KAAK,IAAI,IAAI;EAAW,YAAY;CAAM;AAC7E;;AAGA,SAAS,MAAM,IAA2B;CACxC,OAAO,IAAI,SAAS,YAAY;EAC9B,WAAW,SAAS,EAAE;CACxB,CAAC;AACH"}
|