@sixb/core 0.1.15 → 0.1.17
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/index.js +25 -25
- package/dist/actions/types/context.d.ts +2 -2
- package/dist/actions/types/context.d.ts.map +1 -1
- package/dist/actions/worker.js +1 -1
- package/dist/agents/index.js +41 -40
- package/dist/agents/index.js.map +1 -1
- package/dist/auth/index.js +5 -5
- package/dist/authorization/index.js +2 -2
- package/dist/blob-storage/download-urls.d.ts +41 -0
- package/dist/blob-storage/download-urls.d.ts.map +1 -0
- package/dist/blob-storage/execution.d.ts +9 -1
- package/dist/blob-storage/execution.d.ts.map +1 -1
- package/dist/blob-storage/index.js +5 -3
- package/dist/blob-storage/index.js.map +1 -1
- package/dist/blob-storage/internal.d.ts +2 -0
- package/dist/blob-storage/internal.d.ts.map +1 -0
- package/dist/blob-storage/internal.js +11 -0
- package/dist/blob-storage/internal.js.map +9 -0
- package/dist/bootstrap/index.js +45 -44
- package/dist/bootstrap/index.js.map +1 -1
- package/dist/{chunk-wem5vqjw.js → chunk-10styjgk.js} +18 -13
- package/dist/{chunk-wem5vqjw.js.map → chunk-10styjgk.js.map} +3 -3
- package/dist/{chunk-hgqpcmyr.js → chunk-1hqwggsn.js} +47 -19
- package/dist/chunk-1hqwggsn.js.map +12 -0
- package/dist/{chunk-q3grgzp1.js → chunk-23xs4qp9.js} +2 -2
- package/dist/{chunk-vef6qa14.js → chunk-2am3db31.js} +2 -2
- package/dist/{chunk-fj1dvp37.js → chunk-2vhg6ysa.js} +1 -1
- package/dist/{chunk-p0nbkys4.js → chunk-33saed7g.js} +1 -1
- package/dist/{chunk-mdnw7nj8.js → chunk-3rrezgyc.js} +33 -8
- package/dist/chunk-3rrezgyc.js.map +15 -0
- package/dist/{chunk-jgwb25gc.js → chunk-4as3wt1c.js} +13 -5
- package/dist/chunk-4as3wt1c.js.map +12 -0
- package/dist/chunk-4ra628t7.js +88 -0
- package/dist/chunk-4ra628t7.js.map +10 -0
- package/dist/{chunk-mmac1mp6.js → chunk-52c5zb0z.js} +2 -2
- package/dist/{chunk-8fjmqjyx.js → chunk-5be2ath4.js} +1 -1
- package/dist/{chunk-2fv8sajb.js → chunk-5thzcb8g.js} +2 -2
- package/dist/{chunk-fjw417jf.js → chunk-5yd8cchh.js} +1143 -784
- package/dist/chunk-5yd8cchh.js.map +66 -0
- package/dist/{chunk-2tz5vnvz.js → chunk-6wbm6ymz.js} +235 -41
- package/dist/{chunk-2tz5vnvz.js.map → chunk-6wbm6ymz.js.map} +8 -6
- package/dist/{chunk-py2dw8cw.js → chunk-7ecp4v7a.js} +26 -19
- package/dist/chunk-7ecp4v7a.js.map +17 -0
- package/dist/{chunk-f85hpqnm.js → chunk-99nd4rc1.js} +3 -3
- package/dist/{chunk-f85hpqnm.js.map → chunk-99nd4rc1.js.map} +3 -3
- package/dist/{chunk-1jvq82rp.js → chunk-9g6jz9kk.js} +5 -5
- package/dist/{chunk-39tqv9hz.js → chunk-9se093qz.js} +5 -6
- package/dist/{chunk-39tqv9hz.js.map → chunk-9se093qz.js.map} +3 -4
- package/dist/{chunk-8w27xf9e.js → chunk-a7er86jd.js} +1 -1
- package/dist/{chunk-zdkcdshk.js → chunk-aq39q04r.js} +41 -3
- package/dist/{chunk-zdkcdshk.js.map → chunk-aq39q04r.js.map} +4 -3
- package/dist/chunk-b9affek3.js +261 -0
- package/dist/chunk-b9affek3.js.map +12 -0
- package/dist/{chunk-bxx3ms5t.js → chunk-c2rga5cx.js} +2 -2
- package/dist/{chunk-dsfw1bdr.js → chunk-cnb5kv05.js} +2 -2
- package/dist/chunk-d62kjtbg.js.map +2 -2
- package/dist/{chunk-dqkd3kdj.js → chunk-dam456ve.js} +234 -35
- package/dist/{chunk-dqkd3kdj.js.map → chunk-dam456ve.js.map} +7 -5
- package/dist/{chunk-n5t4mq6z.js → chunk-e67ynxcr.js} +3 -3
- package/dist/{chunk-xnx96gfy.js → chunk-ere85b8y.js} +17 -8
- package/dist/chunk-ere85b8y.js.map +15 -0
- package/dist/{chunk-k4kkp58d.js → chunk-ewqa58h9.js} +12 -2
- package/dist/chunk-ewqa58h9.js.map +11 -0
- package/dist/{chunk-6q7c68yx.js → chunk-f1xh7a32.js} +3 -3
- package/dist/{chunk-z708gemf.js → chunk-fggq3d9k.js} +450 -799
- package/dist/chunk-fggq3d9k.js.map +49 -0
- package/dist/{chunk-7jc21943.js → chunk-gf7yht60.js} +4 -4
- package/dist/chunk-h8teetr0.js +9 -0
- package/dist/chunk-h8teetr0.js.map +10 -0
- package/dist/chunk-hn2r7z41.js.map +1 -1
- package/dist/{chunk-ffwvdgk1.js → chunk-jjrn5v0p.js} +1 -1
- package/dist/{chunk-r5sc1d2b.js → chunk-jnfxmr3f.js} +1 -1
- package/dist/{chunk-y0zmae99.js → chunk-k4g51s47.js} +3 -3
- package/dist/{chunk-a0073121.js → chunk-kpx7jrmn.js} +3 -1
- package/dist/chunk-kpx7jrmn.js.map +12 -0
- package/dist/{chunk-p1683c0v.js → chunk-kyjcwqz6.js} +5 -2
- package/dist/{chunk-p1683c0v.js.map → chunk-kyjcwqz6.js.map} +3 -3
- package/dist/{chunk-3c90jvfj.js → chunk-pja9jfz6.js} +742 -583
- package/dist/chunk-pja9jfz6.js.map +19 -0
- package/dist/chunk-pqajwytd.js.map +1 -1
- package/dist/{chunk-mr60an99.js → chunk-qczk96d9.js} +22 -2
- package/dist/{chunk-mr60an99.js.map → chunk-qczk96d9.js.map} +3 -3
- package/dist/{chunk-s3csryxe.js → chunk-rj69qcrd.js} +8 -2
- package/dist/chunk-rj69qcrd.js.map +11 -0
- package/dist/{chunk-d8yes9yx.js → chunk-rpxz486p.js} +32 -5
- package/dist/{chunk-d8yes9yx.js.map → chunk-rpxz486p.js.map} +4 -4
- package/dist/{chunk-drz59ve0.js → chunk-rx7h5fdx.js} +1 -1
- package/dist/{chunk-ky7zpbtt.js → chunk-s7ftxrdr.js} +106 -8
- package/dist/chunk-s7ftxrdr.js.map +22 -0
- package/dist/{chunk-yfppyaty.js → chunk-sk0hcjsz.js} +1 -1
- package/dist/{chunk-qne45xqq.js → chunk-svabwqdq.js} +2 -2
- package/dist/{chunk-xr7y35yj.js → chunk-t9shqx3w.js} +2 -2
- package/dist/{chunk-4jph1t3v.js → chunk-tjjgy3z4.js} +27 -24
- package/dist/{chunk-4jph1t3v.js.map → chunk-tjjgy3z4.js.map} +4 -4
- package/dist/{chunk-ex8s8wsk.js → chunk-vp3z1ckh.js} +42 -10
- package/dist/{chunk-ex8s8wsk.js.map → chunk-vp3z1ckh.js.map} +7 -6
- package/dist/{chunk-adbve9zt.js → chunk-vre348sb.js} +2 -2
- package/dist/{chunk-a4g5yjm0.js → chunk-w9yycd3t.js} +1 -1
- package/dist/{chunk-g4rbm4a6.js → chunk-wt4szfec.js} +379 -331
- package/dist/chunk-wt4szfec.js.map +14 -0
- package/dist/{chunk-wd34wnsy.js → chunk-xcy5ddha.js} +6 -6
- package/dist/{chunk-3nx8vj5a.js → chunk-xyvy73tj.js} +5 -3
- package/dist/chunk-xyvy73tj.js.map +12 -0
- package/dist/datasets/write.js +1 -1
- package/dist/execution/agent.js +38 -37
- package/dist/execution/agent.js.map +1 -1
- package/dist/execution/authorized-object-reader.d.ts +3 -1
- package/dist/execution/authorized-object-reader.d.ts.map +1 -1
- package/dist/execution/primitive.js +36 -35
- package/dist/execution/primitive.js.map +2 -2
- package/dist/execution/request.js +37 -36
- package/dist/execution/request.js.map +2 -2
- package/dist/index.d.ts +8 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +62 -59
- package/dist/index.js.map +1 -1
- package/dist/lake-storage/in-memory.d.ts +5 -1
- package/dist/lake-storage/in-memory.d.ts.map +1 -1
- package/dist/lake-storage/index.d.ts +1 -1
- package/dist/lake-storage/index.d.ts.map +1 -1
- package/dist/lake-storage/index.js +2 -2
- package/dist/lake-storage/types.d.ts +26 -0
- package/dist/lake-storage/types.d.ts.map +1 -1
- package/dist/maintenance/ontology-maintenance.d.ts +5 -1
- package/dist/maintenance/ontology-maintenance.d.ts.map +1 -1
- package/dist/maintenance/types.d.ts +1 -4
- package/dist/maintenance/types.d.ts.map +1 -1
- package/dist/materialization/event-envelopes.d.ts +20 -0
- package/dist/materialization/event-envelopes.d.ts.map +1 -0
- package/dist/materialization/events.d.ts +29 -3
- package/dist/materialization/events.d.ts.map +1 -1
- package/dist/materialization/index.d.ts +4 -1
- package/dist/materialization/index.d.ts.map +1 -1
- package/dist/materialization/index.js +9 -3
- package/dist/materialization/index.js.map +1 -1
- package/dist/materializer/edits/plan.d.ts +2 -10
- package/dist/materializer/edits/plan.d.ts.map +1 -1
- package/dist/materializer/effective/build-events.d.ts +5 -21
- package/dist/materializer/effective/build-events.d.ts.map +1 -1
- package/dist/materializer/effective/vector-indexing.d.ts +2 -3
- package/dist/materializer/effective/vector-indexing.d.ts.map +1 -1
- package/dist/materializer/effective/vectors.d.ts +2 -3
- package/dist/materializer/effective/vectors.d.ts.map +1 -1
- package/dist/materializer/execution/scope.d.ts +1 -11
- package/dist/materializer/execution/scope.d.ts.map +1 -1
- package/dist/materializer/execution/work-executor.d.ts +5 -7
- package/dist/materializer/execution/work-executor.d.ts.map +1 -1
- package/dist/materializer/execution/work-records.d.ts +1 -3
- package/dist/materializer/execution/work-records.d.ts.map +1 -1
- package/dist/materializer/index.js +31 -32
- package/dist/materializer/index.js.map +1 -1
- package/dist/materializer/projections/replace.d.ts.map +1 -1
- package/dist/materializer/projections/replacement-plan.d.ts +8 -11
- package/dist/materializer/projections/replacement-plan.d.ts.map +1 -1
- package/dist/materializer/shared/batching.d.ts +5 -0
- package/dist/materializer/shared/batching.d.ts.map +1 -1
- package/dist/materializer/telemetry/plan.d.ts +2 -8
- package/dist/materializer/telemetry/plan.d.ts.map +1 -1
- package/dist/models/audio/catalog.d.ts +20 -0
- package/dist/models/audio/catalog.d.ts.map +1 -0
- package/dist/models/audio/errors.d.ts +8 -0
- package/dist/models/audio/errors.d.ts.map +1 -0
- package/dist/models/audio/file.d.ts +9 -0
- package/dist/models/audio/file.d.ts.map +1 -0
- package/dist/models/audio/runtime.d.ts +8 -0
- package/dist/models/audio/runtime.d.ts.map +1 -0
- package/dist/models/audio/types.d.ts +60 -0
- package/dist/models/audio/types.d.ts.map +1 -0
- package/dist/models/catalog.d.ts +23 -1
- package/dist/models/catalog.d.ts.map +1 -1
- package/dist/models/definitions.d.ts +1 -1
- package/dist/models/definitions.d.ts.map +1 -1
- package/dist/models/embedding-model.d.ts +4 -0
- package/dist/models/embedding-model.d.ts.map +1 -1
- package/dist/models/events.d.ts +3 -0
- package/dist/models/events.d.ts.map +1 -1
- package/dist/models/execution/index.js +22 -22
- package/dist/models/execution/model-call-admission.d.ts +6 -1
- package/dist/models/execution/model-call-admission.d.ts.map +1 -1
- package/dist/models/execution/model-call-limits.d.ts.map +1 -1
- package/dist/models/execution/model-call-recorder.d.ts.map +1 -1
- package/dist/models/execution/reranking.d.ts +4 -0
- package/dist/models/execution/reranking.d.ts.map +1 -0
- package/dist/models/execution/usage.d.ts.map +1 -1
- package/dist/models/execution.d.ts +2 -1
- package/dist/models/execution.d.ts.map +1 -1
- package/dist/models/generation-types.d.ts +2 -0
- package/dist/models/generation-types.d.ts.map +1 -1
- package/dist/models/index.d.ts +7 -1
- package/dist/models/index.d.ts.map +1 -1
- package/dist/models/index.js +7 -3
- package/dist/models/index.js.map +1 -1
- package/dist/models/pricing.d.ts +2 -2
- package/dist/models/pricing.d.ts.map +1 -1
- package/dist/models/reranking-model.d.ts +49 -0
- package/dist/models/reranking-model.d.ts.map +1 -0
- package/dist/objects/index.js +25 -25
- package/dist/objects/query/executor.d.ts +2 -1
- package/dist/objects/query/executor.d.ts.map +1 -1
- package/dist/objects/query/index.d.ts +1 -1
- package/dist/objects/query/index.d.ts.map +1 -1
- package/dist/objects/query/index.js +24 -24
- package/dist/objects/query/index.js.map +1 -1
- package/dist/objects/query/ir.d.ts +8 -1
- package/dist/objects/query/ir.d.ts.map +1 -1
- package/dist/objects/query/normalize.d.ts.map +1 -1
- package/dist/objects/query/planner.d.ts +1 -1
- package/dist/objects/query/planner.d.ts.map +1 -1
- package/dist/objects/query/primary-id.d.ts +7 -0
- package/dist/objects/query/primary-id.d.ts.map +1 -0
- package/dist/objects/query/reranking-executor.d.ts +13 -0
- package/dist/objects/query/reranking-executor.d.ts.map +1 -0
- package/dist/objects/query/reranking-limits.d.ts +3 -0
- package/dist/objects/query/reranking-limits.d.ts.map +1 -0
- package/dist/objects/query/reranking-query.d.ts +4 -0
- package/dist/objects/query/reranking-query.d.ts.map +1 -0
- package/dist/objects/query/validate.d.ts.map +1 -1
- package/dist/objects/sdk/query-builder.d.ts +8 -0
- package/dist/objects/sdk/query-builder.d.ts.map +1 -1
- package/dist/objects/sdk/query-executor.d.ts +2 -2
- package/dist/objects/sdk/query-executor.d.ts.map +1 -1
- package/dist/objects/sdk/runtime-query-executor.d.ts.map +1 -1
- package/dist/objects/vectors/indexing-dispatch.d.ts +21 -0
- package/dist/objects/vectors/indexing-dispatch.d.ts.map +1 -0
- package/dist/objects/vectors/indexing-generate.d.ts.map +1 -1
- package/dist/objects/vectors/profile.d.ts.map +1 -1
- package/dist/objects/vectors/query.d.ts +1 -1
- package/dist/objects/vectors/query.d.ts.map +1 -1
- package/dist/objects/vectors/resolve-query.d.ts.map +1 -1
- package/dist/objects/vectors/types.d.ts +1 -1
- package/dist/objects/vectors/types.d.ts.map +1 -1
- package/dist/ontology/builders.d.ts +13 -4
- package/dist/ontology/builders.d.ts.map +1 -1
- package/dist/ontology/index.d.ts +1 -1
- package/dist/ontology/index.d.ts.map +1 -1
- package/dist/ontology/index.js +3 -3
- package/dist/ontology/internal.js +2 -2
- package/dist/ontology/query-capabilities.d.ts +1 -0
- package/dist/ontology/query-capabilities.d.ts.map +1 -1
- package/dist/ontology/types.d.ts +20 -0
- package/dist/ontology/types.d.ts.map +1 -1
- package/dist/ontology/validation/query.d.ts.map +1 -1
- package/dist/ontology/vector-profiles.d.ts.map +1 -1
- package/dist/pipelines/index.js +23 -23
- package/dist/projections/internal.js +22 -22
- package/dist/query.d.ts +4 -2
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +2 -2
- package/dist/queues/in-memory.d.ts +3 -0
- package/dist/queues/in-memory.d.ts.map +1 -1
- package/dist/queues/index.js +1 -1
- package/dist/queues/types.d.ts +4 -0
- package/dist/queues/types.d.ts.map +1 -1
- package/dist/runtime/host.d.ts +1 -0
- package/dist/runtime/host.d.ts.map +1 -1
- package/dist/runtime/index.d.ts +1 -1
- package/dist/runtime/index.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/internal.js +28 -26
- package/dist/runtime/internal.js.map +1 -1
- package/dist/runtime/public-origin.d.ts +10 -0
- package/dist/runtime/public-origin.d.ts.map +1 -0
- package/dist/runtime/sixb.d.ts +1 -0
- package/dist/runtime/sixb.d.ts.map +1 -1
- package/dist/runtime/types.d.ts +12 -2
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/sandboxes/index.js +5 -5
- package/dist/shares/internal.js +19 -19
- package/dist/storage/agents/provider.js +2 -2
- package/dist/storage/ai-cost/analytics.d.ts +1 -0
- package/dist/storage/ai-cost/analytics.d.ts.map +1 -1
- package/dist/storage/ai-cost/provider.js +3 -3
- package/dist/storage/ai-cost/types.d.ts +1 -1
- package/dist/storage/ai-cost/types.d.ts.map +1 -1
- package/dist/storage/ai-cost/validation.d.ts.map +1 -1
- package/dist/storage/ai-limits/enforcement.js +2 -2
- package/dist/storage/ai-limits/in-memory.d.ts.map +1 -1
- package/dist/storage/ai-limits/provider.d.ts +7 -2
- package/dist/storage/ai-limits/provider.d.ts.map +1 -1
- package/dist/storage/ai-limits/provider.js +4 -2
- package/dist/storage/ai-limits/provider.js.map +1 -1
- package/dist/storage/ai-limits/types.d.ts +3 -0
- package/dist/storage/ai-limits/types.d.ts.map +1 -1
- package/dist/storage/ai-usage/record.d.ts.map +1 -1
- package/dist/storage/ai-usage/types.d.ts +8 -4
- package/dist/storage/ai-usage/types.d.ts.map +1 -1
- package/dist/storage/ai-usage/usage.d.ts.map +1 -1
- package/dist/storage/file-download-grants/in-memory.d.ts +11 -0
- package/dist/storage/file-download-grants/in-memory.d.ts.map +1 -0
- package/dist/storage/file-download-grants/index.d.ts +3 -0
- package/dist/storage/file-download-grants/index.d.ts.map +1 -0
- package/dist/storage/file-download-grants/record.d.ts +11 -0
- package/dist/storage/file-download-grants/record.d.ts.map +1 -0
- package/dist/storage/file-download-grants/types.d.ts +44 -0
- package/dist/storage/file-download-grants/types.d.ts.map +1 -0
- package/dist/storage/file-upload-sessions/provider.js +6 -6
- package/dist/storage/in-memory/index.d.ts +4 -0
- package/dist/storage/in-memory/index.d.ts.map +1 -1
- package/dist/storage/index.d.ts +5 -3
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/index.js +30 -30
- package/dist/storage/index.js.map +1 -1
- package/dist/storage/internal.d.ts +1 -0
- package/dist/storage/internal.d.ts.map +1 -1
- package/dist/storage/internal.js +8 -4
- package/dist/storage/internal.js.map +1 -1
- package/dist/storage/migrations/index.d.ts +1 -1
- package/dist/storage/migrations/index.d.ts.map +1 -1
- package/dist/storage/migrations/migrate-storage.d.ts +3 -3
- package/dist/storage/migrations/migrate-storage.d.ts.map +1 -1
- package/dist/storage/migrations/types.d.ts +7 -0
- package/dist/storage/migrations/types.d.ts.map +1 -1
- package/dist/storage/objects/in-memory/query.d.ts.map +1 -1
- package/dist/storage/objects/in-memory/selected-reader.d.ts.map +1 -1
- package/dist/storage/objects/in-memory/storage.d.ts.map +1 -1
- package/dist/storage/objects/query-preparation.d.ts +39 -0
- package/dist/storage/objects/query-preparation.d.ts.map +1 -0
- package/dist/storage/objects/types.d.ts +2 -0
- package/dist/storage/objects/types.d.ts.map +1 -1
- package/dist/storage/ontology/commits.d.ts +1 -6
- package/dist/storage/ontology/commits.d.ts.map +1 -1
- package/dist/storage/ontology/in-memory/index.d.ts +4 -2
- package/dist/storage/ontology/in-memory/index.d.ts.map +1 -1
- package/dist/storage/ontology/in-memory/materializations-state.d.ts +0 -2
- package/dist/storage/ontology/in-memory/materializations-state.d.ts.map +1 -1
- package/dist/storage/ontology/in-memory/materializations-work.d.ts +1 -3
- package/dist/storage/ontology/in-memory/materializations-work.d.ts.map +1 -1
- package/dist/storage/ontology/in-memory/materializations.d.ts +23 -57
- package/dist/storage/ontology/in-memory/materializations.d.ts.map +1 -1
- package/dist/storage/ontology/in-memory/outbox.d.ts +3 -2
- package/dist/storage/ontology/in-memory/outbox.d.ts.map +1 -1
- package/dist/storage/ontology/in-memory/replacement-plans.d.ts +104 -0
- package/dist/storage/ontology/in-memory/replacement-plans.d.ts.map +1 -0
- package/dist/storage/ontology/in-memory/shared-state.d.ts +17 -2
- package/dist/storage/ontology/in-memory/shared-state.d.ts.map +1 -1
- package/dist/storage/ontology/in-memory/source-roots.d.ts +3 -1
- package/dist/storage/ontology/in-memory/source-roots.d.ts.map +1 -1
- package/dist/storage/ontology/in-memory/sources.d.ts +1 -2
- package/dist/storage/ontology/in-memory/sources.d.ts.map +1 -1
- package/dist/storage/ontology/in-memory/state-reader.d.ts +25 -0
- package/dist/storage/ontology/in-memory/state-reader.d.ts.map +1 -0
- package/dist/storage/ontology/index.d.ts +6 -3
- package/dist/storage/ontology/index.d.ts.map +1 -1
- package/dist/storage/ontology/materializations.d.ts +40 -59
- package/dist/storage/ontology/materializations.d.ts.map +1 -1
- package/dist/storage/ontology/outbox.d.ts +4 -6
- package/dist/storage/ontology/outbox.d.ts.map +1 -1
- package/dist/storage/ontology/provider-work.d.ts +114 -3
- package/dist/storage/ontology/provider-work.d.ts.map +1 -1
- package/dist/storage/ontology/provider.d.ts +14 -39
- package/dist/storage/ontology/provider.d.ts.map +1 -1
- package/dist/storage/ontology/provider.js +26 -12
- package/dist/storage/ontology/provider.js.map +1 -1
- package/dist/storage/ontology/replacement-plans.d.ts +103 -0
- package/dist/storage/ontology/replacement-plans.d.ts.map +1 -0
- package/dist/storage/ontology/sources.d.ts +0 -8
- package/dist/storage/ontology/sources.d.ts.map +1 -1
- package/dist/storage/operation-scope.d.ts.map +1 -1
- package/dist/storage/operation-scope.js +1 -1
- package/dist/storage/projection-runs/in-memory.d.ts.map +1 -1
- package/dist/storage/projection-runs/types.d.ts +2 -0
- package/dist/storage/projection-runs/types.d.ts.map +1 -1
- package/dist/storage/types.d.ts +2 -0
- package/dist/storage/types.d.ts.map +1 -1
- package/dist/storage/workflow-runs/provider.js +6 -6
- package/dist/syncs/index.js +24 -24
- package/dist/testing/ai-cost-storage-contract.d.ts.map +1 -1
- package/dist/testing/ai-limit-storage-contract.d.ts.map +1 -1
- package/dist/testing/ai-usage-storage-contract.d.ts.map +1 -1
- package/dist/testing/file-download-grant-storage-contract.d.ts +9 -0
- package/dist/testing/file-download-grant-storage-contract.d.ts.map +1 -0
- package/dist/testing/index.d.ts +1 -0
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +2548 -1489
- package/dist/testing/index.js.map +14 -13
- package/dist/testing/lake-storage-contract.d.ts.map +1 -1
- package/dist/testing/materializer-storage-contract.d.ts +14 -0
- package/dist/testing/materializer-storage-contract.d.ts.map +1 -1
- package/dist/testing/object-read-scope-contract.d.ts.map +1 -1
- package/dist/testing/ontology-contract-fixture.d.ts +5 -1
- package/dist/testing/ontology-contract-fixture.d.ts.map +1 -1
- package/dist/testing/ontology-storage-contract.d.ts.map +1 -1
- package/dist/testing/projection-run-storage-contract.d.ts.map +1 -1
- package/dist/testing/queues-contract.d.ts.map +1 -1
- package/dist/webhooks/internal.js +20 -20
- package/dist/workers/index.js +15 -17
- package/dist/workers/index.js.map +3 -3
- package/dist/workers/queue-worker.d.ts +3 -2
- package/dist/workers/queue-worker.d.ts.map +1 -1
- package/dist/workflows/index.js +42 -41
- package/dist/workflows/index.js.map +1 -1
- package/package.json +7 -1
- package/src/actions/types/context.ts +5 -2
- package/src/blob-storage/download-urls.ts +138 -0
- package/src/blob-storage/execution.ts +32 -1
- package/src/blob-storage/internal.ts +1 -0
- package/src/execution/authorized-object-reader.ts +8 -1
- package/src/index.ts +25 -0
- package/src/lake-storage/in-memory.ts +38 -9
- package/src/lake-storage/index.ts +2 -0
- package/src/lake-storage/types.ts +30 -0
- package/src/maintenance/ontology-maintenance.ts +50 -23
- package/src/maintenance/types.ts +1 -4
- package/src/materialization/event-envelopes.ts +168 -0
- package/src/materialization/events.ts +40 -4
- package/src/materialization/index.ts +9 -1
- package/src/materializer/README.md +55 -10
- package/src/materializer/edits/commit.ts +3 -19
- package/src/materializer/edits/plan.ts +20 -71
- package/src/materializer/effective/build-events.ts +42 -136
- package/src/materializer/effective/vector-indexing.ts +2 -3
- package/src/materializer/effective/vectors.ts +2 -3
- package/src/materializer/execution/scope.ts +1 -38
- package/src/materializer/execution/work-executor.ts +21 -115
- package/src/materializer/execution/work-records.ts +0 -15
- package/src/materializer/projections/replace.ts +106 -63
- package/src/materializer/projections/replacement-plan.ts +73 -218
- package/src/materializer/shared/batching.ts +7 -0
- package/src/materializer/telemetry/append.ts +2 -14
- package/src/materializer/telemetry/plan.ts +6 -43
- package/src/models/audio/catalog.ts +90 -0
- package/src/models/audio/errors.ts +19 -0
- package/src/models/audio/file.ts +78 -0
- package/src/models/audio/runtime.ts +182 -0
- package/src/models/audio/types.ts +69 -0
- package/src/models/catalog.ts +52 -5
- package/src/models/definitions.ts +8 -1
- package/src/models/embedding-model.ts +12 -0
- package/src/models/events.ts +3 -0
- package/src/models/execution/README.md +20 -1
- package/src/models/execution/embedding.ts +5 -1
- package/src/models/execution/model-call-admission.ts +6 -1
- package/src/models/execution/model-call-limits.ts +21 -11
- package/src/models/execution/model-call-recorder.ts +1 -0
- package/src/models/execution/model-call-recovery.ts +1 -0
- package/src/models/execution/reranking.ts +137 -0
- package/src/models/execution/usage.ts +1 -0
- package/src/models/execution.ts +5 -1
- package/src/models/generation-types.ts +2 -0
- package/src/models/index.ts +32 -0
- package/src/models/pricing.ts +2 -1
- package/src/models/reranking-model.ts +114 -0
- package/src/objects/query/executor.ts +42 -2
- package/src/objects/query/explain.ts +8 -0
- package/src/objects/query/index.ts +1 -0
- package/src/objects/query/ir.ts +10 -0
- package/src/objects/query/normalize.ts +2 -0
- package/src/objects/query/planner.ts +12 -1
- package/src/objects/query/primary-id.ts +56 -0
- package/src/objects/query/reranking-executor.ts +91 -0
- package/src/objects/query/reranking-limits.ts +3 -0
- package/src/objects/query/reranking-query.ts +8 -0
- package/src/objects/query/validate.ts +33 -10
- package/src/objects/sdk/query-builder.ts +15 -2
- package/src/objects/sdk/query-executor.ts +2 -2
- package/src/objects/sdk/runtime-query-executor.ts +7 -4
- package/src/objects/vectors/README.md +14 -2
- package/src/objects/vectors/handle.ts +1 -1
- package/src/objects/vectors/indexing-dispatch.ts +83 -0
- package/src/objects/vectors/indexing-generate.ts +5 -1
- package/src/objects/vectors/profile.ts +2 -0
- package/src/objects/vectors/query.ts +21 -4
- package/src/objects/vectors/resolve-query.ts +9 -5
- package/src/objects/vectors/types.ts +3 -1
- package/src/ontology/builders.ts +22 -7
- package/src/ontology/index.ts +2 -0
- package/src/ontology/query-capabilities.ts +1 -1
- package/src/ontology/types.ts +21 -0
- package/src/ontology/validation/query.ts +57 -0
- package/src/ontology/vector-profiles.ts +1 -0
- package/src/query.ts +4 -0
- package/src/queues/in-memory.ts +54 -19
- package/src/queues/types.ts +4 -0
- package/src/runtime/host.ts +28 -1
- package/src/runtime/index.ts +1 -0
- package/src/runtime/internal.ts +1 -0
- package/src/runtime/public-origin.ts +33 -0
- package/src/runtime/sixb.ts +13 -2
- package/src/runtime/types.ts +12 -2
- package/src/storage/ai-cost/analytics.ts +2 -0
- package/src/storage/ai-cost/codec.ts +2 -1
- package/src/storage/ai-cost/types.ts +1 -0
- package/src/storage/ai-cost/validation.ts +21 -8
- package/src/storage/ai-limits/in-memory.ts +10 -2
- package/src/storage/ai-limits/provider.ts +29 -2
- package/src/storage/ai-limits/types.ts +3 -0
- package/src/storage/ai-usage/record.ts +9 -0
- package/src/storage/ai-usage/types.ts +8 -4
- package/src/storage/ai-usage/usage.ts +2 -0
- package/src/storage/file-download-grants/in-memory.ts +73 -0
- package/src/storage/file-download-grants/index.ts +8 -0
- package/src/storage/file-download-grants/record.ts +47 -0
- package/src/storage/file-download-grants/types.ts +48 -0
- package/src/storage/in-memory/index.ts +13 -2
- package/src/storage/index.ts +31 -13
- package/src/storage/internal.ts +1 -0
- package/src/storage/migrations/index.ts +1 -0
- package/src/storage/migrations/migrate-storage.ts +36 -12
- package/src/storage/migrations/types.ts +8 -0
- package/src/storage/objects/in-memory/query.ts +2 -0
- package/src/storage/objects/in-memory/selected-reader.ts +1 -0
- package/src/storage/objects/in-memory/storage.ts +1 -0
- package/src/storage/objects/query-preparation.ts +77 -0
- package/src/storage/objects/types.ts +2 -0
- package/src/storage/ontology/commits.ts +1 -6
- package/src/storage/ontology/in-memory/index.ts +28 -9
- package/src/storage/ontology/in-memory/materializations-finalization.ts +35 -68
- package/src/storage/ontology/in-memory/materializations-state.ts +0 -22
- package/src/storage/ontology/in-memory/materializations-work.ts +0 -45
- package/src/storage/ontology/in-memory/materializations.ts +172 -653
- package/src/storage/ontology/in-memory/outbox.ts +37 -29
- package/src/storage/ontology/in-memory/replacement-plans.ts +697 -0
- package/src/storage/ontology/in-memory/shared-state.ts +24 -2
- package/src/storage/ontology/in-memory/source-roots.ts +7 -2
- package/src/storage/ontology/in-memory/sources.ts +7 -33
- package/src/storage/ontology/in-memory/state-reader.ts +245 -0
- package/src/storage/ontology/index.ts +19 -13
- package/src/storage/ontology/materializations.ts +45 -74
- package/src/storage/ontology/outbox.ts +4 -7
- package/src/storage/ontology/provider-header-validation.ts +0 -57
- package/src/storage/ontology/provider-work.ts +381 -90
- package/src/storage/ontology/provider.ts +74 -171
- package/src/storage/ontology/replacement-plans.ts +117 -0
- package/src/storage/ontology/sources.ts +0 -12
- package/src/storage/operation-scope.ts +33 -1
- package/src/storage/projection-runs/in-memory.ts +7 -1
- package/src/storage/projection-runs/types.ts +2 -0
- package/src/storage/types.ts +2 -0
- package/src/testing/ai-cost-storage-contract.ts +1 -0
- package/src/testing/ai-limit-storage-contract.ts +62 -0
- package/src/testing/ai-usage-storage-contract.ts +31 -0
- package/src/testing/file-download-grant-storage-contract.ts +139 -0
- package/src/testing/index.ts +4 -0
- package/src/testing/lake-storage-contract.ts +87 -1
- package/src/testing/materializer-storage-contract.ts +1008 -1
- package/src/testing/object-read-scope-contract.ts +1 -0
- package/src/testing/ontology-contract-fixture.ts +11 -87
- package/src/testing/ontology-storage-contract.ts +70 -39
- package/src/testing/projection-run-storage-contract.ts +14 -0
- package/src/testing/queues-contract.ts +59 -0
- package/src/workers/queue-worker.ts +19 -16
- package/dist/chunk-3c90jvfj.js.map +0 -15
- package/dist/chunk-3nx8vj5a.js.map +0 -12
- package/dist/chunk-7ytf06d3.js +0 -113
- package/dist/chunk-7ytf06d3.js.map +0 -10
- package/dist/chunk-a0073121.js.map +0 -12
- package/dist/chunk-fjw417jf.js.map +0 -62
- package/dist/chunk-g4rbm4a6.js.map +0 -15
- package/dist/chunk-hgqpcmyr.js.map +0 -12
- package/dist/chunk-jgwb25gc.js.map +0 -12
- package/dist/chunk-k4kkp58d.js.map +0 -11
- package/dist/chunk-ky7zpbtt.js.map +0 -19
- package/dist/chunk-mdnw7nj8.js.map +0 -15
- package/dist/chunk-py2dw8cw.js.map +0 -17
- package/dist/chunk-s3csryxe.js.map +0 -11
- package/dist/chunk-xnx96gfy.js.map +0 -15
- package/dist/chunk-z708gemf.js.map +0 -50
- package/dist/materializer/execution/plan-stream.d.ts +0 -8
- package/dist/materializer/execution/plan-stream.d.ts.map +0 -1
- package/src/materializer/execution/plan-stream.ts +0 -121
- /package/dist/{chunk-q3grgzp1.js.map → chunk-23xs4qp9.js.map} +0 -0
- /package/dist/{chunk-vef6qa14.js.map → chunk-2am3db31.js.map} +0 -0
- /package/dist/{chunk-fj1dvp37.js.map → chunk-2vhg6ysa.js.map} +0 -0
- /package/dist/{chunk-p0nbkys4.js.map → chunk-33saed7g.js.map} +0 -0
- /package/dist/{chunk-mmac1mp6.js.map → chunk-52c5zb0z.js.map} +0 -0
- /package/dist/{chunk-8fjmqjyx.js.map → chunk-5be2ath4.js.map} +0 -0
- /package/dist/{chunk-2fv8sajb.js.map → chunk-5thzcb8g.js.map} +0 -0
- /package/dist/{chunk-1jvq82rp.js.map → chunk-9g6jz9kk.js.map} +0 -0
- /package/dist/{chunk-8w27xf9e.js.map → chunk-a7er86jd.js.map} +0 -0
- /package/dist/{chunk-bxx3ms5t.js.map → chunk-c2rga5cx.js.map} +0 -0
- /package/dist/{chunk-dsfw1bdr.js.map → chunk-cnb5kv05.js.map} +0 -0
- /package/dist/{chunk-n5t4mq6z.js.map → chunk-e67ynxcr.js.map} +0 -0
- /package/dist/{chunk-6q7c68yx.js.map → chunk-f1xh7a32.js.map} +0 -0
- /package/dist/{chunk-7jc21943.js.map → chunk-gf7yht60.js.map} +0 -0
- /package/dist/{chunk-ffwvdgk1.js.map → chunk-jjrn5v0p.js.map} +0 -0
- /package/dist/{chunk-r5sc1d2b.js.map → chunk-jnfxmr3f.js.map} +0 -0
- /package/dist/{chunk-y0zmae99.js.map → chunk-k4g51s47.js.map} +0 -0
- /package/dist/{chunk-drz59ve0.js.map → chunk-rx7h5fdx.js.map} +0 -0
- /package/dist/{chunk-yfppyaty.js.map → chunk-sk0hcjsz.js.map} +0 -0
- /package/dist/{chunk-qne45xqq.js.map → chunk-svabwqdq.js.map} +0 -0
- /package/dist/{chunk-xr7y35yj.js.map → chunk-t9shqx3w.js.map} +0 -0
- /package/dist/{chunk-adbve9zt.js.map → chunk-vre348sb.js.map} +0 -0
- /package/dist/{chunk-a4g5yjm0.js.map → chunk-w9yycd3t.js.map} +0 -0
- /package/dist/{chunk-wd34wnsy.js.map → chunk-xcy5ddha.js.map} +0 -0
package/src/runtime/internal.ts
CHANGED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The origin the API is reachable at from outside, for features that hand out absolute URLs a
|
|
3
|
+
* third party will fetch. It is deployment topology, not app configuration: the API server
|
|
4
|
+
* records the `publicOrigin` it was started with, and the CLI records `SIXB_API_PUBLIC_ORIGIN`
|
|
5
|
+
* for worker processes. A process that never learns it cannot issue such URLs.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const apiPublicOrigins = new WeakMap<object, string>()
|
|
9
|
+
|
|
10
|
+
/** Record where the API is reachable. A host served by several servers keeps the latest one. */
|
|
11
|
+
export function setApiPublicOrigin(host: object, origin: string): void {
|
|
12
|
+
apiPublicOrigins.set(host, normalizeOrigin(origin))
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function getApiPublicOrigin(host: object): string | undefined {
|
|
16
|
+
return apiPublicOrigins.get(host)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function normalizeOrigin(value: string): string {
|
|
20
|
+
let url: URL
|
|
21
|
+
try {
|
|
22
|
+
url = new URL(value)
|
|
23
|
+
} catch {
|
|
24
|
+
throw new Error(`[Sixb] Invalid API public origin: '${value}'.`)
|
|
25
|
+
}
|
|
26
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") {
|
|
27
|
+
throw new Error("[Sixb] The API public origin must use http or https.")
|
|
28
|
+
}
|
|
29
|
+
if (url.pathname !== "/" || url.search || url.hash) {
|
|
30
|
+
throw new Error("[Sixb] The API public origin must be an origin, not a full URL.")
|
|
31
|
+
}
|
|
32
|
+
return url.origin
|
|
33
|
+
}
|
package/src/runtime/sixb.ts
CHANGED
|
@@ -65,6 +65,7 @@ export interface SixbDependencies {
|
|
|
65
65
|
readonly connectorService: ConnectorService
|
|
66
66
|
readonly connectorConnections?: ConnectorConnectionProcess
|
|
67
67
|
readonly blobStorage: BlobStorage
|
|
68
|
+
readonly apiPublicOrigin: () => string | undefined
|
|
68
69
|
readonly lakeStorage: LakeStorage
|
|
69
70
|
}
|
|
70
71
|
|
|
@@ -129,13 +130,23 @@ function createExecutionFacades<TParams extends Record<string, unknown>>(
|
|
|
129
130
|
dependencies.definitions.models,
|
|
130
131
|
dependencies.sandbox
|
|
131
132
|
),
|
|
132
|
-
models: createModelsRuntime(
|
|
133
|
+
models: createModelsRuntime(
|
|
134
|
+
runtime,
|
|
135
|
+
execution,
|
|
136
|
+
dependencies.definitions.models,
|
|
137
|
+
dependencies.blobStorage
|
|
138
|
+
),
|
|
133
139
|
aiUsage: createAiUsageRuntime(runtime, dependencies.definitions.security),
|
|
134
140
|
events: createEventsRuntime(runtime),
|
|
135
141
|
logs: createLogsRuntime(runtime, dependencies.logging),
|
|
136
142
|
schedules: createSchedulesRuntime(runtime, dependencies.definitions.schedules),
|
|
137
143
|
shares: createSharesRuntime(runtime, execution, dependencies.definitions.shares),
|
|
138
144
|
connector: createConnectorRuntime(runtime, execution, dependencies.connectorService),
|
|
139
|
-
blobs: createBlobsRuntime(
|
|
145
|
+
blobs: createBlobsRuntime(
|
|
146
|
+
runtime,
|
|
147
|
+
execution,
|
|
148
|
+
dependencies.blobStorage,
|
|
149
|
+
dependencies.apiPublicOrigin
|
|
150
|
+
),
|
|
140
151
|
}
|
|
141
152
|
}
|
package/src/runtime/types.ts
CHANGED
|
@@ -16,7 +16,7 @@ import type { Broker } from "../broker"
|
|
|
16
16
|
import type { DomainEventLog } from "../events"
|
|
17
17
|
import type { RuntimeAuthorization } from "../execution"
|
|
18
18
|
import type { AuthorizedObjectReader } from "../execution/authorized-object-reader"
|
|
19
|
-
import type { EmbeddingModelCatalog } from "../models"
|
|
19
|
+
import type { EmbeddingModelCatalog, RerankingModelCatalog, RerankingModelRef } from "../models"
|
|
20
20
|
import type { ModelExecutionSession } from "../models/execution/session"
|
|
21
21
|
import type {
|
|
22
22
|
ObjectQuery,
|
|
@@ -58,6 +58,7 @@ import type { ActionRunRecord, ObjectLinkRow, Storage } from "../storage"
|
|
|
58
58
|
*/
|
|
59
59
|
export interface SixbHostContext {
|
|
60
60
|
readonly embeddingModels?: EmbeddingModelCatalog
|
|
61
|
+
readonly rerankingModels?: RerankingModelCatalog
|
|
61
62
|
readonly projectId: string
|
|
62
63
|
readonly broker: Broker
|
|
63
64
|
readonly ontology: OntologyRegistry
|
|
@@ -414,6 +415,12 @@ export type ObjectQueryFacetBucket = {
|
|
|
414
415
|
count: number
|
|
415
416
|
}
|
|
416
417
|
|
|
418
|
+
/** Total and facet buckets are calculated from the same matching set. */
|
|
419
|
+
export type ObjectQueryFacetsResult = {
|
|
420
|
+
total: number
|
|
421
|
+
facets: ObjectQueryFacetResult[]
|
|
422
|
+
}
|
|
423
|
+
|
|
417
424
|
export type ObjectQueryFacetResult = {
|
|
418
425
|
propertyId: string
|
|
419
426
|
buckets: ObjectQueryFacetBucket[]
|
|
@@ -669,6 +676,9 @@ export interface ObjectQueryBuilder<
|
|
|
669
676
|
options: { k: number }
|
|
670
677
|
): ObjectQueryBuilder<TObjectType, TRow>
|
|
671
678
|
|
|
679
|
+
/** Reorder up to 100 vector candidates with an explicitly registered server-side model. */
|
|
680
|
+
rerank(options: { model: RerankingModelRef }): ObjectQueryBuilder<TObjectType, TRow>
|
|
681
|
+
|
|
672
682
|
/** Follow an outgoing link and make the linked object type the current result type. */
|
|
673
683
|
traverse<TLinkToken extends LinkToken<TObjectType["id"], string, LinkTargetObjectTypeIdValue>>(
|
|
674
684
|
link: TLinkToken,
|
|
@@ -750,7 +760,7 @@ export interface ObjectQueryBuilder<
|
|
|
750
760
|
exists(): Promise<boolean>
|
|
751
761
|
|
|
752
762
|
/** Count matching objects by configured facetable properties. */
|
|
753
|
-
facets(input: readonly ObjectQueryFacetInput<TObjectType>[]): Promise<
|
|
763
|
+
facets(input: readonly ObjectQueryFacetInput<TObjectType>[]): Promise<ObjectQueryFacetsResult>
|
|
754
764
|
|
|
755
765
|
/** Execute this query with an outer limit of one and return the first object. */
|
|
756
766
|
first(): Promise<Simplify<TRow> | null>
|
|
@@ -68,6 +68,7 @@ export interface AiAccountingAggregateFragment {
|
|
|
68
68
|
readonly cacheWriteInputTokens: AiAccountingUsageMeterFragment
|
|
69
69
|
readonly textOutputTokens: AiAccountingUsageMeterFragment
|
|
70
70
|
readonly reasoningOutputTokens: AiAccountingUsageMeterFragment
|
|
71
|
+
readonly audioDurationMs: AiAccountingUsageMeterFragment
|
|
71
72
|
}
|
|
72
73
|
readonly costs: {
|
|
73
74
|
readonly amount?: AiMoney
|
|
@@ -406,6 +407,7 @@ const AGGREGATE_USAGE_FIELDS = [
|
|
|
406
407
|
"cacheWriteInputTokens",
|
|
407
408
|
"textOutputTokens",
|
|
408
409
|
"reasoningOutputTokens",
|
|
410
|
+
"audioDurationMs",
|
|
409
411
|
] as const
|
|
410
412
|
|
|
411
413
|
type AggregateUsageField = (typeof AGGREGATE_USAGE_FIELDS)[number]
|
|
@@ -110,7 +110,8 @@ function billableMeter(value: unknown): AiBillableMeter {
|
|
|
110
110
|
value !== "tokens.input.cacheWrite1h" &&
|
|
111
111
|
value !== "tokens.output.total" &&
|
|
112
112
|
value !== "tokens.output.text" &&
|
|
113
|
-
value !== "tokens.output.reasoning"
|
|
113
|
+
value !== "tokens.output.reasoning" &&
|
|
114
|
+
value !== "audio.input.milliseconds"
|
|
114
115
|
) {
|
|
115
116
|
throw invalidDetails()
|
|
116
117
|
}
|
|
@@ -15,8 +15,8 @@ import type {
|
|
|
15
15
|
} from "./types"
|
|
16
16
|
|
|
17
17
|
const SIGNED_INT64_MAX = 9_223_372_036_854_775_807n
|
|
18
|
-
const
|
|
19
|
-
const HALF_MILLION =
|
|
18
|
+
const UNITS_PER_MILLION = 1_000_000n
|
|
19
|
+
const HALF_MILLION = UNITS_PER_MILLION / 2n
|
|
20
20
|
const MAX_NUMERIC_TEXT_LENGTH = 128
|
|
21
21
|
const METER_ORDER: Readonly<Record<AiBillableMeter, number>> = {
|
|
22
22
|
"tokens.input.total": 0,
|
|
@@ -28,6 +28,7 @@ const METER_ORDER: Readonly<Record<AiBillableMeter, number>> = {
|
|
|
28
28
|
"tokens.output.total": 6,
|
|
29
29
|
"tokens.output.text": 7,
|
|
30
30
|
"tokens.output.reasoning": 8,
|
|
31
|
+
"audio.input.milliseconds": 9,
|
|
31
32
|
}
|
|
32
33
|
const METERS = new Set(Object.keys(METER_ORDER) as AiBillableMeter[])
|
|
33
34
|
const UNPRICEABLE_REASONS = new Set<AiUnpriceableReason>([
|
|
@@ -120,11 +121,7 @@ export function aiModelCallCostMatchesUsage(
|
|
|
120
121
|
const components = new Map(
|
|
121
122
|
record.estimate.components.map((component) => [component.meter, component])
|
|
122
123
|
)
|
|
123
|
-
if (
|
|
124
|
-
!inputComponentsMatchUsage(components, usage) ||
|
|
125
|
-
!outputComponentsMatchUsage(components, usage)
|
|
126
|
-
)
|
|
127
|
-
return false
|
|
124
|
+
if (!componentsMatchUsage(components, usage)) return false
|
|
128
125
|
}
|
|
129
126
|
if (record.status === "unpriceable") return true
|
|
130
127
|
if (record.components.length === 0 && isExternalValuationSource(record.priceSource.sourceId)) {
|
|
@@ -133,6 +130,22 @@ export function aiModelCallCostMatchesUsage(
|
|
|
133
130
|
|
|
134
131
|
const usage = normalizeAiModelCallUsage(usageRecord.usage)
|
|
135
132
|
const components = new Map(record.components.map((component) => [component.meter, component]))
|
|
133
|
+
return componentsMatchUsage(components, usage)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function componentsMatchUsage(
|
|
137
|
+
components: ReadonlyMap<AiBillableMeter, AiCostComponent>,
|
|
138
|
+
usage: AiModelCallUsage
|
|
139
|
+
): boolean {
|
|
140
|
+
const audio = components.get("audio.input.milliseconds")
|
|
141
|
+
if (audio) {
|
|
142
|
+
return (
|
|
143
|
+
components.size === 1 &&
|
|
144
|
+
usage.audioDurationMs !== undefined &&
|
|
145
|
+
BigInt(audio.quantity) === BigInt(usage.audioDurationMs)
|
|
146
|
+
)
|
|
147
|
+
}
|
|
148
|
+
|
|
136
149
|
return (
|
|
137
150
|
inputComponentsMatchUsage(components, usage) && outputComponentsMatchUsage(components, usage)
|
|
138
151
|
)
|
|
@@ -362,7 +375,7 @@ function calculateComponent(
|
|
|
362
375
|
): AiCostComponent {
|
|
363
376
|
const normalizedQuantity = parseQuantity(quantity, `${meter} quantity`)
|
|
364
377
|
const rate = parseNonnegativeInt64(rateAmountNanosPerMillion, `${meter} rate`)
|
|
365
|
-
const charge = (normalizedQuantity * rate + HALF_MILLION) /
|
|
378
|
+
const charge = (normalizedQuantity * rate + HALF_MILLION) / UNITS_PER_MILLION
|
|
366
379
|
assertSignedInt64(charge, `${meter} charge`)
|
|
367
380
|
return {
|
|
368
381
|
meter,
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
AiLimitOperationLock,
|
|
9
9
|
aiLimitAccountingEntryAppliesToSubject,
|
|
10
10
|
aiLimitAmountKey,
|
|
11
|
+
aiLimitMeterApplies,
|
|
11
12
|
aiLimitPolicyDimensionKey,
|
|
12
13
|
aiLimitQuantityFromAmount,
|
|
13
14
|
aiLimitReservationBuckets,
|
|
@@ -227,7 +228,12 @@ export class InMemoryAiLimitStorage implements AiLimitStorage {
|
|
|
227
228
|
const unavailablePolicies: AiLimitPolicyStatus[] = []
|
|
228
229
|
const unavailableReasons = new Set<"missingEstimate" | "incompleteAccounting">()
|
|
229
230
|
for (const policy of enabledPolicies) {
|
|
230
|
-
if (
|
|
231
|
+
if (
|
|
232
|
+
!subjectKeys.has(aiLimitSubjectKey(policy.subject)) ||
|
|
233
|
+
!aiLimitMeterApplies(policy.limit.meter, request.modelKind)
|
|
234
|
+
) {
|
|
235
|
+
continue
|
|
236
|
+
}
|
|
231
237
|
const limit = normalizeAiLimitAmount(policy.limit)
|
|
232
238
|
const estimate = estimates.get(aiLimitAmountKey(limit))
|
|
233
239
|
const status = await this.policyStatus(policy, request.period)
|
|
@@ -268,7 +274,8 @@ export class InMemoryAiLimitStorage implements AiLimitStorage {
|
|
|
268
274
|
const buckets = aiLimitReservationBuckets(
|
|
269
275
|
enabledPolicies,
|
|
270
276
|
request.subjects,
|
|
271
|
-
request.estimates
|
|
277
|
+
request.estimates,
|
|
278
|
+
request.modelKind
|
|
272
279
|
)
|
|
273
280
|
if (buckets.length === 0) return { status: "notRequired" }
|
|
274
281
|
for (const bucket of buckets) {
|
|
@@ -601,6 +608,7 @@ export class InMemoryAiLimitStorage implements AiLimitStorage {
|
|
|
601
608
|
attempt: record.attempt,
|
|
602
609
|
callId: record.callId,
|
|
603
610
|
occurredAt: new Date(record.occurredAt),
|
|
611
|
+
...(record.modelKind === undefined ? {} : { modelKind: record.modelKind }),
|
|
604
612
|
...(record.usage.totalTokens === undefined ? {} : { totalTokens: record.usage.totalTokens }),
|
|
605
613
|
requesterGroupIds: [...record.requesterGroupIds],
|
|
606
614
|
...(requester?.type === "user" || requester?.type === "serviceAccount"
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import type { ModelKind } from "../../models/definitions"
|
|
1
2
|
import type { AiMoney } from "../ai-cost"
|
|
2
3
|
import { AiLimitStorageError } from "./errors"
|
|
3
4
|
import { aiLimitCalendarMonth } from "./period"
|
|
4
5
|
import type {
|
|
6
|
+
AiLimitMeter,
|
|
5
7
|
AiLimitPeriod,
|
|
6
8
|
AiLimitPolicy,
|
|
7
9
|
AiLimitQuantity,
|
|
@@ -16,6 +18,20 @@ import type {
|
|
|
16
18
|
|
|
17
19
|
const SIGNED_INT64_MAX = 9_223_372_036_854_775_807n
|
|
18
20
|
|
|
21
|
+
// These calls are billed per audio second or per search, and their providers report no tokens.
|
|
22
|
+
// Token limits neither admit nor count them; cost limits still do.
|
|
23
|
+
const TOKENLESS_MODEL_KINDS: ReadonlySet<ModelKind> = new Set(["transcription", "reranking"])
|
|
24
|
+
|
|
25
|
+
/** @internal Whether a limit meter governs calls of this kind. Unclassified calls are metered. */
|
|
26
|
+
export function aiLimitMeterApplies(
|
|
27
|
+
meter: AiLimitMeter,
|
|
28
|
+
modelKind: ModelKind | undefined
|
|
29
|
+
): boolean {
|
|
30
|
+
return (
|
|
31
|
+
meter !== "tokens.total" || modelKind === undefined || !TOKENLESS_MODEL_KINDS.has(modelKind)
|
|
32
|
+
)
|
|
33
|
+
}
|
|
34
|
+
|
|
19
35
|
/** @internal Serialize compound limit operations, including within an existing transaction. */
|
|
20
36
|
export class AiLimitOperationLock {
|
|
21
37
|
private tail: Promise<void> = Promise.resolve()
|
|
@@ -55,6 +71,7 @@ export interface AiLimitAccountingEntry {
|
|
|
55
71
|
readonly attempt: number
|
|
56
72
|
readonly callId: string
|
|
57
73
|
readonly occurredAt: Date
|
|
74
|
+
readonly modelKind?: ModelKind
|
|
58
75
|
readonly totalTokens?: number
|
|
59
76
|
readonly requesterGroupIds: readonly string[]
|
|
60
77
|
readonly requester?:
|
|
@@ -228,6 +245,7 @@ export function normalizeReserveAiModelCall(input: ReserveAiModelCallInput): {
|
|
|
228
245
|
readonly identity: AiModelCallReservationIdentity
|
|
229
246
|
readonly subjects: readonly AiLimitSubject[]
|
|
230
247
|
readonly estimates: readonly AiLimitQuantity[]
|
|
248
|
+
readonly modelKind?: ModelKind
|
|
231
249
|
readonly period: AiLimitPeriod
|
|
232
250
|
readonly reservedAt: Date
|
|
233
251
|
} {
|
|
@@ -237,6 +255,7 @@ export function normalizeReserveAiModelCall(input: ReserveAiModelCallInput): {
|
|
|
237
255
|
identity,
|
|
238
256
|
subjects: normalizeAiLimitSubjects(input.subjects),
|
|
239
257
|
estimates: normalizeAiLimitQuantities(input.estimates, "estimates"),
|
|
258
|
+
...(input.modelKind === undefined ? {} : { modelKind: input.modelKind }),
|
|
240
259
|
period: aiLimitCalendarMonth(reservedAt),
|
|
241
260
|
reservedAt,
|
|
242
261
|
}
|
|
@@ -297,13 +316,16 @@ export function aiLimitReservationRequestKey(
|
|
|
297
316
|
const amount = normalizeAiLimitAmount(quantity)
|
|
298
317
|
return [amount.meter, amount.currency, amount.amount.toString()]
|
|
299
318
|
}),
|
|
319
|
+
// Appended only when present, so keys of reservations made before model kinds stay valid.
|
|
320
|
+
...(request.modelKind === undefined ? [] : [request.modelKind]),
|
|
300
321
|
])
|
|
301
322
|
}
|
|
302
323
|
|
|
303
324
|
export function aiLimitReservationBuckets(
|
|
304
325
|
policies: readonly AiLimitPolicy[],
|
|
305
326
|
subjects: readonly AiLimitSubject[],
|
|
306
|
-
estimates: readonly AiLimitQuantity[]
|
|
327
|
+
estimates: readonly AiLimitQuantity[],
|
|
328
|
+
modelKind?: ModelKind
|
|
307
329
|
): readonly AiLimitReservationBucket[] {
|
|
308
330
|
const subjectKeys = new Set(subjects.map(aiLimitSubjectKey))
|
|
309
331
|
const estimatesByDimension = new Map(
|
|
@@ -313,7 +335,11 @@ export function aiLimitReservationBuckets(
|
|
|
313
335
|
})
|
|
314
336
|
)
|
|
315
337
|
return policies
|
|
316
|
-
.filter(
|
|
338
|
+
.filter(
|
|
339
|
+
(policy) =>
|
|
340
|
+
subjectKeys.has(aiLimitSubjectKey(policy.subject)) &&
|
|
341
|
+
aiLimitMeterApplies(policy.limit.meter, modelKind)
|
|
342
|
+
)
|
|
317
343
|
.flatMap((policy) => {
|
|
318
344
|
const estimate = estimatesByDimension.get(
|
|
319
345
|
aiLimitAmountKey(normalizeAiLimitAmount(policy.limit))
|
|
@@ -357,6 +383,7 @@ export function resolveAiLimitActual(
|
|
|
357
383
|
let accountingStatus: ResolvedAiLimitActual["accountingStatus"] = "complete"
|
|
358
384
|
for (const entry of entries) {
|
|
359
385
|
if (dimension.meter === "tokens.total") {
|
|
386
|
+
if (!aiLimitMeterApplies(dimension.meter, entry.modelKind)) continue
|
|
360
387
|
if (entry.totalTokens === undefined) {
|
|
361
388
|
accountingStatus = "unavailable"
|
|
362
389
|
} else {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ModelKind } from "../../models/definitions"
|
|
1
2
|
import type { AiMoney } from "../ai-cost"
|
|
2
3
|
|
|
3
4
|
/** A project-wide, group, or durable requester identity charged for AI model calls. */
|
|
@@ -129,6 +130,8 @@ export interface ReserveAiModelCallInput extends AiModelCallReservationIdentity
|
|
|
129
130
|
/** The project subject is always added, even when omitted here. */
|
|
130
131
|
readonly subjects: readonly AiLimitSubject[]
|
|
131
132
|
readonly estimates: readonly AiLimitQuantity[]
|
|
133
|
+
/** Transcription and reranking calls are outside token limits; see `aiLimitMeterApplies`. */
|
|
134
|
+
readonly modelKind?: ModelKind
|
|
132
135
|
readonly reservedAt?: Date
|
|
133
136
|
}
|
|
134
137
|
|
|
@@ -19,6 +19,14 @@ export function normalizeAiModelCallRecord(input: RecordAiModelCallInput): AiMod
|
|
|
19
19
|
}
|
|
20
20
|
assertNonBlank(input.responseId, "responseId")
|
|
21
21
|
|
|
22
|
+
if (
|
|
23
|
+
input.modelKind !== undefined &&
|
|
24
|
+
!["language", "image", "video", "embedding", "decision", "transcription", "reranking"].includes(
|
|
25
|
+
input.modelKind
|
|
26
|
+
)
|
|
27
|
+
) {
|
|
28
|
+
throw new TypeError("[Sixb] AI model kind is invalid.")
|
|
29
|
+
}
|
|
22
30
|
const occurredAt = cloneValidDate(input.occurredAt, "occurredAt")
|
|
23
31
|
const recordedAt = cloneValidDate(input.recordedAt ?? new Date(), "recordedAt")
|
|
24
32
|
const requesterGroupIds = normalizeRequesterGroupIds(input.requesterGroupIds)
|
|
@@ -37,6 +45,7 @@ export function normalizeAiModelCallRecord(input: RecordAiModelCallInput): AiMod
|
|
|
37
45
|
? {}
|
|
38
46
|
: { providerIds: normalizeModelProviderIds(input.providerIds) }),
|
|
39
47
|
requestedModelId: input.requestedModelId,
|
|
48
|
+
...(input.modelKind === undefined ? {} : { modelKind: input.modelKind }),
|
|
40
49
|
...(requestedReasoning === undefined ? {} : { requestedReasoning }),
|
|
41
50
|
...(input.responseModelId === undefined ? {} : { responseModelId: input.responseModelId }),
|
|
42
51
|
responseId: input.responseId,
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import type { ReadonlyJsonObject } from "../../json"
|
|
2
2
|
import type { ModelReasoning } from "../../models/language-model"
|
|
3
3
|
|
|
4
|
-
/**
|
|
4
|
+
/** Coverage of normalized usage. Complete means both token totals are known; duration alone is partial. */
|
|
5
5
|
export type AiUsageReportingStatus = "complete" | "partial" | "unavailable"
|
|
6
6
|
|
|
7
|
-
/** Provider-neutral
|
|
7
|
+
/** Provider-neutral usage accepted at the model-call boundary. */
|
|
8
8
|
export interface AiModelCallUsageInput {
|
|
9
|
+
/** Audio content duration in milliseconds, rounded to the nearest millisecond. Not billed duration. */
|
|
10
|
+
readonly audioDurationMs?: number
|
|
9
11
|
readonly inputTokens?: number
|
|
10
12
|
readonly outputTokens?: number
|
|
11
13
|
readonly uncachedInputTokens?: number
|
|
@@ -15,7 +17,7 @@ export interface AiModelCallUsageInput {
|
|
|
15
17
|
readonly reasoningOutputTokens?: number
|
|
16
18
|
}
|
|
17
19
|
|
|
18
|
-
/** Normalized
|
|
20
|
+
/** Normalized usage for one completed model call. Token details overlap their input/output totals. */
|
|
19
21
|
export interface AiModelCallUsage extends AiModelCallUsageInput {
|
|
20
22
|
/** Present only when both input and output totals are known. */
|
|
21
23
|
readonly totalTokens?: number
|
|
@@ -32,6 +34,8 @@ export interface AiUsageExecutionSummary {
|
|
|
32
34
|
|
|
33
35
|
/** Input for an idempotent model-call ledger append. */
|
|
34
36
|
export interface RecordAiModelCallInput {
|
|
37
|
+
/** Absent for historical calls whose kind was not captured. */
|
|
38
|
+
readonly modelKind?: import("../../models/definitions").ModelKind
|
|
35
39
|
readonly providerIds?: import("../../models/events").ModelProviderIds
|
|
36
40
|
readonly id: string
|
|
37
41
|
readonly projectId: string
|
|
@@ -89,7 +93,7 @@ export interface GetLatestAiModelCallForExecutionInput {
|
|
|
89
93
|
readonly executionId: string
|
|
90
94
|
}
|
|
91
95
|
|
|
92
|
-
/** Durable, provider-neutral accounting for completed
|
|
96
|
+
/** Durable, provider-neutral accounting for completed model calls. */
|
|
93
97
|
export interface AiUsageStorage {
|
|
94
98
|
/**
|
|
95
99
|
* Append one model-call record idempotently. The identity is project, execution ID, attempt, call
|
|
@@ -8,6 +8,7 @@ const USAGE_FIELDS = [
|
|
|
8
8
|
"cacheWriteInputTokens",
|
|
9
9
|
"textOutputTokens",
|
|
10
10
|
"reasoningOutputTokens",
|
|
11
|
+
"audioDurationMs",
|
|
11
12
|
] as const
|
|
12
13
|
|
|
13
14
|
type AiUsageField = (typeof USAGE_FIELDS)[number]
|
|
@@ -30,6 +31,7 @@ export function normalizeAiModelCallUsage(input: AiModelCallUsageInput): AiModel
|
|
|
30
31
|
: "unavailable"
|
|
31
32
|
|
|
32
33
|
return {
|
|
34
|
+
...(input.audioDurationMs === undefined ? {} : { audioDurationMs: input.audioDurationMs }),
|
|
33
35
|
...(input.inputTokens === undefined ? {} : { inputTokens: input.inputTokens }),
|
|
34
36
|
...(input.outputTokens === undefined ? {} : { outputTokens: input.outputTokens }),
|
|
35
37
|
...(totalTokens === undefined ? {} : { totalTokens }),
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { cloneFileDownloadGrantRecord } from "./record"
|
|
2
|
+
import type {
|
|
3
|
+
DeleteExpiredFileDownloadGrantsInput,
|
|
4
|
+
FileDownloadGrantRecord,
|
|
5
|
+
FileDownloadGrantStorage,
|
|
6
|
+
FindFileDownloadGrantInput,
|
|
7
|
+
RevokeFileDownloadGrantInput,
|
|
8
|
+
} from "./types"
|
|
9
|
+
|
|
10
|
+
export class InMemoryFileDownloadGrantStorage implements FileDownloadGrantStorage {
|
|
11
|
+
private rows = new Map<string, FileDownloadGrantRecord>()
|
|
12
|
+
|
|
13
|
+
async create(record: FileDownloadGrantRecord): Promise<void> {
|
|
14
|
+
const duplicate = [...this.rows.values()].some(
|
|
15
|
+
(current) =>
|
|
16
|
+
current.projectId === record.projectId &&
|
|
17
|
+
(current.id === record.id || current.tokenHash === record.tokenHash)
|
|
18
|
+
)
|
|
19
|
+
if (duplicate) {
|
|
20
|
+
throw new Error(`[Sixb] File download grant '${record.id}' conflicts with an existing one.`)
|
|
21
|
+
}
|
|
22
|
+
this.rows.set(rowKey(record.projectId, record.id), cloneFileDownloadGrantRecord(record))
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async findByTokenHash(
|
|
26
|
+
input: FindFileDownloadGrantInput
|
|
27
|
+
): Promise<FileDownloadGrantRecord | null> {
|
|
28
|
+
for (const record of this.rows.values()) {
|
|
29
|
+
if (record.projectId === input.projectId && record.tokenHash === input.tokenHash) {
|
|
30
|
+
return cloneFileDownloadGrantRecord(record)
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return null
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async revoke(input: RevokeFileDownloadGrantInput): Promise<FileDownloadGrantRecord | null> {
|
|
37
|
+
const key = rowKey(input.projectId, input.id)
|
|
38
|
+
const current = this.rows.get(key)
|
|
39
|
+
if (!current) return null
|
|
40
|
+
if (!current.revokedAt) {
|
|
41
|
+
this.rows.set(key, { ...current, revokedAt: new Date(input.revokedAt) })
|
|
42
|
+
}
|
|
43
|
+
return cloneFileDownloadGrantRecord(this.rows.get(key) as FileDownloadGrantRecord)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async deleteExpired(input: DeleteExpiredFileDownloadGrantsInput): Promise<number> {
|
|
47
|
+
const expired = [...this.rows.entries()]
|
|
48
|
+
.filter(
|
|
49
|
+
([, record]) =>
|
|
50
|
+
record.projectId === input.projectId &&
|
|
51
|
+
record.expiresAt.getTime() < input.expiredBefore.getTime()
|
|
52
|
+
)
|
|
53
|
+
.slice(0, input.limit)
|
|
54
|
+
for (const [key] of expired) this.rows.delete(key)
|
|
55
|
+
return expired.length
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
snapshot(): ReadonlyMap<string, FileDownloadGrantRecord> {
|
|
59
|
+
return new Map(
|
|
60
|
+
[...this.rows].map(([key, record]) => [key, cloneFileDownloadGrantRecord(record)])
|
|
61
|
+
)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
restore(snapshot: ReadonlyMap<string, FileDownloadGrantRecord>): void {
|
|
65
|
+
this.rows = new Map(
|
|
66
|
+
[...snapshot].map(([key, record]) => [key, cloneFileDownloadGrantRecord(record)])
|
|
67
|
+
)
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function rowKey(projectId: string, id: string): string {
|
|
72
|
+
return `${projectId}\0${id}`
|
|
73
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { isFileRef } from "../../blob-storage"
|
|
2
|
+
import type { FileDownloadGrantRecord } from "./types"
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Rebuilds a grant from a provider row with camelCase keys. `file` may arrive parsed (jsonb) or
|
|
6
|
+
* as text (SQLite), and timestamps as `Date` or ISO text. Fails closed on corruption: a grant that
|
|
7
|
+
* cannot be read must not serve a file.
|
|
8
|
+
*/
|
|
9
|
+
export function parseFileDownloadGrantRow(row: {
|
|
10
|
+
readonly [column: string]: unknown
|
|
11
|
+
}): FileDownloadGrantRecord {
|
|
12
|
+
const id = text(row.id, "id", String(row.id))
|
|
13
|
+
const file = typeof row.file === "string" ? JSON.parse(row.file) : row.file
|
|
14
|
+
if (!isFileRef(file)) throw corrupt(id, "file is not a file reference")
|
|
15
|
+
|
|
16
|
+
return {
|
|
17
|
+
id,
|
|
18
|
+
projectId: text(row.projectId, "projectId", id),
|
|
19
|
+
tokenHash: text(row.tokenHash, "tokenHash", id),
|
|
20
|
+
file,
|
|
21
|
+
executionId: text(row.executionId, "executionId", id),
|
|
22
|
+
createdAt: date(row.createdAt, "createdAt", id),
|
|
23
|
+
expiresAt: date(row.expiresAt, "expiresAt", id),
|
|
24
|
+
...(row.revokedAt == null ? {} : { revokedAt: date(row.revokedAt, "revokedAt", id) }),
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function cloneFileDownloadGrantRecord(
|
|
29
|
+
record: FileDownloadGrantRecord
|
|
30
|
+
): FileDownloadGrantRecord {
|
|
31
|
+
return structuredClone(record)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function text(value: unknown, column: string, id: string): string {
|
|
35
|
+
if (typeof value !== "string" || value.length === 0) throw corrupt(id, `${column} is not text`)
|
|
36
|
+
return value
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function date(value: unknown, column: string, id: string): Date {
|
|
40
|
+
const parsed = value instanceof Date || typeof value === "string" ? new Date(value) : null
|
|
41
|
+
if (!parsed || !Number.isFinite(parsed.getTime())) throw corrupt(id, `${column} is not a date`)
|
|
42
|
+
return parsed
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function corrupt(id: string, reason: string): Error {
|
|
46
|
+
return new Error(`[Sixb] Stored file download grant '${id}' is invalid: ${reason}.`)
|
|
47
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { FileRef } from "../../blob-storage"
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* One download URL issued by `blobs.createDownloadUrl()`. Each call issues its own grant, so URLs
|
|
5
|
+
* for the same file expire and are revoked independently.
|
|
6
|
+
*/
|
|
7
|
+
export interface FileDownloadGrantRecord {
|
|
8
|
+
readonly id: string
|
|
9
|
+
readonly projectId: string
|
|
10
|
+
/** SHA-256 hex of the URL token. The token itself is never stored. */
|
|
11
|
+
readonly tokenHash: string
|
|
12
|
+
/** The file the URL serves, without `logicalPath`: serving the bytes does not need it. */
|
|
13
|
+
readonly file: FileRef
|
|
14
|
+
/** The execution that issued the URL, so an exposure can be traced back to its cause. */
|
|
15
|
+
readonly executionId: string
|
|
16
|
+
readonly createdAt: Date
|
|
17
|
+
readonly expiresAt: Date
|
|
18
|
+
readonly revokedAt?: Date
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface FindFileDownloadGrantInput {
|
|
22
|
+
readonly projectId: string
|
|
23
|
+
readonly tokenHash: string
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface RevokeFileDownloadGrantInput {
|
|
27
|
+
readonly projectId: string
|
|
28
|
+
readonly id: string
|
|
29
|
+
readonly revokedAt: Date
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface DeleteExpiredFileDownloadGrantsInput {
|
|
33
|
+
readonly projectId: string
|
|
34
|
+
readonly expiredBefore: Date
|
|
35
|
+
readonly limit: number
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** Persistence only: token generation, expiry, and revocation checks live in Core. */
|
|
39
|
+
export interface FileDownloadGrantStorage {
|
|
40
|
+
/** `(projectId, id)` and `(projectId, tokenHash)` are each unique. */
|
|
41
|
+
create(record: FileDownloadGrantRecord): Promise<void>
|
|
42
|
+
/** Returns expired and revoked grants too; the caller decides whether one still serves. */
|
|
43
|
+
findByTokenHash(input: FindFileDownloadGrantInput): Promise<FileDownloadGrantRecord | null>
|
|
44
|
+
/** Keeps the first revocation. Returns the grant, or `null` when it does not exist. */
|
|
45
|
+
revoke(input: RevokeFileDownloadGrantInput): Promise<FileDownloadGrantRecord | null>
|
|
46
|
+
/** Deletes up to `limit` grants that expired before `expiredBefore`, and returns the count. */
|
|
47
|
+
deleteExpired(input: DeleteExpiredFileDownloadGrantsInput): Promise<number>
|
|
48
|
+
}
|