@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
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
MAX_OBJECT_READ_FACETS2,
|
|
4
4
|
isAllowed2,
|
|
5
5
|
assertAuthorized2
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-5be2ath4.js";
|
|
7
7
|
import {
|
|
8
8
|
validateSchemaValue2,
|
|
9
9
|
validatePropertyValue2,
|
|
@@ -12,7 +12,10 @@ import {
|
|
|
12
12
|
isTextSchema,
|
|
13
13
|
isContainsSchema,
|
|
14
14
|
queryScalarKindForSchema
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-rpxz486p.js";
|
|
16
|
+
import {
|
|
17
|
+
validateRerankingResults
|
|
18
|
+
} from "./chunk-s7ftxrdr.js";
|
|
16
19
|
import {
|
|
17
20
|
hasVectorProfile2,
|
|
18
21
|
isVectorProfileQuery2,
|
|
@@ -23,453 +26,110 @@ import {
|
|
|
23
26
|
queryScalarValuesEqual,
|
|
24
27
|
MAX_VECTOR_K,
|
|
25
28
|
vectorConfiguration,
|
|
29
|
+
vectorSources,
|
|
26
30
|
normalizeVector2
|
|
27
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-5yd8cchh.js";
|
|
28
32
|
import {
|
|
29
33
|
normalizeObjectQuery2,
|
|
30
34
|
ObjectQueryValidationError2,
|
|
31
35
|
ObjectQueryPlanningError2,
|
|
32
36
|
ObjectQueryExecutionError2
|
|
33
|
-
} from "./chunk-
|
|
34
|
-
import {
|
|
35
|
-
sameEmbeddingModel
|
|
36
|
-
} from "./chunk-p1683c0v.js";
|
|
37
|
+
} from "./chunk-kpx7jrmn.js";
|
|
37
38
|
import {
|
|
38
39
|
formatUnknownObjectTypeMessage
|
|
39
40
|
} from "./chunk-cqr3acm1.js";
|
|
41
|
+
import {
|
|
42
|
+
sameEmbeddingModel
|
|
43
|
+
} from "./chunk-kyjcwqz6.js";
|
|
40
44
|
import {
|
|
41
45
|
normalizeDecimalValue2
|
|
42
46
|
} from "./chunk-3bh94gbw.js";
|
|
43
47
|
import {
|
|
44
48
|
stableJsonStringify2
|
|
45
49
|
} from "./chunk-wy0qdqfm.js";
|
|
46
|
-
// src/objects/
|
|
47
|
-
var
|
|
48
|
-
|
|
49
|
-
if (query.kind === "limit" || query.kind === "project") {
|
|
50
|
-
const input = await resolveVectorSearchText(query.input, ontology, models, signal);
|
|
51
|
-
return { ...query, input };
|
|
52
|
-
}
|
|
53
|
-
if (query.kind !== "vector" || typeof query.vector !== "string")
|
|
54
|
-
return query;
|
|
55
|
-
const model = resolveProfileEmbeddingModel(query, ontology, models);
|
|
56
|
-
const vector = await embedSearchText(query.vector, model, signal);
|
|
57
|
-
return { ...query, vector };
|
|
58
|
-
}
|
|
59
|
-
function resolveProfileEmbeddingModel(query, ontology, models) {
|
|
60
|
-
let input = query.input;
|
|
61
|
-
while (input.kind === "filter")
|
|
62
|
-
input = input.input;
|
|
63
|
-
if (input.kind !== "start" || !query.profile) {
|
|
64
|
-
throw new ObjectQueryExecutionError2("embedding_model_unavailable", "Vector search requires the embedding model registered for its profile.");
|
|
65
|
-
}
|
|
66
|
-
const profile = ontology.resolveObjectType(input.objectTypeId).search?.vectors?.[query.profile];
|
|
67
|
-
if (!profile) {
|
|
68
|
-
throw new ObjectQueryExecutionError2("embedding_model_unavailable", "Vector search requires the embedding model registered for its profile.");
|
|
69
|
-
}
|
|
70
|
-
const model = models?.getByRef({
|
|
71
|
-
provider: profile.model.providerId,
|
|
72
|
-
modelId: profile.model.modelId
|
|
73
|
-
})?.model;
|
|
74
|
-
if (!model || !sameEmbeddingModel(model, profile.model)) {
|
|
75
|
-
throw new ObjectQueryExecutionError2("embedding_model_unavailable", "Vector search requires the embedding model registered for its profile.");
|
|
76
|
-
}
|
|
77
|
-
return model;
|
|
78
|
-
}
|
|
79
|
-
async function embedSearchText(text, model, signal) {
|
|
80
|
-
const dimensions = model.definition.dimensions;
|
|
81
|
-
const timeout = AbortSignal.timeout(QUERY_EMBEDDING_TIMEOUT_MS);
|
|
82
|
-
const requestSignal = signal ? AbortSignal.any([signal, timeout]) : timeout;
|
|
83
|
-
requestSignal.throwIfAborted();
|
|
84
|
-
const result = await model.embed({ texts: [text], signal: requestSignal });
|
|
85
|
-
requestSignal.throwIfAborted();
|
|
86
|
-
if (!Array.isArray(result?.vectors) || result.vectors.length !== 1) {
|
|
87
|
-
throw new ObjectQueryExecutionError2("invalid_embedding_response", "Embedding model must return exactly one vector for the search text.");
|
|
88
|
-
}
|
|
89
|
-
try {
|
|
90
|
-
return normalizeVector2(result.vectors[0], dimensions);
|
|
91
|
-
} catch {
|
|
92
|
-
throw new ObjectQueryExecutionError2("invalid_embedding_response", "Embedding model returned an invalid vector for the search profile.");
|
|
93
|
-
}
|
|
94
|
-
}
|
|
50
|
+
// src/objects/query/reranking-limits.ts
|
|
51
|
+
var MAX_RERANK_CANDIDATES = 100;
|
|
52
|
+
var MAX_RERANK_INPUT_BYTES = 1048576;
|
|
95
53
|
|
|
96
|
-
// src/objects/query/
|
|
97
|
-
var
|
|
98
|
-
var
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
const
|
|
125
|
-
if (
|
|
126
|
-
|
|
127
|
-
mode: "fallback",
|
|
128
|
-
query,
|
|
129
|
-
providerIssues,
|
|
130
|
-
fallbackIssues,
|
|
131
|
-
issues: [],
|
|
132
|
-
fallback: {
|
|
133
|
-
maxRows: options.maxFallbackRows ?? DEFAULT_MAX_FALLBACK_ROWS,
|
|
134
|
-
requiresExplicitBound: options.requiresExplicitFallbackBound !== false
|
|
135
|
-
}
|
|
136
|
-
};
|
|
54
|
+
// src/objects/query/validate.ts
|
|
55
|
+
var DEFAULT_MAX_LIMIT = 1000;
|
|
56
|
+
var DEFAULT_MAX_PAGE_SIZE = 1000;
|
|
57
|
+
var DEFAULT_MAX_REFS = 1000;
|
|
58
|
+
var NOOP_ADMISSION_STATE = Object.freeze({});
|
|
59
|
+
var NOOP_QUERY_ADMISSION = Object.freeze({
|
|
60
|
+
empty: () => NOOP_ADMISSION_STATE,
|
|
61
|
+
source: () => ({ state: NOOP_ADMISSION_STATE }),
|
|
62
|
+
property: () => {
|
|
63
|
+
return;
|
|
64
|
+
},
|
|
65
|
+
edge: (input) => ({
|
|
66
|
+
state: input.state
|
|
67
|
+
}),
|
|
68
|
+
set: (input) => input.states[0] ?? NOOP_ADMISSION_STATE
|
|
69
|
+
});
|
|
70
|
+
function validateObjectQuery2(query, options) {
|
|
71
|
+
const admitted = validateObjectQueryWithAdmission(query, options, NOOP_QUERY_ADMISSION);
|
|
72
|
+
return {
|
|
73
|
+
query: admitted.query,
|
|
74
|
+
result: admitted.result,
|
|
75
|
+
touchedObjectTypeIds: admitted.touchedObjectTypeIds
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
function validateObjectQueryWithAdmission(query, options, admission) {
|
|
79
|
+
const normalized = options.normalize === false ? query : normalizeObjectQuery2(query);
|
|
80
|
+
const ctx = createValidationContext(options, admission);
|
|
81
|
+
validateVectorComposition(query, ctx);
|
|
82
|
+
const validation = validateQueryNode(normalized, "$", ctx);
|
|
83
|
+
if (ctx.issues.length > 0) {
|
|
84
|
+
throw new ObjectQueryValidationError2(ctx.issues);
|
|
137
85
|
}
|
|
86
|
+
const denial = ctx.admissionDenials[0];
|
|
87
|
+
if (denial)
|
|
88
|
+
throw denial;
|
|
138
89
|
return {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
issues
|
|
90
|
+
query: validation.query,
|
|
91
|
+
result: validation.result,
|
|
92
|
+
touchedObjectTypeIds: [...ctx.touchedObjectTypeIds],
|
|
93
|
+
admissionState: validation.admissionState
|
|
144
94
|
};
|
|
145
95
|
}
|
|
146
|
-
function
|
|
147
|
-
const
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
96
|
+
function collectObjectQueryValidationIssues2(query, options) {
|
|
97
|
+
const normalized = options.normalize === false ? query : normalizeObjectQuery2(query);
|
|
98
|
+
const ctx = createValidationContext(options, NOOP_QUERY_ADMISSION);
|
|
99
|
+
validateVectorComposition(query, ctx);
|
|
100
|
+
validateQueryNode(normalized, "$", ctx);
|
|
101
|
+
return ctx.issues;
|
|
151
102
|
}
|
|
152
|
-
function
|
|
153
|
-
|
|
154
|
-
if (!enabled) {
|
|
155
|
-
const code = `${operationIssuePrefix(options.operation)}_not_enabled`;
|
|
156
|
-
addIssue(issues, "$", code, `Object storage capabilities do not enable ${options.operation} pushdown`);
|
|
157
|
-
}
|
|
158
|
-
if (options.hasImplementation)
|
|
159
|
-
return;
|
|
160
|
-
const code = `${operationIssuePrefix(options.operation)}_not_implemented`;
|
|
161
|
-
addIssue(issues, "$", code, `Object storage does not implement ${options.operation}`);
|
|
103
|
+
function resolveObjectQueryResultShape2(query, options) {
|
|
104
|
+
return validateObjectQuery2(query, options).result;
|
|
162
105
|
}
|
|
163
|
-
function
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
return options.hasExistsObjects === true;
|
|
171
|
-
case "facetObjects":
|
|
172
|
-
return options.hasFacetObjects === true;
|
|
173
|
-
}
|
|
106
|
+
function validateVectorComposition(query, ctx) {
|
|
107
|
+
if (hasVectorProfile2(query) && !isVectorProfileQuery2(query))
|
|
108
|
+
ctx.issues.push({
|
|
109
|
+
path: "$",
|
|
110
|
+
code: "vector.composition",
|
|
111
|
+
message: "Vector profiles support one top-k over one concrete type, with filters, traversals or sets before ranking, optional reranking, then limit/project."
|
|
112
|
+
});
|
|
174
113
|
}
|
|
175
|
-
function
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
114
|
+
function createValidationContext(options, admission) {
|
|
115
|
+
return {
|
|
116
|
+
ontology: options.ontology,
|
|
117
|
+
valueTypesById: options.ontology.getValueTypesById(),
|
|
118
|
+
maxLimit: options.maxLimit ?? DEFAULT_MAX_LIMIT,
|
|
119
|
+
maxPageSize: options.maxPageSize ?? DEFAULT_MAX_PAGE_SIZE,
|
|
120
|
+
maxRefs: options.maxRefs ?? DEFAULT_MAX_REFS,
|
|
121
|
+
issues: [],
|
|
122
|
+
touchedObjectTypeIds: new Set,
|
|
123
|
+
admission,
|
|
124
|
+
admissionDenials: []
|
|
125
|
+
};
|
|
186
126
|
}
|
|
187
|
-
function
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
switch (query.kind) {
|
|
192
|
-
case "start":
|
|
193
|
-
if (query.includeSubtypes === true && capabilities.features?.includeSubtypes !== true) {
|
|
194
|
-
addIssue(issues, path, "include_subtypes_not_supported", "Provider does not support start.includeSubtypes expansion");
|
|
195
|
-
}
|
|
196
|
-
return;
|
|
197
|
-
case "refs":
|
|
198
|
-
return;
|
|
199
|
-
case "filter":
|
|
200
|
-
collectPredicateProviderIssues(query.predicate, `${path}.predicate`, capabilities, issues);
|
|
201
|
-
collectNodeProviderIssues(query.input, `${path}.input`, capabilities, issues);
|
|
202
|
-
return;
|
|
203
|
-
case "text":
|
|
204
|
-
case "vector":
|
|
205
|
-
case "project":
|
|
206
|
-
collectNodeProviderIssues(query.input, `${path}.input`, capabilities, issues);
|
|
207
|
-
return;
|
|
208
|
-
case "limit":
|
|
209
|
-
collectProviderMaxLimitIssues(query.limit, path, capabilities, issues);
|
|
210
|
-
collectNodeProviderIssues(query.input, `${path}.input`, capabilities, issues);
|
|
211
|
-
return;
|
|
212
|
-
case "page":
|
|
213
|
-
collectProviderMaxPageSizeIssues(query.pageSize, path, capabilities, issues);
|
|
214
|
-
collectNodeProviderIssues(query.input, `${path}.input`, capabilities, issues);
|
|
215
|
-
return;
|
|
216
|
-
case "traverse":
|
|
217
|
-
if (capabilities.traversalDirections?.[query.direction] !== true) {
|
|
218
|
-
addIssue(issues, path, "traversal_direction_not_supported", `Provider does not support ${query.direction} traversal`);
|
|
219
|
-
}
|
|
220
|
-
collectNodeProviderIssues(query.input, `${path}.input`, capabilities, issues);
|
|
221
|
-
return;
|
|
222
|
-
case "set":
|
|
223
|
-
if (capabilities.setOps?.[query.op] !== true) {
|
|
224
|
-
addIssue(issues, path, "set_operation_not_supported", `Provider does not support set operation '${query.op}'`);
|
|
225
|
-
}
|
|
226
|
-
query.inputs.forEach((input, index) => {
|
|
227
|
-
collectNodeProviderIssues(input, `${path}.inputs[${index}]`, capabilities, issues);
|
|
228
|
-
});
|
|
229
|
-
return;
|
|
230
|
-
case "sort":
|
|
231
|
-
query.fields.forEach((field, index) => {
|
|
232
|
-
collectSortProviderIssues(field, `${path}.fields[${index}]`, capabilities, issues);
|
|
233
|
-
});
|
|
234
|
-
collectNodeProviderIssues(query.input, `${path}.input`, capabilities, issues);
|
|
235
|
-
return;
|
|
236
|
-
case "expand":
|
|
237
|
-
query.expansions.forEach((expansion, index) => {
|
|
238
|
-
collectExpansionProviderIssues(expansion, `${path}.expansions[${index}]`, capabilities, issues);
|
|
239
|
-
});
|
|
240
|
-
collectNodeProviderIssues(query.input, `${path}.input`, capabilities, issues);
|
|
241
|
-
return;
|
|
127
|
+
function validateQueryNode(query, path, ctx) {
|
|
128
|
+
const validation = dispatchQueryNode(query, path, ctx);
|
|
129
|
+
for (const objectTypeId of validation.result.objectTypeIds) {
|
|
130
|
+
ctx.touchedObjectTypeIds.add(objectTypeId);
|
|
242
131
|
}
|
|
243
|
-
|
|
244
|
-
function collectExpansionProviderIssues(expansion, path, capabilities, issues) {
|
|
245
|
-
if (expansion.cardinality === undefined) {
|
|
246
|
-
addIssue(issues, path, "expand_cardinality_unresolved", `Provider cannot push down expansion '${expansion.linkId}' without a resolved cardinality`);
|
|
247
|
-
}
|
|
248
|
-
expansion.orderBy?.forEach((field, index) => {
|
|
249
|
-
collectSortProviderIssues(field, `${path}.orderBy[${index}]`, capabilities, issues);
|
|
250
|
-
});
|
|
251
|
-
expansion.expand?.forEach((nested, index) => {
|
|
252
|
-
collectExpansionProviderIssues(nested, `${path}.expand[${index}]`, capabilities, issues);
|
|
253
|
-
});
|
|
254
|
-
}
|
|
255
|
-
function collectPredicateProviderIssues(predicate, path, capabilities, issues) {
|
|
256
|
-
const scalarOperation = predicateScalarOperation(predicate);
|
|
257
|
-
if ("scalarKind" in predicate && predicate.scalarKind !== undefined && scalarOperation !== undefined && capabilities.scalarOperations?.[predicate.scalarKind]?.[scalarOperation] !== true) {
|
|
258
|
-
addIssue(issues, path, "scalar_operation_not_supported", `Provider does not support ${scalarOperation} for '${predicate.scalarKind}' values`);
|
|
259
|
-
}
|
|
260
|
-
if (capabilities.predicateOps?.[predicate.op] !== true) {
|
|
261
|
-
addIssue(issues, path, "predicate_operation_not_supported", `Provider does not support predicate operation '${predicate.op}'`);
|
|
262
|
-
}
|
|
263
|
-
switch (predicate.op) {
|
|
264
|
-
case "and":
|
|
265
|
-
case "or":
|
|
266
|
-
predicate.items.forEach((item, index) => {
|
|
267
|
-
collectPredicateProviderIssues(item, `${path}.items[${index}]`, capabilities, issues);
|
|
268
|
-
});
|
|
269
|
-
return;
|
|
270
|
-
case "not":
|
|
271
|
-
collectPredicateProviderIssues(predicate.item, `${path}.item`, capabilities, issues);
|
|
272
|
-
return;
|
|
273
|
-
default:
|
|
274
|
-
return;
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
function predicateScalarOperation(predicate) {
|
|
278
|
-
switch (predicate.op) {
|
|
279
|
-
case "eq":
|
|
280
|
-
case "neq":
|
|
281
|
-
case "in":
|
|
282
|
-
case "contains":
|
|
283
|
-
return "equality";
|
|
284
|
-
case "lt":
|
|
285
|
-
case "lte":
|
|
286
|
-
case "gt":
|
|
287
|
-
case "gte":
|
|
288
|
-
return "ordering";
|
|
289
|
-
default:
|
|
290
|
-
return;
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
function collectSortProviderIssues(field, path, capabilities, issues) {
|
|
294
|
-
if (field.kind === "property" && field.scalarKind !== undefined && capabilities.scalarOperations?.[field.scalarKind]?.ordering !== true) {
|
|
295
|
-
addIssue(issues, path, "scalar_operation_not_supported", `Provider does not support ordering for '${field.scalarKind}' values`);
|
|
296
|
-
}
|
|
297
|
-
if (capabilities.sortKinds?.[field.kind] === true)
|
|
298
|
-
return;
|
|
299
|
-
addIssue(issues, path, "sort_kind_not_supported", `Provider does not support sort kind '${field.kind}'`);
|
|
300
|
-
}
|
|
301
|
-
function collectProviderMaxLimitIssues(limit, path, capabilities, issues) {
|
|
302
|
-
const maxLimit = capabilities.limits?.maxLimit;
|
|
303
|
-
if (maxLimit === undefined)
|
|
304
|
-
return;
|
|
305
|
-
if (!Number.isInteger(maxLimit) || maxLimit < 0) {
|
|
306
|
-
addIssue(issues, path, "invalid_provider_limit_capability", "Provider limit capability maxLimit must be a non-negative integer");
|
|
307
|
-
return;
|
|
308
|
-
}
|
|
309
|
-
if (limit > maxLimit) {
|
|
310
|
-
addIssue(issues, path, "provider_limit_too_large", `Provider supports limit up to ${maxLimit}`);
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
function collectProviderMaxPageSizeIssues(pageSize, path, capabilities, issues) {
|
|
314
|
-
const maxPageSize = capabilities.limits?.maxPageSize;
|
|
315
|
-
if (maxPageSize === undefined)
|
|
316
|
-
return;
|
|
317
|
-
if (!Number.isInteger(maxPageSize) || maxPageSize <= 0) {
|
|
318
|
-
addIssue(issues, path, "invalid_provider_page_size_capability", "Provider limit capability maxPageSize must be a positive integer");
|
|
319
|
-
return;
|
|
320
|
-
}
|
|
321
|
-
if (pageSize > maxPageSize) {
|
|
322
|
-
addIssue(issues, path, "provider_page_size_too_large", `Provider supports pageSize up to ${maxPageSize}`);
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
function collectFallbackIssues(query, options) {
|
|
326
|
-
const issues = [];
|
|
327
|
-
if (options.allowFallback === false) {
|
|
328
|
-
addIssue(issues, "$", "fallback_disabled", "Object query fallback is disabled");
|
|
329
|
-
return issues;
|
|
330
|
-
}
|
|
331
|
-
const maxFallbackRows = options.maxFallbackRows ?? DEFAULT_MAX_FALLBACK_ROWS;
|
|
332
|
-
if (!Number.isInteger(maxFallbackRows) || maxFallbackRows <= 0) {
|
|
333
|
-
addIssue(issues, "$", "invalid_fallback_bound", "maxFallbackRows must be a positive integer");
|
|
334
|
-
}
|
|
335
|
-
if (options.requiresExplicitFallbackBound !== false && !hasExplicitResultBound(query)) {
|
|
336
|
-
addIssue(issues, "$", "fallback_requires_bound", "Fallback requires an explicit limit or page node");
|
|
337
|
-
}
|
|
338
|
-
collectFallbackNodeIssues(query, "$", issues);
|
|
339
|
-
return issues;
|
|
340
|
-
}
|
|
341
|
-
function collectFallbackNodeIssues(query, path, issues) {
|
|
342
|
-
if (!fallbackNodeKinds.has(query.kind)) {
|
|
343
|
-
addIssue(issues, path, "fallback_node_not_supported", `Fallback does not support query node '${query.kind}'`);
|
|
344
|
-
}
|
|
345
|
-
switch (query.kind) {
|
|
346
|
-
case "start":
|
|
347
|
-
case "refs":
|
|
348
|
-
return;
|
|
349
|
-
case "filter":
|
|
350
|
-
case "limit":
|
|
351
|
-
case "page":
|
|
352
|
-
case "project":
|
|
353
|
-
case "expand":
|
|
354
|
-
collectFallbackNodeIssues(query.input, `${path}.input`, issues);
|
|
355
|
-
return;
|
|
356
|
-
case "sort":
|
|
357
|
-
query.fields.forEach((field, index) => {
|
|
358
|
-
if (field.kind === "relevance") {
|
|
359
|
-
addIssue(issues, `${path}.fields[${index}]`, "fallback_sort_kind_not_supported", "Fallback does not support relevance sorting");
|
|
360
|
-
}
|
|
361
|
-
});
|
|
362
|
-
collectFallbackNodeIssues(query.input, `${path}.input`, issues);
|
|
363
|
-
return;
|
|
364
|
-
case "text":
|
|
365
|
-
case "vector":
|
|
366
|
-
case "traverse":
|
|
367
|
-
collectFallbackNodeIssues(query.input, `${path}.input`, issues);
|
|
368
|
-
return;
|
|
369
|
-
case "set":
|
|
370
|
-
query.inputs.forEach((input, index) => {
|
|
371
|
-
collectFallbackNodeIssues(input, `${path}.inputs[${index}]`, issues);
|
|
372
|
-
});
|
|
373
|
-
return;
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
function hasExplicitResultBound(query) {
|
|
377
|
-
switch (query.kind) {
|
|
378
|
-
case "limit":
|
|
379
|
-
case "page":
|
|
380
|
-
case "refs":
|
|
381
|
-
return true;
|
|
382
|
-
case "start":
|
|
383
|
-
return false;
|
|
384
|
-
case "set":
|
|
385
|
-
return query.inputs.some(hasExplicitResultBound);
|
|
386
|
-
default:
|
|
387
|
-
return hasExplicitResultBound(query.input);
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
function addIssue(issues, path, code, message) {
|
|
391
|
-
issues.push({ path, code, message });
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
// src/objects/query/validate.ts
|
|
395
|
-
var DEFAULT_MAX_LIMIT = 1000;
|
|
396
|
-
var DEFAULT_MAX_PAGE_SIZE = 1000;
|
|
397
|
-
var DEFAULT_MAX_REFS = 1000;
|
|
398
|
-
var NOOP_ADMISSION_STATE = Object.freeze({});
|
|
399
|
-
var NOOP_QUERY_ADMISSION = Object.freeze({
|
|
400
|
-
empty: () => NOOP_ADMISSION_STATE,
|
|
401
|
-
source: () => ({ state: NOOP_ADMISSION_STATE }),
|
|
402
|
-
property: () => {
|
|
403
|
-
return;
|
|
404
|
-
},
|
|
405
|
-
edge: (input) => ({
|
|
406
|
-
state: input.state
|
|
407
|
-
}),
|
|
408
|
-
set: (input) => input.states[0] ?? NOOP_ADMISSION_STATE
|
|
409
|
-
});
|
|
410
|
-
function validateObjectQuery2(query, options) {
|
|
411
|
-
const admitted = validateObjectQueryWithAdmission(query, options, NOOP_QUERY_ADMISSION);
|
|
412
|
-
return {
|
|
413
|
-
query: admitted.query,
|
|
414
|
-
result: admitted.result,
|
|
415
|
-
touchedObjectTypeIds: admitted.touchedObjectTypeIds
|
|
416
|
-
};
|
|
417
|
-
}
|
|
418
|
-
function validateObjectQueryWithAdmission(query, options, admission) {
|
|
419
|
-
const normalized = options.normalize === false ? query : normalizeObjectQuery2(query);
|
|
420
|
-
const ctx = createValidationContext(options, admission);
|
|
421
|
-
validateVectorComposition(query, ctx);
|
|
422
|
-
const validation = validateQueryNode(normalized, "$", ctx);
|
|
423
|
-
if (ctx.issues.length > 0) {
|
|
424
|
-
throw new ObjectQueryValidationError2(ctx.issues);
|
|
425
|
-
}
|
|
426
|
-
const denial = ctx.admissionDenials[0];
|
|
427
|
-
if (denial)
|
|
428
|
-
throw denial;
|
|
429
|
-
return {
|
|
430
|
-
query: validation.query,
|
|
431
|
-
result: validation.result,
|
|
432
|
-
touchedObjectTypeIds: [...ctx.touchedObjectTypeIds],
|
|
433
|
-
admissionState: validation.admissionState
|
|
434
|
-
};
|
|
435
|
-
}
|
|
436
|
-
function collectObjectQueryValidationIssues2(query, options) {
|
|
437
|
-
const normalized = options.normalize === false ? query : normalizeObjectQuery2(query);
|
|
438
|
-
const ctx = createValidationContext(options, NOOP_QUERY_ADMISSION);
|
|
439
|
-
validateVectorComposition(query, ctx);
|
|
440
|
-
validateQueryNode(normalized, "$", ctx);
|
|
441
|
-
return ctx.issues;
|
|
442
|
-
}
|
|
443
|
-
function resolveObjectQueryResultShape2(query, options) {
|
|
444
|
-
return validateObjectQuery2(query, options).result;
|
|
445
|
-
}
|
|
446
|
-
function validateVectorComposition(query, ctx) {
|
|
447
|
-
if (hasVectorProfile2(query) && !isVectorProfileQuery2(query))
|
|
448
|
-
ctx.issues.push({
|
|
449
|
-
path: "$",
|
|
450
|
-
code: "vector.composition",
|
|
451
|
-
message: "Vector profiles support one top-k over one concrete type, with filters before ranking and optional limit/project after it."
|
|
452
|
-
});
|
|
453
|
-
}
|
|
454
|
-
function createValidationContext(options, admission) {
|
|
455
|
-
return {
|
|
456
|
-
ontology: options.ontology,
|
|
457
|
-
valueTypesById: options.ontology.getValueTypesById(),
|
|
458
|
-
maxLimit: options.maxLimit ?? DEFAULT_MAX_LIMIT,
|
|
459
|
-
maxPageSize: options.maxPageSize ?? DEFAULT_MAX_PAGE_SIZE,
|
|
460
|
-
maxRefs: options.maxRefs ?? DEFAULT_MAX_REFS,
|
|
461
|
-
issues: [],
|
|
462
|
-
touchedObjectTypeIds: new Set,
|
|
463
|
-
admission,
|
|
464
|
-
admissionDenials: []
|
|
465
|
-
};
|
|
466
|
-
}
|
|
467
|
-
function validateQueryNode(query, path, ctx) {
|
|
468
|
-
const validation = dispatchQueryNode(query, path, ctx);
|
|
469
|
-
for (const objectTypeId of validation.result.objectTypeIds) {
|
|
470
|
-
ctx.touchedObjectTypeIds.add(objectTypeId);
|
|
471
|
-
}
|
|
472
|
-
return validation;
|
|
132
|
+
return validation;
|
|
473
133
|
}
|
|
474
134
|
function dispatchQueryNode(query, path, ctx) {
|
|
475
135
|
switch (query.kind) {
|
|
@@ -545,6 +205,16 @@ function dispatchQueryNode(query, path, ctx) {
|
|
|
545
205
|
}))
|
|
546
206
|
};
|
|
547
207
|
}
|
|
208
|
+
case "rerank": {
|
|
209
|
+
const input = validateQueryNode(query.input, `${path}.input`, ctx);
|
|
210
|
+
if (input.query.kind !== "vector" || typeof input.query.vector !== "string" || input.query.k > MAX_RERANK_CANDIDATES) {
|
|
211
|
+
addIssue(ctx, path, "invalid_rerank_input", `Reranking requires a text vector query with k at most ${MAX_RERANK_CANDIDATES}, before limit or project.`);
|
|
212
|
+
}
|
|
213
|
+
if (typeof query.model?.provider !== "string" || !query.model.provider.trim() || query.model.provider.trim() !== query.model.provider || typeof query.model.modelId !== "string" || !query.model.modelId.trim() || query.model.modelId.trim() !== query.model.modelId) {
|
|
214
|
+
addIssue(ctx, path, "invalid_rerank_model", "Reranking requires an explicit provider and model ID.");
|
|
215
|
+
}
|
|
216
|
+
return { ...input, query: { ...query, model: { ...query.model }, input: input.query } };
|
|
217
|
+
}
|
|
548
218
|
case "set":
|
|
549
219
|
return validateSet(query.inputs, query.op, path, ctx);
|
|
550
220
|
case "sort": {
|
|
@@ -596,23 +266,23 @@ function dispatchQueryNode(query, path, ctx) {
|
|
|
596
266
|
}
|
|
597
267
|
function validateRefs(refs, path, ctx) {
|
|
598
268
|
if (refs.length === 0) {
|
|
599
|
-
|
|
269
|
+
addIssue(ctx, `${path}.refs`, "empty_refs", "refs must include at least one object reference");
|
|
600
270
|
}
|
|
601
271
|
if (refs.length > ctx.maxRefs) {
|
|
602
|
-
|
|
272
|
+
addIssue(ctx, `${path}.refs`, "too_many_refs", `refs must include at most ${ctx.maxRefs} object references`);
|
|
603
273
|
}
|
|
604
274
|
const objectTypeIds = new Set;
|
|
605
275
|
refs.forEach((ref, index) => {
|
|
606
276
|
const refPath = `${path}.refs[${index}]`;
|
|
607
277
|
if (!ref.objectTypeId) {
|
|
608
|
-
|
|
278
|
+
addIssue(ctx, `${refPath}.objectTypeId`, "missing_object_type", "objectTypeId is required");
|
|
609
279
|
} else if (!ctx.ontology.getObjectTypeById(ref.objectTypeId)) {
|
|
610
|
-
|
|
280
|
+
addIssue(ctx, `${refPath}.objectTypeId`, "unknown_object_type", formatUnknownObjectTypeMessage(ref.objectTypeId));
|
|
611
281
|
} else {
|
|
612
282
|
objectTypeIds.add(ref.objectTypeId);
|
|
613
283
|
}
|
|
614
284
|
if (!ref.primaryId) {
|
|
615
|
-
|
|
285
|
+
addIssue(ctx, `${refPath}.primaryId`, "missing_primary_id", "primaryId is required");
|
|
616
286
|
}
|
|
617
287
|
});
|
|
618
288
|
return {
|
|
@@ -622,11 +292,11 @@ function validateRefs(refs, path, ctx) {
|
|
|
622
292
|
}
|
|
623
293
|
function validateStart(objectTypeId, includeSubtypes, path, ctx) {
|
|
624
294
|
if (!objectTypeId) {
|
|
625
|
-
|
|
295
|
+
addIssue(ctx, path, "missing_object_type", "start.objectTypeId is required");
|
|
626
296
|
return { result: { objectTypeIds: [] }, query: { kind: "start", objectTypeId } };
|
|
627
297
|
}
|
|
628
298
|
if (!ctx.ontology.getObjectTypeById(objectTypeId)) {
|
|
629
|
-
|
|
299
|
+
addIssue(ctx, path, "unknown_object_type", formatUnknownObjectTypeMessage(objectTypeId));
|
|
630
300
|
return { result: { objectTypeIds: [] }, query: { kind: "start", objectTypeId } };
|
|
631
301
|
}
|
|
632
302
|
const objectTypeIds = includeSubtypes ? uniqueStrings([objectTypeId, ...ctx.ontology.listSubTypes(objectTypeId)]) : [objectTypeId];
|
|
@@ -637,7 +307,7 @@ function validatePredicate(predicate, shape, admissionState, path, ctx) {
|
|
|
637
307
|
case "and":
|
|
638
308
|
case "or":
|
|
639
309
|
if (predicate.items.length === 0) {
|
|
640
|
-
|
|
310
|
+
addIssue(ctx, path, "empty_predicate_group", `Predicate '${predicate.op}' must not be empty`);
|
|
641
311
|
}
|
|
642
312
|
return {
|
|
643
313
|
...predicate,
|
|
@@ -673,7 +343,7 @@ function validatePredicate(predicate, shape, admissionState, path, ctx) {
|
|
|
673
343
|
const { scalarKind: _authoredScalarKind, ...authoredPredicate } = predicate;
|
|
674
344
|
const scalarKind = resolveAndValidatePredicateProperty(predicate.propertyId, predicate.op, shape, path, ctx);
|
|
675
345
|
if (predicate.values.length === 0) {
|
|
676
|
-
|
|
346
|
+
addIssue(ctx, path, "empty_in_values", "Predicate 'in' must include at least one value");
|
|
677
347
|
}
|
|
678
348
|
predicate.values.forEach((value, index) => {
|
|
679
349
|
validatePredicateValue(predicate.propertyId, value, shape, `${path}.values[${index}]`, ctx);
|
|
@@ -699,7 +369,7 @@ function validatePredicate(predicate, shape, admissionState, path, ctx) {
|
|
|
699
369
|
path
|
|
700
370
|
});
|
|
701
371
|
if (typeof predicate.value !== "boolean") {
|
|
702
|
-
|
|
372
|
+
addIssue(ctx, path, "invalid_exists_value", "Predicate 'exists' value must be boolean");
|
|
703
373
|
}
|
|
704
374
|
return predicate;
|
|
705
375
|
case "contains": {
|
|
@@ -733,19 +403,19 @@ function resolveAndValidatePredicateProperty(propertyId, op, shape, path, ctx) {
|
|
|
733
403
|
continue;
|
|
734
404
|
}
|
|
735
405
|
if (property.query?.searchable !== true || property.query.filterable !== true) {
|
|
736
|
-
|
|
406
|
+
addIssue(ctx, path, "property_not_filterable", `Property '${propertyId}' on '${objectType.id}' must set query.searchable: true and query.filterable: true before it can be used in predicates`);
|
|
737
407
|
continue;
|
|
738
408
|
}
|
|
739
409
|
if (!schema)
|
|
740
410
|
continue;
|
|
741
411
|
if ((op === "lt" || op === "lte" || op === "gt" || op === "gte") && !isSortableSchema(schema)) {
|
|
742
|
-
|
|
412
|
+
addIssue(ctx, path, "operator_not_supported_for_schema", `Predicate '${op}' cannot be used with property '${propertyId}' on '${objectType.id}' because its schema is not orderable`);
|
|
743
413
|
}
|
|
744
414
|
if ((op === "eq" || op === "neq" || op === "in" || op === "exists") && !isExactSchema(schema)) {
|
|
745
|
-
|
|
415
|
+
addIssue(ctx, path, "operator_not_supported_for_schema", `Predicate '${op}' cannot be used with property '${propertyId}' on '${objectType.id}' because its schema cannot be exact-matched`);
|
|
746
416
|
}
|
|
747
417
|
if (op === "contains" && !isContainsSchema(schema)) {
|
|
748
|
-
|
|
418
|
+
addIssue(ctx, path, "operator_not_supported_for_schema", `Predicate 'contains' cannot be used with property '${propertyId}' on '${objectType.id}' because its schema is not string, array, or map`);
|
|
749
419
|
}
|
|
750
420
|
}
|
|
751
421
|
if (op === "exists")
|
|
@@ -790,7 +460,7 @@ function resolveCommonQueryScalarKind(schemas, propertyId, path, ctx) {
|
|
|
790
460
|
const resolvedKinds = new Set(scalarKinds);
|
|
791
461
|
if (resolvedKinds.size === 1)
|
|
792
462
|
return scalarKinds[0];
|
|
793
|
-
|
|
463
|
+
addIssue(ctx, path, "incompatible_property_scalar_kinds", `Property '${propertyId}' resolves to incompatible scalar schemas: ${[...resolvedKinds].join(", ")}`);
|
|
794
464
|
return;
|
|
795
465
|
}
|
|
796
466
|
function validatePredicateValue(propertyId, value, shape, path, ctx) {
|
|
@@ -800,7 +470,7 @@ function validatePredicateValue(propertyId, value, shape, path, ctx) {
|
|
|
800
470
|
try {
|
|
801
471
|
validatePropertyValue2(property, value, `${objectType.id}.${property.id}`, ctx.valueTypesById);
|
|
802
472
|
} catch (error) {
|
|
803
|
-
|
|
473
|
+
addIssue(ctx, path, "invalid_predicate_value", error instanceof Error ? error.message : `Invalid value for property '${property.id}' on '${objectType.id}'`);
|
|
804
474
|
}
|
|
805
475
|
}
|
|
806
476
|
}
|
|
@@ -814,7 +484,7 @@ function validateContainsValue(propertyId, value, shape, path, ctx) {
|
|
|
814
484
|
if (typeof schema === "string") {
|
|
815
485
|
if (isContainsSchema(schema)) {
|
|
816
486
|
if (typeof value !== "string") {
|
|
817
|
-
|
|
487
|
+
addIssue(ctx, path, "invalid_contains_value", `Predicate 'contains' value for '${objectType.id}.${property.id}' must be a string`);
|
|
818
488
|
}
|
|
819
489
|
}
|
|
820
490
|
continue;
|
|
@@ -823,24 +493,24 @@ function validateContainsValue(propertyId, value, shape, path, ctx) {
|
|
|
823
493
|
try {
|
|
824
494
|
validateSchemaValue2(schema.items, value, `${objectType.id}.${property.id}[]`, ctx.valueTypesById);
|
|
825
495
|
} catch (error) {
|
|
826
|
-
|
|
496
|
+
addIssue(ctx, path, "invalid_contains_value", error instanceof Error ? error.message : `Invalid contains value for '${objectType.id}.${property.id}'`);
|
|
827
497
|
}
|
|
828
498
|
continue;
|
|
829
499
|
}
|
|
830
500
|
if (schema.type === "map" && typeof value !== "string") {
|
|
831
|
-
|
|
501
|
+
addIssue(ctx, path, "invalid_contains_value", `Predicate 'contains' value for '${objectType.id}.${property.id}' must be a map key string`);
|
|
832
502
|
}
|
|
833
503
|
}
|
|
834
504
|
}
|
|
835
505
|
function validateTextQuery(query, fields, shape, admissionState, path, ctx) {
|
|
836
506
|
if (query.trim().length === 0) {
|
|
837
|
-
|
|
507
|
+
addIssue(ctx, path, "empty_text_query", "Text query must not be empty");
|
|
838
508
|
}
|
|
839
509
|
const fieldsByObjectType = fields ? undefined : {};
|
|
840
510
|
for (const objectType of getObjectTypesForResult(shape, ctx)) {
|
|
841
511
|
const fieldIds = fields ?? objectType.search?.defaultText;
|
|
842
512
|
if (!fieldIds || fieldIds.length === 0) {
|
|
843
|
-
|
|
513
|
+
addIssue(ctx, path, "missing_text_fields", `Object type '${objectType.id}' must define search.defaultText or the text query must specify fields`);
|
|
844
514
|
continue;
|
|
845
515
|
}
|
|
846
516
|
if (fieldsByObjectType)
|
|
@@ -855,14 +525,14 @@ function validateTextQuery(query, fields, shape, admissionState, path, ctx) {
|
|
|
855
525
|
});
|
|
856
526
|
const property = getProperty(objectType, fieldId);
|
|
857
527
|
if (!property) {
|
|
858
|
-
|
|
528
|
+
addIssue(ctx, path, "unknown_text_field", `Text query references unknown property '${fieldId}' on '${objectType.id}'`);
|
|
859
529
|
continue;
|
|
860
530
|
}
|
|
861
531
|
assertStaticSearchProperty(objectType.id, property, "text query", path, ctx);
|
|
862
532
|
assertQueryFlag(objectType.id, property, "text", "text query", path, ctx);
|
|
863
533
|
const schema = resolveSchemaForProperty(property, objectType.id, ctx, path);
|
|
864
534
|
if (schema && !isTextSchema(schema)) {
|
|
865
|
-
|
|
535
|
+
addIssue(ctx, path, "text_field_not_string_like", `Text query field '${fieldId}' on '${objectType.id}' must be string-like`);
|
|
866
536
|
}
|
|
867
537
|
}
|
|
868
538
|
}
|
|
@@ -871,18 +541,13 @@ function validateTextQuery(query, fields, shape, admissionState, path, ctx) {
|
|
|
871
541
|
function validateVectorProfileQuery(query, shape, state, path, ctx) {
|
|
872
542
|
const types = getObjectTypesForResult(shape, ctx);
|
|
873
543
|
if (types.length !== 1 || !Number.isSafeInteger(query.k) || query.k < 1 || query.k > MAX_VECTOR_K) {
|
|
874
|
-
|
|
544
|
+
addIssue(ctx, path, "invalid_vector_profile_query", `Vector search requires one type, one profile and k between 1 and ${MAX_VECTOR_K}`);
|
|
875
545
|
return query;
|
|
876
546
|
}
|
|
877
|
-
let input = query.input;
|
|
878
|
-
while (input.kind === "filter")
|
|
879
|
-
input = input.input;
|
|
880
|
-
if (input.kind !== "start" || input.includeSubtypes)
|
|
881
|
-
addIssue2(ctx, path, "unsupported_vector_composition", "Vector profile input must be a type with optional filters.");
|
|
882
547
|
const objectType = types[0];
|
|
883
548
|
const profile = query.profile === undefined ? undefined : objectType.search?.vectors?.[query.profile];
|
|
884
549
|
if (!profile) {
|
|
885
|
-
|
|
550
|
+
addIssue(ctx, path, "unknown_vector_profile", `Unknown vector profile: ${query.profile}`);
|
|
886
551
|
return query;
|
|
887
552
|
}
|
|
888
553
|
for (const propertyId of profile.source)
|
|
@@ -897,7 +562,7 @@ function validateVectorProfileQuery(query, shape, state, path, ctx) {
|
|
|
897
562
|
values = normalizeVector2(values, profile.model.definition.dimensions);
|
|
898
563
|
}
|
|
899
564
|
} catch (error) {
|
|
900
|
-
|
|
565
|
+
addIssue(ctx, path, "invalid_vector", error instanceof Error ? error.message : "Invalid vector");
|
|
901
566
|
}
|
|
902
567
|
return {
|
|
903
568
|
...query,
|
|
@@ -908,12 +573,12 @@ function validateVectorProfileQuery(query, shape, state, path, ctx) {
|
|
|
908
573
|
}
|
|
909
574
|
function validateTraverse(linkId, direction, sourceObjectTypeId, shape, path, ctx) {
|
|
910
575
|
if (!linkId) {
|
|
911
|
-
|
|
576
|
+
addIssue(ctx, path, "missing_link_id", "traverse.linkId is required");
|
|
912
577
|
return { objectTypeIds: [] };
|
|
913
578
|
}
|
|
914
579
|
if (direction === "outgoing") {
|
|
915
580
|
if (sourceObjectTypeId !== undefined) {
|
|
916
|
-
|
|
581
|
+
addIssue(ctx, path, "traverse_source_not_applicable", "traverse.sourceObjectTypeId only applies to incoming traversal");
|
|
917
582
|
}
|
|
918
583
|
return validateOutgoingTraverse(linkId, shape, path, ctx);
|
|
919
584
|
}
|
|
@@ -924,17 +589,17 @@ function validateOutgoingTraverse(linkId, shape, path, ctx) {
|
|
|
924
589
|
for (const objectType of getObjectTypesForResult(shape, ctx)) {
|
|
925
590
|
const link = objectType.links.find((candidate) => candidate.id === linkId);
|
|
926
591
|
if (!link) {
|
|
927
|
-
|
|
592
|
+
addIssue(ctx, path, "unknown_link", `Outgoing traversal references unknown link '${linkId}' on '${objectType.id}'`);
|
|
928
593
|
continue;
|
|
929
594
|
}
|
|
930
595
|
if (link.targetObjectTypeId === "*") {
|
|
931
|
-
|
|
596
|
+
addIssue(ctx, path, "wildcard_traverse_target", `Outgoing traversal over wildcard link '${objectType.id}.${linkId}' cannot infer a target object type`);
|
|
932
597
|
continue;
|
|
933
598
|
}
|
|
934
599
|
const declaredTargets = Array.isArray(link.targetObjectTypeId) ? link.targetObjectTypeId : [link.targetObjectTypeId];
|
|
935
600
|
for (const targetId of declaredTargets) {
|
|
936
601
|
if (!ctx.ontology.getObjectTypeById(targetId)) {
|
|
937
|
-
|
|
602
|
+
addIssue(ctx, path, "unknown_link_target", `Outgoing traversal over '${objectType.id}.${linkId}' targets unknown object type '${targetId}'`);
|
|
938
603
|
} else {
|
|
939
604
|
targetTypeIds.push(targetId);
|
|
940
605
|
}
|
|
@@ -947,7 +612,7 @@ function validateIncomingTraverse(linkId, sourceObjectTypeId, shape, path, ctx)
|
|
|
947
612
|
if (sourceObjectTypeId !== undefined) {
|
|
948
613
|
const sourceType = ctx.ontology.getObjectTypeById(sourceObjectTypeId);
|
|
949
614
|
if (!sourceType) {
|
|
950
|
-
|
|
615
|
+
addIssue(ctx, path, "unknown_traverse_source", `Incoming traversal references unknown source object type '${sourceObjectTypeId}'`);
|
|
951
616
|
return { objectTypeIds: [] };
|
|
952
617
|
}
|
|
953
618
|
candidateTypes = [sourceType];
|
|
@@ -966,7 +631,7 @@ function validateIncomingTraverse(linkId, sourceObjectTypeId, shape, path, ctx)
|
|
|
966
631
|
sourceTypeIds.push(sourceType.id);
|
|
967
632
|
}
|
|
968
633
|
if (sourceTypeIds.length === 0) {
|
|
969
|
-
|
|
634
|
+
addIssue(ctx, path, "incoming_link_not_found", `Incoming traversal found no source object types with link '${linkId}' targeting ${shape.objectTypeIds.join(" | ")}`);
|
|
970
635
|
}
|
|
971
636
|
return { objectTypeIds: uniqueStrings(sourceTypeIds) };
|
|
972
637
|
}
|
|
@@ -975,7 +640,7 @@ function validateExpansions(expansions, shape, admissionState, path, ctx) {
|
|
|
975
640
|
}
|
|
976
641
|
function validateExpansion(expansion, shape, admissionState, path, ctx) {
|
|
977
642
|
if (!expansion.linkId) {
|
|
978
|
-
|
|
643
|
+
addIssue(ctx, path, "missing_expand_link", "expand.linkId is required");
|
|
979
644
|
return expansion;
|
|
980
645
|
}
|
|
981
646
|
const targetShape = expansion.direction === "incoming" ? resolveIncomingExpansionTargets(expansion.linkId, expansion.sourceObjectTypeId, shape, path, ctx) : resolveOutgoingExpansionTargets(expansion.linkId, expansion.sourceObjectTypeId, shape, path, ctx);
|
|
@@ -998,7 +663,7 @@ function validateExpansion(expansion, shape, admissionState, path, ctx) {
|
|
|
998
663
|
}
|
|
999
664
|
function resolveOutgoingExpansionTargets(linkId, sourceObjectTypeId, shape, path, ctx) {
|
|
1000
665
|
if (sourceObjectTypeId !== undefined) {
|
|
1001
|
-
|
|
666
|
+
addIssue(ctx, path, "expand_source_not_applicable", "expand.sourceObjectTypeId only applies to incoming expansion");
|
|
1002
667
|
}
|
|
1003
668
|
const targetTypeIds = [];
|
|
1004
669
|
let foundOnAnyType = false;
|
|
@@ -1008,20 +673,20 @@ function resolveOutgoingExpansionTargets(linkId, sourceObjectTypeId, shape, path
|
|
|
1008
673
|
continue;
|
|
1009
674
|
foundOnAnyType = true;
|
|
1010
675
|
if (link.targetObjectTypeId === "*") {
|
|
1011
|
-
|
|
676
|
+
addIssue(ctx, path, "wildcard_expand_target", `Expansion over wildcard link '${objectType.id}.${linkId}' cannot infer a target object type`);
|
|
1012
677
|
continue;
|
|
1013
678
|
}
|
|
1014
679
|
const declaredTargets = Array.isArray(link.targetObjectTypeId) ? link.targetObjectTypeId : [link.targetObjectTypeId];
|
|
1015
680
|
for (const targetId of declaredTargets) {
|
|
1016
681
|
if (!ctx.ontology.getObjectTypeById(targetId)) {
|
|
1017
|
-
|
|
682
|
+
addIssue(ctx, path, "unknown_expand_target", `Expansion over '${objectType.id}.${linkId}' targets unknown object type '${targetId}'`);
|
|
1018
683
|
} else {
|
|
1019
684
|
targetTypeIds.push(targetId);
|
|
1020
685
|
}
|
|
1021
686
|
}
|
|
1022
687
|
}
|
|
1023
688
|
if (!foundOnAnyType) {
|
|
1024
|
-
|
|
689
|
+
addIssue(ctx, path, "unknown_expand_link", `Expansion references link '${linkId}' not present on result type ${shape.objectTypeIds.join(" | ")} (an expand abandoned by a later traverse?)`);
|
|
1025
690
|
}
|
|
1026
691
|
return { objectTypeIds: uniqueStrings(targetTypeIds) };
|
|
1027
692
|
}
|
|
@@ -1030,7 +695,7 @@ function resolveIncomingExpansionTargets(linkId, sourceObjectTypeId, shape, path
|
|
|
1030
695
|
if (sourceObjectTypeId !== undefined) {
|
|
1031
696
|
const sourceType = ctx.ontology.getObjectTypeById(sourceObjectTypeId);
|
|
1032
697
|
if (!sourceType) {
|
|
1033
|
-
|
|
698
|
+
addIssue(ctx, path, "unknown_expand_source", `Incoming expansion references unknown source object type '${sourceObjectTypeId}'`);
|
|
1034
699
|
return { objectTypeIds: [] };
|
|
1035
700
|
}
|
|
1036
701
|
candidateTypes = [sourceType];
|
|
@@ -1049,7 +714,7 @@ function resolveIncomingExpansionTargets(linkId, sourceObjectTypeId, shape, path
|
|
|
1049
714
|
sourceTypeIds.push(sourceType.id);
|
|
1050
715
|
}
|
|
1051
716
|
if (sourceTypeIds.length === 0) {
|
|
1052
|
-
|
|
717
|
+
addIssue(ctx, path, "incoming_expand_link_not_found", `Incoming expansion found no source object types with link '${linkId}' targeting ${shape.objectTypeIds.join(" | ")}`);
|
|
1053
718
|
}
|
|
1054
719
|
return { objectTypeIds: uniqueStrings(sourceTypeIds) };
|
|
1055
720
|
}
|
|
@@ -1057,12 +722,12 @@ function validateExpansionLimit(limit, path, ctx) {
|
|
|
1057
722
|
if (limit === undefined)
|
|
1058
723
|
return;
|
|
1059
724
|
if (!Number.isInteger(limit) || limit < 0) {
|
|
1060
|
-
|
|
725
|
+
addIssue(ctx, `${path}.limit`, "invalid_expand_limit", "expand.limit must be a non-negative integer");
|
|
1061
726
|
}
|
|
1062
727
|
}
|
|
1063
728
|
function validateSet(inputs, op, path, ctx) {
|
|
1064
729
|
if (inputs.length === 0) {
|
|
1065
|
-
|
|
730
|
+
addIssue(ctx, path, "empty_set", `Set operation '${op}' must include at least one input`);
|
|
1066
731
|
return {
|
|
1067
732
|
result: { objectTypeIds: [] },
|
|
1068
733
|
query: { kind: "set", op, inputs },
|
|
@@ -1074,7 +739,7 @@ function validateSet(inputs, op, path, ctx) {
|
|
|
1074
739
|
const expected = keyForTypeIds(first.objectTypeIds);
|
|
1075
740
|
results.forEach((result, index) => {
|
|
1076
741
|
if (keyForTypeIds(result.result.objectTypeIds) !== expected) {
|
|
1077
|
-
|
|
742
|
+
addIssue(ctx, `${path}.inputs[${index}]`, "incompatible_set_input", `Set operation '${op}' inputs must produce the same object type set`);
|
|
1078
743
|
}
|
|
1079
744
|
});
|
|
1080
745
|
return {
|
|
@@ -1089,17 +754,17 @@ function validateSet(inputs, op, path, ctx) {
|
|
|
1089
754
|
}
|
|
1090
755
|
function validateSortFields(fields, shape, admissionState, use, path, ctx) {
|
|
1091
756
|
if (fields.length === 0) {
|
|
1092
|
-
|
|
757
|
+
addIssue(ctx, path, "empty_sort", "Sort must include at least one field");
|
|
1093
758
|
return [];
|
|
1094
759
|
}
|
|
1095
760
|
const seen = new Set;
|
|
1096
761
|
return fields.map((field, index) => {
|
|
1097
762
|
if (field.direction && field.direction !== "asc" && field.direction !== "desc") {
|
|
1098
|
-
|
|
763
|
+
addIssue(ctx, `${path}.fields[${index}]`, "invalid_sort_direction", "Sort direction must be asc or desc");
|
|
1099
764
|
}
|
|
1100
765
|
const key = field.kind === "property" ? `property:${field.propertyId}` : "relevance";
|
|
1101
766
|
if (seen.has(key)) {
|
|
1102
|
-
|
|
767
|
+
addIssue(ctx, `${path}.fields[${index}]`, "duplicate_sort_field", `Duplicate sort field '${key}'`);
|
|
1103
768
|
}
|
|
1104
769
|
seen.add(key);
|
|
1105
770
|
if (field.kind === "relevance")
|
|
@@ -1114,143 +779,604 @@ function validateSortFields(fields, shape, admissionState, use, path, ctx) {
|
|
|
1114
779
|
const schemas = [];
|
|
1115
780
|
for (const { objectType, property } of getPropertiesForResult(field.propertyId, shape, `${path}.fields[${index}]`, ctx)) {
|
|
1116
781
|
if (property.query?.searchable !== true || property.query.sortable !== true) {
|
|
1117
|
-
|
|
782
|
+
addIssue(ctx, `${path}.fields[${index}]`, "property_not_sortable", `Property '${property.id}' on '${objectType.id}' must set query.searchable: true and query.sortable: true before it can be sorted`);
|
|
1118
783
|
continue;
|
|
1119
784
|
}
|
|
1120
785
|
const schema = resolveSchemaForProperty(property, objectType.id, ctx, `${path}.fields[${index}]`);
|
|
1121
786
|
if (schema)
|
|
1122
787
|
schemas.push(schema);
|
|
1123
788
|
if (schema && !isSortableSchema(schema)) {
|
|
1124
|
-
|
|
789
|
+
addIssue(ctx, `${path}.fields[${index}]`, "sort_field_not_orderable", `Sort field '${property.id}' on '${objectType.id}' is not orderable`);
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
const scalarKind = resolveCommonQueryScalarKind(schemas, field.propertyId, `${path}.fields[${index}]`, ctx);
|
|
793
|
+
return { ...authoredField, ...scalarKind ? { scalarKind } : {} };
|
|
794
|
+
});
|
|
795
|
+
}
|
|
796
|
+
function validateLimit(limit, path, ctx) {
|
|
797
|
+
if (!Number.isInteger(limit) || limit < 0) {
|
|
798
|
+
addIssue(ctx, path, "invalid_limit", "limit must be a non-negative integer");
|
|
799
|
+
} else if (limit > ctx.maxLimit) {
|
|
800
|
+
addIssue(ctx, path, "limit_too_large", `limit must be <= ${ctx.maxLimit}`);
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
function validatePage(pageSize, pageToken, path, ctx) {
|
|
804
|
+
if (!Number.isInteger(pageSize) || pageSize <= 0) {
|
|
805
|
+
addIssue(ctx, path, "invalid_page_size", "pageSize must be a positive integer");
|
|
806
|
+
} else if (pageSize > ctx.maxPageSize) {
|
|
807
|
+
addIssue(ctx, path, "page_size_too_large", `pageSize must be <= ${ctx.maxPageSize}`);
|
|
808
|
+
}
|
|
809
|
+
if (pageToken !== undefined && pageToken.length === 0) {
|
|
810
|
+
addIssue(ctx, path, "empty_page_token", "pageToken must not be empty when provided");
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
function validateProjection(properties, shape, admissionState, path, ctx) {
|
|
814
|
+
if (!properties)
|
|
815
|
+
return;
|
|
816
|
+
if (properties.length === 0) {
|
|
817
|
+
addIssue(ctx, path, "empty_projection", "project.properties must not be empty when provided");
|
|
818
|
+
}
|
|
819
|
+
const seen = new Set;
|
|
820
|
+
properties.forEach((propertyId, index) => {
|
|
821
|
+
admitProperty(ctx, {
|
|
822
|
+
state: admissionState,
|
|
823
|
+
propertyId,
|
|
824
|
+
use: "project",
|
|
825
|
+
path: `${path}.properties[${index}]`
|
|
826
|
+
});
|
|
827
|
+
if (seen.has(propertyId)) {
|
|
828
|
+
addIssue(ctx, `${path}.properties[${index}]`, "duplicate_projection_property", `Duplicate projected property '${propertyId}'`);
|
|
829
|
+
}
|
|
830
|
+
seen.add(propertyId);
|
|
831
|
+
getPropertiesForResult(propertyId, shape, `${path}.properties[${index}]`, ctx);
|
|
832
|
+
});
|
|
833
|
+
}
|
|
834
|
+
function getObjectTypesForResult(shape, ctx) {
|
|
835
|
+
const objectTypes = [];
|
|
836
|
+
for (const objectTypeId of shape.objectTypeIds) {
|
|
837
|
+
const objectType = ctx.ontology.getObjectTypeById(objectTypeId);
|
|
838
|
+
if (objectType)
|
|
839
|
+
objectTypes.push(objectType);
|
|
840
|
+
}
|
|
841
|
+
return objectTypes;
|
|
842
|
+
}
|
|
843
|
+
function getPropertiesForResult(propertyId, shape, path, ctx, options = {}) {
|
|
844
|
+
const results = [];
|
|
845
|
+
for (const objectType of getObjectTypesForResult(shape, ctx)) {
|
|
846
|
+
const property = getProperty(objectType, propertyId);
|
|
847
|
+
if (!property) {
|
|
848
|
+
if (options.reportMissing === false) {
|
|
849
|
+
continue;
|
|
850
|
+
}
|
|
851
|
+
addIssue(ctx, path, "unknown_property", `Property '${propertyId}' does not exist on object type '${objectType.id}'`);
|
|
852
|
+
continue;
|
|
853
|
+
}
|
|
854
|
+
results.push({ objectType, property });
|
|
855
|
+
}
|
|
856
|
+
return results;
|
|
857
|
+
}
|
|
858
|
+
function getProperty(objectType, propertyId) {
|
|
859
|
+
return objectType.properties.find((property) => property.id === propertyId);
|
|
860
|
+
}
|
|
861
|
+
function assertStaticSearchProperty(objectTypeId, property, context, path, ctx) {
|
|
862
|
+
if (property.mode === "telemetry") {
|
|
863
|
+
addIssue(ctx, path, "telemetry_search_property", `${context} references telemetry property '${property.id}' on '${objectTypeId}'. Search can only reference static properties because telemetry latest values are not object-query indexed.`);
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
function assertQueryFlag(objectTypeId, property, flag, context, path, ctx) {
|
|
867
|
+
if (property.query?.searchable === true && property.query[flag] === true)
|
|
868
|
+
return;
|
|
869
|
+
addIssue(ctx, path, "query_field_not_enabled", `${context} field '${property.id}' on '${objectTypeId}' must set query.searchable: true and query.${flag}: true`);
|
|
870
|
+
}
|
|
871
|
+
function resolveSchemaForProperty(property, objectTypeId, ctx, path) {
|
|
872
|
+
try {
|
|
873
|
+
return resolveSchema(property.schema, ctx.valueTypesById);
|
|
874
|
+
} catch (error) {
|
|
875
|
+
addIssue(ctx, path, "unresolved_property_schema", error instanceof Error ? error.message : `Could not resolve schema for '${objectTypeId}.${property.id}'`);
|
|
876
|
+
return null;
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
function resolveSchema(schema, valueTypesById, seenValueTypeIds = new Set) {
|
|
880
|
+
if (typeof schema === "string")
|
|
881
|
+
return schema;
|
|
882
|
+
if (schema.type !== "valueTypeRef")
|
|
883
|
+
return schema;
|
|
884
|
+
if (seenValueTypeIds.has(schema.valueTypeId)) {
|
|
885
|
+
throw new Error(`Circular valueTypeRef '${schema.valueTypeId}'`);
|
|
886
|
+
}
|
|
887
|
+
const resolved = schema._resolved ?? valueTypesById.get(schema.valueTypeId)?.schema;
|
|
888
|
+
if (!resolved) {
|
|
889
|
+
throw new Error(`Unknown valueTypeRef '${schema.valueTypeId}'`);
|
|
890
|
+
}
|
|
891
|
+
seenValueTypeIds.add(schema.valueTypeId);
|
|
892
|
+
return resolveSchema(resolved, valueTypesById, seenValueTypeIds);
|
|
893
|
+
}
|
|
894
|
+
function isPrimaryExactPredicate(property, op) {
|
|
895
|
+
return property.primary === true && (op === "eq" || op === "in");
|
|
896
|
+
}
|
|
897
|
+
function keyForTypeIds(typeIds) {
|
|
898
|
+
return uniqueStrings(typeIds).sort().join("\x00");
|
|
899
|
+
}
|
|
900
|
+
function uniqueStrings(values) {
|
|
901
|
+
return [...new Set(values)];
|
|
902
|
+
}
|
|
903
|
+
function admitTransition(ctx, transition) {
|
|
904
|
+
if (transition.denial)
|
|
905
|
+
recordAdmissionDenial(ctx, transition.denial);
|
|
906
|
+
return transition.state;
|
|
907
|
+
}
|
|
908
|
+
function admitProperty(ctx, input) {
|
|
909
|
+
const denial = ctx.admission.property(input);
|
|
910
|
+
if (denial)
|
|
911
|
+
recordAdmissionDenial(ctx, denial);
|
|
912
|
+
}
|
|
913
|
+
function recordAdmissionDenial(ctx, denial) {
|
|
914
|
+
if (ctx.admissionDenials.length === 0)
|
|
915
|
+
ctx.admissionDenials.push(denial);
|
|
916
|
+
}
|
|
917
|
+
function addIssue(ctx, path, code, message) {
|
|
918
|
+
ctx.issues.push({ path, code, message });
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
// src/objects/vectors/resolve-query.ts
|
|
922
|
+
var QUERY_EMBEDDING_TIMEOUT_MS = 30000;
|
|
923
|
+
async function resolveVectorSearchText(query, ontology, models, signal) {
|
|
924
|
+
if (query.kind === "limit" || query.kind === "project") {
|
|
925
|
+
const input = await resolveVectorSearchText(query.input, ontology, models, signal);
|
|
926
|
+
return { ...query, input };
|
|
927
|
+
}
|
|
928
|
+
if (query.kind !== "vector" || typeof query.vector !== "string")
|
|
929
|
+
return query;
|
|
930
|
+
const model = resolveProfileEmbeddingModel(query, ontology, models);
|
|
931
|
+
const vector = await embedSearchText(query.vector, model, signal);
|
|
932
|
+
return { ...query, vector };
|
|
933
|
+
}
|
|
934
|
+
function resolveProfileEmbeddingModel(query, ontology, models) {
|
|
935
|
+
const { objectTypeIds } = resolveObjectQueryResultShape2(query.input, {
|
|
936
|
+
ontology,
|
|
937
|
+
normalize: false
|
|
938
|
+
});
|
|
939
|
+
const objectTypeId = objectTypeIds.length === 1 ? objectTypeIds[0] : undefined;
|
|
940
|
+
if (!objectTypeId || !query.profile) {
|
|
941
|
+
throw new ObjectQueryExecutionError2("embedding_model_unavailable", "Vector search requires the embedding model registered for its profile.");
|
|
942
|
+
}
|
|
943
|
+
const profile = ontology.resolveObjectType(objectTypeId).search?.vectors?.[query.profile];
|
|
944
|
+
if (!profile) {
|
|
945
|
+
throw new ObjectQueryExecutionError2("embedding_model_unavailable", "Vector search requires the embedding model registered for its profile.");
|
|
946
|
+
}
|
|
947
|
+
const model = models?.getByRef({
|
|
948
|
+
provider: profile.model.providerId,
|
|
949
|
+
modelId: profile.model.modelId
|
|
950
|
+
})?.model;
|
|
951
|
+
if (!model || !sameEmbeddingModel(model, profile.model)) {
|
|
952
|
+
throw new ObjectQueryExecutionError2("embedding_model_unavailable", "Vector search requires the embedding model registered for its profile.");
|
|
953
|
+
}
|
|
954
|
+
return model;
|
|
955
|
+
}
|
|
956
|
+
async function embedSearchText(text, model, signal) {
|
|
957
|
+
const dimensions = model.definition.dimensions;
|
|
958
|
+
const timeout = AbortSignal.timeout(QUERY_EMBEDDING_TIMEOUT_MS);
|
|
959
|
+
const requestSignal = signal ? AbortSignal.any([signal, timeout]) : timeout;
|
|
960
|
+
requestSignal.throwIfAborted();
|
|
961
|
+
const result = await model.embed({ texts: [text], purpose: "query", signal: requestSignal });
|
|
962
|
+
requestSignal.throwIfAborted();
|
|
963
|
+
if (!Array.isArray(result?.vectors) || result.vectors.length !== 1) {
|
|
964
|
+
throw new ObjectQueryExecutionError2("invalid_embedding_response", "Embedding model must return exactly one vector for the search text.");
|
|
965
|
+
}
|
|
966
|
+
try {
|
|
967
|
+
return normalizeVector2(result.vectors[0], dimensions);
|
|
968
|
+
} catch {
|
|
969
|
+
throw new ObjectQueryExecutionError2("invalid_embedding_response", "Embedding model returned an invalid vector for the search profile.");
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
// src/objects/query/reranking-query.ts
|
|
974
|
+
function findQueryReranking(query) {
|
|
975
|
+
if (query.kind === "rerank")
|
|
976
|
+
return query;
|
|
977
|
+
if (query.kind === "limit" || query.kind === "project")
|
|
978
|
+
return findQueryReranking(query.input);
|
|
979
|
+
return;
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
// src/objects/query/planner.ts
|
|
983
|
+
var DEFAULT_MAX_FALLBACK_ROWS = 1000;
|
|
984
|
+
var fallbackNodeKinds = new Set([
|
|
985
|
+
"start",
|
|
986
|
+
"refs",
|
|
987
|
+
"filter",
|
|
988
|
+
"sort",
|
|
989
|
+
"limit",
|
|
990
|
+
"page",
|
|
991
|
+
"project",
|
|
992
|
+
"expand"
|
|
993
|
+
]);
|
|
994
|
+
function planObjectQuery2(query, options) {
|
|
995
|
+
const operation = options.operation ?? "queryObjects";
|
|
996
|
+
const reranking = findQueryReranking(query);
|
|
997
|
+
if (reranking) {
|
|
998
|
+
const candidatePlan = planObjectQuery2(reranking.input, options);
|
|
999
|
+
return {
|
|
1000
|
+
...candidatePlan,
|
|
1001
|
+
query,
|
|
1002
|
+
mode: candidatePlan.mode === "rejected" ? "rejected" : "pipeline"
|
|
1003
|
+
};
|
|
1004
|
+
}
|
|
1005
|
+
const providerIssues = collectProviderIssues(query, options.capabilities, {
|
|
1006
|
+
operation,
|
|
1007
|
+
hasImplementation: hasProviderImplementation(operation, options)
|
|
1008
|
+
});
|
|
1009
|
+
if (providerIssues.length === 0) {
|
|
1010
|
+
return {
|
|
1011
|
+
mode: "pushdown",
|
|
1012
|
+
query,
|
|
1013
|
+
providerIssues,
|
|
1014
|
+
fallbackIssues: [],
|
|
1015
|
+
issues: []
|
|
1016
|
+
};
|
|
1017
|
+
}
|
|
1018
|
+
const fallbackIssues = collectFallbackIssues(query, options);
|
|
1019
|
+
const issues = [...providerIssues, ...fallbackIssues];
|
|
1020
|
+
if (fallbackIssues.length === 0) {
|
|
1021
|
+
return {
|
|
1022
|
+
mode: "fallback",
|
|
1023
|
+
query,
|
|
1024
|
+
providerIssues,
|
|
1025
|
+
fallbackIssues,
|
|
1026
|
+
issues: [],
|
|
1027
|
+
fallback: {
|
|
1028
|
+
maxRows: options.maxFallbackRows ?? DEFAULT_MAX_FALLBACK_ROWS,
|
|
1029
|
+
requiresExplicitBound: options.requiresExplicitFallbackBound !== false
|
|
1030
|
+
}
|
|
1031
|
+
};
|
|
1032
|
+
}
|
|
1033
|
+
return {
|
|
1034
|
+
mode: "rejected",
|
|
1035
|
+
query,
|
|
1036
|
+
providerIssues,
|
|
1037
|
+
fallbackIssues,
|
|
1038
|
+
issues
|
|
1039
|
+
};
|
|
1040
|
+
}
|
|
1041
|
+
function collectProviderIssues(query, capabilities, options) {
|
|
1042
|
+
const issues = [];
|
|
1043
|
+
collectOperationProviderIssues(capabilities, options, issues);
|
|
1044
|
+
collectNodeProviderIssues(query, "$", capabilities, issues);
|
|
1045
|
+
return issues;
|
|
1046
|
+
}
|
|
1047
|
+
function collectOperationProviderIssues(capabilities, options, issues) {
|
|
1048
|
+
const enabled = options.operation === "queryObjects" ? capabilities.queryObjects === true : options.operation === "countObjects" ? capabilities.countObjects === true : options.operation === "existsObjects" ? capabilities.existsObjects === true : capabilities.facetObjects === true;
|
|
1049
|
+
if (!enabled) {
|
|
1050
|
+
const code = `${operationIssuePrefix(options.operation)}_not_enabled`;
|
|
1051
|
+
addIssue2(issues, "$", code, `Object storage capabilities do not enable ${options.operation} pushdown`);
|
|
1052
|
+
}
|
|
1053
|
+
if (options.hasImplementation)
|
|
1054
|
+
return;
|
|
1055
|
+
const code = `${operationIssuePrefix(options.operation)}_not_implemented`;
|
|
1056
|
+
addIssue2(issues, "$", code, `Object storage does not implement ${options.operation}`);
|
|
1057
|
+
}
|
|
1058
|
+
function hasProviderImplementation(operation, options) {
|
|
1059
|
+
switch (operation) {
|
|
1060
|
+
case "queryObjects":
|
|
1061
|
+
return options.hasQueryObjects === true;
|
|
1062
|
+
case "countObjects":
|
|
1063
|
+
return options.hasCountObjects === true;
|
|
1064
|
+
case "existsObjects":
|
|
1065
|
+
return options.hasExistsObjects === true;
|
|
1066
|
+
case "facetObjects":
|
|
1067
|
+
return options.hasFacetObjects === true;
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
function operationIssuePrefix(operation) {
|
|
1071
|
+
switch (operation) {
|
|
1072
|
+
case "queryObjects":
|
|
1073
|
+
return "query_objects";
|
|
1074
|
+
case "countObjects":
|
|
1075
|
+
return "count_objects";
|
|
1076
|
+
case "existsObjects":
|
|
1077
|
+
return "exists_objects";
|
|
1078
|
+
case "facetObjects":
|
|
1079
|
+
return "facet_objects";
|
|
1080
|
+
}
|
|
1081
|
+
}
|
|
1082
|
+
function collectNodeProviderIssues(query, path, capabilities, issues) {
|
|
1083
|
+
if (capabilities.nodes?.[query.kind] !== true) {
|
|
1084
|
+
addIssue2(issues, path, "query_node_not_supported", `Provider does not support query node '${query.kind}'`);
|
|
1085
|
+
}
|
|
1086
|
+
switch (query.kind) {
|
|
1087
|
+
case "start":
|
|
1088
|
+
if (query.includeSubtypes === true && capabilities.features?.includeSubtypes !== true) {
|
|
1089
|
+
addIssue2(issues, path, "include_subtypes_not_supported", "Provider does not support start.includeSubtypes expansion");
|
|
1090
|
+
}
|
|
1091
|
+
return;
|
|
1092
|
+
case "refs":
|
|
1093
|
+
return;
|
|
1094
|
+
case "filter":
|
|
1095
|
+
collectPredicateProviderIssues(query.predicate, `${path}.predicate`, capabilities, issues);
|
|
1096
|
+
collectNodeProviderIssues(query.input, `${path}.input`, capabilities, issues);
|
|
1097
|
+
return;
|
|
1098
|
+
case "text":
|
|
1099
|
+
case "vector":
|
|
1100
|
+
case "rerank":
|
|
1101
|
+
case "project":
|
|
1102
|
+
collectNodeProviderIssues(query.input, `${path}.input`, capabilities, issues);
|
|
1103
|
+
return;
|
|
1104
|
+
case "limit":
|
|
1105
|
+
collectProviderMaxLimitIssues(query.limit, path, capabilities, issues);
|
|
1106
|
+
collectNodeProviderIssues(query.input, `${path}.input`, capabilities, issues);
|
|
1107
|
+
return;
|
|
1108
|
+
case "page":
|
|
1109
|
+
collectProviderMaxPageSizeIssues(query.pageSize, path, capabilities, issues);
|
|
1110
|
+
collectNodeProviderIssues(query.input, `${path}.input`, capabilities, issues);
|
|
1111
|
+
return;
|
|
1112
|
+
case "traverse":
|
|
1113
|
+
if (capabilities.traversalDirections?.[query.direction] !== true) {
|
|
1114
|
+
addIssue2(issues, path, "traversal_direction_not_supported", `Provider does not support ${query.direction} traversal`);
|
|
1125
1115
|
}
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1116
|
+
collectNodeProviderIssues(query.input, `${path}.input`, capabilities, issues);
|
|
1117
|
+
return;
|
|
1118
|
+
case "set":
|
|
1119
|
+
if (capabilities.setOps?.[query.op] !== true) {
|
|
1120
|
+
addIssue2(issues, path, "set_operation_not_supported", `Provider does not support set operation '${query.op}'`);
|
|
1121
|
+
}
|
|
1122
|
+
query.inputs.forEach((input, index) => {
|
|
1123
|
+
collectNodeProviderIssues(input, `${path}.inputs[${index}]`, capabilities, issues);
|
|
1124
|
+
});
|
|
1125
|
+
return;
|
|
1126
|
+
case "sort":
|
|
1127
|
+
query.fields.forEach((field, index) => {
|
|
1128
|
+
collectSortProviderIssues(field, `${path}.fields[${index}]`, capabilities, issues);
|
|
1129
|
+
});
|
|
1130
|
+
collectNodeProviderIssues(query.input, `${path}.input`, capabilities, issues);
|
|
1131
|
+
return;
|
|
1132
|
+
case "expand":
|
|
1133
|
+
query.expansions.forEach((expansion, index) => {
|
|
1134
|
+
collectExpansionProviderIssues(expansion, `${path}.expansions[${index}]`, capabilities, issues);
|
|
1135
|
+
});
|
|
1136
|
+
collectNodeProviderIssues(query.input, `${path}.input`, capabilities, issues);
|
|
1137
|
+
return;
|
|
1138
|
+
}
|
|
1130
1139
|
}
|
|
1131
|
-
function
|
|
1132
|
-
if (
|
|
1133
|
-
addIssue2(
|
|
1134
|
-
} else if (limit > ctx.maxLimit) {
|
|
1135
|
-
addIssue2(ctx, path, "limit_too_large", `limit must be <= ${ctx.maxLimit}`);
|
|
1140
|
+
function collectExpansionProviderIssues(expansion, path, capabilities, issues) {
|
|
1141
|
+
if (expansion.cardinality === undefined) {
|
|
1142
|
+
addIssue2(issues, path, "expand_cardinality_unresolved", `Provider cannot push down expansion '${expansion.linkId}' without a resolved cardinality`);
|
|
1136
1143
|
}
|
|
1144
|
+
expansion.orderBy?.forEach((field, index) => {
|
|
1145
|
+
collectSortProviderIssues(field, `${path}.orderBy[${index}]`, capabilities, issues);
|
|
1146
|
+
});
|
|
1147
|
+
expansion.expand?.forEach((nested, index) => {
|
|
1148
|
+
collectExpansionProviderIssues(nested, `${path}.expand[${index}]`, capabilities, issues);
|
|
1149
|
+
});
|
|
1137
1150
|
}
|
|
1138
|
-
function
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
addIssue2(ctx, path, "page_size_too_large", `pageSize must be <= ${ctx.maxPageSize}`);
|
|
1151
|
+
function collectPredicateProviderIssues(predicate, path, capabilities, issues) {
|
|
1152
|
+
const scalarOperation = predicateScalarOperation(predicate);
|
|
1153
|
+
if ("scalarKind" in predicate && predicate.scalarKind !== undefined && scalarOperation !== undefined && capabilities.scalarOperations?.[predicate.scalarKind]?.[scalarOperation] !== true) {
|
|
1154
|
+
addIssue2(issues, path, "scalar_operation_not_supported", `Provider does not support ${scalarOperation} for '${predicate.scalarKind}' values`);
|
|
1143
1155
|
}
|
|
1144
|
-
if (
|
|
1145
|
-
addIssue2(
|
|
1156
|
+
if (capabilities.predicateOps?.[predicate.op] !== true) {
|
|
1157
|
+
addIssue2(issues, path, "predicate_operation_not_supported", `Provider does not support predicate operation '${predicate.op}'`);
|
|
1146
1158
|
}
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1159
|
+
switch (predicate.op) {
|
|
1160
|
+
case "and":
|
|
1161
|
+
case "or":
|
|
1162
|
+
predicate.items.forEach((item, index) => {
|
|
1163
|
+
collectPredicateProviderIssues(item, `${path}.items[${index}]`, capabilities, issues);
|
|
1164
|
+
});
|
|
1165
|
+
return;
|
|
1166
|
+
case "not":
|
|
1167
|
+
collectPredicateProviderIssues(predicate.item, `${path}.item`, capabilities, issues);
|
|
1168
|
+
return;
|
|
1169
|
+
default:
|
|
1170
|
+
return;
|
|
1153
1171
|
}
|
|
1154
|
-
const seen = new Set;
|
|
1155
|
-
properties.forEach((propertyId, index) => {
|
|
1156
|
-
admitProperty(ctx, {
|
|
1157
|
-
state: admissionState,
|
|
1158
|
-
propertyId,
|
|
1159
|
-
use: "project",
|
|
1160
|
-
path: `${path}.properties[${index}]`
|
|
1161
|
-
});
|
|
1162
|
-
if (seen.has(propertyId)) {
|
|
1163
|
-
addIssue2(ctx, `${path}.properties[${index}]`, "duplicate_projection_property", `Duplicate projected property '${propertyId}'`);
|
|
1164
|
-
}
|
|
1165
|
-
seen.add(propertyId);
|
|
1166
|
-
getPropertiesForResult(propertyId, shape, `${path}.properties[${index}]`, ctx);
|
|
1167
|
-
});
|
|
1168
1172
|
}
|
|
1169
|
-
function
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1173
|
+
function predicateScalarOperation(predicate) {
|
|
1174
|
+
switch (predicate.op) {
|
|
1175
|
+
case "eq":
|
|
1176
|
+
case "neq":
|
|
1177
|
+
case "in":
|
|
1178
|
+
case "contains":
|
|
1179
|
+
return "equality";
|
|
1180
|
+
case "lt":
|
|
1181
|
+
case "lte":
|
|
1182
|
+
case "gt":
|
|
1183
|
+
case "gte":
|
|
1184
|
+
return "ordering";
|
|
1185
|
+
default:
|
|
1186
|
+
return;
|
|
1175
1187
|
}
|
|
1176
|
-
return objectTypes;
|
|
1177
1188
|
}
|
|
1178
|
-
function
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
const property = getProperty(objectType, propertyId);
|
|
1182
|
-
if (!property) {
|
|
1183
|
-
if (options.reportMissing === false) {
|
|
1184
|
-
continue;
|
|
1185
|
-
}
|
|
1186
|
-
addIssue2(ctx, path, "unknown_property", `Property '${propertyId}' does not exist on object type '${objectType.id}'`);
|
|
1187
|
-
continue;
|
|
1188
|
-
}
|
|
1189
|
-
results.push({ objectType, property });
|
|
1189
|
+
function collectSortProviderIssues(field, path, capabilities, issues) {
|
|
1190
|
+
if (field.kind === "property" && field.scalarKind !== undefined && capabilities.scalarOperations?.[field.scalarKind]?.ordering !== true) {
|
|
1191
|
+
addIssue2(issues, path, "scalar_operation_not_supported", `Provider does not support ordering for '${field.scalarKind}' values`);
|
|
1190
1192
|
}
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
return objectType.properties.find((property) => property.id === propertyId);
|
|
1193
|
+
if (capabilities.sortKinds?.[field.kind] === true)
|
|
1194
|
+
return;
|
|
1195
|
+
addIssue2(issues, path, "sort_kind_not_supported", `Provider does not support sort kind '${field.kind}'`);
|
|
1195
1196
|
}
|
|
1196
|
-
function
|
|
1197
|
-
|
|
1198
|
-
|
|
1197
|
+
function collectProviderMaxLimitIssues(limit, path, capabilities, issues) {
|
|
1198
|
+
const maxLimit = capabilities.limits?.maxLimit;
|
|
1199
|
+
if (maxLimit === undefined)
|
|
1200
|
+
return;
|
|
1201
|
+
if (!Number.isInteger(maxLimit) || maxLimit < 0) {
|
|
1202
|
+
addIssue2(issues, path, "invalid_provider_limit_capability", "Provider limit capability maxLimit must be a non-negative integer");
|
|
1203
|
+
return;
|
|
1204
|
+
}
|
|
1205
|
+
if (limit > maxLimit) {
|
|
1206
|
+
addIssue2(issues, path, "provider_limit_too_large", `Provider supports limit up to ${maxLimit}`);
|
|
1199
1207
|
}
|
|
1200
1208
|
}
|
|
1201
|
-
function
|
|
1202
|
-
|
|
1209
|
+
function collectProviderMaxPageSizeIssues(pageSize, path, capabilities, issues) {
|
|
1210
|
+
const maxPageSize = capabilities.limits?.maxPageSize;
|
|
1211
|
+
if (maxPageSize === undefined)
|
|
1203
1212
|
return;
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
addIssue2(ctx, path, "unresolved_property_schema", error instanceof Error ? error.message : `Could not resolve schema for '${objectTypeId}.${property.id}'`);
|
|
1211
|
-
return null;
|
|
1213
|
+
if (!Number.isInteger(maxPageSize) || maxPageSize <= 0) {
|
|
1214
|
+
addIssue2(issues, path, "invalid_provider_page_size_capability", "Provider limit capability maxPageSize must be a positive integer");
|
|
1215
|
+
return;
|
|
1216
|
+
}
|
|
1217
|
+
if (pageSize > maxPageSize) {
|
|
1218
|
+
addIssue2(issues, path, "provider_page_size_too_large", `Provider supports pageSize up to ${maxPageSize}`);
|
|
1212
1219
|
}
|
|
1213
1220
|
}
|
|
1214
|
-
function
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
return
|
|
1219
|
-
if (seenValueTypeIds.has(schema.valueTypeId)) {
|
|
1220
|
-
throw new Error(`Circular valueTypeRef '${schema.valueTypeId}'`);
|
|
1221
|
+
function collectFallbackIssues(query, options) {
|
|
1222
|
+
const issues = [];
|
|
1223
|
+
if (options.allowFallback === false) {
|
|
1224
|
+
addIssue2(issues, "$", "fallback_disabled", "Object query fallback is disabled");
|
|
1225
|
+
return issues;
|
|
1221
1226
|
}
|
|
1222
|
-
const
|
|
1223
|
-
if (!
|
|
1224
|
-
|
|
1227
|
+
const maxFallbackRows = options.maxFallbackRows ?? DEFAULT_MAX_FALLBACK_ROWS;
|
|
1228
|
+
if (!Number.isInteger(maxFallbackRows) || maxFallbackRows <= 0) {
|
|
1229
|
+
addIssue2(issues, "$", "invalid_fallback_bound", "maxFallbackRows must be a positive integer");
|
|
1225
1230
|
}
|
|
1226
|
-
|
|
1227
|
-
|
|
1231
|
+
if (options.requiresExplicitFallbackBound !== false && !hasExplicitResultBound(query)) {
|
|
1232
|
+
addIssue2(issues, "$", "fallback_requires_bound", "Fallback requires an explicit limit or page node");
|
|
1233
|
+
}
|
|
1234
|
+
collectFallbackNodeIssues(query, "$", issues);
|
|
1235
|
+
return issues;
|
|
1228
1236
|
}
|
|
1229
|
-
function
|
|
1230
|
-
|
|
1237
|
+
function collectFallbackNodeIssues(query, path, issues) {
|
|
1238
|
+
if (!fallbackNodeKinds.has(query.kind)) {
|
|
1239
|
+
addIssue2(issues, path, "fallback_node_not_supported", `Fallback does not support query node '${query.kind}'`);
|
|
1240
|
+
}
|
|
1241
|
+
switch (query.kind) {
|
|
1242
|
+
case "start":
|
|
1243
|
+
case "refs":
|
|
1244
|
+
return;
|
|
1245
|
+
case "filter":
|
|
1246
|
+
case "limit":
|
|
1247
|
+
case "page":
|
|
1248
|
+
case "project":
|
|
1249
|
+
case "expand":
|
|
1250
|
+
collectFallbackNodeIssues(query.input, `${path}.input`, issues);
|
|
1251
|
+
return;
|
|
1252
|
+
case "sort":
|
|
1253
|
+
query.fields.forEach((field, index) => {
|
|
1254
|
+
if (field.kind === "relevance") {
|
|
1255
|
+
addIssue2(issues, `${path}.fields[${index}]`, "fallback_sort_kind_not_supported", "Fallback does not support relevance sorting");
|
|
1256
|
+
}
|
|
1257
|
+
});
|
|
1258
|
+
collectFallbackNodeIssues(query.input, `${path}.input`, issues);
|
|
1259
|
+
return;
|
|
1260
|
+
case "text":
|
|
1261
|
+
case "vector":
|
|
1262
|
+
case "traverse":
|
|
1263
|
+
collectFallbackNodeIssues(query.input, `${path}.input`, issues);
|
|
1264
|
+
return;
|
|
1265
|
+
case "set":
|
|
1266
|
+
query.inputs.forEach((input, index) => {
|
|
1267
|
+
collectFallbackNodeIssues(input, `${path}.inputs[${index}]`, issues);
|
|
1268
|
+
});
|
|
1269
|
+
return;
|
|
1270
|
+
}
|
|
1231
1271
|
}
|
|
1232
|
-
function
|
|
1233
|
-
|
|
1272
|
+
function hasExplicitResultBound(query) {
|
|
1273
|
+
switch (query.kind) {
|
|
1274
|
+
case "limit":
|
|
1275
|
+
case "page":
|
|
1276
|
+
case "refs":
|
|
1277
|
+
return true;
|
|
1278
|
+
case "start":
|
|
1279
|
+
return false;
|
|
1280
|
+
case "set":
|
|
1281
|
+
return query.inputs.some(hasExplicitResultBound);
|
|
1282
|
+
default:
|
|
1283
|
+
return hasExplicitResultBound(query.input);
|
|
1284
|
+
}
|
|
1234
1285
|
}
|
|
1235
|
-
function
|
|
1236
|
-
|
|
1286
|
+
function addIssue2(issues, path, code, message) {
|
|
1287
|
+
issues.push({ path, code, message });
|
|
1237
1288
|
}
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1289
|
+
|
|
1290
|
+
// src/objects/query/primary-id.ts
|
|
1291
|
+
function usePrimaryIdLookups(query, ontology) {
|
|
1292
|
+
if (query.kind === "set")
|
|
1293
|
+
return { ...query, inputs: query.inputs.map((input) => usePrimaryIdLookups(input, ontology)) };
|
|
1294
|
+
if (!("input" in query))
|
|
1295
|
+
return query;
|
|
1296
|
+
const input = usePrimaryIdLookups(query.input, ontology);
|
|
1297
|
+
if (query.kind === "filter" && input.kind === "start" && !input.includeSubtypes) {
|
|
1298
|
+
const propertyId = ontology.getPrimaryPropertyId(input.objectTypeId);
|
|
1299
|
+
const ids = primaryIds(query.predicate, propertyId);
|
|
1300
|
+
if (ids?.length && ids.length <= 1000)
|
|
1301
|
+
return {
|
|
1302
|
+
...query,
|
|
1303
|
+
input: {
|
|
1304
|
+
kind: "refs",
|
|
1305
|
+
refs: [...new Set(ids)].sort().map((primaryId) => ({ objectTypeId: input.objectTypeId, primaryId }))
|
|
1306
|
+
}
|
|
1307
|
+
};
|
|
1308
|
+
}
|
|
1309
|
+
return input === query.input ? query : { ...query, input };
|
|
1242
1310
|
}
|
|
1243
|
-
function
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1311
|
+
function primaryIds(predicate, propertyId) {
|
|
1312
|
+
if (predicate.op === "and") {
|
|
1313
|
+
for (const item of predicate.items) {
|
|
1314
|
+
const ids = primaryIds(item, propertyId);
|
|
1315
|
+
if (ids)
|
|
1316
|
+
return ids;
|
|
1317
|
+
}
|
|
1318
|
+
return;
|
|
1319
|
+
}
|
|
1320
|
+
if (predicate.op === "eq" && predicate.propertyId === propertyId && typeof predicate.value === "string")
|
|
1321
|
+
return [predicate.value];
|
|
1322
|
+
if (predicate.op === "in" && predicate.propertyId === propertyId && predicate.values.every((value) => typeof value === "string"))
|
|
1323
|
+
return predicate.values;
|
|
1324
|
+
return;
|
|
1247
1325
|
}
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1326
|
+
|
|
1327
|
+
// src/objects/query/reranking-executor.ts
|
|
1328
|
+
async function rerankObjectCandidates(input) {
|
|
1329
|
+
const { vector, candidates, model, signal } = input;
|
|
1330
|
+
if (typeof vector.vector !== "string" || !vector.source) {
|
|
1331
|
+
throw new ObjectQueryExecutionError2("invalid_rerank_input", "Reranking requires a validated text vector query.");
|
|
1332
|
+
}
|
|
1333
|
+
signal?.throwIfAborted();
|
|
1334
|
+
if (candidates.length > vector.k) {
|
|
1335
|
+
throw new ObjectQueryExecutionError2("rerank_candidate_limit_exceeded", "Storage exceeded the admitted vector candidate bound.");
|
|
1336
|
+
}
|
|
1337
|
+
const source = vector.source;
|
|
1338
|
+
const documents = candidates.map((row) => vectorSources(source, row.properties).text);
|
|
1339
|
+
const encoder = new TextEncoder;
|
|
1340
|
+
const bytes = encoder.encode(vector.vector).byteLength + documents.reduce((sum, text) => sum + encoder.encode(text).byteLength, 0);
|
|
1341
|
+
if (bytes > MAX_RERANK_INPUT_BYTES) {
|
|
1342
|
+
throw new ObjectQueryExecutionError2("rerank_input_limit_exceeded", "Reranking input exceeds 1 MiB. Use fewer candidates or shorter profile sources.");
|
|
1343
|
+
}
|
|
1344
|
+
const results = documents.length === 0 ? [] : (await model.rerank({ query: vector.vector, documents, signal })).results;
|
|
1345
|
+
signal?.throwIfAborted();
|
|
1346
|
+
const ranking = validateRerankingResults(results, candidates.length);
|
|
1347
|
+
const rows = ranking.map(({ index, score }) => ({ ...candidates[index], score }));
|
|
1348
|
+
const shaped = shapeRerankedRows(input.query, rows);
|
|
1349
|
+
return {
|
|
1350
|
+
objects: shaped.rows,
|
|
1351
|
+
hasMore: shaped.hasMore,
|
|
1352
|
+
...input.includeTotal === false ? {} : { total: shaped.total }
|
|
1353
|
+
};
|
|
1251
1354
|
}
|
|
1252
|
-
function
|
|
1253
|
-
|
|
1355
|
+
function shapeRerankedRows(query, rows) {
|
|
1356
|
+
if (query.kind === "rerank")
|
|
1357
|
+
return { rows, total: rows.length, hasMore: false };
|
|
1358
|
+
if (query.kind === "limit") {
|
|
1359
|
+
const input = shapeRerankedRows(query.input, rows);
|
|
1360
|
+
return {
|
|
1361
|
+
rows: input.rows.slice(0, query.limit),
|
|
1362
|
+
total: input.total,
|
|
1363
|
+
hasMore: input.hasMore || query.limit < input.rows.length
|
|
1364
|
+
};
|
|
1365
|
+
}
|
|
1366
|
+
if (query.kind === "project") {
|
|
1367
|
+
const input = shapeRerankedRows(query.input, rows);
|
|
1368
|
+
if (!query.properties)
|
|
1369
|
+
return input;
|
|
1370
|
+
const properties = new Set(query.properties);
|
|
1371
|
+
return {
|
|
1372
|
+
...input,
|
|
1373
|
+
rows: input.rows.map((row) => ({
|
|
1374
|
+
...row,
|
|
1375
|
+
properties: Object.fromEntries(Object.entries(row.properties).filter(([key]) => properties.has(key)))
|
|
1376
|
+
}))
|
|
1377
|
+
};
|
|
1378
|
+
}
|
|
1379
|
+
throw new ObjectQueryExecutionError2("invalid_rerank_composition", "Only limit and project may follow reranking.");
|
|
1254
1380
|
}
|
|
1255
1381
|
|
|
1256
1382
|
// src/objects/query/executor.ts
|
|
@@ -1295,6 +1421,26 @@ async function executeObjectQuery2(input, options) {
|
|
|
1295
1421
|
if (plan.mode === "rejected") {
|
|
1296
1422
|
throw new ObjectQueryPlanningError2(plan.issues);
|
|
1297
1423
|
}
|
|
1424
|
+
if (plan.mode === "pipeline") {
|
|
1425
|
+
const reranking = findQueryReranking(validated.query);
|
|
1426
|
+
if (!reranking || reranking.input.kind !== "vector") {
|
|
1427
|
+
throw new ObjectQueryExecutionError2("invalid_rerank_input", "Reranking requires vector candidates.");
|
|
1428
|
+
}
|
|
1429
|
+
const model = options.rerankingModels?.getByRef(reranking.model)?.model;
|
|
1430
|
+
if (!model) {
|
|
1431
|
+
throw new ObjectQueryExecutionError2("reranking_model_unavailable", `Reranking model '${reranking.model.provider}/${reranking.model.modelId}' is not configured in models.reranking.`);
|
|
1432
|
+
}
|
|
1433
|
+
const candidates = await executeObjectQuery2({ ...input, query: reranking.input, includeTotal: false }, options);
|
|
1434
|
+
const result = await rerankObjectCandidates({
|
|
1435
|
+
query: validated.query,
|
|
1436
|
+
vector: reranking.input,
|
|
1437
|
+
candidates: candidates.objects,
|
|
1438
|
+
model,
|
|
1439
|
+
signal: input.signal,
|
|
1440
|
+
includeTotal: input.includeTotal
|
|
1441
|
+
});
|
|
1442
|
+
return { ...result, plan };
|
|
1443
|
+
}
|
|
1298
1444
|
if (plan.mode === "pushdown") {
|
|
1299
1445
|
if (!options.storage.queryObjects) {
|
|
1300
1446
|
throw new ObjectQueryPlanningError2(plan.providerIssues);
|
|
@@ -1474,6 +1620,7 @@ async function facetObjects2(input, options) {
|
|
|
1474
1620
|
const maxRows = options.maxFallbackRows ?? DEFAULT_MAX_FALLBACK_ROWS2;
|
|
1475
1621
|
const evaluation = await evaluateFallbackQuery(input.projectId, aggregateQuery, options, maxRows);
|
|
1476
1622
|
return {
|
|
1623
|
+
total: evaluation.entries.length,
|
|
1477
1624
|
facets: buildFacetResults(evaluation.entries.map((entry) => entry.row), facets),
|
|
1478
1625
|
plan
|
|
1479
1626
|
};
|
|
@@ -1489,7 +1636,7 @@ function assertQueryViewable(projectId, validated, authorization) {
|
|
|
1489
1636
|
function expandPushdownQuery(query, ontology, capabilities, planning, maxExpansionFanout) {
|
|
1490
1637
|
const ctx = { ontology, maxExpansionFanout };
|
|
1491
1638
|
const annotated = resolveExpansions(query, ctx);
|
|
1492
|
-
const expanded = expandIncludeSubtypes(annotated, ontology);
|
|
1639
|
+
const expanded = usePrimaryIdLookups(expandIncludeSubtypes(annotated, ontology), ontology);
|
|
1493
1640
|
if (expanded === annotated)
|
|
1494
1641
|
return annotated;
|
|
1495
1642
|
const plan = planObjectQuery2(expanded, { ...planning, capabilities, allowFallback: false });
|
|
@@ -1516,6 +1663,7 @@ function resolveExpansions(query, ctx) {
|
|
|
1516
1663
|
case "filter":
|
|
1517
1664
|
case "text":
|
|
1518
1665
|
case "vector":
|
|
1666
|
+
case "rerank":
|
|
1519
1667
|
case "traverse":
|
|
1520
1668
|
case "sort":
|
|
1521
1669
|
case "limit":
|
|
@@ -1595,6 +1743,7 @@ function expandIncludeSubtypes(query, ontology) {
|
|
|
1595
1743
|
case "filter":
|
|
1596
1744
|
case "text":
|
|
1597
1745
|
case "vector":
|
|
1746
|
+
case "rerank":
|
|
1598
1747
|
case "traverse":
|
|
1599
1748
|
case "sort":
|
|
1600
1749
|
case "limit":
|
|
@@ -1681,6 +1830,7 @@ async function evaluateFallbackQuery(projectId, query, options, maxRows) {
|
|
|
1681
1830
|
}
|
|
1682
1831
|
case "text":
|
|
1683
1832
|
case "vector":
|
|
1833
|
+
case "rerank":
|
|
1684
1834
|
case "traverse":
|
|
1685
1835
|
case "set":
|
|
1686
1836
|
throw new ObjectQueryExecutionError2("fallback_node_not_supported", `Fallback execution does not support query node '${query.kind}'`);
|
|
@@ -1971,6 +2121,7 @@ function stripOuterRowShape(query) {
|
|
|
1971
2121
|
case "page":
|
|
1972
2122
|
case "project":
|
|
1973
2123
|
case "sort":
|
|
2124
|
+
case "rerank":
|
|
1974
2125
|
case "expand":
|
|
1975
2126
|
return stripOuterRowShape(query.input);
|
|
1976
2127
|
default:
|
|
@@ -2178,6 +2329,14 @@ function buildExplainNode(query, path) {
|
|
|
2178
2329
|
},
|
|
2179
2330
|
children: [buildExplainNode(query.input, `${path}.input`)]
|
|
2180
2331
|
};
|
|
2332
|
+
case "rerank":
|
|
2333
|
+
return {
|
|
2334
|
+
path,
|
|
2335
|
+
kind: query.kind,
|
|
2336
|
+
summary: `rerank ${query.model.provider}/${query.model.modelId}`,
|
|
2337
|
+
details: { model: query.model },
|
|
2338
|
+
children: [buildExplainNode(query.input, `${path}.input`)]
|
|
2339
|
+
};
|
|
2181
2340
|
case "set":
|
|
2182
2341
|
return {
|
|
2183
2342
|
path,
|
|
@@ -2460,6 +2619,6 @@ async function hydrateLinkQueryObjects(projectId, selected, links, storage) {
|
|
|
2460
2619
|
return row ? [row] : [];
|
|
2461
2620
|
});
|
|
2462
2621
|
}
|
|
2463
|
-
export {
|
|
2622
|
+
export { validateObjectQuery2, validateObjectQueryWithAdmission, collectObjectQueryValidationIssues2, resolveObjectQueryResultShape2, planObjectQuery2, executeObjectQuery2, countObjects2, existsObjects2, facetObjects2, validateObjectFacetRequests, explainObjectQuery2, preflightObjectQueryLinks, executeObjectQueryLinks2 };
|
|
2464
2623
|
|
|
2465
|
-
//# debugId=
|
|
2624
|
+
//# debugId=A31A747EB003D67964756E2164756E21
|