@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
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DynamoDBStore = void 0;
|
|
4
|
+
const langgraph_checkpoint_1 = require("@langchain/langgraph-checkpoint");
|
|
5
|
+
const boundary_js_1 = require("../shared/errors/boundary.js");
|
|
6
|
+
const collaborators_js_1 = require("../shared/validation/collaborators.js");
|
|
7
|
+
const option_shape_js_1 = require("../shared/validation/option-shape.js");
|
|
8
|
+
const list_namespaces_js_1 = require("./actions/list-namespaces.js");
|
|
9
|
+
const put_js_1 = require("./actions/put.js");
|
|
10
|
+
const reconcile_vector_index_js_1 = require("./actions/reconcile-vector-index.js");
|
|
11
|
+
const search_js_1 = require("./actions/search.js");
|
|
12
|
+
const batch_plan_js_1 = require("./internal/batch-plan.js");
|
|
13
|
+
const get_item_js_1 = require("./internal/get-item.js");
|
|
14
|
+
const parse_js_1 = require("./internal/parse.js");
|
|
15
|
+
const setup_js_1 = require("./internal/setup.js");
|
|
16
|
+
class DynamoDBStore extends langgraph_checkpoint_1.BaseStore {
|
|
17
|
+
context;
|
|
18
|
+
shell;
|
|
19
|
+
constructor(options) {
|
|
20
|
+
super();
|
|
21
|
+
const setup = (0, setup_js_1.setUpStore)(options);
|
|
22
|
+
this.context = setup.context;
|
|
23
|
+
this.shell = setup.shell;
|
|
24
|
+
}
|
|
25
|
+
async dispatch(operation, readConcurrency) {
|
|
26
|
+
switch (operation.kind) {
|
|
27
|
+
case 'search':
|
|
28
|
+
return (0, search_js_1.searchItems)({ ...this.context, readConcurrency }, operation);
|
|
29
|
+
case 'put':
|
|
30
|
+
case 'delete':
|
|
31
|
+
await (0, put_js_1.putItem)(this.context, operation);
|
|
32
|
+
return null;
|
|
33
|
+
case 'get':
|
|
34
|
+
return (0, get_item_js_1.getItem)(this.context, operation.address);
|
|
35
|
+
case 'list':
|
|
36
|
+
return (0, list_namespaces_js_1.listNamespaces)(this.context, operation);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
async execute(operations) {
|
|
40
|
+
return (0, batch_plan_js_1.runBatch)(operations, (operation, readConcurrency) => this.dispatch(operation, readConcurrency), this.context.readConcurrency);
|
|
41
|
+
}
|
|
42
|
+
async batch(operations) {
|
|
43
|
+
return (0, boundary_js_1.guardPublic)('store.batch', async () => {
|
|
44
|
+
const results = await this.execute((0, parse_js_1.parseOperations)(operations));
|
|
45
|
+
return results;
|
|
46
|
+
}, this.context.tableName);
|
|
47
|
+
}
|
|
48
|
+
async get(namespace, key) {
|
|
49
|
+
return (0, boundary_js_1.guardPublic)('store.get', async () => {
|
|
50
|
+
const [item] = await this.execute([
|
|
51
|
+
{ kind: 'get', address: (0, parse_js_1.parseStoreAddress)(namespace, key) },
|
|
52
|
+
]);
|
|
53
|
+
return item;
|
|
54
|
+
}, this.context.tableName);
|
|
55
|
+
}
|
|
56
|
+
async put(namespace, key, value, index) {
|
|
57
|
+
return (0, boundary_js_1.guardPublic)('store.put', async () => {
|
|
58
|
+
await this.execute([(0, parse_js_1.parsePutArguments)(namespace, key, value, index)]);
|
|
59
|
+
}, this.context.tableName);
|
|
60
|
+
}
|
|
61
|
+
async delete(namespace, key) {
|
|
62
|
+
return (0, boundary_js_1.guardPublic)('store.delete', async () => {
|
|
63
|
+
await this.execute([{ kind: 'delete', address: (0, parse_js_1.parseStoreAddress)(namespace, key) }]);
|
|
64
|
+
}, this.context.tableName);
|
|
65
|
+
}
|
|
66
|
+
async listNamespaces(options = {}) {
|
|
67
|
+
return (0, boundary_js_1.guardPublic)('store.listNamespaces', async () => {
|
|
68
|
+
const [namespaces] = await this.execute([(0, parse_js_1.parseListNamespacesOptions)(options)]);
|
|
69
|
+
return namespaces;
|
|
70
|
+
}, this.context.tableName);
|
|
71
|
+
}
|
|
72
|
+
async search(namespacePrefix, options = {}) {
|
|
73
|
+
return (0, boundary_js_1.guardPublic)('store.search', () => {
|
|
74
|
+
const prefix = (0, parse_js_1.parseNamespacePrefix)(namespacePrefix, 'namespacePrefix');
|
|
75
|
+
(0, option_shape_js_1.assertObjectShape)(options, 'options');
|
|
76
|
+
(0, collaborators_js_1.assertSignalLike)(options.signal);
|
|
77
|
+
const { signal, ...rest } = options;
|
|
78
|
+
return (0, search_js_1.searchItems)(this.context, (0, parse_js_1.parseSearch)(prefix, rest), signal);
|
|
79
|
+
}, this.context.tableName);
|
|
80
|
+
}
|
|
81
|
+
reconcileVectorIndex(namespacePrefix, options) {
|
|
82
|
+
return (0, boundary_js_1.guardPublic)('store.reconcileVectorIndex', () => {
|
|
83
|
+
(0, collaborators_js_1.assertCancelOptions)(options);
|
|
84
|
+
return (0, reconcile_vector_index_js_1.reconcileVectorIndex)(this.context, namespacePrefix, options);
|
|
85
|
+
}, this.context.tableName);
|
|
86
|
+
}
|
|
87
|
+
stop() {
|
|
88
|
+
this.destroy();
|
|
89
|
+
}
|
|
90
|
+
destroy() {
|
|
91
|
+
(0, boundary_js_1.guardPublicSync)('store.destroy', () => this.shell.release(), this.context.tableName);
|
|
92
|
+
}
|
|
93
|
+
async ensureS3LifecycleRule() {
|
|
94
|
+
return (0, boundary_js_1.guardPublic)('store.ensureS3LifecycleRule', () => this.shell.ensureLifecycleRule(), this.context.tableName);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
exports.DynamoDBStore = DynamoDBStore;
|
|
@@ -12,18 +12,25 @@
|
|
|
12
12
|
* type what it builds without learning how it is checked.
|
|
13
13
|
*/
|
|
14
14
|
import type { IndexConfig, SearchOperation, SerializerProtocol } from '@langchain/langgraph-checkpoint';
|
|
15
|
-
import type { BaseAdapterOptions, CancelOptions, CodecOptions } from '../shared/options';
|
|
16
|
-
import type { VectorBackend, VectorScoreDirection } from './vector-backend';
|
|
17
|
-
/**
|
|
18
|
-
|
|
15
|
+
import type { BaseAdapterOptions, CancelOptions, CodecOptions } from '../shared/options.js';
|
|
16
|
+
import type { VectorBackend, VectorScoreDirection } from './vector-backend.js';
|
|
17
|
+
/**
|
|
18
|
+
* Options for {@link DynamoDBStore}.
|
|
19
|
+
*
|
|
20
|
+
* `indexName` and `indexShards` are not store options: no store read uses the
|
|
21
|
+
* recency index, so a store given either refuses it as an unknown key.
|
|
22
|
+
*/
|
|
23
|
+
export type DynamoDBStoreOptions = Omit<BaseAdapterOptions, 'indexName' | 'indexShards'> & CodecOptions & {
|
|
19
24
|
/**
|
|
20
25
|
* Optional semantic-search index configuration (embeddings + fields).
|
|
21
26
|
*
|
|
22
27
|
* Without a `vectorBackend` the vectors live on the item itself, one per
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
28
|
+
* text the configured fields extract — a wildcard path such as
|
|
29
|
+
* `sections[*].text` extracts one per element — at up to 10 bytes per
|
|
30
|
+
* dimension. They are not counted toward `s3.thresholdBytes` — offload
|
|
31
|
+
* decides on the payload alone — and a row they would take past
|
|
32
|
+
* DynamoDB's 400 KB item limit is refused with `VALIDATION` naming
|
|
33
|
+
* `index` before anything is written.
|
|
27
34
|
*/
|
|
28
35
|
index?: IndexConfig;
|
|
29
36
|
/**
|
|
@@ -46,9 +53,17 @@ export type DynamoDBStoreOptions = BaseAdapterOptions & CodecOptions & {
|
|
|
46
53
|
* Cap on rows read into memory by one search, namespace listing or
|
|
47
54
|
* reconcile before `RESULT_TRUNCATED`. Reaching it is an error, not a
|
|
48
55
|
* truncation: a partial answer is never returned as a complete one.
|
|
49
|
-
* Defaults to
|
|
56
|
+
* Defaults to 10,000; the ceiling is 1,000,000.
|
|
50
57
|
*/
|
|
51
58
|
maxScanItems?: number;
|
|
59
|
+
/**
|
|
60
|
+
* Cap on DynamoDB pages one search, namespace listing or reconcile reads
|
|
61
|
+
* before `RESULT_TRUNCATED` (default 1000; a page is at most 1 MB).
|
|
62
|
+
* `Infinity` reads to the end. It is the cap a rootless search or listing
|
|
63
|
+
* over a large table meets first when most of what it scans is not store
|
|
64
|
+
* rows, since those pages hold few rows for `maxScanItems` to count.
|
|
65
|
+
*/
|
|
66
|
+
maxIterations?: number;
|
|
52
67
|
/**
|
|
53
68
|
* Direction of the score a `vectorBackend` returns. `'relevance'` (the
|
|
54
69
|
* default) forwards it unchanged; `'distance'` negates and re-sorts, so a
|
|
@@ -82,7 +97,7 @@ export interface ListNamespacesOptions {
|
|
|
82
97
|
*/
|
|
83
98
|
maxDepth?: number;
|
|
84
99
|
/**
|
|
85
|
-
* How many namespaces to return, from 0 to
|
|
100
|
+
* How many namespaces to return, from 0 to 10,000;
|
|
86
101
|
* default 100. `0` returns an empty array without reading the table.
|
|
87
102
|
*/
|
|
88
103
|
limit?: number;
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hides how rows written before the recency index are given its keys.
|
|
3
|
+
*
|
|
4
|
+
* The index is opt-in (record 8), so a table can hold rows from before it
|
|
5
|
+
* existed. An operator walks the table a page at a time, resumably, and gives
|
|
6
|
+
* each row the keys its adapter would have written; which rows those are is
|
|
7
|
+
* each adapter's own answer, asked here, and a row that gained keys since the
|
|
8
|
+
* scan read it is left alone.
|
|
9
|
+
*/
|
|
10
|
+
import type { AttributeMap, DynamoDBDocumentLike } from '../shared/dynamodb/client.js';
|
|
11
|
+
import { type IndexTarget } from '../shared/dynamodb/recency-index.js';
|
|
12
|
+
import { type RetryOptions } from '../shared/dynamodb/retry.js';
|
|
13
|
+
/**
|
|
14
|
+
* Give rows written before the recency index their index keys.
|
|
15
|
+
*
|
|
16
|
+
* **Run this before setting `indexName` on any adapter.** A row without the
|
|
17
|
+
* keys is not in the index, so enabling the index first would make every
|
|
18
|
+
* pre-existing session and checkpoint silently vanish from the listings
|
|
19
|
+
* that read it — the rows are still there, and every other read still returns
|
|
20
|
+
* them, but a listing would not.
|
|
21
|
+
*
|
|
22
|
+
* Safe to re-run and safe to run while adapters are writing: every write is
|
|
23
|
+
* conditional on the row still being there and having no keys yet, so a row a
|
|
24
|
+
* live adapter has already indexed is left exactly as it is, and a row deleted
|
|
25
|
+
* after the scan found it stays deleted rather than being re-created by an
|
|
26
|
+
* `UpdateItem`, which upserts.
|
|
27
|
+
*
|
|
28
|
+
* `indexShards` must match what the saver and the history use. A mismatch
|
|
29
|
+
* puts rows on shards no listing queries, which looks exactly like the rows
|
|
30
|
+
* being missing.
|
|
31
|
+
*
|
|
32
|
+
* Accepts: `options` — validated in full before any read: only the keys
|
|
33
|
+
* `BackfillOptions` declares; `tableName`, `indexShards` and the numbers in
|
|
34
|
+
* `retry` by the adapters' rules; `signal` as their methods check it; a
|
|
35
|
+
* `client` providing `scan` and `update`. `options.pageSize` — a positive integer,
|
|
36
|
+
* default 100. `options.cursor` — from a previous run, to resume.
|
|
37
|
+
* `options.maxPages` — how far one run goes, so a large table can be
|
|
38
|
+
* backfilled in bounded slices. `options.indexShards` — must equal the
|
|
39
|
+
* saver's and the history's setting, and has their ceiling. `options.dryRun` — a boolean.
|
|
40
|
+
* `options.signal` — cancels the run; `retry.signal` does so when there is no
|
|
41
|
+
* top-level `signal`, and the top-level one wins when both are given.
|
|
42
|
+
*
|
|
43
|
+
* Returns: how many rows were scanned, how many were given keys and how many
|
|
44
|
+
* were skipped — a row no listing reaches, and a row whose write the condition
|
|
45
|
+
* refused because the row already has keys or is gone — plus a `nextCursor`
|
|
46
|
+
* when the run stopped short of the end. An absent cursor means the table is
|
|
47
|
+
* fully backfilled.
|
|
48
|
+
*
|
|
49
|
+
* Throws: `VALIDATION` naming the offending option, before any DynamoDB
|
|
50
|
+
* call; `RETRY_EXHAUSTED` once a transient failure has used every attempt;
|
|
51
|
+
* `ABORTED` when `signal` fires, or `retry.signal` when no top-level `signal`
|
|
52
|
+
* is given; any other error the scan or the writes throw, wrapped with the
|
|
53
|
+
* code the classifier assigns — this is the function's own error boundary,
|
|
54
|
+
* the same as every adapter's public methods, so a caller's mistake never escapes as a bare
|
|
55
|
+
* exception. A refused write is none of these: it is an outcome for one row,
|
|
56
|
+
* reported in `skipped`.
|
|
57
|
+
*
|
|
58
|
+
* Guarantees: every write is conditional on the row still being there and
|
|
59
|
+
* having no keys yet, so re-running is safe, running against a live table is
|
|
60
|
+
* safe, a row a live adapter has already indexed is left exactly as it is, and
|
|
61
|
+
* a row deleted between the scan and the write is never re-created. Neither
|
|
62
|
+
* refusal stops the run: both mean this run has nothing to do for that row, so
|
|
63
|
+
* the row is counted as skipped and the walk carries on to the rest of the
|
|
64
|
+
* table.
|
|
65
|
+
*/
|
|
66
|
+
export declare function backfillRecencyIndex(options: BackfillOptions): Promise<BackfillResult>;
|
|
67
|
+
/**
|
|
68
|
+
* Which rows the index covers: the checkpointer and the chat history each
|
|
69
|
+
* answer for their own rows; a store row is in no listing the index serves.
|
|
70
|
+
*
|
|
71
|
+
* Accepts: `row` — any row a table scan returns, including a foreign one and
|
|
72
|
+
* one whose `PK`/`SK` are not strings.
|
|
73
|
+
*
|
|
74
|
+
* Returns: the index identity, or undefined for a row no listing reaches — a
|
|
75
|
+
* foreign row, a payload or write row, a META row carrying no `checkpointId`,
|
|
76
|
+
* or a store row.
|
|
77
|
+
*
|
|
78
|
+
* Throws: nothing. A backfill walks the whole table; one unrecognised row must
|
|
79
|
+
* be skipped, not fatal.
|
|
80
|
+
*/
|
|
81
|
+
export declare function indexTargetOf(row: AttributeMap): IndexTarget | undefined;
|
|
82
|
+
/**
|
|
83
|
+
* A scan position, as an opaque string.
|
|
84
|
+
*
|
|
85
|
+
* Accepts: `key` — a `LastEvaluatedKey` from the scan being resumed.
|
|
86
|
+
*
|
|
87
|
+
* Returns: it base64url-encoded. Opaque to the caller: its shape is not a
|
|
88
|
+
* promise, which is what leaves the encoding free to change.
|
|
89
|
+
*
|
|
90
|
+
* Throws: nothing.
|
|
91
|
+
*/
|
|
92
|
+
export declare function encodeScanCursor(key: AttributeMap): string;
|
|
93
|
+
/**
|
|
94
|
+
* The scan position a cursor encodes.
|
|
95
|
+
*
|
|
96
|
+
* Accepts: `cursor` — as a previous page returned it.
|
|
97
|
+
*
|
|
98
|
+
* Returns: the `ExclusiveStartKey` to resume from — always exactly `{ PK,
|
|
99
|
+
* SK }`, both strings, since a plain table `Scan` (no `IndexName`) never
|
|
100
|
+
* returns a `LastEvaluatedKey` shaped any other way.
|
|
101
|
+
*
|
|
102
|
+
* Throws: `VALIDATION` naming `cursor` for anything this tool did not
|
|
103
|
+
* issue — text that is not base64url, that does not decode to JSON, or that
|
|
104
|
+
* decodes to anything but `{ PK: string, SK: string }`: an array, an object
|
|
105
|
+
* missing either key, carrying an extra one, or carrying a non-string value
|
|
106
|
+
* for either. A cursor is fed straight back to DynamoDB as
|
|
107
|
+
* `ExclusiveStartKey`, so a value of the wrong shape is refused here rather
|
|
108
|
+
* than surfacing as a raw `ValidationException` from the service.
|
|
109
|
+
*/
|
|
110
|
+
export declare function decodeScanCursor(cursor: string): AttributeMap;
|
|
111
|
+
/** What one pass of the backfill did, and where to resume. */
|
|
112
|
+
export interface BackfillResult {
|
|
113
|
+
/** Rows the scan returned: those without index keys, since its filter drops every row that has them. Not the rows DynamoDB evaluated, which a filter does not reduce. */
|
|
114
|
+
scanned: number;
|
|
115
|
+
/** Rows given index keys. */
|
|
116
|
+
indexed: number;
|
|
117
|
+
/**
|
|
118
|
+
* Rows this run wrote no keys for: one no listing reaches, and one whose
|
|
119
|
+
* write the condition refused because it already has keys or is gone.
|
|
120
|
+
*/
|
|
121
|
+
skipped: number;
|
|
122
|
+
/**
|
|
123
|
+
* Opaque; absent when the table is fully walked. Pass it back to continue —
|
|
124
|
+
* the pass is resumable, so a large table can be backfilled in bounded runs.
|
|
125
|
+
*/
|
|
126
|
+
nextCursor?: string;
|
|
127
|
+
}
|
|
128
|
+
/** What the backfill needs to walk a table. A key this type does not declare is refused. */
|
|
129
|
+
export interface BackfillOptions {
|
|
130
|
+
client: DynamoDBDocumentLike;
|
|
131
|
+
tableName: string;
|
|
132
|
+
/** Must equal the saver's and the history's `indexShards`, or rows land on shards no listing queries. */
|
|
133
|
+
indexShards?: number;
|
|
134
|
+
/** Rows per scan page. */
|
|
135
|
+
pageSize?: number;
|
|
136
|
+
/** Stop after this many pages and return a cursor. Default: walk the whole table. */
|
|
137
|
+
maxPages?: number;
|
|
138
|
+
cursor?: string;
|
|
139
|
+
/** Report what would change without writing. */
|
|
140
|
+
dryRun?: boolean;
|
|
141
|
+
/**
|
|
142
|
+
* The full retry surface, not the adapters' narrower `RetryPolicy`:
|
|
143
|
+
* `onRetry` is backfill's only way to observe retries in progress, since it
|
|
144
|
+
* takes no `logger`.
|
|
145
|
+
*/
|
|
146
|
+
retry?: RetryOptions;
|
|
147
|
+
signal?: AbortSignal;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Validate every option `backfillRecencyIndex` reads, before any of them is
|
|
151
|
+
* read for real.
|
|
152
|
+
*
|
|
153
|
+
* Accepts: `options` — must be an object naming only the nine keys
|
|
154
|
+
* {@link BackfillOptions} declares. `tableName` and `client` are required, the
|
|
155
|
+
* rest optional; each, when given, follows the same rule an adapter's own
|
|
156
|
+
* option of the same name does. `tableName` reuses the adapters' own
|
|
157
|
+
* `tableName` validator outright; `indexShards` is held to the adapters'
|
|
158
|
+
* shard cap of 1024; and `retry` shares its numeric bounds with
|
|
159
|
+
* the adapters' own `retry` validator while accepting the wider surface
|
|
160
|
+
* backfill's `RetryOptions` needs, so a mismatch between backfill and the
|
|
161
|
+
* adapters it feeds cannot drift in on what a bound means.
|
|
162
|
+
*
|
|
163
|
+
* Returns: nothing: the value is kept under its declared type, and this
|
|
164
|
+
* checks it.
|
|
165
|
+
*
|
|
166
|
+
* Throws: `VALIDATION` naming `options.<key>` for an unknown key;
|
|
167
|
+
* `tableName`; `client` or `client.<member>`; `indexShards`, `pageSize` or
|
|
168
|
+
* `maxPages` for a non-positive-integer bound (`indexShards` is additionally
|
|
169
|
+
* capped); `dryRun` for a non-boolean; `retry`/`retry.<key>`; `signal`.
|
|
170
|
+
*/
|
|
171
|
+
export declare function assertBackfillOptions(options: BackfillOptions): void;
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { checkpointIndexTarget } from '../checkpointer/internal/rows.js';
|
|
2
|
+
import { sessionIndexTarget } from '../history/internal/session.js';
|
|
3
|
+
import { DEFAULT_READ_CONCURRENCY, mapWithConcurrency } from '../shared/concurrency.js';
|
|
4
|
+
import { isConditionalCheckFailed } from '../shared/dynamodb/idempotent-write.js';
|
|
5
|
+
import { DEFAULT_INDEX_SHARDS, INDEX_PARTITION_ATTRIBUTE, INDEX_SORT_ATTRIBUTE, indexKeys, MAX_INDEX_SHARDS, } from '../shared/dynamodb/recency-index.js';
|
|
6
|
+
import { withDynamoDBRetry } from '../shared/dynamodb/retry.js';
|
|
7
|
+
import { PARTITION_KEY_ATTRIBUTE, rowKeyOf } from '../shared/dynamodb/table-schema.js';
|
|
8
|
+
import { guardPublic } from '../shared/errors/boundary.js';
|
|
9
|
+
import { validationError } from '../shared/errors/errors.js';
|
|
10
|
+
import { assertClientTranslation, assertMembers, assertSignalLike, } from '../shared/validation/collaborators.js';
|
|
11
|
+
import { allKeysOf, assertShape } from '../shared/validation/option-shape.js';
|
|
12
|
+
import { assertRetryBounds, assertTableName } from '../shared/validation/options.js';
|
|
13
|
+
import { assertInteger, assertStringArray } from '../shared/validation/primitives.js';
|
|
14
|
+
function runRetry(options) {
|
|
15
|
+
return { ...options.retry, signal: options.signal ?? options.retry?.signal };
|
|
16
|
+
}
|
|
17
|
+
async function indexRow(options, row, shards) {
|
|
18
|
+
const target = indexTargetOf(row);
|
|
19
|
+
if (target === undefined)
|
|
20
|
+
return false;
|
|
21
|
+
const keys = indexKeys(target.tag, target.id, target.at, shards);
|
|
22
|
+
if (options.dryRun)
|
|
23
|
+
return true;
|
|
24
|
+
try {
|
|
25
|
+
await writeIndexKeys(options, row, keys);
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
if (!isConditionalCheckFailed(error))
|
|
29
|
+
throw error;
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
async function writeIndexKeys(options, row, keys) {
|
|
35
|
+
await withDynamoDBRetry((request) => options.client.update({
|
|
36
|
+
TableName: options.tableName,
|
|
37
|
+
Key: rowKeyOf(row),
|
|
38
|
+
UpdateExpression: 'SET #gpk = :gpk, #gsk = :gsk',
|
|
39
|
+
ExpressionAttributeNames: {
|
|
40
|
+
'#gpk': INDEX_PARTITION_ATTRIBUTE,
|
|
41
|
+
'#gsk': INDEX_SORT_ATTRIBUTE,
|
|
42
|
+
},
|
|
43
|
+
ExpressionAttributeValues: { ':gpk': keys.gsi1pk, ':gsk': keys.gsi1sk },
|
|
44
|
+
ConditionExpression: `attribute_exists(${PARTITION_KEY_ATTRIBUTE}) AND attribute_not_exists(#gpk)`,
|
|
45
|
+
}, request), runRetry(options));
|
|
46
|
+
}
|
|
47
|
+
async function backfillPage(options, shards, startKey) {
|
|
48
|
+
const result = await withDynamoDBRetry((request) => options.client.scan({
|
|
49
|
+
TableName: options.tableName,
|
|
50
|
+
Limit: options.pageSize ?? 100,
|
|
51
|
+
ExclusiveStartKey: startKey,
|
|
52
|
+
FilterExpression: 'attribute_not_exists(#gpk)',
|
|
53
|
+
ExpressionAttributeNames: { '#gpk': INDEX_PARTITION_ATTRIBUTE },
|
|
54
|
+
}, request), runRetry(options));
|
|
55
|
+
const rows = (result.Items ?? []);
|
|
56
|
+
const written = await mapWithConcurrency(rows, DEFAULT_READ_CONCURRENCY, (row) => indexRow(options, row, shards));
|
|
57
|
+
return {
|
|
58
|
+
rows: rows.length,
|
|
59
|
+
indexed: written.filter(Boolean).length,
|
|
60
|
+
nextKey: result.LastEvaluatedKey,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
export async function backfillRecencyIndex(options) {
|
|
64
|
+
return guardPublic('backfillRecencyIndex', async () => {
|
|
65
|
+
assertBackfillOptions(options);
|
|
66
|
+
const shards = options.indexShards ?? DEFAULT_INDEX_SHARDS;
|
|
67
|
+
let startKey = options.cursor === undefined ? undefined : decodeScanCursor(options.cursor);
|
|
68
|
+
let scanned = 0;
|
|
69
|
+
let indexed = 0;
|
|
70
|
+
for (let page = 1;; page++) {
|
|
71
|
+
const result = await backfillPage(options, shards, startKey);
|
|
72
|
+
scanned += result.rows;
|
|
73
|
+
indexed += result.indexed;
|
|
74
|
+
startKey = result.nextKey;
|
|
75
|
+
if (startKey === undefined)
|
|
76
|
+
break;
|
|
77
|
+
if (options.maxPages !== undefined && page >= options.maxPages) {
|
|
78
|
+
return {
|
|
79
|
+
scanned,
|
|
80
|
+
indexed,
|
|
81
|
+
skipped: scanned - indexed,
|
|
82
|
+
nextCursor: encodeScanCursor(startKey),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return { scanned, indexed, skipped: scanned - indexed };
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
export function indexTargetOf(row) {
|
|
90
|
+
return checkpointIndexTarget(row) ?? sessionIndexTarget(row);
|
|
91
|
+
}
|
|
92
|
+
export function encodeScanCursor(key) {
|
|
93
|
+
return Buffer.from(JSON.stringify(key), 'utf8').toString('base64url');
|
|
94
|
+
}
|
|
95
|
+
function isTableKeyShape(value) {
|
|
96
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value))
|
|
97
|
+
return false;
|
|
98
|
+
const keys = Object.keys(value);
|
|
99
|
+
return keys.length === 2 && typeof value.PK === 'string' && typeof value.SK === 'string';
|
|
100
|
+
}
|
|
101
|
+
export function decodeScanCursor(cursor) {
|
|
102
|
+
try {
|
|
103
|
+
const decoded = JSON.parse(Buffer.from(cursor, 'base64url').toString('utf8'));
|
|
104
|
+
if (!isTableKeyShape(decoded))
|
|
105
|
+
throw new Error('not a scan position');
|
|
106
|
+
return decoded;
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
throw validationError('cursor is not one this tool issued', 'cursor');
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
const BACKFILL_KEYS = allKeysOf({
|
|
113
|
+
client: 'client',
|
|
114
|
+
tableName: 'tableName',
|
|
115
|
+
indexShards: 'indexShards',
|
|
116
|
+
pageSize: 'pageSize',
|
|
117
|
+
maxPages: 'maxPages',
|
|
118
|
+
cursor: 'cursor',
|
|
119
|
+
dryRun: 'dryRun',
|
|
120
|
+
retry: 'retry',
|
|
121
|
+
signal: 'signal',
|
|
122
|
+
});
|
|
123
|
+
const BACKFILL_CLIENT_MEMBERS = ['scan', 'update'];
|
|
124
|
+
const BACKFILL_RETRY_KEYS = allKeysOf({
|
|
125
|
+
maxAttempts: 'maxAttempts',
|
|
126
|
+
baseDelayMs: 'baseDelayMs',
|
|
127
|
+
maxDelayMs: 'maxDelayMs',
|
|
128
|
+
retryableErrors: 'retryableErrors',
|
|
129
|
+
isRetryable: 'isRetryable',
|
|
130
|
+
onRetry: 'onRetry',
|
|
131
|
+
signal: 'signal',
|
|
132
|
+
rng: 'rng',
|
|
133
|
+
});
|
|
134
|
+
function assertBackfillRetryOptions(retry) {
|
|
135
|
+
assertShape(retry, BACKFILL_RETRY_KEYS, 'retry');
|
|
136
|
+
assertRetryBounds(retry);
|
|
137
|
+
if (retry.retryableErrors !== undefined) {
|
|
138
|
+
assertStringArray(retry.retryableErrors, 'retry.retryableErrors');
|
|
139
|
+
}
|
|
140
|
+
if (retry.isRetryable !== undefined && typeof retry.isRetryable !== 'function') {
|
|
141
|
+
throw validationError('retry.isRetryable must be a function', 'retry.isRetryable');
|
|
142
|
+
}
|
|
143
|
+
if (retry.onRetry !== undefined && typeof retry.onRetry !== 'function') {
|
|
144
|
+
throw validationError('retry.onRetry must be a function', 'retry.onRetry');
|
|
145
|
+
}
|
|
146
|
+
if (retry.rng !== undefined && typeof retry.rng !== 'function') {
|
|
147
|
+
throw validationError('retry.rng must be a function', 'retry.rng');
|
|
148
|
+
}
|
|
149
|
+
assertSignalLike(retry.signal, 'retry.signal');
|
|
150
|
+
}
|
|
151
|
+
function assertPositiveBound(value, field, max) {
|
|
152
|
+
if (value === undefined)
|
|
153
|
+
return;
|
|
154
|
+
assertInteger(value, field, max === undefined ? { min: 1 } : { min: 1, max });
|
|
155
|
+
}
|
|
156
|
+
export function assertBackfillOptions(options) {
|
|
157
|
+
assertShape(options, BACKFILL_KEYS, 'options');
|
|
158
|
+
assertTableName(options.tableName);
|
|
159
|
+
assertMembers(options.client, BACKFILL_CLIENT_MEMBERS, 'client');
|
|
160
|
+
assertClientTranslation(options.client);
|
|
161
|
+
assertPositiveBound(options.indexShards, 'indexShards', MAX_INDEX_SHARDS);
|
|
162
|
+
assertPositiveBound(options.pageSize, 'pageSize');
|
|
163
|
+
assertPositiveBound(options.maxPages, 'maxPages');
|
|
164
|
+
if (options.dryRun !== undefined && typeof options.dryRun !== 'boolean') {
|
|
165
|
+
throw validationError('dryRun must be a boolean', 'dryRun');
|
|
166
|
+
}
|
|
167
|
+
if (options.retry !== undefined)
|
|
168
|
+
assertBackfillRetryOptions(options.retry);
|
|
169
|
+
assertSignalLike(options.signal);
|
|
170
|
+
}
|
package/dist/{checkpointer/actions/delete-thread.js → esm/checkpointer/actions/delete-thread.d.ts}
RENAMED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Hides what deleting a thread means for the checkpointer's rows.
|
|
4
3
|
*
|
|
@@ -8,12 +7,7 @@
|
|
|
8
7
|
* write rewritten after the read is left alone. A caller names a thread and
|
|
9
8
|
* never learns the row kinds, their sort keys or how a refusal is counted.
|
|
10
9
|
*/
|
|
11
|
-
|
|
12
|
-
exports.deleteThread = deleteThread;
|
|
13
|
-
const partition_delete_1 = require("../../shared/dynamodb/partition-delete");
|
|
14
|
-
const retry_1 = require("../../shared/dynamodb/retry");
|
|
15
|
-
const parse_1 = require("../internal/parse");
|
|
16
|
-
const rows_1 = require("../internal/rows");
|
|
10
|
+
import type { CheckpointerContext } from '../internal/setup.js';
|
|
17
11
|
/**
|
|
18
12
|
* Delete exactly the checkpoint, payload and write rows of one thread that the
|
|
19
13
|
* partition read observed.
|
|
@@ -51,22 +45,6 @@ const rows_1 = require("../internal/rows");
|
|
|
51
45
|
* the read never saw still survives the pass, which is why the thread should be
|
|
52
46
|
* quiescent.
|
|
53
47
|
*/
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
client: context.client,
|
|
58
|
-
tableName: context.tableName,
|
|
59
|
-
params: (0, rows_1.partitionQuery)(context.tableName, (0, rows_1.partitionKey)(thread), { consistent: true }),
|
|
60
|
-
logger: context.logger,
|
|
61
|
-
retry: (0, retry_1.retryFor)(context, options.signal),
|
|
62
|
-
signal: options.signal,
|
|
63
|
-
offloader: context.offloader,
|
|
64
|
-
operation: 'deleteThread',
|
|
65
|
-
ownsSortKey: rows_1.isCheckpointerSortKey,
|
|
66
|
-
descriptorsOf: rows_1.checkpointRowDescriptors,
|
|
67
|
-
idAttribute: rows_1.WRITE_GROUP_ATTRIBUTE,
|
|
68
|
-
unitOf: rows_1.checkpointRowUnit,
|
|
69
|
-
kindOf: rows_1.checkpointRowKind,
|
|
70
|
-
scope: [thread],
|
|
71
|
-
});
|
|
72
|
-
}
|
|
48
|
+
export declare function deleteThread(context: CheckpointerContext, threadId: string, options?: {
|
|
49
|
+
signal?: AbortSignal;
|
|
50
|
+
}): Promise<void>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { deletePartitionRows } from '../../shared/dynamodb/partition-delete.js';
|
|
2
|
+
import { retryFor } from '../../shared/dynamodb/retry.js';
|
|
3
|
+
import { parseThreadId } from '../internal/parse.js';
|
|
4
|
+
import { checkpointRowDescriptors, checkpointRowKind, checkpointRowUnit, isCheckpointerSortKey, partitionKey, partitionQuery, WRITE_GROUP_ATTRIBUTE, } from '../internal/rows.js';
|
|
5
|
+
export async function deleteThread(context, threadId, options = {}) {
|
|
6
|
+
const thread = parseThreadId(threadId);
|
|
7
|
+
await deletePartitionRows({
|
|
8
|
+
client: context.client,
|
|
9
|
+
tableName: context.tableName,
|
|
10
|
+
params: partitionQuery(context.tableName, partitionKey(thread), { consistent: true }),
|
|
11
|
+
logger: context.logger,
|
|
12
|
+
retry: retryFor(context, options.signal),
|
|
13
|
+
signal: options.signal,
|
|
14
|
+
offloader: context.offloader,
|
|
15
|
+
operation: 'deleteThread',
|
|
16
|
+
ownsSortKey: isCheckpointerSortKey,
|
|
17
|
+
descriptorsOf: checkpointRowDescriptors,
|
|
18
|
+
idAttribute: WRITE_GROUP_ATTRIBUTE,
|
|
19
|
+
unitOf: checkpointRowUnit,
|
|
20
|
+
kindOf: checkpointRowKind,
|
|
21
|
+
scope: [thread],
|
|
22
|
+
});
|
|
23
|
+
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Hides which checkpoint a read config resolves to.
|
|
4
3
|
*
|
|
@@ -8,10 +7,9 @@
|
|
|
8
7
|
* as the reference saver answers. That the read is strongly consistent, so a
|
|
9
8
|
* checkpoint just written is always seen, is fixed here too.
|
|
10
9
|
*/
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const read_1 = require("../internal/read");
|
|
10
|
+
import type { RunnableConfig } from '@langchain/core/runnables';
|
|
11
|
+
import type { CheckpointTuple } from '@langchain/langgraph-checkpoint';
|
|
12
|
+
import type { CheckpointerContext } from '../internal/setup.js';
|
|
15
13
|
/**
|
|
16
14
|
* One checkpoint with its metadata and pending writes.
|
|
17
15
|
*
|
|
@@ -24,8 +22,9 @@ const read_1 = require("../internal/read");
|
|
|
24
22
|
* `config.signal` — cancels the reads; checked before any of them.
|
|
25
23
|
*
|
|
26
24
|
* Returns: the tuple, or undefined for an unknown thread, an unknown
|
|
27
|
-
* checkpoint, a config naming no thread, or a META row whose PAYLOAD row is
|
|
28
|
-
*
|
|
25
|
+
* checkpoint, a config naming no thread, or a META row whose PAYLOAD row is
|
|
26
|
+
* gone — a thread mid-delete, or an expiry sweep that reached the PAYLOAD row
|
|
27
|
+
* first; the two are written in one transaction, so no write leaves that gap.
|
|
29
28
|
*
|
|
30
29
|
* Throws: `VALIDATION`, before any read, naming `config`, `configurable` or
|
|
31
30
|
* `signal` for a config of the wrong shape, or `thread_id`, `checkpoint_ns`,
|
|
@@ -34,20 +33,4 @@ const read_1 = require("../internal/read");
|
|
|
34
33
|
*
|
|
35
34
|
* Guarantees: strongly consistent, so a checkpoint just written is always seen.
|
|
36
35
|
*/
|
|
37
|
-
|
|
38
|
-
const parsed = (0, parse_1.parseConfig)(config);
|
|
39
|
-
if (parsed.threadId === undefined)
|
|
40
|
-
return undefined;
|
|
41
|
-
const address = {
|
|
42
|
-
threadId: parsed.threadId,
|
|
43
|
-
checkpointNs: parsed.checkpointNs ?? parse_1.ROOT_NAMESPACE,
|
|
44
|
-
checkpointId: parsed.checkpointId,
|
|
45
|
-
};
|
|
46
|
-
const meta = await (0, read_1.fetchTargetMeta)(context, address, parsed.signal);
|
|
47
|
-
if (!meta)
|
|
48
|
-
return undefined;
|
|
49
|
-
return (0, read_1.assembleTuple)(context, { threadId: address.threadId, checkpointNs: address.checkpointNs }, meta, {
|
|
50
|
-
signal: parsed.signal,
|
|
51
|
-
consistent: true,
|
|
52
|
-
});
|
|
53
|
-
}
|
|
36
|
+
export declare function getCheckpointTuple(context: CheckpointerContext, config: RunnableConfig): Promise<CheckpointTuple | undefined>;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { parseConfig, ROOT_NAMESPACE } from '../internal/parse.js';
|
|
2
|
+
import { assembleTuple, fetchTargetMeta } from '../internal/read.js';
|
|
3
|
+
export async function getCheckpointTuple(context, config) {
|
|
4
|
+
const parsed = parseConfig(config);
|
|
5
|
+
if (parsed.threadId === undefined)
|
|
6
|
+
return undefined;
|
|
7
|
+
const address = {
|
|
8
|
+
threadId: parsed.threadId,
|
|
9
|
+
checkpointNs: parsed.checkpointNs ?? ROOT_NAMESPACE,
|
|
10
|
+
checkpointId: parsed.checkpointId,
|
|
11
|
+
};
|
|
12
|
+
const meta = await fetchTargetMeta(context, address, parsed.signal);
|
|
13
|
+
if (!meta)
|
|
14
|
+
return undefined;
|
|
15
|
+
return assembleTuple(context, { threadId: address.threadId, checkpointNs: address.checkpointNs }, meta, {
|
|
16
|
+
signal: parsed.signal,
|
|
17
|
+
consistent: true,
|
|
18
|
+
});
|
|
19
|
+
}
|