@warlock.js/ai 4.2.10 → 4.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +61 -1
- package/cjs/index.cjs +10151 -4625
- package/cjs/index.cjs.map +1 -1
- package/cjs/magic-string.es-BtxW4VqG.cjs +1015 -0
- package/cjs/magic-string.es-BtxW4VqG.cjs.map +1 -0
- package/cjs/matcher-logic-SBnzYohQ.cjs +217 -0
- package/cjs/matcher-logic-SBnzYohQ.cjs.map +1 -0
- package/cjs/matchers-BBh3gyB-.cjs +13739 -0
- package/cjs/matchers-BBh3gyB-.cjs.map +1 -0
- package/esm/agent/agent-config.type.d.mts +19 -6
- package/esm/agent/agent-config.type.d.mts.map +1 -1
- package/esm/agent/agent.d.mts.map +1 -1
- package/esm/agent/agent.mjs +17 -6
- package/esm/agent/agent.mjs.map +1 -1
- package/esm/agent/index.d.mts +2 -1
- package/esm/agent/index.mjs +1 -0
- package/esm/agent/spawn-sub-agent.d.mts +87 -0
- package/esm/agent/spawn-sub-agent.d.mts.map +1 -0
- package/esm/agent/spawn-sub-agent.mjs +68 -0
- package/esm/agent/spawn-sub-agent.mjs.map +1 -0
- package/esm/ai.d.mts +58 -3
- package/esm/ai.d.mts.map +1 -1
- package/esm/ai.mjs +58 -3
- package/esm/ai.mjs.map +1 -1
- package/esm/batch/batch.d.mts +43 -0
- package/esm/batch/batch.d.mts.map +1 -0
- package/esm/batch/batch.mjs +179 -0
- package/esm/batch/batch.mjs.map +1 -0
- package/esm/batch/batch.type.d.mts +144 -0
- package/esm/batch/batch.type.d.mts.map +1 -0
- package/esm/batch/index.mjs +3 -0
- package/esm/batch/run-batch-item.mjs +100 -0
- package/esm/batch/run-batch-item.mjs.map +1 -0
- package/esm/batch/run-with-concurrency.mjs +39 -0
- package/esm/batch/run-with-concurrency.mjs.map +1 -0
- package/esm/checkpoint/index.d.mts +3 -0
- package/esm/checkpoint/memory.d.mts +21 -0
- package/esm/checkpoint/memory.d.mts.map +1 -0
- package/esm/checkpoint/memory.mjs +0 -0
- package/esm/checkpoint/memory.mjs.map +1 -0
- package/esm/checkpoint/pg.d.mts +37 -0
- package/esm/checkpoint/pg.d.mts.map +1 -0
- package/esm/checkpoint/pg.mjs +265 -0
- package/esm/checkpoint/pg.mjs.map +1 -0
- package/esm/checkpoint/redis.d.mts +39 -0
- package/esm/checkpoint/redis.d.mts.map +1 -0
- package/esm/checkpoint/redis.mjs +200 -0
- package/esm/checkpoint/redis.mjs.map +1 -0
- package/esm/config.d.mts +61 -14
- package/esm/config.d.mts.map +1 -1
- package/esm/config.mjs +25 -6
- package/esm/config.mjs.map +1 -1
- package/esm/contracts/agent/agent.contract.d.mts +43 -0
- package/esm/contracts/agent/agent.contract.d.mts.map +1 -1
- package/esm/contracts/agent/eval.type.d.mts +143 -0
- package/esm/contracts/agent/eval.type.d.mts.map +1 -0
- package/esm/contracts/agent/index.d.mts +1 -0
- package/esm/contracts/events/supervisor-events.type.d.mts +3 -3
- package/esm/contracts/fallback-model.contract.d.mts +65 -0
- package/esm/contracts/fallback-model.contract.d.mts.map +1 -0
- package/esm/contracts/index.d.mts +32 -12
- package/esm/contracts/memory/index.d.mts +4 -0
- package/esm/contracts/memory/memory-config.type.d.mts +150 -0
- package/esm/contracts/memory/memory-config.type.d.mts.map +1 -0
- package/esm/contracts/memory/memory-item.type.d.mts +64 -0
- package/esm/contracts/memory/memory-item.type.d.mts.map +1 -0
- package/esm/contracts/memory/memory.contract.d.mts +87 -0
- package/esm/contracts/memory/memory.contract.d.mts.map +1 -0
- package/esm/contracts/memory/recall-options.type.d.mts +33 -0
- package/esm/contracts/memory/recall-options.type.d.mts.map +1 -0
- package/esm/contracts/middleware/index.d.mts +2 -2
- package/esm/contracts/middleware/middleware-context.type.d.mts +42 -2
- package/esm/contracts/middleware/middleware-context.type.d.mts.map +1 -1
- package/esm/contracts/middleware/middleware.contract.d.mts +46 -2
- package/esm/contracts/middleware/middleware.contract.d.mts.map +1 -1
- package/esm/contracts/model.contract.d.mts +63 -2
- package/esm/contracts/model.contract.d.mts.map +1 -1
- package/esm/contracts/orchestrator/checkpoint-store.contract.d.mts +91 -0
- package/esm/contracts/orchestrator/checkpoint-store.contract.d.mts.map +1 -0
- package/esm/contracts/orchestrator/index.d.mts +8 -0
- package/esm/contracts/orchestrator/orchestrator-commands.type.d.mts +43 -0
- package/esm/contracts/orchestrator/orchestrator-commands.type.d.mts.map +1 -0
- package/esm/contracts/orchestrator/orchestrator-config.type.d.mts +170 -0
- package/esm/contracts/orchestrator/orchestrator-config.type.d.mts.map +1 -0
- package/esm/contracts/orchestrator/orchestrator-event.type.d.mts +118 -0
- package/esm/contracts/orchestrator/orchestrator-event.type.d.mts.map +1 -0
- package/esm/contracts/orchestrator/orchestrator-execute-options.type.d.mts +44 -0
- package/esm/contracts/orchestrator/orchestrator-execute-options.type.d.mts.map +1 -0
- package/esm/contracts/orchestrator/orchestrator.contract.d.mts +129 -0
- package/esm/contracts/orchestrator/orchestrator.contract.d.mts.map +1 -0
- package/esm/contracts/orchestrator/session.contract.d.mts +26 -0
- package/esm/contracts/orchestrator/session.contract.d.mts.map +1 -0
- package/esm/contracts/orchestrator/snapshot-store.contract.d.mts +89 -0
- package/esm/contracts/orchestrator/snapshot-store.contract.d.mts.map +1 -0
- package/esm/contracts/planner/index.d.mts +6 -0
- package/esm/contracts/planner/planner-capability.type.d.mts +39 -0
- package/esm/contracts/planner/planner-capability.type.d.mts.map +1 -0
- package/esm/contracts/planner/planner-config.type.d.mts +78 -0
- package/esm/contracts/planner/planner-config.type.d.mts.map +1 -0
- package/esm/contracts/planner/planner-execute-options.type.d.mts +43 -0
- package/esm/contracts/planner/planner-execute-options.type.d.mts.map +1 -0
- package/esm/contracts/planner/planner-plan.type.d.mts +48 -0
- package/esm/contracts/planner/planner-plan.type.d.mts.map +1 -0
- package/esm/contracts/planner/planner-result.type.d.mts +82 -0
- package/esm/contracts/planner/planner-result.type.d.mts.map +1 -0
- package/esm/contracts/planner/planner.contract.d.mts +60 -0
- package/esm/contracts/planner/planner.contract.d.mts.map +1 -0
- package/esm/contracts/result/base-report.type.d.mts +7 -2
- package/esm/contracts/result/base-report.type.d.mts.map +1 -1
- package/esm/contracts/result/base-report.type.mjs.map +1 -1
- package/esm/contracts/result/index.d.mts +2 -1
- package/esm/contracts/result/model-pricing.type.d.mts +10 -0
- package/esm/contracts/result/model-pricing.type.d.mts.map +1 -1
- package/esm/contracts/result/orchestrator-result.type.d.mts +139 -0
- package/esm/contracts/result/orchestrator-result.type.d.mts.map +1 -0
- package/esm/contracts/result/session-send-result.type.d.mts +12 -3
- package/esm/contracts/result/session-send-result.type.d.mts.map +1 -1
- package/esm/contracts/result/supervisor-result.type.d.mts +1 -1
- package/esm/contracts/result/usage.type.d.mts +24 -0
- package/esm/contracts/result/usage.type.d.mts.map +1 -1
- package/esm/contracts/sdk-adapter.contract.d.mts +1 -1
- package/esm/contracts/supervisor/dispatch-context.type.d.mts +3 -3
- package/esm/contracts/supervisor/evaluate-context.type.d.mts +1 -1
- package/esm/contracts/supervisor/index.d.mts +5 -5
- package/esm/contracts/supervisor/route-context.type.d.mts +2 -2
- package/esm/contracts/supervisor/supervisor-config.type.d.mts +55 -13
- package/esm/contracts/supervisor/supervisor-config.type.d.mts.map +1 -1
- package/esm/contracts/supervisor/supervisor-snapshot.type.d.mts +1 -1
- package/esm/contracts/supervisor/supervisor.contract.d.mts +9 -2
- package/esm/contracts/supervisor/supervisor.contract.d.mts.map +1 -1
- package/esm/contracts/workflow/index.d.mts +2 -2
- package/esm/contracts/workflow/workflow.contract.d.mts +28 -7
- package/esm/contracts/workflow/workflow.contract.d.mts.map +1 -1
- package/esm/errors/error-code.type.d.mts +1 -1
- package/esm/errors/index.d.mts +7 -0
- package/esm/errors/index.mjs +7 -0
- package/esm/errors/orchestrator-cancelled-error.d.mts +32 -0
- package/esm/errors/orchestrator-cancelled-error.d.mts.map +1 -0
- package/esm/errors/orchestrator-cancelled-error.mjs +31 -0
- package/esm/errors/orchestrator-cancelled-error.mjs.map +1 -0
- package/esm/errors/orchestrator-config-error.d.mts +26 -0
- package/esm/errors/orchestrator-config-error.d.mts.map +1 -0
- package/esm/errors/orchestrator-config-error.mjs +30 -0
- package/esm/errors/orchestrator-config-error.mjs.map +1 -0
- package/esm/errors/orchestrator-drift-error.d.mts +38 -0
- package/esm/errors/orchestrator-drift-error.d.mts.map +1 -0
- package/esm/errors/orchestrator-drift-error.mjs +37 -0
- package/esm/errors/orchestrator-drift-error.mjs.map +1 -0
- package/esm/errors/orchestrator-failed-error.d.mts +33 -0
- package/esm/errors/orchestrator-failed-error.d.mts.map +1 -0
- package/esm/errors/orchestrator-failed-error.mjs +36 -0
- package/esm/errors/orchestrator-failed-error.mjs.map +1 -0
- package/esm/errors/planner-cancelled-error.d.mts +33 -0
- package/esm/errors/planner-cancelled-error.d.mts.map +1 -0
- package/esm/errors/planner-cancelled-error.mjs +29 -0
- package/esm/errors/planner-cancelled-error.mjs.map +1 -0
- package/esm/errors/planner-failed-error.d.mts +40 -0
- package/esm/errors/planner-failed-error.d.mts.map +1 -0
- package/esm/errors/planner-failed-error.mjs +37 -0
- package/esm/errors/planner-failed-error.mjs.map +1 -0
- package/esm/errors/planner-plan-invalid-error.d.mts +21 -0
- package/esm/errors/planner-plan-invalid-error.d.mts.map +1 -0
- package/esm/errors/planner-plan-invalid-error.mjs +25 -0
- package/esm/errors/planner-plan-invalid-error.mjs.map +1 -0
- package/esm/eval/eval-runner.d.mts +17 -0
- package/esm/eval/eval-runner.d.mts.map +1 -0
- package/esm/eval/eval-runner.mjs +121 -0
- package/esm/eval/eval-runner.mjs.map +1 -0
- package/esm/eval/index.d.mts +29 -0
- package/esm/eval/index.d.mts.map +1 -0
- package/esm/eval/index.mjs +30 -0
- package/esm/eval/index.mjs.map +1 -0
- package/esm/eval/judge-scorer.d.mts +21 -0
- package/esm/eval/judge-scorer.d.mts.map +1 -0
- package/esm/eval/judge-scorer.mjs +87 -0
- package/esm/eval/judge-scorer.mjs.map +1 -0
- package/esm/eval/scorers.d.mts +50 -0
- package/esm/eval/scorers.d.mts.map +1 -0
- package/esm/eval/scorers.mjs +101 -0
- package/esm/eval/scorers.mjs.map +1 -0
- package/esm/index.d.mts +95 -30
- package/esm/index.mjs +66 -22
- package/esm/memory/derive-id.mjs +24 -0
- package/esm/memory/derive-id.mjs.map +1 -0
- package/esm/memory/episodic-memory.mjs +106 -0
- package/esm/memory/episodic-memory.mjs.map +1 -0
- package/esm/memory/index.d.mts +5 -0
- package/esm/memory/memory.d.mts +42 -0
- package/esm/memory/memory.d.mts.map +1 -0
- package/esm/memory/memory.mjs +166 -0
- package/esm/memory/memory.mjs.map +1 -0
- package/esm/memory/procedural-memory.mjs +103 -0
- package/esm/memory/procedural-memory.mjs.map +1 -0
- package/esm/memory/semantic-memory.mjs +80 -0
- package/esm/memory/semantic-memory.mjs.map +1 -0
- package/esm/memory/working-memory.mjs +62 -0
- package/esm/memory/working-memory.mjs.map +1 -0
- package/esm/middleware/builtins/budget-contract.type.d.mts +126 -0
- package/esm/middleware/builtins/budget-contract.type.d.mts.map +1 -0
- package/esm/middleware/builtins/budget.d.mts +71 -1
- package/esm/middleware/builtins/budget.d.mts.map +1 -1
- package/esm/middleware/builtins/budget.mjs +119 -4
- package/esm/middleware/builtins/budget.mjs.map +1 -1
- package/esm/middleware/builtins/semantic-cache.d.mts +1 -1
- package/esm/middleware/index.d.mts +2 -1
- package/esm/middleware/index.mjs +1 -1
- package/esm/middleware/pipeline.d.mts +9 -6
- package/esm/middleware/pipeline.d.mts.map +1 -1
- package/esm/middleware/pipeline.mjs.map +1 -1
- package/esm/mock/index.d.mts +1 -0
- package/esm/mock/index.mjs +1 -0
- package/esm/mock/mock-router.d.mts +63 -0
- package/esm/mock/mock-router.d.mts.map +1 -0
- package/esm/mock/mock-router.mjs +58 -0
- package/esm/mock/mock-router.mjs.map +1 -0
- package/esm/model/fallback-model.d.mts +45 -0
- package/esm/model/fallback-model.d.mts.map +1 -0
- package/esm/model/fallback-model.mjs +218 -0
- package/esm/model/fallback-model.mjs.map +1 -0
- package/esm/model/index.d.mts +2 -0
- package/esm/model/index.mjs +3 -0
- package/esm/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs +78 -0
- package/esm/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs.map +1 -0
- package/esm/node_modules/@vitest/expect/dist/index.mjs +1473 -0
- package/esm/node_modules/@vitest/expect/dist/index.mjs.map +1 -0
- package/esm/node_modules/@vitest/pretty-format/dist/index.mjs +888 -0
- package/esm/node_modules/@vitest/pretty-format/dist/index.mjs.map +1 -0
- package/esm/node_modules/@vitest/runner/dist/chunk-artifact.mjs +1533 -0
- package/esm/node_modules/@vitest/runner/dist/chunk-artifact.mjs.map +1 -0
- package/esm/node_modules/@vitest/runner/dist/index.mjs +3 -0
- package/esm/node_modules/@vitest/runner/dist/utils.mjs +3 -0
- package/esm/node_modules/@vitest/snapshot/dist/index.mjs +922 -0
- package/esm/node_modules/@vitest/snapshot/dist/index.mjs.map +1 -0
- package/esm/node_modules/@vitest/spy/dist/index.mjs +386 -0
- package/esm/node_modules/@vitest/spy/dist/index.mjs.map +1 -0
- package/esm/node_modules/@vitest/utils/dist/chunk-pathe.M-eThtNZ.mjs +82 -0
- package/esm/node_modules/@vitest/utils/dist/chunk-pathe.M-eThtNZ.mjs.map +1 -0
- package/esm/node_modules/@vitest/utils/dist/diff.mjs +1357 -0
- package/esm/node_modules/@vitest/utils/dist/diff.mjs.map +1 -0
- package/esm/node_modules/@vitest/utils/dist/display.mjs +559 -0
- package/esm/node_modules/@vitest/utils/dist/display.mjs.map +1 -0
- package/esm/node_modules/@vitest/utils/dist/error.mjs +38 -0
- package/esm/node_modules/@vitest/utils/dist/error.mjs.map +1 -0
- package/esm/node_modules/@vitest/utils/dist/helpers.mjs +181 -0
- package/esm/node_modules/@vitest/utils/dist/helpers.mjs.map +1 -0
- package/esm/node_modules/@vitest/utils/dist/offset.mjs +27 -0
- package/esm/node_modules/@vitest/utils/dist/offset.mjs.map +1 -0
- package/esm/node_modules/@vitest/utils/dist/serialize.mjs +77 -0
- package/esm/node_modules/@vitest/utils/dist/serialize.mjs.map +1 -0
- package/esm/node_modules/@vitest/utils/dist/source-map.mjs +374 -0
- package/esm/node_modules/@vitest/utils/dist/source-map.mjs.map +1 -0
- package/esm/node_modules/@vitest/utils/dist/timers.mjs +37 -0
- package/esm/node_modules/@vitest/utils/dist/timers.mjs.map +1 -0
- package/esm/node_modules/chai/index.mjs +2973 -0
- package/esm/node_modules/chai/index.mjs.map +1 -0
- package/esm/node_modules/magic-string/dist/magic-string.es.mjs +940 -0
- package/esm/node_modules/magic-string/dist/magic-string.es.mjs.map +1 -0
- package/esm/node_modules/tinyrainbow/dist/index.mjs +87 -0
- package/esm/node_modules/tinyrainbow/dist/index.mjs.map +1 -0
- package/esm/node_modules/vitest/dist/chunks/_commonjsHelpers.D26ty3Ew.mjs +6 -0
- package/esm/node_modules/vitest/dist/chunks/_commonjsHelpers.D26ty3Ew.mjs.map +1 -0
- package/esm/node_modules/vitest/dist/chunks/rpc.MzXet3jl.mjs +52 -0
- package/esm/node_modules/vitest/dist/chunks/rpc.MzXet3jl.mjs.map +1 -0
- package/esm/node_modules/vitest/dist/chunks/test.DNmyFkvJ.mjs +2697 -0
- package/esm/node_modules/vitest/dist/chunks/test.DNmyFkvJ.mjs.map +1 -0
- package/esm/node_modules/vitest/dist/chunks/utils.BX5Fg8C4.mjs +45 -0
- package/esm/node_modules/vitest/dist/chunks/utils.BX5Fg8C4.mjs.map +1 -0
- package/esm/orchestrator/as-tool.d.mts +42 -0
- package/esm/orchestrator/as-tool.d.mts.map +1 -0
- package/esm/orchestrator/as-tool.mjs +98 -0
- package/esm/orchestrator/as-tool.mjs.map +1 -0
- package/esm/orchestrator/checkpoint.mjs +75 -0
- package/esm/orchestrator/checkpoint.mjs.map +1 -0
- package/esm/orchestrator/commands.d.mts +38 -0
- package/esm/orchestrator/commands.d.mts.map +1 -0
- package/esm/orchestrator/commands.mjs +34 -0
- package/esm/orchestrator/commands.mjs.map +1 -0
- package/esm/orchestrator/compaction.mjs +206 -0
- package/esm/orchestrator/compaction.mjs.map +1 -0
- package/esm/orchestrator/dispatch.mjs +171 -0
- package/esm/orchestrator/dispatch.mjs.map +1 -0
- package/esm/orchestrator/emitter-port.type.d.mts +31 -0
- package/esm/orchestrator/emitter-port.type.d.mts.map +1 -0
- package/esm/orchestrator/emitter.d.mts +56 -0
- package/esm/orchestrator/emitter.d.mts.map +1 -0
- package/esm/orchestrator/emitter.mjs +85 -0
- package/esm/orchestrator/emitter.mjs.map +1 -0
- package/esm/orchestrator/engine-context.type.d.mts +56 -0
- package/esm/orchestrator/engine-context.type.d.mts.map +1 -0
- package/esm/orchestrator/execution.d.mts +116 -0
- package/esm/orchestrator/execution.d.mts.map +1 -0
- package/esm/orchestrator/execution.mjs +406 -0
- package/esm/orchestrator/execution.mjs.map +1 -0
- package/esm/orchestrator/index.d.mts +8 -0
- package/esm/orchestrator/index.mjs +10 -0
- package/esm/orchestrator/load.mjs +49 -0
- package/esm/orchestrator/load.mjs.map +1 -0
- package/esm/orchestrator/lock.mjs +75 -0
- package/esm/orchestrator/lock.mjs.map +1 -0
- package/esm/orchestrator/memory.d.mts +84 -0
- package/esm/orchestrator/memory.d.mts.map +1 -0
- package/esm/orchestrator/memory.mjs +141 -0
- package/esm/orchestrator/memory.mjs.map +1 -0
- package/esm/orchestrator/orchestrator-stream.d.mts +42 -0
- package/esm/orchestrator/orchestrator-stream.d.mts.map +1 -0
- package/esm/orchestrator/orchestrator-stream.mjs +98 -0
- package/esm/orchestrator/orchestrator-stream.mjs.map +1 -0
- package/esm/orchestrator/orchestrator.d.mts +38 -0
- package/esm/orchestrator/orchestrator.d.mts.map +1 -0
- package/esm/orchestrator/orchestrator.mjs +173 -0
- package/esm/orchestrator/orchestrator.mjs.map +1 -0
- package/esm/orchestrator/resume.mjs +74 -0
- package/esm/orchestrator/resume.mjs.map +1 -0
- package/esm/orchestrator/signature.d.mts +40 -0
- package/esm/orchestrator/signature.d.mts.map +1 -0
- package/esm/orchestrator/signature.mjs +120 -0
- package/esm/orchestrator/signature.mjs.map +1 -0
- package/esm/orchestrator/window.mjs +56 -0
- package/esm/orchestrator/window.mjs.map +1 -0
- package/esm/planner/index.d.mts +5 -0
- package/esm/planner/index.mjs +6 -0
- package/esm/planner/plan-prompt.d.mts +17 -0
- package/esm/planner/plan-prompt.d.mts.map +1 -0
- package/esm/planner/plan-prompt.mjs +30 -0
- package/esm/planner/plan-prompt.mjs.map +1 -0
- package/esm/planner/plan-schema.d.mts +27 -0
- package/esm/planner/plan-schema.d.mts.map +1 -0
- package/esm/planner/plan-schema.mjs +117 -0
- package/esm/planner/plan-schema.mjs.map +1 -0
- package/esm/planner/planner-run.d.mts +23 -0
- package/esm/planner/planner-run.d.mts.map +1 -0
- package/esm/planner/planner-run.mjs +344 -0
- package/esm/planner/planner-run.mjs.map +1 -0
- package/esm/planner/planner.d.mts +37 -0
- package/esm/planner/planner.d.mts.map +1 -0
- package/esm/planner/planner.mjs +120 -0
- package/esm/planner/planner.mjs.map +1 -0
- package/esm/planner/signature.d.mts +18 -0
- package/esm/planner/signature.d.mts.map +1 -0
- package/esm/planner/signature.mjs +27 -0
- package/esm/planner/signature.mjs.map +1 -0
- package/esm/snapshot/index.d.mts +3 -0
- package/esm/snapshot/memory.d.mts +26 -0
- package/esm/snapshot/memory.d.mts.map +1 -0
- package/esm/snapshot/memory.mjs +81 -0
- package/esm/snapshot/memory.mjs.map +1 -0
- package/esm/snapshot/pg.d.mts +41 -0
- package/esm/snapshot/pg.d.mts.map +1 -0
- package/esm/snapshot/pg.mjs +146 -0
- package/esm/snapshot/pg.mjs.map +1 -0
- package/esm/snapshot/redis.d.mts +42 -0
- package/esm/snapshot/redis.d.mts.map +1 -0
- package/esm/snapshot/redis.mjs +101 -0
- package/esm/snapshot/redis.mjs.map +1 -0
- package/esm/supervisor/as-tool.d.mts +0 -6
- package/esm/supervisor/as-tool.d.mts.map +1 -1
- package/esm/supervisor/as-tool.mjs +0 -6
- package/esm/supervisor/as-tool.mjs.map +1 -1
- package/esm/supervisor/execution.d.mts +43 -8
- package/esm/supervisor/execution.d.mts.map +1 -1
- package/esm/supervisor/execution.mjs +66 -16
- package/esm/supervisor/execution.mjs.map +1 -1
- package/esm/supervisor/fan-out.d.mts +65 -0
- package/esm/supervisor/fan-out.d.mts.map +1 -0
- package/esm/supervisor/fan-out.mjs +65 -0
- package/esm/supervisor/fan-out.mjs.map +1 -0
- package/esm/supervisor/index.d.mts +5 -3
- package/esm/supervisor/index.mjs +3 -1
- package/esm/supervisor/router-factory.d.mts +110 -0
- package/esm/supervisor/router-factory.d.mts.map +1 -0
- package/esm/supervisor/router-factory.mjs +141 -0
- package/esm/supervisor/router-factory.mjs.map +1 -0
- package/esm/supervisor/router-prompt.d.mts +1 -1
- package/esm/supervisor/snapshot.d.mts +4 -10
- package/esm/supervisor/snapshot.d.mts.map +1 -1
- package/esm/supervisor/snapshot.mjs +8 -16
- package/esm/supervisor/snapshot.mjs.map +1 -1
- package/esm/supervisor/supervisor.mjs +1 -0
- package/esm/supervisor/supervisor.mjs.map +1 -1
- package/esm/system-prompt/index.mjs +6 -0
- package/esm/system-prompt/system-prompt.d.mts +51 -3
- package/esm/system-prompt/system-prompt.d.mts.map +1 -1
- package/esm/system-prompt/system-prompt.mjs +52 -6
- package/esm/system-prompt/system-prompt.mjs.map +1 -1
- package/esm/testing/matcher-logic.d.mts +76 -0
- package/esm/testing/matcher-logic.d.mts.map +1 -0
- package/esm/testing/matcher-logic.mjs +144 -0
- package/esm/testing/matcher-logic.mjs.map +1 -0
- package/esm/testing/matchers.d.mts +48 -0
- package/esm/testing/matchers.d.mts.map +1 -0
- package/esm/testing/matchers.mjs +37 -0
- package/esm/testing/matchers.mjs.map +1 -0
- package/esm/testing/register-lazy.d.mts +20 -0
- package/esm/testing/register-lazy.d.mts.map +1 -0
- package/esm/testing/register-lazy.mjs +24 -0
- package/esm/testing/register-lazy.mjs.map +1 -0
- package/esm/tool/executable-as-tool.d.mts +87 -0
- package/esm/tool/executable-as-tool.d.mts.map +1 -0
- package/esm/tool/executable-as-tool.mjs +81 -0
- package/esm/tool/executable-as-tool.mjs.map +1 -0
- package/esm/tool/index.d.mts +2 -1
- package/esm/tool/index.mjs +1 -0
- package/esm/workflow/as-tool.mjs +0 -6
- package/esm/workflow/as-tool.mjs.map +1 -1
- package/esm/workflow/engine.mjs +2 -2
- package/esm/workflow/snapshot.mjs +13 -7
- package/esm/workflow/snapshot.mjs.map +1 -1
- package/esm/workflow/step-runner.mjs +1 -1
- package/esm/workflow/workflow.mjs +1 -0
- package/esm/workflow/workflow.mjs.map +1 -1
- package/llms-full.txt +947 -42
- package/llms.txt +13 -8
- package/package.json +3 -3
- package/skills/README.md +25 -5
- package/skills/ai-basics/SKILL.md +18 -7
- package/skills/ai-dx-helpers/SKILL.md +180 -0
- package/skills/attach-ai-middleware/SKILL.md +32 -3
- package/skills/handle-ai-errors/SKILL.md +20 -6
- package/skills/manage-ai-stores/SKILL.md +127 -0
- package/skills/persist-ai-data/SKILL.md +21 -10
- package/skills/pick-ai-provider/SKILL.md +46 -12
- package/skills/run-ai-agent/SKILL.md +51 -2
- package/skills/run-orchestrator/SKILL.md +198 -0
- package/skills/run-planner/SKILL.md +68 -0
- package/skills/run-supervisor/SKILL.md +47 -2
- package/skills/use-ai-memory/SKILL.md +124 -0
- package/skills/write-system-prompt/SKILL.md +14 -1
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { isAbortError, resolveBackoff, resolveRetryConfig } from "../workflow/retry.mjs";
|
|
2
|
+
import { toAIError } from "../workflow/step-runner.mjs";
|
|
3
|
+
|
|
4
|
+
//#region ../@warlock.js/ai/src/batch/run-batch-item.ts
|
|
5
|
+
/**
|
|
6
|
+
* Sleep for `ms`, settling early (without throwing) if `signal`
|
|
7
|
+
* aborts during the wait. The caller re-checks `signal.aborted` after
|
|
8
|
+
* this resolves, so a silent early return is enough — we never want a
|
|
9
|
+
* pending timer to keep the batch alive past cancellation.
|
|
10
|
+
*/
|
|
11
|
+
function sleep(ms, signal) {
|
|
12
|
+
return new Promise((resolve) => {
|
|
13
|
+
const timer = setTimeout(() => {
|
|
14
|
+
signal?.removeEventListener("abort", onAbort);
|
|
15
|
+
resolve();
|
|
16
|
+
}, ms);
|
|
17
|
+
const onAbort = () => {
|
|
18
|
+
clearTimeout(timer);
|
|
19
|
+
resolve();
|
|
20
|
+
};
|
|
21
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Execute one item with per-item retry, isolated so a failure can
|
|
26
|
+
* neither throw nor disturb sibling items running in the same pool.
|
|
27
|
+
*
|
|
28
|
+
* Reuses the workflow retry vocabulary verbatim
|
|
29
|
+
* ({@link resolveRetryConfig} / {@link resolveBackoff}) so batch and
|
|
30
|
+
* workflow steps retry identically. An item is `"completed"` when the
|
|
31
|
+
* primitive's own result carries no `error`; a primitive that returns
|
|
32
|
+
* `result.error` (rather than throwing) is treated as a failed attempt
|
|
33
|
+
* and re-run under the same policy.
|
|
34
|
+
*
|
|
35
|
+
* Cancellation short-circuits: if the signal is already aborted on
|
|
36
|
+
* entry the item is reported `"cancelled"` without executing; an abort
|
|
37
|
+
* observed mid-flight surfaces as `"cancelled"` too.
|
|
38
|
+
*/
|
|
39
|
+
async function runBatchItem(params) {
|
|
40
|
+
const { index, input, executable, signal } = params;
|
|
41
|
+
if (signal?.aborted) return {
|
|
42
|
+
index,
|
|
43
|
+
status: "cancelled",
|
|
44
|
+
attempts: 0
|
|
45
|
+
};
|
|
46
|
+
const retryConfig = resolveRetryConfig({ retry: params.retry }, void 0);
|
|
47
|
+
const totalAttempts = Math.max(1, retryConfig.attempts ?? 1);
|
|
48
|
+
let lastResult;
|
|
49
|
+
let lastError;
|
|
50
|
+
let attemptsMade = 0;
|
|
51
|
+
for (let attempt = 1; attempt <= totalAttempts; attempt++) {
|
|
52
|
+
if (signal?.aborted) return {
|
|
53
|
+
index,
|
|
54
|
+
status: "cancelled",
|
|
55
|
+
result: lastResult,
|
|
56
|
+
attempts: attemptsMade
|
|
57
|
+
};
|
|
58
|
+
attemptsMade = attempt;
|
|
59
|
+
try {
|
|
60
|
+
const result = await executable.execute(input, { signal });
|
|
61
|
+
lastResult = result;
|
|
62
|
+
if (!result.error) return {
|
|
63
|
+
index,
|
|
64
|
+
status: "completed",
|
|
65
|
+
result,
|
|
66
|
+
attempts: attempt
|
|
67
|
+
};
|
|
68
|
+
lastError = result.error;
|
|
69
|
+
} catch (error) {
|
|
70
|
+
if (isAbortError(error)) return {
|
|
71
|
+
index,
|
|
72
|
+
status: "cancelled",
|
|
73
|
+
result: lastResult,
|
|
74
|
+
attempts: attempt
|
|
75
|
+
};
|
|
76
|
+
lastError = error;
|
|
77
|
+
}
|
|
78
|
+
if (!(attempt < totalAttempts && (retryConfig.retryOn ? retryConfig.retryOn(lastError, attempt) !== false : true))) break;
|
|
79
|
+
retryConfig.onRetry?.(attempt + 1, lastError);
|
|
80
|
+
const delay = resolveBackoff(attempt, retryConfig.backoff);
|
|
81
|
+
if (delay > 0) await sleep(delay, signal);
|
|
82
|
+
}
|
|
83
|
+
if (signal?.aborted) return {
|
|
84
|
+
index,
|
|
85
|
+
status: "cancelled",
|
|
86
|
+
result: lastResult,
|
|
87
|
+
attempts: attemptsMade
|
|
88
|
+
};
|
|
89
|
+
return {
|
|
90
|
+
index,
|
|
91
|
+
status: "failed",
|
|
92
|
+
result: lastResult,
|
|
93
|
+
error: toAIError(lastError),
|
|
94
|
+
attempts: attemptsMade
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
//#endregion
|
|
99
|
+
export { runBatchItem };
|
|
100
|
+
//# sourceMappingURL=run-batch-item.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-batch-item.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/batch/run-batch-item.ts"],"sourcesContent":["import type { BaseResult } from \"../contracts/result/base-result.type\";\nimport type { ExecutableContract } from \"../contracts/executable.contract\";\nimport type { RetryConfig } from \"../contracts/workflow/retry-config.type\";\nimport { isAbortError, resolveBackoff, resolveRetryConfig } from \"../workflow/retry\";\nimport { toAIError } from \"../workflow/step-runner\";\nimport type { BatchItemResult } from \"./batch.type\";\n\n/**\n * Parameters for {@link runBatchItem}. Kept as a plain bag so the\n * concurrency pool can build it once per index without a long\n * positional argument list.\n */\nexport type RunBatchItemParams<TInput, TOptions, TResult extends BaseResult> = {\n index: number;\n input: TInput;\n executable: ExecutableContract<TInput, TOptions, TResult>;\n retry: RetryConfig | undefined;\n signal: AbortSignal | undefined;\n};\n\n/**\n * Sleep for `ms`, settling early (without throwing) if `signal`\n * aborts during the wait. The caller re-checks `signal.aborted` after\n * this resolves, so a silent early return is enough — we never want a\n * pending timer to keep the batch alive past cancellation.\n */\nfunction sleep(ms: number, signal: AbortSignal | undefined): Promise<void> {\n return new Promise((resolve) => {\n const timer = setTimeout(() => {\n signal?.removeEventListener(\"abort\", onAbort);\n resolve();\n }, ms);\n\n const onAbort = (): void => {\n clearTimeout(timer);\n resolve();\n };\n\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n });\n}\n\n/**\n * Execute one item with per-item retry, isolated so a failure can\n * neither throw nor disturb sibling items running in the same pool.\n *\n * Reuses the workflow retry vocabulary verbatim\n * ({@link resolveRetryConfig} / {@link resolveBackoff}) so batch and\n * workflow steps retry identically. An item is `\"completed\"` when the\n * primitive's own result carries no `error`; a primitive that returns\n * `result.error` (rather than throwing) is treated as a failed attempt\n * and re-run under the same policy.\n *\n * Cancellation short-circuits: if the signal is already aborted on\n * entry the item is reported `\"cancelled\"` without executing; an abort\n * observed mid-flight surfaces as `\"cancelled\"` too.\n */\nexport async function runBatchItem<TInput, TOptions, TResult extends BaseResult>(\n params: RunBatchItemParams<TInput, TOptions, TResult>,\n): Promise<BatchItemResult<TResult>> {\n const { index, input, executable, signal } = params;\n\n if (signal?.aborted) {\n return { index, status: \"cancelled\", attempts: 0 };\n }\n\n const retryConfig = resolveRetryConfig({ retry: params.retry }, undefined);\n const totalAttempts = Math.max(1, retryConfig.attempts ?? 1);\n\n let lastResult: TResult | undefined;\n let lastError: unknown;\n let attemptsMade = 0;\n\n for (let attempt = 1; attempt <= totalAttempts; attempt++) {\n if (signal?.aborted) {\n return { index, status: \"cancelled\", result: lastResult, attempts: attemptsMade };\n }\n\n attemptsMade = attempt;\n\n try {\n const result = await executable.execute(input, { signal } as TOptions);\n lastResult = result;\n\n if (!result.error) {\n return { index, status: \"completed\", result, attempts: attempt };\n }\n\n lastError = result.error;\n } catch (error) {\n if (isAbortError(error)) {\n return { index, status: \"cancelled\", result: lastResult, attempts: attempt };\n }\n\n lastError = error;\n }\n\n const canRetry =\n attempt < totalAttempts &&\n (retryConfig.retryOn ? retryConfig.retryOn(lastError, attempt) !== false : true);\n\n if (!canRetry) {\n break;\n }\n\n retryConfig.onRetry?.(attempt + 1, lastError);\n\n const delay = resolveBackoff(attempt, retryConfig.backoff);\n if (delay > 0) {\n await sleep(delay, signal);\n }\n }\n\n if (signal?.aborted) {\n return { index, status: \"cancelled\", result: lastResult, attempts: attemptsMade };\n }\n\n return {\n index,\n status: \"failed\",\n result: lastResult,\n error: toAIError(lastError),\n attempts: attemptsMade,\n };\n}\n"],"mappings":";;;;;;;;;;AA0BA,SAAS,MAAM,IAAY,QAAgD;CACzE,OAAO,IAAI,SAAS,YAAY;EAC9B,MAAM,QAAQ,iBAAiB;GAC7B,QAAQ,oBAAoB,SAAS,OAAO;GAC5C,QAAQ;EACV,GAAG,EAAE;EAEL,MAAM,gBAAsB;GAC1B,aAAa,KAAK;GAClB,QAAQ;EACV;EAEA,QAAQ,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;CAC3D,CAAC;AACH;;;;;;;;;;;;;;;;AAiBA,eAAsB,aACpB,QACmC;CACnC,MAAM,EAAE,OAAO,OAAO,YAAY,WAAW;CAE7C,IAAI,QAAQ,SACV,OAAO;EAAE;EAAO,QAAQ;EAAa,UAAU;CAAE;CAGnD,MAAM,cAAc,mBAAmB,EAAE,OAAO,OAAO,MAAM,GAAG,MAAS;CACzE,MAAM,gBAAgB,KAAK,IAAI,GAAG,YAAY,YAAY,CAAC;CAE3D,IAAI;CACJ,IAAI;CACJ,IAAI,eAAe;CAEnB,KAAK,IAAI,UAAU,GAAG,WAAW,eAAe,WAAW;EACzD,IAAI,QAAQ,SACV,OAAO;GAAE;GAAO,QAAQ;GAAa,QAAQ;GAAY,UAAU;EAAa;EAGlF,eAAe;EAEf,IAAI;GACF,MAAM,SAAS,MAAM,WAAW,QAAQ,OAAO,EAAE,OAAO,CAAa;GACrE,aAAa;GAEb,IAAI,CAAC,OAAO,OACV,OAAO;IAAE;IAAO,QAAQ;IAAa;IAAQ,UAAU;GAAQ;GAGjE,YAAY,OAAO;EACrB,SAAS,OAAO;GACd,IAAI,aAAa,KAAK,GACpB,OAAO;IAAE;IAAO,QAAQ;IAAa,QAAQ;IAAY,UAAU;GAAQ;GAG7E,YAAY;EACd;EAMA,IAAI,EAHF,UAAU,kBACT,YAAY,UAAU,YAAY,QAAQ,WAAW,OAAO,MAAM,QAAQ,QAG3E;EAGF,YAAY,UAAU,UAAU,GAAG,SAAS;EAE5C,MAAM,QAAQ,eAAe,SAAS,YAAY,OAAO;EACzD,IAAI,QAAQ,GACV,MAAM,MAAM,OAAO,MAAM;CAE7B;CAEA,IAAI,QAAQ,SACV,OAAO;EAAE;EAAO,QAAQ;EAAa,QAAQ;EAAY,UAAU;CAAa;CAGlF,OAAO;EACL;EACA,QAAQ;EACR,QAAQ;EACR,OAAO,UAAU,SAAS;EAC1B,UAAU;CACZ;AACF"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
//#region ../@warlock.js/ai/src/batch/run-with-concurrency.ts
|
|
2
|
+
/**
|
|
3
|
+
* Run an async `worker` over every index `0..total-1` with at most
|
|
4
|
+
* `limit` workers in flight at any moment, preserving nothing about
|
|
5
|
+
* completion order (the worker is responsible for recording results
|
|
6
|
+
* positionally). Resolves once every index has settled.
|
|
7
|
+
*
|
|
8
|
+
* A fixed pool of `limit` runners each pull the next unclaimed index
|
|
9
|
+
* from a shared cursor — this keeps exactly `limit` items in flight
|
|
10
|
+
* even when item durations vary wildly, unlike fixed-size chunking
|
|
11
|
+
* which stalls a chunk on its slowest member.
|
|
12
|
+
*
|
|
13
|
+
* `limit` is clamped to `[1, total]`: a non-positive limit runs fully
|
|
14
|
+
* serially, a limit larger than `total` simply starts every item.
|
|
15
|
+
* `total === 0` resolves immediately.
|
|
16
|
+
*
|
|
17
|
+
* The worker must never reject — it owns its own try/catch and records
|
|
18
|
+
* outcomes. A rejection here would abort sibling runners, which is not
|
|
19
|
+
* the batch contract (one item's failure never cancels another's).
|
|
20
|
+
*/
|
|
21
|
+
async function runWithConcurrency(total, limit, worker) {
|
|
22
|
+
if (total <= 0) return;
|
|
23
|
+
const poolSize = Math.max(1, Math.min(limit, total));
|
|
24
|
+
let cursor = 0;
|
|
25
|
+
const runner = async () => {
|
|
26
|
+
while (cursor < total) {
|
|
27
|
+
const index = cursor;
|
|
28
|
+
cursor += 1;
|
|
29
|
+
await worker(index);
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
const pool = [];
|
|
33
|
+
for (let slot = 0; slot < poolSize; slot++) pool.push(runner());
|
|
34
|
+
await Promise.all(pool);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
//#endregion
|
|
38
|
+
export { runWithConcurrency };
|
|
39
|
+
//# sourceMappingURL=run-with-concurrency.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-with-concurrency.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/batch/run-with-concurrency.ts"],"sourcesContent":["/**\n * Run an async `worker` over every index `0..total-1` with at most\n * `limit` workers in flight at any moment, preserving nothing about\n * completion order (the worker is responsible for recording results\n * positionally). Resolves once every index has settled.\n *\n * A fixed pool of `limit` runners each pull the next unclaimed index\n * from a shared cursor — this keeps exactly `limit` items in flight\n * even when item durations vary wildly, unlike fixed-size chunking\n * which stalls a chunk on its slowest member.\n *\n * `limit` is clamped to `[1, total]`: a non-positive limit runs fully\n * serially, a limit larger than `total` simply starts every item.\n * `total === 0` resolves immediately.\n *\n * The worker must never reject — it owns its own try/catch and records\n * outcomes. A rejection here would abort sibling runners, which is not\n * the batch contract (one item's failure never cancels another's).\n */\nexport async function runWithConcurrency(\n total: number,\n limit: number,\n worker: (index: number) => Promise<void>,\n): Promise<void> {\n if (total <= 0) {\n return;\n }\n\n const poolSize = Math.max(1, Math.min(limit, total));\n let cursor = 0;\n\n const runner = async (): Promise<void> => {\n while (cursor < total) {\n const index = cursor;\n cursor += 1;\n await worker(index);\n }\n };\n\n const pool: Promise<void>[] = [];\n for (let slot = 0; slot < poolSize; slot++) {\n pool.push(runner());\n }\n\n await Promise.all(pool);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAmBA,eAAsB,mBACpB,OACA,OACA,QACe;CACf,IAAI,SAAS,GACX;CAGF,MAAM,WAAW,KAAK,IAAI,GAAG,KAAK,IAAI,OAAO,KAAK,CAAC;CACnD,IAAI,SAAS;CAEb,MAAM,SAAS,YAA2B;EACxC,OAAO,SAAS,OAAO;GACrB,MAAM,QAAQ;GACd,UAAU;GACV,MAAM,OAAO,KAAK;EACpB;CACF;CAEA,MAAM,OAAwB,CAAC;CAC/B,KAAK,IAAI,OAAO,GAAG,OAAO,UAAU,QAClC,KAAK,KAAK,OAAO,CAAC;CAGpB,MAAM,QAAQ,IAAI,IAAI;AACxB"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { CheckpointStore } from "../contracts/orchestrator/checkpoint-store.contract.mjs";
|
|
2
|
+
|
|
3
|
+
//#region ../@warlock.js/ai/src/checkpoint/memory.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Create an in-memory {@link CheckpointStore}. Zero-config — no client,
|
|
6
|
+
* no connection. Suitable for dev, tests, and single-process apps that
|
|
7
|
+
* don't need resume across restarts.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* import { ai } from "@warlock.js/ai";
|
|
11
|
+
*
|
|
12
|
+
* const orchestrator = ai.orchestrator({
|
|
13
|
+
* name: "support",
|
|
14
|
+
* intents: { ... },
|
|
15
|
+
* checkpointStore: ai.checkpoint.memory(),
|
|
16
|
+
* });
|
|
17
|
+
*/
|
|
18
|
+
declare function memory(): CheckpointStore;
|
|
19
|
+
//#endregion
|
|
20
|
+
export { memory };
|
|
21
|
+
//# sourceMappingURL=memory.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai/src/checkpoint/memory.ts"],"mappings":";;;;;AAmKA;;;;AAAyC;;;;;;;;iBAAzB,MAAA,IAAU,eAAe"}
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/checkpoint/memory.ts"],"sourcesContent":["import type {\n CheckpointRecord,\n CheckpointStore,\n} from \"../contracts/orchestrator/checkpoint-store.contract\";\n\n/**\n * Composite key for the in-memory session index — one bucket per\n * `(orchestratorName, sessionId)` pair. The separator can't appear in\n * the segments in practice (names are identifiers, sessionIds are\n * dev-owned opaque strings), so a simple join is collision-safe enough\n * for an in-process store.\n */\nfunction bucketKey(orchestratorName: string, sessionId: string): string {\n return `${orchestratorName}\u0000${sessionId}`;\n}\n\n/**\n * In-memory {@link CheckpointStore} — append-only session checkpoints\n * held in a process-local `Map`, never persisted to disk.\n *\n * Owns: the per-session bucket of {@link CheckpointRecord} rows and the\n * \"latest turn wins\" load semantics. Does NOT own: durability,\n * cross-process sharing, or TTL eviction — it is the zero-config\n * default for dev, tests, and single-process apps that don't need\n * resume across restarts. Reach for `ai.checkpoint.pg()` /\n * `ai.checkpoint.redis()` (Phase 2) when durability matters.\n *\n * Front it with the {@link memory} factory — callers never `new` it.\n */\nclass MemoryCheckpointStore implements CheckpointStore {\n /** Per-session append-only row buckets, keyed by `(orchestratorName, sessionId)`. */\n private readonly sessions = new Map<string, CheckpointRecord[]>();\n\n /**\n * Return the latest checkpoint (highest `turn_index`) for a session,\n * or `undefined` when the session has no rows. Rows are appended in\n * turn order, so the last element is the latest — no scan needed.\n */\n public async load(\n orchestratorName: string,\n sessionId: string,\n ): Promise<CheckpointRecord | undefined> {\n const rows = this.sessions.get(bucketKey(orchestratorName, sessionId));\n\n if (!rows || rows.length === 0) {\n return undefined;\n }\n\n return rows[rows.length - 1];\n }\n\n /**\n * Append a checkpoint row to its session bucket. Append-only — an\n * existing `turn_index` is never overwritten; a fresh row is pushed.\n */\n public async save(record: CheckpointRecord): Promise<void> {\n const key = bucketKey(record.orchestrator_name, record.session_id);\n const rows = this.sessions.get(key);\n\n if (rows) {\n rows.push(record);\n\n return;\n }\n\n this.sessions.set(key, [record]);\n }\n\n /**\n * Drop every row for a session, ending it.\n */\n public async delete(\n orchestratorName: string,\n sessionId: string,\n ): Promise<void> {\n this.sessions.delete(bucketKey(orchestratorName, sessionId));\n }\n\n /**\n * List the session ids known for an orchestrator, optionally filtered\n * by a session-id prefix. Reads the latest row of each bucket so the\n * authoritative `session_id` is returned even if the key encoding\n * ever changes.\n */\n public async list(\n orchestratorName: string,\n prefix?: string,\n ): Promise<string[]> {\n const sessionIds: string[] = [];\n\n for (const rows of this.sessions.values()) {\n const latest = rows[rows.length - 1];\n\n if (!latest || latest.orchestrator_name !== orchestratorName) {\n continue;\n }\n\n if (prefix !== undefined && !latest.session_id.startsWith(prefix)) {\n continue;\n }\n\n sessionIds.push(latest.session_id);\n }\n\n return sessionIds;\n }\n\n /**\n * Drop every row for a session whose `turn_index` is strictly below\n * `keepBeforeTurnIndex`, enforcing the `keepSnapshots` retention bound\n * (§4 Phase 6, Q20). Rebuilds the bucket in place with the surviving\n * tail; an emptied bucket is removed so `list()` no longer reports the\n * session.\n */\n public async prune(\n orchestratorName: string,\n sessionId: string,\n keepBeforeTurnIndex: number,\n ): Promise<void> {\n const key = bucketKey(orchestratorName, sessionId);\n const rows = this.sessions.get(key);\n\n if (!rows) {\n return;\n }\n\n const kept = rows.filter((row) => row.turn_index >= keepBeforeTurnIndex);\n\n if (kept.length === 0) {\n this.sessions.delete(key);\n\n return;\n }\n\n if (kept.length !== rows.length) {\n this.sessions.set(key, kept);\n }\n }\n\n /**\n * The memory store has no backing table — there is nothing to\n * migrate. Returns an empty string so callers can treat `schema()`\n * uniformly across drivers.\n */\n public schema(): string {\n return \"\";\n }\n}\n\n/**\n * Create an in-memory {@link CheckpointStore}. Zero-config — no client,\n * no connection. Suitable for dev, tests, and single-process apps that\n * don't need resume across restarts.\n *\n * @example\n * import { ai } from \"@warlock.js/ai\";\n *\n * const orchestrator = ai.orchestrator({\n * name: \"support\",\n * intents: { ... },\n * checkpointStore: ai.checkpoint.memory(),\n * });\n */\nexport function memory(): CheckpointStore {\n return new MemoryCheckpointStore();\n}\n"],"mappings":";;;;;;;;AAYA,SAAS,UAAU,kBAA0B,WAA2B;CACtE,OAAO,GAAG,iBAAiB,GAAG;AAChC;;;;;;;;;;;;;;AAeA,IAAM,wBAAN,MAAuD;;kCAEzB,IAAI,IAAgC;;;;;;;CAOhE,MAAa,KACX,kBACA,WACuC;EACvC,MAAM,OAAO,KAAK,SAAS,IAAI,UAAU,kBAAkB,SAAS,CAAC;EAErE,IAAI,CAAC,QAAQ,KAAK,WAAW,GAC3B;EAGF,OAAO,KAAK,KAAK,SAAS;CAC5B;;;;;CAMA,MAAa,KAAK,QAAyC;EACzD,MAAM,MAAM,UAAU,OAAO,mBAAmB,OAAO,UAAU;EACjE,MAAM,OAAO,KAAK,SAAS,IAAI,GAAG;EAElC,IAAI,MAAM;GACR,KAAK,KAAK,MAAM;GAEhB;EACF;EAEA,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,CAAC;CACjC;;;;CAKA,MAAa,OACX,kBACA,WACe;EACf,KAAK,SAAS,OAAO,UAAU,kBAAkB,SAAS,CAAC;CAC7D;;;;;;;CAQA,MAAa,KACX,kBACA,QACmB;EACnB,MAAM,aAAuB,CAAC;EAE9B,KAAK,MAAM,QAAQ,KAAK,SAAS,OAAO,GAAG;GACzC,MAAM,SAAS,KAAK,KAAK,SAAS;GAElC,IAAI,CAAC,UAAU,OAAO,sBAAsB,kBAC1C;GAGF,IAAI,WAAW,UAAa,CAAC,OAAO,WAAW,WAAW,MAAM,GAC9D;GAGF,WAAW,KAAK,OAAO,UAAU;EACnC;EAEA,OAAO;CACT;;;;;;;;CASA,MAAa,MACX,kBACA,WACA,qBACe;EACf,MAAM,MAAM,UAAU,kBAAkB,SAAS;EACjD,MAAM,OAAO,KAAK,SAAS,IAAI,GAAG;EAElC,IAAI,CAAC,MACH;EAGF,MAAM,OAAO,KAAK,QAAQ,QAAQ,IAAI,cAAc,mBAAmB;EAEvE,IAAI,KAAK,WAAW,GAAG;GACrB,KAAK,SAAS,OAAO,GAAG;GAExB;EACF;EAEA,IAAI,KAAK,WAAW,KAAK,QACvB,KAAK,SAAS,IAAI,KAAK,IAAI;CAE/B;;;;;;CAOA,AAAO,SAAiB;EACtB,OAAO;CACT;AACF;;;;;;;;;;;;;;;AAgBA,SAAgB,SAA0B;CACxC,OAAO,IAAI,sBAAsB;AACnC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { PgClientLike } from "../contracts/orchestrator/snapshot-store.contract.mjs";
|
|
2
|
+
import { CheckpointStore } from "../contracts/orchestrator/checkpoint-store.contract.mjs";
|
|
3
|
+
|
|
4
|
+
//#region ../@warlock.js/ai/src/checkpoint/pg.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Options for the Postgres {@link CheckpointStore} (orchestrator.md §8.3).
|
|
7
|
+
*
|
|
8
|
+
* The dev owns the connection — `@warlock.js/ai` takes no peer dep on
|
|
9
|
+
* `pg` and never opens or closes the client. A single `pg.Pool` can
|
|
10
|
+
* back both the cache and the orchestrator stores.
|
|
11
|
+
*/
|
|
12
|
+
type PgCheckpointOptions = {
|
|
13
|
+
/** An already-built `pg.Pool` / `pg.Client` — anything matching {@link PgClientLike}. */client: PgClientLike; /** Backing table name. Defaults to `warlock_orchestrator_sessions` (§8.6). Must be a safe SQL identifier. */
|
|
14
|
+
table?: string; /** Idle-row TTL in seconds. When set, rows older than the TTL are eligible for cleanup on prune. */
|
|
15
|
+
ttl?: number;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Create a Postgres-backed {@link CheckpointStore} (orchestrator.md
|
|
19
|
+
* §8.3). The dev installs `pg` and passes a `pg.Pool` / `pg.Client` —
|
|
20
|
+
* `@warlock.js/ai` never imports `pg`. Run {@link CheckpointStore.schema}
|
|
21
|
+
* through your migration tool once before use; the store never
|
|
22
|
+
* auto-migrates.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* import { Pool } from "pg";
|
|
26
|
+
* import { ai } from "@warlock.js/ai";
|
|
27
|
+
*
|
|
28
|
+
* const pool = new Pool({ connectionString: process.env.DATABASE_URL });
|
|
29
|
+
* const store = ai.checkpoint.pg({ client: pool });
|
|
30
|
+
*
|
|
31
|
+
* // Once, via your migration tooling:
|
|
32
|
+
* // await pool.query(store.schema());
|
|
33
|
+
*/
|
|
34
|
+
declare function pg(options: PgCheckpointOptions): CheckpointStore;
|
|
35
|
+
//#endregion
|
|
36
|
+
export { PgCheckpointOptions, pg };
|
|
37
|
+
//# sourceMappingURL=pg.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pg.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai/src/checkpoint/pg.ts"],"mappings":";;;;;;AAaA;;;;;KAAY,mBAAA;EAIV,yFAFA,MAAA,EAAQ,YAAY,EAIjB;EAFH,KAAA,WAyWc;EAvWd,GAAA;AAAA;;;;;;AAuW+D;;;;;;;;;;;;iBAAjD,EAAA,CAAG,OAAA,EAAS,mBAAA,GAAsB,eAAe"}
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
//#region ../@warlock.js/ai/src/checkpoint/pg.ts
|
|
2
|
+
/**
|
|
3
|
+
* Default backing table — matches the §8.6 reference DDL verbatim so a
|
|
4
|
+
* stock migration provisions the store with no extra config.
|
|
5
|
+
*/
|
|
6
|
+
const DEFAULT_TABLE = "warlock_orchestrator_sessions";
|
|
7
|
+
/**
|
|
8
|
+
* Allowed characters in a Postgres identifier (table name). The table
|
|
9
|
+
* name is interpolated into DDL/DML, so anything outside this
|
|
10
|
+
* conservative ASCII subset is rejected — interpolating an arbitrary
|
|
11
|
+
* string would be a SQL-injection footgun (mirrors `PgCacheDriver`).
|
|
12
|
+
*/
|
|
13
|
+
const SAFE_IDENTIFIER = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
14
|
+
/**
|
|
15
|
+
* Coerce a Postgres `INTEGER` column back to a number. `pg` hands back
|
|
16
|
+
* `INTEGER` as a JS number already, but some pool wrappers surface it
|
|
17
|
+
* as a string — normalize defensively so `turn_index` arithmetic and
|
|
18
|
+
* the latest-turn ordering never compare strings.
|
|
19
|
+
*/
|
|
20
|
+
function toNumber(value) {
|
|
21
|
+
return typeof value === "string" ? Number(value) : value;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Coerce a nullable Postgres integer column to `number | null`.
|
|
25
|
+
*/
|
|
26
|
+
function toNullableNumber(value) {
|
|
27
|
+
return value === null || value === void 0 ? null : toNumber(value);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Coerce a Postgres timestamp/text column to an ISO string. `pg`
|
|
31
|
+
* returns `TIMESTAMPTZ` as a `Date`; normalize to the ISO wire shape
|
|
32
|
+
* the {@link CheckpointRecord} contract declares.
|
|
33
|
+
*/
|
|
34
|
+
function toIso(value) {
|
|
35
|
+
if (value instanceof Date) return value.toISOString();
|
|
36
|
+
return value;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Coerce a nullable Postgres timestamp column to `string | null`.
|
|
40
|
+
*/
|
|
41
|
+
function toNullableIso(value) {
|
|
42
|
+
if (value === null || value === void 0) return null;
|
|
43
|
+
return toIso(value);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Decode the single `last_route` `TEXT` column back to the
|
|
47
|
+
* `string | string[] | null` shape the contract declares. A fan-out
|
|
48
|
+
* array is written JSON-encoded (it starts with `[`), so a leading `[`
|
|
49
|
+
* is the signal to parse; any other value is a single intent stored
|
|
50
|
+
* verbatim. Symmetric with {@link PgCheckpointStore.serializeRoute}.
|
|
51
|
+
*/
|
|
52
|
+
function deserializeRoute(value) {
|
|
53
|
+
if (value === null || value === void 0) return null;
|
|
54
|
+
const route = value;
|
|
55
|
+
if (route.startsWith("[")) return JSON.parse(route);
|
|
56
|
+
return route;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Map a raw DB row to a {@link CheckpointRecord}. Column names match
|
|
60
|
+
* the §8.6 DDL 1:1, so this is a typed projection plus the defensive
|
|
61
|
+
* coercions a heterogeneous `pg` client population needs.
|
|
62
|
+
*/
|
|
63
|
+
function rowToRecord(row) {
|
|
64
|
+
const state = typeof row.state === "string" ? JSON.parse(row.state) : row.state;
|
|
65
|
+
return {
|
|
66
|
+
orchestrator_name: row.orchestrator_name,
|
|
67
|
+
session_id: row.session_id,
|
|
68
|
+
turn_index: toNumber(row.turn_index),
|
|
69
|
+
state,
|
|
70
|
+
last_route: deserializeRoute(row.last_route),
|
|
71
|
+
signature: row.signature,
|
|
72
|
+
version: row.version ?? null,
|
|
73
|
+
summarized_through: toNullableNumber(row.summarized_through),
|
|
74
|
+
lock_acquired_at: toNullableIso(row.lock_acquired_at),
|
|
75
|
+
lock_expires_at: toNullableIso(row.lock_expires_at),
|
|
76
|
+
saved_at: toIso(row.saved_at)
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Postgres-backed {@link CheckpointStore} (orchestrator.md §8.2, §8.6).
|
|
81
|
+
*
|
|
82
|
+
* Owns: append-only checkpoint rows keyed by
|
|
83
|
+
* `(orchestrator_name, session_id, turn_index)`, the "latest turn wins"
|
|
84
|
+
* load, the §8.6 DDL via {@link PgCheckpointStore.schema}, and the
|
|
85
|
+
* §4-Phase-6 retention prune. Does NOT own: the connection lifecycle
|
|
86
|
+
* (the dev passes a client and keeps it), schema migration (the dev
|
|
87
|
+
* runs `schema()` through their own tool — never auto-migrated, §8.5),
|
|
88
|
+
* or the `keepSnapshots` policy itself (that lives on the orchestrator
|
|
89
|
+
* config; the orchestrator passes the resolved bound into
|
|
90
|
+
* {@link PgCheckpointStore.prune}).
|
|
91
|
+
*
|
|
92
|
+
* Front it with the {@link pg} factory — callers never `new` it.
|
|
93
|
+
*/
|
|
94
|
+
var PgCheckpointStore = class {
|
|
95
|
+
constructor(options) {
|
|
96
|
+
if (!options || typeof options.client?.query !== "function") throw new TypeError("ai.checkpoint.pg requires a 'client' option implementing { query(text, params) } — pass a pg.Pool or pg.Client.");
|
|
97
|
+
const table = options.table ?? DEFAULT_TABLE;
|
|
98
|
+
if (!SAFE_IDENTIFIER.test(table)) throw new TypeError(`ai.checkpoint.pg: invalid table name '${table}'. Allowed: [A-Za-z_][A-Za-z0-9_]*.`);
|
|
99
|
+
this.client = options.client;
|
|
100
|
+
this.table = table;
|
|
101
|
+
this.ttl = options.ttl;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Return the latest checkpoint (highest `turn_index`) for a session,
|
|
105
|
+
* or `undefined` when the store has never seen it. The `(name,
|
|
106
|
+
* session_id, turn_index DESC)` lookup index keeps this O(1) on the
|
|
107
|
+
* latest row (§8.6).
|
|
108
|
+
*/
|
|
109
|
+
async load(orchestratorName, sessionId) {
|
|
110
|
+
const { rows } = await this.client.query(`SELECT * FROM ${this.table}
|
|
111
|
+
WHERE orchestrator_name = $1 AND session_id = $2
|
|
112
|
+
ORDER BY turn_index DESC
|
|
113
|
+
LIMIT 1`, [orchestratorName, sessionId]);
|
|
114
|
+
if (rows.length === 0) return;
|
|
115
|
+
return rowToRecord(rows[0]);
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Persist a fresh checkpoint row. Append-only — an existing
|
|
119
|
+
* `turn_index` is never overwritten; the PK collision surfaces as a
|
|
120
|
+
* Postgres error rather than a silent clobber (§4 Phase 6, Q15).
|
|
121
|
+
*/
|
|
122
|
+
async save(record) {
|
|
123
|
+
await this.client.query(`INSERT INTO ${this.table} (
|
|
124
|
+
orchestrator_name, session_id, turn_index, state, last_route,
|
|
125
|
+
signature, version, summarized_through, lock_acquired_at,
|
|
126
|
+
lock_expires_at, saved_at
|
|
127
|
+
)
|
|
128
|
+
VALUES ($1, $2, $3, $4::jsonb, $5, $6, $7, $8, $9, $10, $11)`, [
|
|
129
|
+
record.orchestrator_name,
|
|
130
|
+
record.session_id,
|
|
131
|
+
record.turn_index,
|
|
132
|
+
JSON.stringify(record.state),
|
|
133
|
+
this.serializeRoute(record.last_route),
|
|
134
|
+
record.signature,
|
|
135
|
+
record.version,
|
|
136
|
+
record.summarized_through,
|
|
137
|
+
record.lock_acquired_at,
|
|
138
|
+
record.lock_expires_at,
|
|
139
|
+
record.saved_at
|
|
140
|
+
]);
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Delete every checkpoint row for a session, ending it.
|
|
144
|
+
*/
|
|
145
|
+
async delete(orchestratorName, sessionId) {
|
|
146
|
+
await this.client.query(`DELETE FROM ${this.table}
|
|
147
|
+
WHERE orchestrator_name = $1 AND session_id = $2`, [orchestratorName, sessionId]);
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* List the distinct session ids known for an orchestrator, optionally
|
|
151
|
+
* filtered by a session-id prefix. Used by the production boot-drain
|
|
152
|
+
* loop (§9.3). The prefix is matched with `LIKE`, escaping the SQL
|
|
153
|
+
* wildcards so a literal `_` or `%` in the prefix is not treated as a
|
|
154
|
+
* pattern.
|
|
155
|
+
*/
|
|
156
|
+
async list(orchestratorName, prefix) {
|
|
157
|
+
if (prefix === void 0) {
|
|
158
|
+
const { rows } = await this.client.query(`SELECT DISTINCT session_id FROM ${this.table}
|
|
159
|
+
WHERE orchestrator_name = $1`, [orchestratorName]);
|
|
160
|
+
return rows.map((row) => row.session_id);
|
|
161
|
+
}
|
|
162
|
+
const escaped = prefix.replace(/\\/g, "\\\\").replace(/_/g, "\\_").replace(/%/g, "\\%");
|
|
163
|
+
const { rows } = await this.client.query(`SELECT DISTINCT session_id FROM ${this.table}
|
|
164
|
+
WHERE orchestrator_name = $1 AND session_id LIKE $2 ESCAPE '\\'`, [orchestratorName, `${escaped}%`]);
|
|
165
|
+
return rows.map((row) => row.session_id);
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Prune retained turns for a session down to the most recent
|
|
169
|
+
* `keepSnapshots` rows (orchestrator.md §4 Phase 6 / §15.2). Deletes
|
|
170
|
+
* every row with `turn_index < (max_turn_index - keepSnapshots)`. The
|
|
171
|
+
* orchestrator calls this synchronously after a successful
|
|
172
|
+
* {@link save} when `keepSnapshots` is a finite number; `"all"`
|
|
173
|
+
* retention skips the call entirely. Additive to the
|
|
174
|
+
* {@link CheckpointStore} contract — the contract carries no prune
|
|
175
|
+
* hook, so the policy stays on the orchestrator and the store only
|
|
176
|
+
* executes the bounded delete.
|
|
177
|
+
*/
|
|
178
|
+
async prune(orchestratorName, sessionId, keepSnapshots) {
|
|
179
|
+
if (!Number.isFinite(keepSnapshots) || keepSnapshots < 0) return;
|
|
180
|
+
await this.client.query(`DELETE FROM ${this.table}
|
|
181
|
+
WHERE orchestrator_name = $1
|
|
182
|
+
AND session_id = $2
|
|
183
|
+
AND turn_index < (
|
|
184
|
+
SELECT max(turn_index) - $3
|
|
185
|
+
FROM ${this.table}
|
|
186
|
+
WHERE orchestrator_name = $1 AND session_id = $2
|
|
187
|
+
)`, [
|
|
188
|
+
orchestratorName,
|
|
189
|
+
sessionId,
|
|
190
|
+
keepSnapshots
|
|
191
|
+
]);
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Return the §8.6 reference DDL for this store's backing table,
|
|
195
|
+
* interpolating the configured table name. The dev runs it through
|
|
196
|
+
* their migration tool — the framework never auto-migrates (§8.5).
|
|
197
|
+
*
|
|
198
|
+
* @example
|
|
199
|
+
* await pool.query(store.schema());
|
|
200
|
+
*/
|
|
201
|
+
schema() {
|
|
202
|
+
return [
|
|
203
|
+
`CREATE TABLE IF NOT EXISTS ${this.table} (`,
|
|
204
|
+
` orchestrator_name TEXT NOT NULL,`,
|
|
205
|
+
` session_id TEXT NOT NULL,`,
|
|
206
|
+
` turn_index INTEGER NOT NULL,`,
|
|
207
|
+
` state JSONB NOT NULL,`,
|
|
208
|
+
` last_route TEXT,`,
|
|
209
|
+
` signature TEXT NOT NULL,`,
|
|
210
|
+
` version TEXT,`,
|
|
211
|
+
` summarized_through INTEGER,`,
|
|
212
|
+
` lock_acquired_at TIMESTAMPTZ,`,
|
|
213
|
+
` lock_expires_at TIMESTAMPTZ,`,
|
|
214
|
+
` saved_at TIMESTAMPTZ NOT NULL DEFAULT now(),`,
|
|
215
|
+
` PRIMARY KEY (orchestrator_name, session_id, turn_index)`,
|
|
216
|
+
`);`,
|
|
217
|
+
`CREATE INDEX IF NOT EXISTS idx_${this.table}_saved_at`,
|
|
218
|
+
` ON ${this.table} (saved_at);`,
|
|
219
|
+
`CREATE INDEX IF NOT EXISTS idx_${this.table}_lookup`,
|
|
220
|
+
` ON ${this.table} (orchestrator_name, session_id, turn_index DESC);`
|
|
221
|
+
].join("\n");
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Set the idle-row TTL (§8.2). Stored for prune-time cleanup; the
|
|
225
|
+
* store never opens a background timer.
|
|
226
|
+
*/
|
|
227
|
+
setOptions(options) {
|
|
228
|
+
this.ttl = options.ttl;
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* `last_route` rides a single `TEXT` column. A fan-out array is
|
|
232
|
+
* JSON-encoded so it round-trips through one column without a schema
|
|
233
|
+
* change; a single intent (an identifier — never starts with `[`) is
|
|
234
|
+
* stored verbatim. {@link deserializeRoute} reverses this on load.
|
|
235
|
+
*/
|
|
236
|
+
serializeRoute(route) {
|
|
237
|
+
if (route === null) return null;
|
|
238
|
+
if (Array.isArray(route)) return JSON.stringify(route);
|
|
239
|
+
return route;
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
/**
|
|
243
|
+
* Create a Postgres-backed {@link CheckpointStore} (orchestrator.md
|
|
244
|
+
* §8.3). The dev installs `pg` and passes a `pg.Pool` / `pg.Client` —
|
|
245
|
+
* `@warlock.js/ai` never imports `pg`. Run {@link CheckpointStore.schema}
|
|
246
|
+
* through your migration tool once before use; the store never
|
|
247
|
+
* auto-migrates.
|
|
248
|
+
*
|
|
249
|
+
* @example
|
|
250
|
+
* import { Pool } from "pg";
|
|
251
|
+
* import { ai } from "@warlock.js/ai";
|
|
252
|
+
*
|
|
253
|
+
* const pool = new Pool({ connectionString: process.env.DATABASE_URL });
|
|
254
|
+
* const store = ai.checkpoint.pg({ client: pool });
|
|
255
|
+
*
|
|
256
|
+
* // Once, via your migration tooling:
|
|
257
|
+
* // await pool.query(store.schema());
|
|
258
|
+
*/
|
|
259
|
+
function pg(options) {
|
|
260
|
+
return new PgCheckpointStore(options);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
//#endregion
|
|
264
|
+
export { pg };
|
|
265
|
+
//# sourceMappingURL=pg.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pg.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/checkpoint/pg.ts"],"sourcesContent":["import type {\n CheckpointRecord,\n CheckpointStore,\n} from \"../contracts/orchestrator/checkpoint-store.contract\";\nimport type { PgClientLike } from \"../contracts/orchestrator/snapshot-store.contract\";\n\n/**\n * Options for the Postgres {@link CheckpointStore} (orchestrator.md §8.3).\n *\n * The dev owns the connection — `@warlock.js/ai` takes no peer dep on\n * `pg` and never opens or closes the client. A single `pg.Pool` can\n * back both the cache and the orchestrator stores.\n */\nexport type PgCheckpointOptions = {\n /** An already-built `pg.Pool` / `pg.Client` — anything matching {@link PgClientLike}. */\n client: PgClientLike;\n /** Backing table name. Defaults to `warlock_orchestrator_sessions` (§8.6). Must be a safe SQL identifier. */\n table?: string;\n /** Idle-row TTL in seconds. When set, rows older than the TTL are eligible for cleanup on prune. */\n ttl?: number;\n};\n\n/**\n * Default backing table — matches the §8.6 reference DDL verbatim so a\n * stock migration provisions the store with no extra config.\n */\nconst DEFAULT_TABLE = \"warlock_orchestrator_sessions\";\n\n/**\n * Allowed characters in a Postgres identifier (table name). The table\n * name is interpolated into DDL/DML, so anything outside this\n * conservative ASCII subset is rejected — interpolating an arbitrary\n * string would be a SQL-injection footgun (mirrors `PgCacheDriver`).\n */\nconst SAFE_IDENTIFIER = /^[A-Za-z_][A-Za-z0-9_]*$/;\n\n/**\n * Coerce a Postgres `INTEGER` column back to a number. `pg` hands back\n * `INTEGER` as a JS number already, but some pool wrappers surface it\n * as a string — normalize defensively so `turn_index` arithmetic and\n * the latest-turn ordering never compare strings.\n */\nfunction toNumber(value: unknown): number {\n return typeof value === \"string\" ? Number(value) : (value as number);\n}\n\n/**\n * Coerce a nullable Postgres integer column to `number | null`.\n */\nfunction toNullableNumber(value: unknown): number | null {\n return value === null || value === undefined ? null : toNumber(value);\n}\n\n/**\n * Coerce a Postgres timestamp/text column to an ISO string. `pg`\n * returns `TIMESTAMPTZ` as a `Date`; normalize to the ISO wire shape\n * the {@link CheckpointRecord} contract declares.\n */\nfunction toIso(value: unknown): string {\n if (value instanceof Date) {\n return value.toISOString();\n }\n\n return value as string;\n}\n\n/**\n * Coerce a nullable Postgres timestamp column to `string | null`.\n */\nfunction toNullableIso(value: unknown): string | null {\n if (value === null || value === undefined) {\n return null;\n }\n\n return toIso(value);\n}\n\n/**\n * Decode the single `last_route` `TEXT` column back to the\n * `string | string[] | null` shape the contract declares. A fan-out\n * array is written JSON-encoded (it starts with `[`), so a leading `[`\n * is the signal to parse; any other value is a single intent stored\n * verbatim. Symmetric with {@link PgCheckpointStore.serializeRoute}.\n */\nfunction deserializeRoute(value: unknown): string | string[] | null {\n if (value === null || value === undefined) {\n return null;\n }\n\n const route = value as string;\n\n if (route.startsWith(\"[\")) {\n return JSON.parse(route) as string[];\n }\n\n return route;\n}\n\n/**\n * Map a raw DB row to a {@link CheckpointRecord}. Column names match\n * the §8.6 DDL 1:1, so this is a typed projection plus the defensive\n * coercions a heterogeneous `pg` client population needs.\n */\nfunction rowToRecord(row: Record<string, unknown>): CheckpointRecord {\n const state =\n typeof row.state === \"string\" ? JSON.parse(row.state) : row.state;\n\n return {\n orchestrator_name: row.orchestrator_name as string,\n session_id: row.session_id as string,\n turn_index: toNumber(row.turn_index),\n state,\n last_route: deserializeRoute(row.last_route),\n signature: row.signature as string,\n version: (row.version as string | null) ?? null,\n summarized_through: toNullableNumber(row.summarized_through),\n lock_acquired_at: toNullableIso(row.lock_acquired_at),\n lock_expires_at: toNullableIso(row.lock_expires_at),\n saved_at: toIso(row.saved_at),\n };\n}\n\n/**\n * Postgres-backed {@link CheckpointStore} (orchestrator.md §8.2, §8.6).\n *\n * Owns: append-only checkpoint rows keyed by\n * `(orchestrator_name, session_id, turn_index)`, the \"latest turn wins\"\n * load, the §8.6 DDL via {@link PgCheckpointStore.schema}, and the\n * §4-Phase-6 retention prune. Does NOT own: the connection lifecycle\n * (the dev passes a client and keeps it), schema migration (the dev\n * runs `schema()` through their own tool — never auto-migrated, §8.5),\n * or the `keepSnapshots` policy itself (that lives on the orchestrator\n * config; the orchestrator passes the resolved bound into\n * {@link PgCheckpointStore.prune}).\n *\n * Front it with the {@link pg} factory — callers never `new` it.\n */\nclass PgCheckpointStore implements CheckpointStore {\n /** The dev-supplied `pg.Pool` / `pg.Client`. Never closed by the store. */\n private readonly client: PgClientLike;\n\n /** Validated backing table name, safe to interpolate into SQL. */\n private readonly table: string;\n\n /** Idle-row TTL in seconds, or `undefined` for no expiry. */\n private ttl?: number;\n\n public constructor(options: PgCheckpointOptions) {\n if (!options || typeof options.client?.query !== \"function\") {\n throw new TypeError(\n \"ai.checkpoint.pg requires a 'client' option implementing { query(text, params) } — pass a pg.Pool or pg.Client.\",\n );\n }\n\n const table = options.table ?? DEFAULT_TABLE;\n\n if (!SAFE_IDENTIFIER.test(table)) {\n throw new TypeError(\n `ai.checkpoint.pg: invalid table name '${table}'. Allowed: [A-Za-z_][A-Za-z0-9_]*.`,\n );\n }\n\n this.client = options.client;\n this.table = table;\n this.ttl = options.ttl;\n }\n\n /**\n * Return the latest checkpoint (highest `turn_index`) for a session,\n * or `undefined` when the store has never seen it. The `(name,\n * session_id, turn_index DESC)` lookup index keeps this O(1) on the\n * latest row (§8.6).\n */\n public async load(\n orchestratorName: string,\n sessionId: string,\n ): Promise<CheckpointRecord | undefined> {\n const { rows } = await this.client.query(\n `SELECT * FROM ${this.table}\n WHERE orchestrator_name = $1 AND session_id = $2\n ORDER BY turn_index DESC\n LIMIT 1`,\n [orchestratorName, sessionId],\n );\n\n if (rows.length === 0) {\n return undefined;\n }\n\n return rowToRecord(rows[0] as Record<string, unknown>);\n }\n\n /**\n * Persist a fresh checkpoint row. Append-only — an existing\n * `turn_index` is never overwritten; the PK collision surfaces as a\n * Postgres error rather than a silent clobber (§4 Phase 6, Q15).\n */\n public async save(record: CheckpointRecord): Promise<void> {\n await this.client.query(\n `INSERT INTO ${this.table} (\n orchestrator_name, session_id, turn_index, state, last_route,\n signature, version, summarized_through, lock_acquired_at,\n lock_expires_at, saved_at\n )\n VALUES ($1, $2, $3, $4::jsonb, $5, $6, $7, $8, $9, $10, $11)`,\n [\n record.orchestrator_name,\n record.session_id,\n record.turn_index,\n JSON.stringify(record.state),\n this.serializeRoute(record.last_route),\n record.signature,\n record.version,\n record.summarized_through,\n record.lock_acquired_at,\n record.lock_expires_at,\n record.saved_at,\n ],\n );\n }\n\n /**\n * Delete every checkpoint row for a session, ending it.\n */\n public async delete(\n orchestratorName: string,\n sessionId: string,\n ): Promise<void> {\n await this.client.query(\n `DELETE FROM ${this.table}\n WHERE orchestrator_name = $1 AND session_id = $2`,\n [orchestratorName, sessionId],\n );\n }\n\n /**\n * List the distinct session ids known for an orchestrator, optionally\n * filtered by a session-id prefix. Used by the production boot-drain\n * loop (§9.3). The prefix is matched with `LIKE`, escaping the SQL\n * wildcards so a literal `_` or `%` in the prefix is not treated as a\n * pattern.\n */\n public async list(\n orchestratorName: string,\n prefix?: string,\n ): Promise<string[]> {\n if (prefix === undefined) {\n const { rows } = await this.client.query(\n `SELECT DISTINCT session_id FROM ${this.table}\n WHERE orchestrator_name = $1`,\n [orchestratorName],\n );\n\n return rows.map((row) => (row as Record<string, unknown>).session_id as string);\n }\n\n const escaped = prefix\n .replace(/\\\\/g, \"\\\\\\\\\")\n .replace(/_/g, \"\\\\_\")\n .replace(/%/g, \"\\\\%\");\n\n const { rows } = await this.client.query(\n `SELECT DISTINCT session_id FROM ${this.table}\n WHERE orchestrator_name = $1 AND session_id LIKE $2 ESCAPE '\\\\'`,\n [orchestratorName, `${escaped}%`],\n );\n\n return rows.map((row) => (row as Record<string, unknown>).session_id as string);\n }\n\n /**\n * Prune retained turns for a session down to the most recent\n * `keepSnapshots` rows (orchestrator.md §4 Phase 6 / §15.2). Deletes\n * every row with `turn_index < (max_turn_index - keepSnapshots)`. The\n * orchestrator calls this synchronously after a successful\n * {@link save} when `keepSnapshots` is a finite number; `\"all\"`\n * retention skips the call entirely. Additive to the\n * {@link CheckpointStore} contract — the contract carries no prune\n * hook, so the policy stays on the orchestrator and the store only\n * executes the bounded delete.\n */\n public async prune(\n orchestratorName: string,\n sessionId: string,\n keepSnapshots: number,\n ): Promise<void> {\n if (!Number.isFinite(keepSnapshots) || keepSnapshots < 0) {\n return;\n }\n\n await this.client.query(\n `DELETE FROM ${this.table}\n WHERE orchestrator_name = $1\n AND session_id = $2\n AND turn_index < (\n SELECT max(turn_index) - $3\n FROM ${this.table}\n WHERE orchestrator_name = $1 AND session_id = $2\n )`,\n [orchestratorName, sessionId, keepSnapshots],\n );\n }\n\n /**\n * Return the §8.6 reference DDL for this store's backing table,\n * interpolating the configured table name. The dev runs it through\n * their migration tool — the framework never auto-migrates (§8.5).\n *\n * @example\n * await pool.query(store.schema());\n */\n public schema(): string {\n return [\n `CREATE TABLE IF NOT EXISTS ${this.table} (`,\n ` orchestrator_name TEXT NOT NULL,`,\n ` session_id TEXT NOT NULL,`,\n ` turn_index INTEGER NOT NULL,`,\n ` state JSONB NOT NULL,`,\n ` last_route TEXT,`,\n ` signature TEXT NOT NULL,`,\n ` version TEXT,`,\n ` summarized_through INTEGER,`,\n ` lock_acquired_at TIMESTAMPTZ,`,\n ` lock_expires_at TIMESTAMPTZ,`,\n ` saved_at TIMESTAMPTZ NOT NULL DEFAULT now(),`,\n ` PRIMARY KEY (orchestrator_name, session_id, turn_index)`,\n `);`,\n `CREATE INDEX IF NOT EXISTS idx_${this.table}_saved_at`,\n ` ON ${this.table} (saved_at);`,\n `CREATE INDEX IF NOT EXISTS idx_${this.table}_lookup`,\n ` ON ${this.table} (orchestrator_name, session_id, turn_index DESC);`,\n ].join(\"\\n\");\n }\n\n /**\n * Set the idle-row TTL (§8.2). Stored for prune-time cleanup; the\n * store never opens a background timer.\n */\n public setOptions(options: { ttl?: number }): void {\n this.ttl = options.ttl;\n }\n\n /**\n * `last_route` rides a single `TEXT` column. A fan-out array is\n * JSON-encoded so it round-trips through one column without a schema\n * change; a single intent (an identifier — never starts with `[`) is\n * stored verbatim. {@link deserializeRoute} reverses this on load.\n */\n private serializeRoute(route: string | string[] | null): string | null {\n if (route === null) {\n return null;\n }\n\n if (Array.isArray(route)) {\n return JSON.stringify(route);\n }\n\n return route;\n }\n}\n\n/**\n * Create a Postgres-backed {@link CheckpointStore} (orchestrator.md\n * §8.3). The dev installs `pg` and passes a `pg.Pool` / `pg.Client` —\n * `@warlock.js/ai` never imports `pg`. Run {@link CheckpointStore.schema}\n * through your migration tool once before use; the store never\n * auto-migrates.\n *\n * @example\n * import { Pool } from \"pg\";\n * import { ai } from \"@warlock.js/ai\";\n *\n * const pool = new Pool({ connectionString: process.env.DATABASE_URL });\n * const store = ai.checkpoint.pg({ client: pool });\n *\n * // Once, via your migration tooling:\n * // await pool.query(store.schema());\n */\nexport function pg(options: PgCheckpointOptions): CheckpointStore {\n return new PgCheckpointStore(options);\n}\n"],"mappings":";;;;;AA0BA,MAAM,gBAAgB;;;;;;;AAQtB,MAAM,kBAAkB;;;;;;;AAQxB,SAAS,SAAS,OAAwB;CACxC,OAAO,OAAO,UAAU,WAAW,OAAO,KAAK,IAAK;AACtD;;;;AAKA,SAAS,iBAAiB,OAA+B;CACvD,OAAO,UAAU,QAAQ,UAAU,SAAY,OAAO,SAAS,KAAK;AACtE;;;;;;AAOA,SAAS,MAAM,OAAwB;CACrC,IAAI,iBAAiB,MACnB,OAAO,MAAM,YAAY;CAG3B,OAAO;AACT;;;;AAKA,SAAS,cAAc,OAA+B;CACpD,IAAI,UAAU,QAAQ,UAAU,QAC9B,OAAO;CAGT,OAAO,MAAM,KAAK;AACpB;;;;;;;;AASA,SAAS,iBAAiB,OAA0C;CAClE,IAAI,UAAU,QAAQ,UAAU,QAC9B,OAAO;CAGT,MAAM,QAAQ;CAEd,IAAI,MAAM,WAAW,GAAG,GACtB,OAAO,KAAK,MAAM,KAAK;CAGzB,OAAO;AACT;;;;;;AAOA,SAAS,YAAY,KAAgD;CACnE,MAAM,QACJ,OAAO,IAAI,UAAU,WAAW,KAAK,MAAM,IAAI,KAAK,IAAI,IAAI;CAE9D,OAAO;EACL,mBAAmB,IAAI;EACvB,YAAY,IAAI;EAChB,YAAY,SAAS,IAAI,UAAU;EACnC;EACA,YAAY,iBAAiB,IAAI,UAAU;EAC3C,WAAW,IAAI;EACf,SAAU,IAAI,WAA6B;EAC3C,oBAAoB,iBAAiB,IAAI,kBAAkB;EAC3D,kBAAkB,cAAc,IAAI,gBAAgB;EACpD,iBAAiB,cAAc,IAAI,eAAe;EAClD,UAAU,MAAM,IAAI,QAAQ;CAC9B;AACF;;;;;;;;;;;;;;;;AAiBA,IAAM,oBAAN,MAAmD;CAUjD,AAAO,YAAY,SAA8B;EAC/C,IAAI,CAAC,WAAW,OAAO,QAAQ,QAAQ,UAAU,YAC/C,MAAM,IAAI,UACR,iHACF;EAGF,MAAM,QAAQ,QAAQ,SAAS;EAE/B,IAAI,CAAC,gBAAgB,KAAK,KAAK,GAC7B,MAAM,IAAI,UACR,yCAAyC,MAAM,oCACjD;EAGF,KAAK,SAAS,QAAQ;EACtB,KAAK,QAAQ;EACb,KAAK,MAAM,QAAQ;CACrB;;;;;;;CAQA,MAAa,KACX,kBACA,WACuC;EACvC,MAAM,EAAE,SAAS,MAAM,KAAK,OAAO,MACjC,iBAAiB,KAAK,MAAM;;;iBAI5B,CAAC,kBAAkB,SAAS,CAC9B;EAEA,IAAI,KAAK,WAAW,GAClB;EAGF,OAAO,YAAY,KAAK,EAA6B;CACvD;;;;;;CAOA,MAAa,KAAK,QAAyC;EACzD,MAAM,KAAK,OAAO,MAChB,eAAe,KAAK,MAAM;;;;;sEAM1B;GACE,OAAO;GACP,OAAO;GACP,OAAO;GACP,KAAK,UAAU,OAAO,KAAK;GAC3B,KAAK,eAAe,OAAO,UAAU;GACrC,OAAO;GACP,OAAO;GACP,OAAO;GACP,OAAO;GACP,OAAO;GACP,OAAO;EACT,CACF;CACF;;;;CAKA,MAAa,OACX,kBACA,WACe;EACf,MAAM,KAAK,OAAO,MAChB,eAAe,KAAK,MAAM;0DAE1B,CAAC,kBAAkB,SAAS,CAC9B;CACF;;;;;;;;CASA,MAAa,KACX,kBACA,QACmB;EACnB,IAAI,WAAW,QAAW;GACxB,MAAM,EAAE,SAAS,MAAM,KAAK,OAAO,MACjC,mCAAmC,KAAK,MAAM;wCAE9C,CAAC,gBAAgB,CACnB;GAEA,OAAO,KAAK,KAAK,QAAS,IAAgC,UAAoB;EAChF;EAEA,MAAM,UAAU,OACb,QAAQ,OAAO,MAAM,CAAC,CACtB,QAAQ,MAAM,KAAK,CAAC,CACpB,QAAQ,MAAM,KAAK;EAEtB,MAAM,EAAE,SAAS,MAAM,KAAK,OAAO,MACjC,mCAAmC,KAAK,MAAM;yEAE9C,CAAC,kBAAkB,GAAG,QAAQ,EAAE,CAClC;EAEA,OAAO,KAAK,KAAK,QAAS,IAAgC,UAAoB;CAChF;;;;;;;;;;;;CAaA,MAAa,MACX,kBACA,WACA,eACe;EACf,IAAI,CAAC,OAAO,SAAS,aAAa,KAAK,gBAAgB,GACrD;EAGF,MAAM,KAAK,OAAO,MAChB,eAAe,KAAK,MAAM;;;;;kBAKd,KAAK,MAAM;;aAGvB;GAAC;GAAkB;GAAW;EAAa,CAC7C;CACF;;;;;;;;;CAUA,AAAO,SAAiB;EACtB,OAAO;GACL,8BAA8B,KAAK,MAAM;GACzC;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA,kCAAkC,KAAK,MAAM;GAC7C,QAAQ,KAAK,MAAM;GACnB,kCAAkC,KAAK,MAAM;GAC7C,QAAQ,KAAK,MAAM;EACrB,CAAC,CAAC,KAAK,IAAI;CACb;;;;;CAMA,AAAO,WAAW,SAAiC;EACjD,KAAK,MAAM,QAAQ;CACrB;;;;;;;CAQA,AAAQ,eAAe,OAAgD;EACrE,IAAI,UAAU,MACZ,OAAO;EAGT,IAAI,MAAM,QAAQ,KAAK,GACrB,OAAO,KAAK,UAAU,KAAK;EAG7B,OAAO;CACT;AACF;;;;;;;;;;;;;;;;;;AAmBA,SAAgB,GAAG,SAA+C;CAChE,OAAO,IAAI,kBAAkB,OAAO;AACtC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { RedisClientLike } from "../contracts/orchestrator/snapshot-store.contract.mjs";
|
|
2
|
+
import { CheckpointStore } from "../contracts/orchestrator/checkpoint-store.contract.mjs";
|
|
3
|
+
|
|
4
|
+
//#region ../@warlock.js/ai/src/checkpoint/redis.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Options for the Redis {@link CheckpointStore} (orchestrator.md §8.3).
|
|
7
|
+
*
|
|
8
|
+
* The dev owns the connection — `@warlock.js/ai` takes no peer dep on
|
|
9
|
+
* `redis` and never opens or closes the client.
|
|
10
|
+
*/
|
|
11
|
+
type RedisCheckpointOptions = {
|
|
12
|
+
/** An already-connected `redis` client — anything matching {@link RedisClientLike}. */client: RedisClientLike;
|
|
13
|
+
/**
|
|
14
|
+
* Key prefix for every key this store writes. Lets one Redis database
|
|
15
|
+
* back multiple stores without collision. Defaults to
|
|
16
|
+
* `warlock:orchestrator`.
|
|
17
|
+
*/
|
|
18
|
+
prefix?: string; /** Idle-key TTL in seconds. When set, every written key expires after the TTL. */
|
|
19
|
+
ttl?: number;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Create a Redis-backed {@link CheckpointStore} (orchestrator.md §8.3).
|
|
23
|
+
* The dev installs `redis` and passes a connected client —
|
|
24
|
+
* `@warlock.js/ai` never imports `redis`. {@link CheckpointStore.schema}
|
|
25
|
+
* returns an empty string; Redis needs no migration.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* import { createClient } from "redis";
|
|
29
|
+
* import { ai } from "@warlock.js/ai";
|
|
30
|
+
*
|
|
31
|
+
* const client = createClient();
|
|
32
|
+
* await client.connect();
|
|
33
|
+
*
|
|
34
|
+
* const store = ai.checkpoint.redis({ client });
|
|
35
|
+
*/
|
|
36
|
+
declare function redis(options: RedisCheckpointOptions): CheckpointStore;
|
|
37
|
+
//#endregion
|
|
38
|
+
export { RedisCheckpointOptions, redis };
|
|
39
|
+
//# sourceMappingURL=redis.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redis.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai/src/checkpoint/redis.ts"],"mappings":";;;;;;AAYA;;;;KAAY,sBAAA;EAEF,uFAAR,MAAA,EAAQ,eAAe;EAQvB;;AAAG;AA0UL;;EA5UE,MAAA,WA4UqE;EA1UrE,GAAA;AAAA;;;AA0UqE;;;;;;;;;;;;;iBAAvD,KAAA,CAAM,OAAA,EAAS,sBAAA,GAAyB,eAAe"}
|