@farukada/aws-langgraph-dynamodb-ts 0.9.0 → 1.0.0-rc.1
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 +282 -49
- package/dist/checkpointer/actions/delete-thread.d.ts +3 -2
- package/dist/checkpointer/actions/delete-thread.js +5 -2
- package/dist/checkpointer/actions/get-tuple.d.ts +3 -2
- package/dist/checkpointer/actions/get-tuple.js +10 -4
- package/dist/checkpointer/actions/list.d.ts +14 -4
- package/dist/checkpointer/actions/list.js +89 -63
- package/dist/checkpointer/actions/put-writes.d.ts +5 -5
- package/dist/checkpointer/actions/put-writes.js +12 -41
- package/dist/checkpointer/actions/put.d.ts +10 -3
- package/dist/checkpointer/actions/put.js +42 -12
- package/dist/checkpointer/internal/assemble.d.ts +10 -3
- package/dist/checkpointer/internal/assemble.js +7 -6
- package/dist/checkpointer/internal/checkpoint-write-verify.d.ts +24 -0
- package/dist/checkpointer/internal/checkpoint-write-verify.js +67 -0
- package/dist/checkpointer/internal/configurable.d.ts +0 -1
- package/dist/checkpointer/internal/configurable.js +10 -9
- package/dist/checkpointer/internal/fetch.d.ts +14 -5
- package/dist/checkpointer/internal/fetch.js +56 -14
- package/dist/checkpointer/internal/filter-match.d.ts +3 -2
- package/dist/checkpointer/internal/filter-match.js +4 -3
- package/dist/checkpointer/internal/item-reader.d.ts +17 -6
- package/dist/checkpointer/internal/item-reader.js +39 -14
- package/dist/checkpointer/internal/item-writer.d.ts +12 -3
- package/dist/checkpointer/internal/item-writer.js +24 -9
- package/dist/checkpointer/internal/keys.d.ts +11 -1
- package/dist/checkpointer/internal/keys.js +33 -3
- package/dist/checkpointer/internal/list-scope.d.ts +61 -0
- package/dist/checkpointer/internal/list-scope.js +108 -0
- package/dist/checkpointer/internal/pending-sends.d.ts +13 -0
- package/dist/checkpointer/internal/pending-sends.js +29 -0
- package/dist/checkpointer/internal/query.d.ts +2 -1
- package/dist/checkpointer/internal/query.js +9 -3
- package/dist/checkpointer/internal/regular-write.d.ts +28 -0
- package/dist/checkpointer/internal/regular-write.js +66 -0
- package/dist/checkpointer/internal/setup.d.ts +3 -1
- package/dist/checkpointer/internal/setup.js +10 -8
- package/dist/checkpointer/internal/special-write-cas.d.ts +1 -2
- package/dist/checkpointer/internal/special-write-cas.js +9 -9
- package/dist/checkpointer/internal/special-write-cleanup.d.ts +1 -2
- package/dist/checkpointer/internal/special-write-cleanup.js +10 -7
- package/dist/checkpointer/internal/special-write-verify.d.ts +0 -1
- package/dist/checkpointer/internal/special-write-verify.js +18 -3
- package/dist/checkpointer/internal/stored-channels.d.ts +31 -0
- package/dist/checkpointer/internal/stored-channels.js +70 -0
- package/dist/checkpointer/internal/validation.d.ts +11 -6
- package/dist/checkpointer/internal/validation.js +19 -9
- package/dist/checkpointer/internal/write-guard.d.ts +8 -1
- package/dist/checkpointer/internal/write-guard.js +16 -7
- package/dist/checkpointer/internal/write-index.d.ts +0 -1
- package/dist/checkpointer/internal/write-index.js +0 -1
- package/dist/checkpointer/saver.d.ts +50 -10
- package/dist/checkpointer/saver.js +59 -17
- package/dist/checkpointer/types.d.ts +8 -1
- package/dist/checkpointer/types.js +0 -1
- package/dist/factory/factory.d.ts +22 -25
- package/dist/factory/factory.js +58 -18
- package/dist/factory/types.d.ts +57 -0
- package/dist/factory/types.js +2 -0
- package/dist/history/actions/add-messages.d.ts +1 -2
- package/dist/history/actions/add-messages.js +4 -4
- package/dist/history/actions/clear.d.ts +3 -2
- package/dist/history/actions/clear.js +5 -2
- package/dist/history/actions/get-messages.d.ts +13 -6
- package/dist/history/actions/get-messages.js +63 -42
- package/dist/history/actions/list-sessions.d.ts +1 -1
- package/dist/history/actions/list-sessions.js +8 -12
- package/dist/history/actions/reconcile-count.d.ts +1 -2
- package/dist/history/actions/reconcile-count.js +20 -7
- package/dist/history/chat-message-history.d.ts +51 -26
- package/dist/history/chat-message-history.js +60 -30
- package/dist/history/internal/append-saga.d.ts +7 -2
- package/dist/history/internal/append-saga.js +58 -14
- package/dist/history/internal/compensation.d.ts +6 -2
- package/dist/history/internal/compensation.js +14 -6
- package/dist/history/internal/item-mapper.d.ts +0 -3
- package/dist/history/internal/item-mapper.js +2 -8
- package/dist/history/internal/keys.d.ts +0 -1
- package/dist/history/internal/keys.js +0 -1
- package/dist/history/internal/message-chunker.d.ts +0 -1
- package/dist/history/internal/message-chunker.js +0 -1
- package/dist/history/internal/message-transaction.d.ts +0 -1
- package/dist/history/internal/message-transaction.js +3 -2
- package/dist/history/internal/message-window.d.ts +17 -0
- package/dist/history/internal/message-window.js +49 -0
- package/dist/history/internal/query.d.ts +16 -3
- package/dist/history/internal/query.js +13 -5
- package/dist/history/internal/session-count.d.ts +8 -2
- package/dist/history/internal/session-count.js +14 -8
- package/dist/history/internal/session-title.d.ts +0 -1
- package/dist/history/internal/session-title.js +1 -2
- package/dist/history/internal/session-update.d.ts +0 -1
- package/dist/history/internal/session-update.js +0 -1
- package/dist/history/internal/setup.d.ts +3 -1
- package/dist/history/internal/setup.js +16 -8
- package/dist/history/internal/title-generator.d.ts +0 -1
- package/dist/history/internal/title-generator.js +19 -3
- package/dist/history/internal/ttl-anchor.d.ts +1 -2
- package/dist/history/internal/ttl-anchor.js +5 -5
- package/dist/history/internal/validation.d.ts +19 -3
- package/dist/history/internal/validation.js +41 -4
- package/dist/history/session-adapter.d.ts +9 -3
- package/dist/history/session-adapter.js +6 -3
- package/dist/history/types.d.ts +23 -2
- package/dist/history/types.js +0 -1
- package/dist/index.d.ts +12 -5
- package/dist/index.js +5 -3
- package/dist/shared/clock.d.ts +6 -1
- package/dist/shared/clock.js +9 -1
- package/dist/shared/codec/codec.d.ts +26 -17
- package/dist/shared/codec/codec.js +46 -24
- package/dist/shared/codec/compression.d.ts +1 -2
- package/dist/shared/codec/compression.js +2 -3
- package/dist/shared/codec/descriptor-keys.d.ts +11 -3
- package/dist/shared/codec/descriptor-keys.js +2 -2
- package/dist/shared/codec/encode.d.ts +13 -0
- package/dist/shared/codec/encode.js +43 -0
- package/dist/shared/codec/json-serde.d.ts +0 -1
- package/dist/shared/codec/json-serde.js +0 -1
- package/dist/shared/codec/payload-loss.d.ts +12 -0
- package/dist/shared/codec/payload-loss.js +38 -0
- package/dist/shared/codec/s3/adapter-config.d.ts +13 -0
- package/dist/shared/codec/s3/adapter-config.js +22 -0
- package/dist/shared/codec/s3/bounded-body.d.ts +14 -0
- package/dist/shared/codec/s3/bounded-body.js +47 -0
- package/dist/shared/codec/s3/client-types.d.ts +34 -0
- package/dist/shared/codec/s3/client-types.js +7 -0
- package/dist/shared/codec/s3/client.d.ts +11 -5
- package/dist/shared/codec/s3/client.js +25 -3
- package/dist/shared/codec/s3/config.d.ts +32 -5
- package/dist/shared/codec/s3/config.js +37 -5
- package/dist/shared/codec/s3/delete.d.ts +0 -1
- package/dist/shared/codec/s3/delete.js +0 -1
- package/dist/shared/codec/s3/key-scope.d.ts +23 -0
- package/dist/shared/codec/s3/key-scope.js +44 -0
- package/dist/shared/codec/s3/lifecycle.d.ts +11 -5
- package/dist/shared/codec/s3/lifecycle.js +32 -16
- package/dist/shared/codec/s3/offloader.d.ts +6 -2
- package/dist/shared/codec/s3/offloader.js +21 -3
- package/dist/shared/codec/s3/orphans.d.ts +6 -1
- package/dist/shared/codec/s3/orphans.js +15 -2
- package/dist/shared/codec/s3/read-write.d.ts +7 -3
- package/dist/shared/codec/s3/read-write.js +16 -8
- package/dist/shared/codec/s3/retry.d.ts +4 -4
- package/dist/shared/codec/s3/retry.js +13 -16
- package/dist/shared/concurrency.d.ts +6 -0
- package/dist/shared/concurrency.js +30 -0
- package/dist/shared/constants.d.ts +53 -5
- package/dist/shared/constants.js +55 -7
- package/dist/shared/dynamodb/abort.d.ts +9 -0
- package/dist/shared/dynamodb/abort.js +27 -0
- package/dist/shared/dynamodb/backoff.d.ts +4 -4
- package/dist/shared/dynamodb/backoff.js +7 -7
- package/dist/shared/dynamodb/batch-write.d.ts +0 -1
- package/dist/shared/dynamodb/batch-write.js +0 -1
- package/dist/shared/dynamodb/cancellation.d.ts +0 -1
- package/dist/shared/dynamodb/cancellation.js +0 -1
- package/dist/shared/dynamodb/client.d.ts +9 -2
- package/dist/shared/dynamodb/client.js +24 -1
- package/dist/shared/dynamodb/conditional-put.d.ts +18 -2
- package/dist/shared/dynamodb/conditional-put.js +19 -2
- package/dist/shared/dynamodb/drain-unprocessed.d.ts +3 -1
- package/dist/shared/dynamodb/drain-unprocessed.js +1 -2
- package/dist/shared/dynamodb/expiry.d.ts +16 -0
- package/dist/shared/dynamodb/expiry.js +29 -0
- package/dist/shared/dynamodb/paginate-core.d.ts +5 -3
- package/dist/shared/dynamodb/paginate-core.js +47 -17
- package/dist/shared/dynamodb/paginate.d.ts +0 -1
- package/dist/shared/dynamodb/paginate.js +1 -2
- package/dist/shared/dynamodb/partition-delete.d.ts +7 -1
- package/dist/shared/dynamodb/partition-delete.js +4 -3
- package/dist/shared/dynamodb/retry-classifier.d.ts +10 -2
- package/dist/shared/dynamodb/retry-classifier.js +42 -11
- package/dist/shared/dynamodb/retry-policy.d.ts +26 -0
- package/dist/shared/dynamodb/retry-policy.js +22 -0
- package/dist/shared/dynamodb/retry.d.ts +14 -1
- package/dist/shared/dynamodb/retry.js +11 -7
- package/dist/shared/dynamodb/scan.d.ts +0 -1
- package/dist/shared/dynamodb/scan.js +1 -2
- package/dist/shared/dynamodb/types.d.ts +1 -2
- package/dist/shared/dynamodb/types.js +0 -1
- package/dist/shared/errors/base-error.d.ts +14 -6
- package/dist/shared/errors/base-error.js +8 -9
- package/dist/shared/errors/boundary.d.ts +18 -0
- package/dist/shared/errors/boundary.js +46 -0
- package/dist/shared/errors/error-code.d.ts +2 -2
- package/dist/shared/errors/error-code.js +1 -1
- package/dist/shared/errors/errors.d.ts +13 -13
- package/dist/shared/errors/errors.js +18 -16
- package/dist/shared/errors/upstream-error.d.ts +16 -0
- package/dist/shared/errors/upstream-error.js +27 -0
- package/dist/shared/errors/wrap-error.d.ts +0 -9
- package/dist/shared/errors/wrap-error.js +0 -15
- package/dist/shared/logging/logger.d.ts +6 -2
- package/dist/shared/logging/logger.js +0 -1
- package/dist/shared/logging/redaction-walk.d.ts +2 -2
- package/dist/shared/logging/redaction-walk.js +38 -18
- package/dist/shared/logging/redaction.d.ts +9 -5
- package/dist/shared/logging/redaction.js +19 -4
- package/dist/shared/logging/secret-patterns.d.ts +21 -3
- package/dist/shared/logging/secret-patterns.js +32 -6
- package/dist/shared/options.d.ts +9 -4
- package/dist/shared/options.js +0 -1
- package/dist/shared/ulid.d.ts +15 -2
- package/dist/shared/ulid.js +35 -3
- package/dist/shared/validation/options.d.ts +8 -0
- package/dist/shared/validation/options.js +90 -0
- package/dist/shared/validation/primitives.d.ts +14 -10
- package/dist/shared/validation/primitives.js +23 -25
- package/dist/shared/validation/ttl.d.ts +14 -7
- package/dist/shared/validation/ttl.js +29 -11
- package/dist/store/actions/get.d.ts +11 -3
- package/dist/store/actions/get.js +52 -14
- package/dist/store/actions/list-namespaces.d.ts +0 -1
- package/dist/store/actions/list-namespaces.js +10 -6
- package/dist/store/actions/put.d.ts +0 -1
- package/dist/store/actions/put.js +24 -13
- package/dist/store/actions/reconcile-vector-index.d.ts +3 -2
- package/dist/store/actions/reconcile-vector-index.js +2 -3
- package/dist/store/actions/search.d.ts +1 -2
- package/dist/store/actions/search.js +11 -38
- package/dist/store/internal/backend-search.d.ts +1 -2
- package/dist/store/internal/backend-search.js +12 -6
- package/dist/store/internal/batch-plan.d.ts +11 -0
- package/dist/store/internal/batch-plan.js +52 -0
- package/dist/store/internal/candidates.d.ts +23 -0
- package/dist/store/internal/candidates.js +94 -0
- package/dist/store/internal/filter.d.ts +0 -1
- package/dist/store/internal/filter.js +0 -1
- package/dist/store/internal/index-reconcile.d.ts +5 -6
- package/dist/store/internal/index-reconcile.js +25 -12
- package/dist/store/internal/index-sync.d.ts +0 -1
- package/dist/store/internal/index-sync.js +0 -1
- package/dist/store/internal/item-mapper.d.ts +5 -3
- package/dist/store/internal/item-mapper.js +14 -6
- package/dist/store/internal/keys.d.ts +0 -1
- package/dist/store/internal/keys.js +0 -1
- package/dist/store/internal/namespace-match.d.ts +0 -1
- package/dist/store/internal/namespace-match.js +0 -1
- package/dist/store/internal/option-validation.d.ts +13 -0
- package/dist/store/internal/option-validation.js +77 -0
- package/dist/store/internal/overwrite-swap.d.ts +0 -1
- package/dist/store/internal/overwrite-swap.js +10 -4
- package/dist/store/internal/persist.d.ts +3 -2
- package/dist/store/internal/persist.js +16 -11
- package/dist/store/internal/query.d.ts +6 -1
- package/dist/store/internal/query.js +17 -1
- package/dist/store/internal/ranker.d.ts +7 -2
- package/dist/store/internal/ranker.js +10 -2
- package/dist/store/internal/read-existing.d.ts +9 -5
- package/dist/store/internal/read-existing.js +22 -10
- package/dist/store/internal/score-direction.d.ts +0 -1
- package/dist/store/internal/score-direction.js +0 -1
- package/dist/store/internal/search-filter.d.ts +0 -1
- package/dist/store/internal/search-filter.js +0 -1
- package/dist/store/internal/semantic-search.d.ts +26 -5
- package/dist/store/internal/semantic-search.js +59 -19
- package/dist/store/internal/setup.d.ts +5 -13
- package/dist/store/internal/setup.js +11 -63
- package/dist/store/internal/text-path.d.ts +17 -0
- package/dist/store/internal/text-path.js +147 -0
- package/dist/store/internal/validation.d.ts +8 -3
- package/dist/store/internal/validation.js +21 -5
- package/dist/store/internal/write-verify.d.ts +15 -10
- package/dist/store/internal/write-verify.js +24 -21
- package/dist/store/store.d.ts +37 -9
- package/dist/store/store.js +52 -17
- package/dist/store/types.d.ts +6 -2
- package/dist/store/types.js +0 -1
- package/dist/store/vector-backend.d.ts +0 -1
- package/dist/store/vector-backend.js +0 -1
- package/package.json +21 -15
- package/dist/checkpointer/actions/delete-thread.d.ts.map +0 -1
- package/dist/checkpointer/actions/delete-thread.js.map +0 -1
- package/dist/checkpointer/actions/get-tuple.d.ts.map +0 -1
- package/dist/checkpointer/actions/get-tuple.js.map +0 -1
- package/dist/checkpointer/actions/list.d.ts.map +0 -1
- package/dist/checkpointer/actions/list.js.map +0 -1
- package/dist/checkpointer/actions/put-writes.d.ts.map +0 -1
- package/dist/checkpointer/actions/put-writes.js.map +0 -1
- package/dist/checkpointer/actions/put.d.ts.map +0 -1
- package/dist/checkpointer/actions/put.js.map +0 -1
- package/dist/checkpointer/internal/assemble.d.ts.map +0 -1
- package/dist/checkpointer/internal/assemble.js.map +0 -1
- package/dist/checkpointer/internal/configurable.d.ts.map +0 -1
- package/dist/checkpointer/internal/configurable.js.map +0 -1
- package/dist/checkpointer/internal/fetch.d.ts.map +0 -1
- package/dist/checkpointer/internal/fetch.js.map +0 -1
- package/dist/checkpointer/internal/filter-match.d.ts.map +0 -1
- package/dist/checkpointer/internal/filter-match.js.map +0 -1
- package/dist/checkpointer/internal/item-reader.d.ts.map +0 -1
- package/dist/checkpointer/internal/item-reader.js.map +0 -1
- package/dist/checkpointer/internal/item-writer.d.ts.map +0 -1
- package/dist/checkpointer/internal/item-writer.js.map +0 -1
- package/dist/checkpointer/internal/keys.d.ts.map +0 -1
- package/dist/checkpointer/internal/keys.js.map +0 -1
- package/dist/checkpointer/internal/query.d.ts.map +0 -1
- package/dist/checkpointer/internal/query.js.map +0 -1
- package/dist/checkpointer/internal/setup.d.ts.map +0 -1
- package/dist/checkpointer/internal/setup.js.map +0 -1
- package/dist/checkpointer/internal/special-write-cas.d.ts.map +0 -1
- package/dist/checkpointer/internal/special-write-cas.js.map +0 -1
- package/dist/checkpointer/internal/special-write-cleanup.d.ts.map +0 -1
- package/dist/checkpointer/internal/special-write-cleanup.js.map +0 -1
- package/dist/checkpointer/internal/special-write-verify.d.ts.map +0 -1
- package/dist/checkpointer/internal/special-write-verify.js.map +0 -1
- package/dist/checkpointer/internal/validation.d.ts.map +0 -1
- package/dist/checkpointer/internal/validation.js.map +0 -1
- package/dist/checkpointer/internal/write-guard.d.ts.map +0 -1
- package/dist/checkpointer/internal/write-guard.js.map +0 -1
- package/dist/checkpointer/internal/write-index.d.ts.map +0 -1
- package/dist/checkpointer/internal/write-index.js.map +0 -1
- package/dist/checkpointer/saver.d.ts.map +0 -1
- package/dist/checkpointer/saver.js.map +0 -1
- package/dist/checkpointer/types.d.ts.map +0 -1
- package/dist/checkpointer/types.js.map +0 -1
- package/dist/factory/factory.d.ts.map +0 -1
- package/dist/factory/factory.js.map +0 -1
- package/dist/history/actions/add-messages.d.ts.map +0 -1
- package/dist/history/actions/add-messages.js.map +0 -1
- package/dist/history/actions/clear.d.ts.map +0 -1
- package/dist/history/actions/clear.js.map +0 -1
- package/dist/history/actions/get-messages.d.ts.map +0 -1
- package/dist/history/actions/get-messages.js.map +0 -1
- package/dist/history/actions/list-sessions.d.ts.map +0 -1
- package/dist/history/actions/list-sessions.js.map +0 -1
- package/dist/history/actions/reconcile-count.d.ts.map +0 -1
- package/dist/history/actions/reconcile-count.js.map +0 -1
- package/dist/history/chat-message-history.d.ts.map +0 -1
- package/dist/history/chat-message-history.js.map +0 -1
- package/dist/history/internal/append-saga.d.ts.map +0 -1
- package/dist/history/internal/append-saga.js.map +0 -1
- package/dist/history/internal/compensation.d.ts.map +0 -1
- package/dist/history/internal/compensation.js.map +0 -1
- package/dist/history/internal/item-mapper.d.ts.map +0 -1
- package/dist/history/internal/item-mapper.js.map +0 -1
- package/dist/history/internal/keys.d.ts.map +0 -1
- package/dist/history/internal/keys.js.map +0 -1
- package/dist/history/internal/message-chunker.d.ts.map +0 -1
- package/dist/history/internal/message-chunker.js.map +0 -1
- package/dist/history/internal/message-transaction.d.ts.map +0 -1
- package/dist/history/internal/message-transaction.js.map +0 -1
- package/dist/history/internal/query.d.ts.map +0 -1
- package/dist/history/internal/query.js.map +0 -1
- package/dist/history/internal/session-count.d.ts.map +0 -1
- package/dist/history/internal/session-count.js.map +0 -1
- package/dist/history/internal/session-title.d.ts.map +0 -1
- package/dist/history/internal/session-title.js.map +0 -1
- package/dist/history/internal/session-update.d.ts.map +0 -1
- package/dist/history/internal/session-update.js.map +0 -1
- package/dist/history/internal/setup.d.ts.map +0 -1
- package/dist/history/internal/setup.js.map +0 -1
- package/dist/history/internal/title-generator.d.ts.map +0 -1
- package/dist/history/internal/title-generator.js.map +0 -1
- package/dist/history/internal/ttl-anchor.d.ts.map +0 -1
- package/dist/history/internal/ttl-anchor.js.map +0 -1
- package/dist/history/internal/validation.d.ts.map +0 -1
- package/dist/history/internal/validation.js.map +0 -1
- package/dist/history/session-adapter.d.ts.map +0 -1
- package/dist/history/session-adapter.js.map +0 -1
- package/dist/history/types.d.ts.map +0 -1
- package/dist/history/types.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/shared/clock.d.ts.map +0 -1
- package/dist/shared/clock.js.map +0 -1
- package/dist/shared/codec/codec.d.ts.map +0 -1
- package/dist/shared/codec/codec.js.map +0 -1
- package/dist/shared/codec/compression.d.ts.map +0 -1
- package/dist/shared/codec/compression.js.map +0 -1
- package/dist/shared/codec/descriptor-keys.d.ts.map +0 -1
- package/dist/shared/codec/descriptor-keys.js.map +0 -1
- package/dist/shared/codec/json-serde.d.ts.map +0 -1
- package/dist/shared/codec/json-serde.js.map +0 -1
- package/dist/shared/codec/s3/client.d.ts.map +0 -1
- package/dist/shared/codec/s3/client.js.map +0 -1
- package/dist/shared/codec/s3/config.d.ts.map +0 -1
- package/dist/shared/codec/s3/config.js.map +0 -1
- package/dist/shared/codec/s3/delete.d.ts.map +0 -1
- package/dist/shared/codec/s3/delete.js.map +0 -1
- package/dist/shared/codec/s3/lifecycle.d.ts.map +0 -1
- package/dist/shared/codec/s3/lifecycle.js.map +0 -1
- package/dist/shared/codec/s3/offloader.d.ts.map +0 -1
- package/dist/shared/codec/s3/offloader.js.map +0 -1
- package/dist/shared/codec/s3/orphans.d.ts.map +0 -1
- package/dist/shared/codec/s3/orphans.js.map +0 -1
- package/dist/shared/codec/s3/read-write.d.ts.map +0 -1
- package/dist/shared/codec/s3/read-write.js.map +0 -1
- package/dist/shared/codec/s3/retry.d.ts.map +0 -1
- package/dist/shared/codec/s3/retry.js.map +0 -1
- package/dist/shared/constants.d.ts.map +0 -1
- package/dist/shared/constants.js.map +0 -1
- package/dist/shared/dynamodb/backoff.d.ts.map +0 -1
- package/dist/shared/dynamodb/backoff.js.map +0 -1
- package/dist/shared/dynamodb/batch-write.d.ts.map +0 -1
- package/dist/shared/dynamodb/batch-write.js.map +0 -1
- package/dist/shared/dynamodb/cancellation.d.ts.map +0 -1
- package/dist/shared/dynamodb/cancellation.js.map +0 -1
- package/dist/shared/dynamodb/client.d.ts.map +0 -1
- package/dist/shared/dynamodb/client.js.map +0 -1
- package/dist/shared/dynamodb/conditional-put.d.ts.map +0 -1
- package/dist/shared/dynamodb/conditional-put.js.map +0 -1
- package/dist/shared/dynamodb/drain-unprocessed.d.ts.map +0 -1
- package/dist/shared/dynamodb/drain-unprocessed.js.map +0 -1
- package/dist/shared/dynamodb/paginate-core.d.ts.map +0 -1
- package/dist/shared/dynamodb/paginate-core.js.map +0 -1
- package/dist/shared/dynamodb/paginate.d.ts.map +0 -1
- package/dist/shared/dynamodb/paginate.js.map +0 -1
- package/dist/shared/dynamodb/partition-delete.d.ts.map +0 -1
- package/dist/shared/dynamodb/partition-delete.js.map +0 -1
- package/dist/shared/dynamodb/retry-classifier.d.ts.map +0 -1
- package/dist/shared/dynamodb/retry-classifier.js.map +0 -1
- package/dist/shared/dynamodb/retry.d.ts.map +0 -1
- package/dist/shared/dynamodb/retry.js.map +0 -1
- package/dist/shared/dynamodb/scan.d.ts.map +0 -1
- package/dist/shared/dynamodb/scan.js.map +0 -1
- package/dist/shared/dynamodb/types.d.ts.map +0 -1
- package/dist/shared/dynamodb/types.js.map +0 -1
- package/dist/shared/errors/base-error.d.ts.map +0 -1
- package/dist/shared/errors/base-error.js.map +0 -1
- package/dist/shared/errors/error-code.d.ts.map +0 -1
- package/dist/shared/errors/error-code.js.map +0 -1
- package/dist/shared/errors/errors.d.ts.map +0 -1
- package/dist/shared/errors/errors.js.map +0 -1
- package/dist/shared/errors/wrap-error.d.ts.map +0 -1
- package/dist/shared/errors/wrap-error.js.map +0 -1
- package/dist/shared/logging/logger.d.ts.map +0 -1
- package/dist/shared/logging/logger.js.map +0 -1
- package/dist/shared/logging/redaction-walk.d.ts.map +0 -1
- package/dist/shared/logging/redaction-walk.js.map +0 -1
- package/dist/shared/logging/redaction.d.ts.map +0 -1
- package/dist/shared/logging/redaction.js.map +0 -1
- package/dist/shared/logging/secret-patterns.d.ts.map +0 -1
- package/dist/shared/logging/secret-patterns.js.map +0 -1
- package/dist/shared/options.d.ts.map +0 -1
- package/dist/shared/options.js.map +0 -1
- package/dist/shared/ulid.d.ts.map +0 -1
- package/dist/shared/ulid.js.map +0 -1
- package/dist/shared/validation/primitives.d.ts.map +0 -1
- package/dist/shared/validation/primitives.js.map +0 -1
- package/dist/shared/validation/ttl.d.ts.map +0 -1
- package/dist/shared/validation/ttl.js.map +0 -1
- package/dist/store/actions/get.d.ts.map +0 -1
- package/dist/store/actions/get.js.map +0 -1
- package/dist/store/actions/list-namespaces.d.ts.map +0 -1
- package/dist/store/actions/list-namespaces.js.map +0 -1
- package/dist/store/actions/put.d.ts.map +0 -1
- package/dist/store/actions/put.js.map +0 -1
- package/dist/store/actions/reconcile-vector-index.d.ts.map +0 -1
- package/dist/store/actions/reconcile-vector-index.js.map +0 -1
- package/dist/store/actions/search.d.ts.map +0 -1
- package/dist/store/actions/search.js.map +0 -1
- package/dist/store/internal/backend-search.d.ts.map +0 -1
- package/dist/store/internal/backend-search.js.map +0 -1
- package/dist/store/internal/filter.d.ts.map +0 -1
- package/dist/store/internal/filter.js.map +0 -1
- package/dist/store/internal/index-reconcile.d.ts.map +0 -1
- package/dist/store/internal/index-reconcile.js.map +0 -1
- package/dist/store/internal/index-sync.d.ts.map +0 -1
- package/dist/store/internal/index-sync.js.map +0 -1
- package/dist/store/internal/item-mapper.d.ts.map +0 -1
- package/dist/store/internal/item-mapper.js.map +0 -1
- package/dist/store/internal/keys.d.ts.map +0 -1
- package/dist/store/internal/keys.js.map +0 -1
- package/dist/store/internal/namespace-match.d.ts.map +0 -1
- package/dist/store/internal/namespace-match.js.map +0 -1
- package/dist/store/internal/overwrite-swap.d.ts.map +0 -1
- package/dist/store/internal/overwrite-swap.js.map +0 -1
- package/dist/store/internal/persist.d.ts.map +0 -1
- package/dist/store/internal/persist.js.map +0 -1
- package/dist/store/internal/query.d.ts.map +0 -1
- package/dist/store/internal/query.js.map +0 -1
- package/dist/store/internal/ranker.d.ts.map +0 -1
- package/dist/store/internal/ranker.js.map +0 -1
- package/dist/store/internal/read-existing.d.ts.map +0 -1
- package/dist/store/internal/read-existing.js.map +0 -1
- package/dist/store/internal/score-direction.d.ts.map +0 -1
- package/dist/store/internal/score-direction.js.map +0 -1
- package/dist/store/internal/search-filter.d.ts.map +0 -1
- package/dist/store/internal/search-filter.js.map +0 -1
- package/dist/store/internal/semantic-search.d.ts.map +0 -1
- package/dist/store/internal/semantic-search.js.map +0 -1
- package/dist/store/internal/setup.d.ts.map +0 -1
- package/dist/store/internal/setup.js.map +0 -1
- package/dist/store/internal/validation.d.ts.map +0 -1
- package/dist/store/internal/validation.js.map +0 -1
- package/dist/store/internal/write-verify.d.ts.map +0 -1
- package/dist/store/internal/write-verify.js.map +0 -1
- package/dist/store/store.d.ts.map +0 -1
- package/dist/store/store.js.map +0 -1
- package/dist/store/types.d.ts.map +0 -1
- package/dist/store/types.js.map +0 -1
- package/dist/store/vector-backend.d.ts.map +0 -1
- package/dist/store/vector-backend.js.map +0 -1
|
@@ -2,57 +2,78 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getMessages = getMessages;
|
|
4
4
|
const messages_1 = require("@langchain/core/messages");
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
5
|
+
const codec_1 = require("../../shared/codec/codec");
|
|
6
|
+
const payload_loss_1 = require("../../shared/codec/payload-loss");
|
|
7
|
+
const concurrency_1 = require("../../shared/concurrency");
|
|
8
|
+
const constants_1 = require("../../shared/constants");
|
|
9
|
+
const wrap_error_1 = require("../../shared/errors/wrap-error");
|
|
10
|
+
const message_window_1 = require("../internal/message-window");
|
|
8
11
|
const validation_1 = require("../internal/validation");
|
|
9
|
-
function isExpired(item, nowSeconds) {
|
|
10
|
-
return item.ttl !== undefined && item.ttl <= nowSeconds;
|
|
11
|
-
}
|
|
12
12
|
/**
|
|
13
|
-
* Decode one item
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
13
|
+
* Decode one item in two stages so failures are classified by what caused
|
|
14
|
+
* them. Fetching the bytes (an S3 download, decompression) is infrastructure:
|
|
15
|
+
* a transport, throttling or permission failure there is rethrown, because
|
|
16
|
+
* dropping the message would hand the caller a silently truncated conversation
|
|
17
|
+
* that `RunnableWithMessageHistory` then re-persists. Only a *permanent* loss
|
|
18
|
+
* at that stage — the object is gone, or the decompression guard tripped — is
|
|
19
|
+
* corruption. Deserializing and rebuilding the message is pure data handling,
|
|
20
|
+
* so any failure there (bad bytes, a type LangChain cannot rebuild such as a
|
|
21
|
+
* `RemoveMessage`) is corruption too, and is confined to that one message.
|
|
18
22
|
*/
|
|
19
|
-
async function
|
|
23
|
+
async function decodeMessage(context, item, sessionId) {
|
|
24
|
+
const deps = {
|
|
25
|
+
serde: context.serde,
|
|
26
|
+
compression: context.compression,
|
|
27
|
+
offloader: context.offloader,
|
|
28
|
+
};
|
|
29
|
+
let bytes;
|
|
20
30
|
try {
|
|
21
|
-
|
|
31
|
+
bytes = await (0, codec_1.readPayloadBytes)(item.message, deps, [sessionId]);
|
|
22
32
|
}
|
|
23
33
|
catch (error) {
|
|
24
|
-
if (
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
return
|
|
34
|
+
if ((0, payload_loss_1.isPermanentPayloadLoss)(error))
|
|
35
|
+
return { kind: 'corrupt', error: error };
|
|
36
|
+
throw error;
|
|
37
|
+
}
|
|
38
|
+
try {
|
|
39
|
+
const stored = (await context.serde.loadsTyped(item.message.serdeType, bytes));
|
|
40
|
+
return { kind: 'ok', message: (0, messages_1.mapStoredMessagesToChatMessages)([stored])[0] };
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
return { kind: 'corrupt', error: (0, wrap_error_1.toError)(error) };
|
|
31
44
|
}
|
|
32
45
|
}
|
|
33
46
|
/**
|
|
34
|
-
* Return a session's messages in chronological order
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
47
|
+
* Return a session's messages in chronological order — the whole session, or
|
|
48
|
+
* the window `options` selects: `limit` keeps only the newest `limit`
|
|
49
|
+
* messages, `before` only those appended before that instant (see
|
|
50
|
+
* {@link readWindow}). Items past their TTL are filtered out on read
|
|
51
|
+
* (DynamoDB's background TTL sweep can lag by up to 48h), so the returned
|
|
52
|
+
* history is never stale. A corrupt item — see
|
|
53
|
+
* {@link decodeMessage} for exactly what counts — is handled per
|
|
54
|
+
* `onCorruptMessage`: `'throw'` fails the read with the underlying error;
|
|
55
|
+
* `'skip'` (the default) reports it at `error` with its sort key and returns
|
|
56
|
+
* the rest. Every other failure propagates regardless of the policy.
|
|
38
57
|
*/
|
|
39
|
-
async function getMessages(context, sessionId) {
|
|
58
|
+
async function getMessages(context, sessionId, options = {}) {
|
|
40
59
|
(0, validation_1.validateSessionId)(sessionId);
|
|
41
|
-
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
60
|
+
(0, validation_1.validateMessageWindow)(options);
|
|
61
|
+
const items = await (0, message_window_1.readWindow)(context, sessionId, options);
|
|
62
|
+
/** Offloaded rows cost one S3 GET each, so they decode several at a time; the policy is applied in order. */
|
|
63
|
+
const decoded = await (0, concurrency_1.mapWithConcurrency)(items, constants_1.DEFAULT_READ_CONCURRENCY, (item) => decodeMessage(context, item, sessionId));
|
|
64
|
+
const messages = [];
|
|
65
|
+
decoded.forEach((result, index) => {
|
|
66
|
+
if (result.kind === 'ok') {
|
|
67
|
+
messages.push(result.message);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
if (context.onCorruptMessage === 'throw')
|
|
71
|
+
throw result.error;
|
|
72
|
+
context.logger.error('getMessages: skipped a corrupt message item', {
|
|
73
|
+
sessionId,
|
|
74
|
+
sortKey: items[index].SK,
|
|
75
|
+
reason: result.error.name,
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
return messages;
|
|
57
79
|
}
|
|
58
|
-
//# sourceMappingURL=get-messages.js.map
|
|
@@ -9,5 +9,5 @@ import type { SessionMetadata } from '../types';
|
|
|
9
9
|
export declare function listSessions(context: HistoryContext, options?: {
|
|
10
10
|
maxIterations?: number;
|
|
11
11
|
maxItems?: number;
|
|
12
|
+
signal?: AbortSignal;
|
|
12
13
|
}): Promise<SessionMetadata[]>;
|
|
13
|
-
//# sourceMappingURL=list-sessions.d.ts.map
|
|
@@ -1,17 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.listSessions = listSessions;
|
|
4
|
+
const clock_1 = require("../../shared/clock");
|
|
5
|
+
const expiry_1 = require("../../shared/dynamodb/expiry");
|
|
6
|
+
const retry_policy_1 = require("../../shared/dynamodb/retry-policy");
|
|
4
7
|
const scan_1 = require("../../shared/dynamodb/scan");
|
|
5
8
|
const keys_1 = require("../internal/keys");
|
|
6
|
-
/**
|
|
7
|
-
* True when a session row is past its TTL. DynamoDB's background sweep can lag
|
|
8
|
-
* up to 48h, so an expired session would otherwise keep appearing in listings
|
|
9
|
-
* after `getMessages` had already stopped returning its messages — the same
|
|
10
|
-
* filter that read path applies.
|
|
11
|
-
*/
|
|
12
|
-
function isExpired(item, nowSeconds) {
|
|
13
|
-
return item.ttl !== undefined && item.ttl <= nowSeconds;
|
|
14
|
-
}
|
|
15
9
|
/**
|
|
16
10
|
* List all sessions as metadata summaries, newest-updated first. The scan is
|
|
17
11
|
* filtered to session items so the adapter works on a table shared with the
|
|
@@ -20,8 +14,10 @@ function isExpired(item, nowSeconds) {
|
|
|
20
14
|
*/
|
|
21
15
|
async function listSessions(context, options) {
|
|
22
16
|
const sessions = [];
|
|
23
|
-
const nowSeconds =
|
|
17
|
+
const nowSeconds = (0, clock_1.nowSeconds)();
|
|
24
18
|
for await (const raw of (0, scan_1.paginateScan)({
|
|
19
|
+
retry: (0, retry_policy_1.retryFor)(context, options?.signal),
|
|
20
|
+
signal: options?.signal,
|
|
25
21
|
client: context.client,
|
|
26
22
|
params: {
|
|
27
23
|
TableName: context.tableName,
|
|
@@ -35,7 +31,7 @@ async function listSessions(context, options) {
|
|
|
35
31
|
const item = raw;
|
|
36
32
|
if (item.SK !== keys_1.SESSION_SORT_KEY || typeof item.sessionId !== 'string')
|
|
37
33
|
continue;
|
|
38
|
-
if (
|
|
34
|
+
if ((0, expiry_1.isExpiredRow)(item, nowSeconds))
|
|
39
35
|
continue;
|
|
40
36
|
sessions.push({
|
|
41
37
|
sessionId: item.sessionId,
|
|
@@ -43,6 +39,7 @@ async function listSessions(context, options) {
|
|
|
43
39
|
messageCount: item.messageCount,
|
|
44
40
|
createdAt: item.createdAt,
|
|
45
41
|
updatedAt: item.updatedAt,
|
|
42
|
+
expiresAt: item.ttl === undefined ? undefined : new Date(item.ttl * 1000).toISOString(),
|
|
46
43
|
});
|
|
47
44
|
}
|
|
48
45
|
/**
|
|
@@ -54,4 +51,3 @@ async function listSessions(context, options) {
|
|
|
54
51
|
sessions.sort((a, b) => (a.updatedAt < b.updatedAt ? 1 : a.updatedAt > b.updatedAt ? -1 : 0));
|
|
55
52
|
return sessions;
|
|
56
53
|
}
|
|
57
|
-
//# sourceMappingURL=list-sessions.js.map
|
|
@@ -9,5 +9,4 @@ import type { HistoryContext } from '../internal/setup';
|
|
|
9
9
|
* rather than creating a permanent, TTL-less metadata-only row. Returns the
|
|
10
10
|
* reconciled count.
|
|
11
11
|
*/
|
|
12
|
-
export declare function reconcileMessageCount(context: HistoryContext, sessionId: string): Promise<number>;
|
|
13
|
-
//# sourceMappingURL=reconcile-count.d.ts.map
|
|
12
|
+
export declare function reconcileMessageCount(context: HistoryContext, sessionId: string, signal?: AbortSignal): Promise<number>;
|
|
@@ -1,17 +1,31 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.reconcileMessageCount = reconcileMessageCount;
|
|
4
|
+
const clock_1 = require("../../shared/clock");
|
|
4
5
|
const retry_1 = require("../../shared/dynamodb/retry");
|
|
6
|
+
const retry_policy_1 = require("../../shared/dynamodb/retry-policy");
|
|
5
7
|
const errors_1 = require("../../shared/errors/errors");
|
|
6
8
|
const keys_1 = require("../internal/keys");
|
|
7
9
|
const query_1 = require("../internal/query");
|
|
8
10
|
const validation_1 = require("../internal/validation");
|
|
9
|
-
|
|
10
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Count only the rows `getMessages` would return: an expired message that
|
|
13
|
+
* DynamoDB's TTL sweep has not yet removed is invisible to the read path, so
|
|
14
|
+
* counting it would "repair" `messageCount` to a number no reader ever sees.
|
|
15
|
+
*/
|
|
16
|
+
async function countMessages(context, sessionId, signal) {
|
|
17
|
+
const query = (0, query_1.messageQuery)(context.tableName, sessionId);
|
|
18
|
+
const base = {
|
|
19
|
+
...query,
|
|
20
|
+
Select: 'COUNT',
|
|
21
|
+
FilterExpression: 'attribute_not_exists(#ttl) OR #ttl > :now',
|
|
22
|
+
ExpressionAttributeNames: { ...query.ExpressionAttributeNames, '#ttl': 'ttl' },
|
|
23
|
+
ExpressionAttributeValues: { ...query.ExpressionAttributeValues, ':now': (0, clock_1.nowSeconds)() },
|
|
24
|
+
};
|
|
11
25
|
let total = 0;
|
|
12
26
|
let startKey;
|
|
13
27
|
do {
|
|
14
|
-
const page = await (0, retry_1.withDynamoDBRetry)(() => context.client.query({ ...base,
|
|
28
|
+
const page = await (0, retry_1.withDynamoDBRetry)(() => context.client.query({ ...base, ExclusiveStartKey: startKey }), (0, retry_policy_1.retryFor)(context, signal));
|
|
15
29
|
total += page.Count ?? 0;
|
|
16
30
|
startKey = page.LastEvaluatedKey;
|
|
17
31
|
} while (startKey);
|
|
@@ -27,9 +41,9 @@ async function countMessages(context, sessionId) {
|
|
|
27
41
|
* rather than creating a permanent, TTL-less metadata-only row. Returns the
|
|
28
42
|
* reconciled count.
|
|
29
43
|
*/
|
|
30
|
-
async function reconcileMessageCount(context, sessionId) {
|
|
44
|
+
async function reconcileMessageCount(context, sessionId, signal) {
|
|
31
45
|
(0, validation_1.validateSessionId)(sessionId);
|
|
32
|
-
const count = await countMessages(context, sessionId);
|
|
46
|
+
const count = await countMessages(context, sessionId, signal);
|
|
33
47
|
try {
|
|
34
48
|
await (0, retry_1.withDynamoDBRetry)(() => context.client.update({
|
|
35
49
|
TableName: context.tableName,
|
|
@@ -38,7 +52,7 @@ async function reconcileMessageCount(context, sessionId) {
|
|
|
38
52
|
ExpressionAttributeNames: { '#count': 'messageCount' },
|
|
39
53
|
ExpressionAttributeValues: { ':count': count },
|
|
40
54
|
ConditionExpression: 'attribute_exists(PK)',
|
|
41
|
-
}));
|
|
55
|
+
}), (0, retry_policy_1.retryFor)(context, signal));
|
|
42
56
|
}
|
|
43
57
|
catch (error) {
|
|
44
58
|
if (error.name === 'ConditionalCheckFailedException') {
|
|
@@ -48,4 +62,3 @@ async function reconcileMessageCount(context, sessionId) {
|
|
|
48
62
|
}
|
|
49
63
|
return count;
|
|
50
64
|
}
|
|
51
|
-
//# sourceMappingURL=reconcile-count.js.map
|
|
@@ -1,48 +1,73 @@
|
|
|
1
1
|
import type { BaseMessage } from '@langchain/core/messages';
|
|
2
|
-
import {
|
|
3
|
-
import type
|
|
2
|
+
import type { CancelOptions } from '../shared/options';
|
|
3
|
+
import { type AdapterWindow, DynamoDBSessionChatMessageHistory } from './session-adapter';
|
|
4
|
+
import type { DynamoDBChatMessageHistoryOptions, GetMessagesOptions, ListSessionsOptions, SessionMetadata } from './types';
|
|
4
5
|
/**
|
|
5
6
|
* DynamoDB-backed multi-session chat history. Each message is its own item
|
|
6
7
|
* (ordered by a monotonic ULID, compressed / S3-offloaded as needed) alongside a
|
|
7
8
|
* per-session metadata item; every message in a session shares one uniform TTL.
|
|
8
9
|
* Appends are O(1) and lock-free. Use {@link forSession} to get a single-session
|
|
9
|
-
* LangChain adapter.
|
|
10
|
+
* LangChain adapter. Every public method is the library's error boundary — a
|
|
11
|
+
* raw AWS SDK error escaping an action surfaces as an `UpstreamError`.
|
|
10
12
|
*/
|
|
11
13
|
export declare class DynamoDBChatMessageHistory {
|
|
12
14
|
private readonly context;
|
|
13
15
|
private readonly ownsClient;
|
|
14
16
|
private readonly ddbClient;
|
|
15
17
|
constructor(options: DynamoDBChatMessageHistoryOptions);
|
|
16
|
-
/**
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
18
|
+
/**
|
|
19
|
+
* Get a session's messages in chronological order: the whole session by
|
|
20
|
+
* default, or a window of it — `{ limit }` returns only the newest `limit`
|
|
21
|
+
* messages, `{ before }` only those appended before that instant — so a
|
|
22
|
+
* long-lived session can be read a page at a time instead of whole.
|
|
23
|
+
* @remarks Strongly consistent; one query page plus one S3 download per offloaded message.
|
|
24
|
+
* @throws ValidationError for a malformed session id or window; UpstreamError; AbortError; and, under `onCorruptMessage: 'throw'`, the decode error of a corrupt row.
|
|
25
|
+
*/
|
|
26
|
+
getMessages(sessionId: string, options?: GetMessagesOptions): Promise<BaseMessage[]>;
|
|
27
|
+
/**
|
|
28
|
+
* Append messages to a session in one transaction per chunk of up to 99
|
|
29
|
+
* messages, keeping the session's `messageCount` exact. Lock-free and safe
|
|
30
|
+
* under concurrent appends to one session; every message shares the
|
|
31
|
+
* session's TTL when one is configured.
|
|
32
|
+
* @throws ValidationError for a message that could never be read back; CompensationFailedError when a later chunk fails and the rollback fails too; RetryExhaustedError after 18 contended attempts; UpstreamError; AbortError.
|
|
33
|
+
*/
|
|
34
|
+
addMessages(sessionId: string, messages: BaseMessage[], options?: CancelOptions): Promise<void>;
|
|
35
|
+
/** Append one message; see {@link addMessages}. */
|
|
36
|
+
addMessage(sessionId: string, message: BaseMessage, options?: CancelOptions): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Delete a session's messages, metadata and offloaded objects. Single pass:
|
|
39
|
+
* call it when the session is quiescent.
|
|
40
|
+
* @throws BatchWriteAllIncompleteError when a delete batch does not fully drain; UpstreamError; AbortError.
|
|
41
|
+
*/
|
|
42
|
+
clear(sessionId: string, options?: CancelOptions): Promise<void>;
|
|
43
|
+
/**
|
|
44
|
+
* List every session as a metadata summary, most recently updated first.
|
|
45
|
+
* A table scan: cross-tenant by construction and bounded by `maxItems` /
|
|
46
|
+
* `maxIterations`.
|
|
47
|
+
* @throws ResultTruncatedError past either cap; UpstreamError; AbortError.
|
|
48
|
+
*/
|
|
49
|
+
listSessions(options?: ListSessionsOptions): Promise<SessionMetadata[]>;
|
|
29
50
|
/**
|
|
30
51
|
* Recompute and repair a session's `messageCount` from the stored messages.
|
|
31
52
|
* A maintenance tool for external corruption; run it when the session is idle.
|
|
53
|
+
* @throws ConflictError when the session does not exist or changed while counting; UpstreamError; AbortError.
|
|
54
|
+
*/
|
|
55
|
+
reconcileMessageCount(sessionId: string, options?: CancelOptions): Promise<number>;
|
|
56
|
+
/**
|
|
57
|
+
* Get a single-session LangChain adapter for `sessionId`. `{ limit }` bounds
|
|
58
|
+
* what the adapter feeds the chain to the newest `limit` messages.
|
|
32
59
|
*/
|
|
33
|
-
|
|
34
|
-
/** Get a single-session LangChain adapter for `sessionId`. */
|
|
35
|
-
forSession(sessionId: string): DynamoDBSessionChatMessageHistory;
|
|
60
|
+
forSession(sessionId: string, window?: AdapterWindow): DynamoDBSessionChatMessageHistory;
|
|
36
61
|
/** Release owned resources (the underlying client and any S3 client). */
|
|
37
62
|
destroy(): void;
|
|
38
63
|
/**
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
* `s3:GetLifecycleConfiguration
|
|
43
|
-
* permissions (broader than the
|
|
44
|
-
* needs) — call this once during
|
|
64
|
+
* Provision an S3 lifecycle expiration rule matching the configured TTL, so
|
|
65
|
+
* offloaded objects don't outlive their DynamoDB item forever. No-ops when
|
|
66
|
+
* S3 offload or TTL isn't configured; throws when the bucket cannot be read
|
|
67
|
+
* or written. Requires the `s3:GetLifecycleConfiguration` /
|
|
68
|
+
* `s3:PutLifecycleConfiguration` bucket-level permissions (broader than the
|
|
69
|
+
* object-level CRUD the rest of S3 offload needs) — call this once during
|
|
70
|
+
* deployment/provisioning, not per-request.
|
|
45
71
|
*/
|
|
46
72
|
ensureS3LifecycleRule(): Promise<void>;
|
|
47
73
|
}
|
|
48
|
-
//# sourceMappingURL=chat-message-history.d.ts.map
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.DynamoDBChatMessageHistory = void 0;
|
|
4
|
+
const boundary_1 = require("../shared/errors/boundary");
|
|
4
5
|
const ttl_1 = require("../shared/validation/ttl");
|
|
5
6
|
const add_messages_1 = require("./actions/add-messages");
|
|
6
7
|
const clear_1 = require("./actions/clear");
|
|
@@ -14,7 +15,8 @@ const session_adapter_1 = require("./session-adapter");
|
|
|
14
15
|
* (ordered by a monotonic ULID, compressed / S3-offloaded as needed) alongside a
|
|
15
16
|
* per-session metadata item; every message in a session shares one uniform TTL.
|
|
16
17
|
* Appends are O(1) and lock-free. Use {@link forSession} to get a single-session
|
|
17
|
-
* LangChain adapter.
|
|
18
|
+
* LangChain adapter. Every public method is the library's error boundary — a
|
|
19
|
+
* raw AWS SDK error escaping an action surfaces as an `UpstreamError`.
|
|
18
20
|
*/
|
|
19
21
|
class DynamoDBChatMessageHistory {
|
|
20
22
|
context;
|
|
@@ -26,36 +28,62 @@ class DynamoDBChatMessageHistory {
|
|
|
26
28
|
this.ownsClient = setup.ownsClient;
|
|
27
29
|
this.ddbClient = setup.ddbClient;
|
|
28
30
|
}
|
|
29
|
-
/**
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
/**
|
|
32
|
+
* Get a session's messages in chronological order: the whole session by
|
|
33
|
+
* default, or a window of it — `{ limit }` returns only the newest `limit`
|
|
34
|
+
* messages, `{ before }` only those appended before that instant — so a
|
|
35
|
+
* long-lived session can be read a page at a time instead of whole.
|
|
36
|
+
* @remarks Strongly consistent; one query page plus one S3 download per offloaded message.
|
|
37
|
+
* @throws ValidationError for a malformed session id or window; UpstreamError; AbortError; and, under `onCorruptMessage: 'throw'`, the decode error of a corrupt row.
|
|
38
|
+
*/
|
|
39
|
+
getMessages(sessionId, options) {
|
|
40
|
+
return (0, boundary_1.guardPublic)('history.getMessages', () => (0, get_messages_1.getMessages)(this.context, sessionId, options));
|
|
32
41
|
}
|
|
33
|
-
/**
|
|
34
|
-
|
|
35
|
-
|
|
42
|
+
/**
|
|
43
|
+
* Append messages to a session in one transaction per chunk of up to 99
|
|
44
|
+
* messages, keeping the session's `messageCount` exact. Lock-free and safe
|
|
45
|
+
* under concurrent appends to one session; every message shares the
|
|
46
|
+
* session's TTL when one is configured.
|
|
47
|
+
* @throws ValidationError for a message that could never be read back; CompensationFailedError when a later chunk fails and the rollback fails too; RetryExhaustedError after 18 contended attempts; UpstreamError; AbortError.
|
|
48
|
+
*/
|
|
49
|
+
addMessages(sessionId, messages, options) {
|
|
50
|
+
return (0, boundary_1.guardPublic)('history.addMessages', () => (0, add_messages_1.addMessages)(this.context, sessionId, messages, options?.signal));
|
|
36
51
|
}
|
|
37
|
-
/** Append
|
|
38
|
-
addMessage(sessionId, message) {
|
|
39
|
-
return (0, add_messages_1.addMessages)(this.context, sessionId, [message]);
|
|
52
|
+
/** Append one message; see {@link addMessages}. */
|
|
53
|
+
addMessage(sessionId, message, options) {
|
|
54
|
+
return (0, boundary_1.guardPublic)('history.addMessage', () => (0, add_messages_1.addMessages)(this.context, sessionId, [message], options?.signal));
|
|
40
55
|
}
|
|
41
|
-
/**
|
|
42
|
-
|
|
43
|
-
|
|
56
|
+
/**
|
|
57
|
+
* Delete a session's messages, metadata and offloaded objects. Single pass:
|
|
58
|
+
* call it when the session is quiescent.
|
|
59
|
+
* @throws BatchWriteAllIncompleteError when a delete batch does not fully drain; UpstreamError; AbortError.
|
|
60
|
+
*/
|
|
61
|
+
clear(sessionId, options) {
|
|
62
|
+
return (0, boundary_1.guardPublic)('history.clear', () => (0, clear_1.clearSession)(this.context, sessionId, options));
|
|
44
63
|
}
|
|
45
|
-
/**
|
|
64
|
+
/**
|
|
65
|
+
* List every session as a metadata summary, most recently updated first.
|
|
66
|
+
* A table scan: cross-tenant by construction and bounded by `maxItems` /
|
|
67
|
+
* `maxIterations`.
|
|
68
|
+
* @throws ResultTruncatedError past either cap; UpstreamError; AbortError.
|
|
69
|
+
*/
|
|
46
70
|
listSessions(options) {
|
|
47
|
-
return (0, list_sessions_1.listSessions)(this.context, options);
|
|
71
|
+
return (0, boundary_1.guardPublic)('history.listSessions', () => (0, list_sessions_1.listSessions)(this.context, options));
|
|
48
72
|
}
|
|
49
73
|
/**
|
|
50
74
|
* Recompute and repair a session's `messageCount` from the stored messages.
|
|
51
75
|
* A maintenance tool for external corruption; run it when the session is idle.
|
|
76
|
+
* @throws ConflictError when the session does not exist or changed while counting; UpstreamError; AbortError.
|
|
52
77
|
*/
|
|
53
|
-
reconcileMessageCount(sessionId) {
|
|
54
|
-
return (0, reconcile_count_1.reconcileMessageCount)(this.context, sessionId);
|
|
78
|
+
reconcileMessageCount(sessionId, options) {
|
|
79
|
+
return (0, boundary_1.guardPublic)('history.reconcileMessageCount', () => (0, reconcile_count_1.reconcileMessageCount)(this.context, sessionId, options?.signal));
|
|
55
80
|
}
|
|
56
|
-
/**
|
|
57
|
-
|
|
58
|
-
|
|
81
|
+
/**
|
|
82
|
+
* Get a single-session LangChain adapter for `sessionId`. `{ limit }` bounds
|
|
83
|
+
* what the adapter feeds the chain to the newest `limit` messages.
|
|
84
|
+
*/
|
|
85
|
+
forSession(sessionId, window) {
|
|
86
|
+
return new session_adapter_1.DynamoDBSessionChatMessageHistory(this, sessionId, window);
|
|
59
87
|
}
|
|
60
88
|
/** Release owned resources (the underlying client and any S3 client). */
|
|
61
89
|
destroy() {
|
|
@@ -64,18 +92,20 @@ class DynamoDBChatMessageHistory {
|
|
|
64
92
|
this.ddbClient?.destroy();
|
|
65
93
|
}
|
|
66
94
|
/**
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
* `s3:GetLifecycleConfiguration
|
|
71
|
-
* permissions (broader than the
|
|
72
|
-
* needs) — call this once during
|
|
95
|
+
* Provision an S3 lifecycle expiration rule matching the configured TTL, so
|
|
96
|
+
* offloaded objects don't outlive their DynamoDB item forever. No-ops when
|
|
97
|
+
* S3 offload or TTL isn't configured; throws when the bucket cannot be read
|
|
98
|
+
* or written. Requires the `s3:GetLifecycleConfiguration` /
|
|
99
|
+
* `s3:PutLifecycleConfiguration` bucket-level permissions (broader than the
|
|
100
|
+
* object-level CRUD the rest of S3 offload needs) — call this once during
|
|
101
|
+
* deployment/provisioning, not per-request.
|
|
73
102
|
*/
|
|
74
103
|
async ensureS3LifecycleRule() {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
104
|
+
return (0, boundary_1.guardPublic)('history.ensureS3LifecycleRule', async () => {
|
|
105
|
+
if (!this.context.offloader || !this.context.ttl)
|
|
106
|
+
return;
|
|
107
|
+
await this.context.offloader.ensureLifecycleRule((0, ttl_1.lifecycleExpirationDays)(this.context.ttl));
|
|
108
|
+
});
|
|
78
109
|
}
|
|
79
110
|
}
|
|
80
111
|
exports.DynamoDBChatMessageHistory = DynamoDBChatMessageHistory;
|
|
81
|
-
//# sourceMappingURL=chat-message-history.js.map
|
|
@@ -15,6 +15,11 @@ export interface AppendFields {
|
|
|
15
15
|
* state before the error is rethrown. Except on a failed rollback, which
|
|
16
16
|
* surfaces as {@link CompensationFailedError} and deliberately leaves the
|
|
17
17
|
* committed chunks' S3 objects behind, since their rows may survive.
|
|
18
|
+
*
|
|
19
|
+
* A `RetryExhaustedError` is ambiguous — the transaction may have committed
|
|
20
|
+
* and lost its response — so the chunk is read back first: present means it
|
|
21
|
+
* committed (continue), absent means it did not (compensate), and a failed
|
|
22
|
+
* read compensates but leaks that chunk's objects rather than delete objects
|
|
23
|
+
* its possibly-live rows reference.
|
|
18
24
|
*/
|
|
19
|
-
export declare function appendChunks(context: HistoryContext, sessionId: string, chunks: ChatMessageItem[][], fields: AppendFields): Promise<void>;
|
|
20
|
-
//# sourceMappingURL=append-saga.d.ts.map
|
|
25
|
+
export declare function appendChunks(context: HistoryContext, sessionId: string, chunks: ChatMessageItem[][], fields: AppendFields, signal?: AbortSignal): Promise<void>;
|
|
@@ -1,9 +1,49 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.appendChunks = appendChunks;
|
|
4
|
+
const retry_1 = require("../../shared/dynamodb/retry");
|
|
5
|
+
const error_code_1 = require("../../shared/errors/error-code");
|
|
4
6
|
const wrap_error_1 = require("../../shared/errors/wrap-error");
|
|
5
7
|
const compensation_1 = require("./compensation");
|
|
6
8
|
const message_transaction_1 = require("./message-transaction");
|
|
9
|
+
/** True for the one failure shape that leaves the outcome ambiguous. */
|
|
10
|
+
function isAmbiguous(error) {
|
|
11
|
+
return error.code === error_code_1.ErrorCode.RETRY_EXHAUSTED;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Read the chunk's first row back with `ConsistentRead`. A chunk commits
|
|
15
|
+
* atomically, so one row present means the whole chunk (and its count `ADD`)
|
|
16
|
+
* landed and only the response was lost. Message sort keys are per-call
|
|
17
|
+
* ULIDs, so a present row can only be this call's own.
|
|
18
|
+
*/
|
|
19
|
+
async function verifyChunkLanded(context, chunk) {
|
|
20
|
+
try {
|
|
21
|
+
const result = await (0, retry_1.withDynamoDBRetry)(() => context.client.get({
|
|
22
|
+
TableName: context.tableName,
|
|
23
|
+
Key: { PK: chunk[0].PK, SK: chunk[0].SK },
|
|
24
|
+
ConsistentRead: true,
|
|
25
|
+
ProjectionExpression: '#sk',
|
|
26
|
+
ExpressionAttributeNames: { '#sk': 'SK' },
|
|
27
|
+
}), context.retry);
|
|
28
|
+
return result.Item ? 'committed' : 'not-committed';
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return 'unverified';
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/** Run one chunk's transaction, returning its error instead of throwing. */
|
|
35
|
+
async function commitChunk(context, sessionId, chunk, fields, signal) {
|
|
36
|
+
try {
|
|
37
|
+
await (0, message_transaction_1.writeMessageChunk)(context, chunk, { ...fields, sessionId, count: chunk.length }, { signal });
|
|
38
|
+
return undefined;
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
return (0, wrap_error_1.toError)(error);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
function asCommitted(chunk) {
|
|
45
|
+
return { keys: chunk.map((item) => ({ PK: item.PK, SK: item.SK })), count: chunk.length };
|
|
46
|
+
}
|
|
7
47
|
/**
|
|
8
48
|
* Append message chunks with caller-observed atomicity. Each chunk commits its
|
|
9
49
|
* messages and count in one transaction; if a later chunk fails, every
|
|
@@ -12,24 +52,28 @@ const message_transaction_1 = require("./message-transaction");
|
|
|
12
52
|
* state before the error is rethrown. Except on a failed rollback, which
|
|
13
53
|
* surfaces as {@link CompensationFailedError} and deliberately leaves the
|
|
14
54
|
* committed chunks' S3 objects behind, since their rows may survive.
|
|
55
|
+
*
|
|
56
|
+
* A `RetryExhaustedError` is ambiguous — the transaction may have committed
|
|
57
|
+
* and lost its response — so the chunk is read back first: present means it
|
|
58
|
+
* committed (continue), absent means it did not (compensate), and a failed
|
|
59
|
+
* read compensates but leaks that chunk's objects rather than delete objects
|
|
60
|
+
* its possibly-live rows reference.
|
|
15
61
|
*/
|
|
16
|
-
async function appendChunks(context, sessionId, chunks, fields) {
|
|
62
|
+
async function appendChunks(context, sessionId, chunks, fields, signal) {
|
|
17
63
|
const committed = [];
|
|
18
64
|
for (const chunk of chunks) {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
count: chunk.length,
|
|
24
|
-
});
|
|
25
|
-
committed.push({
|
|
26
|
-
keys: chunk.map((item) => ({ PK: item.PK, SK: item.SK })),
|
|
27
|
-
count: chunk.length,
|
|
28
|
-
});
|
|
65
|
+
const failure = await commitChunk(context, sessionId, chunk, fields, signal);
|
|
66
|
+
if (!failure) {
|
|
67
|
+
committed.push(asCommitted(chunk));
|
|
68
|
+
continue;
|
|
29
69
|
}
|
|
30
|
-
|
|
31
|
-
await (
|
|
70
|
+
const verdict = isAmbiguous(failure)
|
|
71
|
+
? await verifyChunkLanded(context, chunk)
|
|
72
|
+
: 'not-committed';
|
|
73
|
+
if (verdict === 'committed') {
|
|
74
|
+
committed.push(asCommitted(chunk));
|
|
75
|
+
continue;
|
|
32
76
|
}
|
|
77
|
+
await (0, compensation_1.compensate)(context, sessionId, chunks, committed, failure, fields.now, fields.title, verdict === 'unverified');
|
|
33
78
|
}
|
|
34
79
|
}
|
|
35
|
-
//# sourceMappingURL=append-saga.js.map
|
|
@@ -16,6 +16,10 @@ export interface CommittedChunk {
|
|
|
16
16
|
* objects are deliberately left in place (their rows may survive) and it
|
|
17
17
|
* raises {@link CompensationFailedError} carrying both the trigger and the
|
|
18
18
|
* rollback error; otherwise it rethrows the trigger.
|
|
19
|
+
*
|
|
20
|
+
* `uncertain` marks the failed chunk (`chunks[committed.length]`) as one whose
|
|
21
|
+
* outcome could not be verified: its rows may be live, so its objects are
|
|
22
|
+
* leaked rather than deleted, while the never-attempted chunks after it are
|
|
23
|
+
* still cleaned.
|
|
19
24
|
*/
|
|
20
|
-
export declare function compensate(context: HistoryContext, sessionId: string, chunks: ChatMessageItem[][], committed: CommittedChunk[], trigger: Error, now: string, title: string | undefined): Promise<never>;
|
|
21
|
-
//# sourceMappingURL=compensation.d.ts.map
|
|
25
|
+
export declare function compensate(context: HistoryContext, sessionId: string, chunks: ChatMessageItem[][], committed: CommittedChunk[], trigger: Error, now: string, title: string | undefined, uncertain: boolean): Promise<never>;
|