@farukada/aws-langgraph-dynamodb-ts 1.0.0-rc.1 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1820 -290
- package/dist/cjs/backfill/backfill.d.ts +171 -0
- package/dist/cjs/backfill/backfill.js +177 -0
- package/dist/cjs/checkpointer/actions/delete-thread.d.ts +50 -0
- package/dist/cjs/checkpointer/actions/delete-thread.js +26 -0
- package/dist/cjs/checkpointer/actions/get-tuple.d.ts +36 -0
- package/dist/cjs/checkpointer/actions/get-tuple.js +22 -0
- package/dist/cjs/checkpointer/actions/list.d.ts +55 -0
- package/dist/cjs/checkpointer/actions/list.js +70 -0
- package/dist/cjs/checkpointer/actions/put-writes.d.ts +49 -0
- package/dist/cjs/checkpointer/actions/put-writes.js +21 -0
- package/dist/cjs/checkpointer/actions/put.d.ts +95 -0
- package/dist/cjs/checkpointer/actions/put.js +79 -0
- package/dist/cjs/checkpointer/internal/delta-history.d.ts +124 -0
- package/dist/cjs/checkpointer/internal/delta-history.js +131 -0
- package/dist/cjs/checkpointer/internal/listing.d.ts +149 -0
- package/dist/cjs/checkpointer/internal/listing.js +104 -0
- package/dist/cjs/checkpointer/internal/parse.d.ts +298 -0
- package/dist/cjs/checkpointer/internal/parse.js +184 -0
- package/dist/cjs/checkpointer/internal/pending-writes.d.ts +314 -0
- package/dist/cjs/checkpointer/internal/pending-writes.js +241 -0
- package/dist/cjs/checkpointer/internal/read.d.ts +135 -0
- package/dist/cjs/checkpointer/internal/read.js +132 -0
- package/dist/cjs/checkpointer/internal/rows.d.ts +644 -0
- package/dist/cjs/checkpointer/internal/rows.js +356 -0
- package/dist/cjs/checkpointer/internal/setup.d.ts +47 -0
- package/dist/cjs/checkpointer/internal/setup.js +25 -0
- package/dist/cjs/checkpointer/saver.d.ts +306 -0
- package/dist/cjs/checkpointer/saver.js +56 -0
- package/dist/cjs/checkpointer/types.d.ts +51 -0
- package/dist/cjs/factory/factory.d.ts +154 -0
- package/dist/cjs/factory/factory.js +137 -0
- package/dist/{factory → cjs/factory}/types.d.ts +33 -14
- package/dist/cjs/history/actions/add-messages.d.ts +51 -0
- package/dist/cjs/history/actions/add-messages.js +17 -0
- package/dist/cjs/history/actions/clear.d.ts +52 -0
- package/dist/cjs/history/actions/clear.js +29 -0
- package/dist/cjs/history/actions/get-messages.d.ts +60 -0
- package/dist/cjs/history/actions/get-messages.js +58 -0
- package/dist/cjs/history/actions/list-sessions.d.ts +55 -0
- package/dist/cjs/history/actions/list-sessions.js +67 -0
- package/dist/cjs/history/actions/reconcile-count.d.ts +49 -0
- package/dist/cjs/history/actions/reconcile-count.js +8 -0
- package/dist/cjs/history/chat-message-history.d.ts +267 -0
- package/dist/cjs/history/chat-message-history.js +61 -0
- package/dist/cjs/history/internal/append.d.ts +244 -0
- package/dist/cjs/history/internal/append.js +267 -0
- package/dist/cjs/history/internal/message-read.d.ts +84 -0
- package/dist/cjs/history/internal/message-read.js +93 -0
- package/dist/cjs/history/internal/parse.d.ts +153 -0
- package/dist/cjs/history/internal/parse.js +113 -0
- package/dist/cjs/history/internal/rows.d.ts +196 -0
- package/dist/cjs/history/internal/rows.js +96 -0
- package/dist/cjs/history/internal/session.d.ts +350 -0
- package/dist/cjs/history/internal/session.js +296 -0
- package/dist/cjs/history/internal/setup.d.ts +64 -0
- package/dist/cjs/history/internal/setup.js +60 -0
- package/dist/cjs/history/session-adapter.d.ts +112 -0
- package/dist/cjs/history/session-adapter.js +38 -0
- package/dist/cjs/history/types.d.ts +102 -0
- package/dist/cjs/index.d.ts +53 -0
- package/dist/cjs/index.js +25 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/shared/adapter.d.ts +146 -0
- package/dist/cjs/shared/adapter.js +70 -0
- package/dist/cjs/shared/clock.d.ts +52 -0
- package/dist/cjs/shared/clock.js +14 -0
- package/dist/cjs/shared/codec/codec.d.ts +336 -0
- package/dist/cjs/shared/codec/codec.js +162 -0
- package/dist/cjs/shared/codec/compression.d.ts +66 -0
- package/dist/cjs/shared/codec/compression.js +45 -0
- package/dist/cjs/shared/codec/json-serde.d.ts +80 -0
- package/dist/cjs/shared/codec/json-serde.js +58 -0
- package/dist/{shared → cjs/shared}/codec/s3/client-types.d.ts +22 -2
- package/dist/{shared → cjs/shared}/codec/s3/client-types.js +0 -1
- package/dist/cjs/shared/codec/s3/client.d.ts +63 -0
- package/dist/cjs/shared/codec/s3/client.js +78 -0
- package/dist/cjs/shared/codec/s3/config.d.ts +260 -0
- package/dist/cjs/shared/codec/s3/config.js +92 -0
- package/dist/cjs/shared/codec/s3/lifecycle.d.ts +220 -0
- package/dist/cjs/shared/codec/s3/lifecycle.js +223 -0
- package/dist/cjs/shared/codec/s3/offloader.d.ts +428 -0
- package/dist/cjs/shared/codec/s3/offloader.js +289 -0
- package/dist/cjs/shared/concurrency.d.ts +43 -0
- package/dist/{shared → cjs/shared}/concurrency.js +10 -9
- package/dist/cjs/shared/dynamodb/abort.d.ts +47 -0
- package/dist/cjs/shared/dynamodb/abort.js +16 -0
- package/dist/cjs/shared/dynamodb/batch-write.d.ts +86 -0
- package/dist/cjs/shared/dynamodb/batch-write.js +79 -0
- package/dist/cjs/shared/dynamodb/cancellation.d.ts +124 -0
- package/dist/cjs/shared/dynamodb/cancellation.js +37 -0
- package/dist/cjs/shared/dynamodb/client.d.ts +177 -0
- package/dist/{shared → cjs/shared}/dynamodb/client.js +12 -14
- package/dist/cjs/shared/dynamodb/idempotent-write.d.ts +596 -0
- package/dist/cjs/shared/dynamodb/idempotent-write.js +173 -0
- package/dist/cjs/shared/dynamodb/paginate.d.ts +111 -0
- package/dist/cjs/shared/dynamodb/paginate.js +90 -0
- package/dist/cjs/shared/dynamodb/partition-delete.d.ts +204 -0
- package/dist/cjs/shared/dynamodb/partition-delete.js +177 -0
- package/dist/cjs/shared/dynamodb/recency-index.d.ts +243 -0
- package/dist/cjs/shared/dynamodb/recency-index.js +146 -0
- package/dist/cjs/shared/dynamodb/retry.d.ts +317 -0
- package/dist/cjs/shared/dynamodb/retry.js +193 -0
- package/dist/cjs/shared/dynamodb/row-size.d.ts +33 -0
- package/dist/cjs/shared/dynamodb/row-size.js +30 -0
- package/dist/cjs/shared/dynamodb/table-schema.d.ts +199 -0
- package/dist/cjs/shared/dynamodb/table-schema.js +52 -0
- package/dist/cjs/shared/errors/base-error.d.ts +231 -0
- package/dist/cjs/shared/errors/base-error.js +73 -0
- package/dist/cjs/shared/errors/boundary.d.ts +86 -0
- package/dist/cjs/shared/errors/boundary.js +61 -0
- package/dist/cjs/shared/errors/classify.d.ts +206 -0
- package/dist/cjs/shared/errors/classify.js +232 -0
- package/dist/cjs/shared/errors/error-code.d.ts +95 -0
- package/dist/{shared → cjs/shared}/errors/error-code.js +12 -2
- package/dist/cjs/shared/errors/errors.d.ts +233 -0
- package/dist/cjs/shared/errors/errors.js +123 -0
- package/dist/cjs/shared/logging/logger.d.ts +80 -0
- package/dist/cjs/shared/logging/logger.js +30 -0
- package/dist/cjs/shared/logging/redaction.d.ts +123 -0
- package/dist/cjs/shared/logging/redaction.js +145 -0
- package/dist/cjs/shared/logging/secret-patterns.d.ts +227 -0
- package/dist/cjs/shared/logging/secret-patterns.js +93 -0
- package/dist/cjs/shared/logging/truncate.d.ts +197 -0
- package/dist/cjs/shared/logging/truncate.js +31 -0
- package/dist/cjs/shared/options.d.ts +100 -0
- package/dist/cjs/shared/ulid.d.ts +80 -0
- package/dist/{shared → cjs/shared}/ulid.js +7 -21
- package/dist/cjs/shared/validation/collaborators.d.ts +160 -0
- package/dist/cjs/shared/validation/collaborators.js +79 -0
- package/dist/cjs/shared/validation/option-shape.d.ts +91 -0
- package/dist/cjs/shared/validation/option-shape.js +31 -0
- package/dist/cjs/shared/validation/options.d.ts +145 -0
- package/dist/cjs/shared/validation/options.js +166 -0
- package/dist/cjs/shared/validation/primitives.d.ts +292 -0
- package/dist/cjs/shared/validation/primitives.js +114 -0
- package/dist/cjs/shared/validation/ttl.d.ts +94 -0
- package/dist/cjs/shared/validation/ttl.js +52 -0
- package/dist/cjs/store/actions/list-namespaces.d.ts +79 -0
- package/dist/cjs/store/actions/list-namespaces.js +92 -0
- package/dist/cjs/store/actions/put.d.ts +43 -0
- package/dist/cjs/store/actions/put.js +49 -0
- package/dist/cjs/store/actions/reconcile-vector-index.d.ts +38 -0
- package/dist/cjs/store/actions/reconcile-vector-index.js +13 -0
- package/dist/cjs/store/actions/search.d.ts +38 -0
- package/dist/cjs/store/actions/search.js +26 -0
- package/dist/cjs/store/internal/batch-plan.d.ts +56 -0
- package/dist/cjs/store/internal/batch-plan.js +32 -0
- package/dist/cjs/store/internal/filter.d.ts +43 -0
- package/dist/cjs/store/internal/filter.js +64 -0
- package/dist/cjs/store/internal/get-item.d.ts +77 -0
- package/dist/cjs/store/internal/get-item.js +58 -0
- package/dist/cjs/store/internal/item-write.d.ts +270 -0
- package/dist/cjs/store/internal/item-write.js +181 -0
- package/dist/cjs/store/internal/parse.d.ts +230 -0
- package/dist/cjs/store/internal/parse.js +180 -0
- package/dist/cjs/store/internal/rows.d.ts +359 -0
- package/dist/cjs/store/internal/rows.js +166 -0
- package/dist/cjs/store/internal/semantic-search.d.ts +168 -0
- package/dist/{store/internal/text-path.js → cjs/store/internal/semantic-search.js} +92 -28
- package/dist/cjs/store/internal/setup.d.ts +96 -0
- package/dist/cjs/store/internal/setup.js +103 -0
- package/dist/cjs/store/internal/table-search.d.ts +100 -0
- package/dist/cjs/store/internal/table-search.js +123 -0
- package/dist/cjs/store/internal/vector-index.d.ts +258 -0
- package/dist/cjs/store/internal/vector-index.js +269 -0
- package/dist/cjs/store/store.d.ts +329 -0
- package/dist/cjs/store/store.js +97 -0
- package/dist/cjs/store/types.d.ts +111 -0
- package/dist/cjs/store/vector-backend.d.ts +104 -0
- package/dist/cjs/store/vector-backend.js +4 -0
- package/dist/esm/backfill/backfill.d.ts +171 -0
- package/dist/esm/backfill/backfill.js +170 -0
- package/dist/esm/checkpointer/actions/delete-thread.d.ts +50 -0
- package/dist/esm/checkpointer/actions/delete-thread.js +23 -0
- package/dist/esm/checkpointer/actions/get-tuple.d.ts +36 -0
- package/dist/esm/checkpointer/actions/get-tuple.js +19 -0
- package/dist/esm/checkpointer/actions/list.d.ts +55 -0
- package/dist/esm/checkpointer/actions/list.js +67 -0
- package/dist/esm/checkpointer/actions/put-writes.d.ts +49 -0
- package/dist/esm/checkpointer/actions/put-writes.js +18 -0
- package/dist/esm/checkpointer/actions/put.d.ts +95 -0
- package/dist/esm/checkpointer/actions/put.js +75 -0
- package/dist/esm/checkpointer/internal/delta-history.d.ts +124 -0
- package/dist/esm/checkpointer/internal/delta-history.js +126 -0
- package/dist/esm/checkpointer/internal/listing.d.ts +149 -0
- package/dist/esm/checkpointer/internal/listing.js +95 -0
- package/dist/esm/checkpointer/internal/parse.d.ts +298 -0
- package/dist/esm/checkpointer/internal/parse.js +169 -0
- package/dist/esm/checkpointer/internal/pending-writes.d.ts +314 -0
- package/dist/esm/checkpointer/internal/pending-writes.js +229 -0
- package/dist/esm/checkpointer/internal/read.d.ts +135 -0
- package/dist/esm/checkpointer/internal/read.js +125 -0
- package/dist/esm/checkpointer/internal/rows.d.ts +644 -0
- package/dist/esm/checkpointer/internal/rows.js +323 -0
- package/dist/esm/checkpointer/internal/setup.d.ts +47 -0
- package/dist/esm/checkpointer/internal/setup.js +21 -0
- package/dist/esm/checkpointer/saver.d.ts +306 -0
- package/dist/esm/checkpointer/saver.js +52 -0
- package/dist/esm/checkpointer/types.d.ts +51 -0
- package/dist/esm/checkpointer/types.js +1 -0
- package/dist/esm/factory/factory.d.ts +154 -0
- package/dist/esm/factory/factory.js +133 -0
- package/dist/esm/factory/types.d.ts +76 -0
- package/dist/esm/factory/types.js +1 -0
- package/dist/esm/history/actions/add-messages.d.ts +51 -0
- package/dist/esm/history/actions/add-messages.js +14 -0
- package/dist/esm/history/actions/clear.d.ts +52 -0
- package/dist/esm/history/actions/clear.js +26 -0
- package/dist/esm/history/actions/get-messages.d.ts +60 -0
- package/dist/esm/history/actions/get-messages.js +55 -0
- package/dist/esm/history/actions/list-sessions.d.ts +55 -0
- package/dist/esm/history/actions/list-sessions.js +64 -0
- package/dist/esm/history/actions/reconcile-count.d.ts +49 -0
- package/dist/esm/history/actions/reconcile-count.js +5 -0
- package/dist/esm/history/chat-message-history.d.ts +267 -0
- package/dist/esm/history/chat-message-history.js +57 -0
- package/dist/esm/history/internal/append.d.ts +244 -0
- package/dist/esm/history/internal/append.js +259 -0
- package/dist/esm/history/internal/message-read.d.ts +84 -0
- package/dist/esm/history/internal/message-read.js +89 -0
- package/dist/esm/history/internal/parse.d.ts +153 -0
- package/dist/esm/history/internal/parse.js +105 -0
- package/dist/esm/history/internal/rows.d.ts +196 -0
- package/dist/esm/history/internal/rows.js +83 -0
- package/dist/esm/history/internal/session.d.ts +350 -0
- package/dist/esm/history/internal/session.js +285 -0
- package/dist/esm/history/internal/setup.d.ts +64 -0
- package/dist/esm/history/internal/setup.js +56 -0
- package/dist/esm/history/session-adapter.d.ts +112 -0
- package/dist/esm/history/session-adapter.js +34 -0
- package/dist/esm/history/types.d.ts +102 -0
- package/dist/esm/history/types.js +1 -0
- package/dist/esm/index.d.ts +53 -0
- package/dist/esm/index.js +10 -0
- package/dist/esm/shared/adapter.d.ts +146 -0
- package/dist/esm/shared/adapter.js +65 -0
- package/dist/esm/shared/clock.d.ts +52 -0
- package/dist/esm/shared/clock.js +9 -0
- package/dist/esm/shared/codec/codec.d.ts +336 -0
- package/dist/esm/shared/codec/codec.js +150 -0
- package/dist/esm/shared/codec/compression.d.ts +66 -0
- package/dist/esm/shared/codec/compression.js +40 -0
- package/dist/esm/shared/codec/json-serde.d.ts +80 -0
- package/dist/esm/shared/codec/json-serde.js +54 -0
- package/dist/esm/shared/codec/s3/client-types.d.ts +54 -0
- package/dist/esm/shared/codec/s3/client-types.js +3 -0
- package/dist/esm/shared/codec/s3/client.d.ts +63 -0
- package/dist/esm/shared/codec/s3/client.js +40 -0
- package/dist/esm/shared/codec/s3/config.d.ts +260 -0
- package/dist/esm/shared/codec/s3/config.js +79 -0
- package/dist/esm/shared/codec/s3/lifecycle.d.ts +220 -0
- package/dist/esm/shared/codec/s3/lifecycle.js +214 -0
- package/dist/esm/shared/codec/s3/offloader.d.ts +428 -0
- package/dist/esm/shared/codec/s3/offloader.js +278 -0
- package/dist/esm/shared/concurrency.d.ts +43 -0
- package/dist/esm/shared/concurrency.js +27 -0
- package/dist/esm/shared/dynamodb/abort.d.ts +47 -0
- package/dist/esm/shared/dynamodb/abort.js +12 -0
- package/dist/esm/shared/dynamodb/batch-write.d.ts +86 -0
- package/dist/esm/shared/dynamodb/batch-write.js +74 -0
- package/dist/esm/shared/dynamodb/cancellation.d.ts +124 -0
- package/dist/esm/shared/dynamodb/cancellation.js +30 -0
- package/dist/esm/shared/dynamodb/client.d.ts +177 -0
- package/dist/esm/shared/dynamodb/client.js +35 -0
- package/dist/esm/shared/dynamodb/idempotent-write.d.ts +596 -0
- package/dist/esm/shared/dynamodb/idempotent-write.js +153 -0
- package/dist/esm/shared/dynamodb/paginate.d.ts +111 -0
- package/dist/esm/shared/dynamodb/paginate.js +84 -0
- package/dist/esm/shared/dynamodb/partition-delete.d.ts +204 -0
- package/dist/esm/shared/dynamodb/partition-delete.js +171 -0
- package/dist/esm/shared/dynamodb/recency-index.d.ts +243 -0
- package/dist/esm/shared/dynamodb/recency-index.js +136 -0
- package/dist/esm/shared/dynamodb/retry.d.ts +317 -0
- package/dist/esm/shared/dynamodb/retry.js +180 -0
- package/dist/esm/shared/dynamodb/row-size.d.ts +33 -0
- package/dist/esm/shared/dynamodb/row-size.js +26 -0
- package/dist/esm/shared/dynamodb/table-schema.d.ts +199 -0
- package/dist/esm/shared/dynamodb/table-schema.js +43 -0
- package/dist/esm/shared/errors/base-error.d.ts +231 -0
- package/dist/esm/shared/errors/base-error.js +64 -0
- package/dist/esm/shared/errors/boundary.d.ts +86 -0
- package/dist/esm/shared/errors/boundary.js +54 -0
- package/dist/esm/shared/errors/classify.d.ts +206 -0
- package/dist/esm/shared/errors/classify.js +220 -0
- package/dist/esm/shared/errors/error-code.d.ts +95 -0
- package/dist/esm/shared/errors/error-code.js +24 -0
- package/dist/esm/shared/errors/errors.d.ts +233 -0
- package/dist/esm/shared/errors/errors.js +110 -0
- package/dist/esm/shared/logging/logger.d.ts +80 -0
- package/dist/esm/shared/logging/logger.js +25 -0
- package/dist/esm/shared/logging/redaction.d.ts +123 -0
- package/dist/esm/shared/logging/redaction.js +140 -0
- package/dist/esm/shared/logging/secret-patterns.d.ts +227 -0
- package/dist/esm/shared/logging/secret-patterns.js +83 -0
- package/dist/esm/shared/logging/truncate.d.ts +197 -0
- package/dist/esm/shared/logging/truncate.js +25 -0
- package/dist/esm/shared/options.d.ts +100 -0
- package/dist/esm/shared/options.js +1 -0
- package/dist/esm/shared/ulid.d.ts +80 -0
- package/dist/esm/shared/ulid.js +77 -0
- package/dist/esm/shared/validation/collaborators.d.ts +160 -0
- package/dist/esm/shared/validation/collaborators.js +70 -0
- package/dist/esm/shared/validation/option-shape.d.ts +91 -0
- package/dist/esm/shared/validation/option-shape.js +24 -0
- package/dist/esm/shared/validation/options.d.ts +145 -0
- package/dist/esm/shared/validation/options.js +156 -0
- package/dist/esm/shared/validation/primitives.d.ts +292 -0
- package/dist/esm/shared/validation/primitives.js +100 -0
- package/dist/esm/shared/validation/ttl.d.ts +94 -0
- package/dist/esm/shared/validation/ttl.js +46 -0
- package/dist/esm/store/actions/list-namespaces.d.ts +79 -0
- package/dist/esm/store/actions/list-namespaces.js +86 -0
- package/dist/esm/store/actions/put.d.ts +43 -0
- package/dist/esm/store/actions/put.js +46 -0
- package/dist/esm/store/actions/reconcile-vector-index.d.ts +38 -0
- package/dist/esm/store/actions/reconcile-vector-index.js +10 -0
- package/dist/esm/store/actions/search.d.ts +38 -0
- package/dist/esm/store/actions/search.js +23 -0
- package/dist/esm/store/internal/batch-plan.d.ts +56 -0
- package/dist/esm/store/internal/batch-plan.js +28 -0
- package/dist/esm/store/internal/filter.d.ts +43 -0
- package/dist/esm/store/internal/filter.js +60 -0
- package/dist/esm/store/internal/get-item.d.ts +77 -0
- package/dist/esm/store/internal/get-item.js +54 -0
- package/dist/esm/store/internal/item-write.d.ts +270 -0
- package/dist/esm/store/internal/item-write.js +173 -0
- package/dist/esm/store/internal/parse.d.ts +230 -0
- package/dist/esm/store/internal/parse.js +169 -0
- package/dist/esm/store/internal/rows.d.ts +359 -0
- package/dist/esm/store/internal/rows.js +147 -0
- package/dist/esm/store/internal/semantic-search.d.ts +168 -0
- package/dist/esm/store/internal/semantic-search.js +200 -0
- package/dist/esm/store/internal/setup.d.ts +96 -0
- package/dist/esm/store/internal/setup.js +98 -0
- package/dist/esm/store/internal/table-search.d.ts +100 -0
- package/dist/esm/store/internal/table-search.js +119 -0
- package/dist/esm/store/internal/vector-index.d.ts +258 -0
- package/dist/esm/store/internal/vector-index.js +256 -0
- package/dist/esm/store/store.d.ts +329 -0
- package/dist/esm/store/store.js +93 -0
- package/dist/esm/store/types.d.ts +111 -0
- package/dist/esm/store/types.js +1 -0
- package/dist/esm/store/vector-backend.d.ts +104 -0
- package/dist/esm/store/vector-backend.js +1 -0
- package/package.json +68 -46
- package/dist/checkpointer/actions/delete-thread.d.ts +0 -10
- package/dist/checkpointer/actions/delete-thread.js +0 -38
- package/dist/checkpointer/actions/get-tuple.d.ts +0 -11
- package/dist/checkpointer/actions/get-tuple.js +0 -25
- package/dist/checkpointer/actions/list.d.ts +0 -20
- package/dist/checkpointer/actions/list.js +0 -113
- package/dist/checkpointer/actions/put-writes.d.ts +0 -15
- package/dist/checkpointer/actions/put-writes.js +0 -62
- package/dist/checkpointer/actions/put.d.ts +0 -17
- package/dist/checkpointer/actions/put.js +0 -73
- package/dist/checkpointer/internal/assemble.d.ts +0 -17
- package/dist/checkpointer/internal/assemble.js +0 -38
- package/dist/checkpointer/internal/checkpoint-write-verify.d.ts +0 -24
- package/dist/checkpointer/internal/checkpoint-write-verify.js +0 -67
- package/dist/checkpointer/internal/configurable.d.ts +0 -12
- package/dist/checkpointer/internal/configurable.js +0 -24
- package/dist/checkpointer/internal/fetch.d.ts +0 -19
- package/dist/checkpointer/internal/fetch.js +0 -88
- package/dist/checkpointer/internal/filter-match.d.ts +0 -13
- package/dist/checkpointer/internal/filter-match.js +0 -15
- package/dist/checkpointer/internal/item-reader.d.ts +0 -66
- package/dist/checkpointer/internal/item-reader.js +0 -113
- package/dist/checkpointer/internal/item-writer.d.ts +0 -35
- package/dist/checkpointer/internal/item-writer.js +0 -107
- package/dist/checkpointer/internal/keys.d.ts +0 -41
- package/dist/checkpointer/internal/keys.js +0 -117
- package/dist/checkpointer/internal/list-scope.d.ts +0 -61
- package/dist/checkpointer/internal/list-scope.js +0 -108
- package/dist/checkpointer/internal/pending-sends.d.ts +0 -13
- package/dist/checkpointer/internal/pending-sends.js +0 -29
- package/dist/checkpointer/internal/query.d.ts +0 -21
- package/dist/checkpointer/internal/query.js +0 -42
- package/dist/checkpointer/internal/regular-write.d.ts +0 -28
- package/dist/checkpointer/internal/regular-write.js +0 -66
- package/dist/checkpointer/internal/setup.d.ts +0 -33
- package/dist/checkpointer/internal/setup.js +0 -38
- package/dist/checkpointer/internal/special-write-cas.d.ts +0 -29
- package/dist/checkpointer/internal/special-write-cas.js +0 -104
- package/dist/checkpointer/internal/special-write-cleanup.d.ts +0 -23
- package/dist/checkpointer/internal/special-write-cleanup.js +0 -50
- package/dist/checkpointer/internal/special-write-verify.d.ts +0 -53
- package/dist/checkpointer/internal/special-write-verify.js +0 -80
- package/dist/checkpointer/internal/stored-channels.d.ts +0 -31
- package/dist/checkpointer/internal/stored-channels.js +0 -70
- package/dist/checkpointer/internal/validation.d.ts +0 -18
- package/dist/checkpointer/internal/validation.js +0 -40
- package/dist/checkpointer/internal/write-guard.d.ts +0 -20
- package/dist/checkpointer/internal/write-guard.js +0 -48
- package/dist/checkpointer/internal/write-index.d.ts +0 -36
- package/dist/checkpointer/internal/write-index.js +0 -41
- package/dist/checkpointer/saver.d.ts +0 -70
- package/dist/checkpointer/saver.js +0 -105
- package/dist/checkpointer/types.d.ts +0 -58
- package/dist/factory/factory.d.ts +0 -40
- package/dist/factory/factory.js +0 -87
- package/dist/history/actions/add-messages.d.ts +0 -15
- package/dist/history/actions/add-messages.js +0 -77
- package/dist/history/actions/clear.d.ts +0 -10
- package/dist/history/actions/clear.js +0 -34
- package/dist/history/actions/get-messages.d.ts +0 -17
- package/dist/history/actions/get-messages.js +0 -79
- package/dist/history/actions/list-sessions.d.ts +0 -13
- package/dist/history/actions/list-sessions.js +0 -53
- package/dist/history/actions/reconcile-count.d.ts +0 -12
- package/dist/history/actions/reconcile-count.js +0 -64
- package/dist/history/chat-message-history.d.ts +0 -73
- package/dist/history/chat-message-history.js +0 -111
- package/dist/history/internal/append-saga.d.ts +0 -25
- package/dist/history/internal/append-saga.js +0 -79
- package/dist/history/internal/compensation.d.ts +0 -25
- package/dist/history/internal/compensation.js +0 -92
- package/dist/history/internal/item-mapper.d.ts +0 -9
- package/dist/history/internal/item-mapper.js +0 -27
- package/dist/history/internal/keys.d.ts +0 -16
- package/dist/history/internal/keys.js +0 -48
- package/dist/history/internal/message-chunker.d.ts +0 -13
- package/dist/history/internal/message-chunker.js +0 -67
- package/dist/history/internal/message-transaction.d.ts +0 -25
- package/dist/history/internal/message-transaction.js +0 -61
- package/dist/history/internal/message-window.d.ts +0 -17
- package/dist/history/internal/message-window.js +0 -49
- package/dist/history/internal/query.d.ts +0 -23
- package/dist/history/internal/query.js +0 -39
- package/dist/history/internal/session-count.d.ts +0 -47
- package/dist/history/internal/session-count.js +0 -115
- package/dist/history/internal/session-title.d.ts +0 -19
- package/dist/history/internal/session-title.js +0 -43
- package/dist/history/internal/session-update.d.ts +0 -27
- package/dist/history/internal/session-update.js +0 -69
- package/dist/history/internal/setup.d.ts +0 -31
- package/dist/history/internal/setup.js +0 -43
- package/dist/history/internal/title-generator.d.ts +0 -12
- package/dist/history/internal/title-generator.js +0 -41
- package/dist/history/internal/ttl-anchor.d.ts +0 -24
- package/dist/history/internal/ttl-anchor.js +0 -38
- package/dist/history/internal/validation.d.ts +0 -25
- package/dist/history/internal/validation.js +0 -53
- package/dist/history/session-adapter.d.ts +0 -29
- package/dist/history/session-adapter.js +0 -35
- package/dist/history/types.d.ts +0 -69
- package/dist/index.d.ts +0 -29
- package/dist/index.js +0 -32
- package/dist/shared/clock.d.ts +0 -8
- package/dist/shared/clock.js +0 -16
- package/dist/shared/codec/codec.d.ts +0 -53
- package/dist/shared/codec/codec.js +0 -66
- package/dist/shared/codec/compression.d.ts +0 -24
- package/dist/shared/codec/compression.js +0 -48
- package/dist/shared/codec/descriptor-keys.d.ts +0 -12
- package/dist/shared/codec/descriptor-keys.js +0 -14
- package/dist/shared/codec/encode.d.ts +0 -13
- package/dist/shared/codec/encode.js +0 -43
- package/dist/shared/codec/json-serde.d.ts +0 -7
- package/dist/shared/codec/json-serde.js +0 -17
- package/dist/shared/codec/payload-loss.d.ts +0 -12
- package/dist/shared/codec/payload-loss.js +0 -38
- package/dist/shared/codec/s3/adapter-config.d.ts +0 -13
- package/dist/shared/codec/s3/adapter-config.js +0 -22
- package/dist/shared/codec/s3/bounded-body.d.ts +0 -14
- package/dist/shared/codec/s3/bounded-body.js +0 -47
- package/dist/shared/codec/s3/client.d.ts +0 -18
- package/dist/shared/codec/s3/client.js +0 -46
- package/dist/shared/codec/s3/config.d.ts +0 -51
- package/dist/shared/codec/s3/config.js +0 -58
- package/dist/shared/codec/s3/delete.d.ts +0 -7
- package/dist/shared/codec/s3/delete.js +0 -28
- package/dist/shared/codec/s3/key-scope.d.ts +0 -23
- package/dist/shared/codec/s3/key-scope.js +0 -44
- package/dist/shared/codec/s3/lifecycle.d.ts +0 -14
- package/dist/shared/codec/s3/lifecycle.js +0 -63
- package/dist/shared/codec/s3/offloader.d.ts +0 -44
- package/dist/shared/codec/s3/offloader.js +0 -118
- package/dist/shared/codec/s3/orphans.d.ts +0 -23
- package/dist/shared/codec/s3/orphans.js +0 -71
- package/dist/shared/codec/s3/read-write.d.ts +0 -18
- package/dist/shared/codec/s3/read-write.js +0 -51
- package/dist/shared/codec/s3/retry.d.ts +0 -5
- package/dist/shared/codec/s3/retry.js +0 -22
- package/dist/shared/concurrency.d.ts +0 -6
- package/dist/shared/constants.d.ts +0 -112
- package/dist/shared/constants.js +0 -115
- package/dist/shared/dynamodb/abort.d.ts +0 -9
- package/dist/shared/dynamodb/abort.js +0 -27
- package/dist/shared/dynamodb/backoff.d.ts +0 -15
- package/dist/shared/dynamodb/backoff.js +0 -48
- package/dist/shared/dynamodb/batch-write.d.ts +0 -22
- package/dist/shared/dynamodb/batch-write.js +0 -53
- package/dist/shared/dynamodb/cancellation.d.ts +0 -6
- package/dist/shared/dynamodb/cancellation.js +0 -7
- package/dist/shared/dynamodb/client.d.ts +0 -28
- package/dist/shared/dynamodb/conditional-put.d.ts +0 -67
- package/dist/shared/dynamodb/conditional-put.js +0 -76
- package/dist/shared/dynamodb/drain-unprocessed.d.ts +0 -21
- package/dist/shared/dynamodb/drain-unprocessed.js +0 -43
- package/dist/shared/dynamodb/expiry.d.ts +0 -16
- package/dist/shared/dynamodb/expiry.js +0 -29
- package/dist/shared/dynamodb/paginate-core.d.ts +0 -24
- package/dist/shared/dynamodb/paginate-core.js +0 -82
- package/dist/shared/dynamodb/paginate.d.ts +0 -14
- package/dist/shared/dynamodb/paginate.js +0 -19
- package/dist/shared/dynamodb/partition-delete.d.ts +0 -39
- package/dist/shared/dynamodb/partition-delete.js +0 -71
- package/dist/shared/dynamodb/retry-classifier.d.ts +0 -17
- package/dist/shared/dynamodb/retry-classifier.js +0 -118
- package/dist/shared/dynamodb/retry-policy.d.ts +0 -26
- package/dist/shared/dynamodb/retry-policy.js +0 -22
- package/dist/shared/dynamodb/retry.d.ts +0 -31
- package/dist/shared/dynamodb/retry.js +0 -57
- package/dist/shared/dynamodb/scan.d.ts +0 -14
- package/dist/shared/dynamodb/scan.js +0 -19
- package/dist/shared/dynamodb/types.d.ts +0 -23
- package/dist/shared/errors/base-error.d.ts +0 -30
- package/dist/shared/errors/base-error.js +0 -27
- package/dist/shared/errors/boundary.d.ts +0 -18
- package/dist/shared/errors/boundary.js +0 -46
- package/dist/shared/errors/error-code.d.ts +0 -13
- package/dist/shared/errors/errors.d.ts +0 -68
- package/dist/shared/errors/errors.js +0 -114
- package/dist/shared/errors/upstream-error.d.ts +0 -16
- package/dist/shared/errors/upstream-error.js +0 -27
- package/dist/shared/errors/wrap-error.d.ts +0 -7
- package/dist/shared/errors/wrap-error.js +0 -15
- package/dist/shared/logging/logger.d.ts +0 -18
- package/dist/shared/logging/logger.js +0 -15
- package/dist/shared/logging/redaction-walk.d.ts +0 -23
- package/dist/shared/logging/redaction-walk.js +0 -112
- package/dist/shared/logging/redaction.d.ts +0 -39
- package/dist/shared/logging/redaction.js +0 -75
- package/dist/shared/logging/secret-patterns.d.ts +0 -92
- package/dist/shared/logging/secret-patterns.js +0 -133
- package/dist/shared/options.d.ts +0 -37
- package/dist/shared/ulid.d.ts +0 -23
- package/dist/shared/validation/options.d.ts +0 -8
- package/dist/shared/validation/options.js +0 -90
- package/dist/shared/validation/primitives.d.ts +0 -29
- package/dist/shared/validation/primitives.js +0 -82
- package/dist/shared/validation/ttl.d.ts +0 -28
- package/dist/shared/validation/ttl.js +0 -52
- package/dist/store/actions/get.d.ts +0 -13
- package/dist/store/actions/get.js +0 -73
- package/dist/store/actions/list-namespaces.d.ts +0 -8
- package/dist/store/actions/list-namespaces.js +0 -59
- package/dist/store/actions/put.d.ts +0 -10
- package/dist/store/actions/put.js +0 -96
- package/dist/store/actions/reconcile-vector-index.d.ts +0 -18
- package/dist/store/actions/reconcile-vector-index.js +0 -26
- package/dist/store/actions/search.d.ts +0 -9
- package/dist/store/actions/search.js +0 -34
- package/dist/store/internal/backend-search.d.ts +0 -4
- package/dist/store/internal/backend-search.js +0 -74
- package/dist/store/internal/batch-plan.d.ts +0 -11
- package/dist/store/internal/batch-plan.js +0 -52
- package/dist/store/internal/candidates.d.ts +0 -23
- package/dist/store/internal/candidates.js +0 -94
- package/dist/store/internal/filter.d.ts +0 -9
- package/dist/store/internal/filter.js +0 -85
- package/dist/store/internal/index-reconcile.d.ts +0 -21
- package/dist/store/internal/index-reconcile.js +0 -118
- package/dist/store/internal/index-sync.d.ts +0 -10
- package/dist/store/internal/index-sync.js +0 -25
- package/dist/store/internal/item-mapper.d.ts +0 -27
- package/dist/store/internal/item-mapper.js +0 -61
- package/dist/store/internal/keys.d.ts +0 -17
- package/dist/store/internal/keys.js +0 -41
- package/dist/store/internal/namespace-match.d.ts +0 -11
- package/dist/store/internal/namespace-match.js +0 -40
- package/dist/store/internal/option-validation.d.ts +0 -13
- package/dist/store/internal/option-validation.js +0 -77
- package/dist/store/internal/overwrite-swap.d.ts +0 -32
- package/dist/store/internal/overwrite-swap.js +0 -68
- package/dist/store/internal/persist.d.ts +0 -28
- package/dist/store/internal/persist.js +0 -64
- package/dist/store/internal/query.d.ts +0 -11
- package/dist/store/internal/query.js +0 -48
- package/dist/store/internal/ranker.d.ts +0 -18
- package/dist/store/internal/ranker.js +0 -39
- package/dist/store/internal/read-existing.d.ts +0 -23
- package/dist/store/internal/read-existing.js +0 -41
- package/dist/store/internal/score-direction.d.ts +0 -31
- package/dist/store/internal/score-direction.js +0 -38
- package/dist/store/internal/search-filter.d.ts +0 -3
- package/dist/store/internal/search-filter.js +0 -10
- package/dist/store/internal/semantic-search.d.ts +0 -34
- package/dist/store/internal/semantic-search.js +0 -87
- package/dist/store/internal/setup.d.ts +0 -36
- package/dist/store/internal/setup.js +0 -40
- package/dist/store/internal/text-path.d.ts +0 -17
- package/dist/store/internal/validation.d.ts +0 -18
- package/dist/store/internal/validation.js +0 -51
- package/dist/store/internal/write-verify.d.ts +0 -42
- package/dist/store/internal/write-verify.js +0 -71
- package/dist/store/store.d.ts +0 -61
- package/dist/store/store.js +0 -107
- package/dist/store/types.d.ts +0 -50
- package/dist/store/types.js +0 -2
- package/dist/store/vector-backend.d.ts +0 -43
- package/dist/store/vector-backend.js +0 -2
- /package/dist/{checkpointer → cjs/checkpointer}/types.js +0 -0
- /package/dist/{factory → cjs/factory}/types.js +0 -0
- /package/dist/{history → cjs/history}/types.js +0 -0
- /package/dist/{shared → cjs/shared}/options.js +0 -0
- /package/dist/{shared/dynamodb → cjs/store}/types.js +0 -0
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import { validationError } from '../../shared/errors/errors.js';
|
|
2
|
+
const EMBED_BATCH_SIZE = 100;
|
|
3
|
+
export function cosineSimilarity(a, b) {
|
|
4
|
+
if (a.length !== b.length)
|
|
5
|
+
return 0;
|
|
6
|
+
let dot = 0;
|
|
7
|
+
let normA = 0;
|
|
8
|
+
let normB = 0;
|
|
9
|
+
for (let i = 0; i < a.length; i++) {
|
|
10
|
+
dot += a[i] * b[i];
|
|
11
|
+
normA += a[i] * a[i];
|
|
12
|
+
normB += b[i] * b[i];
|
|
13
|
+
}
|
|
14
|
+
if (normA === 0 || normB === 0)
|
|
15
|
+
return 0;
|
|
16
|
+
return dot / (Math.sqrt(normA) * Math.sqrt(normB));
|
|
17
|
+
}
|
|
18
|
+
export function extractTexts(value, fields) {
|
|
19
|
+
return fields.flatMap((field) => getTextAtPath(value, field)).filter((text) => text.length > 0);
|
|
20
|
+
}
|
|
21
|
+
export function extractText(value, fields) {
|
|
22
|
+
return extractTexts(value, fields).join(' ');
|
|
23
|
+
}
|
|
24
|
+
export function assertVectorDims(index, vector, what) {
|
|
25
|
+
const dims = index.dims;
|
|
26
|
+
if (!Number.isInteger(dims) || dims <= 0 || vector.length === dims)
|
|
27
|
+
return;
|
|
28
|
+
throw validationError(`index.embeddings returned a ${vector.length}-dimensional ${what} vector but index.dims ` +
|
|
29
|
+
`is ${dims}; the embeddings model does not match the configured index`, 'index.dims');
|
|
30
|
+
}
|
|
31
|
+
export async function embedValues(context, values, fieldsOverride) {
|
|
32
|
+
const index = context.index;
|
|
33
|
+
if (!index)
|
|
34
|
+
return values.map(() => undefined);
|
|
35
|
+
const fields = fieldsOverride ?? index.fields ?? ['$'];
|
|
36
|
+
const pending = [];
|
|
37
|
+
values.forEach((value, position) => {
|
|
38
|
+
const text = extractText(value, fields);
|
|
39
|
+
if (text.length > 0)
|
|
40
|
+
pending.push({ text, position });
|
|
41
|
+
});
|
|
42
|
+
const vectors = values.map(() => undefined);
|
|
43
|
+
for (let start = 0; start < pending.length; start += EMBED_BATCH_SIZE) {
|
|
44
|
+
const batch = pending.slice(start, start + EMBED_BATCH_SIZE);
|
|
45
|
+
const embedded = await index.embeddings.embedDocuments(batch.map((entry) => entry.text));
|
|
46
|
+
batch.forEach((entry, i) => {
|
|
47
|
+
assertVectorDims(index, embedded[i], 'document');
|
|
48
|
+
vectors[entry.position] = embedded[i];
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
return vectors;
|
|
52
|
+
}
|
|
53
|
+
export async function embedValue(context, value, fieldsOverride) {
|
|
54
|
+
return (await embedValues(context, [value], fieldsOverride))[0];
|
|
55
|
+
}
|
|
56
|
+
export async function embedPassages(context, value, fieldsOverride) {
|
|
57
|
+
const index = context.index;
|
|
58
|
+
if (!index)
|
|
59
|
+
return undefined;
|
|
60
|
+
const texts = extractTexts(value, fieldsOverride ?? index.fields ?? ['$']);
|
|
61
|
+
if (texts.length === 0)
|
|
62
|
+
return undefined;
|
|
63
|
+
const vectors = [];
|
|
64
|
+
for (let start = 0; start < texts.length; start += EMBED_BATCH_SIZE) {
|
|
65
|
+
const embedded = await index.embeddings.embedDocuments(texts.slice(start, start + EMBED_BATCH_SIZE));
|
|
66
|
+
for (const vector of embedded) {
|
|
67
|
+
assertVectorDims(index, vector, 'document');
|
|
68
|
+
vectors.push(vector);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return vectors;
|
|
72
|
+
}
|
|
73
|
+
function prettyText(value) {
|
|
74
|
+
let text;
|
|
75
|
+
try {
|
|
76
|
+
text = JSON.stringify(value, null, 2);
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
return [];
|
|
80
|
+
}
|
|
81
|
+
return text === undefined ? [] : [text];
|
|
82
|
+
}
|
|
83
|
+
function isScalar(value) {
|
|
84
|
+
return typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean';
|
|
85
|
+
}
|
|
86
|
+
function leafText(value) {
|
|
87
|
+
if (isScalar(value))
|
|
88
|
+
return [String(value)];
|
|
89
|
+
if (value === null)
|
|
90
|
+
return [];
|
|
91
|
+
return prettyText(value);
|
|
92
|
+
}
|
|
93
|
+
function scanGroup(path, start, open, close) {
|
|
94
|
+
let depth = 1;
|
|
95
|
+
let i = start;
|
|
96
|
+
while (i < path.length && depth > 0) {
|
|
97
|
+
if (path[i] === open)
|
|
98
|
+
depth += 1;
|
|
99
|
+
else if (path[i] === close)
|
|
100
|
+
depth -= 1;
|
|
101
|
+
i += 1;
|
|
102
|
+
}
|
|
103
|
+
return i;
|
|
104
|
+
}
|
|
105
|
+
export function tokenizePath(path) {
|
|
106
|
+
const tokens = [];
|
|
107
|
+
let current = '';
|
|
108
|
+
const flush = () => {
|
|
109
|
+
if (current.length > 0)
|
|
110
|
+
tokens.push(current);
|
|
111
|
+
current = '';
|
|
112
|
+
};
|
|
113
|
+
let i = 0;
|
|
114
|
+
while (i < path.length) {
|
|
115
|
+
const char = path[i];
|
|
116
|
+
if (char === '[' || char === '{') {
|
|
117
|
+
flush();
|
|
118
|
+
const end = scanGroup(path, i + 1, char, char === '[' ? ']' : '}');
|
|
119
|
+
tokens.push(path.slice(i, end));
|
|
120
|
+
i = end;
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
if (char === '.')
|
|
124
|
+
flush();
|
|
125
|
+
else
|
|
126
|
+
current += char;
|
|
127
|
+
i += 1;
|
|
128
|
+
}
|
|
129
|
+
flush();
|
|
130
|
+
return tokens;
|
|
131
|
+
}
|
|
132
|
+
function groupFieldText(value, field) {
|
|
133
|
+
let current = value;
|
|
134
|
+
for (const token of tokenizePath(field)) {
|
|
135
|
+
if (current !== null && typeof current === 'object' && token in current) {
|
|
136
|
+
current = current[token];
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
return [];
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return isScalar(current) ? [String(current)] : prettyText(current);
|
|
143
|
+
}
|
|
144
|
+
function indexText(value, token, tokens, pos) {
|
|
145
|
+
if (!Array.isArray(value))
|
|
146
|
+
return [];
|
|
147
|
+
const index = token.slice(1, -1);
|
|
148
|
+
if (index === '*')
|
|
149
|
+
return value.flatMap((item) => extract(item, tokens, pos + 1));
|
|
150
|
+
let idx = Number.parseInt(index, 10);
|
|
151
|
+
if (Number.isNaN(idx))
|
|
152
|
+
return [];
|
|
153
|
+
if (idx < 0)
|
|
154
|
+
idx = value.length + idx;
|
|
155
|
+
return idx >= 0 && idx < value.length ? extract(value[idx], tokens, pos + 1) : [];
|
|
156
|
+
}
|
|
157
|
+
function groupText(value, token) {
|
|
158
|
+
if (typeof value !== 'object' || value === null)
|
|
159
|
+
return [];
|
|
160
|
+
const results = [];
|
|
161
|
+
for (const field of token.slice(1, -1).split(',')) {
|
|
162
|
+
const trimmed = field.trim();
|
|
163
|
+
if (tokenizePath(trimmed).length > 0)
|
|
164
|
+
results.push(...groupFieldText(value, trimmed));
|
|
165
|
+
}
|
|
166
|
+
return results;
|
|
167
|
+
}
|
|
168
|
+
function wildcardText(value, tokens, pos) {
|
|
169
|
+
if (Array.isArray(value))
|
|
170
|
+
return value.flatMap((item) => extract(item, tokens, pos + 1));
|
|
171
|
+
if (typeof value === 'object' && value !== null) {
|
|
172
|
+
return Object.values(value).flatMap((item) => extract(item, tokens, pos + 1));
|
|
173
|
+
}
|
|
174
|
+
return [];
|
|
175
|
+
}
|
|
176
|
+
function memberText(value, token, tokens, pos) {
|
|
177
|
+
if (typeof value !== 'object' || value === null || !(token in value))
|
|
178
|
+
return [];
|
|
179
|
+
return extract(value[token], tokens, pos + 1);
|
|
180
|
+
}
|
|
181
|
+
function extract(value, tokens, pos) {
|
|
182
|
+
if (pos >= tokens.length)
|
|
183
|
+
return leafText(value);
|
|
184
|
+
const token = tokens[pos];
|
|
185
|
+
if (token.startsWith('[') && token.endsWith(']'))
|
|
186
|
+
return indexText(value, token, tokens, pos);
|
|
187
|
+
const results = pos === 0 && token === '$' ? prettyText(value) : [];
|
|
188
|
+
if (token.startsWith('{') && token.endsWith('}'))
|
|
189
|
+
results.push(...groupText(value, token));
|
|
190
|
+
else if (token === '*')
|
|
191
|
+
results.push(...wildcardText(value, tokens, pos));
|
|
192
|
+
else
|
|
193
|
+
results.push(...memberText(value, token, tokens, pos));
|
|
194
|
+
return results;
|
|
195
|
+
}
|
|
196
|
+
export function getTextAtPath(value, path) {
|
|
197
|
+
if (path === '' || path === '$')
|
|
198
|
+
return prettyText(value);
|
|
199
|
+
return extract(value, tokenizePath(path), 0);
|
|
200
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hides which options the store and its methods accept, and how the store is
|
|
3
|
+
* assembled from them.
|
|
4
|
+
*
|
|
5
|
+
* The exhaustive key list of every option bag — the constructor's, `search`'s,
|
|
6
|
+
* `listNamespaces`' — lives here, compiler-checked against its type. The
|
|
7
|
+
* store's own options are checked after the shared ones — the in-memory caps,
|
|
8
|
+
* that a vector backend comes with an index, that the index can embed, the
|
|
9
|
+
* score direction — and the context every operation receives is built with its
|
|
10
|
+
* defaults filled in.
|
|
11
|
+
*/
|
|
12
|
+
import type { IndexConfig, SerializerProtocol } from '@langchain/langgraph-checkpoint';
|
|
13
|
+
import { type AdapterCore, type AdapterShell } from '../../shared/adapter.js';
|
|
14
|
+
import type { DynamoDBStoreOptions } from '../types.js';
|
|
15
|
+
import { type VectorBackend, type VectorScoreDirection } from '../vector-backend.js';
|
|
16
|
+
/** Default cap on candidates the in-DB semantic ranker will score. */
|
|
17
|
+
export declare const DEFAULT_MAX_SEARCH_CANDIDATES = 1000;
|
|
18
|
+
/**
|
|
19
|
+
* Largest `maxSearchCandidates` an adapter accepts: this many decoded
|
|
20
|
+
* candidates are held and re-ranked in memory by one `search()` call, so an
|
|
21
|
+
* unbounded value lets a typo or hostile config hold an unbounded working set.
|
|
22
|
+
*/
|
|
23
|
+
export declare const MAX_SEARCH_CANDIDATES = 100000;
|
|
24
|
+
/**
|
|
25
|
+
* Largest `maxScanItems` an adapter accepts: this many raw rows are collected
|
|
26
|
+
* into memory across one paginated scan/query before it errors, so — like
|
|
27
|
+
* {@link MAX_SEARCH_CANDIDATES} — an unbounded value lets a typo or hostile
|
|
28
|
+
* config hold an unbounded working set.
|
|
29
|
+
*/
|
|
30
|
+
export declare const MAX_SCAN_ITEMS = 1000000;
|
|
31
|
+
/** Resolved collaborators shared by every store action. */
|
|
32
|
+
export interface StoreContext extends AdapterCore {
|
|
33
|
+
serde: SerializerProtocol;
|
|
34
|
+
index?: IndexConfig;
|
|
35
|
+
vectorBackend?: VectorBackend;
|
|
36
|
+
vectorScoreDirection: VectorScoreDirection;
|
|
37
|
+
maxSearchCandidates: number;
|
|
38
|
+
maxScanItems: number;
|
|
39
|
+
maxIterations: number;
|
|
40
|
+
}
|
|
41
|
+
/** Result of wiring up a store from its options. */
|
|
42
|
+
export interface StoreSetup {
|
|
43
|
+
context: StoreContext;
|
|
44
|
+
shell: AdapterShell;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Validate the options, then resolve the client, offloader, serializer and index.
|
|
48
|
+
*
|
|
49
|
+
* Accepts: `options` — validated first, so no half-built store exists when one
|
|
50
|
+
* is wrong. Everything optional has a default here and nowhere else, which is
|
|
51
|
+
* what lets every action read `context.x` without re-deciding what absent means.
|
|
52
|
+
*
|
|
53
|
+
* Returns: the context every action shares, and the shell that releases what
|
|
54
|
+
* it holds — a client the caller passed in is never destroyed by `destroy()`.
|
|
55
|
+
*
|
|
56
|
+
* Throws: `VALIDATION` for any invalid option, naming the option.
|
|
57
|
+
*
|
|
58
|
+
* Guarantees: constructing a store performs no I/O. The stacked-retry check is
|
|
59
|
+
* deliberately not awaited: it is a warning about a caller-supplied client, not
|
|
60
|
+
* a precondition.
|
|
61
|
+
*/
|
|
62
|
+
export declare function setUpStore(options: DynamoDBStoreOptions): StoreSetup;
|
|
63
|
+
/**
|
|
64
|
+
* The keys of the store's constructor options, exhaustive in both directions:
|
|
65
|
+
* `allKeysOf<T>` makes omitting or inventing one a compile error, so the list
|
|
66
|
+
* cannot rot away from the type it guards. It lives with the feature because
|
|
67
|
+
* the type it is checked against does; `shared/` knows no feature. `search`'s
|
|
68
|
+
* and `listNamespaces`' options have no list: LangGraph defines them, so a key
|
|
69
|
+
* it adds is ignored rather than refused (decision record 28).
|
|
70
|
+
*/
|
|
71
|
+
export declare const STORE_KEYS: readonly string[];
|
|
72
|
+
/**
|
|
73
|
+
* Validate the store's own options at construction; the shared ones are
|
|
74
|
+
* `openAdapter`'s, which checks them before these.
|
|
75
|
+
*
|
|
76
|
+
* A `vectorBackend` without an `index` is rejected outright rather than
|
|
77
|
+
* silently degrading: with no embeddings configured, every `put` would compute
|
|
78
|
+
* no vector and instruct the backend to *delete* the item's entry instead of
|
|
79
|
+
* indexing it, and `search()` would fall through to an unranked scan-order
|
|
80
|
+
* listing with no `.score` field and no error — a semantic query returning a
|
|
81
|
+
* normal-looking but meaningless response. `reconcileVectorIndex` already
|
|
82
|
+
* refused this exact misconfiguration.
|
|
83
|
+
*
|
|
84
|
+
* Accepts: every option the store takes. The types describe the intended
|
|
85
|
+
* shapes; this runs for the JavaScript caller the types never see, and for the
|
|
86
|
+
* combinations no type can express — a backend without an index, an `index`
|
|
87
|
+
* key `IndexConfig` does not declare, an `embeddings` object missing a method,
|
|
88
|
+
* a direction outside its union.
|
|
89
|
+
*
|
|
90
|
+
* Returns: nothing: the value is kept under its declared type, and this
|
|
91
|
+
* checks it.
|
|
92
|
+
*
|
|
93
|
+
* Throws: `VALIDATION` naming the offending option. Every failure is raised
|
|
94
|
+
* at construction, where the fix is, rather than at the first put or search.
|
|
95
|
+
*/
|
|
96
|
+
export declare function assertStoreOptions(options: DynamoDBStoreOptions): void;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { openAdapter } from '../../shared/adapter.js';
|
|
2
|
+
import { JSON_SERDE } from '../../shared/codec/json-serde.js';
|
|
3
|
+
import { MAX_LOOP_ITERATIONS, MAX_TOTAL_ROWS_IN_MEMORY } from '../../shared/dynamodb/paginate.js';
|
|
4
|
+
import { validationError } from '../../shared/errors/errors.js';
|
|
5
|
+
import { assertMembers, EMBEDDINGS_MEMBERS, VECTOR_BACKEND_MEMBERS, } from '../../shared/validation/collaborators.js';
|
|
6
|
+
import { allKeysOf, assertShape } from '../../shared/validation/option-shape.js';
|
|
7
|
+
import { assertInteger, assertStringArray } from '../../shared/validation/primitives.js';
|
|
8
|
+
import { VECTOR_SCORE_DIRECTIONS, } from '../vector-backend.js';
|
|
9
|
+
export const DEFAULT_MAX_SEARCH_CANDIDATES = 1000;
|
|
10
|
+
export const MAX_SEARCH_CANDIDATES = 100_000;
|
|
11
|
+
export const MAX_SCAN_ITEMS = 1_000_000;
|
|
12
|
+
export function setUpStore(options) {
|
|
13
|
+
assertShape(options, STORE_KEYS, 'options');
|
|
14
|
+
const shell = openAdapter(options, 'store', {
|
|
15
|
+
options: () => assertStoreOptions(options),
|
|
16
|
+
collaborators: () => {
|
|
17
|
+
if (options.vectorBackend !== undefined) {
|
|
18
|
+
assertMembers(options.vectorBackend, VECTOR_BACKEND_MEMBERS, 'vectorBackend');
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
return {
|
|
23
|
+
shell,
|
|
24
|
+
context: {
|
|
25
|
+
...shell.core,
|
|
26
|
+
serde: options.serde ?? JSON_SERDE,
|
|
27
|
+
index: options.index,
|
|
28
|
+
vectorBackend: options.vectorBackend,
|
|
29
|
+
vectorScoreDirection: options.vectorScoreDirection ?? 'relevance',
|
|
30
|
+
maxSearchCandidates: options.maxSearchCandidates ?? DEFAULT_MAX_SEARCH_CANDIDATES,
|
|
31
|
+
maxScanItems: options.maxScanItems ?? MAX_TOTAL_ROWS_IN_MEMORY,
|
|
32
|
+
maxIterations: options.maxIterations ?? MAX_LOOP_ITERATIONS,
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
export const STORE_KEYS = allKeysOf({
|
|
37
|
+
tableName: 'tableName',
|
|
38
|
+
client: 'client',
|
|
39
|
+
clientConfig: 'clientConfig',
|
|
40
|
+
createClient: 'createClient',
|
|
41
|
+
ttl: 'ttl',
|
|
42
|
+
logger: 'logger',
|
|
43
|
+
retry: 'retry',
|
|
44
|
+
readConcurrency: 'readConcurrency',
|
|
45
|
+
compression: 'compression',
|
|
46
|
+
s3: 's3',
|
|
47
|
+
serde: 'serde',
|
|
48
|
+
index: 'index',
|
|
49
|
+
vectorBackend: 'vectorBackend',
|
|
50
|
+
maxSearchCandidates: 'maxSearchCandidates',
|
|
51
|
+
maxScanItems: 'maxScanItems',
|
|
52
|
+
maxIterations: 'maxIterations',
|
|
53
|
+
vectorScoreDirection: 'vectorScoreDirection',
|
|
54
|
+
});
|
|
55
|
+
const INDEX_KEYS = allKeysOf({
|
|
56
|
+
dims: 'dims',
|
|
57
|
+
embeddings: 'embeddings',
|
|
58
|
+
fields: 'fields',
|
|
59
|
+
});
|
|
60
|
+
function assertUsableIndex(index) {
|
|
61
|
+
if (index === undefined)
|
|
62
|
+
return;
|
|
63
|
+
assertShape(index, INDEX_KEYS, 'index');
|
|
64
|
+
assertMembers(index.embeddings, EMBEDDINGS_MEMBERS, 'index.embeddings');
|
|
65
|
+
if (index.fields !== undefined)
|
|
66
|
+
assertStringArray(index.fields, 'index.fields');
|
|
67
|
+
}
|
|
68
|
+
function assertScoreDirection(direction) {
|
|
69
|
+
if (direction === undefined || VECTOR_SCORE_DIRECTIONS.includes(direction))
|
|
70
|
+
return;
|
|
71
|
+
throw validationError(`vectorScoreDirection must be one of ${VECTOR_SCORE_DIRECTIONS.join(' | ')}; received ` +
|
|
72
|
+
`${JSON.stringify(direction)}, which would be left in the backend's own direction and ` +
|
|
73
|
+
'could rank a distance backend backwards', 'vectorScoreDirection');
|
|
74
|
+
}
|
|
75
|
+
function assertLimits(options) {
|
|
76
|
+
if (options.maxScanItems !== undefined) {
|
|
77
|
+
assertInteger(options.maxScanItems, 'maxScanItems', { min: 1, max: MAX_SCAN_ITEMS });
|
|
78
|
+
}
|
|
79
|
+
if (options.maxSearchCandidates !== undefined) {
|
|
80
|
+
assertInteger(options.maxSearchCandidates, 'maxSearchCandidates', {
|
|
81
|
+
min: 1,
|
|
82
|
+
max: MAX_SEARCH_CANDIDATES,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
if (options.maxIterations !== undefined && options.maxIterations !== Infinity) {
|
|
86
|
+
assertInteger(options.maxIterations, 'maxIterations', { min: 1 });
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
export function assertStoreOptions(options) {
|
|
90
|
+
assertLimits(options);
|
|
91
|
+
if (options.vectorBackend && !options.index) {
|
|
92
|
+
throw validationError('vectorBackend requires a configured `index` (embeddings); without one no embedding ' +
|
|
93
|
+
'is computed, every put would clear the item vector, and search would silently return ' +
|
|
94
|
+
'unranked, score-less results', 'vectorBackend');
|
|
95
|
+
}
|
|
96
|
+
assertUsableIndex(options.index);
|
|
97
|
+
assertScoreDirection(options.vectorScoreDirection);
|
|
98
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hides how a search is served from the table alone.
|
|
3
|
+
*
|
|
4
|
+
* Without a vector backend, a search reads the rows under its prefix within
|
|
5
|
+
* `maxScanItems`, decodes them a batch at a time, keeps the ones its filter
|
|
6
|
+
* passes, and — for a semantic query — ranks them in memory by cosine
|
|
7
|
+
* similarity within `maxSearchCandidates`, an item without an embedding sorting
|
|
8
|
+
* last. How far the read goes before it can stop is decided here.
|
|
9
|
+
*/
|
|
10
|
+
import type { Item, SearchItem } from '@langchain/langgraph-checkpoint';
|
|
11
|
+
import type { ParsedSearch } from './parse.js';
|
|
12
|
+
import type { StoreContext } from './setup.js';
|
|
13
|
+
/**
|
|
14
|
+
* How far a collection must go. A plain page is complete once `need`
|
|
15
|
+
* (`offset + limit`) matching items are in hand, so rows past it are never
|
|
16
|
+
* read or decoded; a semantic ranking needs every candidate but is refused as
|
|
17
|
+
* soon as more than `cap` rows exist, before a single decode or embedding.
|
|
18
|
+
*/
|
|
19
|
+
export type CollectBound = {
|
|
20
|
+
kind: 'page';
|
|
21
|
+
need: number;
|
|
22
|
+
} | {
|
|
23
|
+
kind: 'semantic';
|
|
24
|
+
cap: number;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Collect the live rows under the prefix and decode them within `bound`.
|
|
28
|
+
*
|
|
29
|
+
* Accepts: `search.namespacePrefix` — a non-empty prefix is a Query on one
|
|
30
|
+
* partition; an empty one spans every partition and is the Scan this adapter
|
|
31
|
+
* reserves for exactly that (`test/static/guards/scan-sites.ts`). `bound` — a
|
|
32
|
+
* page stops as soon as
|
|
33
|
+
* `need` matching items are in hand; a semantic collection needs every
|
|
34
|
+
* candidate and is refused past `cap`. `search.filter` — applied after decoding,
|
|
35
|
+
* since the filter reads the value.
|
|
36
|
+
*
|
|
37
|
+
* Returns: the matching candidates with the vectors their rows carry, in the
|
|
38
|
+
* order read: sort-key order within a partition, unspecified across partitions.
|
|
39
|
+
* A page therefore pages stably within a namespace, and only there.
|
|
40
|
+
*
|
|
41
|
+
* Throws: `VALIDATION` naming `maxSearchCandidates` before any decode when a
|
|
42
|
+
* semantic collection exceeds `cap`; `RESULT_TRUNCATED` when
|
|
43
|
+
* `maxScanItems` or `maxIterations` is reached while rows remain — a search
|
|
44
|
+
* never silently answers from part of the table; `ABORTED` when the signal
|
|
45
|
+
* fires between pages; whatever a decode throws for a corrupt or unreadable row.
|
|
46
|
+
*
|
|
47
|
+
* Guarantees: a page closes the paginator as soon as it is full, so a namespace
|
|
48
|
+
* far larger than the page costs neither a full decode nor a truncation error.
|
|
49
|
+
* The bound is tested after a row is in hand, not before one is asked for, so
|
|
50
|
+
* a `need` of 0 would still cost one request; `searchItems` answers that case
|
|
51
|
+
* ahead of this call rather than letting it be paid here.
|
|
52
|
+
* Expired rows, rows of other adapters, rows carrying none of the timestamps a
|
|
53
|
+
* decoded item reports, and rows whose own `namespace` does not match the
|
|
54
|
+
* prefix are all skipped — the last matters because a Scan has no key condition
|
|
55
|
+
* at all, so the prefix is enforced here rather than by DynamoDB, and the one
|
|
56
|
+
* before it because a single such row must not cost a search its other results.
|
|
57
|
+
*/
|
|
58
|
+
export declare function collectCandidates(context: StoreContext, search: ParsedSearch, bound: CollectBound, signal?: AbortSignal): Promise<RankCandidate[]>;
|
|
59
|
+
/** A decoded item plus its stored vectors, awaiting ranking. */
|
|
60
|
+
export interface RankCandidate {
|
|
61
|
+
item: Item;
|
|
62
|
+
/**
|
|
63
|
+
* One vector per extracted path. A row written before the store embedded
|
|
64
|
+
* per path carries a single vector and arrives here as a one-element list,
|
|
65
|
+
* which scores identically to how it always did.
|
|
66
|
+
*/
|
|
67
|
+
embeddings?: number[][];
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Rank candidates by cosine similarity to `queryVector`, descending. Throws a
|
|
71
|
+
* `VALIDATION` when the candidate count exceeds `maxCandidates`
|
|
72
|
+
* (steer large corpora to an external VectorBackend).
|
|
73
|
+
*
|
|
74
|
+
* An item is scored by its best-matching vector, as the reference store scores
|
|
75
|
+
* its per-path embeddings. A stored vector whose length differs from the query
|
|
76
|
+
* vector's cannot be scored — it was written by a different embeddings model —
|
|
77
|
+
* and an item with no comparable vector at all is ranked last with an
|
|
78
|
+
* undefined score. `onDimensionMismatch` is invoked once with how many
|
|
79
|
+
* candidates that affected, so the caller can say so instead of silently
|
|
80
|
+
* returning a ranking that quietly omits them.
|
|
81
|
+
*
|
|
82
|
+
* Accepts: `candidates` — in any order; empty ranks to empty. A candidate with
|
|
83
|
+
* no `embeddings` was never indexed (indexing off at write time, or no
|
|
84
|
+
* indexable text) and one with an empty list is the same thing. `queryVector` —
|
|
85
|
+
* the embedded query; one of a different length than everything stored means
|
|
86
|
+
* the query and the corpus were embedded by different models, and nothing
|
|
87
|
+
* scores.
|
|
88
|
+
*
|
|
89
|
+
* Returns: every candidate, scored and sorted best-first. Nothing is dropped:
|
|
90
|
+
* an unscorable item still belongs to the namespace the caller searched, and
|
|
91
|
+
* dropping it would turn a model mismatch into a silently empty result.
|
|
92
|
+
*
|
|
93
|
+
* Throws: `VALIDATION` naming `maxSearchCandidates` when more candidates
|
|
94
|
+
* arrive than may be ranked in memory — a bound on this process's memory, not
|
|
95
|
+
* on the corpus, which is what a `vectorBackend` is for.
|
|
96
|
+
*
|
|
97
|
+
* Guarantees: ranking reads the vectors only; no item is decoded or fetched
|
|
98
|
+
* again, and `onDimensionMismatch` fires at most once per call.
|
|
99
|
+
*/
|
|
100
|
+
export declare function rankInMemory(candidates: RankCandidate[], queryVector: number[], maxCandidates: number, onDimensionMismatch?: (count: number) => void): SearchItem[];
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { nowSeconds } from '../../shared/clock.js';
|
|
2
|
+
import { DEFAULT_READ_CONCURRENCY, mapWithConcurrency } from '../../shared/concurrency.js';
|
|
3
|
+
import { paginateQuery, paginateScan } from '../../shared/dynamodb/paginate.js';
|
|
4
|
+
import { retryFor } from '../../shared/dynamodb/retry.js';
|
|
5
|
+
import { isExpiredRow, withoutExpired } from '../../shared/dynamodb/table-schema.js';
|
|
6
|
+
import { validationError } from '../../shared/errors/errors.js';
|
|
7
|
+
import { passesFilter } from './filter.js';
|
|
8
|
+
import { readCandidate } from './get-item.js';
|
|
9
|
+
import { parseWholeStoreRow, namespaceMatchesPrefix, scopedQuery, storeScan, } from './rows.js';
|
|
10
|
+
import { cosineSimilarity } from './semantic-search.js';
|
|
11
|
+
function storedVectors(record) {
|
|
12
|
+
if (record.embeddings)
|
|
13
|
+
return record.embeddings;
|
|
14
|
+
return record.embedding ? [record.embedding] : undefined;
|
|
15
|
+
}
|
|
16
|
+
function candidateSource(context, search, signal, now) {
|
|
17
|
+
return search.namespacePrefix.length > 0
|
|
18
|
+
? paginateQuery({
|
|
19
|
+
retry: retryFor(context, signal),
|
|
20
|
+
signal,
|
|
21
|
+
client: context.client,
|
|
22
|
+
params: withoutExpired(scopedQuery(context.tableName, search.namespacePrefix), now),
|
|
23
|
+
maxItems: context.maxScanItems,
|
|
24
|
+
maxIterations: context.maxIterations,
|
|
25
|
+
})
|
|
26
|
+
: paginateScan({
|
|
27
|
+
retry: retryFor(context, signal),
|
|
28
|
+
signal,
|
|
29
|
+
client: context.client,
|
|
30
|
+
params: withoutExpired(storeScan(context.tableName), now),
|
|
31
|
+
maxItems: context.maxScanItems,
|
|
32
|
+
maxIterations: context.maxIterations,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
function liveRow(raw, search, now) {
|
|
36
|
+
const record = parseWholeStoreRow(raw);
|
|
37
|
+
if (!record || isExpiredRow(record, now))
|
|
38
|
+
return undefined;
|
|
39
|
+
return namespaceMatchesPrefix(record.namespace, search.namespacePrefix) ? record : undefined;
|
|
40
|
+
}
|
|
41
|
+
async function flush(context, search, state, signal) {
|
|
42
|
+
if (state.pending.length === 0)
|
|
43
|
+
return;
|
|
44
|
+
const batch = state.pending;
|
|
45
|
+
state.pending = [];
|
|
46
|
+
const reads = await mapWithConcurrency(batch, context.readConcurrency ?? DEFAULT_READ_CONCURRENCY, (record) => readCandidate(context, record, signal));
|
|
47
|
+
for (const read of reads) {
|
|
48
|
+
if (read !== undefined && passesFilter(read.item, search.filter)) {
|
|
49
|
+
state.collected.push({ item: read.item, embeddings: storedVectors(read.row) });
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function batchSize(search, need, collected, limit) {
|
|
54
|
+
return search.filter === undefined ? Math.min(limit, need - collected) : limit;
|
|
55
|
+
}
|
|
56
|
+
function tooManyCandidates(count, cap) {
|
|
57
|
+
return validationError(`Semantic search candidate set (${count}) exceeds maxSearchCandidates (${cap}); ` +
|
|
58
|
+
'use a dedicated VectorBackend for large corpora', 'maxSearchCandidates');
|
|
59
|
+
}
|
|
60
|
+
export async function collectCandidates(context, search, bound, signal) {
|
|
61
|
+
const now = nowSeconds();
|
|
62
|
+
const limit = context.readConcurrency ?? DEFAULT_READ_CONCURRENCY;
|
|
63
|
+
const state = { pending: [], collected: [] };
|
|
64
|
+
for await (const raw of candidateSource(context, search, signal, now)) {
|
|
65
|
+
const record = liveRow(raw, search, now);
|
|
66
|
+
if (!record)
|
|
67
|
+
continue;
|
|
68
|
+
state.pending.push(record);
|
|
69
|
+
if (bound.kind === 'semantic') {
|
|
70
|
+
if (state.pending.length > bound.cap)
|
|
71
|
+
throw tooManyCandidates(state.pending.length, bound.cap);
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
if (state.pending.length < batchSize(search, bound.need, state.collected.length, limit)) {
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
await flush(context, search, state, signal);
|
|
78
|
+
if (state.collected.length >= bound.need)
|
|
79
|
+
return state.collected;
|
|
80
|
+
}
|
|
81
|
+
await flush(context, search, state, signal);
|
|
82
|
+
return state.collected;
|
|
83
|
+
}
|
|
84
|
+
const UNSCORED_RANK = -2;
|
|
85
|
+
function bestScore(vectors, queryVector) {
|
|
86
|
+
let best;
|
|
87
|
+
for (const vector of vectors) {
|
|
88
|
+
if (vector.length !== queryVector.length)
|
|
89
|
+
continue;
|
|
90
|
+
const score = cosineSimilarity(queryVector, vector);
|
|
91
|
+
if (best === undefined || score > best)
|
|
92
|
+
best = score;
|
|
93
|
+
}
|
|
94
|
+
return best;
|
|
95
|
+
}
|
|
96
|
+
function isDimensionMismatch(candidate, queryVector) {
|
|
97
|
+
const vectors = candidate.embeddings;
|
|
98
|
+
return (vectors !== undefined &&
|
|
99
|
+
vectors.length > 0 &&
|
|
100
|
+
vectors.every((vector) => vector.length !== queryVector.length));
|
|
101
|
+
}
|
|
102
|
+
export function rankInMemory(candidates, queryVector, maxCandidates, onDimensionMismatch) {
|
|
103
|
+
if (candidates.length > maxCandidates) {
|
|
104
|
+
throw validationError(`Semantic search candidate set (${candidates.length}) exceeds maxSearchCandidates ` +
|
|
105
|
+
`(${maxCandidates}); use a dedicated VectorBackend for large corpora`, 'maxSearchCandidates');
|
|
106
|
+
}
|
|
107
|
+
const mismatched = candidates.filter((candidate) => isDimensionMismatch(candidate, queryVector)).length;
|
|
108
|
+
if (mismatched > 0)
|
|
109
|
+
onDimensionMismatch?.(mismatched);
|
|
110
|
+
return candidates
|
|
111
|
+
.map(({ item, embeddings }) => ({
|
|
112
|
+
...item,
|
|
113
|
+
score: embeddings ? bestScore(embeddings, queryVector) : undefined,
|
|
114
|
+
}))
|
|
115
|
+
.sort((a, b) => rankValue(b) - rankValue(a));
|
|
116
|
+
}
|
|
117
|
+
function rankValue(item) {
|
|
118
|
+
return item.score ?? UNSCORED_RANK;
|
|
119
|
+
}
|