@farukada/aws-langgraph-dynamodb-ts 1.0.0-rc.2 → 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 +390 -193
- package/dist/{backfill → cjs/backfill}/backfill.d.ts +15 -12
- package/dist/cjs/backfill/backfill.js +177 -0
- package/dist/{checkpointer → cjs/checkpointer}/actions/delete-thread.d.ts +1 -1
- package/dist/cjs/checkpointer/actions/delete-thread.js +26 -0
- package/dist/{checkpointer → cjs/checkpointer}/actions/get-tuple.d.ts +4 -3
- package/dist/cjs/checkpointer/actions/get-tuple.js +22 -0
- package/dist/{checkpointer → cjs/checkpointer}/actions/list.d.ts +7 -4
- package/dist/cjs/checkpointer/actions/list.js +70 -0
- package/dist/{checkpointer → cjs/checkpointer}/actions/put-writes.d.ts +8 -6
- package/dist/cjs/checkpointer/actions/put-writes.js +21 -0
- package/dist/{checkpointer → cjs/checkpointer}/actions/put.d.ts +21 -15
- package/dist/cjs/checkpointer/actions/put.js +79 -0
- package/dist/{checkpointer → cjs/checkpointer}/internal/delta-history.d.ts +38 -26
- package/dist/cjs/checkpointer/internal/delta-history.js +131 -0
- package/dist/{checkpointer → cjs/checkpointer}/internal/listing.d.ts +4 -4
- package/dist/cjs/checkpointer/internal/listing.js +104 -0
- package/dist/{checkpointer → cjs/checkpointer}/internal/parse.d.ts +51 -15
- package/dist/cjs/checkpointer/internal/parse.js +184 -0
- package/dist/{checkpointer → cjs/checkpointer}/internal/pending-writes.d.ts +64 -25
- package/dist/cjs/checkpointer/internal/pending-writes.js +241 -0
- package/dist/{checkpointer → cjs/checkpointer}/internal/read.d.ts +15 -10
- package/dist/cjs/checkpointer/internal/read.js +132 -0
- package/dist/{checkpointer → cjs/checkpointer}/internal/rows.d.ts +94 -21
- package/dist/cjs/checkpointer/internal/rows.js +356 -0
- package/dist/{checkpointer → cjs/checkpointer}/internal/setup.d.ts +13 -20
- package/dist/cjs/checkpointer/internal/setup.js +25 -0
- package/dist/{checkpointer → cjs/checkpointer}/saver.d.ts +72 -36
- package/dist/cjs/checkpointer/saver.js +56 -0
- package/dist/{checkpointer → cjs/checkpointer}/types.d.ts +1 -1
- package/dist/cjs/checkpointer/types.js +2 -0
- package/dist/{factory → cjs/factory}/factory.d.ts +25 -20
- package/dist/cjs/factory/factory.js +137 -0
- package/dist/{factory → cjs/factory}/types.d.ts +12 -12
- package/dist/cjs/factory/types.js +2 -0
- package/dist/{history → cjs/history}/actions/add-messages.d.ts +18 -10
- package/dist/cjs/history/actions/add-messages.js +17 -0
- package/dist/{history → cjs/history}/actions/clear.d.ts +1 -1
- package/dist/cjs/history/actions/clear.js +29 -0
- package/dist/{history → cjs/history}/actions/get-messages.d.ts +11 -9
- package/dist/cjs/history/actions/get-messages.js +58 -0
- package/dist/{history → cjs/history}/actions/list-sessions.d.ts +3 -3
- package/dist/cjs/history/actions/list-sessions.js +67 -0
- package/dist/{history → cjs/history}/actions/reconcile-count.d.ts +13 -9
- package/dist/cjs/history/actions/reconcile-count.js +8 -0
- package/dist/{history → cjs/history}/chat-message-history.d.ts +62 -30
- package/dist/cjs/history/chat-message-history.js +61 -0
- package/dist/{history → cjs/history}/internal/append.d.ts +64 -32
- package/dist/cjs/history/internal/append.js +267 -0
- package/dist/{history → cjs/history}/internal/message-read.d.ts +3 -3
- package/dist/cjs/history/internal/message-read.js +93 -0
- package/dist/{history → cjs/history}/internal/parse.d.ts +2 -2
- package/dist/cjs/history/internal/parse.js +113 -0
- package/dist/{history → cjs/history}/internal/rows.d.ts +11 -10
- package/dist/cjs/history/internal/rows.js +96 -0
- package/dist/{history → cjs/history}/internal/session.d.ts +41 -22
- package/dist/cjs/history/internal/session.js +296 -0
- package/dist/{history → cjs/history}/internal/setup.d.ts +2 -2
- package/dist/cjs/history/internal/setup.js +60 -0
- package/dist/{history → cjs/history}/session-adapter.d.ts +0 -6
- package/dist/cjs/history/session-adapter.js +38 -0
- package/dist/{history → cjs/history}/types.d.ts +18 -15
- package/dist/cjs/history/types.js +2 -0
- package/dist/{index.d.ts → cjs/index.d.ts} +27 -27
- package/dist/cjs/index.js +25 -0
- package/dist/cjs/package.json +1 -0
- package/dist/{shared → cjs/shared}/adapter.d.ts +27 -16
- package/dist/cjs/shared/adapter.js +70 -0
- package/dist/cjs/shared/clock.js +14 -0
- package/dist/{shared → cjs/shared}/codec/codec.d.ts +37 -20
- package/dist/cjs/shared/codec/codec.js +162 -0
- package/dist/{shared → cjs/shared}/codec/compression.d.ts +9 -4
- package/dist/cjs/shared/codec/compression.js +45 -0
- package/dist/cjs/shared/codec/json-serde.js +58 -0
- package/dist/{shared → cjs/shared}/codec/s3/client-types.d.ts +2 -1
- package/dist/cjs/shared/codec/s3/client-types.js +6 -0
- package/dist/{shared → cjs/shared}/codec/s3/client.d.ts +25 -7
- package/dist/cjs/shared/codec/s3/client.js +78 -0
- package/dist/{shared → cjs/shared}/codec/s3/config.d.ts +12 -7
- package/dist/cjs/shared/codec/s3/config.js +92 -0
- package/dist/{shared → cjs/shared}/codec/s3/lifecycle.d.ts +71 -17
- package/dist/cjs/shared/codec/s3/lifecycle.js +223 -0
- package/dist/{shared → cjs/shared}/codec/s3/offloader.d.ts +42 -29
- package/dist/cjs/shared/codec/s3/offloader.js +289 -0
- package/dist/cjs/shared/concurrency.js +31 -0
- package/dist/{shared → cjs/shared}/dynamodb/abort.d.ts +2 -2
- package/dist/cjs/shared/dynamodb/abort.js +16 -0
- package/dist/{shared → cjs/shared}/dynamodb/batch-write.d.ts +2 -2
- package/dist/cjs/shared/dynamodb/batch-write.js +79 -0
- package/dist/cjs/shared/dynamodb/cancellation.js +37 -0
- package/dist/{shared → cjs/shared}/dynamodb/client.d.ts +24 -22
- package/dist/cjs/shared/dynamodb/client.js +40 -0
- package/dist/{shared → cjs/shared}/dynamodb/idempotent-write.d.ts +64 -19
- package/dist/cjs/shared/dynamodb/idempotent-write.js +173 -0
- package/dist/{shared → cjs/shared}/dynamodb/paginate.d.ts +2 -2
- package/dist/cjs/shared/dynamodb/paginate.js +90 -0
- package/dist/{shared → cjs/shared}/dynamodb/partition-delete.d.ts +6 -6
- package/dist/cjs/shared/dynamodb/partition-delete.js +177 -0
- package/dist/{shared → cjs/shared}/dynamodb/recency-index.d.ts +27 -15
- package/dist/cjs/shared/dynamodb/recency-index.js +146 -0
- package/dist/{shared → cjs/shared}/dynamodb/retry.d.ts +37 -6
- 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/{shared → cjs/shared}/dynamodb/table-schema.d.ts +27 -18
- package/dist/cjs/shared/dynamodb/table-schema.js +52 -0
- package/dist/{shared → cjs/shared}/errors/base-error.d.ts +42 -7
- package/dist/cjs/shared/errors/base-error.js +73 -0
- package/dist/{shared → cjs/shared}/errors/boundary.d.ts +29 -14
- 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/{shared → cjs/shared}/errors/error-code.d.ts +17 -10
- package/dist/cjs/shared/errors/error-code.js +27 -0
- package/dist/{shared → cjs/shared}/errors/errors.d.ts +75 -9
- package/dist/cjs/shared/errors/errors.js +123 -0
- package/dist/cjs/shared/logging/logger.js +30 -0
- package/dist/{shared → cjs/shared}/logging/redaction.d.ts +8 -4
- package/dist/cjs/shared/logging/redaction.js +145 -0
- package/dist/{shared → cjs/shared}/logging/secret-patterns.d.ts +30 -7
- package/dist/cjs/shared/logging/secret-patterns.js +93 -0
- package/dist/cjs/shared/logging/truncate.js +31 -0
- package/dist/{shared → cjs/shared}/options.d.ts +27 -11
- package/dist/cjs/shared/options.js +2 -0
- package/dist/cjs/shared/ulid.js +83 -0
- package/dist/{shared → cjs/shared}/validation/collaborators.d.ts +21 -2
- package/dist/cjs/shared/validation/collaborators.js +79 -0
- package/dist/{shared → cjs/shared}/validation/option-shape.d.ts +7 -5
- package/dist/cjs/shared/validation/option-shape.js +31 -0
- package/dist/{shared → cjs/shared}/validation/options.d.ts +4 -4
- package/dist/cjs/shared/validation/options.js +166 -0
- package/dist/cjs/shared/validation/primitives.js +114 -0
- package/dist/{shared → cjs/shared}/validation/ttl.d.ts +26 -9
- package/dist/cjs/shared/validation/ttl.js +52 -0
- package/dist/{store → cjs/store}/actions/list-namespaces.d.ts +5 -5
- package/dist/cjs/store/actions/list-namespaces.js +92 -0
- package/dist/{store → cjs/store}/actions/put.d.ts +11 -4
- package/dist/cjs/store/actions/put.js +49 -0
- package/dist/{store → cjs/store}/actions/reconcile-vector-index.d.ts +5 -5
- package/dist/cjs/store/actions/reconcile-vector-index.js +13 -0
- package/dist/{store → cjs/store}/actions/search.d.ts +2 -2
- 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/{store → cjs/store}/internal/filter.d.ts +3 -3
- 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/{store → cjs/store}/internal/item-write.d.ts +72 -32
- package/dist/cjs/store/internal/item-write.js +181 -0
- package/dist/{store → cjs/store}/internal/parse.d.ts +15 -10
- package/dist/cjs/store/internal/parse.js +180 -0
- package/dist/{store → cjs/store}/internal/rows.d.ts +38 -34
- package/dist/cjs/store/internal/rows.js +166 -0
- package/dist/{store → cjs/store}/internal/semantic-search.d.ts +2 -2
- package/dist/cjs/store/internal/semantic-search.js +211 -0
- package/dist/{store → cjs/store}/internal/setup.d.ts +10 -15
- package/dist/cjs/store/internal/setup.js +103 -0
- package/dist/{store → cjs/store}/internal/table-search.d.ts +5 -5
- package/dist/cjs/store/internal/table-search.js +123 -0
- package/dist/{store → cjs/store}/internal/vector-index.d.ts +26 -15
- package/dist/cjs/store/internal/vector-index.js +269 -0
- package/dist/{store → cjs/store}/store.d.ts +82 -39
- package/dist/cjs/store/store.js +97 -0
- package/dist/{store → cjs/store}/types.d.ts +25 -10
- package/dist/cjs/store/types.js +2 -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/{checkpointer/actions/delete-thread.js → esm/checkpointer/actions/delete-thread.d.ts} +4 -26
- package/dist/esm/checkpointer/actions/delete-thread.js +23 -0
- package/dist/{checkpointer/actions/get-tuple.js → esm/checkpointer/actions/get-tuple.d.ts} +7 -24
- 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/{checkpointer/actions/put-writes.js → esm/checkpointer/actions/put-writes.d.ts} +10 -37
- 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/{checkpointer/internal/listing.js → esm/checkpointer/internal/listing.d.ts} +22 -118
- 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/{checkpointer/saver.js → esm/checkpointer/saver.d.ts} +84 -87
- 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/{history/actions/add-messages.js → esm/history/actions/add-messages.d.ts} +20 -26
- package/dist/esm/history/actions/add-messages.js +14 -0
- package/dist/{history/actions/clear.js → esm/history/actions/clear.d.ts} +4 -35
- 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/{history/actions/reconcile-count.js → esm/history/actions/reconcile-count.d.ts} +14 -16
- package/dist/esm/history/actions/reconcile-count.js +5 -0
- package/dist/{history/chat-message-history.js → esm/history/chat-message-history.d.ts} +76 -87
- 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/{history/internal/rows.js → esm/history/internal/rows.d.ts} +58 -112
- 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/{history/session-adapter.js → esm/history/session-adapter.d.ts} +25 -39
- 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/{shared/clock.js → esm/shared/clock.d.ts} +3 -14
- 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/{shared/codec/s3/config.js → esm/shared/codec/s3/config.d.ts} +45 -93
- 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/{shared/concurrency.js → esm/shared/concurrency.d.ts} +2 -37
- package/dist/esm/shared/concurrency.js +27 -0
- package/dist/{shared/dynamodb/abort.js → esm/shared/dynamodb/abort.d.ts} +4 -16
- 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/{shared/dynamodb/cancellation.js → esm/shared/dynamodb/cancellation.d.ts} +25 -53
- package/dist/esm/shared/dynamodb/cancellation.js +30 -0
- package/dist/{shared/dynamodb/client.js → esm/shared/dynamodb/client.d.ts} +74 -64
- package/dist/esm/shared/dynamodb/client.js +35 -0
- package/dist/{shared/dynamodb/idempotent-write.js → esm/shared/dynamodb/idempotent-write.d.ts} +172 -169
- 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/{shared/dynamodb/table-schema.js → esm/shared/dynamodb/table-schema.d.ts} +57 -67
- 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/{shared/errors/error-code.js → esm/shared/errors/error-code.d.ts} +39 -43
- package/dist/esm/shared/errors/error-code.js +24 -0
- package/dist/{shared/errors/errors.js → esm/shared/errors/errors.d.ts} +92 -98
- package/dist/esm/shared/errors/errors.js +110 -0
- package/dist/{shared/logging/logger.js → esm/shared/logging/logger.d.ts} +22 -52
- 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/{shared/logging/secret-patterns.js → esm/shared/logging/secret-patterns.d.ts} +46 -87
- package/dist/esm/shared/logging/secret-patterns.js +83 -0
- package/dist/{shared/logging/truncate.js → esm/shared/logging/truncate.d.ts} +6 -40
- 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/{shared/ulid.js → esm/shared/ulid.d.ts} +4 -84
- package/dist/esm/shared/ulid.js +77 -0
- package/dist/{shared/validation/collaborators.js → esm/shared/validation/collaborators.d.ts} +37 -65
- package/dist/esm/shared/validation/collaborators.js +70 -0
- package/dist/{shared/validation/option-shape.js → esm/shared/validation/option-shape.d.ts} +14 -36
- 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/{shared/validation/primitives.js → esm/shared/validation/primitives.d.ts} +30 -125
- 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/{store/actions/reconcile-vector-index.js → esm/store/actions/reconcile-vector-index.d.ts} +8 -16
- 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/{store/internal/rows.js → esm/store/internal/rows.d.ts} +111 -199
- 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/{store/store.js → esm/store/store.d.ts} +99 -133
- 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 +50 -44
- package/dist/backfill/backfill.js +0 -393
- package/dist/checkpointer/actions/list.js +0 -142
- package/dist/checkpointer/actions/put.js +0 -195
- package/dist/checkpointer/internal/delta-history.js +0 -252
- package/dist/checkpointer/internal/parse.js +0 -372
- package/dist/checkpointer/internal/pending-writes.js +0 -588
- package/dist/checkpointer/internal/read.js +0 -264
- package/dist/checkpointer/internal/rows.js +0 -834
- package/dist/checkpointer/internal/setup.js +0 -72
- package/dist/checkpointer/types.js +0 -12
- package/dist/factory/factory.js +0 -266
- package/dist/factory/types.js +0 -10
- package/dist/history/actions/get-messages.js +0 -141
- package/dist/history/actions/list-sessions.js +0 -156
- package/dist/history/internal/append.js +0 -500
- package/dist/history/internal/message-read.js +0 -204
- package/dist/history/internal/parse.js +0 -252
- package/dist/history/internal/session.js +0 -628
- package/dist/history/internal/setup.js +0 -106
- package/dist/history/types.js +0 -12
- package/dist/index.js +0 -51
- package/dist/shared/adapter.js +0 -143
- package/dist/shared/codec/codec.js +0 -441
- package/dist/shared/codec/compression.js +0 -89
- package/dist/shared/codec/json-serde.js +0 -191
- package/dist/shared/codec/s3/client-types.js +0 -26
- package/dist/shared/codec/s3/client.js +0 -97
- package/dist/shared/codec/s3/lifecycle.js +0 -355
- package/dist/shared/codec/s3/offloader.js +0 -658
- package/dist/shared/dynamodb/batch-write.js +0 -173
- package/dist/shared/dynamodb/paginate.js +0 -188
- package/dist/shared/dynamodb/partition-delete.js +0 -340
- package/dist/shared/dynamodb/recency-index.js +0 -377
- package/dist/shared/dynamodb/retry.js +0 -463
- package/dist/shared/errors/base-error.js +0 -174
- package/dist/shared/errors/boundary.js +0 -143
- package/dist/shared/errors/classify.d.ts +0 -97
- package/dist/shared/errors/classify.js +0 -257
- package/dist/shared/logging/redaction.js +0 -316
- package/dist/shared/options.js +0 -11
- package/dist/shared/validation/options.js +0 -328
- package/dist/shared/validation/ttl.js +0 -132
- package/dist/store/actions/list-namespaces.js +0 -197
- package/dist/store/actions/put.js +0 -78
- package/dist/store/actions/search.js +0 -66
- package/dist/store/internal/batch-plan.d.ts +0 -26
- package/dist/store/internal/batch-plan.js +0 -109
- package/dist/store/internal/filter.js +0 -137
- package/dist/store/internal/get-item.d.ts +0 -45
- package/dist/store/internal/get-item.js +0 -115
- package/dist/store/internal/item-write.js +0 -463
- package/dist/store/internal/parse.js +0 -350
- package/dist/store/internal/semantic-search.js +0 -389
- package/dist/store/internal/setup.js +0 -223
- package/dist/store/internal/table-search.js +0 -213
- package/dist/store/internal/vector-index.js +0 -546
- package/dist/store/types.js +0 -15
- package/dist/store/vector-backend.js +0 -17
- /package/dist/{shared → cjs/shared}/clock.d.ts +0 -0
- /package/dist/{shared → cjs/shared}/codec/json-serde.d.ts +0 -0
- /package/dist/{shared → cjs/shared}/concurrency.d.ts +0 -0
- /package/dist/{shared → cjs/shared}/dynamodb/cancellation.d.ts +0 -0
- /package/dist/{shared → cjs/shared}/logging/logger.d.ts +0 -0
- /package/dist/{shared → cjs/shared}/logging/truncate.d.ts +0 -0
- /package/dist/{shared → cjs/shared}/ulid.d.ts +0 -0
- /package/dist/{shared → cjs/shared}/validation/primitives.d.ts +0 -0
- /package/dist/{store → cjs/store}/vector-backend.d.ts +0 -0
|
@@ -10,10 +10,10 @@
|
|
|
10
10
|
* backend.
|
|
11
11
|
*/
|
|
12
12
|
import type { IndexConfig, SearchItem } from '@langchain/langgraph-checkpoint';
|
|
13
|
-
import type { VectorReconcileResult } from '../types';
|
|
14
|
-
import type { VectorBackend, VectorMatch, VectorRef, VectorScoreDirection } from '../vector-backend';
|
|
15
|
-
import { type Namespace, type ParsedPut, type ParsedSearch, type StoreAddress } from './parse';
|
|
16
|
-
import type { StoreContext } from './setup';
|
|
13
|
+
import type { VectorReconcileResult } from '../types.js';
|
|
14
|
+
import type { VectorBackend, VectorMatch, VectorRef, VectorScoreDirection } from '../vector-backend.js';
|
|
15
|
+
import { type Namespace, type ParsedPut, type ParsedSearch, type StoreAddress } from './parse.js';
|
|
16
|
+
import type { StoreContext } from './setup.js';
|
|
17
17
|
/** A store context whose vector copy is configured: an embeddings index and a backend. */
|
|
18
18
|
export type BackendContext = StoreContext & {
|
|
19
19
|
readonly index: IndexConfig;
|
|
@@ -71,8 +71,9 @@ export declare function syncItemVector(context: StoreContext, address: StoreAddr
|
|
|
71
71
|
* hold a row *now*", which a racing put that recreated it and a
|
|
72
72
|
* compare-and-swap that left it alone both answer the same way, and which costs
|
|
73
73
|
* a point read of this library's own table rather than anything the backend has
|
|
74
|
-
* to offer. The reconciler asks the same question before pruning a
|
|
75
|
-
*
|
|
74
|
+
* to offer. The reconciler asks the same question before pruning a candidate
|
|
75
|
+
* it never saw; one it did see is pinned to the revision the snapshot read
|
|
76
|
+
* instead. Either way, the delete path and the reconciler are equally careful.
|
|
76
77
|
*
|
|
77
78
|
* A read that itself fails answers "not confirmed" and keeps the vector: a
|
|
78
79
|
* stale vector for a deleted item, which `reconcileVectorIndex` removes, rather
|
|
@@ -93,6 +94,8 @@ export interface ReconcileTarget {
|
|
|
93
94
|
namespace: string[];
|
|
94
95
|
key: string;
|
|
95
96
|
embedding: number[] | undefined;
|
|
97
|
+
/** The revision the snapshot read, which a later put replaces; absent on a row written before revisions. */
|
|
98
|
+
rev?: string;
|
|
96
99
|
}
|
|
97
100
|
/**
|
|
98
101
|
* Enumerate the live (unexpired) items under `prefix` and recompute their
|
|
@@ -109,8 +112,9 @@ export interface ReconcileTarget {
|
|
|
109
112
|
* Throws: whatever the reads, the decodes and the embeddings model throw; a
|
|
110
113
|
* failed embedding rejects the whole reconcile, because a skipped item would
|
|
111
114
|
* leave the live set and {@link selectOrphans} would prune its still-valid
|
|
112
|
-
* vector. `RESULT_TRUNCATED` when `maxScanItems`
|
|
113
|
-
* remain — reconciling from a partial view would prune
|
|
115
|
+
* vector. `RESULT_TRUNCATED` when `maxScanItems` or `maxIterations` is
|
|
116
|
+
* reached while rows remain — reconciling from a partial view would prune
|
|
117
|
+
* live vectors.
|
|
114
118
|
*
|
|
115
119
|
* Guarantees: rows are decoded in bounded batches, so a namespace of offloaded
|
|
116
120
|
* items costs neither one round-trip at a time nor every payload in memory at
|
|
@@ -154,11 +158,12 @@ export declare function selectOrphans(backendRefs: VectorRef[], live: ReconcileT
|
|
|
154
158
|
*
|
|
155
159
|
* Throws: whatever the backend and the confirmation read throw.
|
|
156
160
|
*
|
|
157
|
-
* Guarantees: a vector is deleted only on evidence that its item is gone —
|
|
158
|
-
*
|
|
159
|
-
*
|
|
160
|
-
*
|
|
161
|
-
*
|
|
161
|
+
* Guarantees: a vector is deleted only on evidence that its item is gone — a
|
|
162
|
+
* fresh strongly-consistent read finds the item still at the revision the
|
|
163
|
+
* snapshot read — when that snapshot yielded it no embedding — or finds no
|
|
164
|
+
* row at all, or one past its `ttl` that DynamoDB has yet to sweep. An item
|
|
165
|
+
* written between the snapshot and the listing looks orphaned and is kept, so
|
|
166
|
+
* reconciling never drops a just-written item out of semantic search.
|
|
162
167
|
*/
|
|
163
168
|
export declare function pruneOrphans(context: StoreContext, backend: VectorBackend, prefix: Namespace, live: ReconcileTarget[]): Promise<number>;
|
|
164
169
|
/**
|
|
@@ -184,8 +189,14 @@ export declare function reconcileVectors(context: BackendContext, prefix: Namesp
|
|
|
184
189
|
* stored, so a filter is never answered from a stale vector.
|
|
185
190
|
*
|
|
186
191
|
* Returns: the page's items in the backend's order, each carrying the relevance
|
|
187
|
-
* score for its vector
|
|
188
|
-
*
|
|
192
|
+
* score for its vector — once each: a backend holding several vectors for one
|
|
193
|
+
* item (one per passage, say) can return it more than once in a round, and
|
|
194
|
+
* the item is answered at the first score it gave, as the reference store and
|
|
195
|
+
* {@link rankInMemory} answer an item by its best-matching vector. Fewer than
|
|
196
|
+
* `limit` items means the backend has no more matches under the prefix, not
|
|
197
|
+
* that the page was cut short. An item the backend holds no vector for — put
|
|
198
|
+
* with `index: false`, or with no indexable text — is not a match here, where
|
|
199
|
+
* the in-DynamoDB ranker lists it last with no score.
|
|
189
200
|
*
|
|
190
201
|
* Throws: `VALIDATION` naming `index.dims` when the query embeds to a
|
|
191
202
|
* different width than the index declares, and naming `maxSearchCandidates`
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.hasVectorBackend = hasVectorBackend;
|
|
4
|
+
exports.itemVector = itemVector;
|
|
5
|
+
exports.syncItemVector = syncItemVector;
|
|
6
|
+
exports.dropVectorWhenGone = dropVectorWhenGone;
|
|
7
|
+
exports.collectReconcileTargets = collectReconcileTargets;
|
|
8
|
+
exports.pushEmbeddings = pushEmbeddings;
|
|
9
|
+
exports.selectOrphans = selectOrphans;
|
|
10
|
+
exports.pruneOrphans = pruneOrphans;
|
|
11
|
+
exports.reconcileVectors = reconcileVectors;
|
|
12
|
+
exports.searchViaBackend = searchViaBackend;
|
|
13
|
+
exports.toRelevanceScores = toRelevanceScores;
|
|
14
|
+
const clock_js_1 = require("../../shared/clock.js");
|
|
15
|
+
const concurrency_js_1 = require("../../shared/concurrency.js");
|
|
16
|
+
const idempotent_write_js_1 = require("../../shared/dynamodb/idempotent-write.js");
|
|
17
|
+
const paginate_js_1 = require("../../shared/dynamodb/paginate.js");
|
|
18
|
+
const retry_js_1 = require("../../shared/dynamodb/retry.js");
|
|
19
|
+
const table_schema_js_1 = require("../../shared/dynamodb/table-schema.js");
|
|
20
|
+
const base_error_js_1 = require("../../shared/errors/base-error.js");
|
|
21
|
+
const errors_js_1 = require("../../shared/errors/errors.js");
|
|
22
|
+
const truncate_js_1 = require("../../shared/logging/truncate.js");
|
|
23
|
+
const filter_js_1 = require("./filter.js");
|
|
24
|
+
const get_item_js_1 = require("./get-item.js");
|
|
25
|
+
const parse_js_1 = require("./parse.js");
|
|
26
|
+
const rows_js_1 = require("./rows.js");
|
|
27
|
+
const semantic_search_js_1 = require("./semantic-search.js");
|
|
28
|
+
function hasVectorBackend(context) {
|
|
29
|
+
return context.index !== undefined && context.vectorBackend !== undefined;
|
|
30
|
+
}
|
|
31
|
+
async function itemVector(context, op) {
|
|
32
|
+
if (!context.vectorBackend || op.index === false)
|
|
33
|
+
return undefined;
|
|
34
|
+
return (0, semantic_search_js_1.embedValue)(context, op.value, op.index);
|
|
35
|
+
}
|
|
36
|
+
async function syncItemVector(context, address, embedding) {
|
|
37
|
+
const backend = context.vectorBackend;
|
|
38
|
+
if (backend === undefined)
|
|
39
|
+
return;
|
|
40
|
+
try {
|
|
41
|
+
if (embedding)
|
|
42
|
+
await backend.upsert(address.namespace, address.key, embedding);
|
|
43
|
+
else
|
|
44
|
+
await backend.delete(address.namespace, address.key);
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
context.logger.warn('store vector-index sync failed; reconcileVectorIndex will repair', {
|
|
48
|
+
namespace: address.namespace,
|
|
49
|
+
key: address.key,
|
|
50
|
+
operation: embedding ? 'upsert' : 'delete',
|
|
51
|
+
reason: (0, truncate_js_1.truncateForLog)((0, base_error_js_1.failureLabel)(error)),
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
async function dropVectorWhenGone(context, address) {
|
|
56
|
+
if (context.vectorBackend === undefined)
|
|
57
|
+
return;
|
|
58
|
+
const key = (0, rows_js_1.itemRowKey)(address);
|
|
59
|
+
if (!(await (0, idempotent_write_js_1.isRowAbsent)(context, key))) {
|
|
60
|
+
context.logger.info('store.delete: kept a vector whose item was not confirmed gone', {
|
|
61
|
+
namespace: address.namespace,
|
|
62
|
+
key: address.key,
|
|
63
|
+
});
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
await syncItemVector(context, address, undefined);
|
|
67
|
+
}
|
|
68
|
+
function refIdentity(namespace, key) {
|
|
69
|
+
return JSON.stringify([...namespace, key]);
|
|
70
|
+
}
|
|
71
|
+
async function drainPending(context, pending, live, signal) {
|
|
72
|
+
if (pending.length === 0)
|
|
73
|
+
return;
|
|
74
|
+
const batch = pending.splice(0, pending.length);
|
|
75
|
+
const reads = await (0, concurrency_js_1.mapWithConcurrency)(batch, context.readConcurrency ?? concurrency_js_1.DEFAULT_READ_CONCURRENCY, (record) => (0, get_item_js_1.readCandidate)(context, record, signal));
|
|
76
|
+
for (const read of reads) {
|
|
77
|
+
if (read === undefined)
|
|
78
|
+
continue;
|
|
79
|
+
live.push({
|
|
80
|
+
namespace: read.row.namespace,
|
|
81
|
+
key: read.row.key,
|
|
82
|
+
rev: read.row.rev,
|
|
83
|
+
value: read.item.value,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
async function collectReconcileTargets(context, prefix, signal) {
|
|
88
|
+
const now = (0, clock_js_1.nowSeconds)();
|
|
89
|
+
const live = [];
|
|
90
|
+
const pending = [];
|
|
91
|
+
const batchLimit = context.readConcurrency ?? concurrency_js_1.DEFAULT_READ_CONCURRENCY;
|
|
92
|
+
const source = (0, paginate_js_1.paginateQuery)({
|
|
93
|
+
retry: (0, retry_js_1.retryFor)(context, signal),
|
|
94
|
+
signal,
|
|
95
|
+
client: context.client,
|
|
96
|
+
params: (0, table_schema_js_1.withoutExpired)((0, rows_js_1.scopedQuery)(context.tableName, prefix), now),
|
|
97
|
+
maxItems: context.maxScanItems,
|
|
98
|
+
maxIterations: context.maxIterations,
|
|
99
|
+
});
|
|
100
|
+
for await (const raw of source) {
|
|
101
|
+
const record = (0, rows_js_1.parseWholeStoreRow)(raw);
|
|
102
|
+
if (!record) {
|
|
103
|
+
context.logger.warn('reconcileVectorIndex: skipped a row that is not a store item', {
|
|
104
|
+
sortKey: (0, truncate_js_1.truncateForLog)(raw.SK),
|
|
105
|
+
});
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
if ((0, table_schema_js_1.isExpiredRow)(record, now) || !(0, rows_js_1.namespaceMatchesPrefix)(record.namespace, prefix))
|
|
109
|
+
continue;
|
|
110
|
+
pending.push(record);
|
|
111
|
+
if (pending.length >= batchLimit)
|
|
112
|
+
await drainPending(context, pending, live, signal);
|
|
113
|
+
}
|
|
114
|
+
await drainPending(context, pending, live, signal);
|
|
115
|
+
const embeddings = await (0, semantic_search_js_1.embedValues)(context, live.map((entry) => entry.value));
|
|
116
|
+
return live.map((entry, i) => ({
|
|
117
|
+
namespace: entry.namespace,
|
|
118
|
+
key: entry.key,
|
|
119
|
+
embedding: embeddings[i],
|
|
120
|
+
rev: entry.rev,
|
|
121
|
+
}));
|
|
122
|
+
}
|
|
123
|
+
async function pushEmbeddings(backend, targets) {
|
|
124
|
+
let upserted = 0;
|
|
125
|
+
for (const target of targets) {
|
|
126
|
+
if (!target.embedding)
|
|
127
|
+
continue;
|
|
128
|
+
await backend.upsert(target.namespace, target.key, target.embedding);
|
|
129
|
+
upserted += 1;
|
|
130
|
+
}
|
|
131
|
+
return upserted;
|
|
132
|
+
}
|
|
133
|
+
function selectOrphans(backendRefs, live) {
|
|
134
|
+
const liveKeys = new Set(live
|
|
135
|
+
.filter((target) => target.embedding !== undefined)
|
|
136
|
+
.map((target) => refIdentity(target.namespace, target.key)));
|
|
137
|
+
return backendRefs.filter((ref) => !liveKeys.has(refIdentity(ref.namespace, ref.key)));
|
|
138
|
+
}
|
|
139
|
+
async function confirmedGone(context, ref) {
|
|
140
|
+
const row = await (0, idempotent_write_js_1.readRow)(context, {
|
|
141
|
+
key: (0, rows_js_1.itemRowKey)(ref),
|
|
142
|
+
attribute: table_schema_js_1.PARTITION_KEY_ATTRIBUTE,
|
|
143
|
+
also: ['ttl'],
|
|
144
|
+
});
|
|
145
|
+
return row === undefined || (0, table_schema_js_1.isExpiredRow)(row, (0, clock_js_1.nowSeconds)());
|
|
146
|
+
}
|
|
147
|
+
async function unchangedSinceSnapshot(context, ref, rev) {
|
|
148
|
+
const row = await (0, idempotent_write_js_1.readRow)(context, { key: (0, rows_js_1.itemRowKey)(ref), attribute: rows_js_1.REVISION_ATTRIBUTE });
|
|
149
|
+
return row === undefined || row[rows_js_1.REVISION_ATTRIBUTE] === rev;
|
|
150
|
+
}
|
|
151
|
+
async function pruneOrphans(context, backend, prefix, live) {
|
|
152
|
+
if (!backend.listKeys) {
|
|
153
|
+
context.logger.info('reconcileVectorIndex prune skipped: backend has no listKeys', {
|
|
154
|
+
prefix: (0, truncate_js_1.truncateLabelsForLog)(prefix),
|
|
155
|
+
});
|
|
156
|
+
return 0;
|
|
157
|
+
}
|
|
158
|
+
const candidates = selectOrphans(await backend.listKeys(prefix), live);
|
|
159
|
+
const snapshot = new Map(live.map((target) => [refIdentity(target.namespace, target.key), target.rev]));
|
|
160
|
+
let pruned = 0;
|
|
161
|
+
for (const ref of candidates) {
|
|
162
|
+
const identity = refIdentity(ref.namespace, ref.key);
|
|
163
|
+
const stale = snapshot.has(identity)
|
|
164
|
+
? await unchangedSinceSnapshot(context, ref, snapshot.get(identity))
|
|
165
|
+
: await confirmedGone(context, ref);
|
|
166
|
+
if (!stale) {
|
|
167
|
+
context.logger.info('reconcileVectorIndex: kept a vector whose item reappeared', {
|
|
168
|
+
namespace: (0, truncate_js_1.truncateLabelsForLog)(ref.namespace),
|
|
169
|
+
key: (0, truncate_js_1.truncateForLog)(ref.key),
|
|
170
|
+
});
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
await backend.delete(ref.namespace, ref.key);
|
|
174
|
+
pruned += 1;
|
|
175
|
+
}
|
|
176
|
+
return pruned;
|
|
177
|
+
}
|
|
178
|
+
async function reconcileVectors(context, prefix, signal) {
|
|
179
|
+
const targets = await collectReconcileTargets(context, prefix, signal);
|
|
180
|
+
const upserted = await pushEmbeddings(context.vectorBackend, targets);
|
|
181
|
+
const pruned = await pruneOrphans(context, context.vectorBackend, prefix, targets);
|
|
182
|
+
return { upserted, pruned };
|
|
183
|
+
}
|
|
184
|
+
function warnOnNonDescendingScores(context, matches, namespacePrefix) {
|
|
185
|
+
const descending = matches.every((match, position) => position === 0 || matches[position - 1].score >= match.score);
|
|
186
|
+
if (descending)
|
|
187
|
+
return;
|
|
188
|
+
context.logger.warn('search: vectorBackend returned ascending scores; VectorMatch.score must be a relevance ' +
|
|
189
|
+
'(higher is better), not a distance — results are forwarded in the order the backend gave', { namespacePrefix: (0, truncate_js_1.truncateLabelsForLog)(namespacePrefix) });
|
|
190
|
+
}
|
|
191
|
+
function addressOf(context, match) {
|
|
192
|
+
try {
|
|
193
|
+
return (0, parse_js_1.parseStoreAddress)(match.namespace, match.key);
|
|
194
|
+
}
|
|
195
|
+
catch (error) {
|
|
196
|
+
context.logger.warn('search: skipped an unusable vectorBackend match', {
|
|
197
|
+
namespace: (0, truncate_js_1.truncateLabelsForLog)(match.namespace),
|
|
198
|
+
key: (0, truncate_js_1.truncateForLog)(match.key),
|
|
199
|
+
reason: (0, truncate_js_1.truncateForLog)((0, base_error_js_1.failureLabel)(error)),
|
|
200
|
+
});
|
|
201
|
+
return undefined;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
async function fetchMatch(context, match, signal) {
|
|
205
|
+
const address = addressOf(context, match);
|
|
206
|
+
if (address === undefined)
|
|
207
|
+
return null;
|
|
208
|
+
return (0, get_item_js_1.getItem)(context, address, signal);
|
|
209
|
+
}
|
|
210
|
+
function matchIdentity(match) {
|
|
211
|
+
return JSON.stringify([match.namespace, match.key]);
|
|
212
|
+
}
|
|
213
|
+
async function fetchUnseen(context, scoped, fetched, signal) {
|
|
214
|
+
const unseen = new Map();
|
|
215
|
+
for (const match of scoped) {
|
|
216
|
+
const identity = matchIdentity(match);
|
|
217
|
+
if (!fetched.has(identity))
|
|
218
|
+
unseen.set(identity, match);
|
|
219
|
+
}
|
|
220
|
+
const pending = [...unseen.values()];
|
|
221
|
+
const items = await (0, concurrency_js_1.mapWithConcurrency)(pending, context.readConcurrency ?? concurrency_js_1.DEFAULT_READ_CONCURRENCY, (match) => fetchMatch(context, match, signal));
|
|
222
|
+
pending.forEach((match, index) => fetched.set(matchIdentity(match), items[index]));
|
|
223
|
+
}
|
|
224
|
+
async function searchViaBackend(context, search, signal) {
|
|
225
|
+
const backend = context.vectorBackend;
|
|
226
|
+
const index = context.index;
|
|
227
|
+
const { offset, limit } = search;
|
|
228
|
+
const need = offset + limit;
|
|
229
|
+
if (need > context.maxSearchCandidates) {
|
|
230
|
+
throw (0, errors_js_1.validationError)(`Requested page (offset ${offset} + limit ${limit} = ${need}) exceeds maxSearchCandidates ` +
|
|
231
|
+
`(${context.maxSearchCandidates}); narrow the page or raise maxSearchCandidates`, 'maxSearchCandidates');
|
|
232
|
+
}
|
|
233
|
+
const queryVector = await index.embeddings.embedQuery(search.query);
|
|
234
|
+
(0, semantic_search_js_1.assertVectorDims)(index, queryVector, 'query');
|
|
235
|
+
let topK = Math.min(need, context.maxSearchCandidates);
|
|
236
|
+
let results;
|
|
237
|
+
const fetched = new Map();
|
|
238
|
+
for (;;) {
|
|
239
|
+
const matches = toRelevanceScores(await backend.query(search.namespacePrefix, queryVector, topK), context.vectorScoreDirection);
|
|
240
|
+
warnOnNonDescendingScores(context, matches, search.namespacePrefix);
|
|
241
|
+
const scoped = matches.filter((match) => (0, rows_js_1.namespaceMatchesPrefix)(match.namespace, search.namespacePrefix));
|
|
242
|
+
await fetchUnseen(context, scoped, fetched, signal);
|
|
243
|
+
results = [];
|
|
244
|
+
const answered = new Set();
|
|
245
|
+
for (const match of scoped) {
|
|
246
|
+
const identity = matchIdentity(match);
|
|
247
|
+
const item = fetched.get(identity);
|
|
248
|
+
if (!item || answered.has(identity) || !(0, filter_js_1.passesFilter)(item, search.filter))
|
|
249
|
+
continue;
|
|
250
|
+
answered.add(identity);
|
|
251
|
+
results.push({ ...item, score: match.score });
|
|
252
|
+
}
|
|
253
|
+
if (results.length >= need || matches.length < topK)
|
|
254
|
+
break;
|
|
255
|
+
if (topK >= context.maxSearchCandidates) {
|
|
256
|
+
throw (0, errors_js_1.validationError)(`Semantic search collected ${results.length} of ${need} matches within maxSearchCandidates ` +
|
|
257
|
+
`(${context.maxSearchCandidates}); narrow the filter or raise maxSearchCandidates`, 'maxSearchCandidates');
|
|
258
|
+
}
|
|
259
|
+
topK = Math.min(topK * 2, context.maxSearchCandidates);
|
|
260
|
+
}
|
|
261
|
+
return results;
|
|
262
|
+
}
|
|
263
|
+
function toRelevanceScores(matches, direction) {
|
|
264
|
+
if (direction !== 'distance')
|
|
265
|
+
return matches;
|
|
266
|
+
return matches
|
|
267
|
+
.map((match) => ({ ...match, score: -match.score }))
|
|
268
|
+
.sort((left, right) => right.score - left.score);
|
|
269
|
+
}
|
|
@@ -6,15 +6,17 @@
|
|
|
6
6
|
* the five answer and refuse alike. `search` guards the same way but calls
|
|
7
7
|
* its own action directly, to carry a signal that `batch` cannot;
|
|
8
8
|
* `reconcileVectorIndex` and `ensureS3LifecycleRule` guard directly too,
|
|
9
|
-
* since neither is a batchable store operation. Each
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* shell,
|
|
13
|
-
*
|
|
9
|
+
* since neither is a batchable store operation. Each public method declared
|
|
10
|
+
* here is also the error boundary (record 13) — an asynchronous one through
|
|
11
|
+
* `guardPublic`, and the synchronous `destroy`, releasing what the store owns
|
|
12
|
+
* through its shell, through `guardPublicSync`; `stop` is that same guarded
|
|
13
|
+
* call under upstream's lifecycle name. The inherited `start()` no-op —
|
|
14
|
+
* declared by `BaseStore`, not overridden here — is neither guarded nor
|
|
15
|
+
* routed through any of this.
|
|
14
16
|
*/
|
|
15
17
|
import { BaseStore, type Item, type Operation, type OperationResults, type SearchItem } from '@langchain/langgraph-checkpoint';
|
|
16
|
-
import type { CancelOptions } from '../shared/options';
|
|
17
|
-
import type { DynamoDBStoreOptions, ListNamespacesOptions, SearchOptions, VectorReconcileResult } from './types';
|
|
18
|
+
import type { CancelOptions } from '../shared/options.js';
|
|
19
|
+
import type { DynamoDBStoreOptions, ListNamespacesOptions, SearchOptions, VectorReconcileResult } from './types.js';
|
|
18
20
|
/**
|
|
19
21
|
* DynamoDB-backed LangGraph store for long-term memory with optional semantic
|
|
20
22
|
* search. `get`, `put`, `delete` and `listNamespaces` answer and refuse exactly
|
|
@@ -44,7 +46,9 @@ export declare class DynamoDBStore extends BaseStore {
|
|
|
44
46
|
* namespaces for a listing, and `null` for a put or a delete — the value the
|
|
45
47
|
* reference store's `batch` answers a put or a delete with. The kind was
|
|
46
48
|
* decided once, by the parser that built `operation`, so this switches on it
|
|
47
|
-
* instead of asking the operation's shape again.
|
|
49
|
+
* instead of asking the operation's shape again. `readConcurrency` — this
|
|
50
|
+
* operation's share of the call's decode budget, which only a search spends
|
|
51
|
+
* more than one of.
|
|
48
52
|
*/
|
|
49
53
|
private dispatch;
|
|
50
54
|
/**
|
|
@@ -54,15 +58,18 @@ export declare class DynamoDBStore extends BaseStore {
|
|
|
54
58
|
* the brand the *inner* one assigned, so routing `get`, `put`, `delete` and
|
|
55
59
|
* `listNamespaces` through the public {@link batch} reported all four as
|
|
56
60
|
* `store.batch` and left an operator counting AWS failures by
|
|
57
|
-
* `context.operation` unable to tell them apart.
|
|
61
|
+
* `context.operation` unable to tell them apart. The operations one phase
|
|
62
|
+
* keeps in flight together share `this.context.readConcurrency`, the call's
|
|
63
|
+
* one decode budget, so a phase of several concurrent searches never
|
|
64
|
+
* multiplies it (see {@link runBatch}).
|
|
58
65
|
*/
|
|
59
66
|
private execute;
|
|
60
67
|
/**
|
|
61
68
|
* Execute a batch of operations and return their results in operation
|
|
62
69
|
* order.
|
|
63
70
|
*
|
|
64
|
-
* Accepts: `operations` — an array of operation objects
|
|
65
|
-
*
|
|
71
|
+
* Accepts: `operations` — an array of operation objects; an empty batch
|
|
72
|
+
* does nothing and returns `[]`. Every
|
|
66
73
|
* operation is checked before any of them runs. A put carrying a `null`
|
|
67
74
|
* value deletes its item. `get`, `put`, `delete` and `listNamespaces` check
|
|
68
75
|
* their own call by the same rules and run the same dispatch, as upstream's
|
|
@@ -85,15 +92,22 @@ export declare class DynamoDBStore extends BaseStore {
|
|
|
85
92
|
* search; `offset`, `limit`, `maxDepth`, `matchConditions`, `prefix`,
|
|
86
93
|
* `prefix element`, `suffix` or `suffix element` for a listing; and later,
|
|
87
94
|
* from a running operation, `value` for one JSON cannot represent,
|
|
88
|
-
* `maxSearchCandidates` or `index.dims
|
|
95
|
+
* `maxSearchCandidates` or `index.dims`, or — once a put's row is built —
|
|
96
|
+
* `index` or `value` again for one over DynamoDB's 400 KB item limit, naming
|
|
97
|
+
* `index` when its inline vectors are what pushed it over. A classified AWS
|
|
98
|
+
* failure; `RETRY_EXHAUSTED`;
|
|
89
99
|
* `RESULT_TRUNCATED` from a search or a listing that reads past
|
|
90
|
-
* `maxScanItems`. One failing operation rejects the
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
* search
|
|
95
|
-
*
|
|
96
|
-
*
|
|
100
|
+
* `maxScanItems` or `maxIterations`. One failing operation rejects the
|
|
101
|
+
* whole batch.
|
|
102
|
+
*
|
|
103
|
+
* Guarantees: the batch is evaluated as the reference store evaluates one —
|
|
104
|
+
* every get, search and listing is answered as the batch found things, and
|
|
105
|
+
* the puts and deletes land afterwards, one per item, the last one written
|
|
106
|
+
* winning — so two tasks of one superstep that touch one item get the same
|
|
107
|
+
* answers whichever was enqueued first. The reads run concurrently, then the
|
|
108
|
+
* writes, so a batch of ten gets costs about one round trip rather than ten,
|
|
109
|
+
* sharing one `readConcurrency` decode budget between them rather than each
|
|
110
|
+
* holding a full one.
|
|
97
111
|
*/
|
|
98
112
|
batch<Op extends Operation[]>(operations: Op): Promise<OperationResults<Op>>;
|
|
99
113
|
/**
|
|
@@ -140,7 +154,14 @@ export declare class DynamoDBStore extends BaseStore {
|
|
|
140
154
|
* Returns: nothing.
|
|
141
155
|
*
|
|
142
156
|
* Throws: `VALIDATION` naming `namespace`, `namespace element`, `key`,
|
|
143
|
-
* `sortKey`, `value` or `index`; a
|
|
157
|
+
* `sortKey`, `value` or `index`; `payload` for a value too large to store
|
|
158
|
+
* inline without `s3`, or, once offloaded, larger than
|
|
159
|
+
* `s3.maxDownloadBytes`; `s3Key` for an offloaded object's key over S3's
|
|
160
|
+
* cap; `VALIDATION` again, naming `index` or `value`, for the built row over
|
|
161
|
+
* DynamoDB's 400 KB item limit — `index` when its inline vectors are what
|
|
162
|
+
* pushed it over — checked before anything is written; `S3_OFFLOAD_FAILED`
|
|
163
|
+
* when an offloaded payload cannot be uploaded; a classified AWS failure;
|
|
164
|
+
* `RETRY_EXHAUSTED`.
|
|
144
165
|
*/
|
|
145
166
|
put(namespace: string[], key: string, value: Parameters<BaseStore['put']>[2], index?: Parameters<BaseStore['put']>[3]): Promise<void>;
|
|
146
167
|
/**
|
|
@@ -178,16 +199,18 @@ export declare class DynamoDBStore extends BaseStore {
|
|
|
178
199
|
*
|
|
179
200
|
* Accepts: `options.prefix`/`suffix` — labels a namespace can hold, where
|
|
180
201
|
* `'*'` matches any one label. `options.maxDepth` — at least 1.
|
|
181
|
-
* `options.limit` — an integer from 0 to
|
|
202
|
+
* `options.limit` — an integer from 0 to 10,000, defaulting
|
|
182
203
|
* to 100, where `0` returns an empty listing without reading the table.
|
|
183
204
|
* `options.offset` — a non-negative integer, defaulting to 0.
|
|
184
205
|
*
|
|
185
206
|
* Returns: at most `limit` namespaces from `offset`.
|
|
186
207
|
*
|
|
187
|
-
* Throws: `VALIDATION` naming `options`, `
|
|
188
|
-
* `
|
|
189
|
-
* `
|
|
190
|
-
* for an item written by a newer version; a classified
|
|
208
|
+
* Throws: `VALIDATION` naming `options`, `prefix`, `prefix element`,
|
|
209
|
+
* `suffix`, `suffix element`, `maxDepth`, `limit` or `offset`;
|
|
210
|
+
* `RESULT_TRUNCATED` past `maxScanItems` or `maxIterations`;
|
|
211
|
+
* `FORMAT_UNSUPPORTED` for an item written by a newer version; a classified
|
|
212
|
+
* AWS failure. An option key this version does not read is ignored rather
|
|
213
|
+
* than refused, since the options are LangGraph's (decision record 28).
|
|
191
214
|
*/
|
|
192
215
|
listNamespaces(options?: ListNamespacesOptions): Promise<string[][]>;
|
|
193
216
|
/**
|
|
@@ -198,7 +221,7 @@ export declare class DynamoDBStore extends BaseStore {
|
|
|
198
221
|
* whole table. `options.query` —
|
|
199
222
|
* absent or empty ranks nothing. `options.filter` — metadata equality on the
|
|
200
223
|
* item's value. `options.offset` — a non-negative integer, defaulting to 0.
|
|
201
|
-
* `options.limit` — an integer from 0 to
|
|
224
|
+
* `options.limit` — an integer from 0 to 10,000, defaulting
|
|
202
225
|
* to 10, where `0` returns an empty page without a read or an embedding.
|
|
203
226
|
* `options.signal` — aborts the reads.
|
|
204
227
|
*
|
|
@@ -206,12 +229,15 @@ export declare class DynamoDBStore extends BaseStore {
|
|
|
206
229
|
* a query and an index are configured.
|
|
207
230
|
*
|
|
208
231
|
* Throws: `VALIDATION` naming `namespacePrefix`, `namespacePrefix element`,
|
|
209
|
-
* `
|
|
210
|
-
* `
|
|
211
|
-
* `
|
|
232
|
+
* `options` for options that are not an object, `filter`, `query`, `offset`,
|
|
233
|
+
* `limit`, `maxSearchCandidates`, `index.dims` or `signal`; `ABORTED`;
|
|
234
|
+
* `RESULT_TRUNCATED` when the walk reaches `maxScanItems` or `maxIterations`;
|
|
212
235
|
* `FORMAT_UNSUPPORTED` for an item, or its payload, written by a newer
|
|
213
236
|
* version — a search reads rows it did not name, so one such row anywhere in
|
|
214
237
|
* the prefix it walks reports rather than being passed over; a classified AWS failure.
|
|
238
|
+
* An option key this version does not read is ignored rather than refused:
|
|
239
|
+
* the options are LangGraph's, and a key a later LangGraph adds must not turn
|
|
240
|
+
* a search into a refusal (decision record 28).
|
|
215
241
|
*
|
|
216
242
|
* Guarantees: a plain search stops reading once `offset + limit` matches are
|
|
217
243
|
* in hand; a query ranks in-process up to `maxSearchCandidates`, or through
|
|
@@ -223,20 +249,22 @@ export declare class DynamoDBStore extends BaseStore {
|
|
|
223
249
|
* `namespacePrefix`. A maintenance tool; see the action of the same name.
|
|
224
250
|
*
|
|
225
251
|
* Accepts: `namespacePrefix` — a non-empty namespace. `options.signal` —
|
|
226
|
-
*
|
|
252
|
+
* ends the read or download in flight and any wait between them; vectors
|
|
253
|
+
* already upserted or pruned stay so.
|
|
227
254
|
*
|
|
228
255
|
* Returns: how many vectors were upserted and how many pruned.
|
|
229
256
|
*
|
|
230
257
|
* Throws: `VALIDATION` without both an `index` and a `vectorBackend`, for
|
|
231
258
|
* an empty prefix, for an invalid `signal`, or for `options.<key>` naming a
|
|
232
|
-
* key this package does not read; `RESULT_TRUNCATED` past `maxScanItems
|
|
233
|
-
* `FORMAT_UNSUPPORTED` for an item, or its payload, written by a newer
|
|
259
|
+
* key this package does not read; `RESULT_TRUNCATED` past `maxScanItems` or
|
|
260
|
+
* `maxIterations`; `FORMAT_UNSUPPORTED` for an item, or its payload, written by a newer
|
|
234
261
|
* version — repairing a backend from a view of the prefix that silently
|
|
235
262
|
* omitted such a row would prune the vectors of items that are still there;
|
|
236
263
|
* a classified AWS failure.
|
|
237
264
|
*
|
|
238
265
|
* Guarantees: DynamoDB is never written — only the backend is repaired — and
|
|
239
|
-
* a vector is deleted only on evidence that its item is gone
|
|
266
|
+
* a vector is deleted only on evidence that its item is gone, or unchanged
|
|
267
|
+
* since a snapshot that already found it with nothing to embed.
|
|
240
268
|
*/
|
|
241
269
|
reconcileVectorIndex(namespacePrefix: string[], options?: CancelOptions): Promise<VectorReconcileResult>;
|
|
242
270
|
/**
|
|
@@ -260,9 +288,10 @@ export declare class DynamoDBStore extends BaseStore {
|
|
|
260
288
|
* Returns: nothing. Idempotent, and a no-op for a client the caller injected
|
|
261
289
|
* — that one is theirs to close.
|
|
262
290
|
*
|
|
263
|
-
* Throws:
|
|
264
|
-
*
|
|
265
|
-
*
|
|
291
|
+
* Throws: the first failure a resource's own `destroy` raised, as a
|
|
292
|
+
* `DynamoDBLangGraphError` (`UNEXPECTED_ERROR` unless the failure was AWS's)
|
|
293
|
+
* with it as `cause` — raised only after every other resource has been
|
|
294
|
+
* released, and only by the first call: `destroy()` is idempotent.
|
|
266
295
|
*/
|
|
267
296
|
destroy(): void;
|
|
268
297
|
/**
|
|
@@ -273,14 +302,28 @@ export declare class DynamoDBStore extends BaseStore {
|
|
|
273
302
|
* without both.
|
|
274
303
|
*
|
|
275
304
|
* Returns: nothing. Installing a rule that is already there is a no-op too,
|
|
276
|
-
* so calling it on every deploy is safe.
|
|
305
|
+
* so calling it on every deploy is safe. When it writes the rules but
|
|
306
|
+
* cannot confirm within its polling window that a re-read shows them — S3
|
|
307
|
+
* documents that a lifecycle configuration can take minutes to propagate —
|
|
308
|
+
* it logs a `warn` and returns rather than throwing: the rules were
|
|
309
|
+
* written, and a later call can confirm them.
|
|
277
310
|
*
|
|
278
311
|
* Throws: `VALIDATION` naming `s3.keyPrefix` on a rule-id collision;
|
|
279
|
-
* a classified AWS failure when the bucket's lifecycle cannot be read or
|
|
312
|
+
* a classified AWS failure when the bucket's lifecycle cannot be read or
|
|
313
|
+
* written; `CONTENTION` when every one of the five rounds this call polls
|
|
314
|
+
* needs a write — a competing writer replacing the configuration on every
|
|
315
|
+
* single re-read.
|
|
280
316
|
* @remarks Requires the bucket-level `s3:GetLifecycleConfiguration` /
|
|
281
317
|
* `s3:PutLifecycleConfiguration` permissions, broader than the object-level
|
|
282
318
|
* CRUD the rest of S3 offload needs — call it once during provisioning, not
|
|
283
|
-
* per request.
|
|
319
|
+
* per request. When several adapters or processes provision the same
|
|
320
|
+
* bucket, call them one at a time and run each again after a few minutes
|
|
321
|
+
* once every one of them has run.
|
|
322
|
+
*
|
|
323
|
+
* Lowering the `ttl` is safe for new rows at once; the rule is not. Lower
|
|
324
|
+
* `ttl` now, and call this again only once the old `ttl` has elapsed since,
|
|
325
|
+
* because until then rows written under the old value still name objects
|
|
326
|
+
* the shorter rule would expire. Raising the `ttl` is safe at once.
|
|
284
327
|
*/
|
|
285
328
|
ensureS3LifecycleRule(): Promise<void>;
|
|
286
329
|
}
|