@sixb/core 0.1.1 → 0.1.3
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 +31 -20
- package/dist/actions/commit-edits.d.ts +0 -2
- package/dist/actions/commit-edits.d.ts.map +1 -1
- package/dist/actions/execution.d.ts +21 -0
- package/dist/actions/execution.d.ts.map +1 -0
- package/dist/actions/index.d.ts +1 -1
- package/dist/actions/index.d.ts.map +1 -1
- package/dist/actions/index.js +38 -24
- package/dist/actions/index.js.map +1 -1
- package/dist/actions/registry.d.ts +16 -7
- package/dist/actions/registry.d.ts.map +1 -1
- package/dist/actions/request.d.ts +3 -2
- package/dist/actions/request.d.ts.map +1 -1
- package/dist/actions/run-dispatch.d.ts +21 -0
- package/dist/actions/run-dispatch.d.ts.map +1 -0
- package/dist/actions/types/context.d.ts +2 -2
- package/dist/actions/types/context.d.ts.map +1 -1
- package/dist/actions/validation.d.ts +1 -1
- package/dist/actions/validation.d.ts.map +1 -1
- package/dist/actions/worker.js +7 -7
- package/dist/actions/worker.js.map +1 -1
- package/dist/agents/adapters.d.ts +21 -1
- package/dist/agents/adapters.d.ts.map +1 -1
- package/dist/agents/authority.d.ts +31 -0
- package/dist/agents/authority.d.ts.map +1 -0
- package/dist/agents/context.js +2 -2
- package/dist/agents/dispatch.d.ts.map +1 -1
- package/dist/agents/errors.d.ts +2 -2
- package/dist/agents/errors.d.ts.map +1 -1
- package/dist/agents/execution.d.ts +48 -0
- package/dist/agents/execution.d.ts.map +1 -0
- package/dist/agents/index.d.ts +12 -9
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js +77 -18
- package/dist/agents/index.js.map +1 -1
- package/dist/agents/prompt.d.ts +8 -2
- package/dist/agents/prompt.d.ts.map +1 -1
- package/dist/agents/request.d.ts +6 -2
- package/dist/agents/request.d.ts.map +1 -1
- package/dist/agents/streams.d.ts +29 -3
- package/dist/agents/streams.d.ts.map +1 -1
- package/dist/agents/streams.js +22 -3
- package/dist/agents/streams.js.map +1 -1
- package/dist/agents/thread-context-projection.d.ts +19 -0
- package/dist/agents/thread-context-projection.d.ts.map +1 -0
- package/dist/agents/tool-definition.d.ts.map +1 -1
- package/dist/agents/tool-result.d.ts +6 -0
- package/dist/agents/tool-result.d.ts.map +1 -0
- package/dist/agents/types.d.ts +39 -3
- package/dist/agents/types.d.ts.map +1 -1
- package/dist/agents/validation.d.ts +3 -3
- package/dist/agents/validation.d.ts.map +1 -1
- package/dist/auth/attribution.d.ts +17 -0
- package/dist/auth/attribution.d.ts.map +1 -0
- package/dist/auth/index.d.ts +1 -0
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +11 -5
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/runtime.d.ts +4 -4
- package/dist/auth/runtime.d.ts.map +1 -1
- package/dist/authorization/decision.d.ts +24 -11
- package/dist/authorization/decision.d.ts.map +1 -1
- package/dist/authorization/grant-kinds.d.ts +2 -1
- package/dist/authorization/grant-kinds.d.ts.map +1 -1
- package/dist/authorization/index.d.ts +1 -1
- package/dist/authorization/index.d.ts.map +1 -1
- package/dist/authorization/index.js +8 -4
- package/dist/authorization/index.js.map +1 -1
- package/dist/blob-storage/browser.js +2 -2
- package/dist/blob-storage/execution.d.ts +16 -0
- package/dist/blob-storage/execution.d.ts.map +1 -0
- package/dist/blob-storage/index.js +3 -3
- package/dist/bootstrap/discovery.d.ts +90 -24
- package/dist/bootstrap/discovery.d.ts.map +1 -1
- package/dist/bootstrap/index.d.ts +2 -1
- package/dist/bootstrap/index.d.ts.map +1 -1
- package/dist/bootstrap/index.js +63 -60
- package/dist/bootstrap/index.js.map +1 -1
- package/dist/broker/in-memory.d.ts.map +1 -1
- package/dist/broker/index.js +2 -2
- package/dist/broker/types.d.ts +5 -0
- package/dist/broker/types.d.ts.map +1 -1
- package/dist/chunk-0172wgm9.js +333 -0
- package/dist/chunk-0172wgm9.js.map +11 -0
- package/dist/chunk-177ed2mp.js +3118 -0
- package/dist/chunk-177ed2mp.js.map +46 -0
- package/dist/chunk-1ywq4hzk.js +607 -0
- package/dist/chunk-1ywq4hzk.js.map +14 -0
- package/dist/chunk-261ag4t4.js +252 -0
- package/dist/chunk-261ag4t4.js.map +12 -0
- package/dist/{chunk-y2ygpd0m.js → chunk-3j7573mj.js} +2 -2
- package/dist/{chunk-y2ygpd0m.js.map → chunk-3j7573mj.js.map} +2 -2
- package/dist/{chunk-p7vj8xgb.js → chunk-3rsf30p4.js} +81 -58
- package/dist/chunk-3rsf30p4.js.map +35 -0
- package/dist/chunk-4aw0jwk0.js +118 -0
- package/dist/chunk-4aw0jwk0.js.map +10 -0
- package/dist/{chunk-md9jbrm9.js → chunk-4gz41why.js} +1 -1
- package/dist/chunk-4p9rh7jj.js +164 -0
- package/dist/chunk-4p9rh7jj.js.map +12 -0
- package/dist/chunk-4z3n1dzt.js +1206 -0
- package/dist/chunk-4z3n1dzt.js.map +23 -0
- package/dist/chunk-5gd7tpv6.js +28 -0
- package/dist/chunk-5gd7tpv6.js.map +11 -0
- package/dist/{chunk-867jxh7c.js → chunk-5sz8ta9r.js} +6 -295
- package/dist/chunk-5sz8ta9r.js.map +16 -0
- package/dist/chunk-62c7t4jc.js +27 -0
- package/dist/chunk-62c7t4jc.js.map +11 -0
- package/dist/chunk-63te770v.js.map +1 -1
- package/dist/{chunk-xz5g49bp.js → chunk-6gjqgd3d.js} +3 -1
- package/dist/chunk-6gjqgd3d.js.map +11 -0
- package/dist/{chunk-6rzdtvn5.js → chunk-8b55ygje.js} +1 -1
- package/dist/chunk-8m5ejdpn.js +33 -0
- package/dist/chunk-8m5ejdpn.js.map +10 -0
- package/dist/chunk-96swp2wd.js +47 -0
- package/dist/chunk-96swp2wd.js.map +10 -0
- package/dist/chunk-979ww6b3.js +298 -0
- package/dist/chunk-979ww6b3.js.map +12 -0
- package/dist/{chunk-ya6brh8a.js → chunk-9t8f5xfx.js} +10 -5
- package/dist/chunk-9t8f5xfx.js.map +11 -0
- package/dist/{chunk-r82k4z7z.js → chunk-a31h57d5.js} +2 -2
- package/dist/{chunk-t72dvahb.js → chunk-bhxaq2nn.js} +61 -44
- package/dist/chunk-bhxaq2nn.js.map +12 -0
- package/dist/chunk-bv41fmjn.js +3294 -0
- package/dist/chunk-bv41fmjn.js.map +35 -0
- package/dist/chunk-c6cfqydk.js +128 -0
- package/dist/chunk-c6cfqydk.js.map +13 -0
- package/dist/chunk-c8bw2b6c.js +317 -0
- package/dist/chunk-c8bw2b6c.js.map +11 -0
- package/dist/{chunk-qzyemcj7.js → chunk-ckxfnx7f.js} +2 -2
- package/dist/chunk-cy0n5dms.js +27 -0
- package/dist/chunk-cy0n5dms.js.map +11 -0
- package/dist/{chunk-xt6qx9sh.js → chunk-d2adj15j.js} +91 -9
- package/dist/chunk-d2adj15j.js.map +37 -0
- package/dist/{chunk-avppcgt6.js → chunk-d6y2wsfg.js} +241 -144
- package/dist/chunk-d6y2wsfg.js.map +15 -0
- package/dist/chunk-dsrkgtnh.js +50 -0
- package/dist/chunk-dsrkgtnh.js.map +10 -0
- package/dist/{chunk-50kv63vj.js → chunk-dysw7nsm.js} +118 -26
- package/dist/chunk-dysw7nsm.js.map +14 -0
- package/dist/{chunk-rjqm6ksg.js → chunk-ettb0cy4.js} +725 -266
- package/dist/chunk-ettb0cy4.js.map +45 -0
- package/dist/chunk-ezake7g1.js +32 -0
- package/dist/chunk-ezake7g1.js.map +11 -0
- package/dist/{chunk-b1bqvhpe.js → chunk-f1cyvnrk.js} +14 -34
- package/dist/chunk-f1cyvnrk.js.map +13 -0
- package/dist/{chunk-yn947ck3.js → chunk-f2rt4vkh.js} +48 -29
- package/dist/chunk-f2rt4vkh.js.map +14 -0
- package/dist/{chunk-hb9xcx9c.js → chunk-fmx1sz2h.js} +117 -56
- package/dist/chunk-fmx1sz2h.js.map +15 -0
- package/dist/{chunk-f6kyyeef.js → chunk-ghteq96b.js} +8 -8
- package/dist/{chunk-f6kyyeef.js.map → chunk-ghteq96b.js.map} +4 -4
- package/dist/chunk-h9kxd41f.js +271 -0
- package/dist/chunk-h9kxd41f.js.map +11 -0
- package/dist/chunk-htq0qh7z.js +59 -0
- package/dist/chunk-htq0qh7z.js.map +11 -0
- package/dist/chunk-km4rkj4t.js +402 -0
- package/dist/chunk-km4rkj4t.js.map +14 -0
- package/dist/chunk-kqxgf6kv.js +898 -0
- package/dist/chunk-kqxgf6kv.js.map +15 -0
- package/dist/chunk-n5x5y80a.js +137 -0
- package/dist/chunk-n5x5y80a.js.map +10 -0
- package/dist/chunk-nf4r78r4.js +44 -0
- package/dist/chunk-nf4r78r4.js.map +10 -0
- package/dist/chunk-pxtrxm3p.js +55 -0
- package/dist/chunk-pxtrxm3p.js.map +11 -0
- package/dist/chunk-qer6am8w.js +133 -0
- package/dist/chunk-qer6am8w.js.map +11 -0
- package/dist/{chunk-sb0shdvv.js → chunk-rdeagz6b.js} +3 -3
- package/dist/{chunk-sb0shdvv.js.map → chunk-rdeagz6b.js.map} +3 -3
- package/dist/chunk-rhrbz7d4.js +36 -0
- package/dist/chunk-rhrbz7d4.js.map +10 -0
- package/dist/{chunk-53s4asfm.js → chunk-rnshztfq.js} +2 -2
- package/dist/chunk-t0jjkep3.js +35 -0
- package/dist/chunk-t0jjkep3.js.map +10 -0
- package/dist/{chunk-be9vm29v.js → chunk-t8t39h7v.js} +1 -1
- package/dist/{chunk-be9vm29v.js.map → chunk-t8t39h7v.js.map} +3 -3
- package/dist/chunk-t9xghkva.js +28 -0
- package/dist/chunk-t9xghkva.js.map +10 -0
- package/dist/{chunk-nbywkytr.js → chunk-ttba8x6z.js} +13 -33
- package/dist/chunk-ttba8x6z.js.map +15 -0
- package/dist/{chunk-8kv2sez0.js → chunk-vybf6pkp.js} +1 -1
- package/dist/chunk-wb4051cx.js +404 -0
- package/dist/chunk-wb4051cx.js.map +12 -0
- package/dist/{chunk-4tvj3ate.js → chunk-wtmzkcht.js} +4 -3
- package/dist/chunk-wtmzkcht.js.map +11 -0
- package/dist/{chunk-xqbtf4wn.js → chunk-xc7hq65b.js} +5 -3
- package/dist/{chunk-xqbtf4wn.js.map → chunk-xc7hq65b.js.map} +3 -3
- package/dist/{chunk-v5c085yp.js → chunk-xhy826cz.js} +3 -2
- package/dist/chunk-xhy826cz.js.map +10 -0
- package/dist/chunk-xkthy56g.js +33 -0
- package/dist/chunk-xkthy56g.js.map +11 -0
- package/dist/{chunk-raq0x6bd.js → chunk-xmggaxg4.js} +2199 -380
- package/dist/chunk-xmggaxg4.js.map +54 -0
- package/dist/{chunk-6zrpewy4.js → chunk-z3zp0bj1.js} +1 -1
- package/dist/chunk-z8j83gzd.js +90 -0
- package/dist/chunk-z8j83gzd.js.map +10 -0
- package/dist/chunk-zcnhxkvd.js +7 -0
- package/dist/chunk-zcnhxkvd.js.map +10 -0
- package/dist/chunk-zpw39qhj.js +194 -0
- package/dist/chunk-zpw39qhj.js.map +10 -0
- package/dist/chunk-zqqz8052.js +3 -0
- package/dist/{storage/projection-runs/lifecycle.js.map → chunk-zqqz8052.js.map} +1 -1
- package/dist/{chunk-hz8m927w.js → chunk-zqysyfjt.js} +1 -1
- package/dist/connectors/builders.d.ts +2 -1
- package/dist/connectors/builders.d.ts.map +1 -1
- package/dist/connectors/connections/authorizations.d.ts +64 -0
- package/dist/connectors/connections/authorizations.d.ts.map +1 -0
- package/dist/connectors/connections/capability.d.ts +7 -0
- package/dist/connectors/connections/capability.d.ts.map +1 -0
- package/dist/connectors/connections/command-context.d.ts +23 -0
- package/dist/connectors/connections/command-context.d.ts.map +1 -0
- package/dist/connectors/connections/contracts.d.ts +127 -0
- package/dist/connectors/connections/contracts.d.ts.map +1 -0
- package/dist/connectors/connections/credential-codec.d.ts +15 -0
- package/dist/connectors/connections/credential-codec.d.ts.map +1 -0
- package/dist/connectors/connections/credential-mutations.d.ts +63 -0
- package/dist/connectors/connections/credential-mutations.d.ts.map +1 -0
- package/dist/connectors/connections/execution.d.ts +20 -0
- package/dist/connectors/connections/execution.d.ts.map +1 -0
- package/dist/connectors/connections/internal.d.ts +5 -0
- package/dist/connectors/connections/internal.d.ts.map +1 -0
- package/dist/connectors/connections/internal.js +16 -0
- package/dist/connectors/connections/internal.js.map +9 -0
- package/dist/connectors/connections/provider-operation.d.ts +7 -0
- package/dist/connectors/connections/provider-operation.d.ts.map +1 -0
- package/dist/connectors/connections/request.d.ts +84 -0
- package/dist/connectors/connections/request.d.ts.map +1 -0
- package/dist/connectors/connections/runs.d.ts +51 -0
- package/dist/connectors/connections/runs.d.ts.map +1 -0
- package/dist/connectors/connections/service.d.ts +52 -0
- package/dist/connectors/connections/service.d.ts.map +1 -0
- package/dist/connectors/connections/storage-boundary.d.ts +3 -0
- package/dist/connectors/connections/storage-boundary.d.ts.map +1 -0
- package/dist/connectors/connections/tokens.d.ts +32 -0
- package/dist/connectors/connections/tokens.d.ts.map +1 -0
- package/dist/connectors/connections/validation.d.ts +27 -0
- package/dist/connectors/connections/validation.d.ts.map +1 -0
- package/dist/connectors/connections/views.d.ts +7 -0
- package/dist/connectors/connections/views.d.ts.map +1 -0
- package/dist/connectors/credentials.d.ts +25 -0
- package/dist/connectors/credentials.d.ts.map +1 -0
- package/dist/connectors/errors.d.ts +35 -3
- package/dist/connectors/errors.d.ts.map +1 -1
- package/dist/connectors/execution.d.ts +19 -0
- package/dist/connectors/execution.d.ts.map +1 -0
- package/dist/connectors/index.d.ts +5 -3
- package/dist/connectors/index.d.ts.map +1 -1
- package/dist/connectors/service.d.ts +23 -0
- package/dist/connectors/service.d.ts.map +1 -0
- package/dist/connectors/types.d.ts +94 -2
- package/dist/connectors/types.d.ts.map +1 -1
- package/dist/datasets/execution.d.ts +8 -0
- package/dist/datasets/execution.d.ts.map +1 -0
- package/dist/error-reporting/capability.d.ts +4 -49
- package/dist/error-reporting/capability.d.ts.map +1 -1
- package/dist/error-reporting/internal.d.ts +2 -2
- package/dist/error-reporting/internal.d.ts.map +1 -1
- package/dist/error-reporting/internal.js +10 -4
- package/dist/error-reporting/internal.js.map +1 -1
- package/dist/error-reporting/reporter.d.ts +4 -1
- package/dist/error-reporting/reporter.d.ts.map +1 -1
- package/dist/error-reporting/reports.d.ts +64 -0
- package/dist/error-reporting/reports.d.ts.map +1 -0
- package/dist/error-reporting/types.d.ts +88 -34
- package/dist/error-reporting/types.d.ts.map +1 -1
- package/dist/errors/catalog.d.ts +141 -0
- package/dist/errors/catalog.d.ts.map +1 -0
- package/dist/errors/internal.d.ts +68 -0
- package/dist/errors/internal.d.ts.map +1 -0
- package/dist/errors/internal.js +29 -0
- package/dist/errors/internal.js.map +9 -0
- package/dist/errors/types.d.ts +20 -0
- package/dist/errors/types.d.ts.map +1 -0
- package/dist/events/definitions.d.ts +0 -1
- package/dist/events/definitions.d.ts.map +1 -1
- package/dist/events/execution.d.ts +13 -0
- package/dist/events/execution.d.ts.map +1 -0
- package/dist/events/index.d.ts +3 -2
- package/dist/events/index.d.ts.map +1 -1
- package/dist/events/index.js +10 -8
- package/dist/events/index.js.map +1 -1
- package/dist/events/outbox-dispatcher.d.ts +4 -2
- package/dist/events/outbox-dispatcher.d.ts.map +1 -1
- package/dist/events/{runtime.d.ts → service.d.ts} +13 -14
- package/dist/events/service.d.ts.map +1 -0
- package/dist/events/types/pipelines.d.ts +4 -1
- package/dist/events/types/pipelines.d.ts.map +1 -1
- package/dist/events/types/syncs.d.ts +3 -0
- package/dist/events/types/syncs.d.ts.map +1 -1
- package/dist/events/types/workflows.d.ts +4 -2
- package/dist/events/types/workflows.d.ts.map +1 -1
- package/dist/execution/agent.d.ts +42 -0
- package/dist/execution/agent.d.ts.map +1 -0
- package/dist/execution/agent.js +73 -0
- package/dist/execution/agent.js.map +9 -0
- package/dist/execution/authorization.d.ts +60 -0
- package/dist/execution/authorization.d.ts.map +1 -0
- package/dist/execution/dispatch.d.ts +8 -0
- package/dist/execution/dispatch.d.ts.map +1 -0
- package/dist/execution/durable.d.ts +37 -0
- package/dist/execution/durable.d.ts.map +1 -0
- package/dist/execution/index.d.ts +2 -0
- package/dist/execution/index.d.ts.map +1 -0
- package/dist/execution/primitive.d.ts +21 -0
- package/dist/execution/primitive.d.ts.map +1 -0
- package/dist/execution/primitive.js +91 -0
- package/dist/execution/primitive.js.map +10 -0
- package/dist/execution/request.d.ts +38 -0
- package/dist/execution/request.d.ts.map +1 -0
- package/dist/execution/request.js +100 -0
- package/dist/execution/request.js.map +10 -0
- package/dist/execution/scopes.d.ts +30 -0
- package/dist/execution/scopes.d.ts.map +1 -0
- package/dist/execution/types.d.ts +111 -0
- package/dist/execution/types.d.ts.map +1 -0
- package/dist/index.d.ts +31 -14
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +133 -105
- package/dist/index.js.map +1 -1
- package/dist/json.d.ts +0 -1
- package/dist/json.d.ts.map +1 -1
- package/dist/lake-storage/index.js +5 -5
- package/dist/logging/execution.d.ts +9 -0
- package/dist/logging/execution.d.ts.map +1 -0
- package/dist/logging/index.d.ts +1 -1
- package/dist/logging/index.d.ts.map +1 -1
- package/dist/logging/index.js +8 -8
- package/dist/logging/index.js.map +1 -1
- package/dist/logging/{runtime.d.ts → service.d.ts} +7 -7
- package/dist/logging/{runtime.d.ts.map → service.d.ts.map} +1 -1
- package/dist/logging/types.js +2 -2
- package/dist/materialization/events.d.ts +1 -0
- package/dist/materialization/events.d.ts.map +1 -1
- package/dist/materialization/index.d.ts +1 -1
- package/dist/materialization/index.d.ts.map +1 -1
- package/dist/materialization/index.js +2 -2
- package/dist/materialization/model.d.ts +30 -17
- package/dist/materialization/model.d.ts.map +1 -1
- package/dist/materializer/edits/apply.d.ts +6 -1
- package/dist/materializer/edits/apply.d.ts.map +1 -1
- package/dist/materializer/edits/commit.d.ts +2 -1
- package/dist/materializer/edits/commit.d.ts.map +1 -1
- package/dist/materializer/edits/load-state.d.ts +1 -1
- package/dist/materializer/edits/load-state.d.ts.map +1 -1
- package/dist/materializer/edits/operations.d.ts +1 -13
- package/dist/materializer/edits/operations.d.ts.map +1 -1
- package/dist/materializer/edits/plan.d.ts +2 -1
- package/dist/materializer/edits/plan.d.ts.map +1 -1
- package/dist/materializer/edits/working-state.d.ts +38 -8
- package/dist/materializer/edits/working-state.d.ts.map +1 -1
- package/dist/materializer/effective/build-events.d.ts +1 -0
- package/dist/materializer/effective/build-events.d.ts.map +1 -1
- package/dist/materializer/effective/diff.d.ts +7 -0
- package/dist/materializer/effective/diff.d.ts.map +1 -1
- package/dist/materializer/effective/load-state.d.ts +0 -2
- package/dist/materializer/effective/load-state.d.ts.map +1 -1
- package/dist/materializer/effective/resolve.d.ts +19 -2
- package/dist/materializer/effective/resolve.d.ts.map +1 -1
- package/dist/materializer/execution/commit-lifecycle.d.ts +2 -2
- package/dist/materializer/execution/commit-lifecycle.d.ts.map +1 -1
- package/dist/materializer/execution/plan-stream.d.ts.map +1 -1
- package/dist/materializer/execution/scope.d.ts +26 -0
- package/dist/materializer/execution/scope.d.ts.map +1 -0
- package/dist/materializer/execution/work-executor.d.ts.map +1 -1
- package/dist/materializer/execution/work-records.d.ts +6 -5
- package/dist/materializer/execution/work-records.d.ts.map +1 -1
- package/dist/materializer/index.d.ts +2 -2
- package/dist/materializer/index.d.ts.map +1 -1
- package/dist/materializer/index.js +33 -18
- package/dist/materializer/index.js.map +1 -1
- package/dist/materializer/materializer.d.ts +37 -5
- package/dist/materializer/materializer.d.ts.map +1 -1
- package/dist/materializer/projections/finish-run.d.ts +2 -1
- package/dist/materializer/projections/finish-run.d.ts.map +1 -1
- package/dist/materializer/projections/replace.d.ts +2 -1
- package/dist/materializer/projections/replace.d.ts.map +1 -1
- package/dist/materializer/projections/replacement-plan.d.ts +1 -0
- package/dist/materializer/projections/replacement-plan.d.ts.map +1 -1
- package/dist/materializer/shared/batching.d.ts.map +1 -1
- package/dist/materializer/shared/normalize.d.ts.map +1 -1
- package/dist/materializer/telemetry/append.d.ts +2 -1
- package/dist/materializer/telemetry/append.d.ts.map +1 -1
- package/dist/materializer/telemetry/plan.d.ts +7 -1
- package/dist/materializer/telemetry/plan.d.ts.map +1 -1
- package/dist/objects/action/request.d.ts +3 -3
- package/dist/objects/action/request.d.ts.map +1 -1
- package/dist/objects/context/index.d.ts +1 -1
- package/dist/objects/context/index.d.ts.map +1 -1
- package/dist/objects/context/types.d.ts +5 -0
- package/dist/objects/context/types.d.ts.map +1 -1
- package/dist/objects/execution.d.ts +100 -0
- package/dist/objects/execution.d.ts.map +1 -0
- package/dist/objects/index.js +40 -24
- package/dist/objects/index.js.map +1 -1
- package/dist/objects/materializer-adapter.d.ts +1 -1
- package/dist/objects/materializer-adapter.d.ts.map +1 -1
- package/dist/objects/query/executor.d.ts +3 -8
- package/dist/objects/query/executor.d.ts.map +1 -1
- package/dist/objects/query/index.d.ts +2 -2
- package/dist/objects/query/index.d.ts.map +1 -1
- package/dist/objects/query/index.js +9 -13
- package/dist/objects/query/index.js.map +1 -1
- package/dist/objects/query/planner.d.ts +0 -3
- package/dist/objects/query/planner.d.ts.map +1 -1
- package/dist/objects/sdk/object-handle.d.ts +2 -2
- package/dist/objects/sdk/object-handle.d.ts.map +1 -1
- package/dist/objects/sdk/object-set.d.ts +2 -0
- package/dist/objects/sdk/object-set.d.ts.map +1 -1
- package/dist/objects/sdk/runtime-query-executor.d.ts +2 -0
- package/dist/objects/sdk/runtime-query-executor.d.ts.map +1 -1
- package/dist/objects/sdk/telemetry-channel.d.ts.map +1 -1
- package/dist/objects/service/action-service.d.ts +3 -2
- package/dist/objects/service/action-service.d.ts.map +1 -1
- package/dist/objects/service/list-service.d.ts +1 -1
- package/dist/objects/telemetry/history.d.ts +2 -0
- package/dist/objects/telemetry/history.d.ts.map +1 -1
- package/dist/objects/telemetry/write-batch.d.ts.map +1 -1
- package/dist/ontology/index.d.ts +1 -1
- package/dist/ontology/index.d.ts.map +1 -1
- package/dist/ontology/index.js +5 -5
- package/dist/ontology/internal.js +4 -4
- package/dist/ontology/registry.d.ts +15 -2
- package/dist/ontology/registry.d.ts.map +1 -1
- package/dist/pipelines/execution.d.ts +19 -0
- package/dist/pipelines/execution.d.ts.map +1 -0
- package/dist/pipelines/index.d.ts +1 -0
- package/dist/pipelines/index.d.ts.map +1 -1
- package/dist/pipelines/index.js +68 -0
- package/dist/pipelines/index.js.map +9 -0
- package/dist/pipelines/request.d.ts +6 -9
- package/dist/pipelines/request.d.ts.map +1 -1
- package/dist/pipelines/run-dispatch.d.ts +47 -0
- package/dist/pipelines/run-dispatch.d.ts.map +1 -0
- package/dist/projections/builders.d.ts +19 -8
- package/dist/projections/builders.d.ts.map +1 -1
- package/dist/projections/capability.d.ts +7 -0
- package/dist/projections/capability.d.ts.map +1 -0
- package/dist/projections/execution.d.ts +19 -0
- package/dist/projections/execution.d.ts.map +1 -0
- package/dist/projections/index.d.ts +5 -2
- package/dist/projections/index.d.ts.map +1 -1
- package/dist/projections/internal.d.ts +8 -11
- package/dist/projections/internal.d.ts.map +1 -1
- package/dist/projections/internal.js +48 -6
- package/dist/projections/internal.js.map +1 -1
- package/dist/projections/ownership.d.ts +2 -2
- package/dist/projections/ownership.d.ts.map +1 -1
- package/dist/projections/registry.d.ts +21 -11
- package/dist/projections/registry.d.ts.map +1 -1
- package/dist/projections/revision.d.ts +2 -2
- package/dist/projections/revision.d.ts.map +1 -1
- package/dist/projections/run-dispatch.d.ts +37 -0
- package/dist/projections/run-dispatch.d.ts.map +1 -0
- package/dist/projections/run-id.d.ts +3 -0
- package/dist/projections/run-id.d.ts.map +1 -0
- package/dist/projections/timestamp.d.ts +3 -0
- package/dist/projections/timestamp.d.ts.map +1 -0
- package/dist/projections/types.d.ts +12 -0
- package/dist/projections/types.d.ts.map +1 -1
- package/dist/projections/validation.d.ts +2 -2
- package/dist/projections/validation.d.ts.map +1 -1
- package/dist/queues/in-memory.d.ts +11 -10
- package/dist/queues/in-memory.d.ts.map +1 -1
- package/dist/queues/index.d.ts +1 -1
- package/dist/queues/index.d.ts.map +1 -1
- package/dist/queues/index.js +1 -1
- package/dist/queues/types.d.ts +59 -42
- package/dist/queues/types.d.ts.map +1 -1
- package/dist/rules/execution.d.ts +14 -0
- package/dist/rules/execution.d.ts.map +1 -0
- package/dist/rules/index.d.ts +1 -1
- package/dist/rules/index.d.ts.map +1 -1
- package/dist/rules/validation.d.ts +1 -2
- package/dist/rules/validation.d.ts.map +1 -1
- package/dist/runtime/ai-cost.d.ts +8 -0
- package/dist/runtime/ai-cost.d.ts.map +1 -0
- package/dist/runtime/ai-usage.d.ts +8 -0
- package/dist/runtime/ai-usage.d.ts.map +1 -0
- package/dist/runtime/create.d.ts +7 -5
- package/dist/runtime/create.d.ts.map +1 -1
- package/dist/runtime/definitions.d.ts +35 -0
- package/dist/runtime/definitions.d.ts.map +1 -0
- package/dist/runtime/host.d.ts +123 -0
- package/dist/runtime/host.d.ts.map +1 -0
- package/dist/runtime/index.d.ts +6 -5
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/internal.d.ts +4 -0
- package/dist/runtime/internal.d.ts.map +1 -1
- package/dist/runtime/internal.js +6 -2
- package/dist/runtime/internal.js.map +1 -1
- package/dist/runtime/ontology-mutations.d.ts +4 -2
- package/dist/runtime/ontology-mutations.d.ts.map +1 -1
- package/dist/runtime/resolve-definitions.d.ts +42 -0
- package/dist/runtime/resolve-definitions.d.ts.map +1 -0
- package/dist/runtime/sixb.d.ts +43 -219
- package/dist/runtime/sixb.d.ts.map +1 -1
- package/dist/runtime/types.d.ts +16 -216
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/scheduler/index.d.ts +1 -1
- package/dist/scheduler/index.d.ts.map +1 -1
- package/dist/scheduler/index.js +3 -6
- package/dist/scheduler/index.js.map +1 -1
- package/dist/scheduler/runtime.d.ts +7 -2
- package/dist/scheduler/runtime.d.ts.map +1 -1
- package/dist/schedules/execution.d.ts +6 -0
- package/dist/schedules/execution.d.ts.map +1 -0
- package/dist/schedules/index.js +9 -7
- package/dist/schedules/index.js.map +1 -1
- package/dist/schedules/types.d.ts +1 -3
- package/dist/schedules/types.d.ts.map +1 -1
- package/dist/security/every.d.ts +4 -1
- package/dist/security/every.d.ts.map +1 -1
- package/dist/security/grants.d.ts +4 -1
- package/dist/security/grants.d.ts.map +1 -1
- package/dist/security/index.d.ts +3 -1
- package/dist/security/index.d.ts.map +1 -1
- package/dist/security/registry.d.ts +42 -0
- package/dist/security/registry.d.ts.map +1 -0
- package/dist/security/types.d.ts +7 -12
- package/dist/security/types.d.ts.map +1 -1
- package/dist/security/validation.d.ts +2 -0
- package/dist/security/validation.d.ts.map +1 -1
- package/dist/storage/action-runs/failure.d.ts +7 -0
- package/dist/storage/action-runs/failure.d.ts.map +1 -0
- package/dist/storage/action-runs/failure.js +14 -0
- package/dist/storage/action-runs/failure.js.map +9 -0
- package/dist/storage/action-runs/idempotency.d.ts.map +1 -1
- package/dist/storage/action-runs/in-memory.d.ts +3 -1
- package/dist/storage/action-runs/in-memory.d.ts.map +1 -1
- package/dist/storage/action-runs/index.d.ts +2 -1
- package/dist/storage/action-runs/index.d.ts.map +1 -1
- package/dist/storage/action-runs/provider.d.ts +10 -0
- package/dist/storage/action-runs/provider.d.ts.map +1 -0
- package/dist/storage/action-runs/provider.js +13 -0
- package/dist/storage/action-runs/provider.js.map +9 -0
- package/dist/storage/action-runs/types.d.ts +37 -18
- package/dist/storage/action-runs/types.d.ts.map +1 -1
- package/dist/storage/agents/errors.d.ts +1 -1
- package/dist/storage/agents/errors.d.ts.map +1 -1
- package/dist/storage/agents/in-memory.d.ts +22 -5
- package/dist/storage/agents/in-memory.d.ts.map +1 -1
- package/dist/storage/agents/index.d.ts +2 -2
- package/dist/storage/agents/index.d.ts.map +1 -1
- package/dist/storage/agents/provider.d.ts +41 -0
- package/dist/storage/agents/provider.d.ts.map +1 -0
- package/dist/storage/agents/provider.js +28 -0
- package/dist/storage/agents/provider.js.map +9 -0
- package/dist/storage/agents/types.d.ts +83 -26
- package/dist/storage/agents/types.d.ts.map +1 -1
- package/dist/storage/ai-cost/analytics.d.ts +61 -0
- package/dist/storage/ai-cost/analytics.d.ts.map +1 -0
- package/dist/storage/ai-cost/codec.d.ts +14 -0
- package/dist/storage/ai-cost/codec.d.ts.map +1 -0
- package/dist/storage/ai-cost/errors.d.ts +7 -0
- package/dist/storage/ai-cost/errors.d.ts.map +1 -0
- package/dist/storage/ai-cost/in-memory.d.ts +32 -0
- package/dist/storage/ai-cost/in-memory.d.ts.map +1 -0
- package/dist/storage/ai-cost/index.d.ts +6 -0
- package/dist/storage/ai-cost/index.d.ts.map +1 -0
- package/dist/storage/ai-cost/provider.d.ts +7 -0
- package/dist/storage/ai-cost/provider.d.ts.map +1 -0
- package/dist/storage/ai-cost/provider.js +132 -0
- package/dist/storage/ai-cost/provider.js.map +10 -0
- package/dist/storage/ai-cost/types.d.ts +154 -0
- package/dist/storage/ai-cost/types.d.ts.map +1 -0
- package/dist/storage/ai-cost/validation.d.ts +7 -0
- package/dist/storage/ai-cost/validation.d.ts.map +1 -0
- package/dist/storage/ai-usage/errors.d.ts +8 -0
- package/dist/storage/ai-usage/errors.d.ts.map +1 -0
- package/dist/storage/ai-usage/in-memory.d.ts +28 -0
- package/dist/storage/ai-usage/in-memory.d.ts.map +1 -0
- package/dist/storage/ai-usage/index.d.ts +8 -0
- package/dist/storage/ai-usage/index.d.ts.map +1 -0
- package/dist/storage/ai-usage/record.d.ts +6 -0
- package/dist/storage/ai-usage/record.d.ts.map +1 -0
- package/dist/storage/ai-usage/types.d.ts +89 -0
- package/dist/storage/ai-usage/types.d.ts.map +1 -0
- package/dist/storage/ai-usage/usage.d.ts +11 -0
- package/dist/storage/ai-usage/usage.d.ts.map +1 -0
- package/dist/storage/auth/types.d.ts +1 -0
- package/dist/storage/auth/types.d.ts.map +1 -1
- package/dist/storage/connector-connections/errors.d.ts +12 -0
- package/dist/storage/connector-connections/errors.d.ts.map +1 -0
- package/dist/storage/connector-connections/in-memory.d.ts +81 -0
- package/dist/storage/connector-connections/in-memory.d.ts.map +1 -0
- package/dist/storage/connector-connections/index.d.ts +7 -0
- package/dist/storage/connector-connections/index.d.ts.map +1 -0
- package/dist/storage/connector-connections/provider/authorizations.d.ts +20 -0
- package/dist/storage/connector-connections/provider/authorizations.d.ts.map +1 -0
- package/dist/storage/connector-connections/provider/connections.d.ts +17 -0
- package/dist/storage/connector-connections/provider/connections.d.ts.map +1 -0
- package/dist/storage/connector-connections/provider/runs.d.ts +14 -0
- package/dist/storage/connector-connections/provider/runs.d.ts.map +1 -0
- package/dist/storage/connector-connections/provider/shared.d.ts +74 -0
- package/dist/storage/connector-connections/provider/shared.d.ts.map +1 -0
- package/dist/storage/connector-connections/provider.d.ts +49 -0
- package/dist/storage/connector-connections/provider.d.ts.map +1 -0
- package/dist/storage/connector-connections/provider.js +1025 -0
- package/dist/storage/connector-connections/provider.js.map +14 -0
- package/dist/storage/connector-connections/types.d.ts +402 -0
- package/dist/storage/connector-connections/types.d.ts.map +1 -0
- package/dist/storage/executions/errors.d.ts +8 -0
- package/dist/storage/executions/errors.d.ts.map +1 -0
- package/dist/storage/executions/in-memory.d.ts +21 -0
- package/dist/storage/executions/in-memory.d.ts.map +1 -0
- package/dist/storage/executions/index.d.ts +5 -0
- package/dist/storage/executions/index.d.ts.map +1 -0
- package/dist/storage/executions/provider.d.ts +29 -0
- package/dist/storage/executions/provider.d.ts.map +1 -0
- package/dist/storage/executions/provider.js +208 -0
- package/dist/storage/executions/provider.js.map +10 -0
- package/dist/storage/executions/run-link.d.ts +24 -0
- package/dist/storage/executions/run-link.d.ts.map +1 -0
- package/dist/storage/executions/types.d.ts +62 -0
- package/dist/storage/executions/types.d.ts.map +1 -0
- package/dist/storage/executions/validation.d.ts +13 -0
- package/dist/storage/executions/validation.d.ts.map +1 -0
- package/dist/storage/in-memory/index.d.ts +25 -5
- package/dist/storage/in-memory/index.d.ts.map +1 -1
- package/dist/storage/index.d.ts +30 -17
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/index.js +99 -29
- package/dist/storage/index.js.map +1 -1
- package/dist/storage/ontology/commits.d.ts +1 -0
- package/dist/storage/ontology/commits.d.ts.map +1 -1
- package/dist/storage/ontology/in-memory/index.d.ts +1 -0
- package/dist/storage/ontology/in-memory/index.d.ts.map +1 -1
- package/dist/storage/ontology/in-memory/materializations-state.d.ts +3 -2
- package/dist/storage/ontology/in-memory/materializations-state.d.ts.map +1 -1
- package/dist/storage/ontology/in-memory/materializations-work.d.ts +2 -2
- package/dist/storage/ontology/in-memory/materializations-work.d.ts.map +1 -1
- package/dist/storage/ontology/in-memory/materializations.d.ts +3 -1
- package/dist/storage/ontology/in-memory/materializations.d.ts.map +1 -1
- package/dist/storage/ontology/in-memory/shared-state.d.ts +7 -2
- package/dist/storage/ontology/in-memory/shared-state.d.ts.map +1 -1
- package/dist/storage/ontology/index.d.ts +3 -2
- package/dist/storage/ontology/index.d.ts.map +1 -1
- package/dist/storage/ontology/materializations.d.ts +53 -5
- package/dist/storage/ontology/materializations.d.ts.map +1 -1
- package/dist/storage/ontology/outbox.d.ts +8 -2
- package/dist/storage/ontology/outbox.d.ts.map +1 -1
- package/dist/storage/ontology/provider-work.d.ts.map +1 -1
- package/dist/storage/ontology/provider.d.ts +5 -22
- package/dist/storage/ontology/provider.d.ts.map +1 -1
- package/dist/storage/ontology/provider.js +6 -7
- package/dist/storage/ontology/provider.js.map +1 -1
- package/dist/storage/operation-scope.d.ts.map +1 -1
- package/dist/storage/operation-scope.js +1 -1
- package/dist/storage/pipeline-runs/idempotency.d.ts +3 -0
- package/dist/storage/pipeline-runs/idempotency.d.ts.map +1 -0
- package/dist/storage/pipeline-runs/in-memory.d.ts +5 -1
- package/dist/storage/pipeline-runs/in-memory.d.ts.map +1 -1
- package/dist/storage/pipeline-runs/index.d.ts +3 -1
- package/dist/storage/pipeline-runs/index.d.ts.map +1 -1
- package/dist/storage/pipeline-runs/provider.d.ts +10 -0
- package/dist/storage/pipeline-runs/provider.d.ts.map +1 -0
- package/dist/storage/pipeline-runs/provider.js +11 -0
- package/dist/storage/pipeline-runs/provider.js.map +9 -0
- package/dist/storage/pipeline-runs/types.d.ts +30 -14
- package/dist/storage/pipeline-runs/types.d.ts.map +1 -1
- package/dist/storage/projection-runs/in-memory.d.ts +8 -3
- package/dist/storage/projection-runs/in-memory.d.ts.map +1 -1
- package/dist/storage/projection-runs/index.d.ts +2 -2
- package/dist/storage/projection-runs/index.d.ts.map +1 -1
- package/dist/storage/projection-runs/lifecycle.d.ts +14 -8
- package/dist/storage/projection-runs/lifecycle.d.ts.map +1 -1
- package/dist/storage/projection-runs/provider.d.ts +13 -0
- package/dist/storage/projection-runs/provider.d.ts.map +1 -0
- package/dist/storage/projection-runs/{lifecycle.js → provider.js} +15 -4
- package/dist/storage/projection-runs/provider.js.map +9 -0
- package/dist/storage/projection-runs/types.d.ts +28 -11
- package/dist/storage/projection-runs/types.d.ts.map +1 -1
- package/dist/storage/run-listing.d.ts +8 -9
- package/dist/storage/run-listing.d.ts.map +1 -1
- package/dist/storage/sync-runs/idempotency.d.ts +3 -0
- package/dist/storage/sync-runs/idempotency.d.ts.map +1 -0
- package/dist/storage/sync-runs/in-memory.d.ts +5 -1
- package/dist/storage/sync-runs/in-memory.d.ts.map +1 -1
- package/dist/storage/sync-runs/index.d.ts +3 -1
- package/dist/storage/sync-runs/index.d.ts.map +1 -1
- package/dist/storage/sync-runs/provider.d.ts +10 -0
- package/dist/storage/sync-runs/provider.d.ts.map +1 -0
- package/dist/storage/sync-runs/provider.js +11 -0
- package/dist/storage/sync-runs/provider.js.map +9 -0
- package/dist/storage/sync-runs/types.d.ts +28 -11
- package/dist/storage/sync-runs/types.d.ts.map +1 -1
- package/dist/storage/types.d.ts +22 -15
- package/dist/storage/types.d.ts.map +1 -1
- package/dist/storage/webhook-runs/errors.d.ts +3 -0
- package/dist/storage/webhook-runs/errors.d.ts.map +1 -1
- package/dist/storage/webhook-runs/in-memory.d.ts +13 -1
- package/dist/storage/webhook-runs/in-memory.d.ts.map +1 -1
- package/dist/storage/webhook-runs/index.d.ts +3 -2
- package/dist/storage/webhook-runs/index.d.ts.map +1 -1
- package/dist/storage/webhook-runs/provider.d.ts +10 -0
- package/dist/storage/webhook-runs/provider.d.ts.map +1 -0
- package/dist/storage/webhook-runs/provider.js +11 -0
- package/dist/storage/webhook-runs/provider.js.map +9 -0
- package/dist/storage/webhook-runs/types.d.ts +37 -11
- package/dist/storage/webhook-runs/types.d.ts.map +1 -1
- package/dist/storage/workflow-runs/in-memory.d.ts +6 -2
- package/dist/storage/workflow-runs/in-memory.d.ts.map +1 -1
- package/dist/storage/workflow-runs/index.d.ts +2 -1
- package/dist/storage/workflow-runs/index.d.ts.map +1 -1
- package/dist/storage/workflow-runs/provider.d.ts +19 -0
- package/dist/storage/workflow-runs/provider.d.ts.map +1 -0
- package/dist/storage/workflow-runs/provider.js +20 -0
- package/dist/storage/workflow-runs/provider.js.map +9 -0
- package/dist/storage/workflow-runs/types.d.ts +28 -30
- package/dist/storage/workflow-runs/types.d.ts.map +1 -1
- package/dist/syncs/execution.d.ts +18 -0
- package/dist/syncs/execution.d.ts.map +1 -0
- package/dist/syncs/index.d.ts +3 -1
- package/dist/syncs/index.d.ts.map +1 -1
- package/dist/syncs/index.js +67 -0
- package/dist/syncs/index.js.map +9 -0
- package/dist/syncs/request.d.ts +6 -16
- package/dist/syncs/request.d.ts.map +1 -1
- package/dist/syncs/run-dispatch.d.ts +47 -0
- package/dist/syncs/run-dispatch.d.ts.map +1 -0
- package/dist/syncs/sources.d.ts +8 -0
- package/dist/syncs/sources.d.ts.map +1 -0
- package/dist/syncs/types.d.ts +16 -9
- package/dist/syncs/types.d.ts.map +1 -1
- package/dist/testing/action-execution.d.ts +12 -0
- package/dist/testing/action-execution.d.ts.map +1 -0
- package/dist/testing/agent-execution.d.ts +14 -0
- package/dist/testing/agent-execution.d.ts.map +1 -0
- package/dist/testing/agent-storage-contract.d.ts +12 -4
- package/dist/testing/agent-storage-contract.d.ts.map +1 -1
- package/dist/testing/ai-cost-storage-contract.d.ts +12 -0
- package/dist/testing/ai-cost-storage-contract.d.ts.map +1 -0
- package/dist/testing/ai-usage-storage-contract.d.ts +13 -0
- package/dist/testing/ai-usage-storage-contract.d.ts.map +1 -0
- package/dist/testing/auth-storage-contract.d.ts.map +1 -1
- package/dist/testing/broker-contract.d.ts.map +1 -1
- package/dist/testing/connector-connection-storage-contract.d.ts +16 -0
- package/dist/testing/connector-connection-storage-contract.d.ts.map +1 -0
- package/dist/testing/execution-storage-contract.d.ts +15 -0
- package/dist/testing/execution-storage-contract.d.ts.map +1 -0
- package/dist/testing/execution.d.ts +23 -0
- package/dist/testing/execution.d.ts.map +1 -0
- package/dist/testing/index.d.ts +13 -0
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +4754 -1592
- package/dist/testing/index.js.map +26 -13
- package/dist/testing/materializer-fixture.d.ts +2 -2
- package/dist/testing/materializer-fixture.d.ts.map +1 -1
- package/dist/testing/materializer-storage-contract.d.ts.map +1 -1
- package/dist/testing/ontology-contract-fixture.d.ts +1 -0
- package/dist/testing/ontology-contract-fixture.d.ts.map +1 -1
- package/dist/testing/ontology-storage-contract.d.ts.map +1 -1
- package/dist/testing/pipeline-execution.d.ts +16 -0
- package/dist/testing/pipeline-execution.d.ts.map +1 -0
- package/dist/testing/projection-execution.d.ts +20 -0
- package/dist/testing/projection-execution.d.ts.map +1 -0
- package/dist/testing/projection-run-storage-contract.d.ts +9 -4
- package/dist/testing/projection-run-storage-contract.d.ts.map +1 -1
- package/dist/testing/queues-contract.d.ts.map +1 -1
- package/dist/testing/sync-execution.d.ts +16 -0
- package/dist/testing/sync-execution.d.ts.map +1 -0
- package/dist/testing/webhook-execution.d.ts +12 -0
- package/dist/testing/webhook-execution.d.ts.map +1 -0
- package/dist/testing/webhook-run-storage-contract.d.ts +11 -0
- package/dist/testing/webhook-run-storage-contract.d.ts.map +1 -0
- package/dist/testing/workflow-execution.d.ts +23 -0
- package/dist/testing/workflow-execution.d.ts.map +1 -0
- package/dist/webhooks/index.d.ts +2 -1
- package/dist/webhooks/index.d.ts.map +1 -1
- package/dist/webhooks/internal.d.ts +2 -0
- package/dist/webhooks/internal.d.ts.map +1 -0
- package/dist/webhooks/internal.js +152 -0
- package/dist/webhooks/internal.js.map +10 -0
- package/dist/webhooks/registry.d.ts +18 -4
- package/dist/webhooks/registry.d.ts.map +1 -1
- package/dist/webhooks/run-admission.d.ts +25 -0
- package/dist/webhooks/run-admission.d.ts.map +1 -0
- package/dist/webhooks/types.d.ts +8 -5
- package/dist/webhooks/types.d.ts.map +1 -1
- package/dist/workers/index.js +29 -20
- package/dist/workers/index.js.map +4 -4
- package/dist/workers/queue-delivery.d.ts +7 -7
- package/dist/workers/queue-delivery.d.ts.map +1 -1
- package/dist/workers/queue-worker.d.ts +32 -11
- package/dist/workers/queue-worker.d.ts.map +1 -1
- package/dist/workflows/execution.d.ts +52 -0
- package/dist/workflows/execution.d.ts.map +1 -0
- package/dist/workflows/failure.d.ts +28 -0
- package/dist/workflows/failure.d.ts.map +1 -0
- package/dist/workflows/index.d.ts +4 -2
- package/dist/workflows/index.d.ts.map +1 -1
- package/dist/workflows/index.js +67 -36
- package/dist/workflows/index.js.map +1 -1
- package/dist/workflows/request.d.ts +2 -1
- package/dist/workflows/request.d.ts.map +1 -1
- package/dist/workflows/run-dispatch.d.ts +59 -0
- package/dist/workflows/run-dispatch.d.ts.map +1 -0
- package/dist/workflows/types.d.ts +38 -8
- package/dist/workflows/types.d.ts.map +1 -1
- package/package.json +113 -5
- package/src/actions/commit-edits.ts +0 -3
- package/src/actions/execution.ts +83 -0
- package/src/actions/index.ts +1 -1
- package/src/actions/registry.ts +22 -10
- package/src/actions/request.ts +55 -177
- package/src/actions/run-dispatch.ts +276 -0
- package/src/actions/types/context.ts +2 -4
- package/src/actions/validation.ts +2 -2
- package/src/agents/adapters.ts +71 -26
- package/src/agents/authority.ts +189 -0
- package/src/agents/dispatch.ts +1 -6
- package/src/agents/errors.ts +4 -2
- package/src/agents/execution.ts +266 -0
- package/src/agents/index.ts +33 -4
- package/src/agents/prompt.ts +47 -7
- package/src/agents/request.ts +158 -13
- package/src/agents/streams.ts +150 -3
- package/src/agents/thread-context-projection.ts +93 -0
- package/src/agents/tool-definition.ts +17 -2
- package/src/agents/tool-result.ts +61 -0
- package/src/agents/types.ts +49 -5
- package/src/agents/validation.ts +3 -3
- package/src/auth/attribution.ts +48 -0
- package/src/auth/index.ts +1 -0
- package/src/auth/runtime.ts +5 -5
- package/src/authorization/decision.ts +75 -14
- package/src/authorization/grant-kinds.ts +9 -0
- package/src/authorization/index.ts +2 -0
- package/src/blob-storage/execution.ts +78 -0
- package/src/bootstrap/discovery.ts +88 -268
- package/src/bootstrap/index.ts +2 -13
- package/src/broker/in-memory.ts +8 -1
- package/src/broker/types.ts +5 -0
- package/src/connectors/builders.ts +37 -2
- package/src/connectors/connections/authorizations.ts +646 -0
- package/src/connectors/connections/capability.ts +59 -0
- package/src/connectors/connections/command-context.ts +98 -0
- package/src/connectors/connections/contracts.ts +208 -0
- package/src/connectors/connections/credential-codec.ts +48 -0
- package/src/connectors/connections/credential-mutations.ts +574 -0
- package/src/connectors/connections/execution.ts +138 -0
- package/src/connectors/connections/internal.ts +17 -0
- package/src/connectors/connections/provider-operation.ts +41 -0
- package/src/connectors/connections/request.ts +447 -0
- package/src/connectors/connections/runs.ts +702 -0
- package/src/connectors/connections/service.ts +644 -0
- package/src/connectors/connections/storage-boundary.ts +13 -0
- package/src/connectors/connections/tokens.ts +292 -0
- package/src/connectors/connections/validation.ts +316 -0
- package/src/connectors/connections/views.ts +37 -0
- package/src/connectors/credentials.ts +149 -0
- package/src/connectors/errors.ts +111 -3
- package/src/connectors/execution.ts +157 -0
- package/src/connectors/index.ts +26 -2
- package/src/connectors/service.ts +142 -0
- package/src/connectors/types.ts +156 -7
- package/src/datasets/execution.ts +24 -0
- package/src/error-reporting/capability.ts +33 -106
- package/src/error-reporting/internal.ts +3 -1
- package/src/error-reporting/reporter.ts +19 -3
- package/src/error-reporting/reports.ts +172 -0
- package/src/error-reporting/types.ts +97 -43
- package/src/errors/catalog.ts +149 -0
- package/src/errors/internal.ts +322 -0
- package/src/errors/types.ts +21 -0
- package/src/events/definitions.ts +0 -4
- package/src/events/execution.ts +45 -0
- package/src/events/index.ts +15 -14
- package/src/events/outbox-dispatcher.ts +53 -18
- package/src/events/{runtime.ts → service.ts} +19 -23
- package/src/events/types/pipelines.ts +4 -1
- package/src/events/types/syncs.ts +3 -0
- package/src/events/types/workflows.ts +4 -2
- package/src/execution/agent.ts +130 -0
- package/src/execution/authorization.ts +409 -0
- package/src/execution/dispatch.ts +7 -0
- package/src/execution/durable.ts +193 -0
- package/src/execution/index.ts +12 -0
- package/src/execution/primitive.ts +50 -0
- package/src/execution/request.ts +109 -0
- package/src/execution/scopes.ts +198 -0
- package/src/execution/types.ts +113 -0
- package/src/http/api-routes.ts +3 -3
- package/src/index.ts +122 -9
- package/src/json.ts +0 -4
- package/src/logging/execution.ts +28 -0
- package/src/logging/index.ts +4 -4
- package/src/logging/{runtime.ts → service.ts} +7 -7
- package/src/materialization/events.ts +1 -0
- package/src/materialization/index.ts +2 -0
- package/src/materialization/model.ts +34 -18
- package/src/materializer/README.md +9 -13
- package/src/materializer/edits/apply.ts +55 -2
- package/src/materializer/edits/commit.ts +85 -28
- package/src/materializer/edits/load-state.ts +79 -16
- package/src/materializer/edits/operations.ts +80 -37
- package/src/materializer/edits/plan.ts +95 -22
- package/src/materializer/edits/working-state.ts +93 -55
- package/src/materializer/effective/build-events.ts +2 -0
- package/src/materializer/effective/diff.ts +22 -0
- package/src/materializer/effective/load-state.ts +0 -31
- package/src/materializer/effective/resolve.ts +140 -9
- package/src/materializer/execution/commit-lifecycle.ts +9 -1
- package/src/materializer/execution/plan-stream.ts +33 -9
- package/src/materializer/execution/scope.ts +95 -0
- package/src/materializer/execution/work-executor.ts +6 -2
- package/src/materializer/execution/work-records.ts +42 -7
- package/src/materializer/index.ts +9 -1
- package/src/materializer/materializer.ts +67 -5
- package/src/materializer/projections/entry-validator.ts +23 -1
- package/src/materializer/projections/finish-run.ts +29 -11
- package/src/materializer/projections/replace.ts +55 -22
- package/src/materializer/projections/replacement-plan.ts +39 -7
- package/src/materializer/shared/batching.ts +4 -1
- package/src/materializer/shared/normalize.ts +16 -19
- package/src/materializer/telemetry/append.ts +57 -26
- package/src/materializer/telemetry/plan.ts +15 -6
- package/src/objects/action/request.ts +5 -5
- package/src/objects/context/index.ts +1 -0
- package/src/objects/context/types.ts +6 -0
- package/src/objects/execution.ts +346 -0
- package/src/objects/materializer-adapter.ts +1 -23
- package/src/objects/query/executor.ts +15 -29
- package/src/objects/query/index.ts +1 -2
- package/src/objects/query/planner.ts +0 -6
- package/src/objects/sdk/object-handle.ts +2 -2
- package/src/objects/sdk/object-set.ts +17 -7
- package/src/objects/sdk/runtime-query-executor.ts +9 -2
- package/src/objects/sdk/telemetry-channel.ts +5 -1
- package/src/objects/service/action-service.ts +5 -2
- package/src/objects/service/list-service.ts +1 -1
- package/src/objects/telemetry/history.ts +8 -3
- package/src/objects/telemetry/write-batch.ts +0 -2
- package/src/ontology/index.ts +6 -1
- package/src/ontology/registry.ts +16 -2
- package/src/pipelines/execution.ts +105 -0
- package/src/pipelines/index.ts +7 -0
- package/src/pipelines/request.ts +32 -26
- package/src/pipelines/run-dispatch.ts +308 -0
- package/src/projections/builders.ts +100 -44
- package/src/projections/capability.ts +37 -0
- package/src/projections/execution.ts +85 -0
- package/src/projections/index.ts +8 -1
- package/src/projections/internal.ts +21 -61
- package/src/projections/ownership.ts +2 -2
- package/src/projections/registry.ts +33 -11
- package/src/projections/revision.ts +11 -5
- package/src/projections/run-dispatch.ts +497 -0
- package/src/projections/run-id.ts +20 -0
- package/src/projections/timestamp.ts +66 -0
- package/src/projections/types.ts +19 -0
- package/src/projections/validation.ts +27 -3
- package/src/queues/in-memory.ts +37 -11
- package/src/queues/index.ts +10 -2
- package/src/queues/types.ts +78 -45
- package/src/rules/execution.ts +49 -0
- package/src/rules/index.ts +0 -1
- package/src/rules/validation.ts +2 -6
- package/src/runtime/ai-cost.ts +15 -0
- package/src/runtime/ai-usage.ts +17 -0
- package/src/runtime/create.ts +28 -68
- package/src/runtime/definitions.ts +44 -0
- package/src/runtime/host.ts +377 -0
- package/src/runtime/index.ts +5 -13
- package/src/runtime/internal.ts +12 -0
- package/src/runtime/ontology-mutations.ts +5 -3
- package/src/runtime/resolve-definitions.ts +238 -0
- package/src/runtime/sixb.ts +95 -822
- package/src/runtime/types.ts +17 -290
- package/src/scheduler/index.ts +1 -1
- package/src/scheduler/runtime.ts +37 -6
- package/src/schedules/execution.ts +14 -0
- package/src/schedules/types.ts +0 -8
- package/src/security/every.ts +4 -0
- package/src/security/grants.ts +13 -1
- package/src/security/index.ts +3 -1
- package/src/security/registry.ts +107 -0
- package/src/security/types.ts +8 -12
- package/src/security/validation.ts +7 -0
- package/src/storage/action-runs/failure.ts +64 -0
- package/src/storage/action-runs/idempotency.ts +3 -1
- package/src/storage/action-runs/in-memory.ts +39 -9
- package/src/storage/action-runs/index.ts +3 -0
- package/src/storage/action-runs/provider.ts +25 -0
- package/src/storage/action-runs/types.ts +61 -27
- package/src/storage/agents/errors.ts +1 -0
- package/src/storage/agents/in-memory.ts +219 -14
- package/src/storage/agents/index.ts +7 -1
- package/src/storage/agents/provider.ts +252 -0
- package/src/storage/agents/types.ts +96 -22
- package/src/storage/ai-cost/analytics.ts +602 -0
- package/src/storage/ai-cost/codec.ts +136 -0
- package/src/storage/ai-cost/errors.ts +12 -0
- package/src/storage/ai-cost/in-memory.ts +164 -0
- package/src/storage/ai-cost/index.ts +35 -0
- package/src/storage/ai-cost/provider.ts +20 -0
- package/src/storage/ai-cost/types.ts +193 -0
- package/src/storage/ai-cost/validation.ts +337 -0
- package/src/storage/ai-usage/errors.ts +13 -0
- package/src/storage/ai-usage/in-memory.ts +162 -0
- package/src/storage/ai-usage/index.ts +21 -0
- package/src/storage/ai-usage/record.ts +74 -0
- package/src/storage/ai-usage/types.ts +102 -0
- package/src/storage/ai-usage/usage.ts +104 -0
- package/src/storage/auth/types.ts +1 -0
- package/src/storage/connector-connections/errors.ts +24 -0
- package/src/storage/connector-connections/in-memory.ts +1377 -0
- package/src/storage/connector-connections/index.ts +66 -0
- package/src/storage/connector-connections/provider/authorizations.ts +446 -0
- package/src/storage/connector-connections/provider/connections.ts +291 -0
- package/src/storage/connector-connections/provider/runs.ts +369 -0
- package/src/storage/connector-connections/provider/shared.ts +342 -0
- package/src/storage/connector-connections/provider.ts +219 -0
- package/src/storage/connector-connections/types.ts +546 -0
- package/src/storage/executions/errors.ts +21 -0
- package/src/storage/executions/in-memory.ts +75 -0
- package/src/storage/executions/index.ts +16 -0
- package/src/storage/executions/provider.ts +292 -0
- package/src/storage/executions/run-link.ts +70 -0
- package/src/storage/executions/types.ts +49 -0
- package/src/storage/executions/validation.ts +370 -0
- package/src/storage/in-memory/index.ts +100 -16
- package/src/storage/index.ts +191 -15
- package/src/storage/ontology/commits.ts +1 -0
- package/src/storage/ontology/in-memory/index.ts +2 -0
- package/src/storage/ontology/in-memory/materializations-finalization.ts +2 -1
- package/src/storage/ontology/in-memory/materializations-state.ts +10 -0
- package/src/storage/ontology/in-memory/materializations-work.ts +2 -1
- package/src/storage/ontology/in-memory/materializations.ts +132 -9
- package/src/storage/ontology/in-memory/outbox.ts +1 -1
- package/src/storage/ontology/in-memory/shared-state.ts +12 -1
- package/src/storage/ontology/index.ts +6 -0
- package/src/storage/ontology/materializations.ts +53 -4
- package/src/storage/ontology/outbox.ts +13 -2
- package/src/storage/ontology/provider-header-validation.ts +1 -0
- package/src/storage/ontology/provider-work.ts +33 -14
- package/src/storage/ontology/provider.ts +72 -52
- package/src/storage/operation-scope.ts +2 -0
- package/src/storage/pipeline-runs/idempotency.ts +14 -0
- package/src/storage/pipeline-runs/in-memory.ts +88 -8
- package/src/storage/pipeline-runs/index.ts +5 -1
- package/src/storage/pipeline-runs/provider.ts +25 -0
- package/src/storage/pipeline-runs/types.ts +37 -14
- package/src/storage/projection-runs/in-memory.ts +93 -24
- package/src/storage/projection-runs/index.ts +4 -0
- package/src/storage/projection-runs/lifecycle.ts +165 -36
- package/src/storage/projection-runs/provider.ts +34 -0
- package/src/storage/projection-runs/types.ts +34 -11
- package/src/storage/run-listing.ts +22 -13
- package/src/storage/sync-runs/idempotency.ts +18 -0
- package/src/storage/sync-runs/in-memory.ts +90 -7
- package/src/storage/sync-runs/index.ts +4 -1
- package/src/storage/sync-runs/provider.ts +25 -0
- package/src/storage/sync-runs/types.ts +35 -11
- package/src/storage/types.ts +46 -17
- package/src/storage/webhook-runs/errors.ts +14 -0
- package/src/storage/webhook-runs/in-memory.ts +84 -9
- package/src/storage/webhook-runs/index.ts +5 -1
- package/src/storage/webhook-runs/provider.ts +30 -0
- package/src/storage/webhook-runs/types.ts +52 -11
- package/src/storage/workflow-runs/in-memory.ts +89 -55
- package/src/storage/workflow-runs/index.ts +2 -0
- package/src/storage/workflow-runs/provider.ts +70 -0
- package/src/storage/workflow-runs/types.ts +36 -25
- package/src/syncs/builders.ts +2 -2
- package/src/syncs/execution.ts +78 -0
- package/src/syncs/index.ts +13 -0
- package/src/syncs/request.ts +32 -43
- package/src/syncs/run-dispatch.ts +312 -0
- package/src/syncs/sources.ts +20 -0
- package/src/syncs/types.ts +32 -8
- package/src/testing/action-execution.ts +61 -0
- package/src/testing/agent-execution.ts +81 -0
- package/src/testing/agent-storage-contract.ts +498 -64
- package/src/testing/ai-cost-storage-contract.ts +320 -0
- package/src/testing/ai-usage-storage-contract.ts +528 -0
- package/src/testing/auth-storage-contract.ts +17 -1
- package/src/testing/broker-contract.ts +16 -1
- package/src/testing/connector-connection-storage-contract.ts +1052 -0
- package/src/testing/execution-storage-contract.ts +435 -0
- package/src/testing/execution.ts +48 -0
- package/src/testing/index.ts +57 -0
- package/src/testing/materializer-fixture.ts +11 -3
- package/src/testing/materializer-storage-contract.ts +333 -13
- package/src/testing/ontology-contract-fixture.ts +35 -2
- package/src/testing/ontology-storage-contract.ts +75 -14
- package/src/testing/pipeline-execution.ts +64 -0
- package/src/testing/projection-execution.ts +98 -0
- package/src/testing/projection-run-storage-contract.ts +215 -29
- package/src/testing/queues-contract.ts +40 -51
- package/src/testing/sync-execution.ts +61 -0
- package/src/testing/webhook-execution.ts +47 -0
- package/src/testing/webhook-run-storage-contract.ts +240 -0
- package/src/testing/workflow-execution.ts +77 -0
- package/src/webhooks/index.ts +2 -1
- package/src/webhooks/internal.ts +5 -0
- package/src/webhooks/registry.ts +60 -36
- package/src/webhooks/run-admission.ts +172 -0
- package/src/webhooks/types.ts +8 -5
- package/src/workers/queue-delivery.ts +25 -22
- package/src/workers/queue-worker.ts +76 -33
- package/src/workflows/execution.ts +313 -0
- package/src/workflows/failure.ts +63 -0
- package/src/workflows/index.ts +10 -1
- package/src/workflows/request.ts +39 -118
- package/src/workflows/run-dispatch.ts +359 -0
- package/src/workflows/types.ts +39 -8
- package/dist/actions/runtime.d.ts +0 -11
- package/dist/actions/runtime.d.ts.map +0 -1
- package/dist/agents/runtime.d.ts +0 -41
- package/dist/agents/runtime.d.ts.map +0 -1
- package/dist/chunk-4hwxq5e6.js +0 -49
- package/dist/chunk-4hwxq5e6.js.map +0 -10
- package/dist/chunk-4tvj3ate.js.map +0 -11
- package/dist/chunk-50kv63vj.js.map +0 -12
- package/dist/chunk-86459jn0.js +0 -1091
- package/dist/chunk-86459jn0.js.map +0 -22
- package/dist/chunk-867jxh7c.js.map +0 -19
- package/dist/chunk-9k3hgv8h.js +0 -352
- package/dist/chunk-9k3hgv8h.js.map +0 -13
- package/dist/chunk-avppcgt6.js.map +0 -14
- package/dist/chunk-b1bqvhpe.js.map +0 -13
- package/dist/chunk-b5dp7gaf.js +0 -1092
- package/dist/chunk-b5dp7gaf.js.map +0 -26
- package/dist/chunk-bh8bwma3.js +0 -37
- package/dist/chunk-bh8bwma3.js.map +0 -10
- package/dist/chunk-btcsywk4.js +0 -985
- package/dist/chunk-btcsywk4.js.map +0 -15
- package/dist/chunk-exrfbt2d.js +0 -354
- package/dist/chunk-exrfbt2d.js.map +0 -17
- package/dist/chunk-hb9xcx9c.js.map +0 -14
- package/dist/chunk-k25jm1x5.js +0 -102
- package/dist/chunk-k25jm1x5.js.map +0 -10
- package/dist/chunk-k6j72mtt.js +0 -9
- package/dist/chunk-k6j72mtt.js.map +0 -10
- package/dist/chunk-m9w0artv.js +0 -554
- package/dist/chunk-m9w0artv.js.map +0 -13
- package/dist/chunk-nbywkytr.js.map +0 -16
- package/dist/chunk-p7vj8xgb.js.map +0 -34
- package/dist/chunk-raq0x6bd.js.map +0 -48
- package/dist/chunk-rgzed50y.js +0 -1445
- package/dist/chunk-rgzed50y.js.map +0 -22
- package/dist/chunk-rjqm6ksg.js.map +0 -44
- package/dist/chunk-t72dvahb.js.map +0 -12
- package/dist/chunk-v5c085yp.js.map +0 -10
- package/dist/chunk-xt6qx9sh.js.map +0 -36
- package/dist/chunk-xz5g49bp.js.map +0 -11
- package/dist/chunk-ya6brh8a.js.map +0 -11
- package/dist/chunk-yn947ck3.js.map +0 -14
- package/dist/connectors/runtime.d.ts +0 -13
- package/dist/connectors/runtime.d.ts.map +0 -1
- package/dist/events/runtime.d.ts.map +0 -1
- package/dist/objects/contexts.d.ts +0 -45
- package/dist/objects/contexts.d.ts.map +0 -1
- package/dist/objects/helpers.d.ts +0 -7
- package/dist/objects/helpers.d.ts.map +0 -1
- package/dist/runtime/scoped.d.ts +0 -158
- package/dist/runtime/scoped.d.ts.map +0 -1
- package/dist/security/runtime.d.ts +0 -16
- package/dist/security/runtime.d.ts.map +0 -1
- package/dist/storage/webhook-deliveries/in-memory.d.ts +0 -18
- package/dist/storage/webhook-deliveries/in-memory.d.ts.map +0 -1
- package/dist/storage/webhook-deliveries/index.d.ts +0 -3
- package/dist/storage/webhook-deliveries/index.d.ts.map +0 -1
- package/dist/storage/webhook-deliveries/types.d.ts +0 -43
- package/dist/storage/webhook-deliveries/types.d.ts.map +0 -1
- package/dist/workflows/runtime.d.ts +0 -33
- package/dist/workflows/runtime.d.ts.map +0 -1
- package/src/actions/runtime.ts +0 -31
- package/src/agents/runtime.ts +0 -124
- package/src/connectors/runtime.ts +0 -100
- package/src/objects/contexts.ts +0 -64
- package/src/objects/helpers.ts +0 -18
- package/src/runtime/scoped.ts +0 -436
- package/src/security/runtime.ts +0 -101
- package/src/storage/webhook-deliveries/in-memory.ts +0 -108
- package/src/storage/webhook-deliveries/index.ts +0 -9
- package/src/storage/webhook-deliveries/types.ts +0 -41
- package/src/workflows/runtime.ts +0 -68
- /package/dist/{chunk-md9jbrm9.js.map → chunk-4gz41why.js.map} +0 -0
- /package/dist/{chunk-6rzdtvn5.js.map → chunk-8b55ygje.js.map} +0 -0
- /package/dist/{chunk-r82k4z7z.js.map → chunk-a31h57d5.js.map} +0 -0
- /package/dist/{chunk-qzyemcj7.js.map → chunk-ckxfnx7f.js.map} +0 -0
- /package/dist/{chunk-53s4asfm.js.map → chunk-rnshztfq.js.map} +0 -0
- /package/dist/{chunk-8kv2sez0.js.map → chunk-vybf6pkp.js.map} +0 -0
- /package/dist/{chunk-6zrpewy4.js.map → chunk-z3zp0bj1.js.map} +0 -0
- /package/dist/{chunk-hz8m927w.js.map → chunk-zqysyfjt.js.map} +0 -0
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
compareCardinalityWork,
|
|
17
17
|
compareEventWork,
|
|
18
18
|
comparePlanWork,
|
|
19
|
+
createEventId,
|
|
19
20
|
finishScopeAccumulator,
|
|
20
21
|
invalidCorrelation,
|
|
21
22
|
isExactStagingManifest,
|
|
@@ -26,7 +27,7 @@ import {
|
|
|
26
27
|
startScopeAccumulator,
|
|
27
28
|
uniqueSorted,
|
|
28
29
|
workUniquenessKey
|
|
29
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-fmx1sz2h.js";
|
|
30
31
|
import {
|
|
31
32
|
createAgentOperationScope,
|
|
32
33
|
createAuthOperationScope,
|
|
@@ -34,20 +35,28 @@ import {
|
|
|
34
35
|
createOperationScopedFacade,
|
|
35
36
|
createStorageOperationScope,
|
|
36
37
|
createWorkflowRunOperationScope
|
|
37
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-xc7hq65b.js";
|
|
39
|
+
import {
|
|
40
|
+
PipelineRunError,
|
|
41
|
+
assertPipelineRunExecution
|
|
42
|
+
} from "./chunk-cy0n5dms.js";
|
|
38
43
|
import {
|
|
39
44
|
ProjectionRunError,
|
|
40
45
|
advanceProjectionTelemetry,
|
|
41
46
|
assertGenericProgressDoesNotAdvanceTelemetry,
|
|
42
47
|
assertProjectionMissingTarget,
|
|
43
|
-
|
|
48
|
+
assertProjectionRunAttempt,
|
|
49
|
+
assertProjectionRunDurableExecution,
|
|
44
50
|
assertProjectionRunIdentityMatches,
|
|
45
51
|
assertProjectionRunListWindow,
|
|
46
52
|
assertProjectionRunNonEmpty,
|
|
53
|
+
assertProjectionRunQueueInput,
|
|
47
54
|
assertProjectionRunRunning,
|
|
48
55
|
assertProjectionRunStartInput,
|
|
56
|
+
canRequeueProjectionRunAfterEnqueueFailure,
|
|
49
57
|
createProjectionRunClaim,
|
|
50
58
|
createProjectionRunRecord,
|
|
59
|
+
failProjectionRunEnqueue,
|
|
51
60
|
finishProjectionRunRecord,
|
|
52
61
|
immutableDatasetVersionConflict,
|
|
53
62
|
mergeProjectionRunProgress,
|
|
@@ -57,50 +66,95 @@ import {
|
|
|
57
66
|
publicProjectionRunRecord,
|
|
58
67
|
requireTelemetryProjectionRun,
|
|
59
68
|
staleProjectionRunExecution
|
|
60
|
-
} from "./chunk-
|
|
69
|
+
} from "./chunk-dysw7nsm.js";
|
|
61
70
|
import {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
} from "./chunk-
|
|
71
|
+
SyncRunError,
|
|
72
|
+
assertSyncRunExecution
|
|
73
|
+
} from "./chunk-62c7t4jc.js";
|
|
74
|
+
import {
|
|
75
|
+
WebhookRunError,
|
|
76
|
+
assertWebhookRunExecution
|
|
77
|
+
} from "./chunk-ezake7g1.js";
|
|
78
|
+
import {
|
|
79
|
+
WorkflowRunError,
|
|
80
|
+
assertWorkflowAgentNodeRunExecution,
|
|
81
|
+
assertWorkflowRunExecution
|
|
82
|
+
} from "./chunk-pxtrxm3p.js";
|
|
83
|
+
import {
|
|
84
|
+
parseActionRunFailure
|
|
85
|
+
} from "./chunk-htq0qh7z.js";
|
|
86
|
+
import {
|
|
87
|
+
ActionRunError,
|
|
88
|
+
assertActionRunExecution
|
|
89
|
+
} from "./chunk-xkthy56g.js";
|
|
65
90
|
import {
|
|
66
|
-
|
|
67
|
-
|
|
91
|
+
AgentStorageError,
|
|
92
|
+
agentContextCheckpointMatchesCreateInput,
|
|
93
|
+
assertAgentContextCheckpointAnchors,
|
|
94
|
+
assertAgentContextCheckpointAuthority,
|
|
95
|
+
assertAgentContextCheckpointReplayState,
|
|
96
|
+
assertAgentRunExecution,
|
|
97
|
+
assertCreateAgentContextCheckpointInput
|
|
98
|
+
} from "./chunk-qer6am8w.js";
|
|
99
|
+
import {
|
|
100
|
+
InMemoryAiUsageStorage,
|
|
101
|
+
aiModelCallCostMatchesUsage,
|
|
102
|
+
buildAiAccountingOverview,
|
|
103
|
+
buildAiModelCallAccountingList,
|
|
104
|
+
normalizeAiModelCallCostRecord
|
|
105
|
+
} from "./chunk-kqxgf6kv.js";
|
|
106
|
+
import {
|
|
107
|
+
CONNECTOR_CONNECTION_RUN_FAILURE_CODES,
|
|
108
|
+
ConnectorConnectionStorageError
|
|
109
|
+
} from "./chunk-5gd7tpv6.js";
|
|
110
|
+
import {
|
|
111
|
+
ExecutionStorageError,
|
|
112
|
+
cloneExecutionRecord,
|
|
113
|
+
normalizeExecutionRecord,
|
|
114
|
+
validateExecutionRecordReferences
|
|
115
|
+
} from "./chunk-h9kxd41f.js";
|
|
68
116
|
import {
|
|
69
117
|
assertPinnedDatasetWatermark
|
|
70
118
|
} from "./chunk-9dzba0f2.js";
|
|
71
119
|
import {
|
|
72
120
|
linkRefKey,
|
|
73
121
|
linkRefSortKey,
|
|
122
|
+
linkScopeKey,
|
|
74
123
|
linkScopeSortKey,
|
|
75
124
|
objectRefKey,
|
|
76
125
|
objectRefSortKey,
|
|
77
126
|
projectionEntityKey,
|
|
78
127
|
telemetryPointKey,
|
|
79
128
|
telemetryPointSortKey
|
|
80
|
-
} from "./chunk-
|
|
129
|
+
} from "./chunk-vybf6pkp.js";
|
|
81
130
|
import {
|
|
82
131
|
MaterializationConflictError,
|
|
83
132
|
MaterializationValidationError
|
|
84
133
|
} from "./chunk-ry24jbr1.js";
|
|
85
134
|
import {
|
|
86
|
-
|
|
87
|
-
|
|
135
|
+
compareQueryScalarValues,
|
|
136
|
+
queryScalarValuesEqual
|
|
137
|
+
} from "./chunk-6wetht33.js";
|
|
138
|
+
import {
|
|
139
|
+
AGENT_RUN_FAILURE_CODES
|
|
140
|
+
} from "./chunk-t0jjkep3.js";
|
|
88
141
|
import {
|
|
89
142
|
InMemoryAuthStorage,
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
} from "./chunk-
|
|
143
|
+
paginate,
|
|
144
|
+
principalsEqual
|
|
145
|
+
} from "./chunk-d2adj15j.js";
|
|
146
|
+
import {
|
|
147
|
+
normalizeRequesterGroupIds
|
|
148
|
+
} from "./chunk-rhrbz7d4.js";
|
|
149
|
+
import {
|
|
150
|
+
createSixbError,
|
|
151
|
+
parseSixbFailure,
|
|
152
|
+
toSixbFailure
|
|
153
|
+
} from "./chunk-0172wgm9.js";
|
|
93
154
|
import {
|
|
94
155
|
cloneJsonValue,
|
|
95
156
|
stableJsonStringify
|
|
96
|
-
} from "./chunk-
|
|
97
|
-
// src/storage/action-runs/errors.ts
|
|
98
|
-
class ActionRunError extends MaterializationConflictError {
|
|
99
|
-
name = "ActionRunError";
|
|
100
|
-
constructor(message) {
|
|
101
|
-
super("run-correlation", message);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
157
|
+
} from "./chunk-t8t39h7v.js";
|
|
104
158
|
// src/storage/action-runs/idempotency.ts
|
|
105
159
|
function actionSubjectsEqual(left, right) {
|
|
106
160
|
if (left.kind !== right.kind)
|
|
@@ -121,10 +175,10 @@ function finishActionRunPhase(input, current) {
|
|
|
121
175
|
if (input.status === "succeeded") {
|
|
122
176
|
return input.phase ?? current ?? "validation";
|
|
123
177
|
}
|
|
124
|
-
return input.
|
|
178
|
+
return input.error.details.phase;
|
|
125
179
|
}
|
|
126
180
|
function canRequeueActionRunAfterEnqueueFailure(existing, input) {
|
|
127
|
-
return existing.status === "failed" && existing.phase === "enqueue" && existing.actionId === input.actionId && existing.idempotencyKey === input.idempotencyKey && actionSubjectsEqual(existing.subject, input.subject) && actionRunParamsEqual(existing.params, input.params);
|
|
181
|
+
return existing.status === "failed" && existing.phase === "enqueue" && existing.executionId === input.executionId && existing.error?.retryable === true && existing.actionId === input.actionId && existing.idempotencyKey === input.idempotencyKey && actionSubjectsEqual(existing.subject, input.subject) && actionRunParamsEqual(existing.params, input.params);
|
|
128
182
|
}
|
|
129
183
|
function isTerminalActionRun(record) {
|
|
130
184
|
return record.status === "succeeded" || record.status === "failed" || record.status === "cancelled";
|
|
@@ -152,8 +206,8 @@ function normalizeParams(params) {
|
|
|
152
206
|
function normalizeSubject(subject) {
|
|
153
207
|
return structuredClone(subject);
|
|
154
208
|
}
|
|
155
|
-
function normalizeError(error) {
|
|
156
|
-
return
|
|
209
|
+
function normalizeError(error, expectedPhase) {
|
|
210
|
+
return expectedPhase === undefined ? parseActionRunFailure(error) : parseActionRunFailure(error, expectedPhase);
|
|
157
211
|
}
|
|
158
212
|
function normalizeWriteback(input, completedAt) {
|
|
159
213
|
if (input.status === "succeeded") {
|
|
@@ -166,7 +220,7 @@ function normalizeWriteback(input, completedAt) {
|
|
|
166
220
|
return {
|
|
167
221
|
status: "failed",
|
|
168
222
|
completedAt,
|
|
169
|
-
error: normalizeError(input.error)
|
|
223
|
+
error: normalizeError(input.error, "writeback")
|
|
170
224
|
};
|
|
171
225
|
}
|
|
172
226
|
function normalizeEffects(input, completedAt) {
|
|
@@ -179,7 +233,7 @@ function normalizeEffects(input, completedAt) {
|
|
|
179
233
|
return {
|
|
180
234
|
status: "failed",
|
|
181
235
|
completedAt,
|
|
182
|
-
error: normalizeError(input.error)
|
|
236
|
+
error: normalizeError(input.error, "effects")
|
|
183
237
|
};
|
|
184
238
|
}
|
|
185
239
|
function compareRuns(a, b, order) {
|
|
@@ -196,9 +250,11 @@ function compareRuns(a, b, order) {
|
|
|
196
250
|
}
|
|
197
251
|
|
|
198
252
|
class InMemoryActionRunStorage {
|
|
253
|
+
executions;
|
|
199
254
|
rows = new Map;
|
|
200
255
|
runRootOperation;
|
|
201
|
-
constructor(input = {}) {
|
|
256
|
+
constructor(executions, input = {}) {
|
|
257
|
+
this.executions = executions;
|
|
202
258
|
this.runRootOperation = input.runRootOperation ?? runDirectly;
|
|
203
259
|
}
|
|
204
260
|
snapshot() {
|
|
@@ -214,15 +270,26 @@ class InMemoryActionRunStorage {
|
|
|
214
270
|
return this.runRootOperation(() => cloneActionRunRecord(this.requireMaterializationRun(input)));
|
|
215
271
|
}
|
|
216
272
|
async queue(input) {
|
|
217
|
-
return this.runRootOperation(() => {
|
|
273
|
+
return this.runRootOperation(async () => {
|
|
218
274
|
const key = actionRunKey(input.projectId, input.id);
|
|
219
275
|
const existing = this.rows.get(key);
|
|
220
276
|
if (existing && !canRequeueActionRunAfterEnqueueFailure(existing, input)) {
|
|
221
277
|
throw new ActionRunError(`[Sixb] Action run '${input.id}' already exists for project '${input.projectId}'.`);
|
|
222
278
|
}
|
|
279
|
+
if ([...this.rows.values()].some((run) => run.projectId === input.projectId && run.id !== input.id && run.executionId === input.executionId)) {
|
|
280
|
+
throw new ActionRunError(`[Sixb] Execution '${input.executionId}' already belongs to another Action run.`);
|
|
281
|
+
}
|
|
282
|
+
await assertActionRunExecution({
|
|
283
|
+
executions: this.executions,
|
|
284
|
+
projectId: input.projectId,
|
|
285
|
+
executionId: input.executionId,
|
|
286
|
+
runId: input.id,
|
|
287
|
+
actionId: input.actionId
|
|
288
|
+
});
|
|
223
289
|
const record = {
|
|
224
290
|
id: input.id,
|
|
225
291
|
projectId: input.projectId,
|
|
292
|
+
executionId: input.executionId,
|
|
226
293
|
actionId: input.actionId,
|
|
227
294
|
subject: normalizeSubject(input.subject),
|
|
228
295
|
status: "queued",
|
|
@@ -333,7 +400,7 @@ class InMemoryActionRunStorage {
|
|
|
333
400
|
if (isTerminalActionRun(existing)) {
|
|
334
401
|
throw new ActionRunError(`[Sixb] Action run '${input.id}' cannot finish from terminal status '${existing.status}'.`);
|
|
335
402
|
}
|
|
336
|
-
const phase = input.status === "succeeded" ? input.phase ?? existing.phase : input.
|
|
403
|
+
const phase = input.status === "succeeded" ? input.phase ?? existing.phase : input.error.details.phase;
|
|
337
404
|
const base = {
|
|
338
405
|
...existing,
|
|
339
406
|
status: input.status,
|
|
@@ -401,6 +468,1405 @@ class InMemoryActionRunStorage {
|
|
|
401
468
|
return existing;
|
|
402
469
|
}
|
|
403
470
|
}
|
|
471
|
+
// src/agents/message.ts
|
|
472
|
+
var AGENT_MESSAGE_CONTENT_VERSION = 1;
|
|
473
|
+
|
|
474
|
+
// src/storage/agents/in-memory.ts
|
|
475
|
+
function normalizeFailure(failure) {
|
|
476
|
+
return failure ? parseSixbFailure(failure, AGENT_RUN_FAILURE_CODES) : undefined;
|
|
477
|
+
}
|
|
478
|
+
function key(projectId, id) {
|
|
479
|
+
return `${projectId}:${id}`;
|
|
480
|
+
}
|
|
481
|
+
function clone(value) {
|
|
482
|
+
return structuredClone(value);
|
|
483
|
+
}
|
|
484
|
+
function compareByDate(left, right, leftId, rightId, order) {
|
|
485
|
+
const delta = (left?.getTime() ?? 0) - (right?.getTime() ?? 0);
|
|
486
|
+
if (delta !== 0) {
|
|
487
|
+
return order === "asc" ? delta : -delta;
|
|
488
|
+
}
|
|
489
|
+
if (leftId === rightId) {
|
|
490
|
+
return 0;
|
|
491
|
+
}
|
|
492
|
+
return order === "asc" ? leftId.localeCompare(rightId) : rightId.localeCompare(leftId);
|
|
493
|
+
}
|
|
494
|
+
function applyWindow(rows, offset = 0, limit) {
|
|
495
|
+
const total = rows.length;
|
|
496
|
+
const end = limit === undefined ? total : offset + limit;
|
|
497
|
+
const page = rows.slice(offset, end);
|
|
498
|
+
return { page, hasMore: offset + page.length < total, total };
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
class InMemoryAgentThreadStore {
|
|
502
|
+
state;
|
|
503
|
+
constructor(state) {
|
|
504
|
+
this.state = state;
|
|
505
|
+
}
|
|
506
|
+
async create(input) {
|
|
507
|
+
const threadKey = key(input.projectId, input.id);
|
|
508
|
+
if (this.state.threads.has(threadKey)) {
|
|
509
|
+
throw new AgentStorageError("duplicate_id", `[Sixb] Agent thread '${input.id}' already exists for project '${input.projectId}'.`);
|
|
510
|
+
}
|
|
511
|
+
const createdAt = new Date(input.createdAt ?? new Date);
|
|
512
|
+
const record = {
|
|
513
|
+
id: input.id,
|
|
514
|
+
projectId: input.projectId,
|
|
515
|
+
agentId: input.agentId,
|
|
516
|
+
ownerPrincipal: clone(input.ownerPrincipal),
|
|
517
|
+
...input.title === undefined ? {} : { title: input.title },
|
|
518
|
+
status: input.status ?? "active",
|
|
519
|
+
activeRunId: null,
|
|
520
|
+
messageCount: 0,
|
|
521
|
+
createdAt,
|
|
522
|
+
updatedAt: new Date(input.updatedAt ?? createdAt)
|
|
523
|
+
};
|
|
524
|
+
this.state.threads.set(threadKey, clone(record));
|
|
525
|
+
return clone(record);
|
|
526
|
+
}
|
|
527
|
+
async getById(params) {
|
|
528
|
+
const record = this.state.threads.get(key(params.projectId, params.id));
|
|
529
|
+
return record ? clone(record) : null;
|
|
530
|
+
}
|
|
531
|
+
async list(input) {
|
|
532
|
+
const order = input.order ?? "desc";
|
|
533
|
+
const statuses = input.statuses ? new Set(input.statuses) : null;
|
|
534
|
+
const agentIds = input.agentIds ? new Set(input.agentIds) : null;
|
|
535
|
+
const filtered = [...this.state.threads.values()].filter((thread) => thread.projectId === input.projectId).filter((thread) => input.agentId ? thread.agentId === input.agentId : true).filter((thread) => agentIds ? agentIds.has(thread.agentId) : true).filter((thread) => statuses ? statuses.has(thread.status) : true).filter((thread) => input.ownerPrincipal ? principalsEqual(thread.ownerPrincipal, input.ownerPrincipal) : true).sort((a, b) => compareByDate(a.lastMessageAt ?? a.createdAt, b.lastMessageAt ?? b.createdAt, a.id, b.id, order));
|
|
536
|
+
const { page, hasMore, total } = applyWindow(filtered, input.offset, input.limit);
|
|
537
|
+
return { threads: page.map(clone), hasMore, total };
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
class InMemoryAgentRunStore {
|
|
542
|
+
state;
|
|
543
|
+
executions;
|
|
544
|
+
constructor(state, executions) {
|
|
545
|
+
this.state = state;
|
|
546
|
+
this.executions = executions;
|
|
547
|
+
}
|
|
548
|
+
async create(input) {
|
|
549
|
+
await assertAgentRunExecution({
|
|
550
|
+
executions: this.executions,
|
|
551
|
+
projectId: input.projectId,
|
|
552
|
+
executionId: input.executionId,
|
|
553
|
+
runId: input.id,
|
|
554
|
+
agentId: input.agentId
|
|
555
|
+
});
|
|
556
|
+
const threadKey = key(input.projectId, input.threadId);
|
|
557
|
+
const thread = this.state.threads.get(threadKey);
|
|
558
|
+
if (!thread) {
|
|
559
|
+
throw new AgentStorageError("thread_not_found", `[Sixb] Agent thread '${input.threadId}' not found for project '${input.projectId}'.`);
|
|
560
|
+
}
|
|
561
|
+
if (thread.activeRunId !== null) {
|
|
562
|
+
throw new AgentStorageError("active_run_exists", `[Sixb] Agent thread '${input.threadId}' already has an active run '${thread.activeRunId}'.`);
|
|
563
|
+
}
|
|
564
|
+
const runKey = key(input.projectId, input.id);
|
|
565
|
+
if (this.state.runs.has(runKey)) {
|
|
566
|
+
throw new AgentStorageError("duplicate_id", `[Sixb] Agent run '${input.id}' already exists for project '${input.projectId}'.`);
|
|
567
|
+
}
|
|
568
|
+
if ([...this.state.runs.values()].some((run2) => run2.projectId === input.projectId && run2.executionId === input.executionId)) {
|
|
569
|
+
throw new AgentStorageError("duplicate_id", `[Sixb] Execution '${input.executionId}' already belongs to another Agent run.`);
|
|
570
|
+
}
|
|
571
|
+
const createdAt = new Date(input.createdAt ?? new Date);
|
|
572
|
+
const run = {
|
|
573
|
+
id: input.id,
|
|
574
|
+
projectId: input.projectId,
|
|
575
|
+
executionId: input.executionId,
|
|
576
|
+
threadId: input.threadId,
|
|
577
|
+
agentId: input.agentId,
|
|
578
|
+
triggerMessageId: input.triggerMessageId,
|
|
579
|
+
requesterGroupIds: normalizeRequesterGroupIds(input.requesterGroupIds),
|
|
580
|
+
status: "queued",
|
|
581
|
+
attempt: 0,
|
|
582
|
+
createdAt
|
|
583
|
+
};
|
|
584
|
+
this.state.runs.set(runKey, clone(run));
|
|
585
|
+
const updatedThread = {
|
|
586
|
+
...thread,
|
|
587
|
+
activeRunId: run.id,
|
|
588
|
+
updatedAt: createdAt
|
|
589
|
+
};
|
|
590
|
+
this.state.threads.set(threadKey, clone(updatedThread));
|
|
591
|
+
return clone(run);
|
|
592
|
+
}
|
|
593
|
+
async start(input) {
|
|
594
|
+
const run = this.requireStatus(input.projectId, input.id, "queued");
|
|
595
|
+
const startedAt = new Date(input.startedAt ?? new Date);
|
|
596
|
+
const next = {
|
|
597
|
+
...run,
|
|
598
|
+
status: "running",
|
|
599
|
+
...input.modelId === undefined ? {} : { modelId: input.modelId },
|
|
600
|
+
attempt: 1,
|
|
601
|
+
execution: clone(input.execution),
|
|
602
|
+
startedAt
|
|
603
|
+
};
|
|
604
|
+
this.state.runs.set(key(input.projectId, input.id), clone(next));
|
|
605
|
+
return clone(next);
|
|
606
|
+
}
|
|
607
|
+
async finishQueued(input) {
|
|
608
|
+
const run = this.requireStatus(input.projectId, input.id, "queued");
|
|
609
|
+
const completedAt = new Date(input.completedAt ?? new Date);
|
|
610
|
+
const next = {
|
|
611
|
+
...run,
|
|
612
|
+
status: input.status,
|
|
613
|
+
...input.error === undefined ? {} : { error: normalizeFailure(input.error) },
|
|
614
|
+
completedAt
|
|
615
|
+
};
|
|
616
|
+
this.state.runs.set(key(input.projectId, input.id), clone(next));
|
|
617
|
+
this.releaseThread(run, completedAt);
|
|
618
|
+
return clone(next);
|
|
619
|
+
}
|
|
620
|
+
async reclaim(input) {
|
|
621
|
+
const run = this.requireRunning(input.projectId, input.id);
|
|
622
|
+
const next = {
|
|
623
|
+
...run,
|
|
624
|
+
attempt: run.attempt + 1,
|
|
625
|
+
execution: clone(input.execution)
|
|
626
|
+
};
|
|
627
|
+
this.state.runs.set(key(input.projectId, input.id), clone(next));
|
|
628
|
+
return clone(next);
|
|
629
|
+
}
|
|
630
|
+
async confirmExecutionOwnership(input) {
|
|
631
|
+
const run = this.requireRunning(input.projectId, input.id);
|
|
632
|
+
if (!run.execution || run.execution.token !== input.executionToken) {
|
|
633
|
+
throw new AgentStorageError("execution_lost", `[Sixb] Execution token is no longer current on agent run '${input.id}'.`);
|
|
634
|
+
}
|
|
635
|
+
const next = {
|
|
636
|
+
...run,
|
|
637
|
+
execution: {
|
|
638
|
+
...run.execution,
|
|
639
|
+
queueLeaseExpiresAt: new Date(Math.max(run.execution.queueLeaseExpiresAt.getTime(), input.queueLeaseExpiresAt.getTime()))
|
|
640
|
+
}
|
|
641
|
+
};
|
|
642
|
+
this.state.runs.set(key(input.projectId, input.id), clone(next));
|
|
643
|
+
return clone(next);
|
|
644
|
+
}
|
|
645
|
+
async finish(input) {
|
|
646
|
+
const run = this.requireRunning(input.projectId, input.id);
|
|
647
|
+
if (!run.execution || run.execution.token !== input.executionToken) {
|
|
648
|
+
throw new AgentStorageError("execution_lost", `[Sixb] Execution token is no longer current on agent run '${input.id}'.`);
|
|
649
|
+
}
|
|
650
|
+
const completedAt = new Date(input.completedAt ?? new Date);
|
|
651
|
+
const next = {
|
|
652
|
+
...run,
|
|
653
|
+
status: input.status,
|
|
654
|
+
...input.modelId === undefined ? {} : { modelId: input.modelId },
|
|
655
|
+
...input.finishReason === undefined ? {} : { finishReason: input.finishReason },
|
|
656
|
+
...input.diagnostics === undefined ? {} : { diagnostics: clone(input.diagnostics) },
|
|
657
|
+
...input.status === "succeeded" || input.error === undefined ? {} : { error: normalizeFailure(input.error) },
|
|
658
|
+
execution: undefined,
|
|
659
|
+
completedAt
|
|
660
|
+
};
|
|
661
|
+
this.state.runs.set(key(input.projectId, input.id), clone(next));
|
|
662
|
+
this.releaseThread(run, completedAt);
|
|
663
|
+
return clone(next);
|
|
664
|
+
}
|
|
665
|
+
async getById(params) {
|
|
666
|
+
const record = this.state.runs.get(key(params.projectId, params.id));
|
|
667
|
+
return record ? clone(record) : null;
|
|
668
|
+
}
|
|
669
|
+
async getByIds(params) {
|
|
670
|
+
return [...new Set(params.ids)].map((id) => this.state.runs.get(key(params.projectId, id))).filter((record) => record !== undefined).map(clone);
|
|
671
|
+
}
|
|
672
|
+
async list(input) {
|
|
673
|
+
const order = input.order ?? "desc";
|
|
674
|
+
const statuses = input.statuses ? new Set(input.statuses) : null;
|
|
675
|
+
const filtered = [...this.state.runs.values()].filter((run) => run.projectId === input.projectId).filter((run) => input.threadId ? run.threadId === input.threadId : true).filter((run) => input.agentId ? run.agentId === input.agentId : true).filter((run) => statuses ? statuses.has(run.status) : true).filter((run) => input.startedAfter ? (run.startedAt ?? run.createdAt) >= input.startedAfter : true).filter((run) => input.startedBefore ? (run.startedAt ?? run.createdAt) <= input.startedBefore : true).sort((a, b) => compareByDate(a.startedAt ?? a.createdAt, b.startedAt ?? b.createdAt, a.id, b.id, order));
|
|
676
|
+
const { page, hasMore, total } = applyWindow(filtered, input.offset, input.limit);
|
|
677
|
+
return { runs: page.map(clone), hasMore, total };
|
|
678
|
+
}
|
|
679
|
+
requireRunning(projectId, id) {
|
|
680
|
+
return this.requireStatus(projectId, id, "running");
|
|
681
|
+
}
|
|
682
|
+
requireStatus(projectId, id, status) {
|
|
683
|
+
const run = this.state.runs.get(key(projectId, id));
|
|
684
|
+
if (!run) {
|
|
685
|
+
throw new AgentStorageError("run_not_found", `[Sixb] Agent run '${id}' not found for project '${projectId}'.`);
|
|
686
|
+
}
|
|
687
|
+
if (run.status !== status) {
|
|
688
|
+
throw new AgentStorageError("invalid_state", `[Sixb] Agent run '${id}' is not ${status} (status '${run.status}').`);
|
|
689
|
+
}
|
|
690
|
+
return run;
|
|
691
|
+
}
|
|
692
|
+
releaseThread(run, completedAt) {
|
|
693
|
+
const threadKey = key(run.projectId, run.threadId);
|
|
694
|
+
const thread = this.state.threads.get(threadKey);
|
|
695
|
+
if (thread && thread.activeRunId === run.id) {
|
|
696
|
+
this.state.threads.set(threadKey, clone({ ...thread, activeRunId: null, updatedAt: completedAt }));
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
class InMemoryAgentMessageStore {
|
|
702
|
+
state;
|
|
703
|
+
constructor(state) {
|
|
704
|
+
this.state = state;
|
|
705
|
+
}
|
|
706
|
+
async append(input) {
|
|
707
|
+
const threadKey = key(input.projectId, input.threadId);
|
|
708
|
+
const thread = this.state.threads.get(threadKey);
|
|
709
|
+
if (!thread) {
|
|
710
|
+
throw new AgentStorageError("thread_not_found", `[Sixb] Agent thread '${input.threadId}' not found for project '${input.projectId}'.`);
|
|
711
|
+
}
|
|
712
|
+
const messageKey = key(input.projectId, input.id);
|
|
713
|
+
if (this.state.messages.has(messageKey)) {
|
|
714
|
+
throw new AgentStorageError("duplicate_id", `[Sixb] Agent message '${input.id}' already exists for project '${input.projectId}'.`);
|
|
715
|
+
}
|
|
716
|
+
if (input.runId !== null && !this.state.runs.has(key(input.projectId, input.runId))) {
|
|
717
|
+
throw new AgentStorageError("run_not_found", `[Sixb] Agent run '${input.runId}' not found for project '${input.projectId}'.`);
|
|
718
|
+
}
|
|
719
|
+
const createdAt = new Date(input.createdAt ?? new Date);
|
|
720
|
+
const seq = this.nextSeq(input.projectId, input.threadId);
|
|
721
|
+
const message = {
|
|
722
|
+
id: input.id,
|
|
723
|
+
projectId: input.projectId,
|
|
724
|
+
threadId: input.threadId,
|
|
725
|
+
runId: input.runId,
|
|
726
|
+
role: input.role,
|
|
727
|
+
...input.authorPrincipal === undefined ? {} : { authorPrincipal: clone(input.authorPrincipal) },
|
|
728
|
+
seq,
|
|
729
|
+
parts: clone(input.parts),
|
|
730
|
+
...input.metadata === undefined ? {} : { metadata: clone(input.metadata) },
|
|
731
|
+
contentVersion: AGENT_MESSAGE_CONTENT_VERSION,
|
|
732
|
+
createdAt,
|
|
733
|
+
...input.completedAt === undefined ? {} : { completedAt: new Date(input.completedAt) }
|
|
734
|
+
};
|
|
735
|
+
this.state.messages.set(messageKey, clone(message));
|
|
736
|
+
this.state.threads.set(threadKey, clone({
|
|
737
|
+
...thread,
|
|
738
|
+
messageCount: thread.messageCount + 1,
|
|
739
|
+
lastMessageAt: createdAt,
|
|
740
|
+
updatedAt: createdAt
|
|
741
|
+
}));
|
|
742
|
+
return clone(message);
|
|
743
|
+
}
|
|
744
|
+
async deleteByRunId(input) {
|
|
745
|
+
const threadKey = key(input.projectId, input.threadId);
|
|
746
|
+
const thread = this.state.threads.get(threadKey);
|
|
747
|
+
if (!thread) {
|
|
748
|
+
throw new AgentStorageError("thread_not_found", `[Sixb] Agent thread '${input.threadId}' not found for project '${input.projectId}'.`);
|
|
749
|
+
}
|
|
750
|
+
const messages = [...this.state.messages.entries()].filter(([, message]) => message.projectId === input.projectId && message.threadId === input.threadId && message.runId === input.runId);
|
|
751
|
+
if (messages.length === 0) {
|
|
752
|
+
return 0;
|
|
753
|
+
}
|
|
754
|
+
for (const [messageKey] of messages) {
|
|
755
|
+
this.state.messages.delete(messageKey);
|
|
756
|
+
}
|
|
757
|
+
const remainingMessages = [...this.state.messages.values()].filter((message) => message.projectId === input.projectId && message.threadId === input.threadId).sort((left, right) => right.seq - left.seq);
|
|
758
|
+
const latestMessage = remainingMessages[0];
|
|
759
|
+
const updatedAt = new Date;
|
|
760
|
+
this.state.threads.set(threadKey, clone({
|
|
761
|
+
...thread,
|
|
762
|
+
messageCount: remainingMessages.length,
|
|
763
|
+
lastMessageAt: latestMessage?.createdAt,
|
|
764
|
+
updatedAt
|
|
765
|
+
}));
|
|
766
|
+
return messages.length;
|
|
767
|
+
}
|
|
768
|
+
async getById(params) {
|
|
769
|
+
const record = this.state.messages.get(key(params.projectId, params.id));
|
|
770
|
+
return record ? clone(record) : null;
|
|
771
|
+
}
|
|
772
|
+
async list(input) {
|
|
773
|
+
const order = input.order ?? "asc";
|
|
774
|
+
const roles = input.roles ? new Set(input.roles) : null;
|
|
775
|
+
const filtered = [...this.state.messages.values()].filter((message) => message.projectId === input.projectId).filter((message) => message.threadId === input.threadId).filter((message) => input.afterSeq === undefined ? true : message.seq > input.afterSeq).filter((message) => roles ? roles.has(message.role) : true).sort((a, b) => order === "asc" ? a.seq - b.seq : b.seq - a.seq);
|
|
776
|
+
const { page, hasMore, total } = applyWindow(filtered, input.offset, input.limit);
|
|
777
|
+
return { messages: page.map(clone), hasMore, total };
|
|
778
|
+
}
|
|
779
|
+
nextSeq(projectId, threadId) {
|
|
780
|
+
let max = 0;
|
|
781
|
+
for (const message of this.state.messages.values()) {
|
|
782
|
+
if (message.projectId === projectId && message.threadId === threadId && message.seq > max) {
|
|
783
|
+
max = message.seq;
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
return max + 1;
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
class InMemoryAgentContextCheckpointStore {
|
|
791
|
+
state;
|
|
792
|
+
constructor(state) {
|
|
793
|
+
this.state = state;
|
|
794
|
+
}
|
|
795
|
+
async create(input) {
|
|
796
|
+
assertCreateAgentContextCheckpointInput(input);
|
|
797
|
+
const run = this.state.runs.get(key(input.projectId, input.createdByRunId)) ?? null;
|
|
798
|
+
const thread = this.state.threads.get(key(input.projectId, input.threadId)) ?? null;
|
|
799
|
+
assertAgentContextCheckpointAuthority({ create: input, run, thread });
|
|
800
|
+
const messages = [...this.state.messages.values()].filter((message) => message.projectId === input.projectId && message.threadId === input.threadId);
|
|
801
|
+
const headSeq = messages.reduce((head, message) => Math.max(head, message.seq), 0);
|
|
802
|
+
const latest = this.findLatest(input.projectId, input.threadId);
|
|
803
|
+
const existingForRun = [...this.state.checkpoints.values()].find((checkpoint) => checkpoint.projectId === input.projectId && checkpoint.createdByRunId === input.createdByRunId);
|
|
804
|
+
if (existingForRun) {
|
|
805
|
+
if (agentContextCheckpointMatchesCreateInput(existingForRun, input)) {
|
|
806
|
+
assertAgentContextCheckpointReplayState({
|
|
807
|
+
create: input,
|
|
808
|
+
existing: existingForRun,
|
|
809
|
+
latest,
|
|
810
|
+
headSeq
|
|
811
|
+
});
|
|
812
|
+
return clone(existingForRun);
|
|
813
|
+
}
|
|
814
|
+
throw new AgentStorageError("invalid_state", `[Sixb] Agent run '${input.createdByRunId}' already created a different context checkpoint.`);
|
|
815
|
+
}
|
|
816
|
+
if (this.state.checkpoints.has(key(input.projectId, input.id))) {
|
|
817
|
+
throw new AgentStorageError("duplicate_id", `[Sixb] Agent context checkpoint '${input.id}' already exists for project '${input.projectId}'.`);
|
|
818
|
+
}
|
|
819
|
+
const firstRetained = messages.filter((message) => message.seq > input.summarizedThroughSeq).sort((left, right) => left.seq - right.seq)[0] ?? null;
|
|
820
|
+
assertAgentContextCheckpointAnchors({
|
|
821
|
+
create: input,
|
|
822
|
+
latest,
|
|
823
|
+
headSeq,
|
|
824
|
+
firstRetained
|
|
825
|
+
});
|
|
826
|
+
const record = {
|
|
827
|
+
id: input.id,
|
|
828
|
+
projectId: input.projectId,
|
|
829
|
+
threadId: input.threadId,
|
|
830
|
+
createdByRunId: input.createdByRunId,
|
|
831
|
+
...input.expectedPreviousCheckpointId === null ? {} : { previousCheckpointId: input.expectedPreviousCheckpointId },
|
|
832
|
+
reason: input.reason,
|
|
833
|
+
summary: input.summary,
|
|
834
|
+
summaryFormatVersion: input.summaryFormatVersion,
|
|
835
|
+
summarizedThroughSeq: input.summarizedThroughSeq,
|
|
836
|
+
observedHeadSeq: input.observedHeadSeq,
|
|
837
|
+
estimatedInputTokensBefore: input.estimatedInputTokensBefore,
|
|
838
|
+
estimatedInputTokensAfter: input.estimatedInputTokensAfter,
|
|
839
|
+
summaryModelId: input.summaryModelId,
|
|
840
|
+
createdAt: new Date(input.createdAt ?? new Date)
|
|
841
|
+
};
|
|
842
|
+
this.state.checkpoints.set(key(input.projectId, input.id), clone(record));
|
|
843
|
+
return clone(record);
|
|
844
|
+
}
|
|
845
|
+
async getLatest(input) {
|
|
846
|
+
const record = this.findLatest(input.projectId, input.threadId);
|
|
847
|
+
return record ? clone(record) : null;
|
|
848
|
+
}
|
|
849
|
+
findLatest(projectId, threadId) {
|
|
850
|
+
return [...this.state.checkpoints.values()].filter((checkpoint) => checkpoint.projectId === projectId && checkpoint.threadId === threadId).sort((left, right) => right.summarizedThroughSeq - left.summarizedThroughSeq || right.createdAt.getTime() - left.createdAt.getTime() || right.id.localeCompare(left.id))[0] ?? null;
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
class InMemoryAgentStorage {
|
|
855
|
+
state = {
|
|
856
|
+
threads: new Map,
|
|
857
|
+
runs: new Map,
|
|
858
|
+
messages: new Map,
|
|
859
|
+
checkpoints: new Map
|
|
860
|
+
};
|
|
861
|
+
threads;
|
|
862
|
+
runs;
|
|
863
|
+
messages;
|
|
864
|
+
checkpoints;
|
|
865
|
+
constructor(executions) {
|
|
866
|
+
this.threads = new InMemoryAgentThreadStore(this.state);
|
|
867
|
+
this.runs = new InMemoryAgentRunStore(this.state, executions);
|
|
868
|
+
this.messages = new InMemoryAgentMessageStore(this.state);
|
|
869
|
+
this.checkpoints = new InMemoryAgentContextCheckpointStore(this.state);
|
|
870
|
+
}
|
|
871
|
+
snapshot() {
|
|
872
|
+
return {
|
|
873
|
+
threads: structuredClone(this.state.threads),
|
|
874
|
+
runs: structuredClone(this.state.runs),
|
|
875
|
+
messages: structuredClone(this.state.messages),
|
|
876
|
+
checkpoints: structuredClone(this.state.checkpoints)
|
|
877
|
+
};
|
|
878
|
+
}
|
|
879
|
+
restore(snapshot) {
|
|
880
|
+
replace(this.state.threads, snapshot.threads);
|
|
881
|
+
replace(this.state.runs, snapshot.runs);
|
|
882
|
+
replace(this.state.messages, snapshot.messages);
|
|
883
|
+
replace(this.state.checkpoints, snapshot.checkpoints);
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
function replace(target, source) {
|
|
887
|
+
target.clear();
|
|
888
|
+
for (const [k, value] of structuredClone(source)) {
|
|
889
|
+
target.set(k, value);
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
// src/storage/ai-cost/errors.ts
|
|
893
|
+
class AiCostStorageError extends Error {
|
|
894
|
+
code;
|
|
895
|
+
name = "AiCostStorageError";
|
|
896
|
+
constructor(code, message) {
|
|
897
|
+
super(message);
|
|
898
|
+
this.code = code;
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
// src/storage/ai-cost/in-memory.ts
|
|
902
|
+
class InMemoryAiCostStorage {
|
|
903
|
+
usage;
|
|
904
|
+
attribution;
|
|
905
|
+
recordsByUsage = new Map;
|
|
906
|
+
constructor(usage, attribution) {
|
|
907
|
+
this.usage = usage;
|
|
908
|
+
this.attribution = attribution;
|
|
909
|
+
}
|
|
910
|
+
async recordModelCallCost(input) {
|
|
911
|
+
const record = normalizeAiModelCallCostRecord(input);
|
|
912
|
+
const usage = this.usageRecord(record.projectId, record.usageRecordId);
|
|
913
|
+
if (!usage)
|
|
914
|
+
throw missingUsage(record);
|
|
915
|
+
if (!aiModelCallCostMatchesUsage(record, usage)) {
|
|
916
|
+
throw new AiCostStorageError("cost_mismatch", `[Sixb] AI valuation for usage '${record.usageRecordId}' does not match its usage record.`);
|
|
917
|
+
}
|
|
918
|
+
const key2 = usageRecordKey(record.projectId, record.usageRecordId);
|
|
919
|
+
if (!this.recordsByUsage.has(key2))
|
|
920
|
+
this.recordsByUsage.set(key2, structuredClone(record));
|
|
921
|
+
}
|
|
922
|
+
async summarizeExecutions(input) {
|
|
923
|
+
assertNonBlank2(input.projectId, "cost summary projectId");
|
|
924
|
+
for (const id of input.executionIds)
|
|
925
|
+
assertNonBlank2(id, "cost summary executionId");
|
|
926
|
+
const requested = new Set(input.executionIds);
|
|
927
|
+
const usageByExecution = new Map(input.executionIds.map((id) => [id, []]));
|
|
928
|
+
for (const usage of this.usage.snapshot().records.values()) {
|
|
929
|
+
if (usage.projectId === input.projectId && requested.has(usage.executionId)) {
|
|
930
|
+
usageByExecution.get(usage.executionId).push(usage.id);
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
return input.executionIds.map((id) => this.summarizeUsageIds(input.projectId, usageByExecution.get(id) ?? []));
|
|
934
|
+
}
|
|
935
|
+
async queryProjectOverview(input) {
|
|
936
|
+
return buildAiAccountingOverview(input, await this.accountingItems());
|
|
937
|
+
}
|
|
938
|
+
async listModelCalls(input) {
|
|
939
|
+
return buildAiModelCallAccountingList(input, await this.accountingItems());
|
|
940
|
+
}
|
|
941
|
+
snapshot() {
|
|
942
|
+
return structuredClone({ recordsByUsage: this.recordsByUsage });
|
|
943
|
+
}
|
|
944
|
+
restore(snapshot) {
|
|
945
|
+
replaceMap(this.recordsByUsage, snapshot.recordsByUsage);
|
|
946
|
+
}
|
|
947
|
+
usageRecord(projectId, id) {
|
|
948
|
+
return [...this.usage.snapshot().records.values()].find((record) => record.projectId === projectId && record.id === id);
|
|
949
|
+
}
|
|
950
|
+
async accountingItems() {
|
|
951
|
+
return Promise.all([...this.usage.snapshot().records.values()].map(async (usage) => {
|
|
952
|
+
const cost = this.recordsByUsage.get(usageRecordKey(usage.projectId, usage.id));
|
|
953
|
+
const attribution = await this.attribution?.resolve({
|
|
954
|
+
projectId: usage.projectId,
|
|
955
|
+
executionId: usage.executionId
|
|
956
|
+
});
|
|
957
|
+
return {
|
|
958
|
+
usage,
|
|
959
|
+
...attribution ? { attribution } : {},
|
|
960
|
+
...cost ? { cost } : {}
|
|
961
|
+
};
|
|
962
|
+
}));
|
|
963
|
+
}
|
|
964
|
+
summarizeUsageIds(projectId, ids) {
|
|
965
|
+
const amounts = new Map;
|
|
966
|
+
let ratedCallCount = 0;
|
|
967
|
+
let unpriceableCallCount = 0;
|
|
968
|
+
let unvaluedCallCount = 0;
|
|
969
|
+
for (const id of ids) {
|
|
970
|
+
const cost = this.recordsByUsage.get(usageRecordKey(projectId, id));
|
|
971
|
+
if (!cost)
|
|
972
|
+
unvaluedCallCount += 1;
|
|
973
|
+
else if (cost.status === "unpriceable")
|
|
974
|
+
unpriceableCallCount += 1;
|
|
975
|
+
else {
|
|
976
|
+
ratedCallCount += 1;
|
|
977
|
+
addMoney(amounts, cost.money);
|
|
978
|
+
}
|
|
979
|
+
}
|
|
980
|
+
return {
|
|
981
|
+
amounts: [...amounts].sort(([left], [right]) => left.localeCompare(right)).map(([currency, amount]) => ({ currency, amountNanos: amount.toString() })),
|
|
982
|
+
ratedCallCount,
|
|
983
|
+
unpriceableCallCount,
|
|
984
|
+
unvaluedCallCount
|
|
985
|
+
};
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
function missingUsage(record) {
|
|
989
|
+
return new AiCostStorageError("missing_usage", `[Sixb] AI usage '${record.usageRecordId}' does not exist in project '${record.projectId}'.`);
|
|
990
|
+
}
|
|
991
|
+
function addMoney(amounts, money) {
|
|
992
|
+
amounts.set(money.currency, (amounts.get(money.currency) ?? 0n) + BigInt(money.amountNanos));
|
|
993
|
+
}
|
|
994
|
+
function usageRecordKey(projectId, id) {
|
|
995
|
+
return JSON.stringify([projectId, id]);
|
|
996
|
+
}
|
|
997
|
+
function assertNonBlank2(value, field) {
|
|
998
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
999
|
+
throw new TypeError(`[Sixb] AI ${field} must be nonblank.`);
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
function replaceMap(target, source) {
|
|
1003
|
+
target.clear();
|
|
1004
|
+
for (const [key2, value] of structuredClone(source))
|
|
1005
|
+
target.set(key2, value);
|
|
1006
|
+
}
|
|
1007
|
+
// src/storage/connector-connections/in-memory.ts
|
|
1008
|
+
import { timingSafeEqual } from "crypto";
|
|
1009
|
+
function connectionRunBase(record, updatedAt) {
|
|
1010
|
+
return {
|
|
1011
|
+
id: record.id,
|
|
1012
|
+
projectId: record.projectId,
|
|
1013
|
+
connectorId: record.connectorId,
|
|
1014
|
+
kind: record.kind,
|
|
1015
|
+
owner: structuredClone(record.owner),
|
|
1016
|
+
slot: record.slot,
|
|
1017
|
+
initiatedByExecutionId: record.initiatedByExecutionId,
|
|
1018
|
+
createdAt: new Date(record.createdAt),
|
|
1019
|
+
updatedAt: new Date(updatedAt)
|
|
1020
|
+
};
|
|
1021
|
+
}
|
|
1022
|
+
function expireConnectionRun(record, now) {
|
|
1023
|
+
return {
|
|
1024
|
+
...connectionRunBase(record, now),
|
|
1025
|
+
status: "expired",
|
|
1026
|
+
...record.waitingFor === "account_selection" ? { authorizationId: record.authorizationId } : {},
|
|
1027
|
+
finishedAt: new Date(now)
|
|
1028
|
+
};
|
|
1029
|
+
}
|
|
1030
|
+
function failExpiredProcessingRun(record, now) {
|
|
1031
|
+
return {
|
|
1032
|
+
...connectionRunBase(record, now),
|
|
1033
|
+
status: "failed",
|
|
1034
|
+
...record.authorizationId === undefined ? {} : { authorizationId: record.authorizationId },
|
|
1035
|
+
error: toSixbFailure(createSixbError("internal.unexpected", "[Sixb] Connector callback processing did not complete before its deadline."), { allowedCodes: CONNECTOR_CONNECTION_RUN_FAILURE_CODES, at: now }),
|
|
1036
|
+
finishedAt: new Date(now)
|
|
1037
|
+
};
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
class InMemoryConnectorConnectionStorage {
|
|
1041
|
+
options;
|
|
1042
|
+
durability = "ephemeral";
|
|
1043
|
+
attempts = new Map;
|
|
1044
|
+
connectionRuns = new Map;
|
|
1045
|
+
authorizations = new Map;
|
|
1046
|
+
connections = new Map;
|
|
1047
|
+
constructor(options = {}) {
|
|
1048
|
+
this.options = options;
|
|
1049
|
+
}
|
|
1050
|
+
async createAuthorizationAttempt(input) {
|
|
1051
|
+
assertPositiveDuration(input.ttlMs, "authorization attempt TTL");
|
|
1052
|
+
if (this.attempts.has(input.id)) {
|
|
1053
|
+
throw new ConnectorConnectionStorageError("attempt_conflict", "[Sixb] Connector authorization attempt already exists.");
|
|
1054
|
+
}
|
|
1055
|
+
if (input.connectionRunId !== undefined) {
|
|
1056
|
+
const run = this.connectionRuns.get(input.connectionRunId);
|
|
1057
|
+
const existingAttempt = this.findAuthorizationAttemptByConnectionRunId(input.connectionRunId);
|
|
1058
|
+
if (!run || existingAttempt || run.projectId !== input.projectId || run.connectorId !== input.connectorId || run.status !== "waiting" || run.waitingFor !== "provider_authorization" || run.slot !== input.slot || run.initiatedByExecutionId !== input.initiatedByExecutionId) {
|
|
1059
|
+
throw new ConnectorConnectionStorageError("attempt_conflict", "[Sixb] Connector authorization attempt does not match its connection run.");
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
const now = this.now();
|
|
1063
|
+
const record = {
|
|
1064
|
+
id: input.id,
|
|
1065
|
+
projectId: input.projectId,
|
|
1066
|
+
connectorId: input.connectorId,
|
|
1067
|
+
owner: structuredClone(input.owner),
|
|
1068
|
+
slot: input.slot,
|
|
1069
|
+
initiatedByExecutionId: input.initiatedByExecutionId,
|
|
1070
|
+
stateHash: input.stateHash,
|
|
1071
|
+
codeVerifier: structuredClone(input.codeVerifier),
|
|
1072
|
+
redirectUri: input.redirectUri,
|
|
1073
|
+
...input.connectionRunId === undefined ? {} : { connectionRunId: input.connectionRunId },
|
|
1074
|
+
...input.returnTo === undefined ? {} : { returnTo: input.returnTo },
|
|
1075
|
+
...input.callbackBindingHash === undefined ? {} : { callbackBindingHash: input.callbackBindingHash },
|
|
1076
|
+
...input.reauthorizationId === undefined ? {} : { reauthorizationId: input.reauthorizationId },
|
|
1077
|
+
...input.reauthorizationRevision === undefined ? {} : { reauthorizationRevision: input.reauthorizationRevision },
|
|
1078
|
+
...input.reauthorizationConnectionIds === undefined ? {} : { reauthorizationConnectionIds: [...input.reauthorizationConnectionIds] },
|
|
1079
|
+
createdAt: now,
|
|
1080
|
+
expiresAt: new Date(now.getTime() + input.ttlMs)
|
|
1081
|
+
};
|
|
1082
|
+
this.attempts.set(record.id, record);
|
|
1083
|
+
return structuredClone(record);
|
|
1084
|
+
}
|
|
1085
|
+
async consumeAuthorizationAttempt(input) {
|
|
1086
|
+
const record = this.attempts.get(input.id);
|
|
1087
|
+
if (record && record.expiresAt.getTime() <= this.now().getTime()) {
|
|
1088
|
+
this.attempts.delete(record.id);
|
|
1089
|
+
throw invalidAttempt();
|
|
1090
|
+
}
|
|
1091
|
+
if (!record || record.projectId !== input.projectId || record.connectorId !== input.connectorId || record.redirectUri !== input.redirectUri || !safeEqual(record.stateHash, input.stateHash)) {
|
|
1092
|
+
throw invalidAttempt();
|
|
1093
|
+
}
|
|
1094
|
+
this.attempts.delete(input.id);
|
|
1095
|
+
return structuredClone(record);
|
|
1096
|
+
}
|
|
1097
|
+
async createConnectionRun(input) {
|
|
1098
|
+
assertPositiveDuration(input.ttlMs, "connection run TTL");
|
|
1099
|
+
if (this.connectionRuns.has(input.id)) {
|
|
1100
|
+
throw new ConnectorConnectionStorageError("run_conflict", "[Sixb] Connector connection run already exists.");
|
|
1101
|
+
}
|
|
1102
|
+
const now = this.now();
|
|
1103
|
+
const record = {
|
|
1104
|
+
id: input.id,
|
|
1105
|
+
projectId: input.projectId,
|
|
1106
|
+
connectorId: input.connectorId,
|
|
1107
|
+
kind: input.kind,
|
|
1108
|
+
owner: structuredClone(input.owner),
|
|
1109
|
+
slot: input.slot,
|
|
1110
|
+
initiatedByExecutionId: input.initiatedByExecutionId,
|
|
1111
|
+
status: "waiting",
|
|
1112
|
+
waitingFor: "provider_authorization",
|
|
1113
|
+
createdAt: now,
|
|
1114
|
+
updatedAt: now,
|
|
1115
|
+
expiresAt: new Date(now.getTime() + input.ttlMs)
|
|
1116
|
+
};
|
|
1117
|
+
this.connectionRuns.set(record.id, record);
|
|
1118
|
+
return structuredClone(record);
|
|
1119
|
+
}
|
|
1120
|
+
async createConnectionSelectionRun(input) {
|
|
1121
|
+
assertPositiveDuration(input.ttlMs, "connection run TTL");
|
|
1122
|
+
if (this.connectionRuns.has(input.id)) {
|
|
1123
|
+
throw new ConnectorConnectionStorageError("run_conflict", "[Sixb] Connector connection run already exists.");
|
|
1124
|
+
}
|
|
1125
|
+
const authorization = this.authorizations.get(input.authorizationId);
|
|
1126
|
+
if (!sameAuthorizationScope(authorization, input) || authorization.status !== "active" || authorization.credentialMutation) {
|
|
1127
|
+
throw authorizationConflict();
|
|
1128
|
+
}
|
|
1129
|
+
const now = this.now();
|
|
1130
|
+
const record = {
|
|
1131
|
+
id: input.id,
|
|
1132
|
+
projectId: input.projectId,
|
|
1133
|
+
connectorId: input.connectorId,
|
|
1134
|
+
kind: "connect",
|
|
1135
|
+
owner: structuredClone(input.owner),
|
|
1136
|
+
slot: input.slot,
|
|
1137
|
+
initiatedByExecutionId: input.initiatedByExecutionId,
|
|
1138
|
+
status: "waiting",
|
|
1139
|
+
waitingFor: "account_selection",
|
|
1140
|
+
authorizationId: input.authorizationId,
|
|
1141
|
+
createdAt: now,
|
|
1142
|
+
updatedAt: now,
|
|
1143
|
+
expiresAt: new Date(now.getTime() + input.ttlMs)
|
|
1144
|
+
};
|
|
1145
|
+
this.connectionRuns.set(record.id, record);
|
|
1146
|
+
return structuredClone(record);
|
|
1147
|
+
}
|
|
1148
|
+
async claimConnectionRunCallback(input) {
|
|
1149
|
+
assertPositiveDuration(input.processingTtlMs, "connection run processing TTL");
|
|
1150
|
+
const attempt = this.attempts.get(input.attemptId);
|
|
1151
|
+
if (!attempt || attempt.projectId !== input.projectId || attempt.connectionRunId === undefined || attempt.returnTo === undefined || attempt.callbackBindingHash === undefined || attempt.redirectUri !== input.redirectUri || !safeEqual(attempt.stateHash, input.stateHash) || !safeEqual(attempt.callbackBindingHash, input.callbackBindingHash)) {
|
|
1152
|
+
return null;
|
|
1153
|
+
}
|
|
1154
|
+
const run = this.connectionRuns.get(attempt.connectionRunId);
|
|
1155
|
+
if (!run || run.projectId !== input.projectId || run.connectorId !== attempt.connectorId || run.status !== "waiting" || run.waitingFor !== "provider_authorization" || run.slot !== attempt.slot || run.initiatedByExecutionId !== attempt.initiatedByExecutionId) {
|
|
1156
|
+
return null;
|
|
1157
|
+
}
|
|
1158
|
+
const now = this.now();
|
|
1159
|
+
this.attempts.delete(attempt.id);
|
|
1160
|
+
if (attempt.expiresAt.getTime() <= now.getTime() || run.expiresAt.getTime() <= now.getTime()) {
|
|
1161
|
+
const expired = expireConnectionRun(run, now);
|
|
1162
|
+
this.connectionRuns.set(run.id, expired);
|
|
1163
|
+
return { type: "expired", run: structuredClone(expired), returnTo: attempt.returnTo };
|
|
1164
|
+
}
|
|
1165
|
+
const processing = {
|
|
1166
|
+
...connectionRunBase(run, now),
|
|
1167
|
+
status: "running",
|
|
1168
|
+
processingId: input.processingId,
|
|
1169
|
+
callbackStartedAt: now,
|
|
1170
|
+
expiresAt: new Date(now.getTime() + input.processingTtlMs),
|
|
1171
|
+
...attempt.reauthorizationId === undefined ? {} : { authorizationId: attempt.reauthorizationId }
|
|
1172
|
+
};
|
|
1173
|
+
this.connectionRuns.set(run.id, processing);
|
|
1174
|
+
return {
|
|
1175
|
+
type: "claimed",
|
|
1176
|
+
run: structuredClone(processing),
|
|
1177
|
+
attempt: structuredClone(attempt),
|
|
1178
|
+
returnTo: attempt.returnTo
|
|
1179
|
+
};
|
|
1180
|
+
}
|
|
1181
|
+
async attachConnectionRunAuthorization(input) {
|
|
1182
|
+
const run = this.currentConnectionRun(input.runId);
|
|
1183
|
+
const authorization = this.authorizations.get(input.authorizationId);
|
|
1184
|
+
if (!sameConnectionRunScope(run, input) || run.status !== "running" || run.processingId !== input.processingId || run.authorizationId !== undefined && run.authorizationId !== input.authorizationId || !sameAuthorizationScope(authorization, input) || authorization.status !== "pending_selection") {
|
|
1185
|
+
return null;
|
|
1186
|
+
}
|
|
1187
|
+
const updated = {
|
|
1188
|
+
...run,
|
|
1189
|
+
authorizationId: input.authorizationId,
|
|
1190
|
+
updatedAt: this.now()
|
|
1191
|
+
};
|
|
1192
|
+
this.connectionRuns.set(run.id, updated);
|
|
1193
|
+
return structuredClone(updated);
|
|
1194
|
+
}
|
|
1195
|
+
async waitForConnectionRunSelection(input) {
|
|
1196
|
+
const run = this.currentConnectionRun(input.runId);
|
|
1197
|
+
if (!sameConnectionRunScope(run, input) || run.status !== "running" || run.kind !== "connect" || run.processingId !== input.processingId || run.authorizationId !== input.authorizationId) {
|
|
1198
|
+
return null;
|
|
1199
|
+
}
|
|
1200
|
+
const now = this.now();
|
|
1201
|
+
const waiting = {
|
|
1202
|
+
...connectionRunBase(run, now),
|
|
1203
|
+
status: "waiting",
|
|
1204
|
+
waitingFor: "account_selection",
|
|
1205
|
+
authorizationId: input.authorizationId,
|
|
1206
|
+
expiresAt: new Date(input.expiresAt)
|
|
1207
|
+
};
|
|
1208
|
+
this.connectionRuns.set(run.id, waiting);
|
|
1209
|
+
return structuredClone(waiting);
|
|
1210
|
+
}
|
|
1211
|
+
async finishConnectionRun(input) {
|
|
1212
|
+
const run = this.currentConnectionRun(input.runId);
|
|
1213
|
+
if (!sameConnectionRunScope(run, input) || run.status !== "running")
|
|
1214
|
+
return null;
|
|
1215
|
+
if (input.processingId !== run.processingId)
|
|
1216
|
+
return null;
|
|
1217
|
+
const now = this.now();
|
|
1218
|
+
const authorizationId = input.status === "succeeded" ? input.authorizationId : input.status === "failed" ? input.authorizationId ?? run.authorizationId : run.authorizationId;
|
|
1219
|
+
if (input.status !== "succeeded" && run.kind === "connect" && authorizationId) {
|
|
1220
|
+
this.markPendingAuthorizationForCleanup(run.connectorId, authorizationId, now);
|
|
1221
|
+
}
|
|
1222
|
+
const base = connectionRunBase(run, now);
|
|
1223
|
+
const finished = input.status === "succeeded" ? {
|
|
1224
|
+
...base,
|
|
1225
|
+
status: "succeeded",
|
|
1226
|
+
authorizationId: input.authorizationId,
|
|
1227
|
+
...input.cleanupAuthorizationId === undefined ? {} : { cleanupAuthorizationId: input.cleanupAuthorizationId },
|
|
1228
|
+
connections: structuredClone(input.connections),
|
|
1229
|
+
finishedAt: now
|
|
1230
|
+
} : input.status === "failed" ? {
|
|
1231
|
+
...base,
|
|
1232
|
+
status: "failed",
|
|
1233
|
+
...authorizationId === undefined ? {} : { authorizationId },
|
|
1234
|
+
error: parseSixbFailure(input.error, CONNECTOR_CONNECTION_RUN_FAILURE_CODES),
|
|
1235
|
+
finishedAt: now
|
|
1236
|
+
} : {
|
|
1237
|
+
...base,
|
|
1238
|
+
status: "cancelled",
|
|
1239
|
+
...authorizationId === undefined ? {} : { authorizationId },
|
|
1240
|
+
finishedAt: now
|
|
1241
|
+
};
|
|
1242
|
+
this.connectionRuns.set(run.id, finished);
|
|
1243
|
+
return structuredClone(finished);
|
|
1244
|
+
}
|
|
1245
|
+
async getConnectionRun(input) {
|
|
1246
|
+
const run = this.currentConnectionRun(input.runId);
|
|
1247
|
+
return sameConnectionRunScope(run, input) ? structuredClone(run) : null;
|
|
1248
|
+
}
|
|
1249
|
+
async createAuthorization(input) {
|
|
1250
|
+
assertPositiveDuration(input.selectionTtlMs, "account selection TTL");
|
|
1251
|
+
if (this.authorizations.has(input.id)) {
|
|
1252
|
+
throw new ConnectorConnectionStorageError("authorization_conflict", "[Sixb] Connector authorization already exists.");
|
|
1253
|
+
}
|
|
1254
|
+
const now = this.now();
|
|
1255
|
+
const record = {
|
|
1256
|
+
id: input.id,
|
|
1257
|
+
projectId: input.projectId,
|
|
1258
|
+
connectorId: input.connectorId,
|
|
1259
|
+
authorizedBy: structuredClone(input.authorizedBy),
|
|
1260
|
+
credentials: structuredClone(input.credentials),
|
|
1261
|
+
...input.credentialExpiresAt === undefined ? {} : { credentialExpiresAt: new Date(input.credentialExpiresAt) },
|
|
1262
|
+
scopes: [...input.scopes],
|
|
1263
|
+
accounts: structuredClone(input.accounts),
|
|
1264
|
+
status: "pending_selection",
|
|
1265
|
+
selectionExpiresAt: new Date(now.getTime() + input.selectionTtlMs),
|
|
1266
|
+
revision: 0,
|
|
1267
|
+
createdAt: now,
|
|
1268
|
+
updatedAt: now
|
|
1269
|
+
};
|
|
1270
|
+
this.authorizations.set(record.id, record);
|
|
1271
|
+
return structuredClone(record);
|
|
1272
|
+
}
|
|
1273
|
+
async initializeAuthorizationAccounts(input) {
|
|
1274
|
+
const record = this.authorizations.get(input.authorizationId);
|
|
1275
|
+
if (!sameAuthorizationScope(record, input) || record.revision !== input.expectedRevision || record.status !== "pending_selection" || record.credentialMutation) {
|
|
1276
|
+
return null;
|
|
1277
|
+
}
|
|
1278
|
+
const updated = {
|
|
1279
|
+
...record,
|
|
1280
|
+
accounts: structuredClone(input.accounts),
|
|
1281
|
+
revision: record.revision + 1,
|
|
1282
|
+
updatedAt: this.now()
|
|
1283
|
+
};
|
|
1284
|
+
this.authorizations.set(record.id, updated);
|
|
1285
|
+
return structuredClone(updated);
|
|
1286
|
+
}
|
|
1287
|
+
async getAuthorization(input) {
|
|
1288
|
+
const authorization = this.authorizations.get(input.authorizationId);
|
|
1289
|
+
return sameAuthorizationScope(authorization, input) ? structuredClone(authorization) : null;
|
|
1290
|
+
}
|
|
1291
|
+
async getAuthorizationByConnectionId(input) {
|
|
1292
|
+
const connection = this.connections.get(input.connectionId);
|
|
1293
|
+
if (!sameConnectionScope(connection, input))
|
|
1294
|
+
return null;
|
|
1295
|
+
const authorization = this.authorizations.get(connection.authorizationId);
|
|
1296
|
+
return sameAuthorizationScope(authorization, input) ? structuredClone(authorization) : null;
|
|
1297
|
+
}
|
|
1298
|
+
async claimCredentialMutation(input) {
|
|
1299
|
+
assertPositiveDuration(input.leaseDurationMs, "credential mutation lease duration");
|
|
1300
|
+
assertPositiveDuration(input.operationTimeoutMs, "credential mutation timeout");
|
|
1301
|
+
const now = this.now();
|
|
1302
|
+
const record = this.authorizations.get(input.authorizationId);
|
|
1303
|
+
if (!sameAuthorizationScope(record, input) || record.revision !== input.expectedRevision || !canClaimMutation(record.status, input.mutation.kind)) {
|
|
1304
|
+
return null;
|
|
1305
|
+
}
|
|
1306
|
+
if (record.credentialMutation) {
|
|
1307
|
+
const canReplacePrepared = record.credentialMutation.phase === "prepared" && record.credentialMutation.expiresAt.getTime() <= now.getTime();
|
|
1308
|
+
if (!canReplacePrepared)
|
|
1309
|
+
return null;
|
|
1310
|
+
}
|
|
1311
|
+
const attached = this.connectedConnectionsForAuthorization(record.id);
|
|
1312
|
+
if (input.mutation.kind === "reauthorization" && !sameIds(attached.map((connection) => connection.id), input.expectedConnectionIds ?? [])) {
|
|
1313
|
+
return null;
|
|
1314
|
+
}
|
|
1315
|
+
const deadlineAt = new Date(now.getTime() + input.operationTimeoutMs);
|
|
1316
|
+
const mutation = {
|
|
1317
|
+
...structuredClone(input.mutation),
|
|
1318
|
+
phase: "prepared",
|
|
1319
|
+
expiresAt: leaseExpiry(now, input.leaseDurationMs, deadlineAt),
|
|
1320
|
+
deadlineAt,
|
|
1321
|
+
...input.mutation.kind === "reauthorization" ? { expectedConnectionIds: [...input.expectedConnectionIds ?? []] } : {}
|
|
1322
|
+
};
|
|
1323
|
+
const startsRevocation = input.mutation.kind === "revocation" && record.status !== "revocation_pending";
|
|
1324
|
+
const updated = {
|
|
1325
|
+
...record,
|
|
1326
|
+
status: input.mutation.kind === "revocation" ? "revocation_pending" : record.status,
|
|
1327
|
+
selectionExpiresAt: input.mutation.kind === "revocation" ? undefined : record.selectionExpiresAt,
|
|
1328
|
+
revision: startsRevocation ? record.revision + 1 : record.revision,
|
|
1329
|
+
credentialMutation: mutation,
|
|
1330
|
+
updatedAt: now
|
|
1331
|
+
};
|
|
1332
|
+
this.authorizations.set(record.id, updated);
|
|
1333
|
+
const disconnected = [];
|
|
1334
|
+
if (input.mutation.kind === "revocation") {
|
|
1335
|
+
for (const connection of attached) {
|
|
1336
|
+
const updatedConnection = disconnectConnectionRecord(connection, now);
|
|
1337
|
+
this.connections.set(connection.id, updatedConnection);
|
|
1338
|
+
disconnected.push(structuredClone(updatedConnection));
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1341
|
+
return { authorization: structuredClone(updated), disconnected };
|
|
1342
|
+
}
|
|
1343
|
+
async markCredentialMutationExecuting(input) {
|
|
1344
|
+
const now = this.now();
|
|
1345
|
+
const record = this.authorizations.get(input.authorizationId);
|
|
1346
|
+
if (!matchesMutation(record, input, input.holderId) || record.credentialMutation.phase !== "prepared" || mutationExpired(record, now)) {
|
|
1347
|
+
return null;
|
|
1348
|
+
}
|
|
1349
|
+
const updated = {
|
|
1350
|
+
...record,
|
|
1351
|
+
credentialMutation: { ...record.credentialMutation, phase: "executing" },
|
|
1352
|
+
updatedAt: now
|
|
1353
|
+
};
|
|
1354
|
+
this.authorizations.set(record.id, updated);
|
|
1355
|
+
return structuredClone(updated);
|
|
1356
|
+
}
|
|
1357
|
+
async renewCredentialMutation(input) {
|
|
1358
|
+
assertPositiveDuration(input.leaseDurationMs, "credential mutation lease duration");
|
|
1359
|
+
const now = this.now();
|
|
1360
|
+
const record = this.authorizations.get(input.authorizationId);
|
|
1361
|
+
if (!matchesMutation(record, input, input.holderId) || record.credentialMutation.phase === "result_staged" || mutationExpired(record, now)) {
|
|
1362
|
+
return null;
|
|
1363
|
+
}
|
|
1364
|
+
const updated = {
|
|
1365
|
+
...record,
|
|
1366
|
+
credentialMutation: {
|
|
1367
|
+
...record.credentialMutation,
|
|
1368
|
+
expiresAt: leaseExpiry(now, input.leaseDurationMs, record.credentialMutation.deadlineAt)
|
|
1369
|
+
}
|
|
1370
|
+
};
|
|
1371
|
+
this.authorizations.set(record.id, updated);
|
|
1372
|
+
return structuredClone(updated);
|
|
1373
|
+
}
|
|
1374
|
+
async stageCredentialMutationCredentials(input) {
|
|
1375
|
+
const now = this.now();
|
|
1376
|
+
const record = this.authorizations.get(input.authorizationId);
|
|
1377
|
+
if (!matchesMutation(record, input, input.holderId) || record.credentialMutation.phase !== "executing" || mutationExpired(record, now) || record.credentialMutation.kind === "revocation") {
|
|
1378
|
+
return null;
|
|
1379
|
+
}
|
|
1380
|
+
const updated = {
|
|
1381
|
+
...record,
|
|
1382
|
+
credentialMutation: {
|
|
1383
|
+
...record.credentialMutation,
|
|
1384
|
+
phase: "result_staged",
|
|
1385
|
+
stagedCredentials: {
|
|
1386
|
+
credentials: structuredClone(input.credentials),
|
|
1387
|
+
...input.credentialExpiresAt === undefined ? {} : { credentialExpiresAt: new Date(input.credentialExpiresAt) },
|
|
1388
|
+
scopes: [...input.scopes]
|
|
1389
|
+
}
|
|
1390
|
+
},
|
|
1391
|
+
updatedAt: now
|
|
1392
|
+
};
|
|
1393
|
+
this.authorizations.set(record.id, updated);
|
|
1394
|
+
return structuredClone(updated);
|
|
1395
|
+
}
|
|
1396
|
+
async stageCredentialMutationRevocation(input) {
|
|
1397
|
+
const now = this.now();
|
|
1398
|
+
const record = this.authorizations.get(input.authorizationId);
|
|
1399
|
+
if (!matchesMutation(record, input, input.holderId) || record.credentialMutation.phase !== "executing" || record.credentialMutation.kind !== "revocation" || mutationExpired(record, now)) {
|
|
1400
|
+
return null;
|
|
1401
|
+
}
|
|
1402
|
+
const updated = {
|
|
1403
|
+
...record,
|
|
1404
|
+
credentialMutation: { ...record.credentialMutation, phase: "result_staged" },
|
|
1405
|
+
updatedAt: now
|
|
1406
|
+
};
|
|
1407
|
+
this.authorizations.set(record.id, updated);
|
|
1408
|
+
return structuredClone(updated);
|
|
1409
|
+
}
|
|
1410
|
+
async releaseCredentialMutation(input) {
|
|
1411
|
+
const record = this.authorizations.get(input.authorizationId);
|
|
1412
|
+
if (!matchesMutation(record, input, input.holderId) || record.credentialMutation.phase === "result_staged") {
|
|
1413
|
+
return false;
|
|
1414
|
+
}
|
|
1415
|
+
this.authorizations.set(record.id, {
|
|
1416
|
+
...record,
|
|
1417
|
+
credentialMutation: undefined,
|
|
1418
|
+
updatedAt: this.now()
|
|
1419
|
+
});
|
|
1420
|
+
return true;
|
|
1421
|
+
}
|
|
1422
|
+
async recoverExpiredCredentialMutation(input) {
|
|
1423
|
+
const record = this.authorizations.get(input.authorizationId);
|
|
1424
|
+
if (!sameAuthorizationScope(record, input) || !record.credentialMutation)
|
|
1425
|
+
return null;
|
|
1426
|
+
if (record.credentialMutation.phase === "result_staged")
|
|
1427
|
+
return structuredClone(record);
|
|
1428
|
+
const now = this.now();
|
|
1429
|
+
if (!mutationExpired(record, now))
|
|
1430
|
+
return null;
|
|
1431
|
+
const ambiguous = record.credentialMutation.phase === "executing";
|
|
1432
|
+
const failClosed = ambiguous && record.credentialMutation.kind !== "revocation";
|
|
1433
|
+
const updated = {
|
|
1434
|
+
...record,
|
|
1435
|
+
status: failClosed ? "needs_reauthorization" : record.status,
|
|
1436
|
+
selectionExpiresAt: failClosed ? undefined : record.selectionExpiresAt,
|
|
1437
|
+
revision: failClosed ? record.revision + 1 : record.revision,
|
|
1438
|
+
credentialMutation: undefined,
|
|
1439
|
+
updatedAt: now
|
|
1440
|
+
};
|
|
1441
|
+
this.authorizations.set(record.id, updated);
|
|
1442
|
+
return structuredClone(updated);
|
|
1443
|
+
}
|
|
1444
|
+
async markNeedsReauthorization(input) {
|
|
1445
|
+
const record = this.authorizations.get(input.authorizationId);
|
|
1446
|
+
if (!matchesMutation(record, input))
|
|
1447
|
+
return null;
|
|
1448
|
+
const staged = record.credentialMutation.stagedCredentials;
|
|
1449
|
+
const updated = {
|
|
1450
|
+
...record,
|
|
1451
|
+
...staged ? {
|
|
1452
|
+
credentials: structuredClone(staged.credentials),
|
|
1453
|
+
credentialExpiresAt: staged.credentialExpiresAt === undefined ? undefined : new Date(staged.credentialExpiresAt),
|
|
1454
|
+
scopes: [...staged.scopes]
|
|
1455
|
+
} : {},
|
|
1456
|
+
status: "needs_reauthorization",
|
|
1457
|
+
selectionExpiresAt: undefined,
|
|
1458
|
+
revision: record.revision + 1,
|
|
1459
|
+
credentialMutation: undefined,
|
|
1460
|
+
updatedAt: this.now()
|
|
1461
|
+
};
|
|
1462
|
+
this.authorizations.set(record.id, updated);
|
|
1463
|
+
return structuredClone(updated);
|
|
1464
|
+
}
|
|
1465
|
+
async finalizeRefresh(input) {
|
|
1466
|
+
const record = this.authorizations.get(input.authorizationId);
|
|
1467
|
+
const staged = stagedCredentials(record, input, "refresh");
|
|
1468
|
+
if (!record || !staged)
|
|
1469
|
+
return null;
|
|
1470
|
+
const updated = applyStagedCredentials(record, staged, this.now(), {
|
|
1471
|
+
status: "active",
|
|
1472
|
+
accounts: record.accounts
|
|
1473
|
+
});
|
|
1474
|
+
this.authorizations.set(record.id, updated);
|
|
1475
|
+
return structuredClone(updated);
|
|
1476
|
+
}
|
|
1477
|
+
async finalizeReauthorization(input) {
|
|
1478
|
+
const record = this.authorizations.get(input.authorizationId);
|
|
1479
|
+
const staged = stagedCredentials(record, input, "reauthorization");
|
|
1480
|
+
if (!record || !staged || !record.credentialMutation)
|
|
1481
|
+
return null;
|
|
1482
|
+
const attached = this.connectedConnectionsForAuthorization(record.id);
|
|
1483
|
+
if (!sameIds(attached.map((connection) => connection.id), record.credentialMutation.expectedConnectionIds ?? [])) {
|
|
1484
|
+
throw new ConnectorConnectionStorageError("authorization_conflict", "[Sixb] Connections attached to the connector authorization changed during reauthorization.");
|
|
1485
|
+
}
|
|
1486
|
+
const accountsById = new Map(input.accounts.map((account) => [account.id, account]));
|
|
1487
|
+
if (attached.some((connection) => !accountsById.has(connection.account.id))) {
|
|
1488
|
+
throw new ConnectorConnectionStorageError("authorization_conflict", "[Sixb] Reauthorized connector grant no longer exposes every attached account.");
|
|
1489
|
+
}
|
|
1490
|
+
const now = this.now();
|
|
1491
|
+
const updated = applyStagedCredentials(record, staged, now, {
|
|
1492
|
+
status: "active",
|
|
1493
|
+
accounts: input.accounts
|
|
1494
|
+
});
|
|
1495
|
+
this.authorizations.set(record.id, updated);
|
|
1496
|
+
for (const connection of attached) {
|
|
1497
|
+
this.connections.set(connection.id, {
|
|
1498
|
+
...connection,
|
|
1499
|
+
account: structuredClone(accountsById.get(connection.account.id)),
|
|
1500
|
+
updatedAt: now
|
|
1501
|
+
});
|
|
1502
|
+
}
|
|
1503
|
+
return structuredClone(updated);
|
|
1504
|
+
}
|
|
1505
|
+
async finalizeRevocation(input) {
|
|
1506
|
+
const record = this.authorizations.get(input.authorizationId);
|
|
1507
|
+
if (!matchesMutation(record, input) || record.credentialMutation.kind !== "revocation" || record.credentialMutation.phase !== "result_staged") {
|
|
1508
|
+
return null;
|
|
1509
|
+
}
|
|
1510
|
+
const updated = {
|
|
1511
|
+
...record,
|
|
1512
|
+
status: "revoked",
|
|
1513
|
+
credentials: undefined,
|
|
1514
|
+
credentialExpiresAt: undefined,
|
|
1515
|
+
scopes: [],
|
|
1516
|
+
accounts: [],
|
|
1517
|
+
selectionExpiresAt: undefined,
|
|
1518
|
+
revision: record.revision + 1,
|
|
1519
|
+
credentialMutation: undefined,
|
|
1520
|
+
updatedAt: this.now()
|
|
1521
|
+
};
|
|
1522
|
+
this.authorizations.set(record.id, updated);
|
|
1523
|
+
return structuredClone(updated);
|
|
1524
|
+
}
|
|
1525
|
+
async putConnection(input) {
|
|
1526
|
+
return this.putConnectionNow(input, this.now());
|
|
1527
|
+
}
|
|
1528
|
+
async putConnectionFromRun(input) {
|
|
1529
|
+
const run = this.currentConnectionRun(input.runId);
|
|
1530
|
+
if (!sameConnectionRunScope(run, input) || run.status !== "waiting" || run.waitingFor !== "account_selection") {
|
|
1531
|
+
throw invalidRun();
|
|
1532
|
+
}
|
|
1533
|
+
const now = this.now();
|
|
1534
|
+
const result = this.putConnectionNow({
|
|
1535
|
+
id: input.id,
|
|
1536
|
+
projectId: input.projectId,
|
|
1537
|
+
connectorId: input.connectorId,
|
|
1538
|
+
owner: run.owner,
|
|
1539
|
+
slot: run.slot,
|
|
1540
|
+
authorizationId: run.authorizationId,
|
|
1541
|
+
account: input.account,
|
|
1542
|
+
replace: input.replace
|
|
1543
|
+
}, now);
|
|
1544
|
+
const succeeded = {
|
|
1545
|
+
...connectionRunBase(run, now),
|
|
1546
|
+
status: "succeeded",
|
|
1547
|
+
authorizationId: run.authorizationId,
|
|
1548
|
+
...result.revocationPendingAuthorizationId === undefined ? {} : { cleanupAuthorizationId: result.revocationPendingAuthorizationId },
|
|
1549
|
+
connections: [structuredClone(result.connection)],
|
|
1550
|
+
finishedAt: now
|
|
1551
|
+
};
|
|
1552
|
+
this.connectionRuns.set(run.id, succeeded);
|
|
1553
|
+
return { ...result, run: structuredClone(succeeded) };
|
|
1554
|
+
}
|
|
1555
|
+
putConnectionNow(input, now) {
|
|
1556
|
+
let authorization = this.authorizations.get(input.authorizationId);
|
|
1557
|
+
if (!sameAuthorizationScope(authorization, input) || !isSelectable(authorization.status) || authorization.credentialMutation?.kind === "reauthorization") {
|
|
1558
|
+
throw authorizationConflict();
|
|
1559
|
+
}
|
|
1560
|
+
if (authorization.status === "pending_selection" && authorization.selectionExpiresAt.getTime() <= now.getTime()) {
|
|
1561
|
+
authorization = {
|
|
1562
|
+
...authorization,
|
|
1563
|
+
status: "revocation_pending",
|
|
1564
|
+
selectionExpiresAt: undefined,
|
|
1565
|
+
revision: authorization.revision + 1,
|
|
1566
|
+
updatedAt: now
|
|
1567
|
+
};
|
|
1568
|
+
this.authorizations.set(authorization.id, authorization);
|
|
1569
|
+
throw authorizationConflict();
|
|
1570
|
+
}
|
|
1571
|
+
const account = authorization.accounts.find((candidate) => candidate.id === input.account.id);
|
|
1572
|
+
if (!account) {
|
|
1573
|
+
throw new ConnectorConnectionStorageError("authorization_conflict", "[Sixb] Connector connection account is not exposed by its authorization.");
|
|
1574
|
+
}
|
|
1575
|
+
const existing = this.findConnectionRecord(input);
|
|
1576
|
+
const sameAccount = existing?.account.id === account.id;
|
|
1577
|
+
if (existing && !sameAccount && !input.replace) {
|
|
1578
|
+
throw new ConnectorConnectionStorageError("connection_conflict", `[Sixb] Connector slot '${input.slot}' is already connected to another account; explicit replacement is required.`);
|
|
1579
|
+
}
|
|
1580
|
+
if (!existing && this.connections.has(input.id)) {
|
|
1581
|
+
throw new ConnectorConnectionStorageError("connection_conflict", "[Sixb] Connector connection id already exists.");
|
|
1582
|
+
}
|
|
1583
|
+
let revocationPendingAuthorizationId;
|
|
1584
|
+
if (existing?.status === "connected" && existing.authorizationId !== authorization.id) {
|
|
1585
|
+
const previous = this.authorizations.get(existing.authorizationId);
|
|
1586
|
+
if (!previous) {
|
|
1587
|
+
throw new ConnectorConnectionStorageError("authorization_conflict", "[Sixb] Existing connector connection references an unavailable authorization.");
|
|
1588
|
+
}
|
|
1589
|
+
const remaining = this.connectedConnectionsForAuthorization(previous.id).filter((connection2) => connection2.id !== existing.id);
|
|
1590
|
+
this.assertConnectionCanMove(existing, previous, remaining.length === 0);
|
|
1591
|
+
if (remaining.length === 0) {
|
|
1592
|
+
const pending = markAuthorizationRevocationPending(previous, now);
|
|
1593
|
+
this.authorizations.set(previous.id, pending);
|
|
1594
|
+
revocationPendingAuthorizationId = previous.id;
|
|
1595
|
+
}
|
|
1596
|
+
} else if (existing?.status === "connected") {
|
|
1597
|
+
const previous = this.authorizations.get(existing.authorizationId);
|
|
1598
|
+
if (previous)
|
|
1599
|
+
this.assertConnectionCanMove(existing, previous, false);
|
|
1600
|
+
}
|
|
1601
|
+
const updatedAuthorization = authorization.status === "pending_selection" ? {
|
|
1602
|
+
...authorization,
|
|
1603
|
+
status: "active",
|
|
1604
|
+
selectionExpiresAt: undefined,
|
|
1605
|
+
revision: authorization.revision + 1,
|
|
1606
|
+
updatedAt: now
|
|
1607
|
+
} : authorization;
|
|
1608
|
+
const connection = existing ? {
|
|
1609
|
+
...existing,
|
|
1610
|
+
authorizationId: input.authorizationId,
|
|
1611
|
+
account: structuredClone(account),
|
|
1612
|
+
status: "connected",
|
|
1613
|
+
disconnectedAt: undefined,
|
|
1614
|
+
updatedAt: now
|
|
1615
|
+
} : {
|
|
1616
|
+
id: input.id,
|
|
1617
|
+
projectId: input.projectId,
|
|
1618
|
+
connectorId: input.connectorId,
|
|
1619
|
+
owner: structuredClone(input.owner),
|
|
1620
|
+
slot: input.slot,
|
|
1621
|
+
authorizationId: input.authorizationId,
|
|
1622
|
+
account: structuredClone(account),
|
|
1623
|
+
status: "connected",
|
|
1624
|
+
createdAt: now,
|
|
1625
|
+
updatedAt: now
|
|
1626
|
+
};
|
|
1627
|
+
if (updatedAuthorization !== authorization) {
|
|
1628
|
+
this.authorizations.set(updatedAuthorization.id, updatedAuthorization);
|
|
1629
|
+
}
|
|
1630
|
+
this.connections.set(connection.id, connection);
|
|
1631
|
+
return {
|
|
1632
|
+
connection: structuredClone(connection),
|
|
1633
|
+
authorization: structuredClone(updatedAuthorization),
|
|
1634
|
+
...revocationPendingAuthorizationId === undefined ? {} : { revocationPendingAuthorizationId },
|
|
1635
|
+
created: existing === undefined,
|
|
1636
|
+
replaced: existing !== undefined && !sameAccount
|
|
1637
|
+
};
|
|
1638
|
+
}
|
|
1639
|
+
async getConnection(input) {
|
|
1640
|
+
const connection = this.findConnectionRecord(input);
|
|
1641
|
+
return connection?.status === "connected" ? structuredClone(connection) : null;
|
|
1642
|
+
}
|
|
1643
|
+
async getConnectionById(input) {
|
|
1644
|
+
const connection = this.connections.get(input.connectionId);
|
|
1645
|
+
return sameConnectionScope(connection, input) ? structuredClone(connection) : null;
|
|
1646
|
+
}
|
|
1647
|
+
async listConnections(input) {
|
|
1648
|
+
return [...this.connections.values()].filter((connection) => sameConnectionScope(connection, input)).map((connection) => structuredClone(connection));
|
|
1649
|
+
}
|
|
1650
|
+
async listConnectionsByAuthorization(input) {
|
|
1651
|
+
const authorization = this.authorizations.get(input.authorizationId);
|
|
1652
|
+
if (!sameAuthorizationScope(authorization, input))
|
|
1653
|
+
return [];
|
|
1654
|
+
return this.connectedConnectionsForAuthorization(input.authorizationId).filter((connection) => sameConnectionScope(connection, input)).map((connection) => structuredClone(connection));
|
|
1655
|
+
}
|
|
1656
|
+
async disconnectConnection(input) {
|
|
1657
|
+
const connection = this.connections.get(input.connectionId);
|
|
1658
|
+
if (!connection || connection.projectId !== input.projectId || connection.connectorId !== input.connectorId) {
|
|
1659
|
+
return null;
|
|
1660
|
+
}
|
|
1661
|
+
const authorization = this.authorizations.get(connection.authorizationId);
|
|
1662
|
+
if (!sameAuthorizationScope(authorization, input)) {
|
|
1663
|
+
throw new ConnectorConnectionStorageError("authorization_conflict", "[Sixb] Connector connection references an unavailable authorization.");
|
|
1664
|
+
}
|
|
1665
|
+
if (connection.status === "disconnected") {
|
|
1666
|
+
return {
|
|
1667
|
+
connection: structuredClone(connection),
|
|
1668
|
+
authorization: structuredClone(authorization),
|
|
1669
|
+
...authorization.status === "revocation_pending" ? { revocationPendingAuthorizationId: authorization.id } : {}
|
|
1670
|
+
};
|
|
1671
|
+
}
|
|
1672
|
+
const now = this.now();
|
|
1673
|
+
const remaining = this.connectedConnectionsForAuthorization(authorization.id).filter((candidate) => candidate.id !== connection.id);
|
|
1674
|
+
this.assertConnectionCanMove(connection, authorization, remaining.length === 0);
|
|
1675
|
+
const disconnected = disconnectConnectionRecord(connection, now);
|
|
1676
|
+
this.connections.set(connection.id, disconnected);
|
|
1677
|
+
const updatedAuthorization = remaining.length === 0 ? markAuthorizationRevocationPending(authorization, now) : authorization;
|
|
1678
|
+
if (updatedAuthorization !== authorization) {
|
|
1679
|
+
this.authorizations.set(authorization.id, updatedAuthorization);
|
|
1680
|
+
}
|
|
1681
|
+
return {
|
|
1682
|
+
connection: structuredClone(disconnected),
|
|
1683
|
+
authorization: structuredClone(updatedAuthorization),
|
|
1684
|
+
...updatedAuthorization.status === "revocation_pending" && remaining.length === 0 ? { revocationPendingAuthorizationId: updatedAuthorization.id } : {}
|
|
1685
|
+
};
|
|
1686
|
+
}
|
|
1687
|
+
snapshot() {
|
|
1688
|
+
return {
|
|
1689
|
+
attempts: structuredClone(this.attempts),
|
|
1690
|
+
connectionRuns: structuredClone(this.connectionRuns),
|
|
1691
|
+
authorizations: structuredClone(this.authorizations),
|
|
1692
|
+
connections: structuredClone(this.connections)
|
|
1693
|
+
};
|
|
1694
|
+
}
|
|
1695
|
+
restore(snapshot) {
|
|
1696
|
+
replaceMap2(this.attempts, snapshot.attempts);
|
|
1697
|
+
replaceMap2(this.connectionRuns, snapshot.connectionRuns);
|
|
1698
|
+
replaceMap2(this.authorizations, snapshot.authorizations);
|
|
1699
|
+
replaceMap2(this.connections, snapshot.connections);
|
|
1700
|
+
}
|
|
1701
|
+
now() {
|
|
1702
|
+
return new Date(this.options.now?.() ?? new Date);
|
|
1703
|
+
}
|
|
1704
|
+
currentConnectionRun(runId) {
|
|
1705
|
+
const run = this.connectionRuns.get(runId);
|
|
1706
|
+
if (!run || run.status !== "waiting" && run.status !== "running")
|
|
1707
|
+
return run;
|
|
1708
|
+
const now = this.now();
|
|
1709
|
+
if (run.expiresAt.getTime() > now.getTime())
|
|
1710
|
+
return run;
|
|
1711
|
+
if (run.status === "waiting" && run.waitingFor === "provider_authorization") {
|
|
1712
|
+
const attempt = this.findAuthorizationAttemptByConnectionRunId(run.id);
|
|
1713
|
+
if (attempt)
|
|
1714
|
+
this.attempts.delete(attempt.id);
|
|
1715
|
+
}
|
|
1716
|
+
if (run.status === "waiting") {
|
|
1717
|
+
if (run.kind === "connect" && run.waitingFor === "account_selection") {
|
|
1718
|
+
this.markPendingAuthorizationForCleanup(run.connectorId, run.authorizationId, now);
|
|
1719
|
+
}
|
|
1720
|
+
const expired = expireConnectionRun(run, now);
|
|
1721
|
+
this.connectionRuns.set(run.id, expired);
|
|
1722
|
+
return expired;
|
|
1723
|
+
}
|
|
1724
|
+
if (run.kind === "connect" && run.authorizationId) {
|
|
1725
|
+
this.markPendingAuthorizationForCleanup(run.connectorId, run.authorizationId, now);
|
|
1726
|
+
}
|
|
1727
|
+
const failed = failExpiredProcessingRun(run, now);
|
|
1728
|
+
this.connectionRuns.set(run.id, failed);
|
|
1729
|
+
return failed;
|
|
1730
|
+
}
|
|
1731
|
+
findConnectionRecord(input) {
|
|
1732
|
+
for (const connection of this.connections.values()) {
|
|
1733
|
+
if (connection.projectId === input.projectId && connection.connectorId === input.connectorId && connection.owner.type === input.owner.type && connection.slot === input.slot) {
|
|
1734
|
+
return connection;
|
|
1735
|
+
}
|
|
1736
|
+
}
|
|
1737
|
+
return;
|
|
1738
|
+
}
|
|
1739
|
+
findAuthorizationAttemptByConnectionRunId(connectionRunId) {
|
|
1740
|
+
for (const attempt of this.attempts.values()) {
|
|
1741
|
+
if (attempt.connectionRunId === connectionRunId)
|
|
1742
|
+
return attempt;
|
|
1743
|
+
}
|
|
1744
|
+
return;
|
|
1745
|
+
}
|
|
1746
|
+
connectionRecordsForAuthorization(authorizationId) {
|
|
1747
|
+
return [...this.connections.values()].filter((connection) => connection.authorizationId === authorizationId);
|
|
1748
|
+
}
|
|
1749
|
+
connectedConnectionsForAuthorization(authorizationId) {
|
|
1750
|
+
return this.connectionRecordsForAuthorization(authorizationId).filter((connection) => connection.status === "connected");
|
|
1751
|
+
}
|
|
1752
|
+
assertConnectionCanMove(_connection, authorization, removingLastConnection = true) {
|
|
1753
|
+
const mutation = authorization.credentialMutation;
|
|
1754
|
+
if (mutation?.kind === "reauthorization") {
|
|
1755
|
+
throw new ConnectorConnectionStorageError("authorization_conflict", "[Sixb] Connections cannot change while their connector authorization is being reauthorized.");
|
|
1756
|
+
}
|
|
1757
|
+
if (removingLastConnection && mutation) {
|
|
1758
|
+
throw new ConnectorConnectionStorageError("authorization_conflict", "[Sixb] The last connector connection cannot be removed while credentials are being mutated.");
|
|
1759
|
+
}
|
|
1760
|
+
}
|
|
1761
|
+
markPendingAuthorizationForCleanup(connectorId, authorizationId, now) {
|
|
1762
|
+
const authorization = this.authorizations.get(authorizationId);
|
|
1763
|
+
if (!authorization || authorization.connectorId !== connectorId || authorization.status !== "pending_selection") {
|
|
1764
|
+
return;
|
|
1765
|
+
}
|
|
1766
|
+
this.authorizations.set(authorization.id, markAuthorizationRevocationPending(authorization, now));
|
|
1767
|
+
}
|
|
1768
|
+
}
|
|
1769
|
+
function disconnectConnectionRecord(connection, now) {
|
|
1770
|
+
return {
|
|
1771
|
+
...connection,
|
|
1772
|
+
status: "disconnected",
|
|
1773
|
+
disconnectedAt: new Date(now),
|
|
1774
|
+
updatedAt: new Date(now)
|
|
1775
|
+
};
|
|
1776
|
+
}
|
|
1777
|
+
function markAuthorizationRevocationPending(authorization, now) {
|
|
1778
|
+
if (authorization.status === "revocation_pending" || authorization.status === "revoked") {
|
|
1779
|
+
return authorization;
|
|
1780
|
+
}
|
|
1781
|
+
if (authorization.credentialMutation) {
|
|
1782
|
+
throw new ConnectorConnectionStorageError("authorization_conflict", "[Sixb] Connector authorization cannot begin revocation while credentials are being mutated.");
|
|
1783
|
+
}
|
|
1784
|
+
return {
|
|
1785
|
+
...authorization,
|
|
1786
|
+
status: "revocation_pending",
|
|
1787
|
+
selectionExpiresAt: undefined,
|
|
1788
|
+
revision: authorization.revision + 1,
|
|
1789
|
+
updatedAt: new Date(now)
|
|
1790
|
+
};
|
|
1791
|
+
}
|
|
1792
|
+
function safeEqual(left, right) {
|
|
1793
|
+
const leftBytes = Buffer.from(left);
|
|
1794
|
+
const rightBytes = Buffer.from(right);
|
|
1795
|
+
return leftBytes.length === rightBytes.length && timingSafeEqual(leftBytes, rightBytes);
|
|
1796
|
+
}
|
|
1797
|
+
function invalidRun() {
|
|
1798
|
+
return new ConnectorConnectionStorageError("run_invalid", "[Sixb] Connector connection run is invalid, expired, or already used.");
|
|
1799
|
+
}
|
|
1800
|
+
function replaceMap2(target, source) {
|
|
1801
|
+
target.clear();
|
|
1802
|
+
for (const [key2, value] of structuredClone(source))
|
|
1803
|
+
target.set(key2, value);
|
|
1804
|
+
}
|
|
1805
|
+
function sameIds(left, right) {
|
|
1806
|
+
const leftSorted = [...left].sort();
|
|
1807
|
+
const rightSorted = [...right].sort();
|
|
1808
|
+
return leftSorted.length === rightSorted.length && leftSorted.every((value, index) => value === rightSorted[index]);
|
|
1809
|
+
}
|
|
1810
|
+
function invalidAttempt() {
|
|
1811
|
+
return new ConnectorConnectionStorageError("attempt_invalid", "[Sixb] Connector authorization attempt is invalid, expired, or already used.");
|
|
1812
|
+
}
|
|
1813
|
+
function authorizationConflict() {
|
|
1814
|
+
return new ConnectorConnectionStorageError("authorization_conflict", "[Sixb] Connector connection requires a selectable authorization from the same project and connector.");
|
|
1815
|
+
}
|
|
1816
|
+
function assertPositiveDuration(value, name) {
|
|
1817
|
+
if (!Number.isFinite(value) || value <= 0) {
|
|
1818
|
+
throw new ConnectorConnectionStorageError("invalid_input", `[Sixb] Connector ${name} must be positive.`);
|
|
1819
|
+
}
|
|
1820
|
+
}
|
|
1821
|
+
function sameAuthorizationScope(record, input) {
|
|
1822
|
+
return record !== undefined && record.projectId === input.projectId && record.connectorId === input.connectorId;
|
|
1823
|
+
}
|
|
1824
|
+
function sameConnectionScope(record, input) {
|
|
1825
|
+
return record !== undefined && record.projectId === input.projectId && record.connectorId === input.connectorId;
|
|
1826
|
+
}
|
|
1827
|
+
function sameConnectionRunScope(record, input) {
|
|
1828
|
+
return record !== undefined && record.projectId === input.projectId && record.connectorId === input.connectorId;
|
|
1829
|
+
}
|
|
1830
|
+
function canClaimMutation(status, kind) {
|
|
1831
|
+
if (kind === "refresh")
|
|
1832
|
+
return status === "active";
|
|
1833
|
+
if (kind === "reauthorization") {
|
|
1834
|
+
return status === "active" || status === "needs_reauthorization";
|
|
1835
|
+
}
|
|
1836
|
+
return status !== "revoked";
|
|
1837
|
+
}
|
|
1838
|
+
function isSelectable(status) {
|
|
1839
|
+
return status === "pending_selection" || status === "active";
|
|
1840
|
+
}
|
|
1841
|
+
function leaseExpiry(now, durationMs, deadlineAt) {
|
|
1842
|
+
return new Date(Math.min(now.getTime() + durationMs, deadlineAt.getTime()));
|
|
1843
|
+
}
|
|
1844
|
+
function mutationExpired(record, now) {
|
|
1845
|
+
return record.credentialMutation.expiresAt.getTime() <= now.getTime() || record.credentialMutation.deadlineAt.getTime() <= now.getTime();
|
|
1846
|
+
}
|
|
1847
|
+
function matchesMutation(record, input, holderId) {
|
|
1848
|
+
return sameAuthorizationScope(record, input) && record.revision === input.expectedRevision && record.credentialMutation?.id === input.mutationId && (holderId === undefined || record.credentialMutation.holderId === holderId);
|
|
1849
|
+
}
|
|
1850
|
+
function stagedCredentials(record, input, kind) {
|
|
1851
|
+
if (!matchesMutation(record, input) || record.credentialMutation.kind !== kind || record.credentialMutation.phase !== "result_staged") {
|
|
1852
|
+
return null;
|
|
1853
|
+
}
|
|
1854
|
+
return record.credentialMutation.stagedCredentials ?? null;
|
|
1855
|
+
}
|
|
1856
|
+
function applyStagedCredentials(record, staged, now, input) {
|
|
1857
|
+
return {
|
|
1858
|
+
...record,
|
|
1859
|
+
credentials: structuredClone(staged.credentials),
|
|
1860
|
+
credentialExpiresAt: staged.credentialExpiresAt === undefined ? undefined : new Date(staged.credentialExpiresAt),
|
|
1861
|
+
scopes: [...staged.scopes],
|
|
1862
|
+
accounts: structuredClone(input.accounts),
|
|
1863
|
+
status: input.status,
|
|
1864
|
+
selectionExpiresAt: undefined,
|
|
1865
|
+
revision: record.revision + 1,
|
|
1866
|
+
credentialMutation: undefined,
|
|
1867
|
+
updatedAt: now
|
|
1868
|
+
};
|
|
1869
|
+
}
|
|
404
1870
|
// src/storage/errors.ts
|
|
405
1871
|
class ObjectNotFoundError extends Error {
|
|
406
1872
|
objectTypeId;
|
|
@@ -589,6 +2055,55 @@ class InMemoryFileUploadSessions {
|
|
|
589
2055
|
// src/storage/in-memory/index.ts
|
|
590
2056
|
import { AsyncLocalStorage } from "async_hooks";
|
|
591
2057
|
|
|
2058
|
+
// src/storage/executions/in-memory.ts
|
|
2059
|
+
var runDirectly2 = async (run) => run();
|
|
2060
|
+
function executionKey(projectId, id) {
|
|
2061
|
+
return JSON.stringify([projectId, id]);
|
|
2062
|
+
}
|
|
2063
|
+
|
|
2064
|
+
class InMemoryExecutionStorage {
|
|
2065
|
+
auth;
|
|
2066
|
+
rows = new Map;
|
|
2067
|
+
runRootOperation;
|
|
2068
|
+
constructor(auth, input = {}) {
|
|
2069
|
+
this.auth = auth;
|
|
2070
|
+
this.runRootOperation = input.runRootOperation ?? runDirectly2;
|
|
2071
|
+
}
|
|
2072
|
+
snapshot() {
|
|
2073
|
+
return structuredClone(this.rows);
|
|
2074
|
+
}
|
|
2075
|
+
restore(snapshot) {
|
|
2076
|
+
this.rows.clear();
|
|
2077
|
+
for (const [key2, record] of structuredClone(snapshot)) {
|
|
2078
|
+
this.rows.set(key2, record);
|
|
2079
|
+
}
|
|
2080
|
+
}
|
|
2081
|
+
async create(input) {
|
|
2082
|
+
return this.runRootOperation(async () => {
|
|
2083
|
+
const record = normalizeExecutionRecord(input);
|
|
2084
|
+
const key2 = executionKey(record.projectId, record.id);
|
|
2085
|
+
if (this.rows.has(key2)) {
|
|
2086
|
+
throw new ExecutionStorageError("duplicate_execution", `[Sixb] Execution '${record.id}' already exists in project '${record.projectId}'.`);
|
|
2087
|
+
}
|
|
2088
|
+
await validateExecutionRecordReferences(record, {
|
|
2089
|
+
auth: this.auth,
|
|
2090
|
+
getExecution: async ({ projectId, id }) => {
|
|
2091
|
+
const existing = this.rows.get(executionKey(projectId, id));
|
|
2092
|
+
return existing ? cloneExecutionRecord(existing) : null;
|
|
2093
|
+
}
|
|
2094
|
+
});
|
|
2095
|
+
this.rows.set(key2, cloneExecutionRecord(record));
|
|
2096
|
+
return cloneExecutionRecord(record);
|
|
2097
|
+
});
|
|
2098
|
+
}
|
|
2099
|
+
async getById(params) {
|
|
2100
|
+
return this.runRootOperation(() => {
|
|
2101
|
+
const record = this.rows.get(executionKey(params.projectId, params.id));
|
|
2102
|
+
return record ? cloneExecutionRecord(record) : null;
|
|
2103
|
+
});
|
|
2104
|
+
}
|
|
2105
|
+
}
|
|
2106
|
+
|
|
592
2107
|
// src/storage/objects/in-memory.ts
|
|
593
2108
|
var IN_MEMORY_OBJECT_QUERY_CAPABILITIES = {
|
|
594
2109
|
queryObjects: true,
|
|
@@ -715,12 +2230,12 @@ class InMemoryObjectStorage {
|
|
|
715
2230
|
}
|
|
716
2231
|
restore(snapshot) {
|
|
717
2232
|
this.rows.clear();
|
|
718
|
-
for (const [
|
|
719
|
-
this.rows.set(
|
|
2233
|
+
for (const [key2, bucket] of cloneObjectBuckets(snapshot.rows)) {
|
|
2234
|
+
this.rows.set(key2, bucket);
|
|
720
2235
|
}
|
|
721
2236
|
this.links.clear();
|
|
722
|
-
for (const [
|
|
723
|
-
this.links.set(
|
|
2237
|
+
for (const [key2, bucket] of cloneLinkBuckets(snapshot.links)) {
|
|
2238
|
+
this.links.set(key2, bucket);
|
|
724
2239
|
}
|
|
725
2240
|
}
|
|
726
2241
|
getExactObjectRow(projectId, objectTypeId, primaryId) {
|
|
@@ -907,8 +2422,8 @@ class InMemoryObjectStorage {
|
|
|
907
2422
|
if (op === "intersect") {
|
|
908
2423
|
const otherKeySets = evaluations.slice(1).map((evaluation) => new Set(evaluation.entries.map((entry) => rowIdentityKey(entry.row))));
|
|
909
2424
|
const entries = first.entries.filter((entry) => {
|
|
910
|
-
const
|
|
911
|
-
return otherKeySets.every((keys) => keys.has(
|
|
2425
|
+
const key2 = rowIdentityKey(entry.row);
|
|
2426
|
+
return otherKeySets.every((keys) => keys.has(key2));
|
|
912
2427
|
});
|
|
913
2428
|
return completeEvaluation(entries);
|
|
914
2429
|
}
|
|
@@ -1055,8 +2570,8 @@ class InMemoryObjectStorage {
|
|
|
1055
2570
|
}
|
|
1056
2571
|
}
|
|
1057
2572
|
} else {
|
|
1058
|
-
for (const [
|
|
1059
|
-
if (
|
|
2573
|
+
for (const [key2, bucket] of this.rows) {
|
|
2574
|
+
if (key2.startsWith(`${params.projectId}:`)) {
|
|
1060
2575
|
allRows.push(...bucket.values());
|
|
1061
2576
|
}
|
|
1062
2577
|
}
|
|
@@ -1113,18 +2628,18 @@ function assertReconciliationPageLimit(limit) {
|
|
|
1113
2628
|
}
|
|
1114
2629
|
}
|
|
1115
2630
|
function cloneObjectBuckets(rows) {
|
|
1116
|
-
const
|
|
1117
|
-
for (const [
|
|
1118
|
-
|
|
2631
|
+
const clone2 = new Map;
|
|
2632
|
+
for (const [key2, bucket] of rows) {
|
|
2633
|
+
clone2.set(key2, new Map([...bucket.entries()].map(([primaryId, row]) => [primaryId, structuredClone(row)])));
|
|
1119
2634
|
}
|
|
1120
|
-
return
|
|
2635
|
+
return clone2;
|
|
1121
2636
|
}
|
|
1122
2637
|
function cloneLinkBuckets(links) {
|
|
1123
|
-
const
|
|
1124
|
-
for (const [
|
|
1125
|
-
|
|
2638
|
+
const clone2 = new Map;
|
|
2639
|
+
for (const [key2, bucket] of links) {
|
|
2640
|
+
clone2.set(key2, new Map([...bucket.entries()].map(([linkId, row]) => [linkId, structuredClone(row)])));
|
|
1126
2641
|
}
|
|
1127
|
-
return
|
|
2642
|
+
return clone2;
|
|
1128
2643
|
}
|
|
1129
2644
|
function completeEvaluation(entries) {
|
|
1130
2645
|
return {
|
|
@@ -1302,12 +2817,12 @@ function buildFacetBuckets(rows, facet) {
|
|
|
1302
2817
|
const value = row.properties[facet.propertyId];
|
|
1303
2818
|
if (value === undefined)
|
|
1304
2819
|
continue;
|
|
1305
|
-
const
|
|
1306
|
-
const existing = buckets.get(
|
|
2820
|
+
const key2 = facetValueKey(value);
|
|
2821
|
+
const existing = buckets.get(key2);
|
|
1307
2822
|
if (existing) {
|
|
1308
2823
|
existing.count += 1;
|
|
1309
2824
|
} else {
|
|
1310
|
-
buckets.set(
|
|
2825
|
+
buckets.set(key2, { value, count: 1 });
|
|
1311
2826
|
}
|
|
1312
2827
|
}
|
|
1313
2828
|
return [...buckets.values()].sort((left, right) => right.count - left.count || facetValueSortKey(left.value).localeCompare(facetValueSortKey(right.value))).slice(0, facet.limit);
|
|
@@ -1325,14 +2840,14 @@ function rowIdentityKeyParts(objectTypeId, primaryId) {
|
|
|
1325
2840
|
return `${objectTypeId}:${primaryId}`;
|
|
1326
2841
|
}
|
|
1327
2842
|
function upsertEntry(entriesByKey, entry) {
|
|
1328
|
-
const
|
|
1329
|
-
const existing = entriesByKey.get(
|
|
2843
|
+
const key2 = rowIdentityKey(entry.row);
|
|
2844
|
+
const existing = entriesByKey.get(key2);
|
|
1330
2845
|
if (!existing) {
|
|
1331
|
-
entriesByKey.set(
|
|
2846
|
+
entriesByKey.set(key2, entry);
|
|
1332
2847
|
return;
|
|
1333
2848
|
}
|
|
1334
2849
|
if (entry.score > existing.score) {
|
|
1335
|
-
entriesByKey.set(
|
|
2850
|
+
entriesByKey.set(key2, {
|
|
1336
2851
|
...existing,
|
|
1337
2852
|
score: entry.score
|
|
1338
2853
|
});
|
|
@@ -1366,6 +2881,7 @@ function createInMemoryOntologyState() {
|
|
|
1366
2881
|
sourceMaterializations: new Map,
|
|
1367
2882
|
objectOverrides: new Map,
|
|
1368
2883
|
linkOverrides: new Map,
|
|
2884
|
+
linkSlotOverrides: new Map,
|
|
1369
2885
|
outbox: new Map
|
|
1370
2886
|
};
|
|
1371
2887
|
}
|
|
@@ -1387,8 +2903,8 @@ function sourceMaterializationRecord(materialization) {
|
|
|
1387
2903
|
function commitKey(projectId, commitId) {
|
|
1388
2904
|
return JSON.stringify([projectId, commitId]);
|
|
1389
2905
|
}
|
|
1390
|
-
function idempotencyKey(projectId,
|
|
1391
|
-
return JSON.stringify([projectId,
|
|
2906
|
+
function idempotencyKey(projectId, key2) {
|
|
2907
|
+
return JSON.stringify([projectId, key2]);
|
|
1392
2908
|
}
|
|
1393
2909
|
function ontologyCommitOriginSelector(origin) {
|
|
1394
2910
|
if (origin.kind === "action")
|
|
@@ -1422,9 +2938,9 @@ function cloneOntologyState(state) {
|
|
|
1422
2938
|
return structuredClone(state);
|
|
1423
2939
|
}
|
|
1424
2940
|
function restoreOntologyState(target, snapshot) {
|
|
1425
|
-
for (const
|
|
1426
|
-
const targetMap = target[
|
|
1427
|
-
const sourceMap = structuredClone(snapshot[
|
|
2941
|
+
for (const key2 of Object.keys(target)) {
|
|
2942
|
+
const targetMap = target[key2];
|
|
2943
|
+
const sourceMap = structuredClone(snapshot[key2]);
|
|
1428
2944
|
targetMap.clear();
|
|
1429
2945
|
for (const [entryKey, value] of sourceMap)
|
|
1430
2946
|
targetMap.set(entryKey, value);
|
|
@@ -1555,8 +3071,8 @@ class InMemoryTimeseriesStorage {
|
|
|
1555
3071
|
}
|
|
1556
3072
|
restore(snapshot) {
|
|
1557
3073
|
this.pointsByKey.clear();
|
|
1558
|
-
for (const [
|
|
1559
|
-
this.pointsByKey.set(
|
|
3074
|
+
for (const [key2, points] of structuredClone(snapshot.pointsByKey)) {
|
|
3075
|
+
this.pointsByKey.set(key2, points);
|
|
1560
3076
|
}
|
|
1561
3077
|
}
|
|
1562
3078
|
getExactPoint(projectId, series, at) {
|
|
@@ -1580,8 +3096,8 @@ class InMemoryTimeseriesStorage {
|
|
|
1580
3096
|
return latest;
|
|
1581
3097
|
}
|
|
1582
3098
|
applyExactPoint(projectId, point) {
|
|
1583
|
-
const
|
|
1584
|
-
const series = this.pointsByKey.get(
|
|
3099
|
+
const key2 = pointKey(projectId, point.series.object.objectTypeId, point.series.object.primaryId, point.series.propertyId);
|
|
3100
|
+
const series = this.pointsByKey.get(key2) ?? new Map;
|
|
1585
3101
|
series.set(new Date(point.at).getTime(), {
|
|
1586
3102
|
projectId,
|
|
1587
3103
|
objectTypeId: point.series.object.objectTypeId,
|
|
@@ -1592,12 +3108,12 @@ class InMemoryTimeseriesStorage {
|
|
|
1592
3108
|
at: new Date(point.at),
|
|
1593
3109
|
lastCommitId: point.lastCommitId
|
|
1594
3110
|
});
|
|
1595
|
-
this.pointsByKey.set(
|
|
3111
|
+
this.pointsByKey.set(key2, series);
|
|
1596
3112
|
}
|
|
1597
3113
|
async getHistory(params) {
|
|
1598
|
-
const
|
|
3114
|
+
const key2 = pointKey(params.projectId, params.objectTypeId, params.objectId, params.propertyId);
|
|
1599
3115
|
const { from, to } = params;
|
|
1600
|
-
let points = [...this.pointsByKey.get(
|
|
3116
|
+
let points = [...this.pointsByKey.get(key2)?.values() ?? []];
|
|
1601
3117
|
if (from || to) {
|
|
1602
3118
|
points = points.filter((point) => (!from || point.at >= from) && (!to || point.at <= to));
|
|
1603
3119
|
}
|
|
@@ -1671,6 +3187,12 @@ function publicLinkOverride(value) {
|
|
|
1671
3187
|
const { projectId: _, ...stored } = value;
|
|
1672
3188
|
return stored;
|
|
1673
3189
|
}
|
|
3190
|
+
function publicLinkSlotOverride(value) {
|
|
3191
|
+
if (!value)
|
|
3192
|
+
return null;
|
|
3193
|
+
const { projectId: _, ...stored } = value;
|
|
3194
|
+
return stored;
|
|
3195
|
+
}
|
|
1674
3196
|
function uniqueBy(values, keyOf) {
|
|
1675
3197
|
return [...new Map(values.map((value) => [keyOf(value), structuredClone(value)])).values()];
|
|
1676
3198
|
}
|
|
@@ -1751,15 +3273,15 @@ function storedSourceLink(sourceId, materializationId, row) {
|
|
|
1751
3273
|
return storedSource(sourceId, materializationId, row);
|
|
1752
3274
|
}
|
|
1753
3275
|
function addReplacementLink(replacement, ref, diffRequired) {
|
|
1754
|
-
const
|
|
1755
|
-
const existing = replacement.links.get(
|
|
3276
|
+
const key2 = linkRefKey(ref);
|
|
3277
|
+
const existing = replacement.links.get(key2);
|
|
1756
3278
|
if (existing) {
|
|
1757
3279
|
existing.diffRequired ||= diffRequired;
|
|
1758
3280
|
if (diffRequired)
|
|
1759
3281
|
replacement.affectedScopes.add(linkScopeSortKey(ref.source, ref.linkId));
|
|
1760
3282
|
return;
|
|
1761
3283
|
}
|
|
1762
|
-
replacement.links.set(
|
|
3284
|
+
replacement.links.set(key2, {
|
|
1763
3285
|
ref: structuredClone(ref),
|
|
1764
3286
|
sortKey: linkRefSortKey(ref),
|
|
1765
3287
|
diffRequired
|
|
@@ -1921,9 +3443,9 @@ function remainingClassifiedCount(classified, created, updated, deleted) {
|
|
|
1921
3443
|
return classified - created - updated - deleted;
|
|
1922
3444
|
}
|
|
1923
3445
|
function effectiveChangeCountsMatch(actual, expected) {
|
|
1924
|
-
return effectiveChangeCountKeys.every((
|
|
1925
|
-
const count = actual[
|
|
1926
|
-
return Number.isSafeInteger(count) && count >= 0 && count === expected[
|
|
3446
|
+
return effectiveChangeCountKeys.every((key2) => {
|
|
3447
|
+
const count = actual[key2];
|
|
3448
|
+
return Number.isSafeInteger(count) && count >= 0 && count === expected[key2];
|
|
1927
3449
|
});
|
|
1928
3450
|
}
|
|
1929
3451
|
function telemetryCountsCorrelate(session, pointCount, actual) {
|
|
@@ -1946,7 +3468,7 @@ function telemetryCountsCorrelate(session, pointCount, actual) {
|
|
|
1946
3468
|
pointsUnchanged: pointCount - pointsCreated - pointsUpdated,
|
|
1947
3469
|
latestObjectsChanged
|
|
1948
3470
|
};
|
|
1949
|
-
return expected.pointsUnchanged >= 0 && Object.keys(expected).every((
|
|
3471
|
+
return expected.pointsUnchanged >= 0 && Object.keys(expected).every((key2) => Number.isSafeInteger(actual[key2]) && actual[key2] >= 0 && actual[key2] === expected[key2]);
|
|
1950
3472
|
}
|
|
1951
3473
|
function assertSourceActivationCorrelation(activation, session, state) {
|
|
1952
3474
|
const { header } = session;
|
|
@@ -2017,10 +3539,11 @@ function assertFinalizedWork(session, state, objects) {
|
|
|
2017
3539
|
}
|
|
2018
3540
|
}
|
|
2019
3541
|
function assertFinalCardinality(records, projectId, objects) {
|
|
3542
|
+
const effectiveOccupants = records.filter((record) => record.view === "effective");
|
|
2020
3543
|
const scopes = new Map;
|
|
2021
3544
|
let currentScope = null;
|
|
2022
3545
|
let occupiedCount = 0;
|
|
2023
|
-
for (const record of
|
|
3546
|
+
for (const record of effectiveOccupants) {
|
|
2024
3547
|
if (record.scopeSortKey !== currentScope) {
|
|
2025
3548
|
currentScope = record.scopeSortKey;
|
|
2026
3549
|
occupiedCount = 0;
|
|
@@ -2062,7 +3585,7 @@ function assertReplacementFullyStreamed(session, activation) {
|
|
|
2062
3585
|
invalidCorrelation("Link projection replacement state was not fully streamed.");
|
|
2063
3586
|
}
|
|
2064
3587
|
const expectedObjectKeys = activation.projectionKind === "object" ? [...replacement.objects.keys()].sort() : [];
|
|
2065
|
-
const expectedLinkKeys = [...replacement.links.entries()].filter(([, value]) => value.diffRequired).map(([
|
|
3588
|
+
const expectedLinkKeys = [...replacement.links.entries()].filter(([, value]) => value.diffRequired).map(([key2]) => key2).sort();
|
|
2066
3589
|
if (stableJsonStringify(classificationKeys(session, "object")) !== stableJsonStringify(expectedObjectKeys) || stableJsonStringify(classificationKeys(session, "link")) !== stableJsonStringify(expectedLinkKeys) || classificationKeys(session, "point").length > 0) {
|
|
2067
3590
|
invalidCorrelation("Projection replacement classification coverage does not match its streamed state.");
|
|
2068
3591
|
}
|
|
@@ -2082,15 +3605,17 @@ class InMemoryOntologyMaterializationStorage {
|
|
|
2082
3605
|
timeseries;
|
|
2083
3606
|
getTransactionToken;
|
|
2084
3607
|
getMaterializationLifecycle;
|
|
3608
|
+
executionExists;
|
|
2085
3609
|
hooks;
|
|
2086
3610
|
sessions = new WeakMap;
|
|
2087
3611
|
liveSessions = new Set;
|
|
2088
|
-
constructor(state, objects, timeseries, getTransactionToken, getMaterializationLifecycle, hooks = {}) {
|
|
3612
|
+
constructor(state, objects, timeseries, getTransactionToken, getMaterializationLifecycle, executionExists, hooks = {}) {
|
|
2089
3613
|
this.state = state;
|
|
2090
3614
|
this.objects = objects;
|
|
2091
3615
|
this.timeseries = timeseries;
|
|
2092
3616
|
this.getTransactionToken = getTransactionToken;
|
|
2093
3617
|
this.getMaterializationLifecycle = getMaterializationLifecycle;
|
|
3618
|
+
this.executionExists = executionExists;
|
|
2094
3619
|
this.hooks = hooks;
|
|
2095
3620
|
}
|
|
2096
3621
|
async begin(input) {
|
|
@@ -2100,6 +3625,9 @@ class InMemoryOntologyMaterializationStorage {
|
|
|
2100
3625
|
throw new MaterializationValidationError("Materialization sessions require an active storage transaction.");
|
|
2101
3626
|
}
|
|
2102
3627
|
assertMaterializationHeader(input);
|
|
3628
|
+
if (!await this.executionExists(input.commit.projectId, input.commit.executionId)) {
|
|
3629
|
+
throw new MaterializationValidationError(`Ontology commit execution '${input.commit.executionId}' does not exist in project '${input.commit.projectId}'.`);
|
|
3630
|
+
}
|
|
2103
3631
|
this.assertCommitAbsent(input);
|
|
2104
3632
|
for (const expected of input.expected.sources)
|
|
2105
3633
|
this.assertSource(expected, input.commit.projectId);
|
|
@@ -2109,9 +3637,9 @@ class InMemoryOntologyMaterializationStorage {
|
|
|
2109
3637
|
await this.assertLink(expected, input.commit.projectId);
|
|
2110
3638
|
const expectedScopeStates = new Map;
|
|
2111
3639
|
for (const expected of input.expected.linkScopes) {
|
|
2112
|
-
const
|
|
2113
|
-
const current = expectedScopeStates.get(
|
|
2114
|
-
expectedScopeStates.set(
|
|
3640
|
+
const key2 = linkScopeSortKey(expected.source, expected.linkId);
|
|
3641
|
+
const current = expectedScopeStates.get(key2) ?? this.computeLinkScopeState(input.commit.projectId, expected.source, expected.linkId);
|
|
3642
|
+
expectedScopeStates.set(key2, current);
|
|
2115
3643
|
if (current.fingerprint !== expected.fingerprint) {
|
|
2116
3644
|
throw new MaterializationConflictError("effective-state", `Expected link scope changed for ${expected.source.objectTypeId}:${expected.source.primaryId}.${expected.linkId}.`);
|
|
2117
3645
|
}
|
|
@@ -2249,11 +3777,11 @@ class InMemoryOntologyMaterializationStorage {
|
|
|
2249
3777
|
const selected = replacement.orderedObjects.slice(offset, offset + input.pageRows);
|
|
2250
3778
|
const objects = [];
|
|
2251
3779
|
for (const entry of selected) {
|
|
2252
|
-
const
|
|
3780
|
+
const key2 = projectionEntityKey({ kind: "object", ref: entry.ref });
|
|
2253
3781
|
const base = await this.objectState(session, entry.ref);
|
|
2254
3782
|
objects.push({
|
|
2255
3783
|
ref: base.ref,
|
|
2256
|
-
candidateSource: storedSourceObject(input.source.projectionId, replacement.candidate.materializationId, replacement.candidate.rowsByEntity.get(
|
|
3784
|
+
candidateSource: storedSourceObject(input.source.projectionId, replacement.candidate.materializationId, replacement.candidate.rowsByEntity.get(key2)),
|
|
2257
3785
|
override: base.override,
|
|
2258
3786
|
effective: base.effective,
|
|
2259
3787
|
latestTelemetry: base.latestTelemetry
|
|
@@ -2281,13 +3809,14 @@ class InMemoryOntologyMaterializationStorage {
|
|
|
2281
3809
|
const selected = replacement.orderedLinks.slice(offset, offset + input.pageRows);
|
|
2282
3810
|
const links = [];
|
|
2283
3811
|
for (const entry of selected) {
|
|
2284
|
-
const
|
|
3812
|
+
const key2 = projectionEntityKey({ kind: "link", ref: entry.ref });
|
|
2285
3813
|
const base = await this.linkState(session, entry.ref);
|
|
2286
|
-
const ownedByReplacement = replacement.previous?.rowsByEntity.has(
|
|
3814
|
+
const ownedByReplacement = replacement.previous?.rowsByEntity.has(key2) || replacement.candidate.rowsByEntity.has(key2);
|
|
2287
3815
|
links.push({
|
|
2288
3816
|
ref: base.ref,
|
|
2289
|
-
candidateSource: ownedByReplacement ? storedSourceLink(input.source.projectionId, replacement.candidate.materializationId, replacement.candidate.rowsByEntity.get(
|
|
3817
|
+
candidateSource: ownedByReplacement ? storedSourceLink(input.source.projectionId, replacement.candidate.materializationId, replacement.candidate.rowsByEntity.get(key2)) : base.source,
|
|
2290
3818
|
override: base.override,
|
|
3819
|
+
slotOverride: base.slotOverride,
|
|
2291
3820
|
effective: base.effective,
|
|
2292
3821
|
diffRequired: entry.diffRequired
|
|
2293
3822
|
});
|
|
@@ -2389,29 +3918,30 @@ class InMemoryOntologyMaterializationStorage {
|
|
|
2389
3918
|
this.hooks.beforeWrite?.(boundary, session.writeOrdinal++);
|
|
2390
3919
|
apply();
|
|
2391
3920
|
};
|
|
2392
|
-
for (const item of input.chunk.overrides.
|
|
3921
|
+
for (const item of input.chunk.overrides.objects.upserts)
|
|
2393
3922
|
write("override.object.upsert", () => {
|
|
2394
|
-
const
|
|
2395
|
-
assertLastCommit(this.state.objectOverrides.get(
|
|
2396
|
-
this.state.objectOverrides.set(
|
|
3923
|
+
const key2 = projectEntityKey(projectId, objectRefKey(item.ref));
|
|
3924
|
+
assertLastCommit(this.state.objectOverrides.get(key2), item.expectedLastCommitId, "object override");
|
|
3925
|
+
this.state.objectOverrides.set(key2, structuredClone({
|
|
2397
3926
|
projectId,
|
|
2398
3927
|
ref: item.ref,
|
|
2399
3928
|
value: item.value,
|
|
3929
|
+
editedAt: { ...item.editedAt },
|
|
2400
3930
|
lastCommitId: item.lastCommitId,
|
|
2401
3931
|
updatedAt: item.updatedAt
|
|
2402
3932
|
}));
|
|
2403
3933
|
});
|
|
2404
|
-
for (const item of input.chunk.overrides.
|
|
3934
|
+
for (const item of input.chunk.overrides.objects.deletes)
|
|
2405
3935
|
write("override.object.delete", () => {
|
|
2406
|
-
const
|
|
2407
|
-
assertLastCommit(this.state.objectOverrides.get(
|
|
2408
|
-
this.state.objectOverrides.delete(
|
|
3936
|
+
const key2 = projectEntityKey(projectId, objectRefKey(item.ref));
|
|
3937
|
+
assertLastCommit(this.state.objectOverrides.get(key2), item.expectedLastCommitId, "object override");
|
|
3938
|
+
this.state.objectOverrides.delete(key2);
|
|
2409
3939
|
});
|
|
2410
|
-
for (const item of input.chunk.overrides.
|
|
3940
|
+
for (const item of input.chunk.overrides.links.edges.upserts)
|
|
2411
3941
|
write("override.link.upsert", () => {
|
|
2412
|
-
const
|
|
2413
|
-
assertLastCommit(this.state.linkOverrides.get(
|
|
2414
|
-
this.state.linkOverrides.set(
|
|
3942
|
+
const key2 = projectEntityKey(projectId, linkRefKey(item.ref));
|
|
3943
|
+
assertLastCommit(this.state.linkOverrides.get(key2), item.expectedLastCommitId, "link edge override");
|
|
3944
|
+
this.state.linkOverrides.set(key2, structuredClone({
|
|
2415
3945
|
projectId,
|
|
2416
3946
|
ref: item.ref,
|
|
2417
3947
|
value: item.value,
|
|
@@ -2419,11 +3949,29 @@ class InMemoryOntologyMaterializationStorage {
|
|
|
2419
3949
|
updatedAt: item.updatedAt
|
|
2420
3950
|
}));
|
|
2421
3951
|
});
|
|
2422
|
-
for (const item of input.chunk.overrides.
|
|
3952
|
+
for (const item of input.chunk.overrides.links.edges.deletes)
|
|
2423
3953
|
write("override.link.delete", () => {
|
|
2424
|
-
const
|
|
2425
|
-
assertLastCommit(this.state.linkOverrides.get(
|
|
2426
|
-
this.state.linkOverrides.delete(
|
|
3954
|
+
const key2 = projectEntityKey(projectId, linkRefKey(item.ref));
|
|
3955
|
+
assertLastCommit(this.state.linkOverrides.get(key2), item.expectedLastCommitId, "link edge override");
|
|
3956
|
+
this.state.linkOverrides.delete(key2);
|
|
3957
|
+
});
|
|
3958
|
+
for (const item of input.chunk.overrides.links.slots.upserts)
|
|
3959
|
+
write("override.link-slot.upsert", () => {
|
|
3960
|
+
const key2 = projectEntityKey(projectId, linkScopeKey(item.ref.source, item.ref.linkId));
|
|
3961
|
+
assertLastCommit(this.state.linkSlotOverrides.get(key2), item.expectedLastCommitId, "link slot override");
|
|
3962
|
+
this.state.linkSlotOverrides.set(key2, structuredClone({
|
|
3963
|
+
projectId,
|
|
3964
|
+
ref: item.ref,
|
|
3965
|
+
value: item.value,
|
|
3966
|
+
lastCommitId: item.lastCommitId,
|
|
3967
|
+
updatedAt: item.updatedAt
|
|
3968
|
+
}));
|
|
3969
|
+
});
|
|
3970
|
+
for (const item of input.chunk.overrides.links.slots.deletes)
|
|
3971
|
+
write("override.link-slot.delete", () => {
|
|
3972
|
+
const key2 = projectEntityKey(projectId, linkScopeKey(item.ref.source, item.ref.linkId));
|
|
3973
|
+
assertLastCommit(this.state.linkSlotOverrides.get(key2), item.expectedLastCommitId, "link slot override");
|
|
3974
|
+
this.state.linkSlotOverrides.delete(key2);
|
|
2427
3975
|
});
|
|
2428
3976
|
for (const item of input.chunk.effective.linkDeletes)
|
|
2429
3977
|
write("effective.link.delete", () => {
|
|
@@ -2466,20 +4014,20 @@ class InMemoryOntologyMaterializationStorage {
|
|
|
2466
4014
|
assertTimestamp2(item.availableAt, "Outbox availableAt");
|
|
2467
4015
|
assertTimestamp2(item.createdAt, "Outbox createdAt");
|
|
2468
4016
|
assertTimestamp2(envelope.occurredAt, "Outbox event occurredAt");
|
|
2469
|
-
const
|
|
2470
|
-
if (this.state.outbox.has(
|
|
4017
|
+
const key2 = outboxKey(projectId, envelope.id);
|
|
4018
|
+
if (this.state.outbox.has(key2)) {
|
|
2471
4019
|
throw new MaterializationConflictError("effective-state", `Duplicate outbox event '${envelope.id}'.`);
|
|
2472
4020
|
}
|
|
2473
4021
|
if (session.outboxEnvelopes.has(envelope.commitOrdinal))
|
|
2474
4022
|
throw new MaterializationConflictError("effective-state", "Duplicate outbox commit ordinal.");
|
|
2475
|
-
this.state.outbox.set(
|
|
4023
|
+
this.state.outbox.set(key2, {
|
|
2476
4024
|
envelope: structuredClone(envelope),
|
|
2477
4025
|
availableAt: item.availableAt,
|
|
2478
4026
|
attempts: 0,
|
|
2479
4027
|
leaseId: null,
|
|
2480
4028
|
leaseExpiresAt: null,
|
|
2481
4029
|
publishedAt: null,
|
|
2482
|
-
|
|
4030
|
+
lastFailure: null,
|
|
2483
4031
|
createdAt: item.createdAt
|
|
2484
4032
|
});
|
|
2485
4033
|
session.outboxEnvelopes.set(envelope.commitOrdinal, structuredClone(envelope));
|
|
@@ -2610,6 +4158,17 @@ class InMemoryOntologyMaterializationStorage {
|
|
|
2610
4158
|
if (touchesIncident(override.ref))
|
|
2611
4159
|
addReplacementLink(replacement, override.ref, true);
|
|
2612
4160
|
}
|
|
4161
|
+
for (const override of this.state.linkSlotOverrides.values()) {
|
|
4162
|
+
if (override.projectId !== projectId)
|
|
4163
|
+
continue;
|
|
4164
|
+
const ref = {
|
|
4165
|
+
source: override.ref.source,
|
|
4166
|
+
linkId: override.ref.linkId,
|
|
4167
|
+
target: override.value.target
|
|
4168
|
+
};
|
|
4169
|
+
if (touchesIncident(ref))
|
|
4170
|
+
addReplacementLink(replacement, ref, true);
|
|
4171
|
+
}
|
|
2613
4172
|
for (const active of this.state.sourceMaterializations.values()) {
|
|
2614
4173
|
if (active.projectId !== projectId || active.status !== "active")
|
|
2615
4174
|
continue;
|
|
@@ -2625,6 +4184,15 @@ class InMemoryOntologyMaterializationStorage {
|
|
|
2625
4184
|
addReplacementLink(replacement, ref, false);
|
|
2626
4185
|
}
|
|
2627
4186
|
});
|
|
4187
|
+
for (const override of this.state.linkSlotOverrides.values()) {
|
|
4188
|
+
if (override.projectId === projectId && replacement.affectedScopes.has(linkScopeSortKey(override.ref.source, override.ref.linkId))) {
|
|
4189
|
+
addReplacementLink(replacement, {
|
|
4190
|
+
source: override.ref.source,
|
|
4191
|
+
linkId: override.ref.linkId,
|
|
4192
|
+
target: override.value.target
|
|
4193
|
+
}, false);
|
|
4194
|
+
}
|
|
4195
|
+
}
|
|
2628
4196
|
replacement.linksExpanded = true;
|
|
2629
4197
|
replacement.orderedLinks = null;
|
|
2630
4198
|
}
|
|
@@ -2714,24 +4282,25 @@ class InMemoryOntologyMaterializationStorage {
|
|
|
2714
4282
|
ref: structuredClone(ref),
|
|
2715
4283
|
source: this.findActiveLinkSource(projectId, ref),
|
|
2716
4284
|
override: structuredClone(publicLinkOverride(this.state.linkOverrides.get(projectEntityKey(projectId, linkRefKey(ref))))),
|
|
4285
|
+
slotOverride: structuredClone(publicLinkSlotOverride(this.state.linkSlotOverrides.get(projectEntityKey(projectId, linkScopeKey(ref.source, ref.linkId))))),
|
|
2717
4286
|
effective: row ? linkSnapshot(row) : null
|
|
2718
4287
|
};
|
|
2719
4288
|
}
|
|
2720
4289
|
linkScopeState(session, source, linkId) {
|
|
2721
4290
|
session.linkScopeStates ??= new Map;
|
|
2722
|
-
const
|
|
2723
|
-
const existing = session.linkScopeStates.get(
|
|
4291
|
+
const key2 = linkScopeSortKey(source, linkId);
|
|
4292
|
+
const existing = session.linkScopeStates.get(key2);
|
|
2724
4293
|
if (existing)
|
|
2725
4294
|
return structuredClone(existing);
|
|
2726
4295
|
const computed = this.computeLinkScopeState(session.header.commit.projectId, source, linkId);
|
|
2727
|
-
session.linkScopeStates.set(
|
|
4296
|
+
session.linkScopeStates.set(key2, computed);
|
|
2728
4297
|
return structuredClone(computed);
|
|
2729
4298
|
}
|
|
2730
4299
|
computeLinkScopeState(projectId, source, linkId) {
|
|
2731
4300
|
const rows = [];
|
|
2732
4301
|
getInMemoryObjectMaterializerAdapter(this.objects).visitExactScopeLinks(projectId, source.objectTypeId, source.primaryId, linkId, (row) => rows.push(row));
|
|
2733
4302
|
rows.sort((left, right) => linkRefSortKey(linkRef(left)).localeCompare(linkRefSortKey(linkRef(right))));
|
|
2734
|
-
const accumulator = startScopeAccumulator(source, linkId
|
|
4303
|
+
const accumulator = startScopeAccumulator(source, linkId);
|
|
2735
4304
|
for (let offset = 0;offset < rows.length; offset += 1000) {
|
|
2736
4305
|
const page = rows.slice(offset, offset + 1000);
|
|
2737
4306
|
this.hooks.observeBuffer?.("state.link-scope.page", page.length);
|
|
@@ -2739,7 +4308,30 @@ class InMemoryOntologyMaterializationStorage {
|
|
|
2739
4308
|
appendScopeSnapshot(accumulator, linkSnapshot(row));
|
|
2740
4309
|
}
|
|
2741
4310
|
}
|
|
2742
|
-
|
|
4311
|
+
const effective = rows.length === 1 ? linkSnapshot(rows[0]) : null;
|
|
4312
|
+
return {
|
|
4313
|
+
...finishScopeAccumulator(accumulator),
|
|
4314
|
+
sourceAssertion: this.findActiveLinkScopeSource(projectId, source, linkId),
|
|
4315
|
+
override: structuredClone(publicLinkSlotOverride(this.state.linkSlotOverrides.get(projectEntityKey(projectId, linkScopeKey(source, linkId))))),
|
|
4316
|
+
effective
|
|
4317
|
+
};
|
|
4318
|
+
}
|
|
4319
|
+
findActiveLinkScopeSource(projectId, source, linkId) {
|
|
4320
|
+
let found = null;
|
|
4321
|
+
for (const active of this.state.sourceMaterializations.values()) {
|
|
4322
|
+
if (active.projectId !== projectId || active.status !== "active")
|
|
4323
|
+
continue;
|
|
4324
|
+
for (const row of active.rowsByEntity.values()) {
|
|
4325
|
+
if (row.assertion.kind !== "link" || objectRefKey(row.assertion.ref.source) !== objectRefKey(source) || row.assertion.ref.linkId !== linkId) {
|
|
4326
|
+
continue;
|
|
4327
|
+
}
|
|
4328
|
+
if (found) {
|
|
4329
|
+
throw new MaterializationConflictError("source-materialization", `Multiple active source links assert cardinality-one scope '${source.objectTypeId}.${linkId}'.`);
|
|
4330
|
+
}
|
|
4331
|
+
found = storedSource(active.source.projectionId, active.materializationId, row);
|
|
4332
|
+
}
|
|
4333
|
+
}
|
|
4334
|
+
return structuredClone(found);
|
|
2743
4335
|
}
|
|
2744
4336
|
findActiveObjectSource(projectId, ref) {
|
|
2745
4337
|
const found = this.findActiveSource(projectId, projectionEntityKey({ kind: "object", ref }));
|
|
@@ -2780,10 +4372,10 @@ class InMemoryOntologyMaterializationStorage {
|
|
|
2780
4372
|
const consider = (ref) => {
|
|
2781
4373
|
const sortKey = linkRefSortKey(ref);
|
|
2782
4374
|
for (const endpoint of [ref.source, ref.target]) {
|
|
2783
|
-
const
|
|
2784
|
-
const links = mutable.get(
|
|
4375
|
+
const key2 = objectRefKey(endpoint);
|
|
4376
|
+
const links = mutable.get(key2) ?? new Map;
|
|
2785
4377
|
links.set(sortKey, structuredClone(ref));
|
|
2786
|
-
mutable.set(
|
|
4378
|
+
mutable.set(key2, links);
|
|
2787
4379
|
}
|
|
2788
4380
|
};
|
|
2789
4381
|
getInMemoryObjectMaterializerAdapter(this.objects).visitExactLinks(projectId, (row) => consider(linkRef(row)));
|
|
@@ -2791,6 +4383,15 @@ class InMemoryOntologyMaterializationStorage {
|
|
|
2791
4383
|
if (override.projectId === projectId)
|
|
2792
4384
|
consider(override.ref);
|
|
2793
4385
|
}
|
|
4386
|
+
for (const override of this.state.linkSlotOverrides.values()) {
|
|
4387
|
+
if (override.projectId !== projectId)
|
|
4388
|
+
continue;
|
|
4389
|
+
consider({
|
|
4390
|
+
source: override.ref.source,
|
|
4391
|
+
linkId: override.ref.linkId,
|
|
4392
|
+
target: override.value.target
|
|
4393
|
+
});
|
|
4394
|
+
}
|
|
2794
4395
|
for (const active of this.state.sourceMaterializations.values()) {
|
|
2795
4396
|
if (active.projectId !== projectId || active.status !== "active")
|
|
2796
4397
|
continue;
|
|
@@ -2857,8 +4458,8 @@ class InMemoryOntologyOutboxStorage {
|
|
|
2857
4458
|
assertNonblank(input.leaseId, "Ontology outbox lease id");
|
|
2858
4459
|
assertTimestamp2(input.publishedAt, "Ontology outbox publishedAt");
|
|
2859
4460
|
const rows = this.validateLeaseBatch(input.projectId, input.ids, input.leaseId);
|
|
2860
|
-
for (const [
|
|
2861
|
-
this.state.outbox.set(
|
|
4461
|
+
for (const [key2, row] of rows) {
|
|
4462
|
+
this.state.outbox.set(key2, {
|
|
2862
4463
|
...row,
|
|
2863
4464
|
publishedAt: input.publishedAt,
|
|
2864
4465
|
leaseId: null,
|
|
@@ -2874,11 +4475,11 @@ class InMemoryOntologyOutboxStorage {
|
|
|
2874
4475
|
assertNonblank(input.leaseId, "Ontology outbox lease id");
|
|
2875
4476
|
assertTimestamp2(input.availableAt, "Ontology outbox availableAt");
|
|
2876
4477
|
const rows = this.validateLeaseBatch(input.projectId, input.ids, input.leaseId);
|
|
2877
|
-
for (const [
|
|
2878
|
-
this.state.outbox.set(
|
|
4478
|
+
for (const [key2, row] of rows) {
|
|
4479
|
+
this.state.outbox.set(key2, {
|
|
2879
4480
|
...row,
|
|
2880
4481
|
availableAt: input.availableAt,
|
|
2881
|
-
|
|
4482
|
+
lastFailure: input.failure === undefined ? row.lastFailure : structuredClone(input.failure),
|
|
2882
4483
|
leaseId: null,
|
|
2883
4484
|
leaseExpiresAt: null
|
|
2884
4485
|
});
|
|
@@ -2920,12 +4521,12 @@ class InMemoryOntologyOutboxStorage {
|
|
|
2920
4521
|
}
|
|
2921
4522
|
insertBounded(rows, entry, input.limit, ([, left], [, right]) => comparePublishedRows(left, right));
|
|
2922
4523
|
}
|
|
2923
|
-
for (const [
|
|
2924
|
-
this.state.outbox.delete(
|
|
4524
|
+
for (const [key2] of rows)
|
|
4525
|
+
this.state.outbox.delete(key2);
|
|
2925
4526
|
return rows.length;
|
|
2926
4527
|
}
|
|
2927
|
-
requireLease(
|
|
2928
|
-
const row = this.state.outbox.get(
|
|
4528
|
+
requireLease(key2, leaseId) {
|
|
4529
|
+
const row = this.state.outbox.get(key2);
|
|
2929
4530
|
if (!row || row.leaseId !== leaseId || row.leaseExpiresAt === null) {
|
|
2930
4531
|
throw new MaterializationConflictError("outbox-lease", "Ontology outbox lease does not match.");
|
|
2931
4532
|
}
|
|
@@ -2939,8 +4540,8 @@ class InMemoryOntologyOutboxStorage {
|
|
|
2939
4540
|
throw new MaterializationValidationError(`Ontology outbox lease batch repeats event '${id}'.`);
|
|
2940
4541
|
}
|
|
2941
4542
|
seen.add(id);
|
|
2942
|
-
const
|
|
2943
|
-
return [
|
|
4543
|
+
const key2 = outboxKey(projectId, id);
|
|
4544
|
+
return [key2, this.requireLease(key2, leaseId)];
|
|
2944
4545
|
});
|
|
2945
4546
|
}
|
|
2946
4547
|
}
|
|
@@ -2975,8 +4576,8 @@ class InMemoryOntologySourceStorage {
|
|
|
2975
4576
|
return this.runRootOperation(async () => {
|
|
2976
4577
|
assertSourceBeginInput(input);
|
|
2977
4578
|
await this.assertCurrentExecution(input);
|
|
2978
|
-
const
|
|
2979
|
-
const existing = this.state.sourceMaterializations.get(
|
|
4579
|
+
const key2 = sourceMaterializationKey(input.projectId, input.source.projectionId, input.materializationId);
|
|
4580
|
+
const existing = this.state.sourceMaterializations.get(key2);
|
|
2980
4581
|
if (existing) {
|
|
2981
4582
|
if (isExactStagingManifest(sourceMaterializationRecord(existing), input)) {
|
|
2982
4583
|
return sourceMaterializationRecord(existing);
|
|
@@ -3012,7 +4613,7 @@ class InMemoryOntologySourceStorage {
|
|
|
3012
4613
|
rootOrdinals: new Map,
|
|
3013
4614
|
ordinalRoots: new Map
|
|
3014
4615
|
};
|
|
3015
|
-
this.state.sourceMaterializations.set(
|
|
4616
|
+
this.state.sourceMaterializations.set(key2, materialization);
|
|
3016
4617
|
return sourceMaterializationRecord(materialization);
|
|
3017
4618
|
});
|
|
3018
4619
|
}
|
|
@@ -3097,10 +4698,10 @@ class InMemoryOntologySourceStorage {
|
|
|
3097
4698
|
let remaining = input.limit;
|
|
3098
4699
|
let rowsDeleted = 0;
|
|
3099
4700
|
let materializationsDeleted = 0;
|
|
3100
|
-
for (const [
|
|
4701
|
+
for (const [key2, candidate] of candidates) {
|
|
3101
4702
|
if (remaining === 0)
|
|
3102
4703
|
break;
|
|
3103
|
-
const current = this.state.sourceMaterializations.get(
|
|
4704
|
+
const current = this.state.sourceMaterializations.get(key2);
|
|
3104
4705
|
if (current !== candidate)
|
|
3105
4706
|
continue;
|
|
3106
4707
|
current.rootOrdinals.clear();
|
|
@@ -3113,7 +4714,7 @@ class InMemoryOntologySourceStorage {
|
|
|
3113
4714
|
remaining -= 1;
|
|
3114
4715
|
}
|
|
3115
4716
|
if (current.rowsByEntity.size === 0 && remaining > 0) {
|
|
3116
|
-
this.state.sourceMaterializations.delete(
|
|
4717
|
+
this.state.sourceMaterializations.delete(key2);
|
|
3117
4718
|
materializationsDeleted += 1;
|
|
3118
4719
|
remaining -= 1;
|
|
3119
4720
|
}
|
|
@@ -3320,7 +4921,7 @@ class InMemoryOntologyStorage {
|
|
|
3320
4921
|
this.commits = new InMemoryOntologyCommitStorage(this.state, options.runRootOperation);
|
|
3321
4922
|
this.sources = new InMemoryOntologySourceStorage(this.state, options.runRootOperation, options.assertSourceMaterializationExecution);
|
|
3322
4923
|
this.outbox = new InMemoryOntologyOutboxStorage(this.state, options.runRootOperation);
|
|
3323
|
-
this.materializations = new InMemoryOntologyMaterializationStorage(this.state, objects, timeseries, options.getTransactionToken, options.getMaterializationLifecycle, {
|
|
4924
|
+
this.materializations = new InMemoryOntologyMaterializationStorage(this.state, objects, timeseries, options.getTransactionToken, options.getMaterializationLifecycle, options.executionExists, {
|
|
3324
4925
|
beforeRead: (boundary) => this.testHooks.beforeRead?.(boundary),
|
|
3325
4926
|
beforeWrite: (boundary, ordinal) => this.testHooks.beforeWrite?.(boundary, ordinal),
|
|
3326
4927
|
observeBuffer: (boundary, rows) => this.testHooks.observeBuffer?.(boundary, rows),
|
|
@@ -3344,10 +4945,9 @@ class InMemoryOntologyStorage {
|
|
|
3344
4945
|
this.materializations.deactivateTransaction(transactionToken);
|
|
3345
4946
|
}
|
|
3346
4947
|
}
|
|
3347
|
-
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
name = "PipelineRunError";
|
|
4948
|
+
// src/storage/pipeline-runs/idempotency.ts
|
|
4949
|
+
function canRequeuePipelineRunAfterEnqueueFailure(existing, input) {
|
|
4950
|
+
return existing.status === "failed" && existing.error?.code === "queue.enqueue_failed" && existing.error.retryable && existing.executionId === input.executionId && existing.pipelineId === input.pipelineId;
|
|
3351
4951
|
}
|
|
3352
4952
|
// src/storage/run-listing.ts
|
|
3353
4953
|
function storageKey(projectId, id) {
|
|
@@ -3366,16 +4966,17 @@ function matchesRunListDateFilters(record, filters) {
|
|
|
3366
4966
|
if (filters.statuses && !filters.statuses.has(record.status)) {
|
|
3367
4967
|
return false;
|
|
3368
4968
|
}
|
|
3369
|
-
|
|
4969
|
+
const startedAt = effectiveStartedAt(record);
|
|
4970
|
+
if (filters.startedAfter && startedAt < filters.startedAfter) {
|
|
3370
4971
|
return false;
|
|
3371
4972
|
}
|
|
3372
|
-
if (filters.startedBefore &&
|
|
4973
|
+
if (filters.startedBefore && startedAt > filters.startedBefore) {
|
|
3373
4974
|
return false;
|
|
3374
4975
|
}
|
|
3375
4976
|
return true;
|
|
3376
4977
|
}
|
|
3377
4978
|
function compareStartedAt(left, right, order) {
|
|
3378
|
-
const delta = left.
|
|
4979
|
+
const delta = effectiveStartedAt(left).getTime() - effectiveStartedAt(right).getTime();
|
|
3379
4980
|
if (delta !== 0) {
|
|
3380
4981
|
return order === "asc" ? delta : -delta;
|
|
3381
4982
|
}
|
|
@@ -3406,10 +5007,25 @@ function latestStartedAtByOwnerId(records, ownerIds, ownerIdFor) {
|
|
|
3406
5007
|
return record ? [record] : [];
|
|
3407
5008
|
});
|
|
3408
5009
|
}
|
|
5010
|
+
function effectiveStartedAt(record) {
|
|
5011
|
+
const value = record.startedAt ?? record.queuedAt;
|
|
5012
|
+
if (!value) {
|
|
5013
|
+
throw new Error(`[Sixb] Run '${record.id}' has neither startedAt nor queuedAt.`);
|
|
5014
|
+
}
|
|
5015
|
+
return value;
|
|
5016
|
+
}
|
|
5017
|
+
|
|
5018
|
+
// src/storage/pipeline-runs/types.ts
|
|
5019
|
+
var PIPELINE_RUN_FAILURE_CODES = [
|
|
5020
|
+
"internal.unexpected",
|
|
5021
|
+
"runtime.cancelled",
|
|
5022
|
+
"queue.enqueue_failed",
|
|
5023
|
+
"pipeline.step_failed"
|
|
5024
|
+
];
|
|
3409
5025
|
|
|
3410
5026
|
// src/storage/pipeline-runs/in-memory.ts
|
|
3411
5027
|
function normalizeError2(error) {
|
|
3412
|
-
return error ?
|
|
5028
|
+
return error ? parseSixbFailure(error, PIPELINE_RUN_FAILURE_CODES) : undefined;
|
|
3413
5029
|
}
|
|
3414
5030
|
function assertNonNegativeInteger(value, fieldName) {
|
|
3415
5031
|
if (value !== undefined && (!Number.isInteger(value) || value < 0)) {
|
|
@@ -3418,8 +5034,12 @@ function assertNonNegativeInteger(value, fieldName) {
|
|
|
3418
5034
|
}
|
|
3419
5035
|
|
|
3420
5036
|
class InMemoryPipelineRunStorage {
|
|
5037
|
+
executions;
|
|
3421
5038
|
runs = new Map;
|
|
3422
5039
|
steps = new Map;
|
|
5040
|
+
constructor(executions) {
|
|
5041
|
+
this.executions = executions;
|
|
5042
|
+
}
|
|
3423
5043
|
snapshot() {
|
|
3424
5044
|
return {
|
|
3425
5045
|
runs: structuredClone(this.runs),
|
|
@@ -3428,31 +5048,79 @@ class InMemoryPipelineRunStorage {
|
|
|
3428
5048
|
}
|
|
3429
5049
|
restore(snapshot) {
|
|
3430
5050
|
this.runs.clear();
|
|
3431
|
-
for (const [
|
|
3432
|
-
this.runs.set(
|
|
5051
|
+
for (const [key2, record] of structuredClone(snapshot.runs)) {
|
|
5052
|
+
this.runs.set(key2, record);
|
|
3433
5053
|
}
|
|
3434
5054
|
this.steps.clear();
|
|
3435
|
-
for (const [
|
|
3436
|
-
this.steps.set(
|
|
5055
|
+
for (const [key2, record] of structuredClone(snapshot.steps)) {
|
|
5056
|
+
this.steps.set(key2, record);
|
|
3437
5057
|
}
|
|
3438
5058
|
}
|
|
3439
|
-
async
|
|
3440
|
-
const
|
|
3441
|
-
|
|
5059
|
+
async queue(input) {
|
|
5060
|
+
const key2 = storageKey(input.projectId, input.id);
|
|
5061
|
+
const existing = this.runs.get(key2);
|
|
5062
|
+
if (existing && !canRequeuePipelineRunAfterEnqueueFailure(existing, input)) {
|
|
3442
5063
|
throw new PipelineRunError(`[Sixb] Pipeline run '${input.id}' already exists for project '${input.projectId}'.`);
|
|
3443
5064
|
}
|
|
5065
|
+
if ([...this.runs.values()].some((run) => run.projectId === input.projectId && run.id !== input.id && run.executionId === input.executionId)) {
|
|
5066
|
+
throw new PipelineRunError(`[Sixb] Execution '${input.executionId}' already belongs to another Pipeline run.`);
|
|
5067
|
+
}
|
|
5068
|
+
await assertPipelineRunExecution({
|
|
5069
|
+
executions: this.executions,
|
|
5070
|
+
projectId: input.projectId,
|
|
5071
|
+
executionId: input.executionId,
|
|
5072
|
+
runId: input.id,
|
|
5073
|
+
pipelineId: input.pipelineId
|
|
5074
|
+
});
|
|
5075
|
+
const queuedAt = new Date(input.queuedAt ?? new Date);
|
|
5076
|
+
if (existing) {
|
|
5077
|
+
const next = {
|
|
5078
|
+
...existing,
|
|
5079
|
+
status: "queued",
|
|
5080
|
+
queuedAt,
|
|
5081
|
+
startedAt: undefined,
|
|
5082
|
+
finishedAt: undefined,
|
|
5083
|
+
output: undefined,
|
|
5084
|
+
error: undefined
|
|
5085
|
+
};
|
|
5086
|
+
this.runs.set(key2, cloneRecord(next));
|
|
5087
|
+
return cloneRecord(next);
|
|
5088
|
+
}
|
|
3444
5089
|
const record = {
|
|
3445
5090
|
id: input.id,
|
|
3446
5091
|
projectId: input.projectId,
|
|
5092
|
+
executionId: input.executionId,
|
|
3447
5093
|
pipelineId: input.pipelineId,
|
|
3448
|
-
status: "
|
|
3449
|
-
|
|
5094
|
+
status: "queued",
|
|
5095
|
+
queuedAt
|
|
3450
5096
|
};
|
|
3451
|
-
this.runs.set(
|
|
5097
|
+
this.runs.set(key2, cloneRecord(record));
|
|
3452
5098
|
return cloneRecord(record);
|
|
3453
5099
|
}
|
|
5100
|
+
async start(input) {
|
|
5101
|
+
const key2 = storageKey(input.projectId, input.id);
|
|
5102
|
+
const existing = this.runs.get(key2);
|
|
5103
|
+
if (!existing) {
|
|
5104
|
+
throw new PipelineRunError(`[Sixb] Pipeline run '${input.id}' not found for project '${input.projectId}'.`);
|
|
5105
|
+
}
|
|
5106
|
+
if (existing.status !== "queued") {
|
|
5107
|
+
throw new PipelineRunError(`[Sixb] Pipeline run '${input.id}' cannot start from status '${existing.status}'.`);
|
|
5108
|
+
}
|
|
5109
|
+
const next = {
|
|
5110
|
+
...existing,
|
|
5111
|
+
status: "running",
|
|
5112
|
+
startedAt: new Date(input.startedAt ?? new Date),
|
|
5113
|
+
error: undefined
|
|
5114
|
+
};
|
|
5115
|
+
this.runs.set(key2, cloneRecord(next));
|
|
5116
|
+
return cloneRecord(next);
|
|
5117
|
+
}
|
|
3454
5118
|
async finish(input) {
|
|
3455
|
-
const existing = this.
|
|
5119
|
+
const existing = this.requireExistingPipelineRun(input.projectId, input.id);
|
|
5120
|
+
const enqueueFailure = input.status === "failed" && input.error.code === "queue.enqueue_failed";
|
|
5121
|
+
if (enqueueFailure && existing.status !== "queued" || !enqueueFailure && existing.status !== "running") {
|
|
5122
|
+
throw new PipelineRunError(`[Sixb] Pipeline run '${input.id}' cannot finish from status '${existing.status}'.`);
|
|
5123
|
+
}
|
|
3456
5124
|
const base = {
|
|
3457
5125
|
...existing,
|
|
3458
5126
|
status: input.status,
|
|
@@ -3475,8 +5143,8 @@ class InMemoryPipelineRunStorage {
|
|
|
3475
5143
|
if (pipelineRun.pipelineId !== input.pipelineId) {
|
|
3476
5144
|
throw new PipelineRunError(`[Sixb] Pipeline step run '${input.id}' pipeline '${input.pipelineId}' does not match pipeline run '${input.pipelineRunId}' pipeline '${pipelineRun.pipelineId}'.`);
|
|
3477
5145
|
}
|
|
3478
|
-
const
|
|
3479
|
-
if (this.steps.has(
|
|
5146
|
+
const key2 = storageKey(input.projectId, input.id);
|
|
5147
|
+
if (this.steps.has(key2)) {
|
|
3480
5148
|
throw new PipelineRunError(`[Sixb] Pipeline step run '${input.id}' already exists for project '${input.projectId}'.`);
|
|
3481
5149
|
}
|
|
3482
5150
|
const record = {
|
|
@@ -3491,7 +5159,7 @@ class InMemoryPipelineRunStorage {
|
|
|
3491
5159
|
startedAt: new Date(input.startedAt ?? new Date),
|
|
3492
5160
|
inputs: cloneRecord(input.inputs)
|
|
3493
5161
|
};
|
|
3494
|
-
this.steps.set(
|
|
5162
|
+
this.steps.set(key2, cloneRecord(record));
|
|
3495
5163
|
return cloneRecord(record);
|
|
3496
5164
|
}
|
|
3497
5165
|
async finishStep(input) {
|
|
@@ -3600,17 +5268,12 @@ class InMemoryPipelineRunStorage {
|
|
|
3600
5268
|
}
|
|
3601
5269
|
// src/storage/projection-runs/in-memory.ts
|
|
3602
5270
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
3603
|
-
var
|
|
5271
|
+
var runDirectly3 = async (run) => run();
|
|
3604
5272
|
function projectionRunKey(projectId, id) {
|
|
3605
5273
|
return JSON.stringify([projectId, id]);
|
|
3606
5274
|
}
|
|
3607
5275
|
function compareRuns2(a, b, order) {
|
|
3608
|
-
|
|
3609
|
-
if (delta !== 0)
|
|
3610
|
-
return order === "asc" ? delta : -delta;
|
|
3611
|
-
if (a.id === b.id)
|
|
3612
|
-
return 0;
|
|
3613
|
-
return order === "asc" ? a.id.localeCompare(b.id) : b.id.localeCompare(a.id);
|
|
5276
|
+
return compareStartedAt(a, b, order);
|
|
3614
5277
|
}
|
|
3615
5278
|
|
|
3616
5279
|
class InMemoryProjectionRunStorage {
|
|
@@ -3618,10 +5281,12 @@ class InMemoryProjectionRunStorage {
|
|
|
3618
5281
|
executionTokensByRun = new Map;
|
|
3619
5282
|
runRootOperation;
|
|
3620
5283
|
createExecutionToken;
|
|
3621
|
-
constructor(input
|
|
3622
|
-
this.
|
|
5284
|
+
constructor(input) {
|
|
5285
|
+
this.executions = input.executions;
|
|
5286
|
+
this.runRootOperation = input.runRootOperation ?? runDirectly3;
|
|
3623
5287
|
this.createExecutionToken = input.executionToken ?? randomUUID2;
|
|
3624
5288
|
}
|
|
5289
|
+
executions;
|
|
3625
5290
|
snapshot() {
|
|
3626
5291
|
return structuredClone({
|
|
3627
5292
|
rows: this.rows,
|
|
@@ -3631,25 +5296,71 @@ class InMemoryProjectionRunStorage {
|
|
|
3631
5296
|
restore(snapshot) {
|
|
3632
5297
|
this.rows.clear();
|
|
3633
5298
|
this.executionTokensByRun.clear();
|
|
3634
|
-
for (const [
|
|
3635
|
-
this.rows.set(
|
|
3636
|
-
for (const [
|
|
3637
|
-
this.executionTokensByRun.set(
|
|
5299
|
+
for (const [key2, record] of structuredClone(snapshot.rows))
|
|
5300
|
+
this.rows.set(key2, record);
|
|
5301
|
+
for (const [key2, tokens] of structuredClone(snapshot.executionTokensByRun)) {
|
|
5302
|
+
this.executionTokensByRun.set(key2, tokens);
|
|
3638
5303
|
}
|
|
3639
5304
|
}
|
|
5305
|
+
async queue(input) {
|
|
5306
|
+
return this.runRootOperation(async () => {
|
|
5307
|
+
assertProjectionRunQueueInput(input);
|
|
5308
|
+
this.assertDatasetVersionIsImmutable(input);
|
|
5309
|
+
const key2 = projectionRunKey(input.projectId, input.id);
|
|
5310
|
+
const existing = this.rows.get(key2);
|
|
5311
|
+
if (existing && !canRequeueProjectionRunAfterEnqueueFailure(existing, input)) {
|
|
5312
|
+
throw new ProjectionRunError(`[Sixb] Projection run '${input.id}' already exists for project '${input.projectId}'.`);
|
|
5313
|
+
}
|
|
5314
|
+
if ([...this.rows.values()].some((run) => run.projectId === input.projectId && run.id !== input.id && run.executionId === input.executionId)) {
|
|
5315
|
+
throw new ProjectionRunError(`[Sixb] Execution '${input.executionId}' already belongs to another Projection run.`);
|
|
5316
|
+
}
|
|
5317
|
+
await assertProjectionRunDurableExecution({
|
|
5318
|
+
executions: this.executions,
|
|
5319
|
+
projectId: input.projectId,
|
|
5320
|
+
executionId: input.executionId,
|
|
5321
|
+
runId: input.id,
|
|
5322
|
+
projectionId: input.identity.projectionId,
|
|
5323
|
+
datasetId: input.identity.datasetVersion.datasetId,
|
|
5324
|
+
datasetVersionId: input.identity.datasetVersion.versionId
|
|
5325
|
+
});
|
|
5326
|
+
const record = createProjectionRunRecord(input);
|
|
5327
|
+
this.rows.set(key2, structuredClone(record));
|
|
5328
|
+
return publicProjectionRunRecord(record);
|
|
5329
|
+
});
|
|
5330
|
+
}
|
|
3640
5331
|
async startOrReclaim(input) {
|
|
3641
5332
|
return this.runRootOperation(() => {
|
|
3642
5333
|
assertProjectionRunStartInput(input);
|
|
3643
|
-
|
|
3644
|
-
const
|
|
3645
|
-
|
|
3646
|
-
|
|
3647
|
-
const
|
|
3648
|
-
const
|
|
3649
|
-
|
|
5334
|
+
const key2 = projectionRunKey(input.projectId, input.id);
|
|
5335
|
+
const existing = this.rows.get(key2);
|
|
5336
|
+
if (!existing)
|
|
5337
|
+
throw projectionRunNotFound(input.projectId, input.id);
|
|
5338
|
+
const attempt = planProjectionRunReclaim(existing, input).attempt;
|
|
5339
|
+
const executionToken = this.issueExecutionToken(key2, input.id, existing.executionToken);
|
|
5340
|
+
const record = {
|
|
5341
|
+
...existing,
|
|
5342
|
+
status: "running",
|
|
5343
|
+
attempt,
|
|
5344
|
+
executionToken,
|
|
5345
|
+
startedAt: existing.startedAt ?? new Date(input.startedAt ?? new Date),
|
|
5346
|
+
finishedAt: undefined,
|
|
5347
|
+
error: undefined
|
|
5348
|
+
};
|
|
5349
|
+
this.rows.set(key2, structuredClone(record));
|
|
3650
5350
|
return createProjectionRunClaim(record);
|
|
3651
5351
|
});
|
|
3652
5352
|
}
|
|
5353
|
+
async failEnqueue(input) {
|
|
5354
|
+
return this.runRootOperation(() => {
|
|
5355
|
+
const key2 = projectionRunKey(input.projectId, input.id);
|
|
5356
|
+
const existing = this.rows.get(key2);
|
|
5357
|
+
if (!existing)
|
|
5358
|
+
throw projectionRunNotFound(input.projectId, input.id);
|
|
5359
|
+
const next = failProjectionRunEnqueue(existing, input);
|
|
5360
|
+
this.rows.set(key2, structuredClone(next));
|
|
5361
|
+
return publicProjectionRunRecord(next);
|
|
5362
|
+
});
|
|
5363
|
+
}
|
|
3653
5364
|
async lockForMaterialization(input) {
|
|
3654
5365
|
return this.runRootOperation(() => publicProjectionRunRecord(this.requireExecution(input)));
|
|
3655
5366
|
}
|
|
@@ -3733,7 +5444,11 @@ class InMemoryProjectionRunStorage {
|
|
|
3733
5444
|
const limit = input.limit ?? this.rows.size;
|
|
3734
5445
|
const statuses = input.statuses ? new Set(input.statuses) : null;
|
|
3735
5446
|
const objectTypeIds = input.objectTypeIds ? new Set(input.objectTypeIds) : null;
|
|
3736
|
-
const filtered = [...this.rows.values()].filter((record) => record.projectId === input.projectId).filter((record) => input.projectionId ? record.identity.projectionId === input.projectionId : true).filter((record) => input.projectionKind ? record.identity.projectionKind === input.projectionKind : true).filter((record) => input.datasetId ? record.identity.datasetVersion.datasetId === input.datasetId : true).filter((record) => input.datasetVersionId ? record.identity.datasetVersion.versionId === input.datasetVersionId : true).filter((record) => objectTypeIds ? projectionRunObjectTypesVisible(record, (id) => objectTypeIds.has(id)) : true).filter((record) => statuses ? statuses.has(record.status) : true).filter((record) =>
|
|
5447
|
+
const filtered = [...this.rows.values()].filter((record) => record.projectId === input.projectId).filter((record) => input.projectionId ? record.identity.projectionId === input.projectionId : true).filter((record) => input.projectionKind ? record.identity.projectionKind === input.projectionKind : true).filter((record) => input.datasetId ? record.identity.datasetVersion.datasetId === input.datasetId : true).filter((record) => input.datasetVersionId ? record.identity.datasetVersion.versionId === input.datasetVersionId : true).filter((record) => objectTypeIds ? projectionRunObjectTypesVisible(record, (id) => objectTypeIds.has(id)) : true).filter((record) => statuses ? statuses.has(record.status) : true).filter((record) => matchesRunListDateFilters(record, {
|
|
5448
|
+
statuses,
|
|
5449
|
+
startedAfter: input.startedAfter,
|
|
5450
|
+
startedBefore: input.startedBefore
|
|
5451
|
+
})).sort((left, right) => compareRuns2(left, right, order));
|
|
3737
5452
|
const total = filtered.length;
|
|
3738
5453
|
const runs = filtered.slice(offset, offset + limit).map(publicProjectionRunRecord);
|
|
3739
5454
|
return { runs, hasMore: offset + runs.length < total, total };
|
|
@@ -3752,22 +5467,22 @@ class InMemoryProjectionRunStorage {
|
|
|
3752
5467
|
}
|
|
3753
5468
|
}
|
|
3754
5469
|
}
|
|
3755
|
-
issueExecutionToken(
|
|
5470
|
+
issueExecutionToken(key2, runId, currentToken) {
|
|
3756
5471
|
const executionToken = this.createExecutionToken();
|
|
3757
5472
|
assertProjectionRunNonEmpty(executionToken, "executionToken");
|
|
3758
|
-
const usedTokens = this.executionTokensByRun.get(
|
|
5473
|
+
const usedTokens = this.executionTokensByRun.get(key2) ?? new Set;
|
|
3759
5474
|
if (currentToken)
|
|
3760
5475
|
usedTokens.add(currentToken);
|
|
3761
5476
|
if (usedTokens.has(executionToken)) {
|
|
3762
5477
|
throw new ProjectionRunError(`[Sixb] Projection run '${runId}' execution token was already used.`);
|
|
3763
5478
|
}
|
|
3764
5479
|
usedTokens.add(executionToken);
|
|
3765
|
-
this.executionTokensByRun.set(
|
|
5480
|
+
this.executionTokensByRun.set(key2, usedTokens);
|
|
3766
5481
|
return executionToken;
|
|
3767
5482
|
}
|
|
3768
5483
|
requireExecution(input) {
|
|
3769
5484
|
const record = this.requireRunning(input.projectId, input.id);
|
|
3770
|
-
|
|
5485
|
+
assertProjectionRunAttempt(record, input);
|
|
3771
5486
|
return record;
|
|
3772
5487
|
}
|
|
3773
5488
|
requireTelemetryExecution(input) {
|
|
@@ -3827,8 +5542,8 @@ class InMemoryRulesStorage {
|
|
|
3827
5542
|
}
|
|
3828
5543
|
restore(snapshot) {
|
|
3829
5544
|
this.active.clear();
|
|
3830
|
-
for (const [
|
|
3831
|
-
this.active.set(
|
|
5545
|
+
for (const [key2, record] of structuredClone(snapshot)) {
|
|
5546
|
+
this.active.set(key2, record);
|
|
3832
5547
|
}
|
|
3833
5548
|
}
|
|
3834
5549
|
async getActive(params) {
|
|
@@ -3899,10 +5614,18 @@ class InMemoryRulesStorage {
|
|
|
3899
5614
|
}
|
|
3900
5615
|
}
|
|
3901
5616
|
}
|
|
3902
|
-
// src/storage/sync-runs/
|
|
3903
|
-
|
|
3904
|
-
|
|
5617
|
+
// src/storage/sync-runs/idempotency.ts
|
|
5618
|
+
function canRequeueSyncRunAfterEnqueueFailure(existing, input) {
|
|
5619
|
+
return existing.status === "failed" && existing.error?.code === "queue.enqueue_failed" && existing.error.retryable && existing.executionId === input.executionId && existing.syncId === input.syncId && existing.datasetId === input.datasetId && existing.mode === input.mode && existing.expectedLatestVersionId === input.expectedLatestVersionId && existing.commitMessage === input.commitMessage;
|
|
3905
5620
|
}
|
|
5621
|
+
// src/storage/sync-runs/types.ts
|
|
5622
|
+
var SYNC_RUN_FAILURE_CODES = [
|
|
5623
|
+
"internal.unexpected",
|
|
5624
|
+
"runtime.cancelled",
|
|
5625
|
+
"queue.enqueue_failed",
|
|
5626
|
+
"sync.execution_failed"
|
|
5627
|
+
];
|
|
5628
|
+
|
|
3906
5629
|
// src/storage/sync-runs/in-memory.ts
|
|
3907
5630
|
function syncRunKey(projectId, id) {
|
|
3908
5631
|
return `${projectId}:${id}`;
|
|
@@ -3914,45 +5637,99 @@ function normalizeCheckpoint(checkpoint) {
|
|
|
3914
5637
|
return checkpoint !== undefined ? cloneJsonValue(checkpoint) : undefined;
|
|
3915
5638
|
}
|
|
3916
5639
|
function normalizeError3(error) {
|
|
3917
|
-
return error ?
|
|
5640
|
+
return error ? parseSixbFailure(error, SYNC_RUN_FAILURE_CODES) : undefined;
|
|
3918
5641
|
}
|
|
3919
5642
|
|
|
3920
5643
|
class InMemorySyncRunStorage {
|
|
5644
|
+
executions;
|
|
3921
5645
|
rows = new Map;
|
|
5646
|
+
constructor(executions) {
|
|
5647
|
+
this.executions = executions;
|
|
5648
|
+
}
|
|
3922
5649
|
snapshot() {
|
|
3923
5650
|
return structuredClone(this.rows);
|
|
3924
5651
|
}
|
|
3925
5652
|
restore(snapshot) {
|
|
3926
5653
|
this.rows.clear();
|
|
3927
|
-
for (const [
|
|
3928
|
-
this.rows.set(
|
|
5654
|
+
for (const [key2, record] of structuredClone(snapshot)) {
|
|
5655
|
+
this.rows.set(key2, record);
|
|
3929
5656
|
}
|
|
3930
5657
|
}
|
|
3931
|
-
async
|
|
3932
|
-
const
|
|
3933
|
-
|
|
5658
|
+
async queue(input) {
|
|
5659
|
+
const key2 = syncRunKey(input.projectId, input.id);
|
|
5660
|
+
const existing = this.rows.get(key2);
|
|
5661
|
+
if (existing && !canRequeueSyncRunAfterEnqueueFailure(existing, input)) {
|
|
3934
5662
|
throw new SyncRunError(`[Sixb] Sync run '${input.id}' already exists for project '${input.projectId}'.`);
|
|
3935
5663
|
}
|
|
5664
|
+
if ([...this.rows.values()].some((run) => run.projectId === input.projectId && run.id !== input.id && run.executionId === input.executionId)) {
|
|
5665
|
+
throw new SyncRunError(`[Sixb] Execution '${input.executionId}' already belongs to another Sync run.`);
|
|
5666
|
+
}
|
|
5667
|
+
await assertSyncRunExecution({
|
|
5668
|
+
executions: this.executions,
|
|
5669
|
+
projectId: input.projectId,
|
|
5670
|
+
executionId: input.executionId,
|
|
5671
|
+
runId: input.id,
|
|
5672
|
+
syncId: input.syncId
|
|
5673
|
+
});
|
|
5674
|
+
const queuedAt = new Date(input.queuedAt ?? new Date);
|
|
5675
|
+
if (existing) {
|
|
5676
|
+
const next = {
|
|
5677
|
+
...existing,
|
|
5678
|
+
status: "queued",
|
|
5679
|
+
queuedAt,
|
|
5680
|
+
startedAt: undefined,
|
|
5681
|
+
finishedAt: undefined,
|
|
5682
|
+
rowsRead: undefined,
|
|
5683
|
+
output: undefined,
|
|
5684
|
+
error: undefined,
|
|
5685
|
+
checkpoint: undefined
|
|
5686
|
+
};
|
|
5687
|
+
this.rows.set(key2, structuredClone(next));
|
|
5688
|
+
return cloneSyncRunRecord(next);
|
|
5689
|
+
}
|
|
3936
5690
|
const record = {
|
|
3937
5691
|
id: input.id,
|
|
3938
5692
|
projectId: input.projectId,
|
|
5693
|
+
executionId: input.executionId,
|
|
3939
5694
|
syncId: input.syncId,
|
|
3940
5695
|
datasetId: input.datasetId,
|
|
3941
5696
|
mode: input.mode,
|
|
3942
|
-
status: "
|
|
3943
|
-
|
|
5697
|
+
status: "queued",
|
|
5698
|
+
queuedAt,
|
|
3944
5699
|
expectedLatestVersionId: input.expectedLatestVersionId,
|
|
3945
5700
|
commitMessage: input.commitMessage
|
|
3946
5701
|
};
|
|
3947
|
-
this.rows.set(
|
|
5702
|
+
this.rows.set(key2, structuredClone(record));
|
|
3948
5703
|
return cloneSyncRunRecord(record);
|
|
3949
5704
|
}
|
|
5705
|
+
async start(input) {
|
|
5706
|
+
const key2 = syncRunKey(input.projectId, input.id);
|
|
5707
|
+
const existing = this.rows.get(key2);
|
|
5708
|
+
if (!existing) {
|
|
5709
|
+
throw new SyncRunError(`[Sixb] Sync run '${input.id}' not found for project '${input.projectId}'.`);
|
|
5710
|
+
}
|
|
5711
|
+
if (existing.status !== "queued") {
|
|
5712
|
+
throw new SyncRunError(`[Sixb] Sync run '${input.id}' cannot start from status '${existing.status}'.`);
|
|
5713
|
+
}
|
|
5714
|
+
const next = {
|
|
5715
|
+
...existing,
|
|
5716
|
+
status: "running",
|
|
5717
|
+
startedAt: new Date(input.startedAt ?? new Date),
|
|
5718
|
+
error: undefined
|
|
5719
|
+
};
|
|
5720
|
+
this.rows.set(key2, structuredClone(next));
|
|
5721
|
+
return cloneSyncRunRecord(next);
|
|
5722
|
+
}
|
|
3950
5723
|
async finish(input) {
|
|
3951
|
-
const
|
|
3952
|
-
const existing = this.rows.get(
|
|
5724
|
+
const key2 = syncRunKey(input.projectId, input.id);
|
|
5725
|
+
const existing = this.rows.get(key2);
|
|
3953
5726
|
if (!existing) {
|
|
3954
5727
|
throw new SyncRunError(`[Sixb] Sync run '${input.id}' not found for project '${input.projectId}'.`);
|
|
3955
5728
|
}
|
|
5729
|
+
const enqueueFailure = input.status === "failed" && input.error.code === "queue.enqueue_failed";
|
|
5730
|
+
if (enqueueFailure && existing.status !== "queued" || !enqueueFailure && existing.status !== "running") {
|
|
5731
|
+
throw new SyncRunError(`[Sixb] Sync run '${input.id}' cannot finish from status '${existing.status}'.`);
|
|
5732
|
+
}
|
|
3956
5733
|
if (input.status === "succeeded") {
|
|
3957
5734
|
if (input.output && input.output.datasetId !== existing.datasetId) {
|
|
3958
5735
|
throw new SyncRunError(`[Sixb] Sync run '${input.id}' output dataset '${input.output.datasetId}' does not match '${existing.datasetId}'.`);
|
|
@@ -3979,7 +5756,7 @@ class InMemorySyncRunStorage {
|
|
|
3979
5756
|
error: normalizeError3(input.error),
|
|
3980
5757
|
checkpoint: undefined
|
|
3981
5758
|
};
|
|
3982
|
-
this.rows.set(
|
|
5759
|
+
this.rows.set(key2, structuredClone(next));
|
|
3983
5760
|
return cloneSyncRunRecord(next);
|
|
3984
5761
|
}
|
|
3985
5762
|
async getById(params) {
|
|
@@ -4054,133 +5831,85 @@ function throwNestedStorageTransaction() {
|
|
|
4054
5831
|
code: "nested_transaction"
|
|
4055
5832
|
});
|
|
4056
5833
|
}
|
|
4057
|
-
|
|
4058
|
-
|
|
4059
|
-
|
|
4060
|
-
|
|
5834
|
+
// src/storage/webhook-runs/types.ts
|
|
5835
|
+
var WEBHOOK_RUN_FAILURE_CODES = [
|
|
5836
|
+
"internal.unexpected",
|
|
5837
|
+
"webhook.delivery_failed",
|
|
5838
|
+
"webhook.delivery_rejected"
|
|
5839
|
+
];
|
|
5840
|
+
function canRetryWebhookRun(run) {
|
|
5841
|
+
return run.status === "failed" && run.error?.retryable === true;
|
|
4061
5842
|
}
|
|
4062
5843
|
|
|
4063
|
-
class InMemoryWebhookDeliveryStorage {
|
|
4064
|
-
deliveries = new Map;
|
|
4065
|
-
snapshot() {
|
|
4066
|
-
return structuredClone(this.deliveries);
|
|
4067
|
-
}
|
|
4068
|
-
restore(snapshot) {
|
|
4069
|
-
this.deliveries.clear();
|
|
4070
|
-
for (const [key, record] of structuredClone(snapshot)) {
|
|
4071
|
-
this.deliveries.set(key, record);
|
|
4072
|
-
}
|
|
4073
|
-
}
|
|
4074
|
-
async claim(input) {
|
|
4075
|
-
const key = serializeKey(input);
|
|
4076
|
-
const existing = this.deliveries.get(key);
|
|
4077
|
-
if (existing?.status === "completed") {
|
|
4078
|
-
return {
|
|
4079
|
-
...cloneDeliveryRecord(existing),
|
|
4080
|
-
claimResult: "duplicate"
|
|
4081
|
-
};
|
|
4082
|
-
}
|
|
4083
|
-
if (existing?.status === "in_progress") {
|
|
4084
|
-
return {
|
|
4085
|
-
...cloneDeliveryRecord(existing),
|
|
4086
|
-
claimResult: "in_progress"
|
|
4087
|
-
};
|
|
4088
|
-
}
|
|
4089
|
-
const next = {
|
|
4090
|
-
projectId: input.projectId,
|
|
4091
|
-
connectorId: input.connectorId,
|
|
4092
|
-
webhookId: input.webhookId,
|
|
4093
|
-
idempotencyKey: input.idempotencyKey,
|
|
4094
|
-
status: "in_progress",
|
|
4095
|
-
receivedAt: input.receivedAt
|
|
4096
|
-
};
|
|
4097
|
-
this.deliveries.set(key, structuredClone(next));
|
|
4098
|
-
return {
|
|
4099
|
-
...cloneDeliveryRecord(next),
|
|
4100
|
-
claimResult: "claimed"
|
|
4101
|
-
};
|
|
4102
|
-
}
|
|
4103
|
-
async complete(input) {
|
|
4104
|
-
const key = serializeKey(input);
|
|
4105
|
-
const next = {
|
|
4106
|
-
projectId: input.projectId,
|
|
4107
|
-
connectorId: input.connectorId,
|
|
4108
|
-
webhookId: input.webhookId,
|
|
4109
|
-
idempotencyKey: input.idempotencyKey,
|
|
4110
|
-
...this.deliveries.get(key),
|
|
4111
|
-
status: "completed",
|
|
4112
|
-
completedAt: input.completedAt,
|
|
4113
|
-
failedAt: undefined,
|
|
4114
|
-
error: undefined
|
|
4115
|
-
};
|
|
4116
|
-
this.deliveries.set(key, structuredClone(next));
|
|
4117
|
-
return cloneDeliveryRecord(next);
|
|
4118
|
-
}
|
|
4119
|
-
async fail(input) {
|
|
4120
|
-
const key = serializeKey(input);
|
|
4121
|
-
const next = {
|
|
4122
|
-
projectId: input.projectId,
|
|
4123
|
-
connectorId: input.connectorId,
|
|
4124
|
-
webhookId: input.webhookId,
|
|
4125
|
-
idempotencyKey: input.idempotencyKey,
|
|
4126
|
-
...this.deliveries.get(key),
|
|
4127
|
-
status: "failed",
|
|
4128
|
-
failedAt: input.failedAt,
|
|
4129
|
-
error: input.error,
|
|
4130
|
-
completedAt: undefined
|
|
4131
|
-
};
|
|
4132
|
-
this.deliveries.set(key, structuredClone(next));
|
|
4133
|
-
return cloneDeliveryRecord(next);
|
|
4134
|
-
}
|
|
4135
|
-
}
|
|
4136
|
-
function serializeKey(key) {
|
|
4137
|
-
return JSON.stringify([key.projectId, key.connectorId, key.webhookId, key.idempotencyKey]);
|
|
4138
|
-
}
|
|
4139
|
-
// src/storage/webhook-runs/errors.ts
|
|
4140
|
-
class WebhookRunError extends Error {
|
|
4141
|
-
name = "WebhookRunError";
|
|
4142
|
-
}
|
|
4143
5844
|
// src/storage/webhook-runs/in-memory.ts
|
|
4144
5845
|
class InMemoryWebhookRunStorage {
|
|
5846
|
+
executions;
|
|
4145
5847
|
runs = new Map;
|
|
5848
|
+
constructor(executions) {
|
|
5849
|
+
this.executions = executions;
|
|
5850
|
+
}
|
|
4146
5851
|
snapshot() {
|
|
4147
5852
|
return structuredClone(this.runs);
|
|
4148
5853
|
}
|
|
4149
5854
|
restore(snapshot) {
|
|
4150
5855
|
this.runs.clear();
|
|
4151
|
-
for (const [
|
|
4152
|
-
this.runs.set(
|
|
5856
|
+
for (const [key2, record] of structuredClone(snapshot)) {
|
|
5857
|
+
this.runs.set(key2, record);
|
|
4153
5858
|
}
|
|
4154
5859
|
}
|
|
4155
5860
|
async start(input) {
|
|
4156
|
-
|
|
4157
|
-
|
|
4158
|
-
|
|
5861
|
+
await assertWebhookRunExecution({
|
|
5862
|
+
executions: this.executions,
|
|
5863
|
+
projectId: input.projectId,
|
|
5864
|
+
executionId: input.executionId,
|
|
5865
|
+
runId: input.id,
|
|
5866
|
+
route: input.route
|
|
5867
|
+
});
|
|
5868
|
+
const key2 = storageKey(input.projectId, input.id);
|
|
5869
|
+
if (this.runs.has(key2) || this.findByDelivery(input)) {
|
|
5870
|
+
throw new WebhookRunError(`[Sixb] Webhook run '${input.id}' or delivery key already exists for project '${input.projectId}'.`, "duplicate_run");
|
|
4159
5871
|
}
|
|
4160
5872
|
const record = {
|
|
4161
5873
|
id: input.id,
|
|
4162
5874
|
projectId: input.projectId,
|
|
5875
|
+
executionId: input.executionId,
|
|
4163
5876
|
connectorId: input.connectorId,
|
|
4164
5877
|
webhookId: input.webhookId,
|
|
4165
5878
|
status: "running",
|
|
4166
5879
|
method: input.method,
|
|
4167
5880
|
route: input.route,
|
|
4168
|
-
startedAt: new Date(input.startedAt ?? new Date)
|
|
5881
|
+
startedAt: new Date(input.startedAt ?? new Date),
|
|
5882
|
+
requestBodyBytes: input.requestBodyBytes,
|
|
5883
|
+
requestBodySha256: input.requestBodySha256,
|
|
5884
|
+
idempotencyKey: input.idempotencyKey
|
|
4169
5885
|
};
|
|
4170
|
-
this.runs.set(
|
|
5886
|
+
this.runs.set(key2, cloneRecord(record));
|
|
4171
5887
|
return cloneRecord(record);
|
|
4172
5888
|
}
|
|
5889
|
+
async restart(input) {
|
|
5890
|
+
const existing = this.requireWebhookRun(input.projectId, input.id);
|
|
5891
|
+
if (!canRetryWebhookRun(existing)) {
|
|
5892
|
+
throw new WebhookRunError(`[Sixb] Webhook run '${input.id}' cannot restart from status '${existing.status}'.`, "invalid_transition");
|
|
5893
|
+
}
|
|
5894
|
+
const next = {
|
|
5895
|
+
...existing,
|
|
5896
|
+
status: "running",
|
|
5897
|
+
startedAt: new Date(input.startedAt ?? new Date),
|
|
5898
|
+
finishedAt: undefined,
|
|
5899
|
+
responseStatus: undefined,
|
|
5900
|
+
error: undefined
|
|
5901
|
+
};
|
|
5902
|
+
this.runs.set(storageKey(input.projectId, input.id), cloneRecord(next));
|
|
5903
|
+
return cloneRecord(next);
|
|
5904
|
+
}
|
|
4173
5905
|
async finish(input) {
|
|
4174
5906
|
const existing = this.requireRunningWebhookRun(input.projectId, input.id);
|
|
4175
5907
|
const next = {
|
|
4176
5908
|
...existing,
|
|
4177
5909
|
status: input.status,
|
|
4178
5910
|
finishedAt: new Date(input.finishedAt ?? new Date),
|
|
4179
|
-
requestBodyBytes: input.requestBodyBytes,
|
|
4180
5911
|
responseStatus: input.responseStatus,
|
|
4181
|
-
|
|
4182
|
-
deliveryClaimResult: input.deliveryClaimResult,
|
|
4183
|
-
error: input.status === "succeeded" ? undefined : input.error
|
|
5912
|
+
error: input.status === "failed" ? parseSixbFailure(input.error, WEBHOOK_RUN_FAILURE_CODES) : undefined
|
|
4184
5913
|
};
|
|
4185
5914
|
this.runs.set(storageKey(input.projectId, input.id), cloneRecord(next));
|
|
4186
5915
|
return cloneRecord(next);
|
|
@@ -4189,6 +5918,10 @@ class InMemoryWebhookRunStorage {
|
|
|
4189
5918
|
const record = this.runs.get(storageKey(params.projectId, params.id));
|
|
4190
5919
|
return record ? cloneRecord(record) : null;
|
|
4191
5920
|
}
|
|
5921
|
+
async getByDelivery(input) {
|
|
5922
|
+
const record = this.findByDelivery(input);
|
|
5923
|
+
return record ? cloneRecord(record) : null;
|
|
5924
|
+
}
|
|
4192
5925
|
async list(input) {
|
|
4193
5926
|
if (hasEmptyStatuses(input)) {
|
|
4194
5927
|
return {
|
|
@@ -4211,16 +5944,25 @@ class InMemoryWebhookRunStorage {
|
|
|
4211
5944
|
total
|
|
4212
5945
|
};
|
|
4213
5946
|
}
|
|
4214
|
-
|
|
5947
|
+
requireWebhookRun(projectId, id) {
|
|
4215
5948
|
const record = this.runs.get(storageKey(projectId, id));
|
|
4216
5949
|
if (!record) {
|
|
4217
|
-
throw new WebhookRunError(`[Sixb] Webhook run '${id}' not found for project '${projectId}'
|
|
5950
|
+
throw new WebhookRunError(`[Sixb] Webhook run '${id}' not found for project '${projectId}'.`, "not_found");
|
|
4218
5951
|
}
|
|
5952
|
+
return record;
|
|
5953
|
+
}
|
|
5954
|
+
requireRunningWebhookRun(projectId, id) {
|
|
5955
|
+
const record = this.requireWebhookRun(projectId, id);
|
|
4219
5956
|
if (record.status !== "running") {
|
|
4220
|
-
throw new WebhookRunError(`[Sixb] Webhook run '${id}' for project '${projectId}' is already terminal
|
|
5957
|
+
throw new WebhookRunError(`[Sixb] Webhook run '${id}' for project '${projectId}' is already terminal.`, "invalid_transition");
|
|
4221
5958
|
}
|
|
4222
5959
|
return record;
|
|
4223
5960
|
}
|
|
5961
|
+
findByDelivery(input) {
|
|
5962
|
+
if (input.idempotencyKey === undefined)
|
|
5963
|
+
return;
|
|
5964
|
+
return [...this.runs.values()].find((run) => run.projectId === input.projectId && run.connectorId === input.connectorId && run.webhookId === input.webhookId && run.idempotencyKey === input.idempotencyKey);
|
|
5965
|
+
}
|
|
4224
5966
|
}
|
|
4225
5967
|
// src/storage/workflow-interventions/errors.ts
|
|
4226
5968
|
class WorkflowInterventionError extends Error {
|
|
@@ -4240,14 +5982,14 @@ class InMemoryWorkflowInterventionStorage {
|
|
|
4240
5982
|
}
|
|
4241
5983
|
restore(snapshot) {
|
|
4242
5984
|
this.interventions.clear();
|
|
4243
|
-
for (const [
|
|
4244
|
-
this.interventions.set(
|
|
5985
|
+
for (const [key2, record] of structuredClone(snapshot)) {
|
|
5986
|
+
this.interventions.set(key2, record);
|
|
4245
5987
|
}
|
|
4246
5988
|
}
|
|
4247
5989
|
async create(input) {
|
|
4248
5990
|
assertNonNegativeInteger2(input.nodeIndex, "nodeIndex");
|
|
4249
|
-
const
|
|
4250
|
-
if (this.interventions.has(
|
|
5991
|
+
const key2 = storageKey(input.projectId, input.id);
|
|
5992
|
+
if (this.interventions.has(key2)) {
|
|
4251
5993
|
throw new WorkflowInterventionError(`[Sixb] Workflow intervention '${input.id}' already exists for project '${input.projectId}'.`);
|
|
4252
5994
|
}
|
|
4253
5995
|
const record = {
|
|
@@ -4266,7 +6008,7 @@ class InMemoryWorkflowInterventionStorage {
|
|
|
4266
6008
|
requestedAt: new Date(input.requestedAt ?? new Date),
|
|
4267
6009
|
expiresAt: input.expiresAt ? new Date(input.expiresAt) : undefined
|
|
4268
6010
|
};
|
|
4269
|
-
this.interventions.set(
|
|
6011
|
+
this.interventions.set(key2, cloneRecord(record));
|
|
4270
6012
|
return cloneRecord(record);
|
|
4271
6013
|
}
|
|
4272
6014
|
async submit(input) {
|
|
@@ -4346,11 +6088,20 @@ function compareRequestedAt(left, right, order) {
|
|
|
4346
6088
|
}
|
|
4347
6089
|
return order === "asc" ? left.id.localeCompare(right.id) : right.id.localeCompare(left.id);
|
|
4348
6090
|
}
|
|
4349
|
-
// src/storage/workflow-runs/
|
|
4350
|
-
|
|
4351
|
-
|
|
4352
|
-
|
|
6091
|
+
// src/storage/workflow-runs/types.ts
|
|
6092
|
+
var WORKFLOW_RUN_FAILURE_CODES = [
|
|
6093
|
+
"internal.unexpected",
|
|
6094
|
+
"runtime.cancelled",
|
|
6095
|
+
"workflow.node_failed"
|
|
6096
|
+
];
|
|
6097
|
+
|
|
4353
6098
|
// src/storage/workflow-runs/in-memory.ts
|
|
6099
|
+
function normalizeFailure2(failure) {
|
|
6100
|
+
return failure ? parseSixbFailure(failure, WORKFLOW_RUN_FAILURE_CODES) : undefined;
|
|
6101
|
+
}
|
|
6102
|
+
function normalizeAgentFailure(failure) {
|
|
6103
|
+
return failure ? parseSixbFailure(failure, AGENT_RUN_FAILURE_CODES) : undefined;
|
|
6104
|
+
}
|
|
4354
6105
|
function assertNonNegativeInteger3(value, fieldName) {
|
|
4355
6106
|
if (!Number.isInteger(value) || value < 0) {
|
|
4356
6107
|
throw new WorkflowRunError(`[Sixb] Workflow run ${fieldName} must be a non-negative integer.`);
|
|
@@ -4358,18 +6109,21 @@ function assertNonNegativeInteger3(value, fieldName) {
|
|
|
4358
6109
|
}
|
|
4359
6110
|
|
|
4360
6111
|
class InMemoryWorkflowRunStorage {
|
|
6112
|
+
executions;
|
|
4361
6113
|
nodes;
|
|
4362
6114
|
agentNodes;
|
|
4363
6115
|
runs = new Map;
|
|
4364
|
-
constructor() {
|
|
6116
|
+
constructor(executions) {
|
|
6117
|
+
this.executions = executions;
|
|
4365
6118
|
this.nodes = new InMemoryWorkflowNodeRunStorage({
|
|
4366
6119
|
requireRunningWorkflowRun: (projectId, id) => this.requireRunningWorkflowRun(projectId, id),
|
|
4367
6120
|
requireActiveWorkflowRun: (projectId, id) => this.requireActiveWorkflowRun(projectId, id),
|
|
4368
6121
|
assertExecutionOwnership: (projectId, id, token) => this.assertExecutionOwnership(projectId, id, token)
|
|
4369
6122
|
});
|
|
4370
6123
|
this.agentNodes = new InMemoryWorkflowAgentNodeRunStorage({
|
|
4371
|
-
requireAgentNodeRun: (projectId, id) => this.nodes.requireAgentNodeRun(projectId, id)
|
|
4372
|
-
|
|
6124
|
+
requireAgentNodeRun: (projectId, id) => this.nodes.requireAgentNodeRun(projectId, id),
|
|
6125
|
+
requireWorkflowRun: (projectId, id) => this.requireExistingWorkflowRun(projectId, id)
|
|
6126
|
+
}, this.executions);
|
|
4373
6127
|
}
|
|
4374
6128
|
snapshot() {
|
|
4375
6129
|
return {
|
|
@@ -4380,71 +6134,60 @@ class InMemoryWorkflowRunStorage {
|
|
|
4380
6134
|
}
|
|
4381
6135
|
restore(snapshot) {
|
|
4382
6136
|
this.runs.clear();
|
|
4383
|
-
for (const [
|
|
4384
|
-
this.runs.set(
|
|
6137
|
+
for (const [key2, record] of structuredClone(snapshot.runs)) {
|
|
6138
|
+
this.runs.set(key2, record);
|
|
4385
6139
|
}
|
|
4386
6140
|
this.nodes.restore(snapshot.nodes);
|
|
4387
6141
|
this.agentNodes.restore(snapshot.agentNodes);
|
|
4388
6142
|
}
|
|
4389
6143
|
async queue(input) {
|
|
4390
|
-
const
|
|
4391
|
-
if (this.runs.has(
|
|
6144
|
+
const key2 = storageKey(input.projectId, input.id);
|
|
6145
|
+
if (this.runs.has(key2)) {
|
|
4392
6146
|
throw new WorkflowRunError(`[Sixb] Workflow run '${input.id}' already exists for project '${input.projectId}'.`);
|
|
4393
6147
|
}
|
|
6148
|
+
if ([...this.runs.values()].some((run) => run.projectId === input.projectId && run.executionId === input.executionId)) {
|
|
6149
|
+
throw new WorkflowRunError(`[Sixb] Execution '${input.executionId}' already belongs to another workflow run.`);
|
|
6150
|
+
}
|
|
6151
|
+
await assertWorkflowRunExecution({
|
|
6152
|
+
executions: this.executions,
|
|
6153
|
+
projectId: input.projectId,
|
|
6154
|
+
executionId: input.executionId,
|
|
6155
|
+
runId: input.id,
|
|
6156
|
+
workflowId: input.workflowId
|
|
6157
|
+
});
|
|
4394
6158
|
const queuedAt = new Date(input.queuedAt ?? new Date);
|
|
4395
6159
|
const record = {
|
|
4396
6160
|
id: input.id,
|
|
4397
6161
|
projectId: input.projectId,
|
|
6162
|
+
executionId: input.executionId,
|
|
4398
6163
|
workflowId: input.workflowId,
|
|
4399
6164
|
status: "queued",
|
|
4400
6165
|
input: cloneRecord(input.input),
|
|
4401
6166
|
queuedAt,
|
|
4402
6167
|
startedAt: queuedAt,
|
|
4403
6168
|
attempt: 0,
|
|
4404
|
-
|
|
4405
|
-
...input.source ? { source: cloneRecord(input.source) } : {}
|
|
6169
|
+
requesterGroupIds: normalizeRequesterGroupIds(input.requesterGroupIds)
|
|
4406
6170
|
};
|
|
4407
|
-
this.runs.set(
|
|
6171
|
+
this.runs.set(key2, cloneRecord(record));
|
|
4408
6172
|
return cloneRecord(record);
|
|
4409
6173
|
}
|
|
4410
6174
|
async start(input) {
|
|
4411
|
-
const
|
|
4412
|
-
const existing = this.runs.get(
|
|
4413
|
-
if (existing) {
|
|
4414
|
-
|
|
4415
|
-
throw new WorkflowRunError(`[Sixb] Workflow run '${input.id}' already exists for project '${input.projectId}'.`);
|
|
4416
|
-
}
|
|
4417
|
-
if (existing.workflowId !== input.workflowId) {
|
|
4418
|
-
throw new WorkflowRunError(`[Sixb] Workflow run '${input.id}' workflow '${input.workflowId}' does not match existing workflow '${existing.workflowId}'.`);
|
|
4419
|
-
}
|
|
4420
|
-
const next = {
|
|
4421
|
-
...existing,
|
|
4422
|
-
status: "running",
|
|
4423
|
-
input: cloneRecord(input.input),
|
|
4424
|
-
startedAt: new Date(input.startedAt ?? new Date),
|
|
4425
|
-
finishedAt: undefined,
|
|
4426
|
-
error: undefined,
|
|
4427
|
-
source: existing.source ?? (input.source === undefined ? undefined : cloneRecord(input.source)),
|
|
4428
|
-
attempt: existing.attempt + 1,
|
|
4429
|
-
execution: input.execution ? cloneRecord(input.execution) : undefined
|
|
4430
|
-
};
|
|
4431
|
-
this.runs.set(key, cloneRecord(next));
|
|
4432
|
-
return cloneRecord(next);
|
|
6175
|
+
const key2 = storageKey(input.projectId, input.id);
|
|
6176
|
+
const existing = this.runs.get(key2);
|
|
6177
|
+
if (!existing || existing.status !== "queued") {
|
|
6178
|
+
throw new WorkflowRunError(existing ? `[Sixb] Workflow run '${input.id}' cannot start from status '${existing.status}'.` : `[Sixb] Workflow run '${input.id}' not found for project '${input.projectId}'.`);
|
|
4433
6179
|
}
|
|
4434
|
-
const
|
|
4435
|
-
|
|
4436
|
-
projectId: input.projectId,
|
|
4437
|
-
workflowId: input.workflowId,
|
|
6180
|
+
const next = {
|
|
6181
|
+
...existing,
|
|
4438
6182
|
status: "running",
|
|
4439
|
-
input: cloneRecord(input.input),
|
|
4440
6183
|
startedAt: new Date(input.startedAt ?? new Date),
|
|
4441
|
-
|
|
4442
|
-
|
|
4443
|
-
|
|
4444
|
-
|
|
6184
|
+
finishedAt: undefined,
|
|
6185
|
+
error: undefined,
|
|
6186
|
+
attempt: existing.attempt + 1,
|
|
6187
|
+
execution: input.execution ? cloneRecord(input.execution) : undefined
|
|
4445
6188
|
};
|
|
4446
|
-
this.runs.set(
|
|
4447
|
-
return cloneRecord(
|
|
6189
|
+
this.runs.set(key2, cloneRecord(next));
|
|
6190
|
+
return cloneRecord(next);
|
|
4448
6191
|
}
|
|
4449
6192
|
async finish(input) {
|
|
4450
6193
|
const existing = this.requireFinishableWorkflowRun(input);
|
|
@@ -4462,7 +6205,7 @@ class InMemoryWorkflowRunStorage {
|
|
|
4462
6205
|
} : {
|
|
4463
6206
|
...base,
|
|
4464
6207
|
output: undefined,
|
|
4465
|
-
error: input.error
|
|
6208
|
+
error: normalizeFailure2(input.error)
|
|
4466
6209
|
};
|
|
4467
6210
|
this.runs.set(storageKey(input.projectId, input.id), cloneRecord(next));
|
|
4468
6211
|
return cloneRecord(next);
|
|
@@ -4611,8 +6354,8 @@ class InMemoryWorkflowNodeRunStorage {
|
|
|
4611
6354
|
}
|
|
4612
6355
|
restore(snapshot) {
|
|
4613
6356
|
this.nodes.clear();
|
|
4614
|
-
for (const [
|
|
4615
|
-
this.nodes.set(
|
|
6357
|
+
for (const [key2, record] of structuredClone(snapshot)) {
|
|
6358
|
+
this.nodes.set(key2, record);
|
|
4616
6359
|
}
|
|
4617
6360
|
}
|
|
4618
6361
|
async start(input) {
|
|
@@ -4622,8 +6365,8 @@ class InMemoryWorkflowNodeRunStorage {
|
|
|
4622
6365
|
if (workflowRun.workflowId !== input.workflowId) {
|
|
4623
6366
|
throw new WorkflowRunError(`[Sixb] Workflow node run '${input.id}' workflow '${input.workflowId}' does not match workflow run '${input.workflowRunId}' workflow '${workflowRun.workflowId}'.`);
|
|
4624
6367
|
}
|
|
4625
|
-
const
|
|
4626
|
-
if (this.nodes.has(
|
|
6368
|
+
const key2 = storageKey(input.projectId, input.id);
|
|
6369
|
+
if (this.nodes.has(key2)) {
|
|
4627
6370
|
throw new WorkflowRunError(`[Sixb] Workflow node run '${input.id}' already exists for project '${input.projectId}'.`);
|
|
4628
6371
|
}
|
|
4629
6372
|
const record = {
|
|
@@ -4639,7 +6382,7 @@ class InMemoryWorkflowNodeRunStorage {
|
|
|
4639
6382
|
input: cloneRecord(input.input),
|
|
4640
6383
|
startedAt: new Date(input.startedAt ?? new Date)
|
|
4641
6384
|
};
|
|
4642
|
-
this.nodes.set(
|
|
6385
|
+
this.nodes.set(key2, cloneRecord(record));
|
|
4643
6386
|
return cloneRecord(record);
|
|
4644
6387
|
}
|
|
4645
6388
|
async finish(input) {
|
|
@@ -4657,7 +6400,7 @@ class InMemoryWorkflowNodeRunStorage {
|
|
|
4657
6400
|
} : {
|
|
4658
6401
|
...base,
|
|
4659
6402
|
output: undefined,
|
|
4660
|
-
error: input.error
|
|
6403
|
+
error: normalizeFailure2(input.error)
|
|
4661
6404
|
};
|
|
4662
6405
|
this.nodes.set(storageKey(input.projectId, input.id), cloneRecord(next));
|
|
4663
6406
|
return cloneRecord(next);
|
|
@@ -4736,37 +6479,52 @@ class InMemoryWorkflowNodeRunStorage {
|
|
|
4736
6479
|
|
|
4737
6480
|
class InMemoryWorkflowAgentNodeRunStorage {
|
|
4738
6481
|
nodes;
|
|
6482
|
+
executions;
|
|
4739
6483
|
runs = new Map;
|
|
4740
|
-
constructor(nodes) {
|
|
6484
|
+
constructor(nodes, executions) {
|
|
4741
6485
|
this.nodes = nodes;
|
|
6486
|
+
this.executions = executions;
|
|
4742
6487
|
}
|
|
4743
6488
|
snapshot() {
|
|
4744
6489
|
return structuredClone(this.runs);
|
|
4745
6490
|
}
|
|
4746
6491
|
restore(snapshot) {
|
|
4747
6492
|
this.runs.clear();
|
|
4748
|
-
for (const [
|
|
4749
|
-
this.runs.set(
|
|
6493
|
+
for (const [key2, record] of structuredClone(snapshot))
|
|
6494
|
+
this.runs.set(key2, record);
|
|
4750
6495
|
}
|
|
4751
6496
|
async create(input) {
|
|
4752
6497
|
const node = this.nodes.requireAgentNodeRun(input.projectId, input.nodeRunId);
|
|
6498
|
+
const workflowRun = this.nodes.requireWorkflowRun(input.projectId, node.workflowRunId);
|
|
6499
|
+
await assertWorkflowAgentNodeRunExecution({
|
|
6500
|
+
executions: this.executions,
|
|
6501
|
+
projectId: input.projectId,
|
|
6502
|
+
executionId: input.executionId,
|
|
6503
|
+
nodeRunId: input.nodeRunId,
|
|
6504
|
+
agentId: input.agentId,
|
|
6505
|
+
workflowExecutionId: workflowRun.executionId
|
|
6506
|
+
});
|
|
4753
6507
|
if (node.status !== "running") {
|
|
4754
6508
|
throw new WorkflowRunError(`[Sixb] Agent workflow node run '${input.nodeRunId}' must be running when queued.`);
|
|
4755
6509
|
}
|
|
4756
|
-
const
|
|
4757
|
-
if (this.runs.has(
|
|
6510
|
+
const key2 = storageKey(input.projectId, input.nodeRunId);
|
|
6511
|
+
if (this.runs.has(key2)) {
|
|
4758
6512
|
throw new WorkflowRunError(`[Sixb] Agent execution already exists for workflow node run '${input.nodeRunId}'.`);
|
|
4759
6513
|
}
|
|
6514
|
+
if ([...this.runs.values()].some((run) => run.projectId === input.projectId && run.executionId === input.executionId)) {
|
|
6515
|
+
throw new WorkflowRunError(`[Sixb] Execution '${input.executionId}' already belongs to another Workflow Agent-node run.`);
|
|
6516
|
+
}
|
|
4760
6517
|
const record = {
|
|
4761
6518
|
projectId: input.projectId,
|
|
4762
6519
|
nodeRunId: input.nodeRunId,
|
|
6520
|
+
executionId: input.executionId,
|
|
4763
6521
|
agentId: input.agentId,
|
|
4764
6522
|
status: "queued",
|
|
4765
6523
|
prompt: input.prompt,
|
|
4766
6524
|
attempt: 0,
|
|
4767
6525
|
createdAt: new Date(input.createdAt ?? new Date)
|
|
4768
6526
|
};
|
|
4769
|
-
this.runs.set(
|
|
6527
|
+
this.runs.set(key2, cloneRecord(record));
|
|
4770
6528
|
return cloneRecord(record);
|
|
4771
6529
|
}
|
|
4772
6530
|
async start(input) {
|
|
@@ -4774,7 +6532,6 @@ class InMemoryWorkflowAgentNodeRunStorage {
|
|
|
4774
6532
|
const next = {
|
|
4775
6533
|
...run,
|
|
4776
6534
|
status: "running",
|
|
4777
|
-
...input.executionPrincipal ? { executionPrincipal: cloneRecord(input.executionPrincipal) } : {},
|
|
4778
6535
|
...input.modelId ? { modelId: input.modelId } : {},
|
|
4779
6536
|
attempt: 1,
|
|
4780
6537
|
execution: cloneRecord(input.execution),
|
|
@@ -4803,10 +6560,9 @@ class InMemoryWorkflowAgentNodeRunStorage {
|
|
|
4803
6560
|
status: input.status,
|
|
4804
6561
|
...input.modelId === undefined ? {} : { modelId: input.modelId },
|
|
4805
6562
|
...input.finishReason === undefined ? {} : { finishReason: input.finishReason },
|
|
4806
|
-
...input.usage === undefined ? {} : { usage: cloneRecord(input.usage) },
|
|
4807
6563
|
...input.trace === undefined ? {} : { trace: cloneRecord(input.trace) },
|
|
4808
6564
|
...input.diagnostics === undefined ? {} : { diagnostics: cloneRecord(input.diagnostics) },
|
|
4809
|
-
...input.status === "succeeded" || input.error === undefined ? {} : { error: input.error },
|
|
6565
|
+
...input.status === "succeeded" || input.error === undefined ? {} : { error: normalizeAgentFailure(input.error) },
|
|
4810
6566
|
execution: undefined,
|
|
4811
6567
|
completedAt: new Date(input.completedAt ?? new Date)
|
|
4812
6568
|
});
|
|
@@ -4820,7 +6576,7 @@ class InMemoryWorkflowAgentNodeRunStorage {
|
|
|
4820
6576
|
...run,
|
|
4821
6577
|
status: "cancelled",
|
|
4822
6578
|
execution: undefined,
|
|
4823
|
-
error: input.error,
|
|
6579
|
+
error: normalizeAgentFailure(input.error),
|
|
4824
6580
|
completedAt: new Date(input.completedAt ?? new Date)
|
|
4825
6581
|
});
|
|
4826
6582
|
}
|
|
@@ -4878,55 +6634,109 @@ class InMemoryStorage {
|
|
|
4878
6634
|
timeseriesStorage = new InMemoryTimeseriesStorage;
|
|
4879
6635
|
ontologyStorage;
|
|
4880
6636
|
authStorage = new InMemoryAuthStorage;
|
|
4881
|
-
|
|
4882
|
-
|
|
4883
|
-
|
|
4884
|
-
|
|
4885
|
-
|
|
4886
|
-
|
|
6637
|
+
executionStorage = new InMemoryExecutionStorage(this.authStorage);
|
|
6638
|
+
agentStorage = new InMemoryAgentStorage(this.executionStorage);
|
|
6639
|
+
aiUsageStorage = new InMemoryAiUsageStorage(this.executionStorage);
|
|
6640
|
+
aiCostStorage = new InMemoryAiCostStorage(this.aiUsageStorage, {
|
|
6641
|
+
resolve: (input) => this.resolveAiAccountingAttribution(input)
|
|
6642
|
+
});
|
|
6643
|
+
actionRunStorage = new InMemoryActionRunStorage(this.executionStorage);
|
|
6644
|
+
syncRunStorage = new InMemorySyncRunStorage(this.executionStorage);
|
|
6645
|
+
pipelineRunStorage = new InMemoryPipelineRunStorage(this.executionStorage);
|
|
6646
|
+
projectionRunStorage = new InMemoryProjectionRunStorage({
|
|
6647
|
+
executions: this.executionStorage
|
|
6648
|
+
});
|
|
6649
|
+
workflowRunStorage = new InMemoryWorkflowRunStorage(this.executionStorage);
|
|
4887
6650
|
workflowInterventionStorage = new InMemoryWorkflowInterventionStorage;
|
|
4888
|
-
|
|
4889
|
-
webhookRunStorage = new InMemoryWebhookRunStorage;
|
|
6651
|
+
webhookRunStorage = new InMemoryWebhookRunStorage(this.executionStorage);
|
|
4890
6652
|
rulesStorage = new InMemoryRulesStorage;
|
|
4891
6653
|
fileUploadSessionStorage = new InMemoryFileUploadSessions;
|
|
6654
|
+
connectorConnectionStorage;
|
|
4892
6655
|
auth;
|
|
6656
|
+
executions;
|
|
4893
6657
|
agents;
|
|
6658
|
+
aiUsage;
|
|
6659
|
+
aiCosts;
|
|
4894
6660
|
actionRuns;
|
|
4895
6661
|
syncRuns;
|
|
4896
6662
|
pipelineRuns;
|
|
4897
6663
|
projectionRuns;
|
|
4898
6664
|
workflowRuns;
|
|
4899
6665
|
workflowInterventions;
|
|
4900
|
-
webhookDeliveries;
|
|
4901
6666
|
webhookRuns;
|
|
4902
6667
|
rules;
|
|
4903
6668
|
fileUploadSessions;
|
|
4904
|
-
|
|
6669
|
+
connectorConnections;
|
|
6670
|
+
constructor(options = {}) {
|
|
6671
|
+
this.connectorConnectionStorage = new InMemoryConnectorConnectionStorage(options.connectorConnections);
|
|
4905
6672
|
const scope = createStorageOperationScope((run) => this.withStorageOperation(run), () => this.assertRootOperationAvailable());
|
|
4906
6673
|
this.objects = createOperationScopedFacade(this.objectStorage, scope);
|
|
4907
6674
|
this.timeseries = createOperationScopedFacade(this.timeseriesStorage, scope);
|
|
4908
6675
|
this.auth = createAuthOperationScope(this.authStorage, scope);
|
|
6676
|
+
this.executions = createOperationScopedFacade(this.executionStorage, scope);
|
|
4909
6677
|
this.agents = createAgentOperationScope(this.agentStorage, scope);
|
|
6678
|
+
this.aiUsage = createOperationScopedFacade(this.aiUsageStorage, scope);
|
|
6679
|
+
this.aiCosts = createOperationScopedFacade(this.aiCostStorage, scope);
|
|
4910
6680
|
this.actionRuns = createOperationScopedFacade(this.actionRunStorage, scope);
|
|
4911
6681
|
this.syncRuns = createOperationScopedFacade(this.syncRunStorage, scope);
|
|
4912
6682
|
this.pipelineRuns = createOperationScopedFacade(this.pipelineRunStorage, scope);
|
|
4913
6683
|
this.projectionRuns = createOperationScopedFacade(this.projectionRunStorage, scope);
|
|
4914
6684
|
this.workflowRuns = createWorkflowRunOperationScope(this.workflowRunStorage, scope);
|
|
4915
6685
|
this.workflowInterventions = createOperationScopedFacade(this.workflowInterventionStorage, scope);
|
|
4916
|
-
this.webhookDeliveries = createOperationScopedFacade(this.webhookDeliveryStorage, scope);
|
|
4917
6686
|
this.webhookRuns = createOperationScopedFacade(this.webhookRunStorage, scope);
|
|
4918
6687
|
this.rules = createOperationScopedFacade(this.rulesStorage, scope);
|
|
4919
6688
|
this.fileUploadSessions = createOperationScopedFacade(this.fileUploadSessionStorage, scope);
|
|
6689
|
+
this.connectorConnections = createOperationScopedFacade(this.connectorConnectionStorage, scope);
|
|
4920
6690
|
this.ontologyStorage = new InMemoryOntologyStorage(this.objectStorage, this.timeseriesStorage, {
|
|
4921
6691
|
runRootOperation: async (run) => run(),
|
|
4922
6692
|
getTransactionToken: () => this.getActiveTransactionToken(),
|
|
4923
6693
|
getMaterializationLifecycle: () => this.getActiveMaterializationLifecycle(),
|
|
4924
|
-
assertSourceMaterializationExecution: (input) => this.projectionRunStorage.assertSourceMaterializationExecutionUnlocked(input)
|
|
6694
|
+
assertSourceMaterializationExecution: (input) => this.projectionRunStorage.assertSourceMaterializationExecutionUnlocked(input),
|
|
6695
|
+
executionExists: async (projectId, executionId) => await this.executionStorage.getById({ projectId, id: executionId }) !== null
|
|
4925
6696
|
});
|
|
4926
6697
|
this.ontology = createOntologyOperationScope(this.ontologyStorage, scope);
|
|
4927
6698
|
this.ontologyStorage.registerTestingAlias(this.ontology);
|
|
4928
6699
|
registerInMemoryStorageTestingAdapter(this, { snapshot: () => this.snapshot() });
|
|
4929
6700
|
}
|
|
6701
|
+
async resolveAiAccountingAttribution(input) {
|
|
6702
|
+
const execution = await this.executionStorage.getById({
|
|
6703
|
+
projectId: input.projectId,
|
|
6704
|
+
id: input.executionId
|
|
6705
|
+
});
|
|
6706
|
+
if (!execution || execution.executor.type !== "agent")
|
|
6707
|
+
return;
|
|
6708
|
+
const directRun = await this.agentStorage.runs.getById({
|
|
6709
|
+
projectId: input.projectId,
|
|
6710
|
+
id: execution.executor.runId
|
|
6711
|
+
});
|
|
6712
|
+
if (directRun) {
|
|
6713
|
+
return {
|
|
6714
|
+
kind: "agent",
|
|
6715
|
+
agentId: directRun.agentId,
|
|
6716
|
+
agentRunId: directRun.id,
|
|
6717
|
+
threadId: directRun.threadId
|
|
6718
|
+
};
|
|
6719
|
+
}
|
|
6720
|
+
const agentRun = await this.workflowRunStorage.agentNodes.getByNodeRunId({
|
|
6721
|
+
projectId: input.projectId,
|
|
6722
|
+
nodeRunId: execution.executor.runId
|
|
6723
|
+
});
|
|
6724
|
+
if (!agentRun)
|
|
6725
|
+
return;
|
|
6726
|
+
const node = await this.workflowRunStorage.nodes.getById({
|
|
6727
|
+
projectId: input.projectId,
|
|
6728
|
+
id: agentRun.nodeRunId
|
|
6729
|
+
});
|
|
6730
|
+
if (!node)
|
|
6731
|
+
return;
|
|
6732
|
+
return {
|
|
6733
|
+
kind: "workflowAgent",
|
|
6734
|
+
agentId: agentRun.agentId,
|
|
6735
|
+
nodeRunId: agentRun.nodeRunId,
|
|
6736
|
+
workflowId: node.workflowId,
|
|
6737
|
+
workflowRunId: node.workflowRunId
|
|
6738
|
+
};
|
|
6739
|
+
}
|
|
4930
6740
|
transactionScope = new AsyncLocalStorage;
|
|
4931
6741
|
activeTransactionTokens = new WeakSet;
|
|
4932
6742
|
materializationLifecycles = new WeakMap;
|
|
@@ -5004,17 +6814,20 @@ class InMemoryStorage {
|
|
|
5004
6814
|
timeseries: this.timeseriesStorage,
|
|
5005
6815
|
ontology: this.ontologyStorage,
|
|
5006
6816
|
auth: this.authStorage,
|
|
6817
|
+
executions: this.executionStorage,
|
|
5007
6818
|
agents: this.agentStorage,
|
|
6819
|
+
aiUsage: this.aiUsageStorage,
|
|
6820
|
+
aiCosts: this.aiCostStorage,
|
|
5008
6821
|
actionRuns: this.actionRunStorage,
|
|
5009
6822
|
syncRuns: this.syncRunStorage,
|
|
5010
6823
|
pipelineRuns: this.pipelineRunStorage,
|
|
5011
6824
|
projectionRuns: this.projectionRunStorage,
|
|
5012
6825
|
workflowRuns: this.workflowRunStorage,
|
|
5013
6826
|
workflowInterventions: this.workflowInterventionStorage,
|
|
5014
|
-
webhookDeliveries: this.webhookDeliveryStorage,
|
|
5015
6827
|
webhookRuns: this.webhookRunStorage,
|
|
5016
6828
|
rules: this.rulesStorage,
|
|
5017
6829
|
fileUploadSessions: this.fileUploadSessionStorage,
|
|
6830
|
+
connectorConnections: this.connectorConnectionStorage,
|
|
5018
6831
|
ping: async () => {
|
|
5019
6832
|
return;
|
|
5020
6833
|
},
|
|
@@ -5029,17 +6842,20 @@ class InMemoryStorage {
|
|
|
5029
6842
|
timeseries: this.timeseriesStorage.snapshot(),
|
|
5030
6843
|
ontology: this.ontologyStorage.snapshot(),
|
|
5031
6844
|
auth: this.authStorage.snapshot(),
|
|
6845
|
+
executions: this.executionStorage.snapshot(),
|
|
5032
6846
|
agents: this.agentStorage.snapshot(),
|
|
6847
|
+
aiUsage: this.aiUsageStorage.snapshot(),
|
|
6848
|
+
aiCosts: this.aiCostStorage.snapshot(),
|
|
5033
6849
|
actionRuns: this.actionRunStorage.snapshot(),
|
|
5034
6850
|
syncRuns: this.syncRunStorage.snapshot(),
|
|
5035
6851
|
pipelineRuns: this.pipelineRunStorage.snapshot(),
|
|
5036
6852
|
projectionRuns: this.projectionRunStorage.snapshot(),
|
|
5037
6853
|
workflowRuns: this.workflowRunStorage.snapshot(),
|
|
5038
6854
|
workflowInterventions: this.workflowInterventionStorage.snapshot(),
|
|
5039
|
-
webhookDeliveries: this.webhookDeliveryStorage.snapshot(),
|
|
5040
6855
|
webhookRuns: this.webhookRunStorage.snapshot(),
|
|
5041
6856
|
rules: this.rulesStorage.snapshot(),
|
|
5042
|
-
fileUploadSessions: this.fileUploadSessionStorage.snapshot()
|
|
6857
|
+
fileUploadSessions: this.fileUploadSessionStorage.snapshot(),
|
|
6858
|
+
connectorConnections: this.connectorConnectionStorage.snapshot()
|
|
5043
6859
|
};
|
|
5044
6860
|
}
|
|
5045
6861
|
restore(snapshot) {
|
|
@@ -5047,17 +6863,20 @@ class InMemoryStorage {
|
|
|
5047
6863
|
this.timeseriesStorage.restore(snapshot.timeseries);
|
|
5048
6864
|
this.ontologyStorage.restore(snapshot.ontology);
|
|
5049
6865
|
this.authStorage.restore(snapshot.auth);
|
|
6866
|
+
this.executionStorage.restore(snapshot.executions);
|
|
5050
6867
|
this.agentStorage.restore(snapshot.agents);
|
|
6868
|
+
this.aiUsageStorage.restore(snapshot.aiUsage);
|
|
6869
|
+
this.aiCostStorage.restore(snapshot.aiCosts);
|
|
5051
6870
|
this.actionRunStorage.restore(snapshot.actionRuns);
|
|
5052
6871
|
this.syncRunStorage.restore(snapshot.syncRuns);
|
|
5053
6872
|
this.pipelineRunStorage.restore(snapshot.pipelineRuns);
|
|
5054
6873
|
this.projectionRunStorage.restore(snapshot.projectionRuns);
|
|
5055
6874
|
this.workflowRunStorage.restore(snapshot.workflowRuns);
|
|
5056
6875
|
this.workflowInterventionStorage.restore(snapshot.workflowInterventions);
|
|
5057
|
-
this.webhookDeliveryStorage.restore(snapshot.webhookDeliveries);
|
|
5058
6876
|
this.webhookRunStorage.restore(snapshot.webhookRuns);
|
|
5059
6877
|
this.rulesStorage.restore(snapshot.rules);
|
|
5060
6878
|
this.fileUploadSessionStorage.restore(snapshot.fileUploadSessions);
|
|
6879
|
+
this.connectorConnectionStorage.restore(snapshot.connectorConnections);
|
|
5061
6880
|
}
|
|
5062
6881
|
}
|
|
5063
6882
|
// src/storage/migrations/migrate-storage.ts
|
|
@@ -5269,6 +7088,6 @@ function assertAppliedPrefix(migrations, rows) {
|
|
|
5269
7088
|
}
|
|
5270
7089
|
return [...rows].sort((a, b) => a.version - b.version);
|
|
5271
7090
|
}
|
|
5272
|
-
export {
|
|
7091
|
+
export { actionSubjectsEqual, actionRunParamsEqual, actionRunPhaseRecordsEqual, finishActionRunPhase, canRequeueActionRunAfterEnqueueFailure, isTerminalActionRun, InMemoryActionRunStorage, AGENT_MESSAGE_CONTENT_VERSION, InMemoryAgentStorage, AiCostStorageError, InMemoryAiCostStorage, InMemoryConnectorConnectionStorage, ObjectNotFoundError, ObjectStorageError, StorageTransactionError, isStorageSerializationFailure, FileUploadSessionError, DEFAULT_FILE_UPLOAD_SESSION_TTL_MS, DEFAULT_FILE_UPLOAD_TERMINAL_SESSION_TTL_MS, createUploadExpiresAt, createFileUploadId, InMemoryFileUploadSessions, canRequeuePipelineRunAfterEnqueueFailure, PIPELINE_RUN_FAILURE_CODES, InMemoryPipelineRunStorage, InMemoryProjectionRunStorage, InMemoryRulesStorage, canRequeueSyncRunAfterEnqueueFailure, SYNC_RUN_FAILURE_CODES, InMemorySyncRunStorage, createTransactionStorageProxy, assertTransactionActive, throwNestedStorageTransaction, WEBHOOK_RUN_FAILURE_CODES, canRetryWebhookRun, InMemoryWebhookRunStorage, WorkflowInterventionError, InMemoryWorkflowInterventionStorage, WORKFLOW_RUN_FAILURE_CODES, InMemoryWorkflowRunStorage, InMemoryWorkflowNodeRunStorage, InMemoryWorkflowAgentNodeRunStorage, InMemoryStorage, isMigrationCapableStorage, migrateStorage, checkStorageSchema, step, defineMigrations, runMigrationSet, describeMigrationHistory };
|
|
5273
7092
|
|
|
5274
|
-
//# debugId=
|
|
7093
|
+
//# debugId=D421DE165E32FF5B64756E2164756E21
|