@farukada/aws-langgraph-dynamodb-ts 0.0.10 → 0.1.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 +353 -242
- package/dist/checkpointer/actions/delete-thread.d.ts +3 -3
- package/dist/checkpointer/actions/delete-thread.d.ts.map +1 -1
- package/dist/checkpointer/actions/delete-thread.js +95 -52
- package/dist/checkpointer/actions/delete-thread.js.map +1 -1
- package/dist/checkpointer/actions/get-tuple.d.ts +8 -1
- package/dist/checkpointer/actions/get-tuple.d.ts.map +1 -1
- package/dist/checkpointer/actions/get-tuple.js +72 -20
- package/dist/checkpointer/actions/get-tuple.js.map +1 -1
- package/dist/checkpointer/actions/put-writes.d.ts.map +1 -1
- package/dist/checkpointer/actions/put-writes.js +27 -22
- package/dist/checkpointer/actions/put-writes.js.map +1 -1
- package/dist/checkpointer/actions/put.d.ts +6 -2
- package/dist/checkpointer/actions/put.d.ts.map +1 -1
- package/dist/checkpointer/actions/put.js +80 -19
- package/dist/checkpointer/actions/put.js.map +1 -1
- package/dist/checkpointer/index.d.ts +43 -2
- package/dist/checkpointer/index.d.ts.map +1 -1
- package/dist/checkpointer/index.js +226 -11
- package/dist/checkpointer/index.js.map +1 -1
- package/dist/checkpointer/types/index.d.ts +66 -4
- package/dist/checkpointer/types/index.d.ts.map +1 -1
- package/dist/checkpointer/types/index.js +10 -0
- package/dist/checkpointer/types/index.js.map +1 -1
- package/dist/checkpointer/utils/deserialization.d.ts +8 -3
- package/dist/checkpointer/utils/deserialization.d.ts.map +1 -1
- package/dist/checkpointer/utils/deserialization.js +23 -5
- package/dist/checkpointer/utils/deserialization.js.map +1 -1
- package/dist/checkpointer/utils/validation.d.ts +1 -1
- package/dist/checkpointer/utils/validation.js +1 -1
- package/dist/checkpointer/utils/validation.js.map +1 -1
- package/dist/factory.d.ts +8 -6
- package/dist/factory.d.ts.map +1 -1
- package/dist/factory.js +16 -4
- package/dist/factory.js.map +1 -1
- package/dist/history/actions/add-message.d.ts +2 -1
- package/dist/history/actions/add-message.d.ts.map +1 -1
- package/dist/history/actions/add-message.js +22 -18
- package/dist/history/actions/add-message.js.map +1 -1
- package/dist/history/actions/add-messages.d.ts +3 -2
- package/dist/history/actions/add-messages.d.ts.map +1 -1
- package/dist/history/actions/add-messages.js +30 -20
- package/dist/history/actions/add-messages.js.map +1 -1
- package/dist/history/actions/clear.d.ts +4 -3
- package/dist/history/actions/clear.d.ts.map +1 -1
- package/dist/history/actions/clear.js +47 -12
- package/dist/history/actions/clear.js.map +1 -1
- package/dist/history/actions/get-messages.d.ts +2 -1
- package/dist/history/actions/get-messages.d.ts.map +1 -1
- package/dist/history/actions/get-messages.js +41 -15
- package/dist/history/actions/get-messages.js.map +1 -1
- package/dist/history/actions/list-sessions.d.ts +11 -0
- package/dist/history/actions/list-sessions.d.ts.map +1 -1
- package/dist/history/actions/list-sessions.js +23 -3
- package/dist/history/actions/list-sessions.js.map +1 -1
- package/dist/history/index.d.ts +8 -0
- package/dist/history/index.d.ts.map +1 -1
- package/dist/history/index.js +22 -2
- package/dist/history/index.js.map +1 -1
- package/dist/history/types/index.d.ts +27 -5
- package/dist/history/types/index.d.ts.map +1 -1
- package/dist/history/types/index.js +1 -0
- package/dist/history/types/index.js.map +1 -1
- package/dist/history/utils/title-generator.js.map +1 -1
- package/dist/history/utils/update-expression-builder.d.ts +45 -21
- package/dist/history/utils/update-expression-builder.d.ts.map +1 -1
- package/dist/history/utils/update-expression-builder.js +105 -38
- package/dist/history/utils/update-expression-builder.js.map +1 -1
- package/dist/history/utils/validation.d.ts +8 -0
- package/dist/history/utils/validation.d.ts.map +1 -1
- package/dist/history/utils/validation.js +22 -0
- package/dist/history/utils/validation.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/shared/utils/batch-write.d.ts +36 -0
- package/dist/shared/utils/batch-write.d.ts.map +1 -0
- package/dist/shared/utils/batch-write.js +62 -0
- package/dist/shared/utils/batch-write.js.map +1 -0
- package/dist/shared/utils/compressor.d.ts +48 -0
- package/dist/shared/utils/compressor.d.ts.map +1 -0
- package/dist/shared/utils/compressor.js +68 -0
- package/dist/shared/utils/compressor.js.map +1 -0
- package/dist/shared/utils/constants.d.ts +2 -0
- package/dist/shared/utils/constants.d.ts.map +1 -1
- package/dist/shared/utils/constants.js +3 -7
- package/dist/shared/utils/constants.js.map +1 -1
- package/dist/shared/utils/index.d.ts +4 -0
- package/dist/shared/utils/index.d.ts.map +1 -1
- package/dist/shared/utils/index.js +4 -0
- package/dist/shared/utils/index.js.map +1 -1
- package/dist/shared/utils/logger.d.ts +48 -0
- package/dist/shared/utils/logger.d.ts.map +1 -0
- package/dist/shared/utils/logger.js +62 -0
- package/dist/shared/utils/logger.js.map +1 -0
- package/dist/shared/utils/retry.d.ts +1 -1
- package/dist/shared/utils/retry.d.ts.map +1 -1
- package/dist/shared/utils/retry.js +13 -6
- package/dist/shared/utils/retry.js.map +1 -1
- package/dist/shared/utils/s3-offloader.d.ts +146 -0
- package/dist/shared/utils/s3-offloader.d.ts.map +1 -0
- package/dist/shared/utils/s3-offloader.js +271 -0
- package/dist/shared/utils/s3-offloader.js.map +1 -0
- package/dist/shared/utils/ttl.d.ts +8 -1
- package/dist/shared/utils/ttl.d.ts.map +1 -1
- package/dist/shared/utils/ttl.js +12 -8
- package/dist/shared/utils/ttl.js.map +1 -1
- package/dist/store/actions/get-operation.js +2 -2
- package/dist/store/actions/get-operation.js.map +1 -1
- package/dist/store/actions/put-operation.d.ts.map +1 -1
- package/dist/store/actions/put-operation.js +2 -1
- package/dist/store/actions/put-operation.js.map +1 -1
- package/dist/store/actions/search-operation.d.ts +6 -0
- package/dist/store/actions/search-operation.d.ts.map +1 -1
- package/dist/store/actions/search-operation.js +41 -21
- package/dist/store/actions/search-operation.js.map +1 -1
- package/dist/store/index.d.ts +10 -2
- package/dist/store/index.d.ts.map +1 -1
- package/dist/store/index.js +28 -5
- package/dist/store/index.js.map +1 -1
- package/dist/store/types/index.d.ts +7 -5
- package/dist/store/types/index.d.ts.map +1 -1
- package/dist/store/utils/index.d.ts +0 -1
- package/dist/store/utils/index.d.ts.map +1 -1
- package/dist/store/utils/index.js +0 -1
- package/dist/store/utils/index.js.map +1 -1
- package/dist/store/utils/validation.js +1 -1
- package/dist/store/utils/validation.js.map +1 -1
- package/package.json +41 -24
- package/dist/store/utils/result.d.ts +0 -42
- package/dist/store/utils/result.d.ts.map +0 -1
- package/dist/store/utils/result.js +0 -51
- package/dist/store/utils/result.js.map +0 -1
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.putAction = void 0;
|
|
4
|
-
const validate_configurable_1 = require("./validate-configurable");
|
|
5
|
-
const utils_1 = require("../utils");
|
|
6
4
|
const shared_1 = require("../../shared");
|
|
5
|
+
const types_1 = require("../types");
|
|
6
|
+
const utils_1 = require("../utils");
|
|
7
|
+
const validate_configurable_1 = require("./validate-configurable");
|
|
7
8
|
/**
|
|
8
|
-
* Save a checkpoint to DynamoDB
|
|
9
|
+
* Save a checkpoint to DynamoDB as two items:
|
|
10
|
+
* 1. Metadata item (SK = checkpoint_id) — lightweight, queried by list()
|
|
11
|
+
* 2. Payload item (SK = PAYLOAD#checkpoint_id) — heavy blob, fetched only by getTuple()
|
|
12
|
+
*
|
|
13
|
+
* Both items are written atomically via transactWrite.
|
|
9
14
|
*
|
|
10
15
|
* @param params - Parameters for the put operation
|
|
11
16
|
* @returns RunnableConfig with the saved checkpoint information
|
|
@@ -19,35 +24,91 @@ const putAction = async (params) => {
|
|
|
19
24
|
}
|
|
20
25
|
(0, utils_1.validateCheckpointId)(params.checkpoint.id, true);
|
|
21
26
|
(0, utils_1.validateTTLDays)(params.ttlDays);
|
|
22
|
-
const [type1,
|
|
23
|
-
const [type2,
|
|
27
|
+
const [type1, rawCheckpoint] = await params.serde.dumpsTyped(params.checkpoint);
|
|
28
|
+
const [type2, rawMetadata] = await params.serde.dumpsTyped(params.metadata);
|
|
24
29
|
if (type1 !== type2) {
|
|
25
30
|
throw new Error('Failed to serialize checkpoint and metadata to the same type.');
|
|
26
31
|
}
|
|
27
|
-
|
|
32
|
+
// Compress after serialization if compressor is provided
|
|
33
|
+
const serializedCheckpoint = params.compressor
|
|
34
|
+
? await params.compressor.compress(rawCheckpoint)
|
|
35
|
+
: rawCheckpoint;
|
|
36
|
+
const serializedMetadata = params.compressor
|
|
37
|
+
? await params.compressor.compress(rawMetadata)
|
|
38
|
+
: rawMetadata;
|
|
39
|
+
// S3 offloading for large payloads
|
|
40
|
+
let s3CheckpointKey;
|
|
41
|
+
let s3MetadataKey;
|
|
42
|
+
let storedCheckpoint = serializedCheckpoint;
|
|
43
|
+
let storedMetadata = serializedMetadata;
|
|
44
|
+
if (params.s3Offloader) {
|
|
45
|
+
const checkpointId = params.checkpoint.id;
|
|
46
|
+
if (params.s3Offloader.shouldOffload(serializedCheckpoint)) {
|
|
47
|
+
s3CheckpointKey = await params.s3Offloader.upload(params.s3Offloader.buildKey(thread_id, checkpointId, 'checkpoint'), serializedCheckpoint);
|
|
48
|
+
storedCheckpoint = new Uint8Array(0); // Empty placeholder in DynamoDB
|
|
49
|
+
}
|
|
50
|
+
if (params.s3Offloader.shouldOffload(serializedMetadata)) {
|
|
51
|
+
s3MetadataKey = await params.s3Offloader.upload(params.s3Offloader.buildKey(thread_id, checkpointId, 'metadata'), serializedMetadata);
|
|
52
|
+
storedMetadata = new Uint8Array(0); // Empty placeholder in DynamoDB
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// Compute TTL once for both items
|
|
56
|
+
let ttl;
|
|
57
|
+
if (params.ttlSeconds !== undefined) {
|
|
58
|
+
ttl = (0, shared_1.calculateTTLTimestampFromSeconds)(params.ttlSeconds);
|
|
59
|
+
}
|
|
60
|
+
else if (params.ttlDays !== undefined) {
|
|
61
|
+
ttl = (0, shared_1.calculateTTLTimestamp)(params.ttlDays);
|
|
62
|
+
}
|
|
63
|
+
const checkpointNs = params.config.configurable?.checkpoint_ns ?? '';
|
|
64
|
+
const checkpointId = params.checkpoint.id;
|
|
65
|
+
// Metadata item — lightweight, read by list() queries
|
|
66
|
+
const metadataItem = {
|
|
28
67
|
thread_id,
|
|
29
|
-
checkpoint_ns:
|
|
30
|
-
checkpoint_id:
|
|
68
|
+
checkpoint_ns: checkpointNs,
|
|
69
|
+
checkpoint_id: checkpointId,
|
|
31
70
|
parent_checkpoint_id: params.config.configurable?.checkpoint_id,
|
|
32
71
|
type: type1,
|
|
33
|
-
|
|
34
|
-
|
|
72
|
+
metadata: storedMetadata,
|
|
73
|
+
s3_checkpoint_key: s3CheckpointKey,
|
|
74
|
+
s3_metadata_key: s3MetadataKey,
|
|
75
|
+
};
|
|
76
|
+
if (ttl !== undefined) {
|
|
77
|
+
metadataItem.ttl = ttl;
|
|
78
|
+
}
|
|
79
|
+
// Payload item — heavy blob, fetched only by getTuple()
|
|
80
|
+
const payloadItem = {
|
|
81
|
+
thread_id,
|
|
82
|
+
checkpoint_id: `${types_1.PAYLOAD_SK_PREFIX}${checkpointId}`,
|
|
83
|
+
checkpoint: storedCheckpoint,
|
|
35
84
|
};
|
|
36
|
-
if (
|
|
37
|
-
|
|
85
|
+
if (ttl !== undefined) {
|
|
86
|
+
payloadItem.ttl = ttl;
|
|
38
87
|
}
|
|
39
|
-
//
|
|
88
|
+
// Atomic write: both items must succeed or both fail
|
|
40
89
|
await (0, shared_1.withDynamoDBRetry)(async () => {
|
|
41
|
-
await params.client.
|
|
42
|
-
|
|
43
|
-
|
|
90
|
+
await params.client.transactWrite({
|
|
91
|
+
TransactItems: [
|
|
92
|
+
{
|
|
93
|
+
Put: {
|
|
94
|
+
TableName: params.checkpointsTableName,
|
|
95
|
+
Item: metadataItem,
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
Put: {
|
|
100
|
+
TableName: params.checkpointsTableName,
|
|
101
|
+
Item: payloadItem,
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
],
|
|
44
105
|
});
|
|
45
106
|
});
|
|
46
107
|
return {
|
|
47
108
|
configurable: {
|
|
48
|
-
thread_id:
|
|
49
|
-
checkpoint_ns:
|
|
50
|
-
checkpoint_id:
|
|
109
|
+
thread_id: metadataItem.thread_id,
|
|
110
|
+
checkpoint_ns: metadataItem.checkpoint_ns,
|
|
111
|
+
checkpoint_id: metadataItem.checkpoint_id,
|
|
51
112
|
},
|
|
52
113
|
};
|
|
53
114
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"put.js","sourceRoot":"","sources":["../../../src/checkpointer/actions/put.ts"],"names":[],"mappings":";;;AAEA,mEAA+D;AAE/D
|
|
1
|
+
{"version":3,"file":"put.js","sourceRoot":"","sources":["../../../src/checkpointer/actions/put.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,15 +2,28 @@
|
|
|
2
2
|
* DynamoDB-based checkpoint saver for LangGraph
|
|
3
3
|
* Provides persistent storage for checkpoints and pending writes
|
|
4
4
|
*/
|
|
5
|
-
import { BaseCheckpointSaver, type Checkpoint, type CheckpointTuple, type CheckpointMetadata, type CheckpointListOptions, type PendingWrite, type ChannelVersions } from '@langchain/langgraph-checkpoint';
|
|
6
5
|
import type { RunnableConfig } from '@langchain/core/runnables';
|
|
6
|
+
import { BaseCheckpointSaver, type Checkpoint, type CheckpointTuple, type CheckpointMetadata, type CheckpointListOptions, type PendingWrite, type ChannelVersions } from '@langchain/langgraph-checkpoint';
|
|
7
7
|
import type { DynamoDBSaverOptions } from './types';
|
|
8
|
+
/**
|
|
9
|
+
* DynamoDB-based checkpoint saver for LangGraph.
|
|
10
|
+
* Provides persistent storage for checkpoints and pending writes.
|
|
11
|
+
*
|
|
12
|
+
* @remarks
|
|
13
|
+
* Uses the base class default for `getNextVersion()` (monotonic integers).
|
|
14
|
+
* Channel versioning is internal to LangGraph's execution engine and does not
|
|
15
|
+
* affect DynamoDB key ordering, which relies on checkpoint IDs.
|
|
16
|
+
*/
|
|
8
17
|
export declare class DynamoDBSaver extends BaseCheckpointSaver {
|
|
9
18
|
private readonly ddbClient;
|
|
10
19
|
private readonly client;
|
|
11
20
|
private readonly checkpointsTableName;
|
|
12
21
|
private readonly writesTableName;
|
|
13
22
|
private readonly ttlDays?;
|
|
23
|
+
private readonly ttlSeconds?;
|
|
24
|
+
private readonly compressor?;
|
|
25
|
+
private readonly s3Offloader?;
|
|
26
|
+
private readonly ownsClient;
|
|
14
27
|
/**
|
|
15
28
|
* Create a new DynamoDB checkpoint saver
|
|
16
29
|
*
|
|
@@ -18,10 +31,20 @@ export declare class DynamoDBSaver extends BaseCheckpointSaver {
|
|
|
18
31
|
* @param options.checkpointsTableName - Name of the DynamoDB table for checkpoints
|
|
19
32
|
* @param options.writesTableName - Name of the DynamoDB table for writes
|
|
20
33
|
* @param options.ttlDays - Optional TTL in days for stored items
|
|
34
|
+
* @param options.ttlSeconds - Optional TTL in seconds (overrides ttlDays if both set)
|
|
21
35
|
* @param options.serde - Optional serializer protocol
|
|
22
36
|
* @param options.clientConfig - Optional DynamoDB client configuration
|
|
37
|
+
* @param options.client - Optional pre-built DynamoDBDocument client (takes precedence over clientConfig)
|
|
38
|
+
* @param options.compression - Optional compression configuration
|
|
39
|
+
* @param options.s3OffloadConfig - Optional S3 offloading configuration
|
|
23
40
|
*/
|
|
24
41
|
constructor(options: DynamoDBSaverOptions);
|
|
42
|
+
/**
|
|
43
|
+
* Release underlying DynamoDB and S3 client resources.
|
|
44
|
+
* Call this when the saver is no longer needed to prevent resource leaks.
|
|
45
|
+
* Skips DynamoDB client cleanup if a shared client was injected via options.
|
|
46
|
+
*/
|
|
47
|
+
destroy(): void;
|
|
25
48
|
/**
|
|
26
49
|
* Delete a thread and all its checkpoints and writes
|
|
27
50
|
*
|
|
@@ -61,10 +84,28 @@ export declare class DynamoDBSaver extends BaseCheckpointSaver {
|
|
|
61
84
|
* List checkpoints for a thread
|
|
62
85
|
*
|
|
63
86
|
* @param config - Runnable configuration containing thread_id
|
|
64
|
-
* @param options - List options including limit and
|
|
87
|
+
* @param options - List options including limit, before checkpoint, and metadata filter
|
|
65
88
|
* @yields CheckpointTuple objects in descending order
|
|
66
89
|
* @throws Error if validation fails or operation fails
|
|
67
90
|
*/
|
|
68
91
|
list(config: RunnableConfig, options: CheckpointListOptions | undefined): AsyncGenerator<CheckpointTuple>;
|
|
92
|
+
/**
|
|
93
|
+
* Fetch checkpoint payloads for a batch of metadata items.
|
|
94
|
+
* Uses BatchGetItem to fetch all payloads in one round trip instead of N+1 queries.
|
|
95
|
+
* Items with S3 keys or legacy inline data are resolved without a remote call.
|
|
96
|
+
*
|
|
97
|
+
* @param items - Checkpoint metadata items from a query result
|
|
98
|
+
* @returns Map from checkpoint_id to raw checkpoint data
|
|
99
|
+
*/
|
|
100
|
+
private fetchCheckpointPayloadsBatch;
|
|
101
|
+
/**
|
|
102
|
+
* Check if checkpoint metadata matches all entries in the filter.
|
|
103
|
+
* Each filter key must exactly match the corresponding metadata value.
|
|
104
|
+
*
|
|
105
|
+
* @param metadata - Deserialized checkpoint metadata
|
|
106
|
+
* @param filter - Key-value pairs to match against metadata
|
|
107
|
+
* @returns true if all filter entries match
|
|
108
|
+
*/
|
|
109
|
+
private matchesFilter;
|
|
69
110
|
}
|
|
70
111
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/checkpointer/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/checkpointer/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EACL,mBAAmB,EACnB,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,EAC1B,KAAK,YAAY,EACjB,KAAK,eAAe,EACrB,MAAM,iCAAiC,CAAC;AAUzC,OAAO,KAAK,EAAyC,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAI3F;;;;;;;;GAQG;AACH,qBAAa,aAAc,SAAQ,mBAAmB;IACpD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA6B;IACvD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmB;IAC1C,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAS;IAC9C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAa;IACzC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAc;IAC3C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAU;IAErC;;;;;;;;;;;;;OAaG;gBACS,OAAO,EAAE,oBAAoB;IAoCzC;;;;OAIG;IACH,OAAO,IAAI,IAAI;IAOf;;;;;OAKG;IACG,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUnD;;;;;;OAMG;IACG,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC;IAY5E;;;;;;;;;OASG;IACG,GAAG,CACP,MAAM,EAAE,cAAc,EACtB,UAAU,EAAE,UAAU,EACtB,QAAQ,EAAE,kBAAkB,EAE5B,WAAW,EAAE,eAAe,GAC3B,OAAO,CAAC,cAAc,CAAC;IAe1B;;;;;;;OAOG;IACG,SAAS,CAAC,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,YAAY,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAe9F;;;;;;;OAOG;IACI,IAAI,CACT,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,qBAAqB,GAAG,SAAS,GACzC,cAAc,CAAC,eAAe,CAAC;IAkHlC;;;;;;;OAOG;YACW,4BAA4B;IAsF1C;;;;;;;OAOG;IACH,OAAO,CAAC,aAAa;CAStB"}
|
|
@@ -5,18 +5,32 @@
|
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
7
|
exports.DynamoDBSaver = void 0;
|
|
8
|
-
const langgraph_checkpoint_1 = require("@langchain/langgraph-checkpoint");
|
|
9
8
|
const client_dynamodb_1 = require("@aws-sdk/client-dynamodb");
|
|
10
9
|
const lib_dynamodb_1 = require("@aws-sdk/lib-dynamodb");
|
|
10
|
+
const langgraph_checkpoint_1 = require("@langchain/langgraph-checkpoint");
|
|
11
|
+
const shared_1 = require("../shared");
|
|
11
12
|
const actions_1 = require("./actions");
|
|
13
|
+
const types_1 = require("./types");
|
|
12
14
|
const utils_1 = require("./utils");
|
|
13
|
-
|
|
15
|
+
/**
|
|
16
|
+
* DynamoDB-based checkpoint saver for LangGraph.
|
|
17
|
+
* Provides persistent storage for checkpoints and pending writes.
|
|
18
|
+
*
|
|
19
|
+
* @remarks
|
|
20
|
+
* Uses the base class default for `getNextVersion()` (monotonic integers).
|
|
21
|
+
* Channel versioning is internal to LangGraph's execution engine and does not
|
|
22
|
+
* affect DynamoDB key ordering, which relies on checkpoint IDs.
|
|
23
|
+
*/
|
|
14
24
|
class DynamoDBSaver extends langgraph_checkpoint_1.BaseCheckpointSaver {
|
|
15
25
|
ddbClient;
|
|
16
26
|
client;
|
|
17
27
|
checkpointsTableName;
|
|
18
28
|
writesTableName;
|
|
19
29
|
ttlDays;
|
|
30
|
+
ttlSeconds;
|
|
31
|
+
compressor;
|
|
32
|
+
s3Offloader;
|
|
33
|
+
ownsClient;
|
|
20
34
|
/**
|
|
21
35
|
* Create a new DynamoDB checkpoint saver
|
|
22
36
|
*
|
|
@@ -24,16 +38,56 @@ class DynamoDBSaver extends langgraph_checkpoint_1.BaseCheckpointSaver {
|
|
|
24
38
|
* @param options.checkpointsTableName - Name of the DynamoDB table for checkpoints
|
|
25
39
|
* @param options.writesTableName - Name of the DynamoDB table for writes
|
|
26
40
|
* @param options.ttlDays - Optional TTL in days for stored items
|
|
41
|
+
* @param options.ttlSeconds - Optional TTL in seconds (overrides ttlDays if both set)
|
|
27
42
|
* @param options.serde - Optional serializer protocol
|
|
28
43
|
* @param options.clientConfig - Optional DynamoDB client configuration
|
|
44
|
+
* @param options.client - Optional pre-built DynamoDBDocument client (takes precedence over clientConfig)
|
|
45
|
+
* @param options.compression - Optional compression configuration
|
|
46
|
+
* @param options.s3OffloadConfig - Optional S3 offloading configuration
|
|
29
47
|
*/
|
|
30
48
|
constructor(options) {
|
|
31
49
|
super(options.serde);
|
|
32
50
|
this.checkpointsTableName = options.checkpointsTableName;
|
|
33
51
|
this.writesTableName = options.writesTableName;
|
|
34
52
|
this.ttlDays = options.ttlDays;
|
|
35
|
-
this.
|
|
36
|
-
|
|
53
|
+
this.ttlSeconds = options.ttlSeconds;
|
|
54
|
+
if (options.client) {
|
|
55
|
+
this.client = options.client;
|
|
56
|
+
this.ddbClient = undefined;
|
|
57
|
+
this.ownsClient = false;
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
this.ddbClient = new client_dynamodb_1.DynamoDBClient(options.clientConfig || {});
|
|
61
|
+
this.client = lib_dynamodb_1.DynamoDBDocument.from(this.ddbClient);
|
|
62
|
+
this.ownsClient = true;
|
|
63
|
+
}
|
|
64
|
+
if (options.compression?.enabled) {
|
|
65
|
+
this.compressor = new shared_1.Compressor(options.compression);
|
|
66
|
+
}
|
|
67
|
+
if (options.s3OffloadConfig) {
|
|
68
|
+
this.s3Offloader = new shared_1.S3Offloader(options.s3OffloadConfig);
|
|
69
|
+
}
|
|
70
|
+
// Auto-configure S3 lifecycle rule when both TTL and S3 offloading are active
|
|
71
|
+
if (this.s3Offloader && (this.ttlSeconds !== undefined || this.ttlDays !== undefined)) {
|
|
72
|
+
const lifecycleDays = this.ttlSeconds !== undefined ? Math.ceil(this.ttlSeconds / 86400) : this.ttlDays;
|
|
73
|
+
this.s3Offloader.ensureLifecycleRule(lifecycleDays).catch((err) => {
|
|
74
|
+
const message = err && typeof err === 'object' && 'message' in err
|
|
75
|
+
? err.message
|
|
76
|
+
: String(err);
|
|
77
|
+
(0, shared_1.getLogger)().warn(`Failed to configure S3 lifecycle rule: ${message}`);
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Release underlying DynamoDB and S3 client resources.
|
|
83
|
+
* Call this when the saver is no longer needed to prevent resource leaks.
|
|
84
|
+
* Skips DynamoDB client cleanup if a shared client was injected via options.
|
|
85
|
+
*/
|
|
86
|
+
destroy() {
|
|
87
|
+
if (this.ownsClient && this.ddbClient) {
|
|
88
|
+
this.ddbClient.destroy();
|
|
89
|
+
}
|
|
90
|
+
this.s3Offloader?.destroy();
|
|
37
91
|
}
|
|
38
92
|
/**
|
|
39
93
|
* Delete a thread and all its checkpoints and writes
|
|
@@ -47,6 +101,7 @@ class DynamoDBSaver extends langgraph_checkpoint_1.BaseCheckpointSaver {
|
|
|
47
101
|
checkpointsTableName: this.checkpointsTableName,
|
|
48
102
|
writesTableName: this.writesTableName,
|
|
49
103
|
threadId,
|
|
104
|
+
s3Offloader: this.s3Offloader,
|
|
50
105
|
});
|
|
51
106
|
}
|
|
52
107
|
/**
|
|
@@ -63,6 +118,8 @@ class DynamoDBSaver extends langgraph_checkpoint_1.BaseCheckpointSaver {
|
|
|
63
118
|
writesTableName: this.writesTableName,
|
|
64
119
|
serde: this.serde,
|
|
65
120
|
config,
|
|
121
|
+
compressor: this.compressor,
|
|
122
|
+
s3Offloader: this.s3Offloader,
|
|
66
123
|
});
|
|
67
124
|
}
|
|
68
125
|
/**
|
|
@@ -86,6 +143,9 @@ class DynamoDBSaver extends langgraph_checkpoint_1.BaseCheckpointSaver {
|
|
|
86
143
|
checkpoint,
|
|
87
144
|
metadata,
|
|
88
145
|
ttlDays: this.ttlDays,
|
|
146
|
+
ttlSeconds: this.ttlSeconds,
|
|
147
|
+
compressor: this.compressor,
|
|
148
|
+
s3Offloader: this.s3Offloader,
|
|
89
149
|
});
|
|
90
150
|
}
|
|
91
151
|
/**
|
|
@@ -105,19 +165,23 @@ class DynamoDBSaver extends langgraph_checkpoint_1.BaseCheckpointSaver {
|
|
|
105
165
|
writes,
|
|
106
166
|
taskId,
|
|
107
167
|
ttlDays: this.ttlDays,
|
|
168
|
+
ttlSeconds: this.ttlSeconds,
|
|
169
|
+
compressor: this.compressor,
|
|
170
|
+
s3Offloader: this.s3Offloader,
|
|
108
171
|
});
|
|
109
172
|
}
|
|
110
173
|
/**
|
|
111
174
|
* List checkpoints for a thread
|
|
112
175
|
*
|
|
113
176
|
* @param config - Runnable configuration containing thread_id
|
|
114
|
-
* @param options - List options including limit and
|
|
177
|
+
* @param options - List options including limit, before checkpoint, and metadata filter
|
|
115
178
|
* @yields CheckpointTuple objects in descending order
|
|
116
179
|
* @throws Error if validation fails or operation fails
|
|
117
180
|
*/
|
|
118
181
|
async *list(config, options) {
|
|
119
|
-
const { limit, before } = options ?? {};
|
|
182
|
+
const { limit, before, filter } = options ?? {};
|
|
120
183
|
const thread_id = config.configurable?.thread_id;
|
|
184
|
+
const checkpoint_ns = config.configurable?.checkpoint_ns;
|
|
121
185
|
// Validate thread_id
|
|
122
186
|
if (typeof thread_id !== 'string') {
|
|
123
187
|
throw new Error('thread_id must be a string');
|
|
@@ -127,26 +191,177 @@ class DynamoDBSaver extends langgraph_checkpoint_1.BaseCheckpointSaver {
|
|
|
127
191
|
(0, utils_1.validateListLimit)(limit);
|
|
128
192
|
const expressionAttributeValues = {
|
|
129
193
|
':thread_id': thread_id,
|
|
194
|
+
':payload_prefix': types_1.PAYLOAD_SK_PREFIX,
|
|
195
|
+
...(checkpoint_ns !== undefined && { ':checkpoint_ns': checkpoint_ns }),
|
|
130
196
|
};
|
|
131
|
-
|
|
197
|
+
// Filter by namespace when provided — applied after reading (costs RCU for
|
|
198
|
+
// non-matching items, but avoids an additional GSI for the uncommon case).
|
|
199
|
+
const filterExpression = checkpoint_ns !== undefined ? 'checkpoint_ns = :checkpoint_ns' : undefined;
|
|
200
|
+
// Key condition excludes PAYLOAD# items — only metadata items are returned.
|
|
201
|
+
// UUID checkpoint IDs (hex 0-9, a-f) sort before 'PAYLOAD#' in ASCII.
|
|
202
|
+
let keyConditionExpression = 'thread_id = :thread_id AND checkpoint_id < :payload_prefix';
|
|
132
203
|
if (before?.configurable?.checkpoint_id) {
|
|
133
|
-
keyConditionExpression
|
|
204
|
+
keyConditionExpression = 'thread_id = :thread_id AND checkpoint_id < :before_checkpoint_id';
|
|
134
205
|
expressionAttributeValues[':before_checkpoint_id'] = before.configurable.checkpoint_id;
|
|
206
|
+
// No need for :payload_prefix — before_checkpoint_id is always a UUID which is < PAYLOAD#
|
|
135
207
|
}
|
|
208
|
+
// When filter is active, skip DynamoDB-level Limit since metadata filtering
|
|
209
|
+
// is a post-filter (metadata is stored as binary and cannot be filtered server-side).
|
|
210
|
+
const hasFilter = filter && Object.keys(filter).length > 0;
|
|
211
|
+
const queryLimit = hasFilter ? undefined : limit;
|
|
136
212
|
const result = await (0, shared_1.withDynamoDBRetry)(async () => {
|
|
137
213
|
return await this.client.query({
|
|
138
214
|
TableName: this.checkpointsTableName,
|
|
139
215
|
KeyConditionExpression: keyConditionExpression,
|
|
140
216
|
ExpressionAttributeValues: expressionAttributeValues,
|
|
141
|
-
|
|
217
|
+
FilterExpression: filterExpression,
|
|
218
|
+
Limit: queryLimit,
|
|
142
219
|
ScanIndexForward: false, // Descending order
|
|
143
220
|
});
|
|
144
221
|
});
|
|
222
|
+
let yieldedCount = 0;
|
|
145
223
|
if (result.Items) {
|
|
146
|
-
|
|
147
|
-
|
|
224
|
+
const items = result.Items;
|
|
225
|
+
const payloadMap = await this.fetchCheckpointPayloadsBatch(items);
|
|
226
|
+
for (const item of items) {
|
|
227
|
+
const checkpointData = payloadMap.get(item.checkpoint_id) ?? new Uint8Array(0);
|
|
228
|
+
const tuple = await (0, utils_1.deserializeCheckpointTuple)(item, checkpointData, this.serde, this.compressor, this.s3Offloader);
|
|
229
|
+
// Apply metadata filter: skip checkpoints that don't match all filter entries
|
|
230
|
+
if (hasFilter && !this.matchesFilter(tuple.metadata, filter)) {
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
yield tuple;
|
|
234
|
+
yieldedCount++;
|
|
235
|
+
if (limit && yieldedCount >= limit)
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
// Paginate through remaining results if LastEvaluatedKey is present
|
|
240
|
+
let lastEvaluatedKey = result.LastEvaluatedKey;
|
|
241
|
+
while (lastEvaluatedKey) {
|
|
242
|
+
const nextResult = await (0, shared_1.withDynamoDBRetry)(async () => {
|
|
243
|
+
return await this.client.query({
|
|
244
|
+
TableName: this.checkpointsTableName,
|
|
245
|
+
KeyConditionExpression: keyConditionExpression,
|
|
246
|
+
ExpressionAttributeValues: expressionAttributeValues,
|
|
247
|
+
FilterExpression: filterExpression,
|
|
248
|
+
Limit: hasFilter ? undefined : limit ? limit - yieldedCount : undefined,
|
|
249
|
+
ScanIndexForward: false,
|
|
250
|
+
ExclusiveStartKey: lastEvaluatedKey,
|
|
251
|
+
});
|
|
252
|
+
});
|
|
253
|
+
if (nextResult.Items) {
|
|
254
|
+
const items = nextResult.Items;
|
|
255
|
+
const payloadMap = await this.fetchCheckpointPayloadsBatch(items);
|
|
256
|
+
for (const item of items) {
|
|
257
|
+
const checkpointData = payloadMap.get(item.checkpoint_id) ?? new Uint8Array(0);
|
|
258
|
+
const tuple = await (0, utils_1.deserializeCheckpointTuple)(item, checkpointData, this.serde, this.compressor, this.s3Offloader);
|
|
259
|
+
if (hasFilter && !this.matchesFilter(tuple.metadata, filter)) {
|
|
260
|
+
continue;
|
|
261
|
+
}
|
|
262
|
+
yield tuple;
|
|
263
|
+
yieldedCount++;
|
|
264
|
+
if (limit && yieldedCount >= limit)
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
lastEvaluatedKey = nextResult.LastEvaluatedKey;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Fetch checkpoint payloads for a batch of metadata items.
|
|
273
|
+
* Uses BatchGetItem to fetch all payloads in one round trip instead of N+1 queries.
|
|
274
|
+
* Items with S3 keys or legacy inline data are resolved without a remote call.
|
|
275
|
+
*
|
|
276
|
+
* @param items - Checkpoint metadata items from a query result
|
|
277
|
+
* @returns Map from checkpoint_id to raw checkpoint data
|
|
278
|
+
*/
|
|
279
|
+
async fetchCheckpointPayloadsBatch(items) {
|
|
280
|
+
const payloadMap = new Map();
|
|
281
|
+
// Partition items into groups
|
|
282
|
+
const splitItems = []; // Need PAYLOAD# fetch
|
|
283
|
+
for (const item of items) {
|
|
284
|
+
if (item.s3_checkpoint_key) {
|
|
285
|
+
// S3 offloaded — deserializeCheckpointTuple will download from S3
|
|
286
|
+
payloadMap.set(item.checkpoint_id, new Uint8Array(0));
|
|
287
|
+
}
|
|
288
|
+
else if (item.checkpoint && item.checkpoint.length > 0) {
|
|
289
|
+
// Legacy inline — use item.checkpoint directly
|
|
290
|
+
payloadMap.set(item.checkpoint_id, item.checkpoint);
|
|
291
|
+
}
|
|
292
|
+
else {
|
|
293
|
+
// New split format — needs PAYLOAD# fetch
|
|
294
|
+
splitItems.push(item);
|
|
148
295
|
}
|
|
149
296
|
}
|
|
297
|
+
if (splitItems.length === 0) {
|
|
298
|
+
return payloadMap;
|
|
299
|
+
}
|
|
300
|
+
// BatchGetItem supports up to 100 keys per call
|
|
301
|
+
const BATCH_GET_MAX = 100;
|
|
302
|
+
for (let i = 0; i < splitItems.length; i += BATCH_GET_MAX) {
|
|
303
|
+
const batch = splitItems.slice(i, i + BATCH_GET_MAX);
|
|
304
|
+
let keys = batch.map((item) => ({
|
|
305
|
+
thread_id: item.thread_id,
|
|
306
|
+
checkpoint_id: `${types_1.PAYLOAD_SK_PREFIX}${item.checkpoint_id}`,
|
|
307
|
+
}));
|
|
308
|
+
// Retry loop for UnprocessedKeys with exponential backoff
|
|
309
|
+
let retryDelay = 100;
|
|
310
|
+
let retryCount = 0;
|
|
311
|
+
while (keys.length > 0) {
|
|
312
|
+
const batchResult = await (0, shared_1.withDynamoDBRetry)(async () => {
|
|
313
|
+
return await this.client.batchGet({
|
|
314
|
+
RequestItems: {
|
|
315
|
+
[this.checkpointsTableName]: { Keys: keys },
|
|
316
|
+
},
|
|
317
|
+
});
|
|
318
|
+
});
|
|
319
|
+
// Map results — BatchGetItem returns items in arbitrary order
|
|
320
|
+
const responses = batchResult.Responses?.[this.checkpointsTableName];
|
|
321
|
+
if (responses) {
|
|
322
|
+
for (const response of responses) {
|
|
323
|
+
// Extract original checkpoint_id from PAYLOAD#<id> sort key
|
|
324
|
+
const originalId = response.checkpoint_id.substring(types_1.PAYLOAD_SK_PREFIX.length);
|
|
325
|
+
payloadMap.set(originalId, response.checkpoint);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
// Handle UnprocessedKeys with exponential backoff
|
|
329
|
+
const unprocessed = batchResult.UnprocessedKeys?.[this.checkpointsTableName]?.Keys;
|
|
330
|
+
if (unprocessed && unprocessed.length > 0) {
|
|
331
|
+
retryCount++;
|
|
332
|
+
if (retryCount > shared_1.MAX_UNPROCESSED_RETRIES) {
|
|
333
|
+
throw new Error(`Failed to fetch all checkpoint payloads after ${shared_1.MAX_UNPROCESSED_RETRIES} retries. ` +
|
|
334
|
+
`${unprocessed.length} keys remain unprocessed.`);
|
|
335
|
+
}
|
|
336
|
+
await new Promise((resolve) => setTimeout(resolve, retryDelay));
|
|
337
|
+
retryDelay = Math.min(retryDelay * 2, 5000);
|
|
338
|
+
keys = unprocessed;
|
|
339
|
+
}
|
|
340
|
+
else {
|
|
341
|
+
break;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
// Verify all split items were fetched
|
|
346
|
+
for (const item of splitItems) {
|
|
347
|
+
if (!payloadMap.has(item.checkpoint_id)) {
|
|
348
|
+
throw new Error(`Checkpoint payload item not found for thread_id=${item.thread_id}, checkpoint_id=${item.checkpoint_id}`);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
return payloadMap;
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Check if checkpoint metadata matches all entries in the filter.
|
|
355
|
+
* Each filter key must exactly match the corresponding metadata value.
|
|
356
|
+
*
|
|
357
|
+
* @param metadata - Deserialized checkpoint metadata
|
|
358
|
+
* @param filter - Key-value pairs to match against metadata
|
|
359
|
+
* @returns true if all filter entries match
|
|
360
|
+
*/
|
|
361
|
+
matchesFilter(metadata, filter) {
|
|
362
|
+
if (!metadata)
|
|
363
|
+
return false;
|
|
364
|
+
return Object.entries(filter).every(([key, value]) => metadata[key] === value);
|
|
150
365
|
}
|
|
151
366
|
}
|
|
152
367
|
exports.DynamoDBSaver = DynamoDBSaver;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/checkpointer/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/checkpointer/index.ts"],"names":[],"mappings":"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"}
|