@warlock.js/ai 4.2.11 → 4.4.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 +68 -1
- package/cjs/index.cjs +10155 -4626
- 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 +88 -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 +143 -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 +2 -2
- package/esm/contracts/result/supervisor-result.type.d.mts.map +1 -1
- package/esm/contracts/result/tool-call.type.d.mts +2 -2
- package/esm/contracts/result/tool-call.type.d.mts.map +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/result/workflow-result.type.d.mts +1 -1
- package/esm/contracts/result/workflow-result.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 +120 -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,127 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: manage-ai-stores
|
|
3
|
+
description: 'Durable orchestrator stores — ai.checkpoint.{memory,pg,redis}() for cross-turn SESSION STATE and ai.snapshot.{memory,pg,redis}() for in-flight SUPERVISOR/WORKFLOW run state. Two distinct contracts (CheckpointStore vs SnapshotStore), dev-owned pg/redis clients (no peer dep), never-auto-migrated schema(), global defaults via ai.config({defaultCheckpointStore, defaultSnapshotStore}). Triggers: `ai.checkpoint`, `ai.snapshot`, `checkpointStore`, `snapshotStore`, `CheckpointStore`, `SnapshotStore`, `CheckpointRecord`, `checkpoint.pg`, `checkpoint.redis`, `snapshot.pg`, `snapshot.redis`, `store.schema()`, `keepSnapshots`, `defaultCheckpointStore`, `defaultSnapshotStore`, `PgClientLike`, `RedisClientLike`; ''persist orchestrator sessions'', ''wire a pg checkpoint store'', ''run the store DDL'', ''checkpoint vs snapshot''; typical import `import { ai } from "@warlock.js/ai"`. Skip: orchestrator lifecycle — `@warlock.js/ai/run-orchestrator/SKILL.md`; cache-backed snapshot resume / semanticCache store — `@warlock.js/ai/persist-ai-data/SKILL.md`; competing libs `temporal`, `inngest`.'
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Orchestrator stores — checkpoint vs snapshot
|
|
7
|
+
|
|
8
|
+
`ai.orchestrator()` persists through **two distinct stores** with two distinct contracts. Confusing them is the #1 wiring mistake.
|
|
9
|
+
|
|
10
|
+
| Store | Contract | Persists | Keyed by | Factories |
|
|
11
|
+
|---|---|---|---|---|
|
|
12
|
+
| **checkpoint** | `CheckpointStore` | cross-turn SESSION STATE (one append-only row per settled turn) | `(orchestrator_name, session_id, turn_index)` | `ai.checkpoint.{memory,pg,redis}()` |
|
|
13
|
+
| **snapshot** | `SnapshotStore` | in-flight internal SUPERVISOR run state (for `iterate: true` mid-turn resume) | `runId` | `ai.snapshot.{memory,pg,redis}()` |
|
|
14
|
+
|
|
15
|
+
- A **checkpoint** is what lets `execute()` rehydrate a session across calls — state, `turn_index`, drift `signature`, `version`, `last_route`, compaction progress, lock metadata.
|
|
16
|
+
- A **snapshot** is what lets a crashed mid-turn `iterate: true` turn resume — it round-trips the existing `SupervisorSnapshot` envelope (the same shape the supervisor's own `snapshotStore` uses).
|
|
17
|
+
|
|
18
|
+
`iterate: false` orchestrators need only a `checkpointStore`. `iterate: true` needs **both**.
|
|
19
|
+
|
|
20
|
+
## Wiring
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
import { ai } from "@warlock.js/ai";
|
|
24
|
+
|
|
25
|
+
const orch = ai.orchestrator({
|
|
26
|
+
name: "support",
|
|
27
|
+
intents,
|
|
28
|
+
route,
|
|
29
|
+
iterate: true,
|
|
30
|
+
checkpointStore: ai.checkpoint.pg({ client: pgPool }),
|
|
31
|
+
snapshotStore: ai.snapshot.pg({ client: pgPool }), // a single pg.Pool backs both
|
|
32
|
+
});
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Global defaults
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
ai.config({
|
|
39
|
+
defaultCheckpointStore: ai.checkpoint.memory(),
|
|
40
|
+
defaultSnapshotStore: ai.snapshot.memory(),
|
|
41
|
+
});
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Resolution: explicit `checkpointStore` / `snapshotStore` on the config wins, else the matching `ai.config({ default… })`, else undefined. `iterate: true` with no snapshot store resolvable throws `OrchestratorConfigError` at construction.
|
|
45
|
+
|
|
46
|
+
## The three drivers
|
|
47
|
+
|
|
48
|
+
| Driver | Client | Durable | Cross-process | Fits |
|
|
49
|
+
|---|---|---|---|---|
|
|
50
|
+
| `memory()` | none | ❌ | ❌ | dev / tests / single-process; no resume across restarts |
|
|
51
|
+
| `pg({ client, table?, ttl? })` | dev-supplied `pg.Pool`/`Client` | ✅ | ✅ | production with Postgres |
|
|
52
|
+
| `redis({ client, prefix?, ttl? })` | dev-supplied `redis` client | ✅ | ✅ | production with Redis |
|
|
53
|
+
|
|
54
|
+
`@warlock.js/ai` takes **NO peer dependency** on `pg` or `redis` — you install the client, build it, and pass it in via `{ client }` (anything matching `PgClientLike` / `RedisClientLike`). The store never opens or closes the connection. A single `pg.Pool` can back the cache, the checkpoint store, and the snapshot store at once.
|
|
55
|
+
|
|
56
|
+
```ts
|
|
57
|
+
import { Pool } from "pg";
|
|
58
|
+
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
|
|
59
|
+
|
|
60
|
+
ai.checkpoint.pg({ client: pool, table: "warlock_orchestrator_sessions", ttl: 86_400 });
|
|
61
|
+
ai.snapshot.pg({ client: pool, table: "warlock_supervisor_snapshots" });
|
|
62
|
+
|
|
63
|
+
// redis
|
|
64
|
+
ai.checkpoint.redis({ client: redisClient, prefix: "warlock:orchestrator", ttl: 86_400 });
|
|
65
|
+
ai.snapshot.redis({ client: redisClient, prefix: "warlock:snapshot" });
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Table / prefix names must be safe SQL identifiers (`[A-Za-z_][A-Za-z0-9_]*`) — interpolated into DDL/DML, so anything outside that subset is rejected. Defaults: pg checkpoint table `warlock_orchestrator_sessions`, pg snapshot table `warlock_supervisor_snapshots`, redis prefix `warlock:orchestrator`.
|
|
69
|
+
|
|
70
|
+
## Schema is NEVER auto-migrated
|
|
71
|
+
|
|
72
|
+
The framework never creates or alters tables. Each pg store exposes `schema()` returning the reference DDL — run it through YOUR migration tool once before use:
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
const store = ai.checkpoint.pg({ client: pool });
|
|
76
|
+
await pool.query(store.schema()); // once, via your migration tooling
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
The memory and redis drivers return an empty `schema()` string (no backing table), so callers can treat `schema()` uniformly.
|
|
80
|
+
|
|
81
|
+
## `CheckpointRecord` — the persisted row
|
|
82
|
+
|
|
83
|
+
```ts
|
|
84
|
+
type CheckpointRecord = {
|
|
85
|
+
orchestrator_name: string; // PK segment 1
|
|
86
|
+
session_id: string; // PK segment 2
|
|
87
|
+
turn_index: number; // PK segment 3 — highest is live
|
|
88
|
+
state: unknown; // post-merge session accumulator (TState)
|
|
89
|
+
last_route: string | string[] | null;
|
|
90
|
+
signature: string; // drift fingerprint at write time
|
|
91
|
+
version: string | null; // config.version tag — metadata only
|
|
92
|
+
summarized_through: number | null; // exclusive turn index compaction reached
|
|
93
|
+
lock_acquired_at: string | null; // compaction lock metadata
|
|
94
|
+
lock_expires_at: string | null;
|
|
95
|
+
saved_at: string; // ISO write timestamp
|
|
96
|
+
};
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Append-only from v1 — `save()` never overwrites a prior `turn_index`. `load(name, sessionId)` returns the latest row (highest `turn_index`), or `undefined` for a session the store has never seen.
|
|
100
|
+
|
|
101
|
+
## Store contract methods
|
|
102
|
+
|
|
103
|
+
Both stores: `load(...)`, `save(...)`, `delete(...)`, optional `list(...)`, `schema()`.
|
|
104
|
+
|
|
105
|
+
- **`list(orchestratorName, prefix?)`** (checkpoint) / **`list(prefix?)`** (snapshot) — enumerate session/run ids for the production boot-drain loop. Optional: stores that can't enumerate omit it.
|
|
106
|
+
- The orchestrator's **`keepSnapshots`** retention policy lives on the orchestrator config, NOT the store — the orchestrator calls the pg store's `prune()` after a successful `save` when `keepSnapshots` is a finite number; `"all"` skips pruning.
|
|
107
|
+
|
|
108
|
+
## Boot-drain pattern
|
|
109
|
+
|
|
110
|
+
On startup, resume any session whose last turn was interrupted mid-flight:
|
|
111
|
+
|
|
112
|
+
```ts
|
|
113
|
+
const sessions = await checkpointStore.list?.(orch.name) ?? [];
|
|
114
|
+
for (const sessionId of sessions) {
|
|
115
|
+
await orch.resume(sessionId); // null when nothing in flight — harmless
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Distinct from `@warlock.js/cache` snapshot resume
|
|
120
|
+
|
|
121
|
+
A bare `ai.supervisor()` / `ai.workflow()` uses a `snapshotStore` for `resume(runId)`. That `SnapshotStore` was promoted from the historical `@warlock.js/cache` `CacheDriver` path. ⚠ The CacheDriver overload is deprecated for one minor — new code wires `ai.snapshot.*` stores. See [`@warlock.js/ai/persist-ai-data/SKILL.md`](@warlock.js/ai/persist-ai-data/SKILL.md) for the supervisor/workflow side and the cache-backed semantic cache.
|
|
122
|
+
|
|
123
|
+
## See also
|
|
124
|
+
|
|
125
|
+
- [`@warlock.js/ai/run-orchestrator/SKILL.md`](@warlock.js/ai/run-orchestrator/SKILL.md) — the consumer of these stores
|
|
126
|
+
- [`@warlock.js/ai/persist-ai-data/SKILL.md`](@warlock.js/ai/persist-ai-data/SKILL.md) — supervisor/workflow snapshot resume + the SnapshotStore migration
|
|
127
|
+
- [`@warlock.js/ai/handle-ai-errors/SKILL.md`](@warlock.js/ai/handle-ai-errors/SKILL.md) — `OrchestratorDriftError` / `OrchestratorConfigError`
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: persist-ai-data
|
|
3
|
-
description: 'Persistence delegated to @warlock.js/cache — workflow + supervisor snapshot resume via snapshotStore, semantic cache via vector-capable CacheDriver, global
|
|
3
|
+
description: 'Persistence delegated to @warlock.js/cache — workflow + supervisor snapshot resume via snapshotStore (4.3.0: now a SnapshotStore from ai.snapshot.*, ⚠ moved off raw CacheDriver), semantic cache + memory via vector-capable CacheDriver, global defaults via ai.config({defaultStore}) + ai.config({defaultSnapshotStore}). Covers drift detection + three recovery paths. Triggers: `ai.config`, `defaultStore`, `defaultSnapshotStore`, `snapshotStore`, `ai.snapshot`, `wf.resume`, `supervisor.resume`, `WorkflowSnapshot`, `SupervisorSnapshot`, `WorkflowDriftError`, `SupervisorDriftError`, `force: true`; ''resume a workflow run'', ''configure snapshot store'', ''handle signature drift'', ''wire pg vector cache''; typical import `import { ai } from "@warlock.js/ai"`. Skip: orchestrator checkpoint/snapshot store factories — `@warlock.js/ai/manage-ai-stores/SKILL.md`; cache driver catalog — `@warlock.js/cache/cache-basics/SKILL.md`; competing libs `temporal`, `inngest`.'
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Persistence — `@warlock.js/cache` everywhere
|
|
@@ -23,15 +23,19 @@ description: 'Persistence delegated to @warlock.js/cache — workflow + supervis
|
|
|
23
23
|
└──────────────┘ └────────────────────┘ └──────────────────┘
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
-
## Resolution order
|
|
26
|
+
## Resolution order — two separate defaults
|
|
27
27
|
|
|
28
28
|
```
|
|
29
|
-
|
|
29
|
+
// semantic cache + memory (CacheDriver):
|
|
30
|
+
options.store ?? ai.config({ defaultStore }) ?? undefined
|
|
31
|
+
|
|
32
|
+
// supervisor / workflow / orchestrator snapshots (SnapshotStore):
|
|
33
|
+
options.snapshotStore ?? ai.config({ defaultSnapshotStore }) ?? undefined
|
|
30
34
|
```
|
|
31
35
|
|
|
32
|
-
When
|
|
36
|
+
`defaultStore` (a `CacheDriver`) and `defaultSnapshotStore` (a `SnapshotStore`) are independent — set whichever the consumer needs. When the relevant one is unset:
|
|
33
37
|
- **Snapshot consumers** silently skip writes and throw on `resume()`.
|
|
34
|
-
- **Semantic cache** throws at construction.
|
|
38
|
+
- **Semantic cache / memory** throws at construction.
|
|
35
39
|
|
|
36
40
|
## `ai.config({ defaultStore })` — set once at boot
|
|
37
41
|
|
|
@@ -60,26 +64,32 @@ Brute-force memory drivers carry an `O(N)` similarity scan — fine up to a few
|
|
|
60
64
|
|
|
61
65
|
## Snapshot resume — workflow + supervisor
|
|
62
66
|
|
|
63
|
-
|
|
67
|
+
> ⚠ **BREAKING (4.3.0): supervisor + workflow snapshot persistence moved `CacheDriver` → `SnapshotStore`.** A `snapshotStore` is now a `SnapshotStore` built with `ai.snapshot.{memory,pg,redis}()`, not a raw `cache.driver(...)`. The framework still ships a deprecated `CacheDriver` overload for ONE minor so existing wiring keeps working, but new code uses the dedicated store factories. The `defaultSnapshotStore` resolution is via `ai.config({ defaultSnapshotStore })` (a `SnapshotStore`), separate from `defaultStore` (a `CacheDriver`, still used for `semanticCache` + memory). See [`@warlock.js/ai/manage-ai-stores/SKILL.md`](@warlock.js/ai/manage-ai-stores/SKILL.md).
|
|
68
|
+
|
|
69
|
+
### Wiring (new)
|
|
64
70
|
|
|
65
71
|
```ts
|
|
66
|
-
|
|
72
|
+
import { ai } from "@warlock.js/ai";
|
|
73
|
+
|
|
74
|
+
ai.config({ defaultSnapshotStore: ai.snapshot.redis({ client }) });
|
|
67
75
|
|
|
68
76
|
const wf = ai.workflow({
|
|
69
77
|
name: "ticket-processor",
|
|
70
78
|
steps: [...],
|
|
71
|
-
// snapshotStore optional — falls back to
|
|
79
|
+
// snapshotStore optional — falls back to ai.config({ defaultSnapshotStore })
|
|
72
80
|
});
|
|
73
81
|
|
|
74
82
|
const sup = ai.supervisor({
|
|
75
83
|
name: "support-team",
|
|
76
84
|
router: routerAgent,
|
|
77
85
|
intents: { triage, billing, resolver },
|
|
78
|
-
// explicit override when this primitive needs a different
|
|
79
|
-
snapshotStore:
|
|
86
|
+
// explicit override when this primitive needs a different store
|
|
87
|
+
snapshotStore: ai.snapshot.pg({ client: pgPool, table: "support_runs" }),
|
|
80
88
|
});
|
|
81
89
|
```
|
|
82
90
|
|
|
91
|
+
The `SnapshotStore` is generic over its snapshot shape — it defaults to `SupervisorSnapshot`, and the workflow engine parameterizes it with `WorkflowSnapshot`; the only structural requirement is a `runId` string. `ai.snapshot.memory()` for dev/tests, `ai.snapshot.{pg,redis}()` for production (dev-owned client, never-auto-migrated `schema()`).
|
|
92
|
+
|
|
83
93
|
### Snapshot shapes
|
|
84
94
|
|
|
85
95
|
```ts
|
|
@@ -200,6 +210,7 @@ The driver must support `similar()`. Without similarity → `CacheUnsupportedErr
|
|
|
200
210
|
|
|
201
211
|
## See also
|
|
202
212
|
|
|
213
|
+
- [`@warlock.js/ai/manage-ai-stores/SKILL.md`](@warlock.js/ai/manage-ai-stores/SKILL.md) — `ai.snapshot.*` + `ai.checkpoint.*` store factories, schema(), drivers
|
|
203
214
|
- [`@warlock.js/ai/run-ai-workflow/SKILL.md`](@warlock.js/ai/run-ai-workflow/SKILL.md) — `snapshotStore` + `resume()`
|
|
204
215
|
- [`@warlock.js/ai/run-supervisor/SKILL.md`](@warlock.js/ai/run-supervisor/SKILL.md) — same on supervisor
|
|
205
216
|
- [`@warlock.js/ai/attach-ai-middleware/SKILL.md`](@warlock.js/ai/attach-ai-middleware/SKILL.md) — `semanticCache` middleware
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: pick-ai-provider
|
|
3
|
-
description: 'Choose an AI provider adapter — @warlock.js/ai-openai (shipped, also handles OpenRouter / Azure via baseURL), @warlock.js/ai-anthropic, @warlock.js/ai-bedrock, @warlock.js/ai-google, @warlock.js/ai-ollama. Triggers: `OpenAISDK`, `SDKAdapterContract`, `ModelContract`, `sdk.model`, `sdk.embedder`, `capabilities.vision`, `capabilities.structuredOutput`, `pricing`, `baseURL`, `provider: "openrouter"`; ''pick a provider'', ''openai vs openrouter'', ''does this model support vision'', ''configure pricing''; typical import `import { OpenAISDK } from "@warlock.js/ai-openai"`. Skip: agent factory — `@warlock.js/ai/run-ai-agent/SKILL.md`; competing libs raw `openai`, `@anthropic-ai/sdk`, `@aws-sdk/client-bedrock-runtime`.'
|
|
3
|
+
description: 'Choose an AI provider adapter — @warlock.js/ai-openai (shipped, also handles OpenRouter / Azure via baseURL), @warlock.js/ai-anthropic, @warlock.js/ai-bedrock, @warlock.js/ai-google, @warlock.js/ai-ollama — plus cost truth: ModelPricing (per-1M tokens), Usage cost breakdown, the cachedTokens / cacheWriteTokens / reasoningTokens channels, and capability flags. Triggers: `OpenAISDK`, `SDKAdapterContract`, `ModelContract`, `ModelPricing`, `ModelCapabilities`, `sdk.model`, `sdk.embedder`, `capabilities.vision`, `capabilities.structuredOutput`, `capabilities.reasoning`, `capabilities.promptCaching`, `pricing`, `Usage.cost`, `cachedTokens`, `cacheWriteTokens`, `reasoningTokens`, `reasoning.effort`, `cacheControl`, `baseURL`, `provider: "openrouter"`; ''pick a provider'', ''openai vs openrouter'', ''does this model support vision/reasoning'', ''configure pricing'', ''how much did reasoning cost'', ''prompt cache tokens''; typical import `import { OpenAISDK } from "@warlock.js/ai-openai"`. Skip: agent factory — `@warlock.js/ai/run-ai-agent/SKILL.md`; competing libs raw `openai`, `@anthropic-ai/sdk`, `@aws-sdk/client-bedrock-runtime`.'
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Pick an AI provider adapter
|
|
@@ -44,16 +44,20 @@ Adapters are classes — `new OpenAISDK({ apiKey })`, `new AnthropicSDK({ apiKey
|
|
|
44
44
|
- `count(text, model?)` — provider-appropriate token count.
|
|
45
45
|
- `embedder({ name })` — text-to-vector. Optional; check `typeof sdk.embedder === "function"` before calling.
|
|
46
46
|
|
|
47
|
-
The `ModelContract.capabilities` field declares what the model supports —
|
|
47
|
+
The `ModelContract.capabilities` field declares what the model supports — all flags optional (absent = treat as `false`):
|
|
48
48
|
|
|
49
49
|
```ts
|
|
50
50
|
type ModelCapabilities = {
|
|
51
51
|
structuredOutput?: boolean; // native response_format: json_schema support?
|
|
52
52
|
vision?: boolean; // can accept image attachments?
|
|
53
|
+
reasoning?: boolean; // forwards ModelCallOptions.reasoning (effort / thinking budget)?
|
|
54
|
+
promptCaching?: boolean; // honors cacheControl breakpoints + reports cache token channels?
|
|
55
|
+
audio?: boolean; // can accept audio ContentPart input?
|
|
56
|
+
pdf?: boolean; // can accept PDF / document ContentPart input?
|
|
53
57
|
};
|
|
54
58
|
```
|
|
55
59
|
|
|
56
|
-
The framework reads `capabilities` to fail loud upfront — e.g. passing `attachments: [...]` to a non-vision model throws at the boundary instead of failing mid-trip.
|
|
60
|
+
The framework reads `capabilities` to fail loud upfront — e.g. passing `attachments: [...]` to a non-vision model throws at the boundary instead of failing mid-trip; reasoning / cacheControl options are silently skipped when the adapter doesn't declare support, rather than sent as unsupported params.
|
|
57
61
|
|
|
58
62
|
## OpenAI adapter — usage
|
|
59
63
|
|
|
@@ -100,23 +104,53 @@ const customModel = openai.model({
|
|
|
100
104
|
});
|
|
101
105
|
```
|
|
102
106
|
|
|
103
|
-
##
|
|
107
|
+
## Cost truth — pricing + token channels
|
|
104
108
|
|
|
105
|
-
|
|
109
|
+
`ModelPricing` is **USD per 1,000,000 tokens** (the industry-standard unit), declared at two optional sites — `SDK.pricing` (registry keyed by model name) and `model({ pricing })` (per-model override, wins). Resolution: per-model > SDK registry > undefined (no cost computed).
|
|
106
110
|
|
|
107
111
|
```ts
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
+
type ModelPricing = {
|
|
113
|
+
input: number; // required — USD / 1M input tokens
|
|
114
|
+
output: number; // required — USD / 1M output tokens
|
|
115
|
+
cachedInput?: number; // prompt-cache READ rate; falls back to `input`
|
|
116
|
+
cachedOutput?: number; // cache-WRITE rate (Anthropic premium); falls back to `output`
|
|
117
|
+
reasoning?: number; // reasoning/thinking-token rate; falls back to `output`
|
|
118
|
+
};
|
|
119
|
+
```
|
|
112
120
|
|
|
121
|
+
Configure it and every report carries `Usage.cost` — a per-channel breakdown captured at emit time as a historical fact (stored reports stay accurate after the upstream table changes):
|
|
122
|
+
|
|
123
|
+
```ts
|
|
113
124
|
const { usage } = await ai.agent({ model: openai.model({ name: "gpt-4o-mini" }) }).execute("hi");
|
|
114
125
|
|
|
115
|
-
usage.cost;
|
|
116
|
-
//
|
|
126
|
+
usage.cost; // { input, output, cachedInput?, cachedOutput? } — USD per channel
|
|
127
|
+
// single scalar total: sum the populated fields, treating undefined as 0.
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
`usage.cost` is `undefined` when no pricing is available — honest absence over false zero. Aggregators merge only defined fields, so one unpriced child never erases a priced sibling's cost.
|
|
131
|
+
|
|
132
|
+
### Token channels (`Usage`) — what each adapter reports
|
|
133
|
+
|
|
134
|
+
Beyond `input` / `output` / `total`, `Usage` carries optional sub-channels (undefined when the provider doesn't meter them):
|
|
135
|
+
|
|
136
|
+
| Channel | Meaning | Provider source |
|
|
137
|
+
|---|---|---|
|
|
138
|
+
| `cachedTokens` | subset of `input` served from prompt cache (READ hit) | OpenAI `prompt_tokens_details.cached_tokens`, Anthropic `cache_read_input_tokens` |
|
|
139
|
+
| `cacheWriteTokens` | input tokens WRITTEN to the cache this call | Anthropic `cache_creation_input_tokens` (OpenAI does not write-bill) |
|
|
140
|
+
| `reasoningTokens` | subset of `output` for internal reasoning/thinking | OpenAI `completion_tokens_details.reasoning_tokens`, Anthropic extended-thinking |
|
|
141
|
+
|
|
142
|
+
### Driving cache + reasoning per call
|
|
143
|
+
|
|
144
|
+
`ModelCallOptions` exposes vendor-neutral controls the agent forwards only when `capabilities` allows:
|
|
145
|
+
|
|
146
|
+
```ts
|
|
147
|
+
await model.complete(messages, {
|
|
148
|
+
reasoning: { effort: "high", maxTokens: 8_000 }, // effort → OpenAI reasoning_effort; maxTokens → Anthropic thinking budget
|
|
149
|
+
cacheControl: { breakpoints: 1 }, // WRITE breakpoint → Anthropic cache_control markers
|
|
150
|
+
});
|
|
117
151
|
```
|
|
118
152
|
|
|
119
|
-
|
|
153
|
+
Read-side cache accounting (`Usage.cachedTokens`) works WITHOUT `cacheControl` — it only controls WRITE placement. Adapters whose `capabilities.reasoning` / `.promptCaching` is absent ignore these rather than forwarding unsupported params.
|
|
120
154
|
|
|
121
155
|
## Embeddings
|
|
122
156
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: run-ai-agent
|
|
3
|
-
description: 'Build agents with ai.agent({...}) — the single-LLM-turn primitive. Covers execute / stream, attachments, structured output, placeholders, events. Triggers: `ai.agent`, `agent.execute`, `agent.stream`, `AgentResult`, `AgentReport`, `streamingToolGuard`, `attachments`, `repair`, `maxTrips`, `sessionId`; ''run an agent'', ''stream an agent response'', ''structured output schema'', ''pass image to agent'', ''cancel an agent run''; typical import `import { ai } from "@warlock.js/ai"`. Skip: tool definition — `@warlock.js/ai/define-ai-tool/SKILL.md`; workflows — `@warlock.js/ai/run-ai-workflow/SKILL.md`; competing libs `langchain`, `ai` (Vercel), raw `openai`.'
|
|
3
|
+
description: 'Build agents with ai.agent({...}) — the single-LLM-turn primitive. Covers execute / stream, attachments, structured output, placeholders, events, agent.eval scoring, and auto-adapting raw executables in tools:[]. Triggers: `ai.agent`, `agent.execute`, `agent.stream`, `agent.eval`, `AgentResult`, `AgentReport`, `AgentToolEntry`, `streamingToolGuard`, `attachments`, `repair`, `maxTrips`, `sessionId`, `spawnSubAgent`, `SpawnSubAgentSpec`; ''run an agent'', ''stream an agent response'', ''structured output schema'', ''pass image to agent'', ''evaluate an agent'', ''put a supervisor in tools'', ''cancel an agent run'', ''spawn a one-shot sub-agent with a per-task budget''; typical import `import { ai } from "@warlock.js/ai"`. Skip: tool definition — `@warlock.js/ai/define-ai-tool/SKILL.md`; workflows — `@warlock.js/ai/run-ai-workflow/SKILL.md`; eval matchers / batch / fallback detail — `@warlock.js/ai/ai-dx-helpers/SKILL.md`; competing libs `langchain`, `ai` (Vercel), raw `openai`.'
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# `ai.agent()` — single-turn primitive
|
|
@@ -19,7 +19,7 @@ ai.agent({
|
|
|
19
19
|
name?: string, // optional — anonymous gets a fingerprint
|
|
20
20
|
model: openai.model({ name: "gpt-4o-mini" }),
|
|
21
21
|
systemPrompt?: string | SystemPromptContract,
|
|
22
|
-
tools?:
|
|
22
|
+
tools?: AgentToolEntry<any, any>[], // ToolContract OR a raw executable (auto-adapted)
|
|
23
23
|
placeholders?: Record<string, unknown>,
|
|
24
24
|
maxTrips?: number, // default 10
|
|
25
25
|
modelOptions?: ModelCallOptions,
|
|
@@ -255,6 +255,55 @@ await myAgent.execute("go", {
|
|
|
255
255
|
|
|
256
256
|
Every event payload carries `runId` and `rootRunId`. Same identity fields ride on stream events.
|
|
257
257
|
|
|
258
|
+
## `tools: []` — auto-adapt executables
|
|
259
|
+
|
|
260
|
+
Each `tools` entry is either a built `ToolContract` (from `ai.tool(...)` or an explicit `.asTool(...)`) OR a **raw executable primitive** (`AgentContract` / `WorkflowInstance` / `SupervisorContract` / orchestrator) — auto-adapted into a `ToolContract` at factory time. The manifest is derived from the executable's `name` + `description` + (optional) `inputSchema`; dispatch flows through its `execute()`.
|
|
261
|
+
|
|
262
|
+
```ts
|
|
263
|
+
const concierge = ai.agent({
|
|
264
|
+
model,
|
|
265
|
+
tools: [billingWorkflow, supportSupervisor, lookupTool], // no .asTool() needed
|
|
266
|
+
});
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
`.asTool()` still works and takes precedence when you need a custom name / schema per use. A supervisor/orchestrator needs `inputSchema` on its config to drop straight into `tools: []`. See [`@warlock.js/ai/define-ai-tool/SKILL.md`](@warlock.js/ai/define-ai-tool/SKILL.md).
|
|
270
|
+
|
|
271
|
+
## `agent.eval(options)` — score the agent against a suite
|
|
272
|
+
|
|
273
|
+
```ts
|
|
274
|
+
const report = await myAgent.eval({
|
|
275
|
+
cases: [
|
|
276
|
+
{ name: "capital", input: "Capital of Egypt?", expected: "Cairo" },
|
|
277
|
+
{ name: "tone", input: "Comfort an upset user." }, // judge-scored
|
|
278
|
+
],
|
|
279
|
+
scorers: [ai.eval.contains()], // default for cases w/o their own
|
|
280
|
+
judge: { agent: judgeAgent, rubric: "Score 1.0 only if empathetic." }, // LLM-as-judge fallback
|
|
281
|
+
passThreshold: 0.5, // default
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
expect(report.passed).toBe(true); // true only when EVERY case passed
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
Each case runs through `execute(input)`; scorer precedence is per-case `scorers` → suite `scorers` → synthesized `judge` (throws at author time if a case resolves none). Built-in scorers on `ai.eval.*`: `exact()`, `contains()`, `predicate(fn)`, `judge(config)`. Full coverage — plus the Vitest matchers (`registerAiMatchers` / `toRouteTo` / `toConverge` / `toPassStep` / `toOutputShape`) — in [`@warlock.js/ai/ai-dx-helpers/SKILL.md`](@warlock.js/ai/ai-dx-helpers/SKILL.md).
|
|
288
|
+
|
|
289
|
+
## `ai.spawnSubAgent()` — one-shot delegation with a budget
|
|
290
|
+
|
|
291
|
+
`ai.spawnSubAgent(spec)` is a thin wrapper over this same `ai.agent()`: it builds a fresh agent from the spec, optionally attaches a `budget` middleware, runs the `task` once, and returns the `AgentResult`. Not a sandbox or a separate runtime — a spawn is an ordinary new agent (empty conversation, its own tools/prompt). It is a **general** primitive: usable inside a tool, a workflow or planner step, a supervisor intent, or hand-rolled orchestration — it is NOT planner-specific (the planner engine never calls it).
|
|
292
|
+
|
|
293
|
+
```ts
|
|
294
|
+
import { ai } from "@warlock.js/ai";
|
|
295
|
+
|
|
296
|
+
const result = await ai.spawnSubAgent({
|
|
297
|
+
name: "extract-entities",
|
|
298
|
+
model,
|
|
299
|
+
task: "Pull every company name from this article: ...",
|
|
300
|
+
budget: { maxCostUSD: 0.05 }, // per-task spend cap — aborts when crossed
|
|
301
|
+
output: companiesSchema,
|
|
302
|
+
});
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
The one field a bare agent config doesn't surface ergonomically is `budget` (`BudgetOptions` — `maxTokens` / `maxCostUSD`), equivalent to `ai.agent({ middleware: [ai.middleware.budget(...)] })` but promoted to a first-class spec field so a delegated subtask can't overrun its cap (distinct from `maxTrips`, which caps round-trips, not spend). The surface is **narrower** than `agent.execute()`: one-shot, with no `history`, `placeholders`, per-call events, or `repair`. The spawned `report` slots under the caller's `report.children[]`, so cost and traces roll up uniformly. Reach for it when you want a named single-use delegation with a hard spend cap; otherwise just build an `ai.agent()` and call it.
|
|
306
|
+
|
|
258
307
|
## When NOT to use this primitive
|
|
259
308
|
|
|
260
309
|
- Multi-step pipeline with a fixed shape → [`@warlock.js/ai/run-ai-workflow/SKILL.md`](@warlock.js/ai/run-ai-workflow/SKILL.md)
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: run-orchestrator
|
|
3
|
+
description: 'Durable stateful sessions with ai.orchestrator({...}) — the capstone of the 4-primitive ladder. Wraps a supervisor with cross-turn session state (checkpointStore), per-turn windowing, drift detection, post-turn compaction, mid-turn resume (iterate: true + snapshotStore), per-turn memory, typed commands, asTool, and a 3-tier event model. Triggers: `ai.orchestrator`, `orchestrator.execute`, `orchestrator.resume`, `orchestrator.command`, `orchestrator.stream`, `OrchestratorConfig`, `OrchestratorResult`, `OrchestratorReport`, `OrchestratorContract`, `CheckpointStore`, `OrchestratorDriftError`, `sessionId`, `iterate`, `historyWindow`, `summarize`, `keepSnapshots`, `awaiting-input`, `turns[]`, `TurnSnapshot`, `CompactionResult`, `initialAgent`, `checkpointStore`; ''multi-turn conversation that persists'', ''durable session across calls'', ''resume an interrupted turn'', ''compact session history'', ''per-session memory''; typical import `import { ai } from "@warlock.js/ai"`. Skip: a single routing turn with no session — `@warlock.js/ai/run-supervisor/SKILL.md`; a fixed pipeline — `@warlock.js/ai/run-ai-workflow/SKILL.md`; the store factories themselves — `@warlock.js/ai/manage-ai-stores/SKILL.md`; competing libs `langgraph`, `crewai`.'
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# `ai.orchestrator()` — durable stateful sessions
|
|
7
|
+
|
|
8
|
+
The capstone of the 4-primitive ladder. An orchestrator is a **session-state manager wrapped around a supervisor**: each `execute` / `stream` call is ONE turn against a named `sessionId`, with the session's accumulated state, drift signature, and compaction progress persisted in a `CheckpointStore` between calls. The "what runs" fields (`intents`, `route` / `router`, `evaluate`, `state`, `output`, `initialAgent`, `maxIterations`) are the supervisor's surface spread directly — the orchestrator builds the supervisor lazily per turn and delegates to it. You never see the supervisor object.
|
|
9
|
+
|
|
10
|
+
## When to reach for it
|
|
11
|
+
|
|
12
|
+
- **`supervisor`** — routes one input to a specialist each turn; stateless between runs unless you wire `snapshotStore`. No cross-turn session memory.
|
|
13
|
+
- **`orchestrator`** — when the **session** matters: a long-running conversation where each turn must rehydrate the prior turn's state, history must be windowed/compacted, and an interrupted turn must resume after a crash.
|
|
14
|
+
|
|
15
|
+
## Shape
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import { ai } from "@warlock.js/ai";
|
|
19
|
+
import { END } from "@warlock.js/ai";
|
|
20
|
+
|
|
21
|
+
type SessionState = { category?: string; order?: { id: string }; reply?: string };
|
|
22
|
+
|
|
23
|
+
const supportBot = ai.orchestrator<SessionState>({
|
|
24
|
+
name: "refund-support",
|
|
25
|
+
intents: { classify, lookup, process, compose },
|
|
26
|
+
route: (ctx) => (ctx.iteration === 0 ? "classify" : END),
|
|
27
|
+
iterate: true, // delegate each turn to a real supervisor
|
|
28
|
+
historyWindow: { router: 5, agents: 20 },
|
|
29
|
+
summarize: { afterTurns: 20, keep: 6 }, // auto-compaction policy
|
|
30
|
+
keepSnapshots: 100, // turns retained per session
|
|
31
|
+
checkpointStore: ai.checkpoint.pg({ client: pg }),
|
|
32
|
+
snapshotStore: ai.snapshot.pg({ client: pg }), // required when iterate: true
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
const result = await supportBot.execute(message, { sessionId: "sess_42", history });
|
|
36
|
+
|
|
37
|
+
if (result.report.status === "awaiting-input") {
|
|
38
|
+
// session continues — wait for the next user turn
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
`route` XOR `router` is required (mutually exclusive). `initialAgent`, when set, must be a key in `intents` and dispatches on turn 0, skipping the first route/router call. All config-shape errors throw `OrchestratorConfigError` at construction (author-time), not on the first turn.
|
|
43
|
+
|
|
44
|
+
## The session is owned by `sessionId` — passed per call
|
|
45
|
+
|
|
46
|
+
There is no stateful session object and no implicit "current session" — every method names the session it acts on via `options.sessionId`. `history` is **required** on every `execute` call: the framework never persists raw messages (it owns session *state*, not the message log — that is the dev's store). `state` is a partial seed/patch shallow-merged into the loaded session state; `context` is the request-scoped bag, frozen at intake.
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
await supportBot.execute(input, {
|
|
50
|
+
sessionId: "sess_42", // required — names the session
|
|
51
|
+
history: priorMessages, // required — the dev re-supplies prior turns each call
|
|
52
|
+
state: { tier: "gold" }, // partial patch shallow-merged into loaded state
|
|
53
|
+
context: { userId, db }, // request-scoped, never persisted
|
|
54
|
+
signal: AbortSignal.timeout(60_000),
|
|
55
|
+
on: { "orchestrator.turn.awaiting-input": (e) => log(e) }, // tier-3 per-call handlers
|
|
56
|
+
force: false, // bypass drift check for this call
|
|
57
|
+
});
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## The turn lifecycle (what each turn does)
|
|
61
|
+
|
|
62
|
+
1. **load** — read the latest checkpoint for `(name, sessionId)`; seed empty on first call (`orchestrator.session.loaded`).
|
|
63
|
+
2. **drift check** — compare the loaded checkpoint's `signature` to the current definition (`orchestrator.drift.checked`). Mismatch throws `OrchestratorDriftError` unless `force: true`.
|
|
64
|
+
3. **lock wait** — wait on the compaction lock if held (`orchestrator.lock.waiting`).
|
|
65
|
+
4. **window** — slice history per `historyWindow.{router,agents}` (`orchestrator.history.windowed`).
|
|
66
|
+
5. **dispatch** — `route`/`router` (or `initialAgent` on turn 0) picks the intent(s); the supervisor runs the turn (`orchestrator.turn.routed`, `orchestrator.turn.streaming`).
|
|
67
|
+
6. **persist** — append a checkpoint row for the settled turn, then prune to `keepSnapshots` (`orchestrator.checkpoint.persisted`).
|
|
68
|
+
7. **compaction** — fire the post-turn compaction trigger if configured (`orchestrator.compaction.suggested` / `.applied`).
|
|
69
|
+
|
|
70
|
+
A clean turn ends with `orchestrator.turn.awaiting-input` (the session stays open for the next user turn); `orchestrator.turn.failed` and `orchestrator.turn.cancelled` end error / cancelled turns. (`orchestrator.turn.completed` is defined on the event map, but the v1 lifecycle maps a clean completion to `awaiting-input`, so it isn't emitted on the normal path — subscribe to `awaiting-input` for "turn done".)
|
|
71
|
+
|
|
72
|
+
## `OrchestratorResult` — read the report
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
const result = await supportBot.execute(message, { sessionId, history });
|
|
76
|
+
|
|
77
|
+
result.sessionId; // echoes the session this turn acted on
|
|
78
|
+
result.turnIndex; // zero-indexed turn number
|
|
79
|
+
result.data; // validated against `output`, if set
|
|
80
|
+
result.error; // typed AIError — execute() never throws on runtime failure
|
|
81
|
+
result.report.type; // "orchestrator"
|
|
82
|
+
result.report.status; // ReportStatus | "awaiting-input"
|
|
83
|
+
result.report.turns; // TurnSnapshot[] — current turn + prior, bounded by keepSnapshots
|
|
84
|
+
result.compaction; // CompactionResult when a turn compacted (and no onCompact ran)
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
`report.children[]` carries ONLY the current turn's dispatched primitive reports. Full session history lives on `report.turns[]` — a `children[]` walker will NOT reach prior turns (intentional). Child `supervisor.*` / `agent.*` events bubble up unmodified under their own identity.
|
|
88
|
+
|
|
89
|
+
**`awaiting-input` is the only non-terminal status across the unified result tree.** Code branching on `status === "completed"` MUST explicitly handle `"awaiting-input"` as a session-continues path, not a failure.
|
|
90
|
+
|
|
91
|
+
## `iterate` — single dispatch vs. internal supervisor
|
|
92
|
+
|
|
93
|
+
- **`iterate: false`** (default) — one dispatch per turn. No `snapshotStore` needed.
|
|
94
|
+
- **`iterate: true`** — each turn delegates to a real internal supervisor that loops to `maxIterations` (default 10). **Requires** a `snapshotStore` (explicit or `ai.config({ defaultSnapshotStore })`) so a crashed mid-turn iteration can resume. Construction throws if you set `iterate: true` without one.
|
|
95
|
+
|
|
96
|
+
## `resume()` — drain an interrupted turn
|
|
97
|
+
|
|
98
|
+
```ts
|
|
99
|
+
const result = await supportBot.resume("sess_42", { context: { db }, force: false });
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Resume continues an interrupted `iterate: true` turn from its persisted supervisor snapshot. Returns `null` when there is nothing in flight for the session (a no-op for `iterate: false` orchestrators). It re-supplies request-scoped `context` (NOT persisted) and rehydrates state from the checkpoint — there is no `history` field, since it continues an in-flight turn rather than opening a fresh one. Runs the same drift check as `execute()`; throws `OrchestratorDriftError` on mismatch unless `{ force: true }`. Use the boot-drain pattern: enumerate sessions via `checkpointStore.list(name)` and `resume()` each on startup.
|
|
103
|
+
|
|
104
|
+
## Compaction — `summarize`
|
|
105
|
+
|
|
106
|
+
Bounds session history growth. Two forms:
|
|
107
|
+
|
|
108
|
+
```ts
|
|
109
|
+
// Object policy — count-based auto-fire after `afterTurns`, keep the most recent `keep`.
|
|
110
|
+
summarize: {
|
|
111
|
+
afterTurns: 20,
|
|
112
|
+
keep: 6,
|
|
113
|
+
summarizer: cheapModel, // defaults to the orchestrator's own model
|
|
114
|
+
onCompact: async (compaction, ctx) => { // apply to the dev's message store
|
|
115
|
+
await messages.applyCompaction(ctx.sessionId, compaction);
|
|
116
|
+
},
|
|
117
|
+
lock: { maxWait: 5_000 },
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Callback form — full control; NEVER auto-fires, driven only by command("compact").
|
|
121
|
+
summarize: (history) => ({ summary, replacesFromIndex, replacesToIndex }),
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
A `CompactionResult` is `{ summary: Message, replacesFromIndex, replacesToIndex }` — the replacement summary plus the inclusive index range it replaces in the dev's history array. When `onCompact` is supplied the orchestrator applies it for you and does NOT surface `result.compaction`; otherwise it surfaces `result.compaction` for you to apply manually.
|
|
125
|
+
|
|
126
|
+
## `command()` — typed built-ins
|
|
127
|
+
|
|
128
|
+
```ts
|
|
129
|
+
const compaction = await supportBot.command("compact", { sessionId, history });
|
|
130
|
+
// → { summary, replacesFromIndex, replacesToIndex }
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
v1 ships exactly one built-in command, `compact` (manual compaction outside the auto-trigger; reuses the same compaction code path). User commands attach via module augmentation of `OrchestratorCommands` — declaring extra keys in your own `.d.ts` widens the typed `command<K>` surface without a framework release.
|
|
134
|
+
|
|
135
|
+
## Per-turn memory — `memory`
|
|
136
|
+
|
|
137
|
+
Wire an `ai.memory()` store so each turn recalls relevant memories before routing and remembers the settled outcome after:
|
|
138
|
+
|
|
139
|
+
```ts
|
|
140
|
+
ai.orchestrator({
|
|
141
|
+
name: "support",
|
|
142
|
+
intents,
|
|
143
|
+
route,
|
|
144
|
+
memory: mem, // bare MemoryContract — recall + remember w/ defaults
|
|
145
|
+
// or finer control:
|
|
146
|
+
memory: {
|
|
147
|
+
store: mem,
|
|
148
|
+
recall: { k: 5, threshold: 0.7, tier: "semantic" }, // k: 0 = write-only memory
|
|
149
|
+
remember: true, // false = read-only (recall, never write)
|
|
150
|
+
rememberTier: "semantic",
|
|
151
|
+
injectKey: "memories", // ctx.context[injectKey] holds RecalledMemory[]
|
|
152
|
+
},
|
|
153
|
+
});
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Recalled memories land in the per-turn `context` bag under `injectKey` (default `"memories"`) — every route / router / evaluate / dispatch callback reads them at `ctx.context.memories`. Memory never mutates the prompt itself; surfacing it stays explicit. Cancelled / failed turns never remember (they revert), regardless of `remember`. See [`@warlock.js/ai/use-ai-memory/SKILL.md`](@warlock.js/ai/use-ai-memory/SKILL.md).
|
|
157
|
+
|
|
158
|
+
## `asTool()` — orchestrator as a tool
|
|
159
|
+
|
|
160
|
+
```ts
|
|
161
|
+
const supportTool = supportBot.asTool({
|
|
162
|
+
name: "handle_refund",
|
|
163
|
+
description: "Handle a refund conversation end-to-end.",
|
|
164
|
+
inputSchema: v.object({ message: v.string() }),
|
|
165
|
+
sessionScope: "fresh", // default — each call gets a brand-new sessionId
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
const concierge = ai.agent({ model, tools: [supportTool] });
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
The tool boundary is **opaque**: the parent's `signal` / `context` / events do NOT auto-forward — anything the wrapped orchestrator needs must ride on the `inputSchema` payload. `sessionScope`:
|
|
172
|
+
- **`"fresh"`** (default) — each invocation gets a generated `sessionId` and empty history; no continuity across calls.
|
|
173
|
+
- **`"shared"`** — the parent threads `sessionId` (and optionally `history`) through the validated payload; the orchestrator participates in that session. A missing/blank `sessionId` throws.
|
|
174
|
+
|
|
175
|
+
## Drift detection
|
|
176
|
+
|
|
177
|
+
The orchestrator signature fingerprints: name + intents map + route/router presence + evaluate presence + initialAgent + maxIterations + iterate flag + historyWindow shape. It does NOT aggregate the internal supervisor's signature — internal-supervisor drift surfaces only on `iterate: true` resume via the supervisor's own drift check. On mismatch, `OrchestratorDriftError` (`code: "ORCHESTRATOR_DRIFT"`, `category: "drift"`) is thrown synchronously — nothing dispatches. Recover by discarding the session, migrating the persisted checkpoint, or passing `{ force: true }`.
|
|
178
|
+
|
|
179
|
+
## 3-tier events
|
|
180
|
+
|
|
181
|
+
Handlers fire definition → instance → per-call, in that order, on every emission:
|
|
182
|
+
|
|
183
|
+
```ts
|
|
184
|
+
const orch = ai.orchestrator({ ..., on: { "orchestrator.turn.failed": tier1 } }); // tier 1 — definition
|
|
185
|
+
const off = orch.on("orchestrator.turn.completed", tier2); // tier 2 — instance
|
|
186
|
+
await orch.execute(input, { sessionId, history, on: { "orchestrator.drift.checked": tier3 } }); // tier 3 — per-call
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## Stores
|
|
190
|
+
|
|
191
|
+
`checkpointStore` (cross-turn session state) and `snapshotStore` (internal-supervisor run state for `iterate: true`) are distinct contracts with distinct factories. See [`@warlock.js/ai/manage-ai-stores/SKILL.md`](@warlock.js/ai/manage-ai-stores/SKILL.md).
|
|
192
|
+
|
|
193
|
+
## See also
|
|
194
|
+
|
|
195
|
+
- [`@warlock.js/ai/run-supervisor/SKILL.md`](@warlock.js/ai/run-supervisor/SKILL.md) — the engine each turn delegates to
|
|
196
|
+
- [`@warlock.js/ai/manage-ai-stores/SKILL.md`](@warlock.js/ai/manage-ai-stores/SKILL.md) — `ai.checkpoint.*` / `ai.snapshot.*`
|
|
197
|
+
- [`@warlock.js/ai/use-ai-memory/SKILL.md`](@warlock.js/ai/use-ai-memory/SKILL.md) — the `memory` field
|
|
198
|
+
- [`@warlock.js/ai/handle-ai-errors/SKILL.md`](@warlock.js/ai/handle-ai-errors/SKILL.md) — `OrchestratorDriftError` / `OrchestratorConfigError`
|