@vercel/factory 0.0.14 → 0.0.15
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/README.md +306 -0
- package/dist/agent-routes.d.mts +69 -0
- package/dist/agent-routes.mjs +64 -0
- package/dist/agent-routes.mjs.map +1 -0
- package/dist/api-contracts.d.mts +1749 -0
- package/dist/api-contracts.mjs +118 -0
- package/dist/api-contracts.mjs.map +1 -0
- package/dist/api-images.d.mts +30 -0
- package/dist/api-images.mjs +28 -0
- package/dist/api-images.mjs.map +1 -0
- package/dist/api-task-graph.mjs +57 -0
- package/dist/api-task-graph.mjs.map +1 -0
- package/dist/api.d.mts +68 -216
- package/dist/api.mjs +872 -97
- package/dist/api.mjs.map +1 -1
- package/dist/approval-access.d.mts +39 -0
- package/dist/approval-access.mjs +62 -0
- package/dist/approval-access.mjs.map +1 -0
- package/dist/approval-contracts.d.mts +692 -0
- package/dist/approval-contracts.mjs +27 -0
- package/dist/approval-contracts.mjs.map +1 -0
- package/dist/approval.d.mts +49 -0
- package/dist/approval.mjs +39 -0
- package/dist/approval.mjs.map +1 -0
- package/dist/blob/artifacts.d.mts +37 -0
- package/dist/blob/artifacts.mjs +45 -0
- package/dist/blob/artifacts.mjs.map +1 -0
- package/dist/blob/index.d.mts +41 -6
- package/dist/blob/index.mjs +158 -40
- package/dist/blob/index.mjs.map +1 -1
- package/dist/budget.d.mts +108 -0
- package/dist/budget.mjs +141 -0
- package/dist/budget.mjs.map +1 -0
- package/dist/budgets.d.mts +4 -0
- package/dist/budgets.mjs +4 -0
- package/dist/build-factory.d.mts +6 -4
- package/dist/build-factory.mjs +2 -1
- package/dist/build-factory.mjs.map +1 -1
- package/dist/change-verification/brief.d.mts +9 -0
- package/dist/change-verification/brief.mjs +13 -0
- package/dist/change-verification/brief.mjs.map +1 -0
- package/dist/change-verification/dispatch.d.mts +24 -0
- package/dist/change-verification/dispatch.mjs +45 -0
- package/dist/change-verification/dispatch.mjs.map +1 -0
- package/dist/change-verification/eve-tool.d.mts +60 -0
- package/dist/change-verification/eve-tool.mjs +101 -0
- package/dist/change-verification/eve-tool.mjs.map +1 -0
- package/dist/changes/eve-record-change.d.mts +56 -0
- package/dist/changes/eve-record-change.mjs +97 -0
- package/dist/changes/eve-record-change.mjs.map +1 -0
- package/dist/changes/presentation.d.mts +14 -0
- package/dist/changes.d.mts +23 -0
- package/dist/changes.mjs +29 -0
- package/dist/changes.mjs.map +1 -0
- package/dist/client-events.d.mts +18 -0
- package/dist/client-events.mjs +41 -0
- package/dist/client-events.mjs.map +1 -0
- package/dist/client-stream.d.mts +28 -0
- package/dist/client-stream.mjs +204 -0
- package/dist/client-stream.mjs.map +1 -0
- package/dist/client-transcript.d.mts +41 -0
- package/dist/client-transcript.mjs +229 -0
- package/dist/client-transcript.mjs.map +1 -0
- package/dist/client.d.mts +234 -0
- package/dist/client.mjs +258 -0
- package/dist/client.mjs.map +1 -0
- package/dist/code-review/contracts.d.mts +26 -0
- package/dist/code-review/eve-post-review.d.mts +70 -0
- package/dist/code-review/eve-post-review.mjs +183 -0
- package/dist/code-review/eve-post-review.mjs.map +1 -0
- package/dist/code-review/eve-review-comments.d.mts +64 -0
- package/dist/code-review/eve-review-comments.mjs +159 -0
- package/dist/code-review/eve-review-comments.mjs.map +1 -0
- package/dist/code-review/github-contracts.d.mts +10 -0
- package/dist/code-review/github-reporter.d.mts +44 -0
- package/dist/code-review/github-reporter.mjs +260 -0
- package/dist/code-review/github-reporter.mjs.map +1 -0
- package/dist/code-review/preparation.d.mts +34 -0
- package/dist/code-review/preparation.mjs +23 -0
- package/dist/code-review/preparation.mjs.map +1 -0
- package/dist/code-review/stall.d.mts +17 -0
- package/dist/code-review/stall.mjs +30 -0
- package/dist/code-review/stall.mjs.map +1 -0
- package/dist/code-review.d.mts +6 -0
- package/dist/code-review.mjs +5 -0
- package/dist/communication.d.mts +9 -0
- package/dist/communication.mjs +9 -0
- package/dist/connectors/github.d.mts +26 -0
- package/dist/connectors/github.mjs +55 -0
- package/dist/connectors/github.mjs.map +1 -0
- package/dist/connectors/index.d.mts +35 -3
- package/dist/connectors/index.mjs +3 -52
- package/dist/connectors/index.mjs.map +1 -1
- package/dist/connectors/outbox.d.mts +34 -0
- package/dist/connectors/outbox.mjs +50 -0
- package/dist/connectors/outbox.mjs.map +1 -0
- package/dist/connectors/slack-approval-blocks.mjs +136 -0
- package/dist/connectors/slack-approval-blocks.mjs.map +1 -0
- package/dist/connectors/slack-approvals.d.mts +29 -0
- package/dist/connectors/slack-approvals.mjs +346 -0
- package/dist/connectors/slack-approvals.mjs.map +1 -0
- package/dist/connectors/slack.d.mts +35 -52
- package/dist/connectors/slack.mjs +13 -85
- package/dist/connectors/slack.mjs.map +1 -1
- package/dist/deepsec/eve-tool.d.mts +110 -0
- package/dist/deepsec/eve-tool.mjs +164 -0
- package/dist/deepsec/eve-tool.mjs.map +1 -0
- package/dist/deepsec/finding.d.mts +84 -0
- package/dist/deepsec/finding.mjs +56 -0
- package/dist/deepsec/finding.mjs.map +1 -0
- package/dist/deepsec.d.mts +3 -0
- package/dist/delivery-metrics/metrics.d.mts +93 -0
- package/dist/delivery-metrics/metrics.mjs +200 -0
- package/dist/delivery-metrics/metrics.mjs.map +1 -0
- package/dist/delivery-metrics.d.mts +2 -0
- package/dist/delivery-metrics.mjs +2 -0
- package/dist/dispatch.d.mts +81 -0
- package/dist/dispatch.mjs +140 -0
- package/dist/dispatch.mjs.map +1 -0
- package/dist/errors.d.mts +15 -0
- package/dist/errors.mjs +38 -0
- package/dist/errors.mjs.map +1 -0
- package/dist/eve/index.d.mts +143 -1271
- package/dist/eve/index.mjs +233 -1065
- package/dist/eve/index.mjs.map +1 -1
- package/dist/eve/invoke.d.mts +144 -0
- package/dist/eve/invoke.mjs +241 -0
- package/dist/eve/invoke.mjs.map +1 -0
- package/dist/eve/session-client.d.mts +68 -0
- package/dist/eve/session-client.mjs +131 -0
- package/dist/eve/session-client.mjs.map +1 -0
- package/dist/eve/task-execution.mjs +18 -0
- package/dist/eve/task-execution.mjs.map +1 -0
- package/dist/eve/task-session.d.mts +87 -0
- package/dist/eve/task-session.mjs +203 -0
- package/dist/eve/task-session.mjs.map +1 -0
- package/dist/eve/transcript.d.mts +37 -0
- package/dist/eve/transcript.mjs +65 -0
- package/dist/eve/transcript.mjs.map +1 -0
- package/dist/execution-public.d.mts +8 -0
- package/dist/execution-public.mjs +7 -0
- package/dist/execution.d.mts +75 -0
- package/dist/execution.mjs +153 -0
- package/dist/execution.mjs.map +1 -0
- package/dist/finding-remediation/admission.d.mts +51 -0
- package/dist/finding-remediation/admission.mjs +87 -0
- package/dist/finding-remediation/admission.mjs.map +1 -0
- package/dist/finding-remediation/brief.d.mts +14 -0
- package/dist/finding-remediation/brief.mjs +25 -0
- package/dist/finding-remediation/brief.mjs.map +1 -0
- package/dist/finding-remediation/eve-tool.d.mts +29 -0
- package/dist/finding-remediation/eve-tool.mjs +34 -0
- package/dist/finding-remediation/eve-tool.mjs.map +1 -0
- package/dist/findings/fingerprint.d.mts +14 -0
- package/dist/findings/fingerprint.mjs +28 -0
- package/dist/findings/fingerprint.mjs.map +1 -0
- package/dist/findings.d.mts +6 -0
- package/dist/findings.mjs +6 -0
- package/dist/github-app.d.mts +54 -0
- package/dist/github-app.mjs +121 -0
- package/dist/github-app.mjs.map +1 -0
- package/dist/github-publication.d.mts +198 -0
- package/dist/github-publication.mjs +429 -0
- package/dist/github-publication.mjs.map +1 -0
- package/dist/github-transfer.d.mts +72 -0
- package/dist/github-transfer.mjs +125 -0
- package/dist/github-transfer.mjs.map +1 -0
- package/dist/github.d.mts +406 -2
- package/dist/github.mjs +239 -40
- package/dist/github.mjs.map +1 -1
- package/dist/image-input.d.mts +51 -0
- package/dist/image-input.mjs +63 -0
- package/dist/image-input.mjs.map +1 -0
- package/dist/index.d.mts +14 -484
- package/dist/index.mjs +14 -522
- package/dist/intake-contracts.d.mts +56 -0
- package/dist/intake-contracts.mjs +33 -0
- package/dist/intake-contracts.mjs.map +1 -0
- package/dist/integrations/deepsec.d.mts +4 -0
- package/dist/integrations/deepsec.mjs +3 -0
- package/dist/integrations/github.d.mts +11 -0
- package/dist/integrations/github.mjs +9 -0
- package/dist/integrations/slack.d.mts +3 -0
- package/dist/integrations/slack.mjs +3 -0
- package/dist/integrations/vercel.d.mts +3 -0
- package/dist/integrations/vercel.mjs +3 -0
- package/dist/merge-resolution/contracts.d.mts +17 -0
- package/dist/merge-resolution/contracts.mjs +19 -0
- package/dist/merge-resolution/contracts.mjs.map +1 -0
- package/dist/merge-resolution/eve-tools.d.mts +46 -0
- package/dist/merge-resolution/eve-tools.mjs +117 -0
- package/dist/merge-resolution/eve-tools.mjs.map +1 -0
- package/dist/multi-repository-changes/coordination.d.mts +49 -0
- package/dist/multi-repository-changes/coordination.mjs +115 -0
- package/dist/multi-repository-changes/coordination.mjs.map +1 -0
- package/dist/planning/cancellation.mjs +82 -0
- package/dist/planning/cancellation.mjs.map +1 -0
- package/dist/planning/configuration.d.mts +23 -0
- package/dist/planning/configuration.mjs +56 -0
- package/dist/planning/configuration.mjs.map +1 -0
- package/dist/planning/contracts.d.mts +136 -0
- package/dist/planning/contracts.mjs +42 -0
- package/dist/planning/contracts.mjs.map +1 -0
- package/dist/planning/dependencies.mjs +44 -0
- package/dist/planning/dependencies.mjs.map +1 -0
- package/dist/planning/effects.mjs +122 -0
- package/dist/planning/effects.mjs.map +1 -0
- package/dist/planning/reconcile.mjs +273 -0
- package/dist/planning/reconcile.mjs.map +1 -0
- package/dist/planning/runtime.d.mts +27 -0
- package/dist/planning/runtime.mjs +25 -0
- package/dist/planning/runtime.mjs.map +1 -0
- package/dist/planning/state.mjs +92 -0
- package/dist/planning/state.mjs.map +1 -0
- package/dist/planning/turns.mjs +262 -0
- package/dist/planning/turns.mjs.map +1 -0
- package/dist/planning/validation.mjs +106 -0
- package/dist/planning/validation.mjs.map +1 -0
- package/dist/postgres/index.d.mts +7 -1
- package/dist/postgres/index.mjs +7 -3
- package/dist/postgres/index.mjs.map +1 -1
- package/dist/presets/software-development/approval.d.mts +14 -0
- package/dist/presets/software-development/approval.mjs +21 -0
- package/dist/presets/software-development/approval.mjs.map +1 -0
- package/dist/presets/software-development/deepsec-brief.d.mts +8 -0
- package/dist/presets/software-development/deepsec-brief.mjs +14 -0
- package/dist/presets/software-development/deepsec-brief.mjs.map +1 -0
- package/dist/presets/software-development/dispatch.d.mts +53 -0
- package/dist/presets/software-development/dispatch.mjs +66 -0
- package/dist/presets/software-development/dispatch.mjs.map +1 -0
- package/dist/presets/software-development/eve-delegation-policy.d.mts +7 -0
- package/dist/presets/software-development/eve-delegation-policy.mjs +34 -0
- package/dist/presets/software-development/eve-delegation-policy.mjs.map +1 -0
- package/dist/presets/software-development/eve.d.mts +18 -0
- package/dist/presets/software-development/eve.mjs +19 -0
- package/dist/presets/software-development/eve.mjs.map +1 -0
- package/dist/presets/software-development/finish-task-policy.d.mts +7 -0
- package/dist/presets/software-development/finish-task-policy.mjs +9 -0
- package/dist/presets/software-development/finish-task-policy.mjs.map +1 -0
- package/dist/presets/software-development/recovery.d.mts +32 -0
- package/dist/presets/software-development/recovery.mjs +120 -0
- package/dist/presets/software-development/recovery.mjs.map +1 -0
- package/dist/presets/software-development/task-communication.d.mts +23 -0
- package/dist/presets/software-development/task-communication.mjs +120 -0
- package/dist/presets/software-development/task-communication.mjs.map +1 -0
- package/dist/presets/software-development.d.mts +9 -0
- package/dist/presets/software-development.mjs +9 -0
- package/dist/pull-requests/contracts.d.mts +72 -0
- package/dist/pull-requests/eve-fetch.d.mts +57 -0
- package/dist/pull-requests/eve-fetch.mjs +151 -0
- package/dist/pull-requests/eve-fetch.mjs.map +1 -0
- package/dist/pull-requests/github-label-manager.d.mts +27 -0
- package/dist/pull-requests/github-label-manager.mjs +40 -0
- package/dist/pull-requests/github-label-manager.mjs.map +1 -0
- package/dist/pull-requests/github-publisher.d.mts +53 -0
- package/dist/pull-requests/github-publisher.mjs +345 -0
- package/dist/pull-requests/github-publisher.mjs.map +1 -0
- package/dist/pull-requests.d.mts +5 -0
- package/dist/pull-requests.mjs +4 -0
- package/dist/receipts.d.mts +4 -0
- package/dist/receipts.mjs +3 -0
- package/dist/repositories.d.mts +18 -0
- package/dist/repositories.mjs +33 -0
- package/dist/repositories.mjs.map +1 -0
- package/dist/sandbox/command.d.mts +18 -0
- package/dist/sandbox/execution-abort.d.mts +16 -0
- package/dist/sandbox/execution-abort.mjs +49 -0
- package/dist/sandbox/execution-abort.mjs.map +1 -0
- package/dist/sandbox/execution-environment.d.mts +25 -0
- package/dist/sandbox/execution-run-ledger.d.mts +115 -0
- package/dist/sandbox/execution-run-ledger.mjs +209 -0
- package/dist/sandbox/execution-run-ledger.mjs.map +1 -0
- package/dist/sandbox/execution.d.mts +54 -0
- package/dist/sandbox/execution.mjs +228 -0
- package/dist/sandbox/execution.mjs.map +1 -0
- package/dist/sandbox/harness-runner.d.mts +79 -0
- package/dist/sandbox/harness-runner.mjs +162 -0
- package/dist/sandbox/harness-runner.mjs.map +1 -0
- package/dist/sandbox/index.d.mts +9 -0
- package/dist/sandbox/index.mjs +7 -0
- package/dist/sandbox/task-environment.d.mts +50 -0
- package/dist/sandbox/task-environment.mjs +140 -0
- package/dist/sandbox/task-environment.mjs.map +1 -0
- package/dist/sandbox/workspace.d.mts +29 -0
- package/dist/sandbox/workspace.mjs +28 -0
- package/dist/sandbox/workspace.mjs.map +1 -0
- package/dist/schema/agent-route.d.mts +22 -0
- package/dist/schema/agent-route.mjs +15 -0
- package/dist/schema/agent-route.mjs.map +1 -0
- package/dist/schema/answer.d.mts +23 -0
- package/dist/schema/answer.mjs +21 -0
- package/dist/schema/answer.mjs.map +1 -0
- package/dist/schema/budget.d.mts +38 -0
- package/dist/schema/budget.mjs +30 -0
- package/dist/schema/budget.mjs.map +1 -0
- package/dist/schema/catalog.mjs +72 -0
- package/dist/schema/catalog.mjs.map +1 -0
- package/dist/schema/change.d.mts +117 -0
- package/dist/schema/change.mjs +68 -0
- package/dist/schema/change.mjs.map +1 -0
- package/dist/schema/common.d.mts +33 -0
- package/dist/{id-BLIkCVue.mjs → schema/common.mjs} +7 -16
- package/dist/schema/common.mjs.map +1 -0
- package/dist/schema/communication.d.mts +52 -0
- package/dist/{communication-Kd9nU5RP.mjs → schema/communication.mjs} +8 -3
- package/dist/schema/communication.mjs.map +1 -0
- package/dist/schema/execution.d.mts +101 -0
- package/dist/schema/execution.mjs +86 -0
- package/dist/schema/execution.mjs.map +1 -0
- package/dist/schema/factory-config.d.mts +95 -0
- package/dist/schema/factory-config.mjs +60 -0
- package/dist/schema/factory-config.mjs.map +1 -0
- package/dist/schema/finding.d.mts +125 -0
- package/dist/schema/finding.mjs +67 -0
- package/dist/schema/finding.mjs.map +1 -0
- package/dist/schema/id.d.mts +43 -0
- package/dist/schema/id.mjs +32 -0
- package/dist/schema/id.mjs.map +1 -0
- package/dist/schema/outbox.d.mts +240 -0
- package/dist/schema/outbox.mjs +53 -0
- package/dist/schema/outbox.mjs.map +1 -0
- package/dist/schema/question-route.mjs +16 -0
- package/dist/schema/question-route.mjs.map +1 -0
- package/dist/schema/receipt.d.mts +81 -0
- package/dist/schema/receipt.mjs +94 -0
- package/dist/schema/receipt.mjs.map +1 -0
- package/dist/schema/repository.d.mts +26 -0
- package/dist/schema/repository.mjs +25 -0
- package/dist/schema/repository.mjs.map +1 -0
- package/dist/schema/session.d.mts +135 -0
- package/dist/schema/session.mjs +53 -0
- package/dist/schema/session.mjs.map +1 -0
- package/dist/schema/signal.d.mts +105 -0
- package/dist/schema/signal.mjs +81 -0
- package/dist/schema/signal.mjs.map +1 -0
- package/dist/schema/stored-session.mjs +10 -0
- package/dist/schema/stored-session.mjs.map +1 -0
- package/dist/schema/stored-task.mjs +20 -0
- package/dist/schema/stored-task.mjs.map +1 -0
- package/dist/schema/task-effect.d.mts +39 -0
- package/dist/schema/task-effect.mjs +29 -0
- package/dist/schema/task-effect.mjs.map +1 -0
- package/dist/schema/task-graph.d.mts +3134 -0
- package/dist/schema/task-graph.mjs +97 -0
- package/dist/schema/task-graph.mjs.map +1 -0
- package/dist/schema/task-message.d.mts +254 -0
- package/dist/schema/task-message.mjs +189 -0
- package/dist/schema/task-message.mjs.map +1 -0
- package/dist/schema/task.d.mts +272 -0
- package/dist/schema/task.mjs +199 -0
- package/dist/schema/task.mjs.map +1 -0
- package/dist/schema/transcript.d.mts +170 -0
- package/dist/schema/transcript.mjs +86 -0
- package/dist/schema/transcript.mjs.map +1 -0
- package/dist/schema/transitions.d.mts +50 -0
- package/dist/schema/transitions.mjs +303 -0
- package/dist/schema/transitions.mjs.map +1 -0
- package/dist/schema/work.d.mts +101 -0
- package/dist/schema/work.mjs +102 -0
- package/dist/schema/work.mjs.map +1 -0
- package/dist/signal-triage.d.mts +20 -0
- package/dist/signal-triage.mjs +85 -0
- package/dist/signal-triage.mjs.map +1 -0
- package/dist/signals.d.mts +19 -0
- package/dist/signals.mjs +19 -0
- package/dist/signals.mjs.map +1 -0
- package/dist/stall.d.mts +38 -0
- package/dist/stall.mjs +79 -0
- package/dist/stall.mjs.map +1 -0
- package/dist/storage.d.mts +4 -0
- package/dist/storage.mjs +4 -0
- package/dist/store/driver.d.mts +65 -0
- package/dist/store/driver.mjs +42 -0
- package/dist/store/driver.mjs.map +1 -0
- package/dist/store/engine.d.mts +485 -0
- package/dist/store/engine.mjs +2175 -0
- package/dist/store/engine.mjs.map +1 -0
- package/dist/store/memory.d.mts +7 -0
- package/dist/store/memory.mjs +52 -0
- package/dist/store/memory.mjs.map +1 -0
- package/dist/store/task-effects.d.mts +38 -0
- package/dist/store/task-effects.mjs +118 -0
- package/dist/store/task-effects.mjs.map +1 -0
- package/dist/store/task-graphs.d.mts +60 -0
- package/dist/store/task-graphs.mjs +212 -0
- package/dist/store/task-graphs.mjs.map +1 -0
- package/dist/store/task-messages.d.mts +136 -0
- package/dist/store/task-messages.mjs +475 -0
- package/dist/store/task-messages.mjs.map +1 -0
- package/dist/store/task-work.d.mts +65 -0
- package/dist/store/task-work.mjs +134 -0
- package/dist/store/task-work.mjs.map +1 -0
- package/dist/store/work-notifications.d.mts +19 -0
- package/dist/store/work-notifications.mjs +48 -0
- package/dist/store/work-notifications.mjs.map +1 -0
- package/dist/sweep.d.mts +57 -0
- package/dist/sweep.mjs +143 -0
- package/dist/sweep.mjs.map +1 -0
- package/dist/task-communication.d.mts +35 -0
- package/dist/task-communication.mjs +47 -0
- package/dist/task-communication.mjs.map +1 -0
- package/dist/task-graph-view.d.mts +264 -0
- package/dist/task-graph-view.mjs +17 -0
- package/dist/task-graph-view.mjs.map +1 -0
- package/dist/task-message-processing.d.mts +60 -0
- package/dist/task-message-processing.mjs +200 -0
- package/dist/task-message-processing.mjs.map +1 -0
- package/dist/task-protocols.d.mts +80 -0
- package/dist/task-protocols.mjs +47 -0
- package/dist/task-protocols.mjs.map +1 -0
- package/dist/tasks.d.mts +17 -0
- package/dist/tasks.mjs +17 -0
- package/dist/vercel-git.d.mts +21 -0
- package/dist/vercel-git.mjs +112 -0
- package/dist/vercel-git.mjs.map +1 -0
- package/dist/vercel.d.mts +33 -2
- package/dist/vercel.mjs +48 -3
- package/dist/vercel.mjs.map +1 -1
- package/dist/work-triage/eve-tool.d.mts +29 -0
- package/dist/work-triage/eve-tool.mjs +32 -0
- package/dist/work-triage/eve-tool.mjs.map +1 -0
- package/dist/work-triage/find-existing-work.d.mts +32 -0
- package/dist/work-triage/find-existing-work.mjs +31 -0
- package/dist/work-triage/find-existing-work.mjs.map +1 -0
- package/dist/work-triage/github.d.mts +15 -0
- package/dist/work-triage/github.mjs +14 -0
- package/dist/work-triage/github.mjs.map +1 -0
- package/dist/work-triage.d.mts +3 -0
- package/dist/work-triage.mjs +3 -0
- package/dist/workflows.d.mts +48 -0
- package/dist/workflows.mjs +86 -0
- package/dist/workflows.mjs.map +1 -0
- package/dist/workspace-diff-assembly.d.mts +33 -0
- package/dist/workspace-diff-assembly.mjs +95 -0
- package/dist/workspace-diff-assembly.mjs.map +1 -0
- package/dist/workspace-diff.d.mts +90 -0
- package/dist/workspace-diff.mjs +61 -0
- package/dist/workspace-diff.mjs.map +1 -0
- package/dist/workspace-snapshot.d.mts +26 -0
- package/dist/workspace-snapshot.mjs +80 -0
- package/dist/workspace-snapshot.mjs.map +1 -0
- package/package.json +129 -44
- package/dist/approval-JX2Px9IC.mjs +0 -132
- package/dist/approval-JX2Px9IC.mjs.map +0 -1
- package/dist/budget-DzSiIA4t.mjs +0 -42
- package/dist/budget-DzSiIA4t.mjs.map +0 -1
- package/dist/change-D2U6v7Ek.mjs +0 -554
- package/dist/change-D2U6v7Ek.mjs.map +0 -1
- package/dist/communication-Kd9nU5RP.mjs.map +0 -1
- package/dist/coordination-Cq08hb1l.mjs +0 -76
- package/dist/coordination-Cq08hb1l.mjs.map +0 -1
- package/dist/dispatch-BaZS3PT8.d.mts +0 -76
- package/dist/driver-BC0Mt5KG.d.mts +0 -34
- package/dist/driver-Bbd25rNM.mjs +0 -23
- package/dist/driver-Bbd25rNM.mjs.map +0 -1
- package/dist/engine-DFHU2Pe-.d.mts +0 -781
- package/dist/engine-WaUM2cGA.mjs +0 -1068
- package/dist/engine-WaUM2cGA.mjs.map +0 -1
- package/dist/factory-config-BoRXOw43.mjs +0 -50
- package/dist/factory-config-BoRXOw43.mjs.map +0 -1
- package/dist/factory-config-D2yU3G0c.d.mts +0 -58
- package/dist/github-C5HNBN6p.d.mts +0 -279
- package/dist/id-BLIkCVue.mjs.map +0 -1
- package/dist/index-Bw6hggoH.d.mts +0 -40
- package/dist/index.mjs.map +0 -1
- package/dist/task-CcOyOJ3k.mjs +0 -154
- package/dist/task-CcOyOJ3k.mjs.map +0 -1
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
import { routeKey } from "../agent-routes.mjs";
|
|
2
|
+
import { BudgetExhaustedError, DispatchRefusedError, dispatchTask } from "../dispatch.mjs";
|
|
3
|
+
import { taskMessageIdSchema } from "../schema/task-message.mjs";
|
|
4
|
+
import { TaskMessageSourceFenceError } from "../store/task-messages.mjs";
|
|
5
|
+
import { handoffPayloadSchema, handoffTaskMessageProtocol } from "../task-protocols.mjs";
|
|
6
|
+
import { plannerCancellationBatch } from "./cancellation.mjs";
|
|
7
|
+
import { runtimePrincipal, terminal } from "./state.mjs";
|
|
8
|
+
import { cancelDescendants } from "./effects.mjs";
|
|
9
|
+
import { cancelBlockedPlannerChildren } from "./dependencies.mjs";
|
|
10
|
+
import { createHash } from "node:crypto";
|
|
11
|
+
//#region src/planning/reconcile.ts
|
|
12
|
+
const MAX_MESSAGES = 32;
|
|
13
|
+
const TURN_TIMEOUT_MS = 9e5;
|
|
14
|
+
function plannerReconciler(options, config, state, turns) {
|
|
15
|
+
const { stores } = options;
|
|
16
|
+
return async (snapshot) => {
|
|
17
|
+
const result = {
|
|
18
|
+
queued: [],
|
|
19
|
+
dispatched: [],
|
|
20
|
+
delivered: 0,
|
|
21
|
+
recovered: 0,
|
|
22
|
+
discarded: 0,
|
|
23
|
+
cancelled: [],
|
|
24
|
+
failed: [],
|
|
25
|
+
errors: []
|
|
26
|
+
};
|
|
27
|
+
const rows = new Map((snapshot ?? await stores.tasks.list()).map((task) => [task.id, task]));
|
|
28
|
+
const errors = (taskId, error) => result.errors.push({
|
|
29
|
+
taskId,
|
|
30
|
+
message: (error instanceof Error ? error.message : String(error)).slice(0, 1e3)
|
|
31
|
+
});
|
|
32
|
+
const roots = new Set([...rows.values()].filter(config.isPlanner).map((task) => task.rootTaskId));
|
|
33
|
+
for (const root of roots) try {
|
|
34
|
+
for (const task of await stores.work.recover(root)) rows.set(task.id, task);
|
|
35
|
+
} catch (error) {
|
|
36
|
+
errors(root, error);
|
|
37
|
+
}
|
|
38
|
+
const cancellations = plannerCancellationBatch(options);
|
|
39
|
+
for (const root of roots) try {
|
|
40
|
+
for (const task of await cancelBlockedPlannerChildren(options, config, root)) {
|
|
41
|
+
rows.set(task.id, task);
|
|
42
|
+
result.cancelled.push(task.id);
|
|
43
|
+
}
|
|
44
|
+
} catch (error) {
|
|
45
|
+
errors(root, error);
|
|
46
|
+
}
|
|
47
|
+
const planners = [...rows.values()].filter(config.isPlanner);
|
|
48
|
+
for (const planner of planners) try {
|
|
49
|
+
const current = await state.task(planner.id);
|
|
50
|
+
if (current.state !== "cancelled" && current.state !== "failed") continue;
|
|
51
|
+
result.cancelled.push(...await cancelDescendants(options, current, cancellations));
|
|
52
|
+
} catch (error) {
|
|
53
|
+
errors(planner.id, error);
|
|
54
|
+
}
|
|
55
|
+
for (const candidate of rows.values()) {
|
|
56
|
+
const parent = candidate.parentTaskId ? rows.get(candidate.parentTaskId) : void 0;
|
|
57
|
+
if (!parent || !config.isPlanner(parent)) continue;
|
|
58
|
+
try {
|
|
59
|
+
const current = await stores.tasks.get(candidate.id);
|
|
60
|
+
if (current) await cancellations.stop(current);
|
|
61
|
+
} catch (error) {
|
|
62
|
+
errors(candidate.id, error);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
let deliveryAttempts = 0;
|
|
66
|
+
for (const candidate of rows.values()) {
|
|
67
|
+
if (deliveryAttempts >= MAX_MESSAGES) break;
|
|
68
|
+
if (!candidate.parentTaskId || !candidate.work.route || !config.allowed.has(routeKey(candidate.work.route))) continue;
|
|
69
|
+
try {
|
|
70
|
+
const child = await stores.tasks.get(candidate.id);
|
|
71
|
+
if (!child || !terminal(child) || child.question) continue;
|
|
72
|
+
const parent = await stores.tasks.get(candidate.parentTaskId);
|
|
73
|
+
if (!parent || !config.isPlanner(parent) || ![
|
|
74
|
+
"queued",
|
|
75
|
+
"running",
|
|
76
|
+
"needs_human"
|
|
77
|
+
].includes(parent.state)) continue;
|
|
78
|
+
await state.authority(parent);
|
|
79
|
+
const operationId = `result:${child.id}:${child.attempt}:${child.state}`;
|
|
80
|
+
const id = taskMessageIdSchema.parse(`msg_${createHash("sha256").update(JSON.stringify([child.id, operationId])).digest("hex")}`);
|
|
81
|
+
if (await stores.messages.get({
|
|
82
|
+
principal: runtimePrincipal,
|
|
83
|
+
toTaskId: parent.id,
|
|
84
|
+
messageId: id
|
|
85
|
+
})) continue;
|
|
86
|
+
const output = child.workResult?.output;
|
|
87
|
+
const includeOutput = output !== void 0 && Buffer.byteLength(JSON.stringify(output), "utf8") <= 48e3;
|
|
88
|
+
const payload = handoffPayloadSchema.parse({
|
|
89
|
+
outcome: child.state === "succeeded" ? "completed" : "failed",
|
|
90
|
+
summary: `${child.work.title}: ${child.state}`.slice(0, 1e3),
|
|
91
|
+
...includeOutput ? { output } : {},
|
|
92
|
+
artifacts: [],
|
|
93
|
+
concerns: includeOutput || output === void 0 ? [] : ["Output omitted from handoff; read canonical Task workResult."],
|
|
94
|
+
deviations: []
|
|
95
|
+
});
|
|
96
|
+
deliveryAttempts++;
|
|
97
|
+
await stores.messages.sendResult({
|
|
98
|
+
principal: runtimePrincipal,
|
|
99
|
+
message: {
|
|
100
|
+
operationId,
|
|
101
|
+
fromTaskId: child.id,
|
|
102
|
+
toTaskId: parent.id,
|
|
103
|
+
expectAttempt: child.attempt,
|
|
104
|
+
type: handoffTaskMessageProtocol.binding,
|
|
105
|
+
payload
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
result.delivered++;
|
|
109
|
+
} catch (error) {
|
|
110
|
+
errors(candidate.id, error);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
let processed = 0;
|
|
114
|
+
let launchAttempted = false;
|
|
115
|
+
for (const planner of planners) try {
|
|
116
|
+
let current = await state.task(planner.id);
|
|
117
|
+
let recoveryLeased = false;
|
|
118
|
+
while (processed < MAX_MESSAGES) {
|
|
119
|
+
const head = (await stores.messages.pending({
|
|
120
|
+
principal: runtimePrincipal,
|
|
121
|
+
toTaskId: current.id
|
|
122
|
+
}))[0];
|
|
123
|
+
if (!head) break;
|
|
124
|
+
if (head.type.id !== "planner-start") {
|
|
125
|
+
const source = await stores.tasks.get(head.fromTaskId);
|
|
126
|
+
if (!source || source.attempt !== head.expectAttempt || source.state === "cancelled" && head.delivery !== "result") {
|
|
127
|
+
await stores.messages.discard({
|
|
128
|
+
principal: runtimePrincipal,
|
|
129
|
+
toTaskId: current.id,
|
|
130
|
+
messageId: head.id,
|
|
131
|
+
reason: "Source attempt changed or was cancelled; await canonical result delivery"
|
|
132
|
+
});
|
|
133
|
+
result.discarded++;
|
|
134
|
+
processed++;
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
const decision = current.state === "cancelled" ? null : await turns.recorded(current, head.id);
|
|
139
|
+
if (terminal(current) && (!decision || current.state === "cancelled")) {
|
|
140
|
+
await stores.messages.discard({
|
|
141
|
+
principal: runtimePrincipal,
|
|
142
|
+
toTaskId: current.id,
|
|
143
|
+
messageId: head.id,
|
|
144
|
+
reason: `Planner ${current.state}; no replayable committed decision`
|
|
145
|
+
});
|
|
146
|
+
result.discarded++;
|
|
147
|
+
processed++;
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
if (!decision || ![
|
|
151
|
+
"running",
|
|
152
|
+
"succeeded",
|
|
153
|
+
"failed"
|
|
154
|
+
].includes(current.state)) break;
|
|
155
|
+
try {
|
|
156
|
+
if (current.state === "running") await turns.prepare({
|
|
157
|
+
taskId: current.id,
|
|
158
|
+
attempt: current.attempt
|
|
159
|
+
});
|
|
160
|
+
if ((await turns.process(current, head.id, void 0, cancellations)).status === "idle") {
|
|
161
|
+
recoveryLeased = true;
|
|
162
|
+
break;
|
|
163
|
+
}
|
|
164
|
+
result.recovered++;
|
|
165
|
+
processed++;
|
|
166
|
+
current = await state.task(current.id);
|
|
167
|
+
} catch (error) {
|
|
168
|
+
if (!(error instanceof TaskMessageSourceFenceError)) throw error;
|
|
169
|
+
await stores.messages.discard({
|
|
170
|
+
principal: runtimePrincipal,
|
|
171
|
+
toTaskId: current.id,
|
|
172
|
+
messageId: head.id,
|
|
173
|
+
reason: "Source attempt changed; discard stale result and await canonical delivery"
|
|
174
|
+
});
|
|
175
|
+
result.discarded++;
|
|
176
|
+
processed++;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
current = await state.task(current.id);
|
|
180
|
+
if (terminal(current) || current.state === "needs_human" || recoveryLeased) continue;
|
|
181
|
+
if (current.attempt > config.limits.maxTurns && [
|
|
182
|
+
"queued",
|
|
183
|
+
"running",
|
|
184
|
+
"stalled"
|
|
185
|
+
].includes(current.state)) {
|
|
186
|
+
await stores.tasks.transition(current.id, "failed", {
|
|
187
|
+
expectFrom: current.state,
|
|
188
|
+
expectAttempt: current.attempt,
|
|
189
|
+
reason: "Planner maxTurns exhausted"
|
|
190
|
+
});
|
|
191
|
+
result.failed.push(current.id);
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
await state.authority(current);
|
|
195
|
+
const activation = (await state.activation(current.id))?.value;
|
|
196
|
+
if (current.state === "running") {
|
|
197
|
+
const active = activation?.attempt === current.attempt ? activation : void 0;
|
|
198
|
+
const since = Math.max(Date.parse(active?.startedAt ?? current.updatedAt), Date.parse(current.lastProgressAt ?? current.updatedAt));
|
|
199
|
+
const expired = Date.parse(state.now()) - since >= TURN_TIMEOUT_MS;
|
|
200
|
+
const handoff = (await stores.messages.pending({
|
|
201
|
+
principal: runtimePrincipal,
|
|
202
|
+
toTaskId: current.id
|
|
203
|
+
})).some((message) => message.type.id === "handoff" && message.type.version === 1);
|
|
204
|
+
const unsubmitted = active && !await turns.recorded(current, active.triggerId);
|
|
205
|
+
if (active?.finished && (handoff || unsubmitted) || !active?.finished && expired) {
|
|
206
|
+
if (!active?.finished && !current.waitingForMessages) current = await stores.tasks.transition(current.id, "stalled", {
|
|
207
|
+
expectFrom: "running",
|
|
208
|
+
expectAttempt: current.attempt,
|
|
209
|
+
reason: "Planner turn or finished hook timed out",
|
|
210
|
+
phase: "workflow"
|
|
211
|
+
});
|
|
212
|
+
else current = await replace(current);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
if (current.state === "stalled") current = await replace(current);
|
|
216
|
+
if (current.state !== "queued") continue;
|
|
217
|
+
if (current.attempt > config.limits.maxTurns) {
|
|
218
|
+
await stores.tasks.transition(current.id, "failed", {
|
|
219
|
+
expectFrom: "queued",
|
|
220
|
+
expectAttempt: current.attempt,
|
|
221
|
+
reason: "Planner maxTurns exhausted"
|
|
222
|
+
});
|
|
223
|
+
result.failed.push(current.id);
|
|
224
|
+
continue;
|
|
225
|
+
}
|
|
226
|
+
if (launchAttempted || current.approval === "required" || current.approval === "denied" || !await stores.graphs.dependenciesSatisfied({
|
|
227
|
+
rootTaskId: current.rootTaskId,
|
|
228
|
+
taskId: current.id
|
|
229
|
+
})) continue;
|
|
230
|
+
launchAttempted = true;
|
|
231
|
+
const launched = await dispatchTask(stores, {
|
|
232
|
+
taskId: current.id,
|
|
233
|
+
route: config.plannerRoute,
|
|
234
|
+
maxLaunchAttempts: config.limits.maxTurns,
|
|
235
|
+
...options.budget ? { budget: options.budget } : {},
|
|
236
|
+
async launch(running) {
|
|
237
|
+
await state.authority(running);
|
|
238
|
+
const prepared = await turns.prepare({
|
|
239
|
+
taskId: running.id,
|
|
240
|
+
attempt: running.attempt
|
|
241
|
+
});
|
|
242
|
+
await state.authority(running);
|
|
243
|
+
return options.launchPlanner(running, prepared.prompt);
|
|
244
|
+
}
|
|
245
|
+
});
|
|
246
|
+
rows.set(launched.id, launched);
|
|
247
|
+
result.dispatched.push(launched.id);
|
|
248
|
+
} catch (error) {
|
|
249
|
+
if (error instanceof BudgetExhaustedError) result.failed.push(planner.id);
|
|
250
|
+
if (!(error instanceof DispatchRefusedError)) errors(planner.id, error);
|
|
251
|
+
}
|
|
252
|
+
result.errors.push(...cancellations.errors);
|
|
253
|
+
result.cancellationPending = [...cancellations.pending];
|
|
254
|
+
return result;
|
|
255
|
+
async function replace(task) {
|
|
256
|
+
const exhausted = task.attempt >= config.limits.maxTurns;
|
|
257
|
+
const next = await stores.tasks.transition(task.id, exhausted ? "failed" : "queued", {
|
|
258
|
+
expectFrom: task.state,
|
|
259
|
+
expectAttempt: task.attempt,
|
|
260
|
+
phase: "workflow",
|
|
261
|
+
reason: exhausted ? "Planner maxTurns exhausted" : "Fresh planner activation after finished turn or timeout"
|
|
262
|
+
});
|
|
263
|
+
if (exhausted) result.failed.push(task.id);
|
|
264
|
+
else result.queued.push(task.id);
|
|
265
|
+
rows.set(next.id, next);
|
|
266
|
+
return next;
|
|
267
|
+
}
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
//#endregion
|
|
271
|
+
export { plannerReconciler };
|
|
272
|
+
|
|
273
|
+
//# sourceMappingURL=reconcile.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reconcile.mjs","names":[],"sources":["../../src/planning/reconcile.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { routeKey } from \"../agent-routes\";\nimport { BudgetExhaustedError, dispatchTask, DispatchRefusedError } from \"../dispatch\";\nimport type { TaskId } from \"../schema/id\";\nimport type { Task } from \"../schema/task\";\nimport { taskMessageIdSchema } from \"../schema/task-message\";\nimport { TaskMessageSourceFenceError } from \"../store/task-messages\";\nimport { handoffPayloadSchema, handoffTaskMessageProtocol } from \"../task-protocols\";\nimport type { PlannerConfiguration } from \"./configuration\";\nimport type { PlannerReconcileResult, PlannerRuntimeOptions } from \"./contracts\";\nimport { cancelDescendants } from \"./effects\";\nimport { plannerCancellationBatch } from \"./cancellation\";\nimport { cancelBlockedPlannerChildren } from \"./dependencies\";\nimport { runtimePrincipal, terminal, type PlannerState } from \"./state\";\nimport type { PlannerTurns } from \"./turns\";\n\nconst MAX_MESSAGES = 32;\nconst TURN_TIMEOUT_MS = 15 * 60_000;\nexport function plannerReconciler(\n options: PlannerRuntimeOptions,\n config: PlannerConfiguration,\n state: PlannerState,\n turns: PlannerTurns,\n) {\n const { stores } = options;\n return async (snapshot?: readonly Task[]): Promise<PlannerReconcileResult> => {\n const result: {\n queued: TaskId[];\n dispatched: TaskId[];\n delivered: number;\n recovered: number;\n discarded: number;\n cancelled: TaskId[];\n cancellationPending?: TaskId[];\n failed: TaskId[];\n errors: { taskId: TaskId; message: string }[];\n } = {\n queued: [],\n dispatched: [],\n delivered: 0,\n recovered: 0,\n discarded: 0,\n cancelled: [],\n failed: [],\n errors: [],\n };\n const rows = new Map((snapshot ?? (await stores.tasks.list())).map((task) => [task.id, task]));\n const errors = (taskId: TaskId, error: unknown) =>\n result.errors.push({\n taskId,\n message: (error instanceof Error ? error.message : String(error)).slice(0, 1000),\n });\n const roots = new Set(\n [...rows.values()].filter(config.isPlanner).map((task) => task.rootTaskId),\n );\n for (const root of roots) {\n try {\n for (const task of await stores.work.recover(root)) rows.set(task.id, task);\n } catch (error) {\n errors(root, error);\n }\n }\n const cancellations = plannerCancellationBatch(options);\n for (const root of roots) {\n try {\n for (const task of await cancelBlockedPlannerChildren(options, config, root)) {\n rows.set(task.id, task);\n result.cancelled.push(task.id);\n }\n } catch (error) {\n errors(root, error);\n }\n }\n const planners = [...rows.values()].filter(config.isPlanner);\n for (const planner of planners) {\n try {\n const current = await state.task(planner.id);\n if (current.state !== \"cancelled\" && current.state !== \"failed\") continue;\n result.cancelled.push(...(await cancelDescendants(options, current, cancellations)));\n } catch (error) {\n errors(planner.id, error);\n }\n }\n for (const candidate of rows.values()) {\n const parent = candidate.parentTaskId ? rows.get(candidate.parentTaskId) : undefined;\n if (!parent || !config.isPlanner(parent)) continue;\n try {\n const current = await stores.tasks.get(candidate.id);\n if (current) await cancellations.stop(current);\n } catch (error) {\n errors(candidate.id, error);\n }\n }\n let deliveryAttempts = 0;\n for (const candidate of rows.values()) {\n if (deliveryAttempts >= MAX_MESSAGES) break;\n if (\n !candidate.parentTaskId ||\n !candidate.work.route ||\n !config.allowed.has(routeKey(candidate.work.route))\n )\n continue;\n try {\n const child = await stores.tasks.get(candidate.id);\n if (!child || !terminal(child) || child.question) continue;\n const parent = await stores.tasks.get(candidate.parentTaskId);\n if (\n !parent ||\n !config.isPlanner(parent) ||\n ![\"queued\", \"running\", \"needs_human\"].includes(parent.state)\n )\n continue;\n await state.authority(parent);\n const operationId = `result:${child.id}:${child.attempt}:${child.state}`;\n const id = taskMessageIdSchema.parse(\n `msg_${createHash(\"sha256\")\n .update(JSON.stringify([child.id, operationId]))\n .digest(\"hex\")}`,\n );\n if (\n await stores.messages.get({\n principal: runtimePrincipal,\n toTaskId: parent.id,\n messageId: id,\n })\n )\n continue;\n const output = child.workResult?.output;\n // The envelope shares the 64 KiB JSON bound with its output; large results stay on the canonical Task.\n const includeOutput =\n output !== undefined && Buffer.byteLength(JSON.stringify(output), \"utf8\") <= 48_000;\n const payload = handoffPayloadSchema.parse({\n outcome: child.state === \"succeeded\" ? \"completed\" : \"failed\",\n summary: `${child.work.title}: ${child.state}`.slice(0, 1000),\n ...(includeOutput ? { output } : {}),\n artifacts: [],\n concerns:\n includeOutput || output === undefined\n ? []\n : [\"Output omitted from handoff; read canonical Task workResult.\"],\n deviations: [],\n });\n deliveryAttempts++;\n await stores.messages.sendResult({\n principal: runtimePrincipal,\n message: {\n operationId,\n fromTaskId: child.id,\n toTaskId: parent.id,\n expectAttempt: child.attempt,\n type: handoffTaskMessageProtocol.binding,\n payload,\n },\n });\n result.delivered++;\n } catch (error) {\n errors(candidate.id, error);\n }\n }\n let processed = 0;\n let launchAttempted = false;\n for (const planner of planners) {\n try {\n let current = await state.task(planner.id);\n let recoveryLeased = false;\n while (processed < MAX_MESSAGES) {\n const head = (\n await stores.messages.pending({\n principal: runtimePrincipal,\n toTaskId: current.id,\n })\n )[0];\n if (!head) break;\n if (head.type.id !== \"planner-start\") {\n const source = await stores.tasks.get(head.fromTaskId);\n if (\n !source ||\n source.attempt !== head.expectAttempt ||\n (source.state === \"cancelled\" && head.delivery !== \"result\")\n ) {\n await stores.messages.discard({\n principal: runtimePrincipal,\n toTaskId: current.id,\n messageId: head.id,\n reason: \"Source attempt changed or was cancelled; await canonical result delivery\",\n });\n result.discarded++;\n processed++;\n continue;\n }\n }\n const decision =\n current.state === \"cancelled\" ? null : await turns.recorded(current, head.id);\n if (terminal(current) && (!decision || current.state === \"cancelled\")) {\n await stores.messages.discard({\n principal: runtimePrincipal,\n toTaskId: current.id,\n messageId: head.id,\n reason: `Planner ${current.state}; no replayable committed decision`,\n });\n result.discarded++;\n processed++;\n continue;\n }\n if (!decision || ![\"running\", \"succeeded\", \"failed\"].includes(current.state)) break;\n try {\n if (current.state === \"running\")\n await turns.prepare({ taskId: current.id, attempt: current.attempt });\n const recovered = await turns.process(current, head.id, undefined, cancellations);\n if (recovered.status === \"idle\") {\n recoveryLeased = true;\n break;\n }\n result.recovered++;\n processed++;\n current = await state.task(current.id);\n } catch (error) {\n if (!(error instanceof TaskMessageSourceFenceError)) throw error;\n await stores.messages.discard({\n principal: runtimePrincipal,\n toTaskId: current.id,\n messageId: head.id,\n reason: \"Source attempt changed; discard stale result and await canonical delivery\",\n });\n result.discarded++;\n processed++;\n }\n }\n current = await state.task(current.id);\n if (terminal(current) || current.state === \"needs_human\" || recoveryLeased) continue;\n if (\n current.attempt > config.limits.maxTurns &&\n [\"queued\", \"running\", \"stalled\"].includes(current.state)\n ) {\n await stores.tasks.transition(current.id, \"failed\", {\n expectFrom: current.state,\n expectAttempt: current.attempt,\n reason: \"Planner maxTurns exhausted\",\n });\n result.failed.push(current.id);\n continue;\n }\n await state.authority(current);\n const activation = (await state.activation(current.id))?.value;\n if (current.state === \"running\") {\n const active = activation?.attempt === current.attempt ? activation : undefined;\n const since = Math.max(\n Date.parse(active?.startedAt ?? current.updatedAt),\n Date.parse(current.lastProgressAt ?? current.updatedAt),\n );\n const expired = Date.parse(state.now()) - since >= TURN_TIMEOUT_MS;\n const pending = await stores.messages.pending({\n principal: runtimePrincipal,\n toTaskId: current.id,\n });\n const handoff = pending.some(\n (message) => message.type.id === \"handoff\" && message.type.version === 1,\n );\n const unsubmitted = active && !(await turns.recorded(current, active.triggerId));\n if ((active?.finished && (handoff || unsubmitted)) || (!active?.finished && expired)) {\n if (!active?.finished && !current.waitingForMessages) {\n current = await stores.tasks.transition(current.id, \"stalled\", {\n expectFrom: \"running\",\n expectAttempt: current.attempt,\n reason: \"Planner turn or finished hook timed out\",\n phase: \"workflow\",\n });\n } else {\n current = await replace(current);\n }\n }\n }\n if (current.state === \"stalled\") current = await replace(current);\n if (current.state !== \"queued\") continue;\n if (current.attempt > config.limits.maxTurns) {\n await stores.tasks.transition(current.id, \"failed\", {\n expectFrom: \"queued\",\n expectAttempt: current.attempt,\n reason: \"Planner maxTurns exhausted\",\n });\n result.failed.push(current.id);\n continue;\n }\n if (\n launchAttempted ||\n current.approval === \"required\" ||\n current.approval === \"denied\" ||\n !(await stores.graphs.dependenciesSatisfied({\n rootTaskId: current.rootTaskId,\n taskId: current.id,\n }))\n )\n continue;\n launchAttempted = true;\n const launched = await dispatchTask(stores, {\n taskId: current.id,\n route: config.plannerRoute,\n maxLaunchAttempts: config.limits.maxTurns,\n ...(options.budget ? { budget: options.budget } : {}),\n async launch(running) {\n await state.authority(running);\n const prepared = await turns.prepare({ taskId: running.id, attempt: running.attempt });\n await state.authority(running);\n return options.launchPlanner(running, prepared.prompt);\n },\n });\n rows.set(launched.id, launched);\n result.dispatched.push(launched.id);\n } catch (error) {\n if (error instanceof BudgetExhaustedError) result.failed.push(planner.id);\n if (!(error instanceof DispatchRefusedError)) errors(planner.id, error);\n }\n }\n result.errors.push(...cancellations.errors);\n result.cancellationPending = [...cancellations.pending];\n return result;\n\n async function replace(task: Task): Promise<Task> {\n const exhausted = task.attempt >= config.limits.maxTurns;\n const next = await stores.tasks.transition(task.id, exhausted ? \"failed\" : \"queued\", {\n expectFrom: task.state,\n expectAttempt: task.attempt,\n phase: \"workflow\",\n reason: exhausted\n ? \"Planner maxTurns exhausted\"\n : \"Fresh planner activation after finished turn or timeout\",\n });\n if (exhausted) result.failed.push(task.id);\n else result.queued.push(task.id);\n rows.set(next.id, next);\n return next;\n }\n };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Task } from "../schema/task.mjs";
|
|
2
|
+
import { TaskMessageId } from "../schema/task-message.mjs";
|
|
3
|
+
import { TaskAttemptRef } from "../schema/execution.mjs";
|
|
4
|
+
import { PlannerContext, PlannerDecision, PlannerLimits, PlannerPrepareResult, PlannerReconcileResult, PlannerRuntimeOptions, PlannerStores, PlannerSubmitResult, plannerDecisionSchema } from "./contracts.mjs";
|
|
5
|
+
import { PlannerMessageProtocols, createPlannerMessagePolicy, createPlannerMessageProtocols } from "./configuration.mjs";
|
|
6
|
+
//#region src/planning/runtime.d.ts
|
|
7
|
+
/** Identifies one proposed decision for the active turn of an exact Task attempt. */
|
|
8
|
+
interface PlannerSubmitInput {
|
|
9
|
+
readonly task: TaskAttemptRef;
|
|
10
|
+
readonly triggerId: TaskMessageId;
|
|
11
|
+
readonly proposed: unknown;
|
|
12
|
+
}
|
|
13
|
+
/** Operations exposed by the bounded durable planner runtime. */
|
|
14
|
+
interface PlannerRuntime {
|
|
15
|
+
prepare(task: TaskAttemptRef): Promise<PlannerPrepareResult>;
|
|
16
|
+
context(task: TaskAttemptRef): Promise<PlannerContext>;
|
|
17
|
+
submit(input: PlannerSubmitInput): Promise<PlannerSubmitResult>;
|
|
18
|
+
turnFinished(task: TaskAttemptRef): Promise<void>;
|
|
19
|
+
reconcile(snapshot?: readonly Task[]): Promise<PlannerReconcileResult>;
|
|
20
|
+
isPlanner(task: Task): boolean;
|
|
21
|
+
readonly limits: PlannerLimits;
|
|
22
|
+
}
|
|
23
|
+
/** Trusted workflow runtime. Transport tools must supply authenticated Task ID/attempt, never model principals. */
|
|
24
|
+
declare function createPlannerRuntime(options: PlannerRuntimeOptions): PlannerRuntime;
|
|
25
|
+
//#endregion
|
|
26
|
+
export { type PlannerContext, type PlannerDecision, type PlannerLimits, type PlannerMessageProtocols, type PlannerPrepareResult, type PlannerReconcileResult, PlannerRuntime, type PlannerRuntimeOptions, type PlannerStores, PlannerSubmitInput, type PlannerSubmitResult, createPlannerMessagePolicy, createPlannerMessageProtocols, createPlannerRuntime, plannerDecisionSchema };
|
|
27
|
+
//# sourceMappingURL=runtime.d.mts.map
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { createPlannerMessagePolicy, createPlannerMessageProtocols, plannerConfiguration } from "./configuration.mjs";
|
|
2
|
+
import { plannerState } from "./state.mjs";
|
|
3
|
+
import { plannerReconciler } from "./reconcile.mjs";
|
|
4
|
+
import { plannerDecisionSchema } from "./contracts.mjs";
|
|
5
|
+
import { plannerTurns } from "./turns.mjs";
|
|
6
|
+
//#region src/planning/runtime.ts
|
|
7
|
+
/** Trusted workflow runtime. Transport tools must supply authenticated Task ID/attempt, never model principals. */
|
|
8
|
+
function createPlannerRuntime(options) {
|
|
9
|
+
const config = plannerConfiguration(options);
|
|
10
|
+
const state = plannerState(options, config);
|
|
11
|
+
const turns = plannerTurns(options, config, state);
|
|
12
|
+
return Object.freeze({
|
|
13
|
+
prepare: turns.prepare,
|
|
14
|
+
context: turns.context,
|
|
15
|
+
submit: ({ task, triggerId, proposed }) => turns.submit(task, triggerId, proposed),
|
|
16
|
+
turnFinished: turns.turnFinished,
|
|
17
|
+
reconcile: plannerReconciler(options, config, state, turns),
|
|
18
|
+
isPlanner: config.isPlanner,
|
|
19
|
+
limits: config.limits
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
//#endregion
|
|
23
|
+
export { createPlannerMessagePolicy, createPlannerMessageProtocols, createPlannerRuntime, plannerDecisionSchema };
|
|
24
|
+
|
|
25
|
+
//# sourceMappingURL=runtime.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.mjs","names":[],"sources":["../../src/planning/runtime.ts"],"sourcesContent":["import { plannerConfiguration } from \"./configuration\";\nimport type { PlannerRuntimeOptions } from \"./contracts\";\nimport { plannerReconciler } from \"./reconcile\";\nimport { plannerState } from \"./state\";\nimport { plannerTurns } from \"./turns\";\nimport type {\n PlannerContext,\n PlannerPrepareResult,\n PlannerReconcileResult,\n PlannerSubmitResult,\n} from \"./contracts\";\nimport type { TaskAttemptRef } from \"../schema/execution\";\nimport type { TaskMessageId } from \"../schema/task-message\";\n\nexport { plannerDecisionSchema } from \"./contracts\";\nexport type {\n PlannerContext,\n PlannerDecision,\n PlannerLimits,\n PlannerPrepareResult,\n PlannerReconcileResult,\n PlannerRuntimeOptions,\n PlannerStores,\n PlannerSubmitResult,\n} from \"./contracts\";\nexport { createPlannerMessagePolicy, createPlannerMessageProtocols } from \"./configuration\";\nexport type { PlannerMessageProtocols } from \"./configuration\";\n\n/** Identifies one proposed decision for the active turn of an exact Task attempt. */\nexport interface PlannerSubmitInput {\n readonly task: TaskAttemptRef;\n readonly triggerId: TaskMessageId;\n readonly proposed: unknown;\n}\n\n/** Operations exposed by the bounded durable planner runtime. */\nexport interface PlannerRuntime {\n prepare(task: TaskAttemptRef): Promise<PlannerPrepareResult>;\n context(task: TaskAttemptRef): Promise<PlannerContext>;\n submit(input: PlannerSubmitInput): Promise<PlannerSubmitResult>;\n turnFinished(task: TaskAttemptRef): Promise<void>;\n reconcile(snapshot?: readonly import(\"../schema/task\").Task[]): Promise<PlannerReconcileResult>;\n isPlanner(task: import(\"../schema/task\").Task): boolean;\n readonly limits: import(\"./contracts\").PlannerLimits;\n}\n\n/** Trusted workflow runtime. Transport tools must supply authenticated Task ID/attempt, never model principals. */\nexport function createPlannerRuntime(options: PlannerRuntimeOptions): PlannerRuntime {\n const config = plannerConfiguration(options);\n const state = plannerState(options, config);\n const turns = plannerTurns(options, config, state);\n return Object.freeze({\n prepare: turns.prepare,\n context: turns.context,\n submit: ({ task, triggerId, proposed }: PlannerSubmitInput) =>\n turns.submit(task, triggerId, proposed),\n turnFinished: turns.turnFinished,\n reconcile: plannerReconciler(options, config, state, turns),\n isPlanner: config.isPlanner,\n limits: config.limits,\n });\n}\n"],"mappings":";;;;;;;AA+CA,SAAgB,qBAAqB,SAAgD;CACnF,MAAM,SAAS,qBAAqB,OAAO;CAC3C,MAAM,QAAQ,aAAa,SAAS,MAAM;CAC1C,MAAM,QAAQ,aAAa,SAAS,QAAQ,KAAK;CACjD,OAAO,OAAO,OAAO;EACnB,SAAS,MAAM;EACf,SAAS,MAAM;EACf,SAAS,EAAE,MAAM,WAAW,eAC1B,MAAM,OAAO,MAAM,WAAW,QAAQ;EACxC,cAAc,MAAM;EACpB,WAAW,kBAAkB,SAAS,QAAQ,OAAO,KAAK;EAC1D,WAAW,OAAO;EAClB,QAAQ,OAAO;CACjB,CAAC;AACH"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { taskIdSchema } from "../schema/id.mjs";
|
|
2
|
+
import { isoDateTimeSchema, schemaVersionSchema } from "../schema/common.mjs";
|
|
3
|
+
import { RecordExistsError, VersionConflictError } from "../store/driver.mjs";
|
|
4
|
+
import { taskMessageIdSchema } from "../schema/task-message.mjs";
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
//#region src/planning/state.ts
|
|
7
|
+
const runtimePrincipal = Object.freeze({ id: "factory:planner-runtime" });
|
|
8
|
+
const terminal = (task) => [
|
|
9
|
+
"succeeded",
|
|
10
|
+
"failed",
|
|
11
|
+
"cancelled"
|
|
12
|
+
].includes(task.state);
|
|
13
|
+
const activationSchema = z.strictObject({
|
|
14
|
+
schemaVersion: schemaVersionSchema,
|
|
15
|
+
taskId: taskIdSchema.describe("Planner Task and directly addressed checkpoint key."),
|
|
16
|
+
attempt: z.number().int().positive().describe("Task attempt owning this activation."),
|
|
17
|
+
triggerId: taskMessageIdSchema.describe("One immutable trigger for this entire activation."),
|
|
18
|
+
seed: z.boolean().describe("Whether preparation must ensure a self-start message is delivered."),
|
|
19
|
+
finished: z.boolean().describe("Trusted turn-finished hook observed; not a provider session lifecycle."),
|
|
20
|
+
startedAt: isoDateTimeSchema.describe("Workflow activation time used for bounded missing-hook recovery.")
|
|
21
|
+
});
|
|
22
|
+
function plannerState(options, config) {
|
|
23
|
+
const { stores } = options;
|
|
24
|
+
const driver = stores.workflowRecords;
|
|
25
|
+
const now = options.now ?? (() => (/* @__PURE__ */ new Date()).toISOString());
|
|
26
|
+
async function task(id, attempt) {
|
|
27
|
+
taskIdSchema.parse(id);
|
|
28
|
+
if (attempt !== void 0) z.number().int().positive().parse(attempt);
|
|
29
|
+
const value = await stores.tasks.get(id);
|
|
30
|
+
if (!value || !config.isPlanner(value)) throw new Error(`Task ${id} requires the exact planner route`);
|
|
31
|
+
if (attempt !== void 0 && value.attempt !== attempt) throw new Error(`Stale planner attempt ${attempt}; current attempt is ${value.attempt}`);
|
|
32
|
+
return value;
|
|
33
|
+
}
|
|
34
|
+
async function authority(value, allowTerminal = false) {
|
|
35
|
+
const current = await task(value.id, value.attempt);
|
|
36
|
+
if (current.state === "cancelled" || !allowTerminal && terminal(current)) throw new Error("Planner is terminal or cancelled");
|
|
37
|
+
if (current.attempt > config.limits.maxTurns) throw new Error("Planner maxTurns exhausted");
|
|
38
|
+
let cursor = current;
|
|
39
|
+
const seen = /* @__PURE__ */ new Set([cursor.id]);
|
|
40
|
+
while (cursor.parentTaskId) {
|
|
41
|
+
const parent = await stores.tasks.get(cursor.parentTaskId);
|
|
42
|
+
if (!parent || parent.rootTaskId !== current.rootTaskId || seen.has(parent.id)) throw new Error("Invalid planner ancestry");
|
|
43
|
+
if (terminal(parent)) throw new Error("Planner ancestor is terminal or cancelled");
|
|
44
|
+
seen.add(parent.id);
|
|
45
|
+
cursor = parent;
|
|
46
|
+
}
|
|
47
|
+
if (cursor.id !== current.rootTaskId) throw new Error("Planner root is missing");
|
|
48
|
+
for (const repositoryId of current.repositoryIds) if (options.canUseRepository && await options.canUseRepository(repositoryId, current) !== true) throw new Error(`Planner repository ${repositoryId} is not permitted`);
|
|
49
|
+
return current;
|
|
50
|
+
}
|
|
51
|
+
async function activation(id) {
|
|
52
|
+
const stored = await driver.get("plannerActivations", id);
|
|
53
|
+
if (!stored) return null;
|
|
54
|
+
const value = activationSchema.parse(stored.value);
|
|
55
|
+
if (value.taskId !== id) throw new Error("Planner activation identity mismatch");
|
|
56
|
+
return {
|
|
57
|
+
value,
|
|
58
|
+
version: stored.version
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
async function save(value, version) {
|
|
62
|
+
const parsed = activationSchema.parse(value);
|
|
63
|
+
try {
|
|
64
|
+
if (version === void 0) await driver.insert({
|
|
65
|
+
collection: "plannerActivations",
|
|
66
|
+
id: value.taskId,
|
|
67
|
+
value: parsed
|
|
68
|
+
});
|
|
69
|
+
else await driver.update({
|
|
70
|
+
collection: "plannerActivations",
|
|
71
|
+
id: value.taskId,
|
|
72
|
+
value: parsed,
|
|
73
|
+
expectedVersion: version
|
|
74
|
+
});
|
|
75
|
+
return true;
|
|
76
|
+
} catch (error) {
|
|
77
|
+
if (error instanceof RecordExistsError || error instanceof VersionConflictError) return false;
|
|
78
|
+
throw error;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
now,
|
|
83
|
+
task,
|
|
84
|
+
authority,
|
|
85
|
+
activation,
|
|
86
|
+
save
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
//#endregion
|
|
90
|
+
export { plannerState, runtimePrincipal, terminal };
|
|
91
|
+
|
|
92
|
+
//# sourceMappingURL=state.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.mjs","names":[],"sources":["../../src/planning/state.ts"],"sourcesContent":["import { z } from \"zod\";\nimport { isoDateTimeSchema, schemaVersionSchema } from \"../schema/common\";\nimport { taskIdSchema, type TaskId } from \"../schema/id\";\nimport type { Task } from \"../schema/task\";\nimport { taskMessageIdSchema } from \"../schema/task-message\";\nimport { RecordExistsError, VersionConflictError } from \"../store/driver\";\nimport type { PlannerRuntimeOptions } from \"./contracts\";\nimport type { PlannerConfiguration } from \"./configuration\";\n\nexport const runtimePrincipal = Object.freeze({ id: \"factory:planner-runtime\" });\nexport const terminal = (task: Task) => [\"succeeded\", \"failed\", \"cancelled\"].includes(task.state);\nconst activationSchema = z.strictObject({\n schemaVersion: schemaVersionSchema,\n taskId: taskIdSchema.describe(\"Planner Task and directly addressed checkpoint key.\"),\n attempt: z.number().int().positive().describe(\"Task attempt owning this activation.\"),\n triggerId: taskMessageIdSchema.describe(\"One immutable trigger for this entire activation.\"),\n seed: z.boolean().describe(\"Whether preparation must ensure a self-start message is delivered.\"),\n finished: z\n .boolean()\n .describe(\"Trusted turn-finished hook observed; not a provider session lifecycle.\"),\n startedAt: isoDateTimeSchema.describe(\n \"Workflow activation time used for bounded missing-hook recovery.\",\n ),\n});\nexport type PlannerActivation = z.infer<typeof activationSchema>;\n\nexport function plannerState(options: PlannerRuntimeOptions, config: PlannerConfiguration) {\n const { stores } = options;\n const driver = stores.workflowRecords;\n const now = options.now ?? (() => new Date().toISOString());\n async function task(id: TaskId, attempt?: number): Promise<Task> {\n taskIdSchema.parse(id);\n if (attempt !== undefined) z.number().int().positive().parse(attempt);\n const value = await stores.tasks.get(id);\n if (!value || !config.isPlanner(value))\n throw new Error(`Task ${id} requires the exact planner route`);\n if (attempt !== undefined && value.attempt !== attempt)\n throw new Error(`Stale planner attempt ${attempt}; current attempt is ${value.attempt}`);\n return value;\n }\n async function authority(value: Task, allowTerminal = false): Promise<Task> {\n const current = await task(value.id, value.attempt);\n if (current.state === \"cancelled\" || (!allowTerminal && terminal(current)))\n throw new Error(\"Planner is terminal or cancelled\");\n if (current.attempt > config.limits.maxTurns) throw new Error(\"Planner maxTurns exhausted\");\n let cursor: Task = current;\n const seen = new Set<string>([cursor.id]);\n while (cursor.parentTaskId) {\n const parent = await stores.tasks.get(cursor.parentTaskId);\n if (!parent || parent.rootTaskId !== current.rootTaskId || seen.has(parent.id))\n throw new Error(\"Invalid planner ancestry\");\n if (terminal(parent)) throw new Error(\"Planner ancestor is terminal or cancelled\");\n seen.add(parent.id);\n cursor = parent;\n }\n if (cursor.id !== current.rootTaskId) throw new Error(\"Planner root is missing\");\n for (const repositoryId of current.repositoryIds) {\n if (\n options.canUseRepository &&\n (await options.canUseRepository(repositoryId, current)) !== true\n ) {\n throw new Error(`Planner repository ${repositoryId} is not permitted`);\n }\n }\n return current;\n }\n async function activation(id: TaskId) {\n const stored = await driver.get(\"plannerActivations\", id);\n if (!stored) return null;\n const value = activationSchema.parse(stored.value);\n if (value.taskId !== id) throw new Error(\"Planner activation identity mismatch\");\n return { value, version: stored.version };\n }\n async function save(value: PlannerActivation, version?: number): Promise<boolean> {\n const parsed = activationSchema.parse(value);\n try {\n if (version === undefined)\n await driver.insert({ collection: \"plannerActivations\", id: value.taskId, value: parsed });\n else\n await driver.update({\n collection: \"plannerActivations\",\n id: value.taskId,\n value: parsed,\n expectedVersion: version,\n });\n return true;\n } catch (error) {\n if (error instanceof RecordExistsError || error instanceof VersionConflictError) return false;\n throw error;\n }\n }\n return { now, task, authority, activation, save };\n}\nexport type PlannerState = ReturnType<typeof plannerState>;\n"],"mappings":"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"}
|