@sixb/core 0.1.6 → 0.1.8
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/dist/actions/delegated-admission.d.ts +24 -0
- package/dist/actions/delegated-admission.d.ts.map +1 -0
- package/dist/actions/descriptor.d.ts +29 -0
- package/dist/actions/descriptor.d.ts.map +1 -0
- package/dist/actions/execution.d.ts +5 -5
- package/dist/actions/execution.d.ts.map +1 -1
- package/dist/actions/index.js +50 -40
- package/dist/actions/index.js.map +1 -1
- package/dist/actions/request.d.ts.map +1 -1
- package/dist/actions/run-authorization.d.ts +20 -0
- package/dist/actions/run-authorization.d.ts.map +1 -0
- package/dist/actions/run-dispatch.d.ts +3 -1
- package/dist/actions/run-dispatch.d.ts.map +1 -1
- package/dist/actions/worker.js +5 -5
- package/dist/actions/worker.js.map +1 -1
- package/dist/agents/adapters.d.ts +6 -166
- package/dist/agents/adapters.d.ts.map +1 -1
- package/dist/agents/authority.d.ts +22 -6
- package/dist/agents/authority.d.ts.map +1 -1
- package/dist/agents/builders.d.ts +3 -11
- package/dist/agents/builders.d.ts.map +1 -1
- package/dist/agents/context-resolution.d.ts.map +1 -1
- package/dist/agents/context.js +2 -2
- package/dist/agents/dispatch.d.ts +9 -1
- package/dist/agents/dispatch.d.ts.map +1 -1
- package/dist/agents/errors.d.ts +1 -10
- package/dist/agents/errors.d.ts.map +1 -1
- package/dist/agents/execution.d.ts +9 -10
- package/dist/agents/execution.d.ts.map +1 -1
- package/dist/agents/identity.d.ts +3 -0
- package/dist/agents/identity.d.ts.map +1 -0
- package/dist/agents/ids.d.ts +4 -0
- package/dist/agents/ids.d.ts.map +1 -1
- package/dist/agents/index.d.ts +15 -11
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js +90 -78
- package/dist/agents/index.js.map +1 -1
- package/dist/agents/message.d.ts +19 -13
- package/dist/agents/message.d.ts.map +1 -1
- package/dist/agents/model-loop.d.ts +58 -0
- package/dist/agents/model-loop.d.ts.map +1 -0
- package/dist/agents/reference.d.ts +4 -0
- package/dist/agents/reference.d.ts.map +1 -0
- package/dist/agents/request.d.ts +10 -8
- package/dist/agents/request.d.ts.map +1 -1
- package/dist/agents/retired-config.d.ts +4 -0
- package/dist/agents/retired-config.d.ts.map +1 -0
- package/dist/agents/streams.d.ts +13 -8
- package/dist/agents/streams.d.ts.map +1 -1
- package/dist/agents/streams.js +7 -5
- package/dist/agents/streams.js.map +1 -1
- package/dist/agents/tool-catalog.d.ts +9 -0
- package/dist/agents/tool-catalog.d.ts.map +1 -0
- package/dist/agents/tool-definition.d.ts +1 -1
- package/dist/agents/tool-definition.d.ts.map +1 -1
- package/dist/agents/types.d.ts +31 -68
- package/dist/agents/types.d.ts.map +1 -1
- package/dist/agents/validation.d.ts +3 -13
- package/dist/agents/validation.d.ts.map +1 -1
- package/dist/ai-usage/execution.d.ts +53 -0
- package/dist/ai-usage/execution.d.ts.map +1 -0
- package/dist/ai-usage/index.d.ts +3 -0
- package/dist/ai-usage/index.d.ts.map +1 -0
- package/dist/auth/index.js +12 -9
- package/dist/auth/index.js.map +1 -1
- package/dist/authorization/decision.d.ts +14 -3
- package/dist/authorization/decision.d.ts.map +1 -1
- package/dist/authorization/grant-kinds.d.ts +25 -8
- 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 +12 -7
- package/dist/authorization/index.js.map +1 -1
- package/dist/authorization/resolve.d.ts +3 -3
- package/dist/authorization/resolve.d.ts.map +1 -1
- package/dist/authorization/types.d.ts +7 -5
- package/dist/authorization/types.d.ts.map +1 -1
- package/dist/blob-storage/browser.js +2 -2
- package/dist/blob-storage/index.js +3 -3
- package/dist/bootstrap/discovery.d.ts +6 -6
- package/dist/bootstrap/discovery.d.ts.map +1 -1
- package/dist/bootstrap/index.js +62 -51
- package/dist/bootstrap/index.js.map +1 -1
- package/dist/bootstrap/ontology-type-manifest.d.ts.map +1 -1
- package/dist/broker/index.js +2 -2
- package/dist/{chunk-zqysyfjt.js → chunk-08m3b6w8.js} +1 -1
- package/dist/chunk-19jp6g9d.js +131 -0
- package/dist/chunk-19jp6g9d.js.map +11 -0
- package/dist/{chunk-3j7573mj.js → chunk-2dw777qw.js} +50 -5
- package/dist/{chunk-3j7573mj.js.map → chunk-2dw777qw.js.map} +4 -3
- package/dist/{chunk-0172wgm9.js → chunk-2xns679x.js} +10 -2
- package/dist/{chunk-0172wgm9.js.map → chunk-2xns679x.js.map} +3 -3
- package/dist/chunk-359jm1jw.js +147 -0
- package/dist/chunk-359jm1jw.js.map +10 -0
- package/dist/{chunk-dy311asx.js → chunk-3xep5cjx.js} +58 -23
- package/dist/chunk-3xep5cjx.js.map +15 -0
- package/dist/{chunk-n4spznws.js → chunk-3z1qec12.js} +83 -12
- package/dist/chunk-3z1qec12.js.map +12 -0
- package/dist/{chunk-z3zp0bj1.js → chunk-407j3msh.js} +1 -1
- package/dist/{chunk-rhrbz7d4.js → chunk-4a849fr1.js} +1 -1
- package/dist/{chunk-cy0n5dms.js → chunk-4jjp5k14.js} +1 -1
- package/dist/chunk-4qfkag59.js +1568 -0
- package/dist/chunk-4qfkag59.js.map +20 -0
- package/dist/{chunk-1e8m6yn3.js → chunk-4sm0aznx.js} +685 -86
- package/dist/chunk-4sm0aznx.js.map +43 -0
- package/dist/chunk-4yqmp43v.js +159 -0
- package/dist/chunk-4yqmp43v.js.map +11 -0
- package/dist/{chunk-rdeagz6b.js → chunk-5e3pq99w.js} +3 -7
- package/dist/{chunk-rdeagz6b.js.map → chunk-5e3pq99w.js.map} +3 -3
- package/dist/{chunk-ezake7g1.js → chunk-5ntny1qx.js} +1 -1
- package/dist/{chunk-dm72y8wt.js → chunk-7y0f6rf1.js} +29 -16
- package/dist/chunk-7y0f6rf1.js.map +10 -0
- package/dist/{chunk-72q2y8hn.js → chunk-8tsf6dmc.js} +2 -2
- package/dist/{chunk-qewtks41.js → chunk-9nbmsvn5.js} +123 -20
- package/dist/chunk-9nbmsvn5.js.map +11 -0
- package/dist/{chunk-5sxb1168.js → chunk-aa2pen2v.js} +256 -82
- package/dist/chunk-aa2pen2v.js.map +34 -0
- package/dist/{chunk-819wnjz8.js → chunk-ajnan18g.js} +13 -10
- package/dist/chunk-ajnan18g.js.map +12 -0
- package/dist/chunk-c15dr03f.js +43 -0
- package/dist/chunk-c15dr03f.js.map +10 -0
- package/dist/{chunk-t0jjkep3.js → chunk-d8qkxt2v.js} +4 -2
- package/dist/chunk-d8qkxt2v.js.map +10 -0
- package/dist/{chunk-vybf6pkp.js → chunk-dbc80ad7.js} +1 -1
- package/dist/{chunk-nkbfrt0c.js → chunk-f26bck4t.js} +7 -7
- package/dist/{chunk-x2yw73hy.js → chunk-fvt9rjsa.js} +23 -7
- package/dist/chunk-fvt9rjsa.js.map +10 -0
- package/dist/{chunk-znagycq7.js → chunk-gbejpkex.js} +5 -5
- package/dist/{chunk-znagycq7.js.map → chunk-gbejpkex.js.map} +1 -1
- package/dist/{chunk-e42bc6m3.js → chunk-gzasd5b6.js} +5 -5
- package/dist/{chunk-e42bc6m3.js.map → chunk-gzasd5b6.js.map} +3 -3
- package/dist/{chunk-rnshztfq.js → chunk-h0k55pc7.js} +6 -6
- package/dist/{chunk-rnshztfq.js.map → chunk-h0k55pc7.js.map} +1 -1
- package/dist/chunk-h5vqbfmd.js +1537 -0
- package/dist/chunk-h5vqbfmd.js.map +19 -0
- package/dist/chunk-j1sbhm7p.js +45 -0
- package/dist/chunk-j1sbhm7p.js.map +10 -0
- package/dist/chunk-jecn6t54.js +307 -0
- package/dist/chunk-jecn6t54.js.map +12 -0
- package/dist/{chunk-dsrkgtnh.js → chunk-jq43kdvk.js} +1 -1
- package/dist/{chunk-wtmzkcht.js → chunk-k34z5rvh.js} +1 -1
- package/dist/{chunk-f6erf2vv.js → chunk-k522z7v6.js} +10 -5
- package/dist/chunk-k522z7v6.js.map +10 -0
- package/dist/{chunk-htq0qh7z.js → chunk-ka3a2ft3.js} +2 -2
- package/dist/{chunk-ckxfnx7f.js → chunk-mth82m8t.js} +129 -95
- package/dist/chunk-mth82m8t.js.map +14 -0
- package/dist/{chunk-5gynx4xn.js → chunk-mwsxn98e.js} +79 -77
- package/dist/{chunk-5gynx4xn.js.map → chunk-mwsxn98e.js.map} +8 -8
- package/dist/{chunk-f2rt4vkh.js → chunk-n2w475r0.js} +3 -3
- package/dist/chunk-n4khvw9n.js +111 -0
- package/dist/chunk-n4khvw9n.js.map +11 -0
- package/dist/{chunk-t8t39h7v.js → chunk-n6jxh8sw.js} +10 -2
- package/dist/chunk-n6jxh8sw.js.map +10 -0
- package/dist/chunk-nn0tekr1.js +284 -0
- package/dist/chunk-nn0tekr1.js.map +12 -0
- package/dist/chunk-nx7k8tpr.js +436 -0
- package/dist/chunk-nx7k8tpr.js.map +12 -0
- package/dist/{chunk-drjqm1aa.js → chunk-p03r0h5s.js} +310 -28
- package/dist/chunk-p03r0h5s.js.map +16 -0
- package/dist/{chunk-1g8negke.js → chunk-p1rzczbt.js} +93 -8
- package/dist/chunk-p1rzczbt.js.map +12 -0
- package/dist/{chunk-f83ka50g.js → chunk-p1x242ad.js} +652 -77
- package/dist/chunk-p1x242ad.js.map +25 -0
- package/dist/chunk-p2vqaxkc.js +528 -0
- package/dist/chunk-p2vqaxkc.js.map +15 -0
- package/dist/{chunk-a31h57d5.js → chunk-pc7ys28c.js} +70 -7
- package/dist/chunk-pc7ys28c.js.map +14 -0
- package/dist/{chunk-md8k0r54.js → chunk-q0k9nc5a.js} +281 -89
- package/dist/chunk-q0k9nc5a.js.map +14 -0
- package/dist/{chunk-bhxaq2nn.js → chunk-qw9gvjv5.js} +1 -1
- package/dist/chunk-r8jrnexe.js +403 -0
- package/dist/chunk-r8jrnexe.js.map +10 -0
- package/dist/{chunk-h9kxd41f.js → chunk-rafagrwr.js} +48 -7
- package/dist/chunk-rafagrwr.js.map +11 -0
- package/dist/{chunk-dysw7nsm.js → chunk-rv2hkwwa.js} +2 -2
- package/dist/{chunk-ghteq96b.js → chunk-s5y30bc9.js} +2 -2
- package/dist/{chunk-t624af60.js → chunk-sbzzr4kx.js} +1848 -757
- package/dist/chunk-sbzzr4kx.js.map +63 -0
- package/dist/{chunk-6gjqgd3d.js → chunk-tpnd31c1.js} +2 -1
- package/dist/chunk-tpnd31c1.js.map +11 -0
- package/dist/chunk-trxxmgnf.js +68 -0
- package/dist/chunk-trxxmgnf.js.map +11 -0
- package/dist/{chunk-0hc5j867.js → chunk-v1xppd0y.js} +17 -13
- package/dist/{chunk-0hc5j867.js.map → chunk-v1xppd0y.js.map} +2 -2
- package/dist/chunk-v4en4jc2.js +252 -0
- package/dist/chunk-v4en4jc2.js.map +10 -0
- package/dist/{chunk-xkthy56g.js → chunk-w1tvjszy.js} +1 -1
- package/dist/{chunk-8b55ygje.js → chunk-w3e09qqk.js} +1 -1
- package/dist/{chunk-8gv5z0zm.js → chunk-w9tg6yyb.js} +13 -8
- package/dist/{chunk-8gv5z0zm.js.map → chunk-w9tg6yyb.js.map} +3 -3
- package/dist/{chunk-62c7t4jc.js → chunk-wdage1eb.js} +1 -1
- package/dist/{chunk-tg5mee00.js → chunk-wtf06et8.js} +11 -7
- package/dist/{chunk-tg5mee00.js.map → chunk-wtf06et8.js.map} +3 -3
- package/dist/{chunk-nva1xkjz.js → chunk-xajtptbw.js} +1237 -1434
- package/dist/chunk-xajtptbw.js.map +40 -0
- package/dist/{chunk-xc7hq65b.js → chunk-yp8ee62z.js} +49 -2
- package/dist/chunk-yp8ee62z.js.map +11 -0
- package/dist/chunk-z4ccwbkz.js +139 -0
- package/dist/chunk-z4ccwbkz.js.map +10 -0
- package/dist/datasets/builders.d.ts +11 -2
- package/dist/datasets/builders.d.ts.map +1 -1
- package/dist/datasets/changes.d.ts +14 -4
- package/dist/datasets/changes.d.ts.map +1 -1
- package/dist/datasets/execution.d.ts +15 -1
- package/dist/datasets/execution.d.ts.map +1 -1
- package/dist/datasets/index.d.ts +1 -0
- package/dist/datasets/index.d.ts.map +1 -1
- package/dist/datasets/sequence.d.ts +7 -0
- package/dist/datasets/sequence.d.ts.map +1 -0
- package/dist/datasets/types.d.ts +1 -0
- package/dist/datasets/types.d.ts.map +1 -1
- package/dist/datasets/validation.d.ts.map +1 -1
- package/dist/datasets/write.d.ts +37 -0
- package/dist/datasets/write.d.ts.map +1 -0
- package/dist/datasets/write.js +17 -0
- package/dist/datasets/write.js.map +9 -0
- package/dist/error-reporting/internal.js +4 -4
- package/dist/error-reporting/types.d.ts +7 -2
- package/dist/error-reporting/types.d.ts.map +1 -1
- package/dist/errors/catalog.d.ts +8 -0
- package/dist/errors/catalog.d.ts.map +1 -1
- package/dist/errors/internal.js +2 -2
- package/dist/events/execution.d.ts.map +1 -1
- package/dist/events/index.js +4 -4
- package/dist/events/types/datasets.d.ts +2 -6
- package/dist/events/types/datasets.d.ts.map +1 -1
- package/dist/execution/agent.d.ts +18 -9
- package/dist/execution/agent.d.ts.map +1 -1
- package/dist/execution/agent.js +62 -46
- package/dist/execution/agent.js.map +1 -1
- package/dist/execution/authorization.d.ts +68 -20
- package/dist/execution/authorization.d.ts.map +1 -1
- package/dist/execution/authorized-object-reader.d.ts +69 -0
- package/dist/execution/authorized-object-reader.d.ts.map +1 -0
- package/dist/execution/durable.d.ts.map +1 -1
- package/dist/execution/index.d.ts +1 -1
- package/dist/execution/index.d.ts.map +1 -1
- package/dist/execution/primitive.js +55 -46
- package/dist/execution/primitive.js.map +2 -2
- package/dist/execution/request.d.ts +14 -1
- package/dist/execution/request.d.ts.map +1 -1
- package/dist/execution/request.js +92 -54
- package/dist/execution/request.js.map +3 -3
- package/dist/execution/scopes.d.ts +16 -0
- package/dist/execution/scopes.d.ts.map +1 -1
- package/dist/execution/types.d.ts +10 -1
- package/dist/execution/types.d.ts.map +1 -1
- package/dist/http/api-routes.d.ts +2 -0
- package/dist/http/api-routes.d.ts.map +1 -1
- package/dist/http/index.js +1 -1
- package/dist/index.d.ts +15 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +128 -109
- package/dist/index.js.map +1 -1
- package/dist/json.d.ts +2 -0
- package/dist/json.d.ts.map +1 -1
- package/dist/lake-storage/definition-updates.d.ts.map +1 -1
- package/dist/lake-storage/errors.d.ts +5 -1
- package/dist/lake-storage/errors.d.ts.map +1 -1
- package/dist/lake-storage/in-memory.d.ts +1 -0
- package/dist/lake-storage/in-memory.d.ts.map +1 -1
- package/dist/lake-storage/index.d.ts +6 -1
- package/dist/lake-storage/index.d.ts.map +1 -1
- package/dist/lake-storage/index.js +27 -10
- package/dist/lake-storage/index.js.map +1 -1
- package/dist/lake-storage/merge-validation.d.ts.map +1 -1
- package/dist/lake-storage/merge.d.ts +13 -2
- package/dist/lake-storage/merge.d.ts.map +1 -1
- package/dist/lake-storage/source-ordering.d.ts +19 -0
- package/dist/lake-storage/source-ordering.d.ts.map +1 -0
- package/dist/lake-storage/sql-transforms.d.ts +2 -1
- package/dist/lake-storage/sql-transforms.d.ts.map +1 -1
- package/dist/lake-storage/types.d.ts +10 -5
- package/dist/lake-storage/types.d.ts.map +1 -1
- package/dist/lake-storage/version-inputs.d.ts +4 -0
- package/dist/lake-storage/version-inputs.d.ts.map +1 -0
- package/dist/logging/index.js +3 -3
- package/dist/logging/types.js +2 -2
- package/dist/materialization/index.js +2 -2
- package/dist/materializer/index.js +38 -31
- package/dist/materializer/index.js.map +1 -1
- package/dist/models/catalog.d.ts +40 -0
- package/dist/models/catalog.d.ts.map +1 -0
- package/dist/models/definitions.d.ts +25 -0
- package/dist/models/definitions.d.ts.map +1 -0
- package/dist/models/errors.d.ts +52 -0
- package/dist/models/errors.d.ts.map +1 -0
- package/dist/models/events.d.ts +192 -0
- package/dist/models/events.d.ts.map +1 -0
- package/dist/models/index.d.ts +17 -39
- package/dist/models/index.d.ts.map +1 -1
- package/dist/models/index.js +50 -0
- package/dist/models/index.js.map +9 -0
- package/dist/models/language-model.d.ts +90 -0
- package/dist/models/language-model.d.ts.map +1 -0
- package/dist/models/messages.d.ts +74 -0
- package/dist/models/messages.d.ts.map +1 -0
- package/dist/models/pricing.d.ts +69 -0
- package/dist/models/pricing.d.ts.map +1 -0
- package/dist/models/rate-card.d.ts +24 -0
- package/dist/models/rate-card.d.ts.map +1 -0
- package/dist/models/tools.d.ts +24 -0
- package/dist/models/tools.d.ts.map +1 -0
- package/dist/objects/authorized-ontology-view.d.ts +25 -0
- package/dist/objects/authorized-ontology-view.d.ts.map +1 -0
- package/dist/objects/execution.d.ts +1 -1
- package/dist/objects/execution.d.ts.map +1 -1
- package/dist/objects/index.js +43 -36
- package/dist/objects/index.js.map +1 -1
- package/dist/objects/link/authorization.d.ts +2 -7
- package/dist/objects/link/authorization.d.ts.map +1 -1
- package/dist/objects/query/executor.d.ts +4 -2
- package/dist/objects/query/executor.d.ts.map +1 -1
- package/dist/objects/query/index.js +36 -29
- package/dist/objects/query/index.js.map +1 -1
- package/dist/objects/query/links.d.ts +22 -1
- package/dist/objects/query/links.d.ts.map +1 -1
- package/dist/objects/query/selected-read-admission.d.ts +27 -0
- package/dist/objects/query/selected-read-admission.d.ts.map +1 -0
- package/dist/objects/query/validate.d.ts +60 -2
- package/dist/objects/query/validate.d.ts.map +1 -1
- package/dist/objects/sdk/object-handle.d.ts.map +1 -1
- package/dist/objects/sdk/object-set.d.ts.map +1 -1
- package/dist/objects/sdk/runtime-query-executor.d.ts +2 -7
- 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/list-service.d.ts +2 -3
- package/dist/objects/service/list-service.d.ts.map +1 -1
- package/dist/objects/telemetry/history.d.ts +8 -6
- package/dist/objects/telemetry/history.d.ts.map +1 -1
- package/dist/objects/telemetry/index.d.ts +2 -2
- package/dist/objects/telemetry/index.d.ts.map +1 -1
- package/dist/objects/telemetry/workload.d.ts +11 -0
- package/dist/objects/telemetry/workload.d.ts.map +1 -0
- package/dist/ontology/index.d.ts +2 -1
- package/dist/ontology/index.d.ts.map +1 -1
- package/dist/ontology/index.js +15 -14
- package/dist/ontology/index.js.map +1 -1
- package/dist/ontology/inference/index.d.ts +2 -1
- package/dist/ontology/inference/index.d.ts.map +1 -1
- package/dist/ontology/internal.d.ts +0 -1
- package/dist/ontology/internal.d.ts.map +1 -1
- package/dist/ontology/internal.js +5 -10
- package/dist/ontology/internal.js.map +3 -3
- package/dist/ontology/json-schema.d.ts +10 -6
- package/dist/ontology/json-schema.d.ts.map +1 -1
- package/dist/ontology/link-path-selection.d.ts +35 -0
- package/dist/ontology/link-path-selection.d.ts.map +1 -0
- package/dist/ontology/refs.d.ts +2 -0
- package/dist/ontology/refs.d.ts.map +1 -1
- package/dist/ontology/tokens.d.ts +2 -1
- package/dist/ontology/tokens.d.ts.map +1 -1
- package/dist/pipelines/execution.d.ts.map +1 -1
- package/dist/pipelines/index.js +41 -36
- package/dist/pipelines/index.js.map +1 -1
- package/dist/pipelines/request.d.ts.map +1 -1
- package/dist/projections/execution.d.ts.map +1 -1
- package/dist/projections/internal.js +39 -32
- package/dist/projections/internal.js.map +1 -1
- package/dist/projections/run-dispatch.d.ts.map +1 -1
- package/dist/queues/in-memory.d.ts +3 -2
- package/dist/queues/in-memory.d.ts.map +1 -1
- package/dist/queues/index.d.ts +3 -1
- package/dist/queues/index.d.ts.map +1 -1
- package/dist/queues/index.js +1 -1
- package/dist/queues/types.d.ts +15 -3
- package/dist/queues/types.d.ts.map +1 -1
- package/dist/rules/execution.d.ts.map +1 -1
- package/dist/runtime/create.d.ts +7 -4
- package/dist/runtime/create.d.ts.map +1 -1
- package/dist/runtime/definitions.d.ts +4 -2
- package/dist/runtime/definitions.d.ts.map +1 -1
- package/dist/runtime/host.d.ts +5 -2
- package/dist/runtime/host.d.ts.map +1 -1
- package/dist/runtime/internal.d.ts +1 -0
- package/dist/runtime/internal.d.ts.map +1 -1
- package/dist/runtime/resolve-definitions.d.ts +4 -2
- package/dist/runtime/resolve-definitions.d.ts.map +1 -1
- package/dist/runtime/sixb.d.ts +8 -2
- package/dist/runtime/sixb.d.ts.map +1 -1
- package/dist/runtime/types.d.ts +3 -0
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/schedules/execution.d.ts +2 -1
- package/dist/schedules/execution.d.ts.map +1 -1
- package/dist/security/every.d.ts +4 -4
- package/dist/security/every.d.ts.map +1 -1
- package/dist/security/grants.d.ts +12 -6
- package/dist/security/grants.d.ts.map +1 -1
- package/dist/security/index.d.ts +1 -1
- package/dist/security/index.d.ts.map +1 -1
- package/dist/security/registry.d.ts +2 -1
- package/dist/security/registry.d.ts.map +1 -1
- package/dist/security/types.d.ts +19 -5
- package/dist/security/types.d.ts.map +1 -1
- package/dist/security/validation.d.ts +6 -2
- package/dist/security/validation.d.ts.map +1 -1
- package/dist/shares/access-plan.d.ts +22 -0
- package/dist/shares/access-plan.d.ts.map +1 -0
- package/dist/shares/builders.d.ts +14 -0
- package/dist/shares/builders.d.ts.map +1 -0
- package/dist/shares/compiler.d.ts +14 -0
- package/dist/shares/compiler.d.ts.map +1 -0
- package/dist/shares/errors.d.ts +4 -0
- package/dist/shares/errors.d.ts.map +1 -0
- package/dist/shares/execution.d.ts +57 -0
- package/dist/shares/execution.d.ts.map +1 -0
- package/dist/shares/index.d.ts +10 -0
- package/dist/shares/index.d.ts.map +1 -0
- package/dist/shares/internal.d.ts +3 -0
- package/dist/shares/internal.d.ts.map +1 -0
- package/dist/shares/internal.js +239 -0
- package/dist/shares/internal.js.map +10 -0
- package/dist/shares/intersection.d.ts +9 -0
- package/dist/shares/intersection.d.ts.map +1 -0
- package/dist/shares/session-protocol.d.ts +41 -0
- package/dist/shares/session-protocol.d.ts.map +1 -0
- package/dist/shares/types.d.ts +51 -0
- package/dist/shares/types.d.ts.map +1 -0
- package/dist/shares/validation.d.ts +11 -0
- package/dist/shares/validation.d.ts.map +1 -0
- package/dist/storage/action-runs/failure.js +3 -3
- package/dist/storage/action-runs/provider.js +2 -2
- 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 +3 -2
- package/dist/storage/agents/in-memory.d.ts.map +1 -1
- package/dist/storage/agents/index.d.ts +1 -1
- package/dist/storage/agents/index.d.ts.map +1 -1
- package/dist/storage/agents/provider.d.ts +11 -4
- package/dist/storage/agents/provider.d.ts.map +1 -1
- package/dist/storage/agents/provider.js +18 -15
- package/dist/storage/agents/provider.js.map +1 -1
- package/dist/storage/agents/types.d.ts +65 -17
- package/dist/storage/agents/types.d.ts.map +1 -1
- package/dist/storage/ai-cost/analytics.d.ts +2 -1
- package/dist/storage/ai-cost/analytics.d.ts.map +1 -1
- package/dist/storage/ai-cost/codec.d.ts +3 -2
- package/dist/storage/ai-cost/codec.d.ts.map +1 -1
- package/dist/storage/ai-cost/groups.d.ts +51 -0
- package/dist/storage/ai-cost/groups.d.ts.map +1 -0
- package/dist/storage/ai-cost/in-memory.d.ts +11 -1
- package/dist/storage/ai-cost/in-memory.d.ts.map +1 -1
- package/dist/storage/ai-cost/index.d.ts +1 -1
- package/dist/storage/ai-cost/index.d.ts.map +1 -1
- package/dist/storage/ai-cost/provider.d.ts +2 -0
- package/dist/storage/ai-cost/provider.d.ts.map +1 -1
- package/dist/storage/ai-cost/provider.js +29 -13
- package/dist/storage/ai-cost/provider.js.map +3 -3
- package/dist/storage/ai-cost/types.d.ts +64 -15
- package/dist/storage/ai-cost/types.d.ts.map +1 -1
- package/dist/storage/ai-cost/validation.d.ts +2 -1
- package/dist/storage/ai-cost/validation.d.ts.map +1 -1
- package/dist/storage/ai-limits/enforcement.d.ts +14 -0
- package/dist/storage/ai-limits/enforcement.d.ts.map +1 -0
- package/dist/storage/ai-limits/enforcement.js +21 -0
- package/dist/storage/ai-limits/enforcement.js.map +9 -0
- package/dist/storage/ai-limits/errors.d.ts +8 -0
- package/dist/storage/ai-limits/errors.d.ts.map +1 -0
- package/dist/storage/ai-limits/in-memory.d.ts +78 -0
- package/dist/storage/ai-limits/in-memory.d.ts.map +1 -0
- package/dist/storage/ai-limits/index.d.ts +7 -0
- package/dist/storage/ai-limits/index.d.ts.map +1 -0
- package/dist/storage/ai-limits/period.d.ts +4 -0
- package/dist/storage/ai-limits/period.d.ts.map +1 -0
- package/dist/storage/ai-limits/provider.d.ts +85 -0
- package/dist/storage/ai-limits/provider.d.ts.map +1 -0
- package/dist/storage/ai-limits/provider.js +62 -0
- package/dist/storage/ai-limits/provider.js.map +9 -0
- package/dist/storage/ai-limits/types.d.ts +175 -0
- package/dist/storage/ai-limits/types.d.ts.map +1 -0
- package/dist/storage/ai-usage/in-memory.d.ts +4 -0
- package/dist/storage/ai-usage/in-memory.d.ts.map +1 -1
- package/dist/storage/ai-usage/record.d.ts.map +1 -1
- package/dist/storage/ai-usage/types.d.ts +6 -2
- package/dist/storage/ai-usage/types.d.ts.map +1 -1
- package/dist/storage/auth/errors.d.ts +1 -1
- package/dist/storage/auth/errors.d.ts.map +1 -1
- package/dist/storage/auth/in-memory/auth-storage.d.ts +4 -1
- package/dist/storage/auth/in-memory/auth-storage.d.ts.map +1 -1
- package/dist/storage/auth/in-memory/device-authorizations.d.ts +29 -0
- package/dist/storage/auth/in-memory/device-authorizations.d.ts.map +1 -0
- package/dist/storage/auth/in-memory/shared.d.ts +3 -1
- package/dist/storage/auth/in-memory/shared.d.ts.map +1 -1
- package/dist/storage/auth/index.d.ts +2 -1
- package/dist/storage/auth/index.d.ts.map +1 -1
- package/dist/storage/auth/types.d.ts +66 -0
- package/dist/storage/auth/types.d.ts.map +1 -1
- package/dist/storage/connector-connections/provider.js +2 -2
- package/dist/storage/executions/in-memory.d.ts +3 -0
- package/dist/storage/executions/in-memory.d.ts.map +1 -1
- package/dist/storage/executions/provider.d.ts +4 -1
- package/dist/storage/executions/provider.d.ts.map +1 -1
- package/dist/storage/executions/provider.js +23 -3
- package/dist/storage/executions/provider.js.map +3 -3
- package/dist/storage/executions/run-link.d.ts +14 -2
- package/dist/storage/executions/run-link.d.ts.map +1 -1
- package/dist/storage/executions/validation.d.ts +6 -0
- package/dist/storage/executions/validation.d.ts.map +1 -1
- package/dist/storage/in-memory/index.d.ts +12 -0
- package/dist/storage/in-memory/index.d.ts.map +1 -1
- package/dist/storage/index.d.ts +15 -6
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/index.js +78 -36
- package/dist/storage/index.js.map +1 -1
- package/dist/storage/objects/execution-limits.d.ts +25 -0
- package/dist/storage/objects/execution-limits.d.ts.map +1 -0
- package/dist/storage/objects/guard.d.ts +16 -0
- package/dist/storage/objects/guard.d.ts.map +1 -0
- package/dist/storage/objects/in-memory/index.d.ts +3 -0
- package/dist/storage/objects/in-memory/index.d.ts.map +1 -0
- package/dist/storage/objects/in-memory/keys.d.ts +10 -0
- package/dist/storage/objects/in-memory/keys.d.ts.map +1 -0
- package/dist/storage/objects/in-memory/query.d.ts +31 -0
- package/dist/storage/objects/in-memory/query.d.ts.map +1 -0
- package/dist/storage/objects/in-memory/read-scope.d.ts +18 -0
- package/dist/storage/objects/in-memory/read-scope.d.ts.map +1 -0
- package/dist/storage/objects/in-memory/read-source.d.ts +10 -0
- package/dist/storage/objects/in-memory/read-source.d.ts.map +1 -0
- package/dist/storage/objects/in-memory/selected-reader.d.ts +9 -0
- package/dist/storage/objects/in-memory/selected-reader.d.ts.map +1 -0
- package/dist/storage/objects/{in-memory.d.ts → in-memory/storage.d.ts} +13 -10
- package/dist/storage/objects/in-memory/storage.d.ts.map +1 -0
- package/dist/storage/objects/index.d.ts +4 -1
- package/dist/storage/objects/index.d.ts.map +1 -1
- package/dist/storage/objects/keys.d.ts +1 -1
- package/dist/storage/objects/keys.d.ts.map +1 -1
- package/dist/storage/objects/read-scope.d.ts +25 -0
- package/dist/storage/objects/read-scope.d.ts.map +1 -0
- package/dist/storage/objects/types.d.ts +114 -22
- package/dist/storage/objects/types.d.ts.map +1 -1
- package/dist/storage/ontology/provider.js +3 -3
- package/dist/storage/operation-scope.d.ts +3 -0
- package/dist/storage/operation-scope.d.ts.map +1 -1
- package/dist/storage/operation-scope.js +4 -2
- package/dist/storage/operation-scope.js.map +1 -1
- package/dist/storage/pipeline-runs/provider.js +2 -2
- package/dist/storage/projection-runs/provider.js +4 -4
- package/dist/storage/share-grants/errors.d.ts +8 -0
- package/dist/storage/share-grants/errors.d.ts.map +1 -0
- package/dist/storage/share-grants/in-memory.d.ts +11 -0
- package/dist/storage/share-grants/in-memory.d.ts.map +1 -0
- package/dist/storage/share-grants/index.d.ts +5 -0
- package/dist/storage/share-grants/index.d.ts.map +1 -0
- package/dist/storage/share-grants/provider.d.ts +4 -0
- package/dist/storage/share-grants/provider.d.ts.map +1 -0
- package/dist/storage/share-grants/provider.js +24 -0
- package/dist/storage/share-grants/provider.js.map +9 -0
- package/dist/storage/share-grants/record.d.ts +11 -0
- package/dist/storage/share-grants/record.d.ts.map +1 -0
- package/dist/storage/share-grants/types.d.ts +97 -0
- package/dist/storage/share-grants/types.d.ts.map +1 -0
- package/dist/storage/share-sessions/errors.d.ts +8 -0
- package/dist/storage/share-sessions/errors.d.ts.map +1 -0
- package/dist/storage/share-sessions/in-memory.d.ts +14 -0
- package/dist/storage/share-sessions/in-memory.d.ts.map +1 -0
- package/dist/storage/share-sessions/index.d.ts +5 -0
- package/dist/storage/share-sessions/index.d.ts.map +1 -0
- package/dist/storage/share-sessions/provider.d.ts +3 -0
- package/dist/storage/share-sessions/provider.d.ts.map +1 -0
- package/dist/storage/share-sessions/provider.js +20 -0
- package/dist/storage/share-sessions/provider.js.map +9 -0
- package/dist/storage/share-sessions/record.d.ts +8 -0
- package/dist/storage/share-sessions/record.d.ts.map +1 -0
- package/dist/storage/share-sessions/types.d.ts +50 -0
- package/dist/storage/share-sessions/types.d.ts.map +1 -0
- package/dist/storage/sync-runs/provider.js +2 -2
- package/dist/storage/transaction.d.ts +2 -1
- package/dist/storage/transaction.d.ts.map +1 -1
- package/dist/storage/types.d.ts +13 -1
- package/dist/storage/types.d.ts.map +1 -1
- package/dist/storage/webhook-runs/provider.js +2 -2
- package/dist/storage/workflow-runs/provider.d.ts +1 -1
- package/dist/storage/workflow-runs/provider.js +14 -12
- package/dist/storage/workflow-runs/provider.js.map +1 -1
- package/dist/storage/workflow-runs/types.d.ts +5 -4
- package/dist/storage/workflow-runs/types.d.ts.map +1 -1
- package/dist/syncs/execution.d.ts.map +1 -1
- package/dist/syncs/index.js +41 -36
- package/dist/syncs/index.js.map +1 -1
- package/dist/syncs/request.d.ts.map +1 -1
- package/dist/testing/agent-execution.d.ts +3 -1
- package/dist/testing/agent-execution.d.ts.map +1 -1
- package/dist/testing/agent-storage-contract.d.ts.map +1 -1
- package/dist/testing/ai-cost-storage-contract.d.ts.map +1 -1
- package/dist/testing/ai-limit-storage-contract.d.ts +18 -0
- package/dist/testing/ai-limit-storage-contract.d.ts.map +1 -0
- package/dist/testing/ai-model-call-groups-contract.d.ts +6 -0
- package/dist/testing/ai-model-call-groups-contract.d.ts.map +1 -0
- package/dist/testing/ai-usage-storage-contract.d.ts.map +1 -1
- package/dist/testing/auth-storage-contract.d.ts.map +1 -1
- package/dist/testing/dataset-sequence-contract.d.ts +4 -0
- package/dist/testing/dataset-sequence-contract.d.ts.map +1 -0
- package/dist/testing/effective-storage-contract.d.ts.map +1 -1
- package/dist/testing/execution-storage-contract.d.ts +4 -0
- package/dist/testing/execution-storage-contract.d.ts.map +1 -1
- package/dist/testing/index.d.ts +5 -0
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +5392 -2070
- package/dist/testing/index.js.map +21 -15
- package/dist/testing/lake-merge-storage-contract.d.ts +1 -0
- package/dist/testing/lake-merge-storage-contract.d.ts.map +1 -1
- package/dist/testing/lake-storage-contract.d.ts.map +1 -1
- package/dist/testing/object-read-scope-contract.d.ts +22 -0
- package/dist/testing/object-read-scope-contract.d.ts.map +1 -0
- package/dist/testing/queues-contract.d.ts.map +1 -1
- package/dist/testing/share-grant-storage-contract.d.ts +10 -0
- package/dist/testing/share-grant-storage-contract.d.ts.map +1 -0
- package/dist/testing/share-session-storage-contract.d.ts +9 -0
- package/dist/testing/share-session-storage-contract.d.ts.map +1 -0
- package/dist/webhooks/internal.js +36 -29
- package/dist/webhooks/internal.js.map +2 -2
- package/dist/workers/index.js +2 -2
- package/dist/workflows/agent-step-identity.d.ts +3 -0
- package/dist/workflows/agent-step-identity.d.ts.map +1 -0
- package/dist/workflows/builders.d.ts +2 -3
- package/dist/workflows/builders.d.ts.map +1 -1
- package/dist/workflows/execution.d.ts +1 -1
- package/dist/workflows/execution.d.ts.map +1 -1
- package/dist/workflows/failure.d.ts +1 -1
- package/dist/workflows/failure.d.ts.map +1 -1
- package/dist/workflows/index.d.ts +3 -2
- package/dist/workflows/index.d.ts.map +1 -1
- package/dist/workflows/index.js +63 -48
- package/dist/workflows/index.js.map +1 -1
- package/dist/workflows/request.d.ts.map +1 -1
- package/dist/workflows/types.d.ts +26 -11
- package/dist/workflows/types.d.ts.map +1 -1
- package/dist/workflows/validation.d.ts +7 -1
- package/dist/workflows/validation.d.ts.map +1 -1
- package/package.json +43 -4
- package/src/actions/delegated-admission.ts +72 -0
- package/src/actions/descriptor.ts +58 -0
- package/src/actions/execution.ts +99 -24
- package/src/actions/request.ts +136 -19
- package/src/actions/run-authorization.ts +53 -0
- package/src/actions/run-dispatch.ts +8 -1
- package/src/agents/adapters.ts +60 -456
- package/src/agents/authority.ts +215 -34
- package/src/agents/builders.ts +3 -50
- package/src/agents/context-compaction.ts +4 -0
- package/src/agents/context-resolution.ts +1 -4
- package/src/agents/dispatch.ts +59 -2
- package/src/agents/errors.ts +4 -11
- package/src/agents/execution.ts +65 -56
- package/src/agents/identity.ts +4 -0
- package/src/agents/ids.ts +16 -1
- package/src/agents/index.ts +23 -30
- package/src/agents/message.ts +20 -12
- package/src/agents/model-loop.ts +1071 -0
- package/src/agents/reference.ts +7 -0
- package/src/agents/request.ts +157 -77
- package/src/agents/retired-config.ts +20 -0
- package/src/agents/streams.ts +45 -19
- package/src/agents/tool-catalog.ts +21 -0
- package/src/agents/tool-definition.ts +9 -5
- package/src/agents/types.ts +39 -81
- package/src/agents/validation.ts +11 -216
- package/src/ai-usage/execution.ts +189 -0
- package/src/ai-usage/index.ts +15 -0
- package/src/authorization/decision.ts +54 -22
- package/src/authorization/grant-kinds.ts +72 -15
- package/src/authorization/index.ts +2 -0
- package/src/authorization/resolve.ts +12 -5
- package/src/authorization/types.ts +7 -5
- package/src/bootstrap/discovery.ts +3 -3
- package/src/bootstrap/ontology-type-manifest.ts +12 -6
- package/src/datasets/builders.ts +23 -2
- package/src/datasets/changes.ts +16 -4
- package/src/datasets/execution.ts +76 -5
- package/src/datasets/index.ts +1 -0
- package/src/datasets/sequence.ts +77 -0
- package/src/datasets/types.ts +1 -0
- package/src/datasets/validation.ts +26 -0
- package/src/datasets/write.ts +240 -0
- package/src/error-reporting/types.ts +4 -2
- package/src/errors/catalog.ts +8 -0
- package/src/events/execution.ts +57 -7
- package/src/events/types/datasets.ts +2 -6
- package/src/execution/agent.ts +129 -25
- package/src/execution/authorization.ts +493 -83
- package/src/execution/authorized-object-reader.ts +695 -0
- package/src/execution/durable.ts +10 -2
- package/src/execution/index.ts +1 -0
- package/src/execution/request.ts +67 -14
- package/src/execution/scopes.ts +36 -6
- package/src/execution/types.ts +9 -1
- package/src/http/api-routes.ts +108 -0
- package/src/index.ts +72 -22
- package/src/json.ts +9 -0
- package/src/lake-storage/definition-updates.ts +9 -0
- package/src/lake-storage/errors.ts +6 -1
- package/src/lake-storage/in-memory.ts +53 -17
- package/src/lake-storage/index.ts +10 -1
- package/src/lake-storage/merge-validation.ts +12 -2
- package/src/lake-storage/merge.ts +40 -2
- package/src/lake-storage/source-ordering.ts +95 -0
- package/src/lake-storage/sql-transforms.ts +2 -1
- package/src/lake-storage/types.ts +10 -5
- package/src/lake-storage/version-inputs.ts +14 -0
- package/src/models/catalog.ts +137 -0
- package/src/models/definitions.ts +202 -0
- package/src/models/errors.ts +83 -0
- package/src/models/events.ts +198 -0
- package/src/models/index.ts +89 -71
- package/src/models/language-model.ts +143 -0
- package/src/models/messages.ts +78 -0
- package/src/models/pricing.ts +390 -0
- package/src/models/rate-card.ts +101 -0
- package/src/models/tools.ts +29 -0
- package/src/objects/authorized-ontology-view.ts +512 -0
- package/src/objects/execution.ts +98 -143
- package/src/objects/link/authorization.ts +3 -2
- package/src/objects/query/executor.ts +45 -34
- package/src/objects/query/links.ts +84 -25
- package/src/objects/query/selected-read-admission.ts +310 -0
- package/src/objects/query/validate.ts +353 -36
- package/src/objects/sdk/object-handle.ts +2 -8
- package/src/objects/sdk/object-set.ts +10 -11
- package/src/objects/sdk/runtime-query-executor.ts +8 -28
- package/src/objects/sdk/telemetry-channel.ts +11 -7
- package/src/objects/service/list-service.ts +15 -29
- package/src/objects/telemetry/history.ts +297 -17
- package/src/objects/telemetry/index.ts +2 -2
- package/src/objects/telemetry/workload.ts +79 -0
- package/src/ontology/index.ts +7 -1
- package/src/ontology/inference/index.ts +4 -1
- package/src/ontology/internal.ts +0 -1
- package/src/ontology/json-schema.ts +13 -12
- package/src/ontology/link-path-selection.ts +193 -0
- package/src/ontology/refs.ts +19 -0
- package/src/ontology/tokens.ts +15 -8
- package/src/pipelines/execution.ts +30 -7
- package/src/pipelines/request.ts +5 -0
- package/src/projections/execution.ts +72 -11
- package/src/projections/run-dispatch.ts +6 -12
- package/src/queues/in-memory.ts +5 -0
- package/src/queues/index.ts +11 -0
- package/src/queues/types.ts +20 -3
- package/src/rules/execution.ts +20 -8
- package/src/runtime/create.ts +11 -5
- package/src/runtime/definitions.ts +4 -2
- package/src/runtime/host.ts +28 -8
- package/src/runtime/internal.ts +1 -0
- package/src/runtime/resolve-definitions.ts +22 -36
- package/src/runtime/sixb.ts +29 -10
- package/src/runtime/types.ts +3 -0
- package/src/schedules/execution.ts +24 -2
- package/src/security/every.ts +4 -4
- package/src/security/grants.ts +100 -14
- package/src/security/index.ts +3 -0
- package/src/security/registry.ts +9 -5
- package/src/security/types.ts +23 -4
- package/src/security/validation.ts +33 -9
- package/src/shares/access-plan.ts +225 -0
- package/src/shares/builders.ts +381 -0
- package/src/shares/compiler.ts +359 -0
- package/src/shares/errors.ts +3 -0
- package/src/shares/execution.ts +394 -0
- package/src/shares/index.ts +28 -0
- package/src/shares/internal.ts +9 -0
- package/src/shares/intersection.ts +178 -0
- package/src/shares/session-protocol.ts +258 -0
- package/src/shares/types.ts +76 -0
- package/src/shares/validation.ts +40 -0
- package/src/storage/agents/errors.ts +1 -0
- package/src/storage/agents/in-memory.ts +121 -11
- package/src/storage/agents/index.ts +7 -0
- package/src/storage/agents/provider.ts +150 -6
- package/src/storage/agents/types.ts +73 -16
- package/src/storage/ai-cost/analytics.ts +63 -6
- package/src/storage/ai-cost/codec.ts +37 -12
- package/src/storage/ai-cost/groups.ts +248 -0
- package/src/storage/ai-cost/in-memory.ts +42 -0
- package/src/storage/ai-cost/index.ts +6 -0
- package/src/storage/ai-cost/provider.ts +7 -0
- package/src/storage/ai-cost/types.ts +76 -14
- package/src/storage/ai-cost/validation.ts +147 -17
- package/src/storage/ai-limits/enforcement.ts +68 -0
- package/src/storage/ai-limits/errors.ts +23 -0
- package/src/storage/ai-limits/in-memory.ts +671 -0
- package/src/storage/ai-limits/index.ts +31 -0
- package/src/storage/ai-limits/period.ts +11 -0
- package/src/storage/ai-limits/provider.ts +430 -0
- package/src/storage/ai-limits/types.ts +195 -0
- package/src/storage/ai-usage/in-memory.ts +13 -0
- package/src/storage/ai-usage/record.ts +17 -0
- package/src/storage/ai-usage/types.ts +6 -2
- package/src/storage/auth/errors.ts +6 -0
- package/src/storage/auth/in-memory/auth-storage.ts +69 -0
- package/src/storage/auth/in-memory/device-authorizations.ts +145 -0
- package/src/storage/auth/in-memory/shared.ts +7 -0
- package/src/storage/auth/index.ts +7 -0
- package/src/storage/auth/types.ts +73 -0
- package/src/storage/executions/in-memory.ts +9 -1
- package/src/storage/executions/provider.ts +30 -1
- package/src/storage/executions/run-link.ts +45 -6
- package/src/storage/executions/validation.ts +82 -7
- package/src/storage/in-memory/index.ts +69 -6
- package/src/storage/index.ts +102 -1
- package/src/storage/objects/execution-limits.ts +283 -0
- package/src/storage/objects/guard.ts +55 -0
- package/src/storage/objects/in-memory/index.ts +2 -0
- package/src/storage/objects/in-memory/keys.ts +46 -0
- package/src/storage/objects/in-memory/query.ts +754 -0
- package/src/storage/objects/in-memory/read-scope.ts +211 -0
- package/src/storage/objects/in-memory/read-source.ts +10 -0
- package/src/storage/objects/in-memory/selected-reader.ts +252 -0
- package/src/storage/objects/in-memory/storage.ts +589 -0
- package/src/storage/objects/index.ts +21 -0
- package/src/storage/objects/keys.ts +1 -1
- package/src/storage/objects/read-scope.ts +672 -0
- package/src/storage/objects/types.ts +123 -19
- package/src/storage/operation-scope.ts +16 -0
- package/src/storage/share-grants/errors.ts +14 -0
- package/src/storage/share-grants/in-memory.ts +107 -0
- package/src/storage/share-grants/index.ts +14 -0
- package/src/storage/share-grants/provider.ts +11 -0
- package/src/storage/share-grants/record.ts +347 -0
- package/src/storage/share-grants/types.ts +112 -0
- package/src/storage/share-sessions/errors.ts +14 -0
- package/src/storage/share-sessions/in-memory.ts +105 -0
- package/src/storage/share-sessions/index.ts +11 -0
- package/src/storage/share-sessions/provider.ts +9 -0
- package/src/storage/share-sessions/record.ts +176 -0
- package/src/storage/share-sessions/types.ts +57 -0
- package/src/storage/transaction.ts +14 -2
- package/src/storage/types.ts +64 -0
- package/src/storage/workflow-runs/in-memory.ts +3 -3
- package/src/storage/workflow-runs/provider.ts +2 -2
- package/src/storage/workflow-runs/types.ts +6 -3
- package/src/syncs/execution.ts +25 -5
- package/src/syncs/request.ts +5 -0
- package/src/testing/agent-execution.ts +40 -28
- package/src/testing/agent-storage-contract.ts +249 -28
- package/src/testing/ai-cost-storage-contract.ts +96 -8
- package/src/testing/ai-limit-storage-contract.ts +1134 -0
- package/src/testing/ai-model-call-groups-contract.ts +353 -0
- package/src/testing/ai-usage-storage-contract.ts +31 -0
- package/src/testing/auth-storage-contract.ts +85 -0
- package/src/testing/dataset-sequence-contract.ts +373 -0
- package/src/testing/effective-storage-contract.ts +34 -0
- package/src/testing/execution-storage-contract.ts +81 -2
- package/src/testing/index.ts +26 -0
- package/src/testing/lake-merge-storage-contract.ts +3 -0
- package/src/testing/lake-storage-contract.ts +58 -0
- package/src/testing/object-read-scope-contract.ts +939 -0
- package/src/testing/queues-contract.ts +36 -1
- package/src/testing/share-grant-storage-contract.ts +325 -0
- package/src/testing/share-session-storage-contract.ts +235 -0
- package/src/workflows/agent-step-identity.ts +4 -0
- package/src/workflows/builders.ts +95 -9
- package/src/workflows/execution.ts +55 -16
- package/src/workflows/failure.ts +2 -2
- package/src/workflows/index.ts +3 -0
- package/src/workflows/request.ts +5 -0
- package/src/workflows/types.ts +23 -11
- package/src/workflows/validation.ts +100 -7
- package/dist/chunk-1e8m6yn3.js.map +0 -37
- package/dist/chunk-1g8negke.js.map +0 -11
- package/dist/chunk-4gz41why.js +0 -72
- package/dist/chunk-4gz41why.js.map +0 -11
- package/dist/chunk-5sxb1168.js.map +0 -34
- package/dist/chunk-6gjqgd3d.js.map +0 -11
- package/dist/chunk-819wnjz8.js.map +0 -12
- package/dist/chunk-a31h57d5.js.map +0 -13
- package/dist/chunk-a44d5zgd.js +0 -556
- package/dist/chunk-a44d5zgd.js.map +0 -16
- package/dist/chunk-ckxfnx7f.js.map +0 -13
- package/dist/chunk-dm72y8wt.js.map +0 -10
- package/dist/chunk-drjqm1aa.js.map +0 -15
- package/dist/chunk-dy311asx.js.map +0 -14
- package/dist/chunk-f6erf2vv.js.map +0 -10
- package/dist/chunk-f83ka50g.js.map +0 -23
- package/dist/chunk-fe5ev6mr.js +0 -55
- package/dist/chunk-fe5ev6mr.js.map +0 -11
- package/dist/chunk-h9kxd41f.js.map +0 -11
- package/dist/chunk-hceck7dq.js +0 -137
- package/dist/chunk-hceck7dq.js.map +0 -10
- package/dist/chunk-md8k0r54.js.map +0 -14
- package/dist/chunk-n4spznws.js.map +0 -11
- package/dist/chunk-nva1xkjz.js.map +0 -46
- package/dist/chunk-qewtks41.js.map +0 -11
- package/dist/chunk-t0jjkep3.js.map +0 -10
- package/dist/chunk-t624af60.js.map +0 -56
- package/dist/chunk-t8t39h7v.js.map +0 -10
- package/dist/chunk-t9xghkva.js +0 -28
- package/dist/chunk-t9xghkva.js.map +0 -10
- package/dist/chunk-x2yw73hy.js.map +0 -10
- package/dist/chunk-xc7hq65b.js.map +0 -10
- package/dist/storage/objects/in-memory.d.ts.map +0 -1
- package/src/storage/objects/in-memory.ts +0 -1241
- /package/dist/{chunk-zqysyfjt.js.map → chunk-08m3b6w8.js.map} +0 -0
- /package/dist/{chunk-z3zp0bj1.js.map → chunk-407j3msh.js.map} +0 -0
- /package/dist/{chunk-rhrbz7d4.js.map → chunk-4a849fr1.js.map} +0 -0
- /package/dist/{chunk-cy0n5dms.js.map → chunk-4jjp5k14.js.map} +0 -0
- /package/dist/{chunk-ezake7g1.js.map → chunk-5ntny1qx.js.map} +0 -0
- /package/dist/{chunk-72q2y8hn.js.map → chunk-8tsf6dmc.js.map} +0 -0
- /package/dist/{chunk-vybf6pkp.js.map → chunk-dbc80ad7.js.map} +0 -0
- /package/dist/{chunk-nkbfrt0c.js.map → chunk-f26bck4t.js.map} +0 -0
- /package/dist/{chunk-dsrkgtnh.js.map → chunk-jq43kdvk.js.map} +0 -0
- /package/dist/{chunk-wtmzkcht.js.map → chunk-k34z5rvh.js.map} +0 -0
- /package/dist/{chunk-htq0qh7z.js.map → chunk-ka3a2ft3.js.map} +0 -0
- /package/dist/{chunk-f2rt4vkh.js.map → chunk-n2w475r0.js.map} +0 -0
- /package/dist/{chunk-bhxaq2nn.js.map → chunk-qw9gvjv5.js.map} +0 -0
- /package/dist/{chunk-dysw7nsm.js.map → chunk-rv2hkwwa.js.map} +0 -0
- /package/dist/{chunk-ghteq96b.js.map → chunk-s5y30bc9.js.map} +0 -0
- /package/dist/{chunk-xkthy56g.js.map → chunk-w1tvjszy.js.map} +0 -0
- /package/dist/{chunk-8b55ygje.js.map → chunk-w3e09qqk.js.map} +0 -0
- /package/dist/{chunk-62c7t4jc.js.map → chunk-wdage1eb.js.map} +0 -0
|
@@ -1,45 +1,8 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import {
|
|
3
|
-
ProviderMaterializationTransactionLifecycle,
|
|
4
|
-
appendScopeSnapshot,
|
|
5
|
-
assertMaterializationHeader,
|
|
6
|
-
assertPageRows,
|
|
7
|
-
assertPlanChunkCorrelations,
|
|
8
|
-
assertSourceBeginInput,
|
|
9
|
-
assertSourceCandidateOwner,
|
|
10
|
-
assertSourceExecutionIdentity,
|
|
11
|
-
assertSourceProject,
|
|
12
|
-
assertSourceStagedRow,
|
|
13
|
-
assertSourceWriteIdentity,
|
|
14
|
-
assertTimestamp,
|
|
15
|
-
assertWorkRecord,
|
|
16
|
-
compareCardinalityWork,
|
|
17
|
-
compareEventWork,
|
|
18
|
-
comparePlanWork,
|
|
19
|
-
createEventId,
|
|
20
|
-
finishScopeAccumulator,
|
|
21
|
-
invalidCorrelation,
|
|
22
|
-
isExactStagingManifest,
|
|
23
|
-
materializationChunkRows,
|
|
24
|
-
materializationPlanItems,
|
|
25
|
-
sourceConflict,
|
|
26
|
-
sourceMaterializationIdentity,
|
|
27
|
-
startScopeAccumulator,
|
|
28
|
-
uniqueSorted,
|
|
29
|
-
workUniquenessKey
|
|
30
|
-
} from "./chunk-72q2y8hn.js";
|
|
31
|
-
import {
|
|
32
|
-
createAgentOperationScope,
|
|
33
|
-
createAuthOperationScope,
|
|
34
|
-
createOntologyOperationScope,
|
|
35
|
-
createOperationScopedFacade,
|
|
36
|
-
createStorageOperationScope,
|
|
37
|
-
createWorkflowRunOperationScope
|
|
38
|
-
} from "./chunk-xc7hq65b.js";
|
|
39
2
|
import {
|
|
40
3
|
PipelineRunError,
|
|
41
4
|
assertPipelineRunExecution
|
|
42
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-4jjp5k14.js";
|
|
43
6
|
import {
|
|
44
7
|
ProjectionRunError,
|
|
45
8
|
advanceProjectionTelemetry,
|
|
@@ -66,43 +29,71 @@ import {
|
|
|
66
29
|
publicProjectionRunRecord,
|
|
67
30
|
requireTelemetryProjectionRun,
|
|
68
31
|
staleProjectionRunExecution
|
|
69
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-rv2hkwwa.js";
|
|
33
|
+
import {
|
|
34
|
+
ShareGrantStorageError,
|
|
35
|
+
cloneShareGrantRecord,
|
|
36
|
+
normalizeGetShareGrantByIdInput,
|
|
37
|
+
normalizeListShareGrantsInput,
|
|
38
|
+
normalizeRevokeShareGrantInput,
|
|
39
|
+
normalizeShareGrantCreate,
|
|
40
|
+
parseShareGrantRecord
|
|
41
|
+
} from "./chunk-nx7k8tpr.js";
|
|
42
|
+
import {
|
|
43
|
+
ShareSessionStorageError,
|
|
44
|
+
cloneShareSessionRecord,
|
|
45
|
+
normalizeGetShareSessionByIdInput,
|
|
46
|
+
normalizeRenewShareSessionIfValidInput,
|
|
47
|
+
normalizeRevokeShareSessionInput,
|
|
48
|
+
normalizeShareSessionCreate,
|
|
49
|
+
parseShareSessionRecord
|
|
50
|
+
} from "./chunk-4yqmp43v.js";
|
|
70
51
|
import {
|
|
71
52
|
SyncRunError,
|
|
72
53
|
assertSyncRunExecution
|
|
73
|
-
} from "./chunk-
|
|
54
|
+
} from "./chunk-wdage1eb.js";
|
|
74
55
|
import {
|
|
75
56
|
WebhookRunError,
|
|
76
57
|
assertWebhookRunExecution
|
|
77
|
-
} from "./chunk-
|
|
58
|
+
} from "./chunk-5ntny1qx.js";
|
|
78
59
|
import {
|
|
79
60
|
WorkflowRunError,
|
|
80
61
|
assertWorkflowAgentNodeRunExecution,
|
|
81
62
|
assertWorkflowRunExecution
|
|
82
|
-
} from "./chunk-
|
|
83
|
-
import {
|
|
84
|
-
parseActionRunFailure
|
|
85
|
-
} from "./chunk-htq0qh7z.js";
|
|
86
|
-
import {
|
|
87
|
-
ActionRunError,
|
|
88
|
-
assertActionRunExecution
|
|
89
|
-
} from "./chunk-xkthy56g.js";
|
|
90
|
-
import {
|
|
91
|
-
AgentStorageError,
|
|
92
|
-
agentContextCheckpointMatchesCreateInput,
|
|
93
|
-
assertAgentContextCheckpointAnchors,
|
|
94
|
-
assertAgentContextCheckpointAuthority,
|
|
95
|
-
assertAgentContextCheckpointReplayState,
|
|
96
|
-
assertAgentRunExecution,
|
|
97
|
-
assertCreateAgentContextCheckpointInput
|
|
98
|
-
} from "./chunk-1g8negke.js";
|
|
63
|
+
} from "./chunk-nn0tekr1.js";
|
|
99
64
|
import {
|
|
100
65
|
InMemoryAiUsageStorage,
|
|
101
66
|
aiModelCallCostMatchesUsage,
|
|
102
67
|
buildAiAccountingOverview,
|
|
103
68
|
buildAiModelCallAccountingList,
|
|
69
|
+
buildAiModelCallGroups,
|
|
104
70
|
normalizeAiModelCallCostRecord
|
|
105
|
-
} from "./chunk-
|
|
71
|
+
} from "./chunk-p03r0h5s.js";
|
|
72
|
+
import {
|
|
73
|
+
AiLimitOperationLock,
|
|
74
|
+
AiLimitStorageError,
|
|
75
|
+
aiLimitAccountingEntryAppliesToSubject,
|
|
76
|
+
aiLimitAmountKey,
|
|
77
|
+
aiLimitCalendarMonth,
|
|
78
|
+
aiLimitPolicyDimensionKey,
|
|
79
|
+
aiLimitQuantityFromAmount,
|
|
80
|
+
aiLimitReservationBuckets,
|
|
81
|
+
aiLimitReservationRequestKey,
|
|
82
|
+
aiLimitReservationRequestMatches,
|
|
83
|
+
aiLimitSubjectKey,
|
|
84
|
+
aiLimitSubjectsFromAccountingEntry,
|
|
85
|
+
aiModelCallReservationKey,
|
|
86
|
+
assertAiLimitAccountingMatchesReservation,
|
|
87
|
+
assertNonBlank,
|
|
88
|
+
cloneAiLimitPolicy,
|
|
89
|
+
cloneValidDate,
|
|
90
|
+
normalizeAiLimitAmount,
|
|
91
|
+
normalizeAiModelCallReservationIdentity,
|
|
92
|
+
normalizeCreateAiLimitPolicy,
|
|
93
|
+
normalizeReserveAiModelCall,
|
|
94
|
+
normalizeUpdateAiLimitPolicy,
|
|
95
|
+
resolveAiLimitActual
|
|
96
|
+
} from "./chunk-jecn6t54.js";
|
|
106
97
|
import {
|
|
107
98
|
CONNECTOR_CONNECTION_RUN_FAILURE_CODES,
|
|
108
99
|
ConnectorConnectionStorageError
|
|
@@ -112,7 +103,65 @@ import {
|
|
|
112
103
|
cloneExecutionRecord,
|
|
113
104
|
normalizeExecutionRecord,
|
|
114
105
|
validateExecutionRecordReferences
|
|
115
|
-
} from "./chunk-
|
|
106
|
+
} from "./chunk-rafagrwr.js";
|
|
107
|
+
import {
|
|
108
|
+
ProviderMaterializationTransactionLifecycle,
|
|
109
|
+
appendScopeSnapshot,
|
|
110
|
+
assertMaterializationHeader,
|
|
111
|
+
assertPageRows,
|
|
112
|
+
assertPlanChunkCorrelations,
|
|
113
|
+
assertSourceBeginInput,
|
|
114
|
+
assertSourceCandidateOwner,
|
|
115
|
+
assertSourceExecutionIdentity,
|
|
116
|
+
assertSourceProject,
|
|
117
|
+
assertSourceStagedRow,
|
|
118
|
+
assertSourceWriteIdentity,
|
|
119
|
+
assertTimestamp,
|
|
120
|
+
assertWorkRecord,
|
|
121
|
+
compareCardinalityWork,
|
|
122
|
+
compareEventWork,
|
|
123
|
+
comparePlanWork,
|
|
124
|
+
createEventId,
|
|
125
|
+
finishScopeAccumulator,
|
|
126
|
+
invalidCorrelation,
|
|
127
|
+
isExactStagingManifest,
|
|
128
|
+
materializationChunkRows,
|
|
129
|
+
materializationPlanItems,
|
|
130
|
+
sourceConflict,
|
|
131
|
+
sourceMaterializationIdentity,
|
|
132
|
+
startScopeAccumulator,
|
|
133
|
+
uniqueSorted,
|
|
134
|
+
workUniquenessKey
|
|
135
|
+
} from "./chunk-8tsf6dmc.js";
|
|
136
|
+
import {
|
|
137
|
+
createAgentOperationScope,
|
|
138
|
+
createAuthOperationScope,
|
|
139
|
+
createObjectOperationScope,
|
|
140
|
+
createOntologyOperationScope,
|
|
141
|
+
createOperationScopedFacade,
|
|
142
|
+
createStorageOperationScope,
|
|
143
|
+
createWorkflowRunOperationScope
|
|
144
|
+
} from "./chunk-yp8ee62z.js";
|
|
145
|
+
import {
|
|
146
|
+
parseActionRunFailure
|
|
147
|
+
} from "./chunk-ka3a2ft3.js";
|
|
148
|
+
import {
|
|
149
|
+
ActionRunError,
|
|
150
|
+
assertActionRunExecution
|
|
151
|
+
} from "./chunk-w1tvjszy.js";
|
|
152
|
+
import {
|
|
153
|
+
AgentStorageError,
|
|
154
|
+
agentContextCheckpointMatchesCreateInput,
|
|
155
|
+
assertAgentContextCheckpointAnchors,
|
|
156
|
+
assertAgentContextCheckpointAuthority,
|
|
157
|
+
assertAgentContextCheckpointReplayState,
|
|
158
|
+
assertAgentRunExecution,
|
|
159
|
+
assertConversationAgentRunSpec,
|
|
160
|
+
assertCreateAgentContextCheckpointInput,
|
|
161
|
+
assertCreateSubagentRunInput,
|
|
162
|
+
assertSubagentRunResult,
|
|
163
|
+
subagentRunMatchesCreateInput
|
|
164
|
+
} from "./chunk-p1rzczbt.js";
|
|
116
165
|
import {
|
|
117
166
|
assertPinnedDatasetWatermark
|
|
118
167
|
} from "./chunk-9dzba0f2.js";
|
|
@@ -126,22 +175,31 @@ import {
|
|
|
126
175
|
projectionEntityKey,
|
|
127
176
|
telemetryPointKey,
|
|
128
177
|
telemetryPointSortKey
|
|
129
|
-
} from "./chunk-
|
|
178
|
+
} from "./chunk-dbc80ad7.js";
|
|
130
179
|
import {
|
|
131
180
|
MaterializationConflictError,
|
|
132
181
|
MaterializationValidationError
|
|
133
182
|
} from "./chunk-ry24jbr1.js";
|
|
134
183
|
import {
|
|
135
184
|
AGENT_RUN_FAILURE_CODES
|
|
136
|
-
} from "./chunk-
|
|
185
|
+
} from "./chunk-d8qkxt2v.js";
|
|
137
186
|
import {
|
|
138
187
|
InMemoryAuthStorage,
|
|
139
188
|
paginate,
|
|
140
189
|
principalsEqual
|
|
141
|
-
} from "./chunk-
|
|
190
|
+
} from "./chunk-4sm0aznx.js";
|
|
142
191
|
import {
|
|
143
192
|
normalizeRequesterGroupIds
|
|
144
|
-
} from "./chunk-
|
|
193
|
+
} from "./chunk-4a849fr1.js";
|
|
194
|
+
import {
|
|
195
|
+
ObjectReadLimitExceededError,
|
|
196
|
+
assertObjectReadFacetCount,
|
|
197
|
+
assertObjectReadOutputWithinLimit,
|
|
198
|
+
snapshotObjectReadExecutionLimits
|
|
199
|
+
} from "./chunk-p1x242ad.js";
|
|
200
|
+
import {
|
|
201
|
+
assertObjectReaderProject
|
|
202
|
+
} from "./chunk-r8jrnexe.js";
|
|
145
203
|
import {
|
|
146
204
|
compareDecimalValues
|
|
147
205
|
} from "./chunk-04b07a9q.js";
|
|
@@ -149,11 +207,11 @@ import {
|
|
|
149
207
|
createSixbError,
|
|
150
208
|
parseSixbFailure,
|
|
151
209
|
toSixbFailure
|
|
152
|
-
} from "./chunk-
|
|
210
|
+
} from "./chunk-2xns679x.js";
|
|
153
211
|
import {
|
|
154
212
|
cloneJsonValue,
|
|
155
213
|
stableJsonStringify
|
|
156
|
-
} from "./chunk-
|
|
214
|
+
} from "./chunk-n6jxh8sw.js";
|
|
157
215
|
// src/storage/action-runs/idempotency.ts
|
|
158
216
|
function actionSubjectsEqual(left, right) {
|
|
159
217
|
if (left.kind !== right.kind)
|
|
@@ -191,7 +249,7 @@ var runDirectly = async (run) => run();
|
|
|
191
249
|
function actionRunKey(projectId, id) {
|
|
192
250
|
return JSON.stringify([projectId, id]);
|
|
193
251
|
}
|
|
194
|
-
function
|
|
252
|
+
function assertNonBlank2(value, fieldName) {
|
|
195
253
|
if (typeof value !== "string" || value.trim().length === 0) {
|
|
196
254
|
throw new ActionRunError(`[Sixb] Action materialization ${fieldName} must be nonblank.`);
|
|
197
255
|
}
|
|
@@ -451,9 +509,9 @@ class InMemoryActionRunStorage {
|
|
|
451
509
|
});
|
|
452
510
|
}
|
|
453
511
|
requireMaterializationRun(input) {
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
512
|
+
assertNonBlank2(input.projectId, "projectId");
|
|
513
|
+
assertNonBlank2(input.runId, "runId");
|
|
514
|
+
assertNonBlank2(input.actionId, "actionId");
|
|
457
515
|
const existing = this.rows.get(actionRunKey(input.projectId, input.runId));
|
|
458
516
|
if (!existing) {
|
|
459
517
|
throw new ActionRunError(`[Sixb] Action run '${input.runId}' not found for project '${input.projectId}'.`);
|
|
@@ -468,7 +526,7 @@ class InMemoryActionRunStorage {
|
|
|
468
526
|
}
|
|
469
527
|
}
|
|
470
528
|
// src/agents/message.ts
|
|
471
|
-
var AGENT_MESSAGE_CONTENT_VERSION =
|
|
529
|
+
var AGENT_MESSAGE_CONTENT_VERSION = 2;
|
|
472
530
|
|
|
473
531
|
// src/storage/agents/in-memory.ts
|
|
474
532
|
function normalizeFailure(failure) {
|
|
@@ -511,7 +569,6 @@ class InMemoryAgentThreadStore {
|
|
|
511
569
|
const record = {
|
|
512
570
|
id: input.id,
|
|
513
571
|
projectId: input.projectId,
|
|
514
|
-
agentId: input.agentId,
|
|
515
572
|
ownerPrincipal: clone(input.ownerPrincipal),
|
|
516
573
|
...input.title === undefined ? {} : { title: input.title },
|
|
517
574
|
status: input.status ?? "active",
|
|
@@ -530,8 +587,7 @@ class InMemoryAgentThreadStore {
|
|
|
530
587
|
async list(input) {
|
|
531
588
|
const order = input.order ?? "desc";
|
|
532
589
|
const statuses = input.statuses ? new Set(input.statuses) : null;
|
|
533
|
-
const
|
|
534
|
-
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));
|
|
590
|
+
const filtered = [...this.state.threads.values()].filter((thread) => thread.projectId === input.projectId).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));
|
|
535
591
|
const { page, hasMore, total } = applyWindow(filtered, input.offset, input.limit);
|
|
536
592
|
return { threads: page.map(clone), hasMore, total };
|
|
537
593
|
}
|
|
@@ -545,12 +601,12 @@ class InMemoryAgentRunStore {
|
|
|
545
601
|
this.executions = executions;
|
|
546
602
|
}
|
|
547
603
|
async create(input) {
|
|
604
|
+
assertConversationAgentRunSpec(input.spec);
|
|
548
605
|
await assertAgentRunExecution({
|
|
549
606
|
executions: this.executions,
|
|
550
607
|
projectId: input.projectId,
|
|
551
608
|
executionId: input.executionId,
|
|
552
|
-
runId: input.id
|
|
553
|
-
agentId: input.agentId
|
|
609
|
+
runId: input.id
|
|
554
610
|
});
|
|
555
611
|
const threadKey = key(input.projectId, input.threadId);
|
|
556
612
|
const thread = this.state.threads.get(threadKey);
|
|
@@ -569,12 +625,13 @@ class InMemoryAgentRunStore {
|
|
|
569
625
|
}
|
|
570
626
|
const createdAt = new Date(input.createdAt ?? new Date);
|
|
571
627
|
const run = {
|
|
628
|
+
kind: "conversation",
|
|
572
629
|
id: input.id,
|
|
573
630
|
projectId: input.projectId,
|
|
574
631
|
executionId: input.executionId,
|
|
575
632
|
threadId: input.threadId,
|
|
576
|
-
agentId: input.agentId,
|
|
577
633
|
triggerMessageId: input.triggerMessageId,
|
|
634
|
+
spec: clone(input.spec),
|
|
578
635
|
requesterGroupIds: normalizeRequesterGroupIds(input.requesterGroupIds),
|
|
579
636
|
status: "queued",
|
|
580
637
|
attempt: 0,
|
|
@@ -589,6 +646,57 @@ class InMemoryAgentRunStore {
|
|
|
589
646
|
this.state.threads.set(threadKey, clone(updatedThread));
|
|
590
647
|
return clone(run);
|
|
591
648
|
}
|
|
649
|
+
async createSubagent(input) {
|
|
650
|
+
assertCreateSubagentRunInput(input);
|
|
651
|
+
const execution = await assertAgentRunExecution({
|
|
652
|
+
executions: this.executions,
|
|
653
|
+
projectId: input.projectId,
|
|
654
|
+
executionId: input.executionId,
|
|
655
|
+
runId: input.id
|
|
656
|
+
});
|
|
657
|
+
const runKey = key(input.projectId, input.id);
|
|
658
|
+
const existing = this.state.runs.get(runKey);
|
|
659
|
+
if (existing) {
|
|
660
|
+
if (subagentRunMatchesCreateInput(existing, input))
|
|
661
|
+
return clone(existing);
|
|
662
|
+
throw new AgentStorageError("duplicate_id", `[Sixb] Subagent run '${input.id}' already exists with different immutable inputs.`);
|
|
663
|
+
}
|
|
664
|
+
const parent = this.state.runs.get(key(input.projectId, input.parentRunId));
|
|
665
|
+
if (!parent || parent.kind !== "conversation") {
|
|
666
|
+
throw new AgentStorageError("run_not_found", `[Sixb] Parent Agent run '${input.parentRunId}' was not found.`);
|
|
667
|
+
}
|
|
668
|
+
if (parent.status !== "running") {
|
|
669
|
+
throw new AgentStorageError("invalid_state", `[Sixb] Parent Agent run '${parent.id}' is not running (status '${parent.status}').`);
|
|
670
|
+
}
|
|
671
|
+
if (execution.source.type !== "execution" || execution.source.executionId !== parent.executionId) {
|
|
672
|
+
throw new AgentStorageError("invalid_input", `[Sixb] Subagent execution '${execution.id}' is not a child of parent execution '${parent.executionId}'.`);
|
|
673
|
+
}
|
|
674
|
+
if (parent.execution?.token !== input.parentExecutionToken) {
|
|
675
|
+
throw new AgentStorageError("execution_lost", `[Sixb] Parent Agent run '${parent.id}' is no longer owned by this execution.`);
|
|
676
|
+
}
|
|
677
|
+
const activeChildren = [...this.state.runs.values()].filter((run2) => run2.kind === "subagent" && run2.projectId === input.projectId && run2.parentRunId === parent.id && (run2.status === "queued" || run2.status === "running")).length;
|
|
678
|
+
if (activeChildren >= input.maxActiveChildren) {
|
|
679
|
+
throw new AgentStorageError("active_child_limit", `[Sixb] Agent run '${parent.id}' already has ${activeChildren} active subagents.`);
|
|
680
|
+
}
|
|
681
|
+
if ([...this.state.runs.values()].some((run2) => run2.projectId === input.projectId && run2.executionId === input.executionId)) {
|
|
682
|
+
throw new AgentStorageError("duplicate_id", `[Sixb] Execution '${input.executionId}' already belongs to another Agent run.`);
|
|
683
|
+
}
|
|
684
|
+
const run = {
|
|
685
|
+
kind: "subagent",
|
|
686
|
+
id: input.id,
|
|
687
|
+
projectId: input.projectId,
|
|
688
|
+
executionId: input.executionId,
|
|
689
|
+
parentRunId: input.parentRunId,
|
|
690
|
+
spawnKey: input.spawnKey,
|
|
691
|
+
spec: clone(input.spec),
|
|
692
|
+
requesterGroupIds: clone(parent.requesterGroupIds),
|
|
693
|
+
status: "queued",
|
|
694
|
+
attempt: 0,
|
|
695
|
+
createdAt: new Date(input.createdAt ?? new Date)
|
|
696
|
+
};
|
|
697
|
+
this.state.runs.set(runKey, clone(run));
|
|
698
|
+
return clone(run);
|
|
699
|
+
}
|
|
592
700
|
async start(input) {
|
|
593
701
|
const run = this.requireStatus(input.projectId, input.id, "queued");
|
|
594
702
|
const startedAt = new Date(input.startedAt ?? new Date);
|
|
@@ -646,6 +754,12 @@ class InMemoryAgentRunStore {
|
|
|
646
754
|
if (!run.execution || run.execution.token !== input.executionToken) {
|
|
647
755
|
throw new AgentStorageError("execution_lost", `[Sixb] Execution token is no longer current on agent run '${input.id}'.`);
|
|
648
756
|
}
|
|
757
|
+
if (input.status === "succeeded" && run.kind === "subagent") {
|
|
758
|
+
assertSubagentRunResult(input.result, run.id);
|
|
759
|
+
}
|
|
760
|
+
if (input.status === "succeeded" && run.kind === "conversation" && input.result !== undefined) {
|
|
761
|
+
throw new AgentStorageError("invalid_input", `[Sixb] Conversational Agent run '${run.id}' cannot persist a subagent result.`);
|
|
762
|
+
}
|
|
649
763
|
const completedAt = new Date(input.completedAt ?? new Date);
|
|
650
764
|
const next = {
|
|
651
765
|
...run,
|
|
@@ -653,6 +767,7 @@ class InMemoryAgentRunStore {
|
|
|
653
767
|
...input.modelId === undefined ? {} : { modelId: input.modelId },
|
|
654
768
|
...input.finishReason === undefined ? {} : { finishReason: input.finishReason },
|
|
655
769
|
...input.diagnostics === undefined ? {} : { diagnostics: clone(input.diagnostics) },
|
|
770
|
+
...input.status === "succeeded" && input.result !== undefined ? { result: clone(input.result) } : {},
|
|
656
771
|
...input.status === "succeeded" || input.error === undefined ? {} : { error: normalizeFailure(input.error) },
|
|
657
772
|
execution: undefined,
|
|
658
773
|
completedAt
|
|
@@ -671,7 +786,8 @@ class InMemoryAgentRunStore {
|
|
|
671
786
|
async list(input) {
|
|
672
787
|
const order = input.order ?? "desc";
|
|
673
788
|
const statuses = input.statuses ? new Set(input.statuses) : null;
|
|
674
|
-
const
|
|
789
|
+
const kinds = input.kinds ? new Set(input.kinds) : null;
|
|
790
|
+
const filtered = [...this.state.runs.values()].filter((run) => run.projectId === input.projectId).filter((run) => kinds ? kinds.has(run.kind) : true).filter((run) => input.threadId ? run.kind === "conversation" && run.threadId === input.threadId : true).filter((run) => input.parentRunId ? run.kind === "subagent" && run.parentRunId === input.parentRunId : 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));
|
|
675
791
|
const { page, hasMore, total } = applyWindow(filtered, input.offset, input.limit);
|
|
676
792
|
return { runs: page.map(clone), hasMore, total };
|
|
677
793
|
}
|
|
@@ -689,6 +805,8 @@ class InMemoryAgentRunStore {
|
|
|
689
805
|
return run;
|
|
690
806
|
}
|
|
691
807
|
releaseThread(run, completedAt) {
|
|
808
|
+
if (run.kind !== "conversation")
|
|
809
|
+
return;
|
|
692
810
|
const threadKey = key(run.projectId, run.threadId);
|
|
693
811
|
const thread = this.state.threads.get(threadKey);
|
|
694
812
|
if (thread && thread.activeRunId === run.id) {
|
|
@@ -926,9 +1044,9 @@ class InMemoryAiCostStorage {
|
|
|
926
1044
|
this.recordsByUsage.set(key2, structuredClone(record));
|
|
927
1045
|
}
|
|
928
1046
|
async summarizeExecutions(input) {
|
|
929
|
-
|
|
1047
|
+
assertNonBlank3(input.projectId, "cost summary projectId");
|
|
930
1048
|
for (const id of input.executionIds)
|
|
931
|
-
|
|
1049
|
+
assertNonBlank3(id, "cost summary executionId");
|
|
932
1050
|
const requested = new Set(input.executionIds);
|
|
933
1051
|
const usageByExecution = new Map(input.executionIds.map((id) => [id, []]));
|
|
934
1052
|
for (const usage of this.usage.snapshot().records.values()) {
|
|
@@ -947,9 +1065,32 @@ class InMemoryAiCostStorage {
|
|
|
947
1065
|
snapshot() {
|
|
948
1066
|
return structuredClone({ recordsByUsage: this.recordsByUsage });
|
|
949
1067
|
}
|
|
1068
|
+
async listModelCallGroups(input) {
|
|
1069
|
+
const items = await this.accountingItems();
|
|
1070
|
+
const roots = new Map;
|
|
1071
|
+
return buildAiModelCallGroups(input, await Promise.all(items.map(async (item) => {
|
|
1072
|
+
const key2 = usageRecordKey(item.usage.projectId, item.usage.executionId);
|
|
1073
|
+
let root = roots.get(key2);
|
|
1074
|
+
if (!root) {
|
|
1075
|
+
root = this.attribution?.resolveGroup?.({
|
|
1076
|
+
projectId: item.usage.projectId,
|
|
1077
|
+
executionId: item.usage.executionId
|
|
1078
|
+
}) ?? Promise.resolve({
|
|
1079
|
+
executionId: item.usage.executionId,
|
|
1080
|
+
attribution: item.attribution
|
|
1081
|
+
});
|
|
1082
|
+
roots.set(key2, root);
|
|
1083
|
+
}
|
|
1084
|
+
return { ...item, root: await root };
|
|
1085
|
+
})));
|
|
1086
|
+
}
|
|
950
1087
|
restore(snapshot) {
|
|
951
1088
|
replaceMap(this.recordsByUsage, snapshot.recordsByUsage);
|
|
952
1089
|
}
|
|
1090
|
+
getRecord(projectId, usageRecordId) {
|
|
1091
|
+
const record = this.recordsByUsage.get(usageRecordKey(projectId, usageRecordId));
|
|
1092
|
+
return record ? structuredClone(record) : null;
|
|
1093
|
+
}
|
|
953
1094
|
usageRecord(projectId, id) {
|
|
954
1095
|
return [...this.usage.snapshot().records.values()].find((record) => record.projectId === projectId && record.id === id);
|
|
955
1096
|
}
|
|
@@ -1000,7 +1141,7 @@ function addMoney(amounts, money) {
|
|
|
1000
1141
|
function usageRecordKey(projectId, id) {
|
|
1001
1142
|
return JSON.stringify([projectId, id]);
|
|
1002
1143
|
}
|
|
1003
|
-
function
|
|
1144
|
+
function assertNonBlank3(value, field) {
|
|
1004
1145
|
if (typeof value !== "string" || value.trim().length === 0) {
|
|
1005
1146
|
throw new TypeError(`[Sixb] AI ${field} must be nonblank.`);
|
|
1006
1147
|
}
|
|
@@ -1010,6 +1151,429 @@ function replaceMap(target, source) {
|
|
|
1010
1151
|
for (const [key2, value] of structuredClone(source))
|
|
1011
1152
|
target.set(key2, value);
|
|
1012
1153
|
}
|
|
1154
|
+
// src/storage/ai-limits/in-memory.ts
|
|
1155
|
+
class InMemoryAiLimitStorage {
|
|
1156
|
+
options;
|
|
1157
|
+
policies = new Map;
|
|
1158
|
+
policyIdsByDimension = new Map;
|
|
1159
|
+
periodStates = new Map;
|
|
1160
|
+
reservations = new Map;
|
|
1161
|
+
operations = new AiLimitOperationLock;
|
|
1162
|
+
constructor(options = {}) {
|
|
1163
|
+
this.options = options;
|
|
1164
|
+
}
|
|
1165
|
+
settleOperations() {
|
|
1166
|
+
return this.operations.settle();
|
|
1167
|
+
}
|
|
1168
|
+
async createPolicy(input) {
|
|
1169
|
+
return this.operations.run(async () => {
|
|
1170
|
+
const policy = normalizeCreateAiLimitPolicy(input);
|
|
1171
|
+
const key2 = policyKey(policy.projectId, policy.id);
|
|
1172
|
+
const dimensionKey = aiLimitPolicyDimensionKey(policy);
|
|
1173
|
+
if (this.policies.has(key2) || this.policyIdsByDimension.has(dimensionKey)) {
|
|
1174
|
+
throw new AiLimitStorageError("duplicate_policy", `[Sixb] An AI limit policy already exists for '${aiLimitSubjectKey(policy.subject)}' and '${aiLimitAmountKey(normalizeAiLimitAmount(policy.limit))}'.`);
|
|
1175
|
+
}
|
|
1176
|
+
this.policies.set(key2, structuredClone(policy));
|
|
1177
|
+
this.policyIdsByDimension.set(dimensionKey, key2);
|
|
1178
|
+
return cloneAiLimitPolicy(policy);
|
|
1179
|
+
});
|
|
1180
|
+
}
|
|
1181
|
+
async updatePolicy(input) {
|
|
1182
|
+
return this.operations.run(async () => {
|
|
1183
|
+
const update = normalizeUpdateAiLimitPolicy(input);
|
|
1184
|
+
const key2 = policyKey(update.projectId, update.id);
|
|
1185
|
+
const existing = this.policies.get(key2);
|
|
1186
|
+
if (!existing)
|
|
1187
|
+
throw missingPolicy(update.projectId, update.id);
|
|
1188
|
+
if (update.limit !== undefined) {
|
|
1189
|
+
const previous = normalizeAiLimitAmount(existing.limit);
|
|
1190
|
+
const next = normalizeAiLimitAmount(update.limit);
|
|
1191
|
+
if (aiLimitAmountKey(previous) !== aiLimitAmountKey(next)) {
|
|
1192
|
+
throw new TypeError("[Sixb] AI limit policy meter and cost currency are immutable.");
|
|
1193
|
+
}
|
|
1194
|
+
}
|
|
1195
|
+
const policy = {
|
|
1196
|
+
...existing,
|
|
1197
|
+
...update.limit === undefined ? {} : { limit: update.limit },
|
|
1198
|
+
...update.enabled === undefined ? {} : { enabled: update.enabled },
|
|
1199
|
+
updatedAt: update.updatedAt
|
|
1200
|
+
};
|
|
1201
|
+
this.policies.set(key2, structuredClone(policy));
|
|
1202
|
+
return cloneAiLimitPolicy(policy);
|
|
1203
|
+
});
|
|
1204
|
+
}
|
|
1205
|
+
async deletePolicy(input) {
|
|
1206
|
+
return this.operations.run(async () => {
|
|
1207
|
+
validatePolicyIdentity(input);
|
|
1208
|
+
const key2 = policyKey(input.projectId, input.id);
|
|
1209
|
+
const existing = this.policies.get(key2);
|
|
1210
|
+
if (!existing)
|
|
1211
|
+
return false;
|
|
1212
|
+
this.policies.delete(key2);
|
|
1213
|
+
this.policyIdsByDimension.delete(aiLimitPolicyDimensionKey(existing));
|
|
1214
|
+
return true;
|
|
1215
|
+
});
|
|
1216
|
+
}
|
|
1217
|
+
async getPolicy(input) {
|
|
1218
|
+
validatePolicyIdentity(input);
|
|
1219
|
+
const policy = this.policies.get(policyKey(input.projectId, input.id));
|
|
1220
|
+
return policy ? cloneAiLimitPolicy(policy) : null;
|
|
1221
|
+
}
|
|
1222
|
+
async listPolicies(input) {
|
|
1223
|
+
assertNonBlank(input.projectId, "projectId");
|
|
1224
|
+
return [...this.policies.values()].filter((policy) => policy.projectId === input.projectId && (input.includeDisabled || policy.enabled)).sort((left, right) => left.id.localeCompare(right.id)).map(cloneAiLimitPolicy);
|
|
1225
|
+
}
|
|
1226
|
+
async listPolicyStatuses(input) {
|
|
1227
|
+
return this.operations.run(async () => {
|
|
1228
|
+
assertNonBlank(input.projectId, "projectId");
|
|
1229
|
+
const period = aiLimitCalendarMonth(input.at ?? new Date);
|
|
1230
|
+
const existingGroups = input.existingGroupIds === undefined ? undefined : new Set(input.existingGroupIds);
|
|
1231
|
+
const policies = await this.listPolicies({
|
|
1232
|
+
projectId: input.projectId,
|
|
1233
|
+
includeDisabled: input.includeDisabled
|
|
1234
|
+
});
|
|
1235
|
+
return Promise.all(policies.map((policy) => this.policyStatus(policy, period, existingGroups)));
|
|
1236
|
+
});
|
|
1237
|
+
}
|
|
1238
|
+
async reserveModelCall(input) {
|
|
1239
|
+
return this.operations.run(async () => {
|
|
1240
|
+
const request = normalizeReserveAiModelCall(input);
|
|
1241
|
+
const reservationKey = aiModelCallReservationKey(request.identity);
|
|
1242
|
+
const existing = this.reservations.get(reservationKey);
|
|
1243
|
+
if (existing) {
|
|
1244
|
+
if (!aiLimitReservationRequestMatches(existing, request)) {
|
|
1245
|
+
throw new AiLimitStorageError("reservation_conflict", `[Sixb] AI model-call reservation '${input.callId}' was replayed with different subjects, estimates, or period.`);
|
|
1246
|
+
}
|
|
1247
|
+
if (existing.state !== "active") {
|
|
1248
|
+
return { status: "terminal", reservation: structuredClone(existing), created: false };
|
|
1249
|
+
}
|
|
1250
|
+
return { status: "reserved", reservation: structuredClone(existing), created: false };
|
|
1251
|
+
}
|
|
1252
|
+
await this.assertExecutionExists(request.identity.projectId, request.identity.executionId);
|
|
1253
|
+
const enabledPolicies = [...this.policies.values()].filter((policy) => policy.projectId === request.identity.projectId && policy.enabled);
|
|
1254
|
+
const subjectKeys = new Set(request.subjects.map(aiLimitSubjectKey));
|
|
1255
|
+
const estimates = new Map(request.estimates.map((quantity) => {
|
|
1256
|
+
const amount = normalizeAiLimitAmount(quantity);
|
|
1257
|
+
return [aiLimitAmountKey(amount), amount];
|
|
1258
|
+
}));
|
|
1259
|
+
const exhaustedPolicies = [];
|
|
1260
|
+
const unavailablePolicies = [];
|
|
1261
|
+
const unavailableReasons = new Set;
|
|
1262
|
+
for (const policy of enabledPolicies) {
|
|
1263
|
+
if (!subjectKeys.has(aiLimitSubjectKey(policy.subject)))
|
|
1264
|
+
continue;
|
|
1265
|
+
const limit = normalizeAiLimitAmount(policy.limit);
|
|
1266
|
+
const estimate = estimates.get(aiLimitAmountKey(limit));
|
|
1267
|
+
const status = await this.policyStatus(policy, request.period);
|
|
1268
|
+
if (!estimate || status.accountingStatus === "unavailable") {
|
|
1269
|
+
unavailablePolicies.push(status);
|
|
1270
|
+
if (!estimate)
|
|
1271
|
+
unavailableReasons.add("missingEstimate");
|
|
1272
|
+
if (status.accountingStatus === "unavailable") {
|
|
1273
|
+
unavailableReasons.add("incompleteAccounting");
|
|
1274
|
+
}
|
|
1275
|
+
continue;
|
|
1276
|
+
}
|
|
1277
|
+
const actual = normalizeAiLimitAmount(status.consumption.actual).amount;
|
|
1278
|
+
const reserved = normalizeAiLimitAmount(status.consumption.reserved).amount;
|
|
1279
|
+
const unknown = normalizeAiLimitAmount(status.consumption.unknown).amount;
|
|
1280
|
+
if (actual + reserved + unknown + estimate.amount > limit.amount) {
|
|
1281
|
+
exhaustedPolicies.push(status);
|
|
1282
|
+
}
|
|
1283
|
+
}
|
|
1284
|
+
if (unavailablePolicies.length > 0) {
|
|
1285
|
+
unavailablePolicies.sort((left, right) => left.policy.id.localeCompare(right.policy.id));
|
|
1286
|
+
return {
|
|
1287
|
+
status: "unavailable",
|
|
1288
|
+
unavailablePolicies,
|
|
1289
|
+
reasons: [...unavailableReasons].sort()
|
|
1290
|
+
};
|
|
1291
|
+
}
|
|
1292
|
+
if (exhaustedPolicies.length > 0) {
|
|
1293
|
+
exhaustedPolicies.sort((left, right) => left.policy.id.localeCompare(right.policy.id));
|
|
1294
|
+
return {
|
|
1295
|
+
status: "denied",
|
|
1296
|
+
exhaustedPolicies,
|
|
1297
|
+
resetAt: new Date(Math.min(...exhaustedPolicies.map((status) => status.period.resetAt.getTime())))
|
|
1298
|
+
};
|
|
1299
|
+
}
|
|
1300
|
+
const buckets = aiLimitReservationBuckets(enabledPolicies, request.subjects, request.estimates);
|
|
1301
|
+
if (buckets.length === 0)
|
|
1302
|
+
return { status: "notRequired" };
|
|
1303
|
+
for (const bucket of buckets) {
|
|
1304
|
+
const amount = normalizeAiLimitAmount(bucket.estimate);
|
|
1305
|
+
const state = this.requirePeriodState(request.identity.projectId, bucket.subject, amount, request.period);
|
|
1306
|
+
state.reserved += amount.amount;
|
|
1307
|
+
state.updatedAt = new Date(request.reservedAt);
|
|
1308
|
+
}
|
|
1309
|
+
const reservation = {
|
|
1310
|
+
...request.identity,
|
|
1311
|
+
buckets,
|
|
1312
|
+
requestKey: aiLimitReservationRequestKey(request),
|
|
1313
|
+
period: request.period,
|
|
1314
|
+
state: "active",
|
|
1315
|
+
reservedAt: request.reservedAt,
|
|
1316
|
+
updatedAt: new Date(request.reservedAt)
|
|
1317
|
+
};
|
|
1318
|
+
this.reservations.set(reservationKey, structuredClone(reservation));
|
|
1319
|
+
return { status: "reserved", reservation: structuredClone(reservation), created: true };
|
|
1320
|
+
});
|
|
1321
|
+
}
|
|
1322
|
+
async recordModelCallActuals(input) {
|
|
1323
|
+
return this.operations.run(async () => {
|
|
1324
|
+
assertNonBlank(input.projectId, "projectId");
|
|
1325
|
+
assertNonBlank(input.usageRecordId, "usageRecordId");
|
|
1326
|
+
const recordedAt = cloneValidDate(input.recordedAt ?? new Date, "recordedAt");
|
|
1327
|
+
const entry = await this.requireAccountingEntry(input.projectId, input.usageRecordId);
|
|
1328
|
+
const period = aiLimitCalendarMonth(entry.occurredAt);
|
|
1329
|
+
const subjectKeys = new Set(aiLimitSubjectsFromAccountingEntry(entry).map(aiLimitSubjectKey));
|
|
1330
|
+
for (const state of this.periodStates.values()) {
|
|
1331
|
+
if (state.projectId !== input.projectId || state.period.start.getTime() !== period.start.getTime() || !subjectKeys.has(aiLimitSubjectKey(state.subject))) {
|
|
1332
|
+
continue;
|
|
1333
|
+
}
|
|
1334
|
+
const actual = resolveAiLimitActual([entry], state);
|
|
1335
|
+
state.actual += actual.amount;
|
|
1336
|
+
if (actual.accountingStatus === "unavailable")
|
|
1337
|
+
state.accountingStatus = "unavailable";
|
|
1338
|
+
state.updatedAt = new Date(recordedAt);
|
|
1339
|
+
}
|
|
1340
|
+
});
|
|
1341
|
+
}
|
|
1342
|
+
async reconcileModelCall(input) {
|
|
1343
|
+
return this.operations.run(async () => {
|
|
1344
|
+
const identity = normalizeAiModelCallReservationIdentity(input);
|
|
1345
|
+
assertNonBlank(input.usageRecordId, "usageRecordId");
|
|
1346
|
+
const reconciledAt = cloneValidDate(input.reconciledAt ?? new Date, "reconciledAt");
|
|
1347
|
+
const key2 = aiModelCallReservationKey(identity);
|
|
1348
|
+
const reservation = this.reservations.get(key2);
|
|
1349
|
+
if (!reservation)
|
|
1350
|
+
throw missingReservation(identity);
|
|
1351
|
+
if (reservation.state === "reconciled") {
|
|
1352
|
+
if (reservation.usageRecordId === input.usageRecordId) {
|
|
1353
|
+
return structuredClone(reservation);
|
|
1354
|
+
}
|
|
1355
|
+
throw new AiLimitStorageError("reconciliation_conflict", `[Sixb] AI model-call reservation '${identity.callId}' was reconciled with a different usage record.`);
|
|
1356
|
+
}
|
|
1357
|
+
const accounting = await this.requireAccountingEntry(identity.projectId, input.usageRecordId);
|
|
1358
|
+
assertAiLimitAccountingMatchesReservation(reservation, accounting);
|
|
1359
|
+
this.reconcileEstimateCounters(reservation, accounting, reconciledAt);
|
|
1360
|
+
const reconciled = {
|
|
1361
|
+
...reservation,
|
|
1362
|
+
state: "reconciled",
|
|
1363
|
+
usageRecordId: input.usageRecordId,
|
|
1364
|
+
updatedAt: reconciledAt
|
|
1365
|
+
};
|
|
1366
|
+
this.reservations.set(key2, structuredClone(reconciled));
|
|
1367
|
+
return structuredClone(reconciled);
|
|
1368
|
+
});
|
|
1369
|
+
}
|
|
1370
|
+
async markReservationUnknown(input) {
|
|
1371
|
+
return this.operations.run(async () => {
|
|
1372
|
+
const identity = normalizeAiModelCallReservationIdentity(input);
|
|
1373
|
+
const markedAt = cloneValidDate(input.markedAt ?? new Date, "markedAt");
|
|
1374
|
+
const key2 = aiModelCallReservationKey(identity);
|
|
1375
|
+
const reservation = this.reservations.get(key2);
|
|
1376
|
+
if (!reservation)
|
|
1377
|
+
throw missingReservation(identity);
|
|
1378
|
+
if (reservation.state === "unknown")
|
|
1379
|
+
return structuredClone(reservation);
|
|
1380
|
+
if (reservation.state !== "active")
|
|
1381
|
+
throw invalidState(reservation, "mark unknown");
|
|
1382
|
+
this.moveEstimateCounter(reservation, "reserved", -1n, markedAt);
|
|
1383
|
+
this.moveEstimateCounter(reservation, "unknown", 1n, markedAt);
|
|
1384
|
+
const unknown = {
|
|
1385
|
+
...reservation,
|
|
1386
|
+
state: "unknown",
|
|
1387
|
+
updatedAt: markedAt
|
|
1388
|
+
};
|
|
1389
|
+
this.reservations.set(key2, structuredClone(unknown));
|
|
1390
|
+
return structuredClone(unknown);
|
|
1391
|
+
});
|
|
1392
|
+
}
|
|
1393
|
+
snapshot() {
|
|
1394
|
+
return structuredClone({
|
|
1395
|
+
policies: this.policies,
|
|
1396
|
+
policyIdsByDimension: this.policyIdsByDimension,
|
|
1397
|
+
periodStates: this.periodStates,
|
|
1398
|
+
reservations: this.reservations
|
|
1399
|
+
});
|
|
1400
|
+
}
|
|
1401
|
+
restore(snapshot) {
|
|
1402
|
+
replaceMap2(this.policies, snapshot.policies);
|
|
1403
|
+
replaceMap2(this.policyIdsByDimension, snapshot.policyIdsByDimension);
|
|
1404
|
+
replaceMap2(this.periodStates, snapshot.periodStates);
|
|
1405
|
+
replaceMap2(this.reservations, snapshot.reservations);
|
|
1406
|
+
}
|
|
1407
|
+
async policyStatus(policy, period, existingGroups) {
|
|
1408
|
+
const limit = normalizeAiLimitAmount(policy.limit);
|
|
1409
|
+
const state = await this.ensurePeriodState(policy, period);
|
|
1410
|
+
const reserved = state.reserved;
|
|
1411
|
+
const unknown = state.unknown;
|
|
1412
|
+
const consumed = state.actual + reserved + unknown;
|
|
1413
|
+
const remaining = limit.amount > consumed ? limit.amount - consumed : 0n;
|
|
1414
|
+
const quantity = (amount) => aiLimitQuantityFromAmount({ ...limit, amount });
|
|
1415
|
+
return {
|
|
1416
|
+
policy: cloneAiLimitPolicy(policy),
|
|
1417
|
+
period: structuredClone(period),
|
|
1418
|
+
consumption: {
|
|
1419
|
+
actual: quantity(state.actual),
|
|
1420
|
+
reserved: quantity(reserved),
|
|
1421
|
+
unknown: quantity(unknown),
|
|
1422
|
+
remaining: quantity(remaining)
|
|
1423
|
+
},
|
|
1424
|
+
accountingStatus: state.accountingStatus,
|
|
1425
|
+
exhausted: consumed >= limit.amount,
|
|
1426
|
+
orphaned: policy.subject.type === "group" && existingGroups !== undefined && !existingGroups.has(policy.subject.id)
|
|
1427
|
+
};
|
|
1428
|
+
}
|
|
1429
|
+
async ensurePeriodState(policy, period) {
|
|
1430
|
+
const amount = normalizeAiLimitAmount(policy.limit);
|
|
1431
|
+
const key2 = periodStateKey(policy.projectId, policy.subject, amount, period);
|
|
1432
|
+
const existing = this.periodStates.get(key2);
|
|
1433
|
+
if (existing?.accountingStatus === "complete")
|
|
1434
|
+
return existing;
|
|
1435
|
+
const actual = await this.resolvePolicyActual(policy, period, amount);
|
|
1436
|
+
if (existing) {
|
|
1437
|
+
existing.actual = actual.amount;
|
|
1438
|
+
existing.accountingStatus = actual.accountingStatus;
|
|
1439
|
+
existing.updatedAt = new Date;
|
|
1440
|
+
return existing;
|
|
1441
|
+
}
|
|
1442
|
+
const state = {
|
|
1443
|
+
projectId: policy.projectId,
|
|
1444
|
+
subject: structuredClone(policy.subject),
|
|
1445
|
+
meter: amount.meter,
|
|
1446
|
+
currency: amount.currency,
|
|
1447
|
+
period: structuredClone(period),
|
|
1448
|
+
actual: actual.amount,
|
|
1449
|
+
reserved: 0n,
|
|
1450
|
+
unknown: 0n,
|
|
1451
|
+
accountingStatus: actual.accountingStatus,
|
|
1452
|
+
updatedAt: new Date
|
|
1453
|
+
};
|
|
1454
|
+
this.periodStates.set(key2, state);
|
|
1455
|
+
return state;
|
|
1456
|
+
}
|
|
1457
|
+
moveEstimateCounter(reservation, counter, direction, updatedAt) {
|
|
1458
|
+
for (const bucket of reservation.buckets) {
|
|
1459
|
+
const amount = normalizeAiLimitAmount(bucket.estimate);
|
|
1460
|
+
const state = this.requirePeriodState(reservation.projectId, bucket.subject, amount, reservation.period);
|
|
1461
|
+
state[counter] += direction * amount.amount;
|
|
1462
|
+
if (state[counter] < 0n) {
|
|
1463
|
+
throw new Error(`[Sixb] In-memory AI limit ${counter} counter became negative.`);
|
|
1464
|
+
}
|
|
1465
|
+
state.updatedAt = new Date(updatedAt);
|
|
1466
|
+
}
|
|
1467
|
+
}
|
|
1468
|
+
reconcileEstimateCounters(reservation, entry, updatedAt) {
|
|
1469
|
+
for (const bucket of reservation.buckets) {
|
|
1470
|
+
const amount = normalizeAiLimitAmount(bucket.estimate);
|
|
1471
|
+
const state = this.requirePeriodState(reservation.projectId, bucket.subject, amount, reservation.period);
|
|
1472
|
+
const counter = reservation.state === "active" ? "reserved" : "unknown";
|
|
1473
|
+
const actual = resolveAiLimitActual([entry], amount);
|
|
1474
|
+
if (actual.accountingStatus === "complete") {
|
|
1475
|
+
state[counter] -= amount.amount;
|
|
1476
|
+
} else if (reservation.state === "active") {
|
|
1477
|
+
state.reserved -= amount.amount;
|
|
1478
|
+
state.unknown += amount.amount;
|
|
1479
|
+
}
|
|
1480
|
+
if (state.reserved < 0n || state.unknown < 0n) {
|
|
1481
|
+
throw new Error("[Sixb] In-memory AI limit reservation counter became negative.");
|
|
1482
|
+
}
|
|
1483
|
+
state.updatedAt = new Date(updatedAt);
|
|
1484
|
+
}
|
|
1485
|
+
}
|
|
1486
|
+
requirePeriodState(projectId, subject, amount, period) {
|
|
1487
|
+
const state = this.periodStates.get(periodStateKey(projectId, subject, amount, period));
|
|
1488
|
+
if (!state)
|
|
1489
|
+
throw new Error("[Sixb] In-memory AI limit period state is inconsistent.");
|
|
1490
|
+
return state;
|
|
1491
|
+
}
|
|
1492
|
+
async assertExecutionExists(projectId, executionId) {
|
|
1493
|
+
if (this.options.resolveExecution) {
|
|
1494
|
+
if (await this.options.resolveExecution({ projectId, executionId }))
|
|
1495
|
+
return;
|
|
1496
|
+
throw new AiLimitStorageError("missing_execution", `[Sixb] AI limit execution '${executionId}' does not exist in project '${projectId}'.`);
|
|
1497
|
+
}
|
|
1498
|
+
if (this.options.executionExists && await this.options.executionExists({ projectId, executionId })) {
|
|
1499
|
+
return;
|
|
1500
|
+
}
|
|
1501
|
+
throw new AiLimitStorageError("missing_execution", `[Sixb] AI limit execution '${executionId}' does not exist in project '${projectId}'.`);
|
|
1502
|
+
}
|
|
1503
|
+
async resolvePolicyActual(policy, period, dimension) {
|
|
1504
|
+
if (!this.options.listUsageRecords || (policy.subject.type === "user" || policy.subject.type === "serviceAccount") && !this.options.resolveExecution) {
|
|
1505
|
+
return { amount: 0n, accountingStatus: "unavailable" };
|
|
1506
|
+
}
|
|
1507
|
+
const records = await this.options.listUsageRecords({ projectId: policy.projectId });
|
|
1508
|
+
const entries = await Promise.all(records.filter((record) => record.occurredAt.getTime() >= period.start.getTime() && record.occurredAt.getTime() < period.end.getTime()).map((record) => this.accountingEntry(record)));
|
|
1509
|
+
return resolveAiLimitActual(entries.filter((entry) => aiLimitAccountingEntryAppliesToSubject(entry, policy.subject)), dimension);
|
|
1510
|
+
}
|
|
1511
|
+
async requireAccountingEntry(projectId, usageRecordId) {
|
|
1512
|
+
if (!this.options.resolveUsageRecord) {
|
|
1513
|
+
throw new AiLimitStorageError("unavailable_actuals", "[Sixb] In-memory AI limit storage has no immutable accounting source.");
|
|
1514
|
+
}
|
|
1515
|
+
const record = await this.options.resolveUsageRecord({ projectId, usageRecordId });
|
|
1516
|
+
if (!record) {
|
|
1517
|
+
throw new AiLimitStorageError("missing_usage_record", `[Sixb] AI usage record '${usageRecordId}' does not exist in project '${projectId}'.`);
|
|
1518
|
+
}
|
|
1519
|
+
return this.accountingEntry(record);
|
|
1520
|
+
}
|
|
1521
|
+
async accountingEntry(record) {
|
|
1522
|
+
const [execution, cost] = await Promise.all([
|
|
1523
|
+
this.options.resolveExecution?.({
|
|
1524
|
+
projectId: record.projectId,
|
|
1525
|
+
executionId: record.executionId
|
|
1526
|
+
}),
|
|
1527
|
+
this.options.resolveCostRecord?.({
|
|
1528
|
+
projectId: record.projectId,
|
|
1529
|
+
usageRecordId: record.id
|
|
1530
|
+
})
|
|
1531
|
+
]);
|
|
1532
|
+
const requester = execution?.requestedBy;
|
|
1533
|
+
return {
|
|
1534
|
+
projectId: record.projectId,
|
|
1535
|
+
usageRecordId: record.id,
|
|
1536
|
+
executionId: record.executionId,
|
|
1537
|
+
attempt: record.attempt,
|
|
1538
|
+
callId: record.callId,
|
|
1539
|
+
occurredAt: new Date(record.occurredAt),
|
|
1540
|
+
...record.usage.totalTokens === undefined ? {} : { totalTokens: record.usage.totalTokens },
|
|
1541
|
+
requesterGroupIds: [...record.requesterGroupIds],
|
|
1542
|
+
...requester?.type === "user" || requester?.type === "serviceAccount" ? { requester: { type: requester.type, id: requester.id } } : {},
|
|
1543
|
+
...cost?.status === "rated" ? { valuation: { status: "rated", money: structuredClone(cost.money) } } : cost ? { valuation: { status: "unavailable" } } : {}
|
|
1544
|
+
};
|
|
1545
|
+
}
|
|
1546
|
+
}
|
|
1547
|
+
function policyKey(projectId, id) {
|
|
1548
|
+
return JSON.stringify([projectId, id]);
|
|
1549
|
+
}
|
|
1550
|
+
function periodStateKey(projectId, subject, amount, period) {
|
|
1551
|
+
return JSON.stringify([
|
|
1552
|
+
projectId,
|
|
1553
|
+
aiLimitSubjectKey(subject),
|
|
1554
|
+
amount.meter,
|
|
1555
|
+
amount.currency,
|
|
1556
|
+
period.start.toISOString()
|
|
1557
|
+
]);
|
|
1558
|
+
}
|
|
1559
|
+
function validatePolicyIdentity(input) {
|
|
1560
|
+
assertNonBlank(input.projectId, "projectId");
|
|
1561
|
+
assertNonBlank(input.id, "policy id");
|
|
1562
|
+
}
|
|
1563
|
+
function missingPolicy(projectId, id) {
|
|
1564
|
+
return new AiLimitStorageError("missing_policy", `[Sixb] AI limit policy '${id}' does not exist in project '${projectId}'.`);
|
|
1565
|
+
}
|
|
1566
|
+
function missingReservation(identity) {
|
|
1567
|
+
return new AiLimitStorageError("missing_reservation", `[Sixb] AI model-call reservation '${identity.callId}' does not exist for execution '${identity.executionId}' attempt ${identity.attempt}.`);
|
|
1568
|
+
}
|
|
1569
|
+
function invalidState(reservation, operation) {
|
|
1570
|
+
return new AiLimitStorageError("invalid_reservation_state", `[Sixb] Cannot ${operation} AI model-call reservation '${reservation.callId}' in state '${reservation.state}'.`);
|
|
1571
|
+
}
|
|
1572
|
+
function replaceMap2(target, source) {
|
|
1573
|
+
target.clear();
|
|
1574
|
+
for (const [key2, value] of structuredClone(source))
|
|
1575
|
+
target.set(key2, value);
|
|
1576
|
+
}
|
|
1013
1577
|
// src/storage/connector-connections/in-memory.ts
|
|
1014
1578
|
import { timingSafeEqual } from "crypto";
|
|
1015
1579
|
function connectionRunBase(record, updatedAt) {
|
|
@@ -1699,10 +2263,10 @@ class InMemoryConnectorConnectionStorage {
|
|
|
1699
2263
|
};
|
|
1700
2264
|
}
|
|
1701
2265
|
restore(snapshot) {
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
2266
|
+
replaceMap3(this.attempts, snapshot.attempts);
|
|
2267
|
+
replaceMap3(this.connectionRuns, snapshot.connectionRuns);
|
|
2268
|
+
replaceMap3(this.authorizations, snapshot.authorizations);
|
|
2269
|
+
replaceMap3(this.connections, snapshot.connections);
|
|
1706
2270
|
}
|
|
1707
2271
|
now() {
|
|
1708
2272
|
return new Date(this.options.now?.() ?? new Date);
|
|
@@ -1803,7 +2367,7 @@ function safeEqual(left, right) {
|
|
|
1803
2367
|
function invalidRun() {
|
|
1804
2368
|
return new ConnectorConnectionStorageError("run_invalid", "[Sixb] Connector connection run is invalid, expired, or already used.");
|
|
1805
2369
|
}
|
|
1806
|
-
function
|
|
2370
|
+
function replaceMap3(target, source) {
|
|
1807
2371
|
target.clear();
|
|
1808
2372
|
for (const [key2, value] of structuredClone(source))
|
|
1809
2373
|
target.set(key2, value);
|
|
@@ -2071,9 +2635,11 @@ class InMemoryExecutionStorage {
|
|
|
2071
2635
|
auth;
|
|
2072
2636
|
rows = new Map;
|
|
2073
2637
|
runRootOperation;
|
|
2638
|
+
shareSessions;
|
|
2074
2639
|
constructor(auth, input = {}) {
|
|
2075
2640
|
this.auth = auth;
|
|
2076
2641
|
this.runRootOperation = input.runRootOperation ?? runDirectly2;
|
|
2642
|
+
this.shareSessions = input.shareSessions;
|
|
2077
2643
|
}
|
|
2078
2644
|
snapshot() {
|
|
2079
2645
|
return structuredClone(this.rows);
|
|
@@ -2096,7 +2662,8 @@ class InMemoryExecutionStorage {
|
|
|
2096
2662
|
getExecution: async ({ projectId, id }) => {
|
|
2097
2663
|
const existing = this.rows.get(executionKey(projectId, id));
|
|
2098
2664
|
return existing ? cloneExecutionRecord(existing) : null;
|
|
2099
|
-
}
|
|
2665
|
+
},
|
|
2666
|
+
getShareSession: async ({ projectId, id }) => await this.shareSessions?.getById({ projectId, id }) ?? null
|
|
2100
2667
|
});
|
|
2101
2668
|
this.rows.set(key2, cloneExecutionRecord(record));
|
|
2102
2669
|
return cloneExecutionRecord(record);
|
|
@@ -2110,21 +2677,80 @@ class InMemoryExecutionStorage {
|
|
|
2110
2677
|
}
|
|
2111
2678
|
}
|
|
2112
2679
|
|
|
2113
|
-
// src/objects/
|
|
2114
|
-
function
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2680
|
+
// src/storage/objects/keys.ts
|
|
2681
|
+
function objectBatchKey(objectTypeId, primaryId) {
|
|
2682
|
+
return JSON.stringify([objectTypeId, primaryId]);
|
|
2683
|
+
}
|
|
2684
|
+
function linkBatchKey(objectTypeId, objectId, linkId) {
|
|
2685
|
+
return JSON.stringify([objectTypeId, objectId, linkId]);
|
|
2686
|
+
}
|
|
2687
|
+
function objectLinkCursor(link) {
|
|
2688
|
+
return [link.sourceTypeId, link.sourceId, link.linkId, link.targetTypeId, link.targetId];
|
|
2689
|
+
}
|
|
2690
|
+
function compareObjectLinkCursors(left, right) {
|
|
2691
|
+
for (let index = 0;index < left.length; index += 1) {
|
|
2692
|
+
if (left[index] < right[index])
|
|
2693
|
+
return -1;
|
|
2694
|
+
if (left[index] > right[index])
|
|
2695
|
+
return 1;
|
|
2696
|
+
}
|
|
2697
|
+
return 0;
|
|
2698
|
+
}
|
|
2699
|
+
function compareObjectLinks(left, right) {
|
|
2700
|
+
return compareObjectLinkCursors(objectLinkCursor(left), objectLinkCursor(right));
|
|
2701
|
+
}
|
|
2702
|
+
|
|
2703
|
+
// src/storage/objects/in-memory/keys.ts
|
|
2704
|
+
function objectRowKey(projectId, objectTypeId) {
|
|
2705
|
+
return JSON.stringify([projectId, objectTypeId]);
|
|
2706
|
+
}
|
|
2707
|
+
function objectRowProjectPrefix(projectId) {
|
|
2708
|
+
return `[${JSON.stringify(projectId)},`;
|
|
2709
|
+
}
|
|
2710
|
+
function compareStrings(left, right) {
|
|
2711
|
+
if (left < right)
|
|
2712
|
+
return -1;
|
|
2713
|
+
if (left > right)
|
|
2714
|
+
return 1;
|
|
2715
|
+
return 0;
|
|
2716
|
+
}
|
|
2717
|
+
function sourceLinkBucketKey(projectId, sourceTypeId, sourceId) {
|
|
2718
|
+
return JSON.stringify([projectId, sourceTypeId, sourceId]);
|
|
2719
|
+
}
|
|
2720
|
+
function linkRowKey(linkId, targetTypeId, targetId) {
|
|
2721
|
+
return JSON.stringify([linkId, targetTypeId, targetId]);
|
|
2722
|
+
}
|
|
2723
|
+
function fullLinkRowKey(row) {
|
|
2724
|
+
return JSON.stringify([
|
|
2725
|
+
row.sourceTypeId,
|
|
2726
|
+
row.sourceId,
|
|
2727
|
+
row.linkId,
|
|
2728
|
+
row.targetTypeId,
|
|
2729
|
+
row.targetId
|
|
2730
|
+
]);
|
|
2731
|
+
}
|
|
2732
|
+
function rowIdentityKey(row) {
|
|
2733
|
+
return rowIdentityKeyParts(row.objectTypeId, row.primaryId);
|
|
2734
|
+
}
|
|
2735
|
+
function rowIdentityKeyParts(objectTypeId, primaryId) {
|
|
2736
|
+
return objectBatchKey(objectTypeId, primaryId);
|
|
2737
|
+
}
|
|
2738
|
+
|
|
2739
|
+
// src/objects/query/scalar-values.ts
|
|
2740
|
+
function compareQueryScalarValues(left, right, scalarKind) {
|
|
2741
|
+
if (left === undefined || right === undefined || left === null || right === null) {
|
|
2742
|
+
return Number.NaN;
|
|
2743
|
+
}
|
|
2744
|
+
if (scalarKind === undefined)
|
|
2745
|
+
return compareRuntimeValues(left, right);
|
|
2746
|
+
switch (scalarKind) {
|
|
2747
|
+
case "string":
|
|
2748
|
+
case "uuid":
|
|
2749
|
+
return typeof left === "string" && typeof right === "string" ? compareStrings2(left, right) : Number.NaN;
|
|
2750
|
+
case "boolean":
|
|
2751
|
+
return typeof left === "boolean" && typeof right === "boolean" ? Number(left) - Number(right) : Number.NaN;
|
|
2752
|
+
case "integer":
|
|
2753
|
+
case "double":
|
|
2128
2754
|
return typeof left === "number" && typeof right === "number" ? left - right : Number.NaN;
|
|
2129
2755
|
case "decimal":
|
|
2130
2756
|
return typeof left === "string" && typeof right === "string" ? compareDecimalValues(left, right) : Number.NaN;
|
|
@@ -2150,7 +2776,7 @@ function compareRuntimeValues(left, right) {
|
|
|
2150
2776
|
if (typeof left === "number" && typeof right === "number")
|
|
2151
2777
|
return left - right;
|
|
2152
2778
|
if (typeof left === "string" && typeof right === "string")
|
|
2153
|
-
return
|
|
2779
|
+
return compareStrings2(left, right);
|
|
2154
2780
|
if (typeof left === "boolean" && typeof right === "boolean") {
|
|
2155
2781
|
return Number(left) - Number(right);
|
|
2156
2782
|
}
|
|
@@ -2183,7 +2809,7 @@ function dateTime(value) {
|
|
|
2183
2809
|
}
|
|
2184
2810
|
return null;
|
|
2185
2811
|
}
|
|
2186
|
-
function
|
|
2812
|
+
function compareStrings2(left, right) {
|
|
2187
2813
|
if (left < right)
|
|
2188
2814
|
return -1;
|
|
2189
2815
|
if (left > right)
|
|
@@ -2191,30 +2817,7 @@ function compareStrings(left, right) {
|
|
|
2191
2817
|
return 0;
|
|
2192
2818
|
}
|
|
2193
2819
|
|
|
2194
|
-
// src/storage/objects/
|
|
2195
|
-
function objectBatchKey(objectTypeId, primaryId) {
|
|
2196
|
-
return JSON.stringify([objectTypeId, primaryId]);
|
|
2197
|
-
}
|
|
2198
|
-
function linkBatchKey(objectTypeId, objectId, linkId) {
|
|
2199
|
-
return JSON.stringify([objectTypeId, objectId, linkId]);
|
|
2200
|
-
}
|
|
2201
|
-
function objectLinkCursor(link) {
|
|
2202
|
-
return [link.sourceTypeId, link.sourceId, link.linkId, link.targetTypeId, link.targetId];
|
|
2203
|
-
}
|
|
2204
|
-
function compareObjectLinkCursors(left, right) {
|
|
2205
|
-
for (let index = 0;index < left.length; index += 1) {
|
|
2206
|
-
if (left[index] < right[index])
|
|
2207
|
-
return -1;
|
|
2208
|
-
if (left[index] > right[index])
|
|
2209
|
-
return 1;
|
|
2210
|
-
}
|
|
2211
|
-
return 0;
|
|
2212
|
-
}
|
|
2213
|
-
function compareObjectLinks(left, right) {
|
|
2214
|
-
return compareObjectLinkCursors(objectLinkCursor(left), objectLinkCursor(right));
|
|
2215
|
-
}
|
|
2216
|
-
|
|
2217
|
-
// src/storage/objects/in-memory.ts
|
|
2820
|
+
// src/storage/objects/in-memory/query.ts
|
|
2218
2821
|
var IN_MEMORY_OBJECT_QUERY_CAPABILITIES = {
|
|
2219
2822
|
queryObjects: true,
|
|
2220
2823
|
countObjects: true,
|
|
@@ -2275,538 +2878,185 @@ var IN_MEMORY_OBJECT_QUERY_CAPABILITIES = {
|
|
|
2275
2878
|
stablePageTokens: true
|
|
2276
2879
|
}
|
|
2277
2880
|
};
|
|
2278
|
-
|
|
2279
|
-
return JSON.stringify([projectId, objectTypeId]);
|
|
2280
|
-
}
|
|
2281
|
-
function objectRowProjectPrefix(projectId) {
|
|
2282
|
-
return `[${JSON.stringify(projectId)},`;
|
|
2283
|
-
}
|
|
2284
|
-
function compareStrings2(left, right) {
|
|
2285
|
-
if (left < right)
|
|
2286
|
-
return -1;
|
|
2287
|
-
if (left > right)
|
|
2288
|
-
return 1;
|
|
2289
|
-
return 0;
|
|
2290
|
-
}
|
|
2881
|
+
var PAGE_TOKEN_PREFIX = "offset:";
|
|
2291
2882
|
function assertLinkQueryLimit(limit) {
|
|
2292
2883
|
if (!Number.isSafeInteger(limit) || limit <= 0) {
|
|
2293
2884
|
throw new Error("Object link query limit must be a positive safe integer.");
|
|
2294
2885
|
}
|
|
2295
2886
|
}
|
|
2296
|
-
function
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2887
|
+
function evaluateObjectQuery(query, source) {
|
|
2888
|
+
switch (query.kind) {
|
|
2889
|
+
case "start":
|
|
2890
|
+
return evaluateStart(query.objectTypeId, source);
|
|
2891
|
+
case "refs":
|
|
2892
|
+
return evaluateRefs(query.refs, source);
|
|
2893
|
+
case "filter": {
|
|
2894
|
+
const input = evaluateObjectQuery(query.input, source);
|
|
2895
|
+
const entries = input.entries.filter((entry) => matchesPredicate(entry.row, query.predicate));
|
|
2896
|
+
return completeEvaluation(entries);
|
|
2897
|
+
}
|
|
2898
|
+
case "text": {
|
|
2899
|
+
const input = evaluateObjectQuery(query.input, source);
|
|
2900
|
+
const scoredEntries = input.entries.flatMap((entry) => {
|
|
2901
|
+
const score = textScore(entry.row, query.query, query.fields, query.fieldsByObjectType);
|
|
2902
|
+
return score > 0 ? [{ ...entry, score: entry.score + score }] : [];
|
|
2903
|
+
});
|
|
2904
|
+
return completeEvaluation(scoredEntries);
|
|
2905
|
+
}
|
|
2906
|
+
case "vector": {
|
|
2907
|
+
const input = evaluateObjectQuery(query.input, source);
|
|
2908
|
+
const scoredEntries = input.entries.flatMap((entry) => {
|
|
2909
|
+
const score = vectorSimilarity(entry.row.properties[query.propertyId], query.vector);
|
|
2910
|
+
return score === null ? [] : [{ ...entry, score: entry.score + score }];
|
|
2911
|
+
});
|
|
2912
|
+
scoredEntries.sort(compareEntriesByRelevance);
|
|
2913
|
+
const limit = Math.max(0, query.k);
|
|
2914
|
+
return {
|
|
2915
|
+
entries: scoredEntries.slice(0, limit),
|
|
2916
|
+
total: scoredEntries.length,
|
|
2917
|
+
hasMore: limit < scoredEntries.length
|
|
2918
|
+
};
|
|
2919
|
+
}
|
|
2920
|
+
case "traverse": {
|
|
2921
|
+
const input = evaluateObjectQuery(query.input, source);
|
|
2922
|
+
const entries = query.direction === "outgoing" ? traverseOutgoing(input.entries, query.linkId, source) : traverseIncoming(input.entries, query.linkId, query.sourceObjectTypeId, source);
|
|
2923
|
+
return completeEvaluation(entries);
|
|
2924
|
+
}
|
|
2925
|
+
case "set":
|
|
2926
|
+
return evaluateSet(query.op, query.inputs, source);
|
|
2927
|
+
case "sort": {
|
|
2928
|
+
const input = evaluateObjectQuery(query.input, source);
|
|
2929
|
+
return {
|
|
2930
|
+
...input,
|
|
2931
|
+
entries: sortEntries(input.entries, query.fields)
|
|
2932
|
+
};
|
|
2933
|
+
}
|
|
2934
|
+
case "limit": {
|
|
2935
|
+
const input = evaluateObjectQuery(query.input, source);
|
|
2936
|
+
const limit = Math.max(0, query.limit);
|
|
2937
|
+
return {
|
|
2938
|
+
entries: input.entries.slice(0, limit),
|
|
2939
|
+
total: input.entries.length,
|
|
2940
|
+
hasMore: limit < input.entries.length
|
|
2941
|
+
};
|
|
2942
|
+
}
|
|
2943
|
+
case "page": {
|
|
2944
|
+
const input = evaluateObjectQuery(query.input, source);
|
|
2945
|
+
const offset = decodePageOffset(query.pageToken);
|
|
2946
|
+
const pageSize = Math.max(0, query.pageSize);
|
|
2947
|
+
const nextOffset = offset + pageSize;
|
|
2948
|
+
const hasMore = pageSize > 0 && nextOffset < input.entries.length;
|
|
2949
|
+
return {
|
|
2950
|
+
entries: input.entries.slice(offset, nextOffset),
|
|
2951
|
+
total: input.entries.length,
|
|
2952
|
+
hasMore,
|
|
2953
|
+
nextPageToken: hasMore ? encodePageOffset(nextOffset) : undefined
|
|
2954
|
+
};
|
|
2955
|
+
}
|
|
2956
|
+
case "project": {
|
|
2957
|
+
const input = evaluateObjectQuery(query.input, source);
|
|
2958
|
+
if (!query.properties)
|
|
2959
|
+
return input;
|
|
2960
|
+
const properties = query.properties;
|
|
2961
|
+
return {
|
|
2962
|
+
...input,
|
|
2963
|
+
entries: input.entries.map((entry) => ({
|
|
2964
|
+
...entry,
|
|
2965
|
+
row: projectRow(entry.row, properties)
|
|
2966
|
+
}))
|
|
2967
|
+
};
|
|
2968
|
+
}
|
|
2969
|
+
case "expand":
|
|
2970
|
+
throw new Error("[Sixb] In-memory object storage does not support 'expand' execution yet");
|
|
2971
|
+
}
|
|
2310
2972
|
}
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2973
|
+
function evaluateStart(objectTypeId, source) {
|
|
2974
|
+
const rows = source.objectsOfType(objectTypeId);
|
|
2975
|
+
const entries = rows.map((row, index) => ({
|
|
2976
|
+
row,
|
|
2977
|
+
score: 0,
|
|
2978
|
+
order: index
|
|
2979
|
+
}));
|
|
2980
|
+
return completeEvaluation(entries);
|
|
2318
2981
|
}
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
if (!bucket)
|
|
2342
|
-
return;
|
|
2343
|
-
for (const row of bucket.values()) {
|
|
2344
|
-
if (row.linkId === linkId)
|
|
2345
|
-
visit(structuredClone(row));
|
|
2346
|
-
}
|
|
2982
|
+
function evaluateRefs(refs, source) {
|
|
2983
|
+
const seen = new Set;
|
|
2984
|
+
const entries = refs.flatMap((ref) => {
|
|
2985
|
+
const key2 = JSON.stringify([ref.objectTypeId, ref.primaryId]);
|
|
2986
|
+
if (seen.has(key2))
|
|
2987
|
+
return [];
|
|
2988
|
+
seen.add(key2);
|
|
2989
|
+
const row = source.getObject(ref.objectTypeId, ref.primaryId);
|
|
2990
|
+
return row ? [row] : [];
|
|
2991
|
+
}).sort((left, right) => compareStrings(left.objectTypeId, right.objectTypeId) || compareStrings(left.primaryId, right.primaryId)).map((row, order) => ({ row, score: 0, order }));
|
|
2992
|
+
return completeEvaluation(entries);
|
|
2993
|
+
}
|
|
2994
|
+
function evaluateSet(op, inputs, source) {
|
|
2995
|
+
const evaluations = inputs.map((input) => evaluateObjectQuery(input, source));
|
|
2996
|
+
const first = evaluations[0];
|
|
2997
|
+
if (!first)
|
|
2998
|
+
return completeEvaluation([]);
|
|
2999
|
+
if (op === "union") {
|
|
3000
|
+
const entriesByKey = new Map;
|
|
3001
|
+
for (const evaluation of evaluations) {
|
|
3002
|
+
for (const entry of evaluation.entries) {
|
|
3003
|
+
upsertEntry(entriesByKey, entry);
|
|
2347
3004
|
}
|
|
2348
|
-
});
|
|
2349
|
-
}
|
|
2350
|
-
snapshot() {
|
|
2351
|
-
return {
|
|
2352
|
-
rows: cloneObjectBuckets(this.rows),
|
|
2353
|
-
links: cloneLinkBuckets(this.links)
|
|
2354
|
-
};
|
|
2355
|
-
}
|
|
2356
|
-
restore(snapshot) {
|
|
2357
|
-
this.rows.clear();
|
|
2358
|
-
for (const [key2, bucket] of cloneObjectBuckets(snapshot.rows)) {
|
|
2359
|
-
this.rows.set(key2, bucket);
|
|
2360
3005
|
}
|
|
2361
|
-
|
|
2362
|
-
for (const [key2, bucket] of cloneLinkBuckets(snapshot.links)) {
|
|
2363
|
-
this.links.set(key2, bucket);
|
|
2364
|
-
}
|
|
2365
|
-
}
|
|
2366
|
-
getExactObjectRow(projectId, objectTypeId, primaryId) {
|
|
2367
|
-
const row = this.rows.get(objectRowKey(projectId, objectTypeId))?.get(primaryId);
|
|
2368
|
-
return row ? structuredClone(row) : null;
|
|
3006
|
+
return completeEvaluation([...entriesByKey.values()]);
|
|
2369
3007
|
}
|
|
2370
|
-
|
|
2371
|
-
const
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
const bucketId = objectRowKey(projectId, row.ref.objectTypeId);
|
|
2376
|
-
const bucket = this.rows.get(bucketId) ?? new Map;
|
|
2377
|
-
this.rows.set(bucketId, bucket);
|
|
2378
|
-
bucket.set(row.ref.primaryId, {
|
|
2379
|
-
projectId,
|
|
2380
|
-
objectTypeId: row.ref.objectTypeId,
|
|
2381
|
-
primaryId: row.ref.primaryId,
|
|
2382
|
-
properties: structuredClone(row.properties),
|
|
2383
|
-
createdAt: new Date(row.createdAt),
|
|
2384
|
-
updatedAt: new Date(row.updatedAt),
|
|
2385
|
-
version: row.version,
|
|
2386
|
-
lastCommitId: row.lastCommitId
|
|
3008
|
+
if (op === "intersect") {
|
|
3009
|
+
const otherKeySets = evaluations.slice(1).map((evaluation) => new Set(evaluation.entries.map((entry) => rowIdentityKey(entry.row))));
|
|
3010
|
+
const entries = first.entries.filter((entry) => {
|
|
3011
|
+
const key2 = rowIdentityKey(entry.row);
|
|
3012
|
+
return otherKeySets.every((keys) => keys.has(key2));
|
|
2387
3013
|
});
|
|
3014
|
+
return completeEvaluation(entries);
|
|
2388
3015
|
}
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
3016
|
+
const subtractKeys = new Set(evaluations.slice(1).flatMap((evaluation) => evaluation.entries.map((entry) => rowIdentityKey(entry.row))));
|
|
3017
|
+
return completeEvaluation(first.entries.filter((entry) => !subtractKeys.has(rowIdentityKey(entry.row))));
|
|
3018
|
+
}
|
|
3019
|
+
function traverseOutgoing(entries, linkId, source) {
|
|
3020
|
+
const resultsByKey = new Map;
|
|
3021
|
+
entries.forEach((entry, index) => {
|
|
3022
|
+
const links = [...source.outgoingLinks(entry.row.objectTypeId, entry.row.primaryId)];
|
|
3023
|
+
for (const link of links) {
|
|
3024
|
+
if (link.linkId !== linkId)
|
|
3025
|
+
continue;
|
|
3026
|
+
const target = source.getObject(link.targetTypeId, link.targetId);
|
|
3027
|
+
if (!target)
|
|
3028
|
+
continue;
|
|
3029
|
+
upsertEntry(resultsByKey, {
|
|
3030
|
+
row: target,
|
|
3031
|
+
score: entry.score,
|
|
3032
|
+
order: entry.order + index / 1e6
|
|
3033
|
+
});
|
|
3034
|
+
}
|
|
3035
|
+
});
|
|
3036
|
+
return [...resultsByKey.values()];
|
|
3037
|
+
}
|
|
3038
|
+
function traverseIncoming(entries, linkId, sourceObjectTypeId, source) {
|
|
3039
|
+
const inputEntriesByTarget = new Map(entries.map((entry) => [rowIdentityKey(entry.row), entry]));
|
|
3040
|
+
const resultsByKey = new Map;
|
|
3041
|
+
const links = [...source.allLinks()];
|
|
3042
|
+
for (const link of links) {
|
|
3043
|
+
if (link.projectId !== source.projectId || link.linkId !== linkId)
|
|
3044
|
+
continue;
|
|
3045
|
+
if (sourceObjectTypeId !== undefined && link.sourceTypeId !== sourceObjectTypeId)
|
|
3046
|
+
continue;
|
|
3047
|
+
const targetEntry = inputEntriesByTarget.get(rowIdentityKeyParts(link.targetTypeId, link.targetId));
|
|
3048
|
+
if (!targetEntry)
|
|
3049
|
+
continue;
|
|
3050
|
+
const row = source.getObject(link.sourceTypeId, link.sourceId);
|
|
3051
|
+
if (!row)
|
|
3052
|
+
continue;
|
|
3053
|
+
upsertEntry(resultsByKey, {
|
|
3054
|
+
row,
|
|
3055
|
+
score: targetEntry.score,
|
|
3056
|
+
order: targetEntry.order
|
|
2407
3057
|
});
|
|
2408
3058
|
}
|
|
2409
|
-
|
|
2410
|
-
this.deleteLinkRow(row.projectId, row.sourceTypeId, row.sourceId, row.linkId, row.targetTypeId, row.targetId);
|
|
2411
|
-
}
|
|
2412
|
-
queryCapabilities() {
|
|
2413
|
-
return IN_MEMORY_OBJECT_QUERY_CAPABILITIES;
|
|
2414
|
-
}
|
|
2415
|
-
async queryObjects(params) {
|
|
2416
|
-
const result = this.evaluateObjectQuery(params.projectId, params.query);
|
|
2417
|
-
return {
|
|
2418
|
-
objects: result.entries.map((entry) => entry.row),
|
|
2419
|
-
hasMore: result.hasMore,
|
|
2420
|
-
nextPageToken: result.nextPageToken,
|
|
2421
|
-
...params.includeTotal === false ? {} : { total: result.total }
|
|
2422
|
-
};
|
|
2423
|
-
}
|
|
2424
|
-
async countObjects(params) {
|
|
2425
|
-
return {
|
|
2426
|
-
count: this.evaluateObjectQuery(params.projectId, stripOuterRowShape(params.query)).total
|
|
2427
|
-
};
|
|
2428
|
-
}
|
|
2429
|
-
async existsObjects(params) {
|
|
2430
|
-
return {
|
|
2431
|
-
exists: this.evaluateObjectQuery(params.projectId, stripOuterRowShape(params.query)).total > 0
|
|
2432
|
-
};
|
|
2433
|
-
}
|
|
2434
|
-
async facetObjects(params) {
|
|
2435
|
-
const result = this.evaluateObjectQuery(params.projectId, stripOuterRowShape(params.query));
|
|
2436
|
-
return {
|
|
2437
|
-
facets: buildFacetResults(result.entries.map((entry) => entry.row), params.facets)
|
|
2438
|
-
};
|
|
2439
|
-
}
|
|
2440
|
-
evaluateObjectQuery(projectId, query) {
|
|
2441
|
-
switch (query.kind) {
|
|
2442
|
-
case "start":
|
|
2443
|
-
return this.evaluateStart(projectId, query.objectTypeId);
|
|
2444
|
-
case "refs":
|
|
2445
|
-
return this.evaluateRefs(projectId, query.refs);
|
|
2446
|
-
case "filter": {
|
|
2447
|
-
const input = this.evaluateObjectQuery(projectId, query.input);
|
|
2448
|
-
const entries = input.entries.filter((entry) => matchesPredicate(entry.row, query.predicate));
|
|
2449
|
-
return completeEvaluation(entries);
|
|
2450
|
-
}
|
|
2451
|
-
case "text": {
|
|
2452
|
-
const input = this.evaluateObjectQuery(projectId, query.input);
|
|
2453
|
-
const scoredEntries = input.entries.flatMap((entry) => {
|
|
2454
|
-
const score = textScore(entry.row, query.query, query.fields, query.fieldsByObjectType);
|
|
2455
|
-
return score > 0 ? [{ ...entry, score: entry.score + score }] : [];
|
|
2456
|
-
});
|
|
2457
|
-
return completeEvaluation(scoredEntries);
|
|
2458
|
-
}
|
|
2459
|
-
case "vector": {
|
|
2460
|
-
const input = this.evaluateObjectQuery(projectId, query.input);
|
|
2461
|
-
const scoredEntries = input.entries.flatMap((entry) => {
|
|
2462
|
-
const score = vectorSimilarity(entry.row.properties[query.propertyId], query.vector);
|
|
2463
|
-
return score === null ? [] : [{ ...entry, score: entry.score + score }];
|
|
2464
|
-
});
|
|
2465
|
-
scoredEntries.sort(compareEntriesByRelevance);
|
|
2466
|
-
const limit = Math.max(0, query.k);
|
|
2467
|
-
return {
|
|
2468
|
-
entries: scoredEntries.slice(0, limit),
|
|
2469
|
-
total: scoredEntries.length,
|
|
2470
|
-
hasMore: limit < scoredEntries.length
|
|
2471
|
-
};
|
|
2472
|
-
}
|
|
2473
|
-
case "traverse": {
|
|
2474
|
-
const input = this.evaluateObjectQuery(projectId, query.input);
|
|
2475
|
-
const entries = query.direction === "outgoing" ? this.traverseOutgoing(projectId, input.entries, query.linkId) : this.traverseIncoming(projectId, input.entries, query.linkId, query.sourceObjectTypeId);
|
|
2476
|
-
return completeEvaluation(entries);
|
|
2477
|
-
}
|
|
2478
|
-
case "set":
|
|
2479
|
-
return this.evaluateSet(projectId, query.op, query.inputs);
|
|
2480
|
-
case "sort": {
|
|
2481
|
-
const input = this.evaluateObjectQuery(projectId, query.input);
|
|
2482
|
-
return {
|
|
2483
|
-
...input,
|
|
2484
|
-
entries: sortEntries(input.entries, query.fields)
|
|
2485
|
-
};
|
|
2486
|
-
}
|
|
2487
|
-
case "limit": {
|
|
2488
|
-
const input = this.evaluateObjectQuery(projectId, query.input);
|
|
2489
|
-
const limit = Math.max(0, query.limit);
|
|
2490
|
-
return {
|
|
2491
|
-
entries: input.entries.slice(0, limit),
|
|
2492
|
-
total: input.entries.length,
|
|
2493
|
-
hasMore: limit < input.entries.length
|
|
2494
|
-
};
|
|
2495
|
-
}
|
|
2496
|
-
case "page": {
|
|
2497
|
-
const input = this.evaluateObjectQuery(projectId, query.input);
|
|
2498
|
-
const offset = decodePageOffset(query.pageToken);
|
|
2499
|
-
const pageSize = Math.max(0, query.pageSize);
|
|
2500
|
-
const nextOffset = offset + pageSize;
|
|
2501
|
-
const hasMore = pageSize > 0 && nextOffset < input.entries.length;
|
|
2502
|
-
return {
|
|
2503
|
-
entries: input.entries.slice(offset, nextOffset),
|
|
2504
|
-
total: input.entries.length,
|
|
2505
|
-
hasMore,
|
|
2506
|
-
nextPageToken: hasMore ? encodePageOffset(nextOffset) : undefined
|
|
2507
|
-
};
|
|
2508
|
-
}
|
|
2509
|
-
case "project": {
|
|
2510
|
-
const input = this.evaluateObjectQuery(projectId, query.input);
|
|
2511
|
-
if (!query.properties)
|
|
2512
|
-
return input;
|
|
2513
|
-
const properties = query.properties;
|
|
2514
|
-
return {
|
|
2515
|
-
...input,
|
|
2516
|
-
entries: input.entries.map((entry) => ({
|
|
2517
|
-
...entry,
|
|
2518
|
-
row: projectRow(entry.row, properties)
|
|
2519
|
-
}))
|
|
2520
|
-
};
|
|
2521
|
-
}
|
|
2522
|
-
case "expand":
|
|
2523
|
-
throw new Error("[Sixb] In-memory object storage does not support 'expand' execution yet");
|
|
2524
|
-
}
|
|
2525
|
-
}
|
|
2526
|
-
evaluateStart(projectId, objectTypeId) {
|
|
2527
|
-
const bucket = this.rows.get(objectRowKey(projectId, objectTypeId));
|
|
2528
|
-
const entries = [...bucket?.values() ?? []].map((row, index) => ({
|
|
2529
|
-
row,
|
|
2530
|
-
score: 0,
|
|
2531
|
-
order: index
|
|
2532
|
-
}));
|
|
2533
|
-
return completeEvaluation(entries);
|
|
2534
|
-
}
|
|
2535
|
-
evaluateRefs(projectId, refs) {
|
|
2536
|
-
const seen = new Set;
|
|
2537
|
-
const entries = refs.flatMap((ref) => {
|
|
2538
|
-
const key2 = JSON.stringify([ref.objectTypeId, ref.primaryId]);
|
|
2539
|
-
if (seen.has(key2))
|
|
2540
|
-
return [];
|
|
2541
|
-
seen.add(key2);
|
|
2542
|
-
const row = this.rows.get(objectRowKey(projectId, ref.objectTypeId))?.get(ref.primaryId);
|
|
2543
|
-
return row ? [row] : [];
|
|
2544
|
-
}).sort((left, right) => compareStrings2(left.objectTypeId, right.objectTypeId) || compareStrings2(left.primaryId, right.primaryId)).map((row, order) => ({ row, score: 0, order }));
|
|
2545
|
-
return completeEvaluation(entries);
|
|
2546
|
-
}
|
|
2547
|
-
evaluateSet(projectId, op, inputs) {
|
|
2548
|
-
const evaluations = inputs.map((input) => this.evaluateObjectQuery(projectId, input));
|
|
2549
|
-
const first = evaluations[0];
|
|
2550
|
-
if (!first)
|
|
2551
|
-
return completeEvaluation([]);
|
|
2552
|
-
if (op === "union") {
|
|
2553
|
-
const entriesByKey = new Map;
|
|
2554
|
-
for (const evaluation of evaluations) {
|
|
2555
|
-
for (const entry of evaluation.entries) {
|
|
2556
|
-
upsertEntry(entriesByKey, entry);
|
|
2557
|
-
}
|
|
2558
|
-
}
|
|
2559
|
-
return completeEvaluation([...entriesByKey.values()]);
|
|
2560
|
-
}
|
|
2561
|
-
if (op === "intersect") {
|
|
2562
|
-
const otherKeySets = evaluations.slice(1).map((evaluation) => new Set(evaluation.entries.map((entry) => rowIdentityKey(entry.row))));
|
|
2563
|
-
const entries = first.entries.filter((entry) => {
|
|
2564
|
-
const key2 = rowIdentityKey(entry.row);
|
|
2565
|
-
return otherKeySets.every((keys) => keys.has(key2));
|
|
2566
|
-
});
|
|
2567
|
-
return completeEvaluation(entries);
|
|
2568
|
-
}
|
|
2569
|
-
const subtractKeys = new Set(evaluations.slice(1).flatMap((evaluation) => evaluation.entries.map((entry) => rowIdentityKey(entry.row))));
|
|
2570
|
-
return completeEvaluation(first.entries.filter((entry) => !subtractKeys.has(rowIdentityKey(entry.row))));
|
|
2571
|
-
}
|
|
2572
|
-
traverseOutgoing(projectId, entries, linkId) {
|
|
2573
|
-
const resultsByKey = new Map;
|
|
2574
|
-
entries.forEach((entry, index) => {
|
|
2575
|
-
const bucket = this.links.get(sourceLinkBucketKey(projectId, entry.row.objectTypeId, entry.row.primaryId));
|
|
2576
|
-
if (!bucket)
|
|
2577
|
-
return;
|
|
2578
|
-
for (const link of bucket.values()) {
|
|
2579
|
-
if (link.linkId !== linkId)
|
|
2580
|
-
continue;
|
|
2581
|
-
const target = this.rows.get(objectRowKey(projectId, link.targetTypeId))?.get(link.targetId);
|
|
2582
|
-
if (!target)
|
|
2583
|
-
continue;
|
|
2584
|
-
upsertEntry(resultsByKey, {
|
|
2585
|
-
row: target,
|
|
2586
|
-
score: entry.score,
|
|
2587
|
-
order: entry.order + index / 1e6
|
|
2588
|
-
});
|
|
2589
|
-
}
|
|
2590
|
-
});
|
|
2591
|
-
return [...resultsByKey.values()];
|
|
2592
|
-
}
|
|
2593
|
-
traverseIncoming(projectId, entries, linkId, sourceObjectTypeId) {
|
|
2594
|
-
const inputEntriesByTarget = new Map(entries.map((entry) => [rowIdentityKey(entry.row), entry]));
|
|
2595
|
-
const resultsByKey = new Map;
|
|
2596
|
-
for (const bucket of this.links.values()) {
|
|
2597
|
-
for (const link of bucket.values()) {
|
|
2598
|
-
if (link.projectId !== projectId || link.linkId !== linkId)
|
|
2599
|
-
continue;
|
|
2600
|
-
if (sourceObjectTypeId !== undefined && link.sourceTypeId !== sourceObjectTypeId)
|
|
2601
|
-
continue;
|
|
2602
|
-
const targetEntry = inputEntriesByTarget.get(rowIdentityKeyParts(link.targetTypeId, link.targetId));
|
|
2603
|
-
if (!targetEntry)
|
|
2604
|
-
continue;
|
|
2605
|
-
const source = this.rows.get(objectRowKey(projectId, link.sourceTypeId))?.get(link.sourceId);
|
|
2606
|
-
if (!source)
|
|
2607
|
-
continue;
|
|
2608
|
-
upsertEntry(resultsByKey, {
|
|
2609
|
-
row: source,
|
|
2610
|
-
score: targetEntry.score,
|
|
2611
|
-
order: targetEntry.order
|
|
2612
|
-
});
|
|
2613
|
-
}
|
|
2614
|
-
}
|
|
2615
|
-
return [...resultsByKey.values()];
|
|
2616
|
-
}
|
|
2617
|
-
async getByPrimaryId(params) {
|
|
2618
|
-
const bucket = this.rows.get(objectRowKey(params.projectId, params.objectTypeId));
|
|
2619
|
-
if (!bucket)
|
|
2620
|
-
return null;
|
|
2621
|
-
return bucket.get(params.primaryId) ?? null;
|
|
2622
|
-
}
|
|
2623
|
-
async listLinks(params) {
|
|
2624
|
-
const direction = params.direction ?? "outgoing";
|
|
2625
|
-
const matches = (row) => !params.linkId || row.linkId === params.linkId;
|
|
2626
|
-
const rows = [];
|
|
2627
|
-
if (direction === "outgoing" || direction === "both") {
|
|
2628
|
-
const bucket = this.links.get(sourceLinkBucketKey(params.projectId, params.objectTypeId, params.objectId));
|
|
2629
|
-
if (bucket)
|
|
2630
|
-
rows.push(...[...bucket.values()].filter(matches));
|
|
2631
|
-
}
|
|
2632
|
-
if (direction === "incoming" || direction === "both") {
|
|
2633
|
-
for (const bucket of this.links.values()) {
|
|
2634
|
-
for (const row of bucket.values()) {
|
|
2635
|
-
if (row.projectId === params.projectId && row.targetTypeId === params.objectTypeId && row.targetId === params.objectId && matches(row)) {
|
|
2636
|
-
rows.push(row);
|
|
2637
|
-
}
|
|
2638
|
-
}
|
|
2639
|
-
}
|
|
2640
|
-
}
|
|
2641
|
-
if (direction !== "both")
|
|
2642
|
-
return rows;
|
|
2643
|
-
return [...new Map(rows.map((row) => [fullLinkRowKey(row), row])).values()];
|
|
2644
|
-
}
|
|
2645
|
-
async getByPrimaryIdBatch(params) {
|
|
2646
|
-
const result = new Map;
|
|
2647
|
-
for (const item of params.items) {
|
|
2648
|
-
const row = await this.getByPrimaryId({
|
|
2649
|
-
projectId: params.projectId,
|
|
2650
|
-
objectTypeId: item.objectTypeId,
|
|
2651
|
-
primaryId: item.primaryId
|
|
2652
|
-
});
|
|
2653
|
-
if (row) {
|
|
2654
|
-
result.set(objectBatchKey(item.objectTypeId, item.primaryId), row);
|
|
2655
|
-
}
|
|
2656
|
-
}
|
|
2657
|
-
return result;
|
|
2658
|
-
}
|
|
2659
|
-
async listLinksBatch(params) {
|
|
2660
|
-
const result = new Map;
|
|
2661
|
-
for (const item of params.items) {
|
|
2662
|
-
const rows = await this.listLinks({
|
|
2663
|
-
projectId: params.projectId,
|
|
2664
|
-
objectTypeId: item.objectTypeId,
|
|
2665
|
-
objectId: item.objectId,
|
|
2666
|
-
linkId: item.linkId
|
|
2667
|
-
});
|
|
2668
|
-
if (rows.length > 0) {
|
|
2669
|
-
result.set(linkBatchKey(item.objectTypeId, item.objectId, item.linkId), [...rows]);
|
|
2670
|
-
}
|
|
2671
|
-
}
|
|
2672
|
-
return result;
|
|
2673
|
-
}
|
|
2674
|
-
async queryLinks(params) {
|
|
2675
|
-
assertLinkQueryLimit(params.limit);
|
|
2676
|
-
if (params.objectRefs.length === 0 || params.endpointObjectTypeIds?.length === 0) {
|
|
2677
|
-
return { links: [], hasMore: false };
|
|
2678
|
-
}
|
|
2679
|
-
const allowedTypes = params.endpointObjectTypeIds ? new Set(params.endpointObjectTypeIds) : undefined;
|
|
2680
|
-
const deduped = new Map;
|
|
2681
|
-
for (const object of params.objectRefs) {
|
|
2682
|
-
const rows2 = await this.listLinks({
|
|
2683
|
-
projectId: params.projectId,
|
|
2684
|
-
objectTypeId: object.objectTypeId,
|
|
2685
|
-
objectId: object.primaryId,
|
|
2686
|
-
direction: params.direction,
|
|
2687
|
-
...params.linkId === undefined ? {} : { linkId: params.linkId }
|
|
2688
|
-
});
|
|
2689
|
-
for (const row of rows2) {
|
|
2690
|
-
if (allowedTypes && (!allowedTypes.has(row.sourceTypeId) || !allowedTypes.has(row.targetTypeId))) {
|
|
2691
|
-
continue;
|
|
2692
|
-
}
|
|
2693
|
-
if (params.after && compareObjectLinkCursors(objectLinkCursor(row), params.after) <= 0) {
|
|
2694
|
-
continue;
|
|
2695
|
-
}
|
|
2696
|
-
deduped.set(fullLinkRowKey(row), row);
|
|
2697
|
-
}
|
|
2698
|
-
}
|
|
2699
|
-
const rows = [...deduped.values()].sort(compareObjectLinks).slice(0, params.limit + 1);
|
|
2700
|
-
return { links: rows.slice(0, params.limit), hasMore: rows.length > params.limit };
|
|
2701
|
-
}
|
|
2702
|
-
async listIncidentLinksBatch(params) {
|
|
2703
|
-
const deduped = new Map;
|
|
2704
|
-
for (const item of params.items) {
|
|
2705
|
-
const rows = await this.listLinks({
|
|
2706
|
-
projectId: params.projectId,
|
|
2707
|
-
objectTypeId: item.objectTypeId,
|
|
2708
|
-
objectId: item.objectId,
|
|
2709
|
-
direction: "both"
|
|
2710
|
-
});
|
|
2711
|
-
for (const row of rows) {
|
|
2712
|
-
deduped.set(fullLinkRowKey(row), row);
|
|
2713
|
-
}
|
|
2714
|
-
}
|
|
2715
|
-
return [...deduped.values()];
|
|
2716
|
-
}
|
|
2717
|
-
async listByPrimaryIdPage(params) {
|
|
2718
|
-
assertReconciliationPageLimit(params.limit);
|
|
2719
|
-
const bucket = this.rows.get(objectRowKey(params.projectId, params.objectTypeId));
|
|
2720
|
-
const rows = [...bucket?.values() ?? []].filter((row) => !params.afterPrimaryId || compareStrings2(row.primaryId, params.afterPrimaryId) > 0).sort((left, right) => compareStrings2(left.primaryId, right.primaryId)).slice(0, params.limit + 1);
|
|
2721
|
-
const hasMore = rows.length > params.limit;
|
|
2722
|
-
const objects = rows.slice(0, params.limit).map((row) => structuredClone(row));
|
|
2723
|
-
const last = objects.at(-1);
|
|
2724
|
-
return {
|
|
2725
|
-
objects,
|
|
2726
|
-
...hasMore && last ? { nextPrimaryId: last.primaryId } : {}
|
|
2727
|
-
};
|
|
2728
|
-
}
|
|
2729
|
-
async list(params) {
|
|
2730
|
-
let allRows = [];
|
|
2731
|
-
if (params.objectTypeId) {
|
|
2732
|
-
const typeIds = Array.isArray(params.objectTypeId) ? params.objectTypeId : [params.objectTypeId];
|
|
2733
|
-
for (const typeId of typeIds) {
|
|
2734
|
-
const bucket = this.rows.get(objectRowKey(params.projectId, typeId));
|
|
2735
|
-
if (bucket) {
|
|
2736
|
-
allRows.push(...bucket.values());
|
|
2737
|
-
}
|
|
2738
|
-
}
|
|
2739
|
-
} else {
|
|
2740
|
-
for (const [key2, bucket] of this.rows) {
|
|
2741
|
-
if (key2.startsWith(objectRowProjectPrefix(params.projectId))) {
|
|
2742
|
-
allRows.push(...bucket.values());
|
|
2743
|
-
}
|
|
2744
|
-
}
|
|
2745
|
-
}
|
|
2746
|
-
const {
|
|
2747
|
-
primaryIdPrefix,
|
|
2748
|
-
primaryIdSuffix,
|
|
2749
|
-
updatedAfter,
|
|
2750
|
-
updatedBefore,
|
|
2751
|
-
createdAfter,
|
|
2752
|
-
createdBefore
|
|
2753
|
-
} = params;
|
|
2754
|
-
if (primaryIdPrefix || primaryIdSuffix || updatedAfter || updatedBefore || createdAfter || createdBefore) {
|
|
2755
|
-
allRows = allRows.filter((row) => (!primaryIdPrefix || row.primaryId.startsWith(primaryIdPrefix)) && (!primaryIdSuffix || row.primaryId.endsWith(primaryIdSuffix)) && (!updatedAfter || row.updatedAt >= updatedAfter) && (!updatedBefore || row.updatedAt <= updatedBefore) && (!createdAfter || row.createdAt >= createdAfter) && (!createdBefore || row.createdAt <= createdBefore));
|
|
2756
|
-
}
|
|
2757
|
-
const total = allRows.length;
|
|
2758
|
-
const offset = params.offset ?? 0;
|
|
2759
|
-
const limit = params.limit ?? 50;
|
|
2760
|
-
if (limit === 0)
|
|
2761
|
-
return { objects: [], hasMore: offset < total, total };
|
|
2762
|
-
const orderBy = params.orderBy ?? "updatedAt";
|
|
2763
|
-
const order = params.order ?? "desc";
|
|
2764
|
-
allRows.sort((a, b) => {
|
|
2765
|
-
let comparison = 0;
|
|
2766
|
-
switch (orderBy) {
|
|
2767
|
-
case "primaryId":
|
|
2768
|
-
comparison = a.primaryId.localeCompare(b.primaryId);
|
|
2769
|
-
break;
|
|
2770
|
-
case "createdAt":
|
|
2771
|
-
comparison = a.createdAt.getTime() - b.createdAt.getTime();
|
|
2772
|
-
break;
|
|
2773
|
-
default:
|
|
2774
|
-
comparison = a.updatedAt.getTime() - b.updatedAt.getTime();
|
|
2775
|
-
break;
|
|
2776
|
-
}
|
|
2777
|
-
return order === "desc" ? -comparison : comparison;
|
|
2778
|
-
});
|
|
2779
|
-
const objects = allRows.slice(offset, offset + limit);
|
|
2780
|
-
const hasMore = offset + limit < total;
|
|
2781
|
-
return { objects, hasMore, total };
|
|
2782
|
-
}
|
|
2783
|
-
deleteObjectRow(projectId, objectTypeId, primaryId) {
|
|
2784
|
-
const bucket = this.rows.get(objectRowKey(projectId, objectTypeId));
|
|
2785
|
-
bucket?.delete(primaryId);
|
|
2786
|
-
}
|
|
2787
|
-
deleteLinkRow(projectId, sourceTypeId, sourceId, linkId, targetTypeId, targetId) {
|
|
2788
|
-
const bucket = this.links.get(sourceLinkBucketKey(projectId, sourceTypeId, sourceId));
|
|
2789
|
-
bucket?.delete(linkRowKey(linkId, targetTypeId, targetId));
|
|
2790
|
-
}
|
|
2791
|
-
}
|
|
2792
|
-
function assertReconciliationPageLimit(limit) {
|
|
2793
|
-
if (!Number.isSafeInteger(limit) || limit <= 0) {
|
|
2794
|
-
throw new Error("Object reconciliation page limit must be a positive safe integer.");
|
|
2795
|
-
}
|
|
2796
|
-
}
|
|
2797
|
-
function cloneObjectBuckets(rows) {
|
|
2798
|
-
const clone2 = new Map;
|
|
2799
|
-
for (const [key2, bucket] of rows) {
|
|
2800
|
-
clone2.set(key2, new Map([...bucket.entries()].map(([primaryId, row]) => [primaryId, structuredClone(row)])));
|
|
2801
|
-
}
|
|
2802
|
-
return clone2;
|
|
2803
|
-
}
|
|
2804
|
-
function cloneLinkBuckets(links) {
|
|
2805
|
-
const clone2 = new Map;
|
|
2806
|
-
for (const [key2, bucket] of links) {
|
|
2807
|
-
clone2.set(key2, new Map([...bucket.entries()].map(([linkId, row]) => [linkId, structuredClone(row)])));
|
|
2808
|
-
}
|
|
2809
|
-
return clone2;
|
|
3059
|
+
return [...resultsByKey.values()];
|
|
2810
3060
|
}
|
|
2811
3061
|
function completeEvaluation(entries) {
|
|
2812
3062
|
return {
|
|
@@ -2928,117 +3178,771 @@ function compareSortField(left, right, field) {
|
|
|
2928
3178
|
const comparison2 = right.score - left.score;
|
|
2929
3179
|
return direction === "desc" ? comparison2 : -comparison2;
|
|
2930
3180
|
}
|
|
2931
|
-
const leftValue = left.row.properties[field.propertyId];
|
|
2932
|
-
const rightValue = right.row.properties[field.propertyId];
|
|
2933
|
-
const leftMissing = leftValue === undefined || leftValue === null;
|
|
2934
|
-
const rightMissing = rightValue === undefined || rightValue === null;
|
|
2935
|
-
if (leftMissing && rightMissing)
|
|
2936
|
-
return 0;
|
|
2937
|
-
if (leftMissing)
|
|
2938
|
-
return 1;
|
|
2939
|
-
if (rightMissing)
|
|
2940
|
-
return -1;
|
|
2941
|
-
const comparison = compareQueryScalarValues(leftValue, rightValue, field.scalarKind);
|
|
2942
|
-
if (Number.isNaN(comparison))
|
|
2943
|
-
return 0;
|
|
2944
|
-
return field.direction === "desc" ? -comparison : comparison;
|
|
2945
|
-
}
|
|
2946
|
-
function compareEntriesByRelevance(left, right) {
|
|
2947
|
-
return right.score - left.score || rowIdentityKey(left.row).localeCompare(rowIdentityKey(right.row));
|
|
2948
|
-
}
|
|
2949
|
-
function projectRow(row, properties) {
|
|
2950
|
-
const projected = {};
|
|
2951
|
-
for (const propertyId of properties) {
|
|
2952
|
-
if (Object.hasOwn(row.properties, propertyId)) {
|
|
2953
|
-
projected[propertyId] = row.properties[propertyId];
|
|
3181
|
+
const leftValue = left.row.properties[field.propertyId];
|
|
3182
|
+
const rightValue = right.row.properties[field.propertyId];
|
|
3183
|
+
const leftMissing = leftValue === undefined || leftValue === null;
|
|
3184
|
+
const rightMissing = rightValue === undefined || rightValue === null;
|
|
3185
|
+
if (leftMissing && rightMissing)
|
|
3186
|
+
return 0;
|
|
3187
|
+
if (leftMissing)
|
|
3188
|
+
return 1;
|
|
3189
|
+
if (rightMissing)
|
|
3190
|
+
return -1;
|
|
3191
|
+
const comparison = compareQueryScalarValues(leftValue, rightValue, field.scalarKind);
|
|
3192
|
+
if (Number.isNaN(comparison))
|
|
3193
|
+
return 0;
|
|
3194
|
+
return field.direction === "desc" ? -comparison : comparison;
|
|
3195
|
+
}
|
|
3196
|
+
function compareEntriesByRelevance(left, right) {
|
|
3197
|
+
return right.score - left.score || rowIdentityKey(left.row).localeCompare(rowIdentityKey(right.row));
|
|
3198
|
+
}
|
|
3199
|
+
function projectRow(row, properties) {
|
|
3200
|
+
const projected = {};
|
|
3201
|
+
for (const propertyId of properties) {
|
|
3202
|
+
if (Object.hasOwn(row.properties, propertyId)) {
|
|
3203
|
+
projected[propertyId] = row.properties[propertyId];
|
|
3204
|
+
}
|
|
3205
|
+
}
|
|
3206
|
+
return {
|
|
3207
|
+
...row,
|
|
3208
|
+
properties: projected
|
|
3209
|
+
};
|
|
3210
|
+
}
|
|
3211
|
+
function stripOuterRowShape(query) {
|
|
3212
|
+
switch (query.kind) {
|
|
3213
|
+
case "limit":
|
|
3214
|
+
case "page":
|
|
3215
|
+
case "project":
|
|
3216
|
+
case "sort":
|
|
3217
|
+
case "expand":
|
|
3218
|
+
return stripOuterRowShape(query.input);
|
|
3219
|
+
default:
|
|
3220
|
+
return query;
|
|
3221
|
+
}
|
|
3222
|
+
}
|
|
3223
|
+
function buildFacetResults(rows, facets) {
|
|
3224
|
+
return facets.map((facet) => ({
|
|
3225
|
+
propertyId: facet.propertyId,
|
|
3226
|
+
buckets: buildFacetBuckets(rows, facet)
|
|
3227
|
+
}));
|
|
3228
|
+
}
|
|
3229
|
+
function buildFacetBuckets(rows, facet) {
|
|
3230
|
+
const buckets = new Map;
|
|
3231
|
+
for (const row of rows) {
|
|
3232
|
+
if (!Object.hasOwn(row.properties, facet.propertyId))
|
|
3233
|
+
continue;
|
|
3234
|
+
const value = row.properties[facet.propertyId];
|
|
3235
|
+
if (value === undefined)
|
|
3236
|
+
continue;
|
|
3237
|
+
const key2 = facetValueKey(value);
|
|
3238
|
+
const existing = buckets.get(key2);
|
|
3239
|
+
if (existing) {
|
|
3240
|
+
existing.count += 1;
|
|
3241
|
+
} else {
|
|
3242
|
+
buckets.set(key2, { value, count: 1 });
|
|
3243
|
+
}
|
|
3244
|
+
}
|
|
3245
|
+
return [...buckets.values()].sort((left, right) => right.count - left.count || facetValueSortKey(left.value).localeCompare(facetValueSortKey(right.value))).slice(0, facet.limit);
|
|
3246
|
+
}
|
|
3247
|
+
function facetValueKey(value) {
|
|
3248
|
+
return JSON.stringify(value) ?? String(value);
|
|
3249
|
+
}
|
|
3250
|
+
function facetValueSortKey(value) {
|
|
3251
|
+
return JSON.stringify(value) ?? String(value);
|
|
3252
|
+
}
|
|
3253
|
+
async function queryLinksFrom(params, listLinks) {
|
|
3254
|
+
assertLinkQueryLimit(params.limit);
|
|
3255
|
+
if (params.objectRefs.length === 0 || params.endpointObjectTypeIds?.length === 0) {
|
|
3256
|
+
return { links: [], hasMore: false };
|
|
3257
|
+
}
|
|
3258
|
+
const allowedTypes = params.endpointObjectTypeIds ? new Set(params.endpointObjectTypeIds) : undefined;
|
|
3259
|
+
const deduped = new Map;
|
|
3260
|
+
for (const object of params.objectRefs) {
|
|
3261
|
+
const rows2 = await listLinks({
|
|
3262
|
+
projectId: params.projectId,
|
|
3263
|
+
objectTypeId: object.objectTypeId,
|
|
3264
|
+
objectId: object.primaryId,
|
|
3265
|
+
direction: params.direction,
|
|
3266
|
+
...params.linkId === undefined ? {} : { linkId: params.linkId }
|
|
3267
|
+
});
|
|
3268
|
+
for (const row of rows2) {
|
|
3269
|
+
if (allowedTypes && (!allowedTypes.has(row.sourceTypeId) || !allowedTypes.has(row.targetTypeId))) {
|
|
3270
|
+
continue;
|
|
3271
|
+
}
|
|
3272
|
+
if (params.after && compareObjectLinkCursors(objectLinkCursor(row), params.after) <= 0) {
|
|
3273
|
+
continue;
|
|
3274
|
+
}
|
|
3275
|
+
deduped.set(fullLinkRowKey(row), row);
|
|
3276
|
+
}
|
|
3277
|
+
}
|
|
3278
|
+
const rows = [...deduped.values()].sort(compareObjectLinks).slice(0, params.limit + 1);
|
|
3279
|
+
return { links: rows.slice(0, params.limit), hasMore: rows.length > params.limit };
|
|
3280
|
+
}
|
|
3281
|
+
function collectLinksBatch(source, params, cloneRows) {
|
|
3282
|
+
const direction = params.direction ?? "outgoing";
|
|
3283
|
+
const orderedKeys = [
|
|
3284
|
+
...new Set(params.items.map((item) => linkBatchKey(item.objectTypeId, item.objectId, item.linkId)))
|
|
3285
|
+
];
|
|
3286
|
+
const requestedKeys = new Set(orderedKeys);
|
|
3287
|
+
const grouped = new Map;
|
|
3288
|
+
const append = (key2, row) => {
|
|
3289
|
+
const bucket = grouped.get(key2) ?? new Map;
|
|
3290
|
+
bucket.set(fullLinkRowKey(row), row);
|
|
3291
|
+
grouped.set(key2, bucket);
|
|
3292
|
+
};
|
|
3293
|
+
if (direction === "outgoing" || direction === "both") {
|
|
3294
|
+
for (const item of params.items) {
|
|
3295
|
+
const key2 = linkBatchKey(item.objectTypeId, item.objectId, item.linkId);
|
|
3296
|
+
for (const row of source.outgoing(item)) {
|
|
3297
|
+
if (row.projectId === params.projectId && row.linkId === item.linkId)
|
|
3298
|
+
append(key2, row);
|
|
3299
|
+
}
|
|
3300
|
+
}
|
|
3301
|
+
}
|
|
3302
|
+
if (direction === "incoming" || direction === "both") {
|
|
3303
|
+
for (const row of source.all()) {
|
|
3304
|
+
if (row.projectId !== params.projectId)
|
|
3305
|
+
continue;
|
|
3306
|
+
const key2 = linkBatchKey(row.targetTypeId, row.targetId, row.linkId);
|
|
3307
|
+
if (requestedKeys.has(key2))
|
|
3308
|
+
append(key2, row);
|
|
3309
|
+
}
|
|
3310
|
+
}
|
|
3311
|
+
return new Map(orderedKeys.flatMap((key2) => {
|
|
3312
|
+
const bucket = grouped.get(key2);
|
|
3313
|
+
if (!bucket)
|
|
3314
|
+
return [];
|
|
3315
|
+
return [
|
|
3316
|
+
[key2, [...bucket.values()].map((row) => cloneRows ? structuredClone(row) : row)]
|
|
3317
|
+
];
|
|
3318
|
+
}));
|
|
3319
|
+
}
|
|
3320
|
+
function upsertEntry(entriesByKey, entry) {
|
|
3321
|
+
const key2 = rowIdentityKey(entry.row);
|
|
3322
|
+
const existing = entriesByKey.get(key2);
|
|
3323
|
+
if (!existing) {
|
|
3324
|
+
entriesByKey.set(key2, entry);
|
|
3325
|
+
return;
|
|
3326
|
+
}
|
|
3327
|
+
if (entry.score > existing.score) {
|
|
3328
|
+
entriesByKey.set(key2, {
|
|
3329
|
+
...existing,
|
|
3330
|
+
score: entry.score
|
|
3331
|
+
});
|
|
3332
|
+
}
|
|
3333
|
+
}
|
|
3334
|
+
function encodePageOffset(offset) {
|
|
3335
|
+
return `${PAGE_TOKEN_PREFIX}${offset}`;
|
|
3336
|
+
}
|
|
3337
|
+
function decodePageOffset(token) {
|
|
3338
|
+
if (!token)
|
|
3339
|
+
return 0;
|
|
3340
|
+
if (!token.startsWith(PAGE_TOKEN_PREFIX)) {
|
|
3341
|
+
throw new Error("[Sixb] Invalid object query page token");
|
|
3342
|
+
}
|
|
3343
|
+
const offset = Number(token.slice(PAGE_TOKEN_PREFIX.length));
|
|
3344
|
+
if (!Number.isInteger(offset) || offset < 0) {
|
|
3345
|
+
throw new Error("[Sixb] Invalid object query page token");
|
|
3346
|
+
}
|
|
3347
|
+
return offset;
|
|
3348
|
+
}
|
|
3349
|
+
function isPlainObject(value) {
|
|
3350
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3351
|
+
}
|
|
3352
|
+
|
|
3353
|
+
// src/storage/objects/in-memory/read-scope.ts
|
|
3354
|
+
function prepareReadPlan(scope) {
|
|
3355
|
+
const selectionsByNode = new Map;
|
|
3356
|
+
for (const selection of scope.objects) {
|
|
3357
|
+
const byType = selectionsByNode.get(selection.nodeId) ?? new Map;
|
|
3358
|
+
byType.set(selection.objectTypeId, new Set(selection.propertyIds));
|
|
3359
|
+
selectionsByNode.set(selection.nodeId, byType);
|
|
3360
|
+
}
|
|
3361
|
+
const steps = [...scope.steps].sort((left, right) => left.parentNodeId - right.parentNodeId || left.nodeId - right.nodeId || left.sourceObjectTypeId.localeCompare(right.sourceObjectTypeId) || left.linkId.localeCompare(right.linkId) || left.targetObjectTypeId.localeCompare(right.targetObjectTypeId));
|
|
3362
|
+
return {
|
|
3363
|
+
roots: scope.roots,
|
|
3364
|
+
selectionsByNode,
|
|
3365
|
+
steps
|
|
3366
|
+
};
|
|
3367
|
+
}
|
|
3368
|
+
function resolveSelectedReadUniverse(source, plan, limits) {
|
|
3369
|
+
const reachableByNode = new Map;
|
|
3370
|
+
const rawObjects = new Map;
|
|
3371
|
+
const objectProperties = new Map;
|
|
3372
|
+
const authorizedLinks = new Map;
|
|
3373
|
+
let traversalFacts = 0;
|
|
3374
|
+
const consumeTraversalFact = () => {
|
|
3375
|
+
traversalFacts += 1;
|
|
3376
|
+
if (traversalFacts > limits.maxTraversalFacts) {
|
|
3377
|
+
throw new ObjectReadLimitExceededError("traversalFacts", limits.maxTraversalFacts);
|
|
3378
|
+
}
|
|
3379
|
+
};
|
|
3380
|
+
const addReachable = (nodeId, row) => {
|
|
3381
|
+
const selectedProperties = plan.selectionsByNode.get(nodeId)?.get(row.objectTypeId);
|
|
3382
|
+
if (!selectedProperties)
|
|
3383
|
+
return;
|
|
3384
|
+
const key2 = rowIdentityKey(row);
|
|
3385
|
+
const reachable = reachableByNode.get(nodeId) ?? new Map;
|
|
3386
|
+
reachable.set(key2, row);
|
|
3387
|
+
reachableByNode.set(nodeId, reachable);
|
|
3388
|
+
rawObjects.set(key2, row);
|
|
3389
|
+
unionInto(objectProperties, key2, selectedProperties);
|
|
3390
|
+
};
|
|
3391
|
+
for (const root of plan.roots) {
|
|
3392
|
+
const row = source.getObject(root.objectTypeId, root.primaryId);
|
|
3393
|
+
if (row) {
|
|
3394
|
+
consumeTraversalFact();
|
|
3395
|
+
addReachable(root.nodeId, row);
|
|
3396
|
+
}
|
|
3397
|
+
}
|
|
3398
|
+
for (const step of plan.steps) {
|
|
3399
|
+
const parents = reachableByNode.get(step.parentNodeId);
|
|
3400
|
+
if (!parents)
|
|
3401
|
+
continue;
|
|
3402
|
+
for (const parent of parents.values()) {
|
|
3403
|
+
if (parent.objectTypeId !== step.sourceObjectTypeId)
|
|
3404
|
+
continue;
|
|
3405
|
+
for (const link of source.outgoingLinks(parent.objectTypeId, parent.primaryId)) {
|
|
3406
|
+
if (link.linkId !== step.linkId || link.targetTypeId !== step.targetObjectTypeId) {
|
|
3407
|
+
continue;
|
|
3408
|
+
}
|
|
3409
|
+
const target = source.getObject(link.targetTypeId, link.targetId);
|
|
3410
|
+
if (!target)
|
|
3411
|
+
continue;
|
|
3412
|
+
consumeTraversalFact();
|
|
3413
|
+
addReachable(step.nodeId, target);
|
|
3414
|
+
const linkKey = fullLinkRowKey(link);
|
|
3415
|
+
const selected = authorizedLinks.get(linkKey);
|
|
3416
|
+
if (selected) {
|
|
3417
|
+
for (const propertyId of step.propertyIds)
|
|
3418
|
+
selected.propertyIds.add(propertyId);
|
|
3419
|
+
} else {
|
|
3420
|
+
authorizedLinks.set(linkKey, {
|
|
3421
|
+
row: link,
|
|
3422
|
+
propertyIds: new Set(step.propertyIds)
|
|
3423
|
+
});
|
|
3424
|
+
}
|
|
3425
|
+
}
|
|
3426
|
+
}
|
|
3427
|
+
}
|
|
3428
|
+
const objects = new Map;
|
|
3429
|
+
for (const [key2, propertyIds] of objectProperties) {
|
|
3430
|
+
const row = rawObjects.get(key2);
|
|
3431
|
+
if (row)
|
|
3432
|
+
objects.set(key2, redactObjectRow(row, propertyIds));
|
|
3433
|
+
}
|
|
3434
|
+
const links = new Map;
|
|
3435
|
+
for (const [key2, selected] of authorizedLinks) {
|
|
3436
|
+
if (!objects.has(rowIdentityKeyParts(selected.row.sourceTypeId, selected.row.sourceId)) || !objects.has(rowIdentityKeyParts(selected.row.targetTypeId, selected.row.targetId))) {
|
|
3437
|
+
continue;
|
|
3438
|
+
}
|
|
3439
|
+
links.set(key2, redactLinkRow(selected.row, selected.propertyIds));
|
|
3440
|
+
}
|
|
3441
|
+
return createReadUniverse(source.projectId, objects, links, objectProperties);
|
|
3442
|
+
}
|
|
3443
|
+
function createReadUniverse(projectId, objects, links, objectProperties) {
|
|
3444
|
+
const linksBySource = new Map;
|
|
3445
|
+
for (const link of links.values()) {
|
|
3446
|
+
const key2 = sourceLinkBucketKey(link.projectId, link.sourceTypeId, link.sourceId);
|
|
3447
|
+
const bucket = linksBySource.get(key2) ?? [];
|
|
3448
|
+
bucket.push(link);
|
|
3449
|
+
linksBySource.set(key2, bucket);
|
|
3450
|
+
}
|
|
3451
|
+
return {
|
|
3452
|
+
projectId,
|
|
3453
|
+
objects,
|
|
3454
|
+
links,
|
|
3455
|
+
linksBySource,
|
|
3456
|
+
objectProperties,
|
|
3457
|
+
objectsOfType: (objectTypeId) => [...objects.values()].filter((row) => row.objectTypeId === objectTypeId),
|
|
3458
|
+
getObject: (objectTypeId, primaryId) => objects.get(rowIdentityKeyParts(objectTypeId, primaryId)),
|
|
3459
|
+
outgoingLinks: (objectTypeId, primaryId) => linksBySource.get(sourceLinkBucketKey(projectId, objectTypeId, primaryId)) ?? [],
|
|
3460
|
+
allLinks: () => links.values()
|
|
3461
|
+
};
|
|
3462
|
+
}
|
|
3463
|
+
function unionInto(target, key2, values) {
|
|
3464
|
+
const union = target.get(key2) ?? new Set;
|
|
3465
|
+
for (const value of values)
|
|
3466
|
+
union.add(value);
|
|
3467
|
+
target.set(key2, union);
|
|
3468
|
+
}
|
|
3469
|
+
function redactObjectRow(row, propertyIds) {
|
|
3470
|
+
const clone2 = structuredClone(row);
|
|
3471
|
+
delete clone2.links;
|
|
3472
|
+
clone2.properties = redactProperties(clone2.properties, propertyIds);
|
|
3473
|
+
return clone2;
|
|
3474
|
+
}
|
|
3475
|
+
function redactLinkRow(row, propertyIds) {
|
|
3476
|
+
const clone2 = structuredClone(row);
|
|
3477
|
+
const properties = redactProperties(clone2.properties ?? {}, propertyIds);
|
|
3478
|
+
if (Object.keys(properties).length === 0) {
|
|
3479
|
+
delete clone2.properties;
|
|
3480
|
+
} else {
|
|
3481
|
+
clone2.properties = properties;
|
|
3482
|
+
}
|
|
3483
|
+
return clone2;
|
|
3484
|
+
}
|
|
3485
|
+
function redactProperties(properties, propertyIds) {
|
|
3486
|
+
return Object.fromEntries([...propertyIds].filter((propertyId) => Object.hasOwn(properties, propertyId)).map((propertyId) => [propertyId, properties[propertyId]]));
|
|
3487
|
+
}
|
|
3488
|
+
|
|
3489
|
+
// src/storage/objects/in-memory/selected-reader.ts
|
|
3490
|
+
function createInMemorySelectedReader(source, params, queryCapabilities) {
|
|
3491
|
+
const projectId = source.projectId;
|
|
3492
|
+
const plan = prepareReadPlan(params.scope);
|
|
3493
|
+
const limits = snapshotObjectReadExecutionLimits(params.limits);
|
|
3494
|
+
const assertProject = (actualProjectId) => assertObjectReaderProject(projectId, actualProjectId);
|
|
3495
|
+
const visible = (value) => {
|
|
3496
|
+
assertObjectReadOutputWithinLimit(value, limits);
|
|
3497
|
+
return value;
|
|
3498
|
+
};
|
|
3499
|
+
const visibleMap = (value) => {
|
|
3500
|
+
assertObjectReadOutputWithinLimit([...value.entries()], limits);
|
|
3501
|
+
return value;
|
|
3502
|
+
};
|
|
3503
|
+
const selectsObjectProperties = async (input) => {
|
|
3504
|
+
assertProject(input.projectId);
|
|
3505
|
+
const universe = resolveSelectedReadUniverse(source, plan, limits);
|
|
3506
|
+
return visible(input.items.map((item) => {
|
|
3507
|
+
const key2 = rowIdentityKeyParts(item.objectTypeId, item.primaryId);
|
|
3508
|
+
if (!universe.objects.has(key2))
|
|
3509
|
+
return false;
|
|
3510
|
+
return universe.objectProperties.get(key2)?.has(item.propertyId) ?? false;
|
|
3511
|
+
}));
|
|
3512
|
+
};
|
|
3513
|
+
return Object.freeze({
|
|
3514
|
+
queryCapabilities,
|
|
3515
|
+
queryObjects: async (input) => {
|
|
3516
|
+
assertProject(input.projectId);
|
|
3517
|
+
const universe = resolveSelectedReadUniverse(source, plan, limits);
|
|
3518
|
+
const result = evaluateObjectQuery(input.query, universe);
|
|
3519
|
+
return visible({
|
|
3520
|
+
objects: result.entries.map((entry) => structuredClone(entry.row)),
|
|
3521
|
+
hasMore: result.hasMore,
|
|
3522
|
+
nextPageToken: result.nextPageToken,
|
|
3523
|
+
...input.includeTotal === false ? {} : { total: result.total }
|
|
3524
|
+
});
|
|
3525
|
+
},
|
|
3526
|
+
countObjects: async (input) => {
|
|
3527
|
+
assertProject(input.projectId);
|
|
3528
|
+
const universe = resolveSelectedReadUniverse(source, plan, limits);
|
|
3529
|
+
return visible({
|
|
3530
|
+
count: evaluateObjectQuery(stripOuterRowShape(input.query), universe).total
|
|
3531
|
+
});
|
|
3532
|
+
},
|
|
3533
|
+
existsObjects: async (input) => {
|
|
3534
|
+
assertProject(input.projectId);
|
|
3535
|
+
const universe = resolveSelectedReadUniverse(source, plan, limits);
|
|
3536
|
+
return visible({
|
|
3537
|
+
exists: evaluateObjectQuery(stripOuterRowShape(input.query), universe).total > 0
|
|
3538
|
+
});
|
|
3539
|
+
},
|
|
3540
|
+
facetObjects: async (input) => {
|
|
3541
|
+
assertProject(input.projectId);
|
|
3542
|
+
assertObjectReadFacetCount(input.facets.length);
|
|
3543
|
+
const universe = resolveSelectedReadUniverse(source, plan, limits);
|
|
3544
|
+
const result = evaluateObjectQuery(stripOuterRowShape(input.query), universe);
|
|
3545
|
+
return visible(structuredClone({
|
|
3546
|
+
facets: buildFacetResults(result.entries.map((entry) => entry.row), input.facets)
|
|
3547
|
+
}));
|
|
3548
|
+
},
|
|
3549
|
+
getByPrimaryId: async (input) => {
|
|
3550
|
+
assertProject(input.projectId);
|
|
3551
|
+
const universe = resolveSelectedReadUniverse(source, plan, limits);
|
|
3552
|
+
const row = universe.objects.get(rowIdentityKeyParts(input.objectTypeId, input.primaryId));
|
|
3553
|
+
return visible(row ? structuredClone(row) : null);
|
|
3554
|
+
},
|
|
3555
|
+
selectsObjectProperties,
|
|
3556
|
+
listLinks: async (input) => {
|
|
3557
|
+
assertProject(input.projectId);
|
|
3558
|
+
const universe = resolveSelectedReadUniverse(source, plan, limits);
|
|
3559
|
+
return visible(listUniverseLinks(universe, input).map((row) => structuredClone(row)));
|
|
3560
|
+
},
|
|
3561
|
+
getByPrimaryIdBatch: async (input) => {
|
|
3562
|
+
assertProject(input.projectId);
|
|
3563
|
+
const universe = resolveSelectedReadUniverse(source, plan, limits);
|
|
3564
|
+
const rows = new Map;
|
|
3565
|
+
for (const item of input.items) {
|
|
3566
|
+
const row = universe.objects.get(rowIdentityKeyParts(item.objectTypeId, item.primaryId));
|
|
3567
|
+
if (row) {
|
|
3568
|
+
rows.set(objectBatchKey(item.objectTypeId, item.primaryId), structuredClone(row));
|
|
3569
|
+
}
|
|
3570
|
+
}
|
|
3571
|
+
return visibleMap(rows);
|
|
3572
|
+
},
|
|
3573
|
+
listLinksBatch: async (input) => {
|
|
3574
|
+
assertProject(input.projectId);
|
|
3575
|
+
const universe = resolveSelectedReadUniverse(source, plan, limits);
|
|
3576
|
+
return visibleMap(collectLinksBatch({
|
|
3577
|
+
all: () => universe.links.values(),
|
|
3578
|
+
outgoing: (item) => universe.linksBySource.get(sourceLinkBucketKey(projectId, item.objectTypeId, item.objectId)) ?? []
|
|
3579
|
+
}, input, true));
|
|
3580
|
+
},
|
|
3581
|
+
queryLinks: async (input) => {
|
|
3582
|
+
assertProject(input.projectId);
|
|
3583
|
+
const universe = resolveSelectedReadUniverse(source, plan, limits);
|
|
3584
|
+
return visible(structuredClone(await queryLinksFrom(input, (item) => listUniverseLinks(universe, item))));
|
|
3585
|
+
},
|
|
3586
|
+
list: async (input) => {
|
|
3587
|
+
assertProject(input.projectId);
|
|
3588
|
+
const universe = resolveSelectedReadUniverse(source, plan, limits);
|
|
3589
|
+
return visible(listRows(input, [...universe.objects.values()]));
|
|
3590
|
+
}
|
|
3591
|
+
});
|
|
3592
|
+
}
|
|
3593
|
+
function listUniverseLinks(universe, params) {
|
|
3594
|
+
const direction = params.direction ?? "outgoing";
|
|
3595
|
+
const matches = (row) => !params.linkId || row.linkId === params.linkId;
|
|
3596
|
+
const rows = [];
|
|
3597
|
+
if (direction === "outgoing" || direction === "both") {
|
|
3598
|
+
const outgoing = universe.linksBySource.get(sourceLinkBucketKey(params.projectId, params.objectTypeId, params.objectId));
|
|
3599
|
+
if (outgoing)
|
|
3600
|
+
rows.push(...outgoing.filter(matches));
|
|
3601
|
+
}
|
|
3602
|
+
if (direction === "incoming" || direction === "both") {
|
|
3603
|
+
for (const row of universe.links.values()) {
|
|
3604
|
+
if (row.targetTypeId === params.objectTypeId && row.targetId === params.objectId && matches(row)) {
|
|
3605
|
+
rows.push(row);
|
|
3606
|
+
}
|
|
3607
|
+
}
|
|
3608
|
+
}
|
|
3609
|
+
if (direction !== "both")
|
|
3610
|
+
return rows;
|
|
3611
|
+
return [...new Map(rows.map((row) => [fullLinkRowKey(row), row])).values()];
|
|
3612
|
+
}
|
|
3613
|
+
function listRows(params, candidates) {
|
|
3614
|
+
const requestedTypes = params.objectTypeId === undefined ? undefined : new Set(typeof params.objectTypeId === "string" ? [params.objectTypeId] : params.objectTypeId);
|
|
3615
|
+
let rows = candidates.filter((row) => row.projectId === params.projectId && (!requestedTypes || requestedTypes.has(row.objectTypeId)));
|
|
3616
|
+
rows = rows.filter((row) => (!params.primaryIdPrefix || row.primaryId.startsWith(params.primaryIdPrefix)) && (!params.primaryIdSuffix || row.primaryId.endsWith(params.primaryIdSuffix)) && (!params.updatedAfter || row.updatedAt >= params.updatedAfter) && (!params.updatedBefore || row.updatedAt <= params.updatedBefore) && (!params.createdAfter || row.createdAt >= params.createdAfter) && (!params.createdBefore || row.createdAt <= params.createdBefore));
|
|
3617
|
+
const total = rows.length;
|
|
3618
|
+
const offset = params.offset ?? 0;
|
|
3619
|
+
const limit = params.limit ?? 50;
|
|
3620
|
+
if (limit === 0)
|
|
3621
|
+
return { objects: [], hasMore: offset < total, total };
|
|
3622
|
+
const orderBy = params.orderBy ?? "updatedAt";
|
|
3623
|
+
const order = params.order ?? "desc";
|
|
3624
|
+
rows.sort((left, right) => {
|
|
3625
|
+
const comparison = orderBy === "primaryId" ? left.primaryId.localeCompare(right.primaryId) : orderBy === "createdAt" ? left.createdAt.getTime() - right.createdAt.getTime() : left.updatedAt.getTime() - right.updatedAt.getTime();
|
|
3626
|
+
return order === "desc" ? -comparison : comparison;
|
|
3627
|
+
});
|
|
3628
|
+
const objects = rows.slice(offset, offset + limit).map((row) => structuredClone(row));
|
|
3629
|
+
return {
|
|
3630
|
+
objects,
|
|
3631
|
+
hasMore: offset + limit < total,
|
|
3632
|
+
total
|
|
3633
|
+
};
|
|
3634
|
+
}
|
|
3635
|
+
|
|
3636
|
+
// src/storage/objects/in-memory/storage.ts
|
|
3637
|
+
var materializerAdapters = new WeakMap;
|
|
3638
|
+
function getInMemoryObjectMaterializerAdapter(storage) {
|
|
3639
|
+
const adapter = materializerAdapters.get(storage);
|
|
3640
|
+
if (!adapter)
|
|
3641
|
+
throw new Error("[Sixb] In-memory object materializer adapter is unavailable.");
|
|
3642
|
+
return adapter;
|
|
3643
|
+
}
|
|
3644
|
+
|
|
3645
|
+
class InMemoryObjectStorage {
|
|
3646
|
+
rows = new Map;
|
|
3647
|
+
links = new Map;
|
|
3648
|
+
constructor() {
|
|
3649
|
+
materializerAdapters.set(this, {
|
|
3650
|
+
getExactObjectRow: (projectId, objectTypeId, primaryId) => this.getExactObjectRow(projectId, objectTypeId, primaryId),
|
|
3651
|
+
getExactLinkRow: (projectId, ref) => this.getExactLinkRow(projectId, ref),
|
|
3652
|
+
applyExactObject: (row, projectId) => this.applyExactObject(row, projectId),
|
|
3653
|
+
deleteExactObject: (projectId, objectTypeId, primaryId) => this.deleteExactObject(projectId, objectTypeId, primaryId),
|
|
3654
|
+
applyExactLink: (row, projectId) => this.applyExactLink(row, projectId),
|
|
3655
|
+
deleteExactLink: (row) => this.deleteExactLink(row),
|
|
3656
|
+
visitExactLinks: (projectId, visit) => {
|
|
3657
|
+
for (const bucket of this.links.values()) {
|
|
3658
|
+
for (const row of bucket.values()) {
|
|
3659
|
+
if (row.projectId === projectId)
|
|
3660
|
+
visit(structuredClone(row));
|
|
3661
|
+
}
|
|
3662
|
+
}
|
|
3663
|
+
},
|
|
3664
|
+
visitExactScopeLinks: (projectId, sourceTypeId, sourceId, linkId, visit) => {
|
|
3665
|
+
const bucket = this.links.get(sourceLinkBucketKey(projectId, sourceTypeId, sourceId));
|
|
3666
|
+
if (!bucket)
|
|
3667
|
+
return;
|
|
3668
|
+
for (const row of bucket.values()) {
|
|
3669
|
+
if (row.linkId === linkId)
|
|
3670
|
+
visit(structuredClone(row));
|
|
3671
|
+
}
|
|
3672
|
+
}
|
|
3673
|
+
});
|
|
3674
|
+
}
|
|
3675
|
+
snapshot() {
|
|
3676
|
+
return {
|
|
3677
|
+
rows: cloneObjectBuckets(this.rows),
|
|
3678
|
+
links: cloneLinkBuckets(this.links)
|
|
3679
|
+
};
|
|
3680
|
+
}
|
|
3681
|
+
restore(snapshot) {
|
|
3682
|
+
this.rows.clear();
|
|
3683
|
+
for (const [key2, bucket] of cloneObjectBuckets(snapshot.rows)) {
|
|
3684
|
+
this.rows.set(key2, bucket);
|
|
3685
|
+
}
|
|
3686
|
+
this.links.clear();
|
|
3687
|
+
for (const [key2, bucket] of cloneLinkBuckets(snapshot.links)) {
|
|
3688
|
+
this.links.set(key2, bucket);
|
|
3689
|
+
}
|
|
3690
|
+
}
|
|
3691
|
+
getExactObjectRow(projectId, objectTypeId, primaryId) {
|
|
3692
|
+
const row = this.rows.get(objectRowKey(projectId, objectTypeId))?.get(primaryId);
|
|
3693
|
+
return row ? structuredClone(row) : null;
|
|
3694
|
+
}
|
|
3695
|
+
getExactLinkRow(projectId, ref) {
|
|
3696
|
+
const row = this.links.get(sourceLinkBucketKey(projectId, ref.sourceTypeId, ref.sourceId))?.get(linkRowKey(ref.linkId, ref.targetTypeId, ref.targetId));
|
|
3697
|
+
return row ? structuredClone(row) : null;
|
|
3698
|
+
}
|
|
3699
|
+
applyExactObject(row, projectId) {
|
|
3700
|
+
const bucketId = objectRowKey(projectId, row.ref.objectTypeId);
|
|
3701
|
+
const bucket = this.rows.get(bucketId) ?? new Map;
|
|
3702
|
+
this.rows.set(bucketId, bucket);
|
|
3703
|
+
bucket.set(row.ref.primaryId, {
|
|
3704
|
+
projectId,
|
|
3705
|
+
objectTypeId: row.ref.objectTypeId,
|
|
3706
|
+
primaryId: row.ref.primaryId,
|
|
3707
|
+
properties: structuredClone(row.properties),
|
|
3708
|
+
createdAt: new Date(row.createdAt),
|
|
3709
|
+
updatedAt: new Date(row.updatedAt),
|
|
3710
|
+
version: row.version,
|
|
3711
|
+
lastCommitId: row.lastCommitId
|
|
3712
|
+
});
|
|
3713
|
+
}
|
|
3714
|
+
deleteExactObject(projectId, objectTypeId, primaryId) {
|
|
3715
|
+
this.deleteObjectRow(projectId, objectTypeId, primaryId);
|
|
3716
|
+
}
|
|
3717
|
+
applyExactLink(row, projectId) {
|
|
3718
|
+
const bucketKey = sourceLinkBucketKey(projectId, row.ref.source.objectTypeId, row.ref.source.primaryId);
|
|
3719
|
+
const bucket = this.links.get(bucketKey) ?? new Map;
|
|
3720
|
+
this.links.set(bucketKey, bucket);
|
|
3721
|
+
bucket.set(linkRowKey(row.ref.linkId, row.ref.target.objectTypeId, row.ref.target.primaryId), {
|
|
3722
|
+
projectId,
|
|
3723
|
+
sourceTypeId: row.ref.source.objectTypeId,
|
|
3724
|
+
sourceId: row.ref.source.primaryId,
|
|
3725
|
+
linkId: row.ref.linkId,
|
|
3726
|
+
targetTypeId: row.ref.target.objectTypeId,
|
|
3727
|
+
targetId: row.ref.target.primaryId,
|
|
3728
|
+
properties: row.properties ? structuredClone(row.properties) : undefined,
|
|
3729
|
+
createdAt: new Date(row.createdAt),
|
|
3730
|
+
updatedAt: new Date(row.updatedAt),
|
|
3731
|
+
lastCommitId: row.lastCommitId
|
|
3732
|
+
});
|
|
3733
|
+
}
|
|
3734
|
+
deleteExactLink(row) {
|
|
3735
|
+
this.deleteLinkRow(row.projectId, row.sourceTypeId, row.sourceId, row.linkId, row.targetTypeId, row.targetId);
|
|
3736
|
+
}
|
|
3737
|
+
queryCapabilities() {
|
|
3738
|
+
return IN_MEMORY_OBJECT_QUERY_CAPABILITIES;
|
|
3739
|
+
}
|
|
3740
|
+
createSelectedReadScope(params) {
|
|
3741
|
+
return createInMemorySelectedReader(this.readSource(params.projectId), params, () => this.queryCapabilities());
|
|
3742
|
+
}
|
|
3743
|
+
readSource(projectId) {
|
|
3744
|
+
return {
|
|
3745
|
+
projectId,
|
|
3746
|
+
objectsOfType: (objectTypeId) => [
|
|
3747
|
+
...this.rows.get(objectRowKey(projectId, objectTypeId))?.values() ?? []
|
|
3748
|
+
],
|
|
3749
|
+
getObject: (objectTypeId, primaryId) => this.rows.get(objectRowKey(projectId, objectTypeId))?.get(primaryId),
|
|
3750
|
+
outgoingLinks: (objectTypeId, primaryId) => this.links.get(sourceLinkBucketKey(projectId, objectTypeId, primaryId))?.values() ?? [],
|
|
3751
|
+
allLinks: () => allLinkRows(this.links)
|
|
3752
|
+
};
|
|
3753
|
+
}
|
|
3754
|
+
async queryObjects(params) {
|
|
3755
|
+
const result = evaluateObjectQuery(params.query, this.readSource(params.projectId));
|
|
3756
|
+
return {
|
|
3757
|
+
objects: result.entries.map((entry) => entry.row),
|
|
3758
|
+
hasMore: result.hasMore,
|
|
3759
|
+
nextPageToken: result.nextPageToken,
|
|
3760
|
+
...params.includeTotal === false ? {} : { total: result.total }
|
|
3761
|
+
};
|
|
3762
|
+
}
|
|
3763
|
+
async countObjects(params) {
|
|
3764
|
+
return {
|
|
3765
|
+
count: evaluateObjectQuery(stripOuterRowShape(params.query), this.readSource(params.projectId)).total
|
|
3766
|
+
};
|
|
3767
|
+
}
|
|
3768
|
+
async existsObjects(params) {
|
|
3769
|
+
return {
|
|
3770
|
+
exists: evaluateObjectQuery(stripOuterRowShape(params.query), this.readSource(params.projectId)).total > 0
|
|
3771
|
+
};
|
|
3772
|
+
}
|
|
3773
|
+
async facetObjects(params) {
|
|
3774
|
+
const result = evaluateObjectQuery(stripOuterRowShape(params.query), this.readSource(params.projectId));
|
|
3775
|
+
return {
|
|
3776
|
+
facets: buildFacetResults(result.entries.map((entry) => entry.row), params.facets)
|
|
3777
|
+
};
|
|
3778
|
+
}
|
|
3779
|
+
async getByPrimaryId(params) {
|
|
3780
|
+
const bucket = this.rows.get(objectRowKey(params.projectId, params.objectTypeId));
|
|
3781
|
+
if (!bucket)
|
|
3782
|
+
return null;
|
|
3783
|
+
return bucket.get(params.primaryId) ?? null;
|
|
3784
|
+
}
|
|
3785
|
+
async selectsObjectProperties(params) {
|
|
3786
|
+
return params.items.map((item) => this.rows.get(objectRowKey(params.projectId, item.objectTypeId))?.has(item.primaryId) ?? false);
|
|
3787
|
+
}
|
|
3788
|
+
async listLinks(params) {
|
|
3789
|
+
const direction = params.direction ?? "outgoing";
|
|
3790
|
+
const matches = (row) => !params.linkId || row.linkId === params.linkId;
|
|
3791
|
+
const rows = [];
|
|
3792
|
+
if (direction === "outgoing" || direction === "both") {
|
|
3793
|
+
const bucket = this.links.get(sourceLinkBucketKey(params.projectId, params.objectTypeId, params.objectId));
|
|
3794
|
+
if (bucket)
|
|
3795
|
+
rows.push(...[...bucket.values()].filter(matches));
|
|
3796
|
+
}
|
|
3797
|
+
if (direction === "incoming" || direction === "both") {
|
|
3798
|
+
for (const bucket of this.links.values()) {
|
|
3799
|
+
for (const row of bucket.values()) {
|
|
3800
|
+
if (row.projectId === params.projectId && row.targetTypeId === params.objectTypeId && row.targetId === params.objectId && matches(row)) {
|
|
3801
|
+
rows.push(row);
|
|
3802
|
+
}
|
|
3803
|
+
}
|
|
3804
|
+
}
|
|
3805
|
+
}
|
|
3806
|
+
if (direction !== "both")
|
|
3807
|
+
return rows;
|
|
3808
|
+
return [...new Map(rows.map((row) => [fullLinkRowKey(row), row])).values()];
|
|
3809
|
+
}
|
|
3810
|
+
async getByPrimaryIdBatch(params) {
|
|
3811
|
+
const result = new Map;
|
|
3812
|
+
for (const item of params.items) {
|
|
3813
|
+
const row = await this.getByPrimaryId({
|
|
3814
|
+
projectId: params.projectId,
|
|
3815
|
+
objectTypeId: item.objectTypeId,
|
|
3816
|
+
primaryId: item.primaryId
|
|
3817
|
+
});
|
|
3818
|
+
if (row) {
|
|
3819
|
+
result.set(objectBatchKey(item.objectTypeId, item.primaryId), row);
|
|
3820
|
+
}
|
|
3821
|
+
}
|
|
3822
|
+
return result;
|
|
3823
|
+
}
|
|
3824
|
+
async listLinksBatch(params) {
|
|
3825
|
+
return collectLinksBatch({
|
|
3826
|
+
all: () => allLinkRows(this.links),
|
|
3827
|
+
outgoing: (item) => this.links.get(sourceLinkBucketKey(params.projectId, item.objectTypeId, item.objectId))?.values() ?? []
|
|
3828
|
+
}, params, false);
|
|
3829
|
+
}
|
|
3830
|
+
async queryLinks(params) {
|
|
3831
|
+
return queryLinksFrom(params, (input) => this.listLinks(input));
|
|
3832
|
+
}
|
|
3833
|
+
async listIncidentLinksBatch(params) {
|
|
3834
|
+
const deduped = new Map;
|
|
3835
|
+
for (const item of params.items) {
|
|
3836
|
+
const rows = await this.listLinks({
|
|
3837
|
+
projectId: params.projectId,
|
|
3838
|
+
objectTypeId: item.objectTypeId,
|
|
3839
|
+
objectId: item.objectId,
|
|
3840
|
+
direction: "both"
|
|
3841
|
+
});
|
|
3842
|
+
for (const row of rows) {
|
|
3843
|
+
deduped.set(fullLinkRowKey(row), row);
|
|
3844
|
+
}
|
|
2954
3845
|
}
|
|
3846
|
+
return [...deduped.values()];
|
|
2955
3847
|
}
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
case "expand":
|
|
2968
|
-
return stripOuterRowShape(query.input);
|
|
2969
|
-
default:
|
|
2970
|
-
return query;
|
|
3848
|
+
async listByPrimaryIdPage(params) {
|
|
3849
|
+
assertReconciliationPageLimit(params.limit);
|
|
3850
|
+
const bucket = this.rows.get(objectRowKey(params.projectId, params.objectTypeId));
|
|
3851
|
+
const rows = [...bucket?.values() ?? []].filter((row) => !params.afterPrimaryId || compareStrings(row.primaryId, params.afterPrimaryId) > 0).sort((left, right) => compareStrings(left.primaryId, right.primaryId)).slice(0, params.limit + 1);
|
|
3852
|
+
const hasMore = rows.length > params.limit;
|
|
3853
|
+
const objects = rows.slice(0, params.limit).map((row) => structuredClone(row));
|
|
3854
|
+
const last = objects.at(-1);
|
|
3855
|
+
return {
|
|
3856
|
+
objects,
|
|
3857
|
+
...hasMore && last ? { nextPrimaryId: last.primaryId } : {}
|
|
3858
|
+
};
|
|
2971
3859
|
}
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
if (!Object.hasOwn(row.properties, facet.propertyId))
|
|
2983
|
-
continue;
|
|
2984
|
-
const value = row.properties[facet.propertyId];
|
|
2985
|
-
if (value === undefined)
|
|
2986
|
-
continue;
|
|
2987
|
-
const key2 = facetValueKey(value);
|
|
2988
|
-
const existing = buckets.get(key2);
|
|
2989
|
-
if (existing) {
|
|
2990
|
-
existing.count += 1;
|
|
3860
|
+
async list(params) {
|
|
3861
|
+
let allRows = [];
|
|
3862
|
+
if (params.objectTypeId) {
|
|
3863
|
+
const typeIds = Array.isArray(params.objectTypeId) ? params.objectTypeId : [params.objectTypeId];
|
|
3864
|
+
for (const typeId of typeIds) {
|
|
3865
|
+
const bucket = this.rows.get(objectRowKey(params.projectId, typeId));
|
|
3866
|
+
if (bucket) {
|
|
3867
|
+
allRows.push(...bucket.values());
|
|
3868
|
+
}
|
|
3869
|
+
}
|
|
2991
3870
|
} else {
|
|
2992
|
-
|
|
3871
|
+
for (const [key2, bucket] of this.rows) {
|
|
3872
|
+
if (key2.startsWith(objectRowProjectPrefix(params.projectId))) {
|
|
3873
|
+
allRows.push(...bucket.values());
|
|
3874
|
+
}
|
|
3875
|
+
}
|
|
3876
|
+
}
|
|
3877
|
+
const {
|
|
3878
|
+
primaryIdPrefix,
|
|
3879
|
+
primaryIdSuffix,
|
|
3880
|
+
updatedAfter,
|
|
3881
|
+
updatedBefore,
|
|
3882
|
+
createdAfter,
|
|
3883
|
+
createdBefore
|
|
3884
|
+
} = params;
|
|
3885
|
+
if (primaryIdPrefix || primaryIdSuffix || updatedAfter || updatedBefore || createdAfter || createdBefore) {
|
|
3886
|
+
allRows = allRows.filter((row) => (!primaryIdPrefix || row.primaryId.startsWith(primaryIdPrefix)) && (!primaryIdSuffix || row.primaryId.endsWith(primaryIdSuffix)) && (!updatedAfter || row.updatedAt >= updatedAfter) && (!updatedBefore || row.updatedAt <= updatedBefore) && (!createdAfter || row.createdAt >= createdAfter) && (!createdBefore || row.createdAt <= createdBefore));
|
|
2993
3887
|
}
|
|
3888
|
+
const total = allRows.length;
|
|
3889
|
+
const offset = params.offset ?? 0;
|
|
3890
|
+
const limit = params.limit ?? 50;
|
|
3891
|
+
if (limit === 0)
|
|
3892
|
+
return { objects: [], hasMore: offset < total, total };
|
|
3893
|
+
const orderBy = params.orderBy ?? "updatedAt";
|
|
3894
|
+
const order = params.order ?? "desc";
|
|
3895
|
+
allRows.sort((a, b) => {
|
|
3896
|
+
let comparison = 0;
|
|
3897
|
+
switch (orderBy) {
|
|
3898
|
+
case "primaryId":
|
|
3899
|
+
comparison = a.primaryId.localeCompare(b.primaryId);
|
|
3900
|
+
break;
|
|
3901
|
+
case "createdAt":
|
|
3902
|
+
comparison = a.createdAt.getTime() - b.createdAt.getTime();
|
|
3903
|
+
break;
|
|
3904
|
+
default:
|
|
3905
|
+
comparison = a.updatedAt.getTime() - b.updatedAt.getTime();
|
|
3906
|
+
break;
|
|
3907
|
+
}
|
|
3908
|
+
return order === "desc" ? -comparison : comparison;
|
|
3909
|
+
});
|
|
3910
|
+
const objects = allRows.slice(offset, offset + limit);
|
|
3911
|
+
const hasMore = offset + limit < total;
|
|
3912
|
+
return { objects, hasMore, total };
|
|
2994
3913
|
}
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
return JSON.stringify(value) ?? String(value);
|
|
2999
|
-
}
|
|
3000
|
-
function facetValueSortKey(value) {
|
|
3001
|
-
return JSON.stringify(value) ?? String(value);
|
|
3002
|
-
}
|
|
3003
|
-
function rowIdentityKey(row) {
|
|
3004
|
-
return rowIdentityKeyParts(row.objectTypeId, row.primaryId);
|
|
3005
|
-
}
|
|
3006
|
-
function rowIdentityKeyParts(objectTypeId, primaryId) {
|
|
3007
|
-
return objectBatchKey(objectTypeId, primaryId);
|
|
3008
|
-
}
|
|
3009
|
-
function upsertEntry(entriesByKey, entry) {
|
|
3010
|
-
const key2 = rowIdentityKey(entry.row);
|
|
3011
|
-
const existing = entriesByKey.get(key2);
|
|
3012
|
-
if (!existing) {
|
|
3013
|
-
entriesByKey.set(key2, entry);
|
|
3014
|
-
return;
|
|
3914
|
+
deleteObjectRow(projectId, objectTypeId, primaryId) {
|
|
3915
|
+
const bucket = this.rows.get(objectRowKey(projectId, objectTypeId));
|
|
3916
|
+
bucket?.delete(primaryId);
|
|
3015
3917
|
}
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
score: entry.score
|
|
3020
|
-
});
|
|
3918
|
+
deleteLinkRow(projectId, sourceTypeId, sourceId, linkId, targetTypeId, targetId) {
|
|
3919
|
+
const bucket = this.links.get(sourceLinkBucketKey(projectId, sourceTypeId, sourceId));
|
|
3920
|
+
bucket?.delete(linkRowKey(linkId, targetTypeId, targetId));
|
|
3021
3921
|
}
|
|
3022
3922
|
}
|
|
3023
|
-
function
|
|
3024
|
-
|
|
3923
|
+
function assertReconciliationPageLimit(limit) {
|
|
3924
|
+
if (!Number.isSafeInteger(limit) || limit <= 0) {
|
|
3925
|
+
throw new Error("Object reconciliation page limit must be a positive safe integer.");
|
|
3926
|
+
}
|
|
3025
3927
|
}
|
|
3026
|
-
function
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
throw new Error("[Sixb] Invalid object query page token");
|
|
3928
|
+
function cloneObjectBuckets(rows) {
|
|
3929
|
+
const clone2 = new Map;
|
|
3930
|
+
for (const [key2, bucket] of rows) {
|
|
3931
|
+
clone2.set(key2, new Map([...bucket.entries()].map(([primaryId, row]) => [primaryId, structuredClone(row)])));
|
|
3031
3932
|
}
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3933
|
+
return clone2;
|
|
3934
|
+
}
|
|
3935
|
+
function cloneLinkBuckets(links) {
|
|
3936
|
+
const clone2 = new Map;
|
|
3937
|
+
for (const [key2, bucket] of links) {
|
|
3938
|
+
clone2.set(key2, new Map([...bucket.entries()].map(([linkId, row]) => [linkId, structuredClone(row)])));
|
|
3035
3939
|
}
|
|
3036
|
-
return
|
|
3940
|
+
return clone2;
|
|
3037
3941
|
}
|
|
3038
|
-
function
|
|
3039
|
-
|
|
3942
|
+
function* allLinkRows(buckets) {
|
|
3943
|
+
for (const bucket of buckets.values())
|
|
3944
|
+
yield* bucket.values();
|
|
3040
3945
|
}
|
|
3041
|
-
|
|
3042
3946
|
// src/storage/ontology/in-memory/shared-state.ts
|
|
3043
3947
|
function createInMemoryOntologyState() {
|
|
3044
3948
|
return {
|
|
@@ -5783,6 +6687,129 @@ class InMemoryRulesStorage {
|
|
|
5783
6687
|
}
|
|
5784
6688
|
}
|
|
5785
6689
|
}
|
|
6690
|
+
// src/storage/share-grants/in-memory.ts
|
|
6691
|
+
class InMemoryShareGrantStorage {
|
|
6692
|
+
rows = new Map;
|
|
6693
|
+
async create(input) {
|
|
6694
|
+
const record = normalizeShareGrantCreate(input);
|
|
6695
|
+
const key2 = rowKey(record.projectId, record.id);
|
|
6696
|
+
const duplicateTokenHash = [...this.rows.values()].some((current) => current.projectId === record.projectId && current.tokenHash === record.tokenHash);
|
|
6697
|
+
if (this.rows.has(key2) || duplicateTokenHash) {
|
|
6698
|
+
throw new ShareGrantStorageError("duplicate", `[Sixb] Share grant '${record.id}' conflicts with an existing record.`);
|
|
6699
|
+
}
|
|
6700
|
+
this.rows.set(key2, record);
|
|
6701
|
+
return cloneShareGrantRecord(record);
|
|
6702
|
+
}
|
|
6703
|
+
async getById(input) {
|
|
6704
|
+
const normalized = normalizeGetShareGrantByIdInput(input);
|
|
6705
|
+
const record = this.rows.get(rowKey(normalized.projectId, normalized.id));
|
|
6706
|
+
return record ? cloneShareGrantRecord(record) : null;
|
|
6707
|
+
}
|
|
6708
|
+
async list(input) {
|
|
6709
|
+
const normalized = normalizeListShareGrantsInput(input);
|
|
6710
|
+
const matching = [...this.rows.values()].filter((record) => record.projectId === normalized.projectId && (normalized.definitionId === undefined || record.definitionId === normalized.definitionId) && (normalized.target === undefined || record.target.objectTypeId === normalized.target.objectTypeId && record.target.primaryId === normalized.target.primaryId) && (normalized.includeRevoked || record.revokedAt === undefined) && (normalized.includeExpired || record.expiresAt.getTime() > normalized.now.getTime())).sort(compareShareGrants);
|
|
6711
|
+
const total = matching.length;
|
|
6712
|
+
const grants = matching.slice(normalized.offset, normalized.offset + normalized.limit).map(cloneShareGrantRecord);
|
|
6713
|
+
return {
|
|
6714
|
+
grants,
|
|
6715
|
+
total,
|
|
6716
|
+
hasMore: normalized.offset + grants.length < total
|
|
6717
|
+
};
|
|
6718
|
+
}
|
|
6719
|
+
async revoke(input) {
|
|
6720
|
+
const normalized = normalizeRevokeShareGrantInput(input);
|
|
6721
|
+
const key2 = rowKey(normalized.projectId, normalized.id);
|
|
6722
|
+
const current = this.rows.get(key2);
|
|
6723
|
+
if (!current)
|
|
6724
|
+
return null;
|
|
6725
|
+
if (current.revokedAt)
|
|
6726
|
+
return cloneShareGrantRecord(current);
|
|
6727
|
+
const revocation = normalizeRevokeShareGrantInput(normalized, current.createdAt);
|
|
6728
|
+
const updated = {
|
|
6729
|
+
...current,
|
|
6730
|
+
revokedAt: new Date(revocation.revokedAt),
|
|
6731
|
+
revokedBy: { ...revocation.revokedBy }
|
|
6732
|
+
};
|
|
6733
|
+
this.rows.set(key2, updated);
|
|
6734
|
+
return cloneShareGrantRecord(updated);
|
|
6735
|
+
}
|
|
6736
|
+
snapshot() {
|
|
6737
|
+
return new Map([...this.rows].map(([key2, record]) => [key2, cloneShareGrantRecord(record)]));
|
|
6738
|
+
}
|
|
6739
|
+
restore(snapshot) {
|
|
6740
|
+
this.rows = new Map([...snapshot].map(([key2, record]) => [key2, parseShareGrantRecord(record)]));
|
|
6741
|
+
}
|
|
6742
|
+
}
|
|
6743
|
+
function compareShareGrants(left, right) {
|
|
6744
|
+
const created = right.createdAt.getTime() - left.createdAt.getTime();
|
|
6745
|
+
if (created !== 0)
|
|
6746
|
+
return created;
|
|
6747
|
+
return left.id === right.id ? 0 : left.id < right.id ? 1 : -1;
|
|
6748
|
+
}
|
|
6749
|
+
function rowKey(projectId, id) {
|
|
6750
|
+
return `${projectId}\x00${id}`;
|
|
6751
|
+
}
|
|
6752
|
+
// src/storage/share-sessions/in-memory.ts
|
|
6753
|
+
class InMemoryShareSessionStorage {
|
|
6754
|
+
grants;
|
|
6755
|
+
rows = new Map;
|
|
6756
|
+
constructor(grants) {
|
|
6757
|
+
this.grants = grants;
|
|
6758
|
+
}
|
|
6759
|
+
async create(input) {
|
|
6760
|
+
const record = normalizeShareSessionCreate(input);
|
|
6761
|
+
const grant = await this.grants.getById({ projectId: record.projectId, id: record.grantId });
|
|
6762
|
+
if (!grant) {
|
|
6763
|
+
throw new ShareSessionStorageError("invalid_input", `[Sixb] Share grant '${record.grantId}' does not exist in project '${record.projectId}'.`);
|
|
6764
|
+
}
|
|
6765
|
+
const key2 = rowKey2(record.projectId, record.id);
|
|
6766
|
+
const duplicateTokenHash = [...this.rows.values()].some((current) => current.projectId === record.projectId && current.tokenHash === record.tokenHash);
|
|
6767
|
+
if (this.rows.has(key2) || duplicateTokenHash) {
|
|
6768
|
+
throw new ShareSessionStorageError("duplicate", `[Sixb] Share session '${record.id}' conflicts with an existing record.`);
|
|
6769
|
+
}
|
|
6770
|
+
this.rows.set(key2, record);
|
|
6771
|
+
return cloneShareSessionRecord(record);
|
|
6772
|
+
}
|
|
6773
|
+
async getById(input) {
|
|
6774
|
+
const normalized = normalizeGetShareSessionByIdInput(input);
|
|
6775
|
+
const record = this.rows.get(rowKey2(normalized.projectId, normalized.id));
|
|
6776
|
+
return record ? cloneShareSessionRecord(record) : null;
|
|
6777
|
+
}
|
|
6778
|
+
async renewIfValid(input) {
|
|
6779
|
+
const normalized = normalizeRenewShareSessionIfValidInput(input);
|
|
6780
|
+
const key2 = rowKey2(normalized.projectId, normalized.id);
|
|
6781
|
+
const current = this.rows.get(key2);
|
|
6782
|
+
if (!current || current.grantId !== normalized.grantId || current.tokenHash !== normalized.tokenHash || current.revokedAt !== undefined || current.createdAt.getTime() > normalized.now.getTime() || current.expiresAt.getTime() <= normalized.now.getTime() || current.absoluteExpiresAt.getTime() <= normalized.now.getTime()) {
|
|
6783
|
+
return null;
|
|
6784
|
+
}
|
|
6785
|
+
const nextExpiry = Math.min(current.absoluteExpiresAt.getTime(), Math.max(current.expiresAt.getTime(), normalized.expiresAt.getTime()));
|
|
6786
|
+
const updated = { ...current, expiresAt: new Date(nextExpiry) };
|
|
6787
|
+
this.rows.set(key2, updated);
|
|
6788
|
+
return cloneShareSessionRecord(updated);
|
|
6789
|
+
}
|
|
6790
|
+
async revoke(input) {
|
|
6791
|
+
const normalized = normalizeRevokeShareSessionInput(input);
|
|
6792
|
+
const key2 = rowKey2(normalized.projectId, normalized.id);
|
|
6793
|
+
const current = this.rows.get(key2);
|
|
6794
|
+
if (!current)
|
|
6795
|
+
return null;
|
|
6796
|
+
if (current.revokedAt)
|
|
6797
|
+
return cloneShareSessionRecord(current);
|
|
6798
|
+
const revocation = normalizeRevokeShareSessionInput(normalized, current.createdAt);
|
|
6799
|
+
const updated = { ...current, revokedAt: new Date(revocation.revokedAt) };
|
|
6800
|
+
this.rows.set(key2, updated);
|
|
6801
|
+
return cloneShareSessionRecord(updated);
|
|
6802
|
+
}
|
|
6803
|
+
snapshot() {
|
|
6804
|
+
return new Map([...this.rows].map(([key2, record]) => [key2, cloneShareSessionRecord(record)]));
|
|
6805
|
+
}
|
|
6806
|
+
restore(snapshot) {
|
|
6807
|
+
this.rows = new Map([...snapshot].map(([key2, record]) => [key2, parseShareSessionRecord(record)]));
|
|
6808
|
+
}
|
|
6809
|
+
}
|
|
6810
|
+
function rowKey2(projectId, id) {
|
|
6811
|
+
return `${projectId}\x00${id}`;
|
|
6812
|
+
}
|
|
5786
6813
|
// src/storage/sync-runs/idempotency.ts
|
|
5787
6814
|
function canRequeueSyncRunAfterEnqueueFailure(existing, input) {
|
|
5788
6815
|
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;
|
|
@@ -5965,6 +6992,13 @@ class InMemorySyncRunStorage {
|
|
|
5965
6992
|
// src/storage/transaction.ts
|
|
5966
6993
|
function createTransactionStorageProxy(target, isActive) {
|
|
5967
6994
|
const proxies = new WeakMap;
|
|
6995
|
+
const objectStorage = createObjectOperationScope(target.objects, {
|
|
6996
|
+
assertAvailable: () => assertTransactionActive(isActive),
|
|
6997
|
+
run: async (operation) => {
|
|
6998
|
+
assertTransactionActive(isActive);
|
|
6999
|
+
return operation();
|
|
7000
|
+
}
|
|
7001
|
+
});
|
|
5968
7002
|
const wrap = (value) => {
|
|
5969
7003
|
const existing = proxies.get(value);
|
|
5970
7004
|
if (existing)
|
|
@@ -5972,7 +7006,7 @@ function createTransactionStorageProxy(target, isActive) {
|
|
|
5972
7006
|
const proxy = new Proxy(value, {
|
|
5973
7007
|
get(current, property, receiver) {
|
|
5974
7008
|
assertTransactionActive(isActive);
|
|
5975
|
-
const result = Reflect.get(current, property, receiver);
|
|
7009
|
+
const result = current === target && property === "objects" ? objectStorage : Reflect.get(current, property, receiver);
|
|
5976
7010
|
if (typeof result === "function") {
|
|
5977
7011
|
return (...args) => {
|
|
5978
7012
|
assertTransactionActive(isActive);
|
|
@@ -6261,7 +7295,9 @@ function compareRequestedAt(left, right, order) {
|
|
|
6261
7295
|
var WORKFLOW_RUN_FAILURE_CODES = [
|
|
6262
7296
|
"internal.unexpected",
|
|
6263
7297
|
"runtime.cancelled",
|
|
6264
|
-
"workflow.node_failed"
|
|
7298
|
+
"workflow.node_failed",
|
|
7299
|
+
"ai.usage_limit_exceeded",
|
|
7300
|
+
"ai.usage_limit_unavailable"
|
|
6265
7301
|
];
|
|
6266
7302
|
|
|
6267
7303
|
// src/storage/workflow-runs/in-memory.ts
|
|
@@ -6670,7 +7706,7 @@ class InMemoryWorkflowAgentNodeRunStorage {
|
|
|
6670
7706
|
projectId: input.projectId,
|
|
6671
7707
|
executionId: input.executionId,
|
|
6672
7708
|
nodeRunId: input.nodeRunId,
|
|
6673
|
-
|
|
7709
|
+
actorId: input.actorId,
|
|
6674
7710
|
workflowExecutionId: workflowRun.executionId
|
|
6675
7711
|
});
|
|
6676
7712
|
if (node.status !== "running") {
|
|
@@ -6687,7 +7723,7 @@ class InMemoryWorkflowAgentNodeRunStorage {
|
|
|
6687
7723
|
projectId: input.projectId,
|
|
6688
7724
|
nodeRunId: input.nodeRunId,
|
|
6689
7725
|
executionId: input.executionId,
|
|
6690
|
-
|
|
7726
|
+
actorId: input.actorId,
|
|
6691
7727
|
status: "queued",
|
|
6692
7728
|
prompt: input.prompt,
|
|
6693
7729
|
attempt: 0,
|
|
@@ -6756,7 +7792,7 @@ class InMemoryWorkflowAgentNodeRunStorage {
|
|
|
6756
7792
|
async list(input) {
|
|
6757
7793
|
const statuses = input.statuses ? new Set(input.statuses) : null;
|
|
6758
7794
|
const order = input.order ?? "desc";
|
|
6759
|
-
const filtered = [...this.runs.values()].filter((run) => run.projectId === input.projectId).filter((run) => input.
|
|
7795
|
+
const filtered = [...this.runs.values()].filter((run) => run.projectId === input.projectId).filter((run) => input.actorId ? run.actorId === input.actorId : true).filter((run) => statuses ? statuses.has(run.status) : true).sort((a, b) => order === "asc" ? a.createdAt.getTime() - b.createdAt.getTime() : b.createdAt.getTime() - a.createdAt.getTime());
|
|
6760
7796
|
const { page, total, hasMore } = paginate(filtered, input);
|
|
6761
7797
|
return { runs: page.map(cloneRecord), total, hasMore };
|
|
6762
7798
|
}
|
|
@@ -6803,11 +7839,39 @@ class InMemoryStorage {
|
|
|
6803
7839
|
timeseriesStorage = new InMemoryTimeseriesStorage;
|
|
6804
7840
|
ontologyStorage;
|
|
6805
7841
|
authStorage = new InMemoryAuthStorage;
|
|
6806
|
-
|
|
7842
|
+
shareGrantStorage = new InMemoryShareGrantStorage;
|
|
7843
|
+
shareSessionStorage = new InMemoryShareSessionStorage(this.shareGrantStorage);
|
|
7844
|
+
executionStorage = new InMemoryExecutionStorage(this.authStorage, {
|
|
7845
|
+
shareSessions: this.shareSessionStorage
|
|
7846
|
+
});
|
|
6807
7847
|
agentStorage = new InMemoryAgentStorage(this.executionStorage);
|
|
6808
7848
|
aiUsageStorage = new InMemoryAiUsageStorage(this.executionStorage);
|
|
6809
7849
|
aiCostStorage = new InMemoryAiCostStorage(this.aiUsageStorage, {
|
|
6810
|
-
resolve: (input) => this.resolveAiAccountingAttribution(input)
|
|
7850
|
+
resolve: (input) => this.resolveAiAccountingAttribution(input),
|
|
7851
|
+
resolveGroup: async (input) => {
|
|
7852
|
+
const attribution = await this.resolveAiAccountingAttribution(input);
|
|
7853
|
+
if (attribution?.kind !== "subagent")
|
|
7854
|
+
return { executionId: input.executionId, attribution };
|
|
7855
|
+
const parent = await this.agentStorage.runs.getById({
|
|
7856
|
+
projectId: input.projectId,
|
|
7857
|
+
id: attribution.parentRunId
|
|
7858
|
+
});
|
|
7859
|
+
if (!parent)
|
|
7860
|
+
throw new Error("[Sixb] Subagent accounting parent is missing.");
|
|
7861
|
+
return {
|
|
7862
|
+
executionId: parent.executionId,
|
|
7863
|
+
attribution: await this.resolveAiAccountingAttribution({
|
|
7864
|
+
...input,
|
|
7865
|
+
executionId: parent.executionId
|
|
7866
|
+
})
|
|
7867
|
+
};
|
|
7868
|
+
}
|
|
7869
|
+
});
|
|
7870
|
+
aiLimitStorage = new InMemoryAiLimitStorage({
|
|
7871
|
+
resolveExecution: ({ projectId, executionId }) => this.executionStorage.getById({ projectId, id: executionId }),
|
|
7872
|
+
resolveUsageRecord: ({ projectId, usageRecordId }) => this.aiUsageStorage.getRecord(projectId, usageRecordId),
|
|
7873
|
+
resolveCostRecord: ({ projectId, usageRecordId }) => this.aiCostStorage.getRecord(projectId, usageRecordId),
|
|
7874
|
+
listUsageRecords: ({ projectId }) => this.aiUsageStorage.listRecords(projectId)
|
|
6811
7875
|
});
|
|
6812
7876
|
actionRunStorage = new InMemoryActionRunStorage(this.executionStorage);
|
|
6813
7877
|
syncRunStorage = new InMemorySyncRunStorage(this.executionStorage);
|
|
@@ -6826,6 +7890,7 @@ class InMemoryStorage {
|
|
|
6826
7890
|
agents;
|
|
6827
7891
|
aiUsage;
|
|
6828
7892
|
aiCosts;
|
|
7893
|
+
aiLimits;
|
|
6829
7894
|
actionRuns;
|
|
6830
7895
|
syncRuns;
|
|
6831
7896
|
pipelineRuns;
|
|
@@ -6834,18 +7899,21 @@ class InMemoryStorage {
|
|
|
6834
7899
|
workflowInterventions;
|
|
6835
7900
|
webhookRuns;
|
|
6836
7901
|
rules;
|
|
7902
|
+
shareGrants;
|
|
7903
|
+
shareSessions;
|
|
6837
7904
|
fileUploadSessions;
|
|
6838
7905
|
connectorConnections;
|
|
6839
7906
|
constructor(options = {}) {
|
|
6840
7907
|
this.connectorConnectionStorage = new InMemoryConnectorConnectionStorage(options.connectorConnections);
|
|
6841
7908
|
const scope = createStorageOperationScope((run) => this.withStorageOperation(run), () => this.assertRootOperationAvailable());
|
|
6842
|
-
this.objects =
|
|
7909
|
+
this.objects = createObjectOperationScope(this.objectStorage, scope);
|
|
6843
7910
|
this.timeseries = createOperationScopedFacade(this.timeseriesStorage, scope);
|
|
6844
7911
|
this.auth = createAuthOperationScope(this.authStorage, scope);
|
|
6845
7912
|
this.executions = createOperationScopedFacade(this.executionStorage, scope);
|
|
6846
7913
|
this.agents = createAgentOperationScope(this.agentStorage, scope);
|
|
6847
7914
|
this.aiUsage = createOperationScopedFacade(this.aiUsageStorage, scope);
|
|
6848
7915
|
this.aiCosts = createOperationScopedFacade(this.aiCostStorage, scope);
|
|
7916
|
+
this.aiLimits = createOperationScopedFacade(this.aiLimitStorage, scope);
|
|
6849
7917
|
this.actionRuns = createOperationScopedFacade(this.actionRunStorage, scope);
|
|
6850
7918
|
this.syncRuns = createOperationScopedFacade(this.syncRunStorage, scope);
|
|
6851
7919
|
this.pipelineRuns = createOperationScopedFacade(this.pipelineRunStorage, scope);
|
|
@@ -6854,6 +7922,8 @@ class InMemoryStorage {
|
|
|
6854
7922
|
this.workflowInterventions = createOperationScopedFacade(this.workflowInterventionStorage, scope);
|
|
6855
7923
|
this.webhookRuns = createOperationScopedFacade(this.webhookRunStorage, scope);
|
|
6856
7924
|
this.rules = createOperationScopedFacade(this.rulesStorage, scope);
|
|
7925
|
+
this.shareGrants = createOperationScopedFacade(this.shareGrantStorage, scope);
|
|
7926
|
+
this.shareSessions = createOperationScopedFacade(this.shareSessionStorage, scope);
|
|
6857
7927
|
this.fileUploadSessions = createOperationScopedFacade(this.fileUploadSessionStorage, scope);
|
|
6858
7928
|
this.connectorConnections = createOperationScopedFacade(this.connectorConnectionStorage, scope);
|
|
6859
7929
|
this.ontologyStorage = new InMemoryOntologyStorage(this.objectStorage, this.timeseriesStorage, {
|
|
@@ -6878,14 +7948,20 @@ class InMemoryStorage {
|
|
|
6878
7948
|
projectId: input.projectId,
|
|
6879
7949
|
id: execution.executor.runId
|
|
6880
7950
|
});
|
|
6881
|
-
if (directRun) {
|
|
7951
|
+
if (directRun?.kind === "conversation") {
|
|
6882
7952
|
return {
|
|
6883
7953
|
kind: "agent",
|
|
6884
|
-
agentId: directRun.agentId,
|
|
6885
7954
|
agentRunId: directRun.id,
|
|
6886
7955
|
threadId: directRun.threadId
|
|
6887
7956
|
};
|
|
6888
7957
|
}
|
|
7958
|
+
if (directRun?.kind === "subagent") {
|
|
7959
|
+
return {
|
|
7960
|
+
kind: "subagent",
|
|
7961
|
+
subagentRunId: directRun.id,
|
|
7962
|
+
parentRunId: directRun.parentRunId
|
|
7963
|
+
};
|
|
7964
|
+
}
|
|
6889
7965
|
const agentRun = await this.workflowRunStorage.agentNodes.getByNodeRunId({
|
|
6890
7966
|
projectId: input.projectId,
|
|
6891
7967
|
nodeRunId: execution.executor.runId
|
|
@@ -6900,7 +7976,7 @@ class InMemoryStorage {
|
|
|
6900
7976
|
return;
|
|
6901
7977
|
return {
|
|
6902
7978
|
kind: "workflowAgent",
|
|
6903
|
-
|
|
7979
|
+
agentStepId: node.nodeId,
|
|
6904
7980
|
nodeRunId: agentRun.nodeRunId,
|
|
6905
7981
|
workflowId: node.workflowId,
|
|
6906
7982
|
workflowRunId: node.workflowRunId
|
|
@@ -6929,7 +8005,13 @@ class InMemoryStorage {
|
|
|
6929
8005
|
this.activeTransactionTokens.add(transactionToken);
|
|
6930
8006
|
this.materializationLifecycles.set(transactionToken, materializationLifecycle);
|
|
6931
8007
|
try {
|
|
6932
|
-
const result = await this.transactionScope.run(transactionToken, async () =>
|
|
8008
|
+
const result = await this.transactionScope.run(transactionToken, async () => {
|
|
8009
|
+
try {
|
|
8010
|
+
return await run(tx);
|
|
8011
|
+
} finally {
|
|
8012
|
+
await this.aiLimitStorage.settleOperations();
|
|
8013
|
+
}
|
|
8014
|
+
});
|
|
6933
8015
|
materializationLifecycle.assertCommittable();
|
|
6934
8016
|
return result;
|
|
6935
8017
|
} catch (error) {
|
|
@@ -6987,6 +8069,7 @@ class InMemoryStorage {
|
|
|
6987
8069
|
agents: this.agentStorage,
|
|
6988
8070
|
aiUsage: this.aiUsageStorage,
|
|
6989
8071
|
aiCosts: this.aiCostStorage,
|
|
8072
|
+
aiLimits: this.aiLimitStorage,
|
|
6990
8073
|
actionRuns: this.actionRunStorage,
|
|
6991
8074
|
syncRuns: this.syncRunStorage,
|
|
6992
8075
|
pipelineRuns: this.pipelineRunStorage,
|
|
@@ -6995,6 +8078,8 @@ class InMemoryStorage {
|
|
|
6995
8078
|
workflowInterventions: this.workflowInterventionStorage,
|
|
6996
8079
|
webhookRuns: this.webhookRunStorage,
|
|
6997
8080
|
rules: this.rulesStorage,
|
|
8081
|
+
shareGrants: this.shareGrantStorage,
|
|
8082
|
+
shareSessions: this.shareSessionStorage,
|
|
6998
8083
|
fileUploadSessions: this.fileUploadSessionStorage,
|
|
6999
8084
|
connectorConnections: this.connectorConnectionStorage,
|
|
7000
8085
|
ping: async () => {
|
|
@@ -7015,6 +8100,7 @@ class InMemoryStorage {
|
|
|
7015
8100
|
agents: this.agentStorage.snapshot(),
|
|
7016
8101
|
aiUsage: this.aiUsageStorage.snapshot(),
|
|
7017
8102
|
aiCosts: this.aiCostStorage.snapshot(),
|
|
8103
|
+
aiLimits: this.aiLimitStorage.snapshot(),
|
|
7018
8104
|
actionRuns: this.actionRunStorage.snapshot(),
|
|
7019
8105
|
syncRuns: this.syncRunStorage.snapshot(),
|
|
7020
8106
|
pipelineRuns: this.pipelineRunStorage.snapshot(),
|
|
@@ -7023,6 +8109,8 @@ class InMemoryStorage {
|
|
|
7023
8109
|
workflowInterventions: this.workflowInterventionStorage.snapshot(),
|
|
7024
8110
|
webhookRuns: this.webhookRunStorage.snapshot(),
|
|
7025
8111
|
rules: this.rulesStorage.snapshot(),
|
|
8112
|
+
shareGrants: this.shareGrantStorage.snapshot(),
|
|
8113
|
+
shareSessions: this.shareSessionStorage.snapshot(),
|
|
7026
8114
|
fileUploadSessions: this.fileUploadSessionStorage.snapshot(),
|
|
7027
8115
|
connectorConnections: this.connectorConnectionStorage.snapshot()
|
|
7028
8116
|
};
|
|
@@ -7036,6 +8124,7 @@ class InMemoryStorage {
|
|
|
7036
8124
|
this.agentStorage.restore(snapshot.agents);
|
|
7037
8125
|
this.aiUsageStorage.restore(snapshot.aiUsage);
|
|
7038
8126
|
this.aiCostStorage.restore(snapshot.aiCosts);
|
|
8127
|
+
this.aiLimitStorage.restore(snapshot.aiLimits);
|
|
7039
8128
|
this.actionRunStorage.restore(snapshot.actionRuns);
|
|
7040
8129
|
this.syncRunStorage.restore(snapshot.syncRuns);
|
|
7041
8130
|
this.pipelineRunStorage.restore(snapshot.pipelineRuns);
|
|
@@ -7044,6 +8133,8 @@ class InMemoryStorage {
|
|
|
7044
8133
|
this.workflowInterventionStorage.restore(snapshot.workflowInterventions);
|
|
7045
8134
|
this.webhookRunStorage.restore(snapshot.webhookRuns);
|
|
7046
8135
|
this.rulesStorage.restore(snapshot.rules);
|
|
8136
|
+
this.shareGrantStorage.restore(snapshot.shareGrants);
|
|
8137
|
+
this.shareSessionStorage.restore(snapshot.shareSessions);
|
|
7047
8138
|
this.fileUploadSessionStorage.restore(snapshot.fileUploadSessions);
|
|
7048
8139
|
this.connectorConnectionStorage.restore(snapshot.connectorConnections);
|
|
7049
8140
|
}
|
|
@@ -7257,6 +8348,6 @@ function assertAppliedPrefix(migrations, rows) {
|
|
|
7257
8348
|
}
|
|
7258
8349
|
return [...rows].sort((a, b) => a.version - b.version);
|
|
7259
8350
|
}
|
|
7260
|
-
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,
|
|
8351
|
+
export { actionSubjectsEqual, actionRunParamsEqual, actionRunPhaseRecordsEqual, finishActionRunPhase, canRequeueActionRunAfterEnqueueFailure, isTerminalActionRun, InMemoryActionRunStorage, AGENT_MESSAGE_CONTENT_VERSION, InMemoryAgentStorage, AiCostStorageError, InMemoryAiCostStorage, InMemoryAiLimitStorage, InMemoryConnectorConnectionStorage, ObjectNotFoundError, ObjectStorageError, StorageTransactionError, isStorageSerializationFailure, FileUploadSessionError, DEFAULT_FILE_UPLOAD_SESSION_TTL_MS, DEFAULT_FILE_UPLOAD_TERMINAL_SESSION_TTL_MS, createUploadExpiresAt, createFileUploadId, InMemoryFileUploadSessions, objectBatchKey, linkBatchKey, objectLinkCursor, compareQueryScalarValues, queryScalarValuesEqual, canRequeuePipelineRunAfterEnqueueFailure, PIPELINE_RUN_FAILURE_CODES, InMemoryPipelineRunStorage, InMemoryProjectionRunStorage, InMemoryRulesStorage, InMemoryShareGrantStorage, InMemoryShareSessionStorage, 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 };
|
|
7261
8352
|
|
|
7262
|
-
//# debugId=
|
|
8353
|
+
//# debugId=904203AAAA1BC24E64756E2164756E21
|