@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,7 +1,8 @@
|
|
|
1
|
-
import { Checkpoint, CheckpointMetadata, PendingWrite, SerializerProtocol } from '@langchain/langgraph-checkpoint';
|
|
2
1
|
import type { DynamoDBClientConfig } from '@aws-sdk/client-dynamodb';
|
|
3
2
|
import { DynamoDBDocument } from '@aws-sdk/lib-dynamodb';
|
|
4
3
|
import { RunnableConfig } from '@langchain/core/runnables';
|
|
4
|
+
import { Checkpoint, CheckpointMetadata, PendingWrite, SerializerProtocol } from '@langchain/langgraph-checkpoint';
|
|
5
|
+
import type { CompressionConfig, Compressor, S3OffloadConfig, S3Offloader } from '../../shared';
|
|
5
6
|
/**
|
|
6
7
|
* Configuration options for DynamoDBSaver
|
|
7
8
|
*
|
|
@@ -15,8 +16,16 @@ export interface DynamoDBSaverOptions {
|
|
|
15
16
|
checkpointsTableName: string;
|
|
16
17
|
writesTableName: string;
|
|
17
18
|
ttlDays?: number;
|
|
19
|
+
/** TTL in seconds for automatic item expiration (overrides ttlDays if both set) */
|
|
20
|
+
ttlSeconds?: number;
|
|
21
|
+
/** Optional compression configuration for checkpoint data */
|
|
22
|
+
compression?: CompressionConfig;
|
|
23
|
+
/** Optional S3 offloading for payloads exceeding DynamoDB's 400KB item limit */
|
|
24
|
+
s3OffloadConfig?: S3OffloadConfig;
|
|
18
25
|
serde?: SerializerProtocol;
|
|
19
26
|
clientConfig?: DynamoDBClientConfig;
|
|
27
|
+
/** Optional pre-built DynamoDBDocument client (takes precedence over clientConfig) */
|
|
28
|
+
client?: DynamoDBDocument;
|
|
20
29
|
}
|
|
21
30
|
/**
|
|
22
31
|
* Properties for creating a Writer instance
|
|
@@ -56,17 +65,31 @@ export interface DynamoDBWriteItem {
|
|
|
56
65
|
channel: string;
|
|
57
66
|
type: string;
|
|
58
67
|
value: Uint8Array;
|
|
68
|
+
/** Optional TTL timestamp for automatic item expiration */
|
|
69
|
+
ttl?: number;
|
|
70
|
+
/** S3 key reference when value was offloaded to S3 */
|
|
71
|
+
s3_value_key?: string;
|
|
59
72
|
}
|
|
60
73
|
/**
|
|
61
|
-
*
|
|
74
|
+
* Sort key prefix for payload items in the checkpoints table.
|
|
75
|
+
* Payload items store the heavy checkpoint blob separately from metadata
|
|
76
|
+
* to reduce RCU consumption on list() queries.
|
|
77
|
+
*
|
|
78
|
+
* UUID checkpoint IDs (hex chars 0-9, a-f) sort before 'PAYLOAD#' in ASCII,
|
|
79
|
+
* so key condition `checkpoint_id < PAYLOAD#` naturally excludes payload items.
|
|
80
|
+
*/
|
|
81
|
+
export declare const PAYLOAD_SK_PREFIX = "PAYLOAD#";
|
|
82
|
+
/**
|
|
83
|
+
* DynamoDB representation of a checkpoint metadata item.
|
|
84
|
+
* Stores lightweight metadata; the heavy checkpoint blob lives in a separate payload item.
|
|
62
85
|
*
|
|
63
86
|
* @property thread_id - Unique identifier for the conversation thread (partition key)
|
|
64
87
|
* @property checkpoint_ns - Namespace for checkpoint isolation
|
|
65
88
|
* @property checkpoint_id - Unique identifier for the checkpoint (sort key)
|
|
66
89
|
* @property parent_checkpoint_id - Optional ID of the parent checkpoint for checkpoint chains
|
|
67
90
|
* @property type - Type identifier for deserialization
|
|
68
|
-
* @property checkpoint - Serialized checkpoint data as binary
|
|
69
91
|
* @property metadata - Serialized metadata as binary
|
|
92
|
+
* @property checkpoint - Present only for backward compatibility with legacy single-item format
|
|
70
93
|
*/
|
|
71
94
|
export interface CheckpointItem {
|
|
72
95
|
thread_id: string;
|
|
@@ -74,8 +97,29 @@ export interface CheckpointItem {
|
|
|
74
97
|
checkpoint_id: string;
|
|
75
98
|
parent_checkpoint_id?: string;
|
|
76
99
|
type: string;
|
|
77
|
-
checkpoint: Uint8Array;
|
|
78
100
|
metadata: Uint8Array;
|
|
101
|
+
/** S3 key reference when checkpoint data was offloaded to S3 */
|
|
102
|
+
s3_checkpoint_key?: string;
|
|
103
|
+
/** S3 key reference when metadata was offloaded to S3 */
|
|
104
|
+
s3_metadata_key?: string;
|
|
105
|
+
/**
|
|
106
|
+
* Legacy field: present only on old single-item checkpoint items.
|
|
107
|
+
* New items store the checkpoint blob in a separate payload item.
|
|
108
|
+
*/
|
|
109
|
+
checkpoint?: Uint8Array;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* DynamoDB representation of a checkpoint payload item.
|
|
113
|
+
* Contains only the heavy serialized checkpoint blob.
|
|
114
|
+
*
|
|
115
|
+
* @property thread_id - Partition key (same as metadata item)
|
|
116
|
+
* @property checkpoint_id - Sort key with PAYLOAD# prefix
|
|
117
|
+
* @property checkpoint - Serialized checkpoint data as binary
|
|
118
|
+
*/
|
|
119
|
+
export interface CheckpointPayloadItem {
|
|
120
|
+
thread_id: string;
|
|
121
|
+
checkpoint_id: string;
|
|
122
|
+
checkpoint: Uint8Array;
|
|
79
123
|
}
|
|
80
124
|
/**
|
|
81
125
|
* Validated configurable parameters from RunnableConfig
|
|
@@ -102,6 +146,8 @@ export interface DeleteThreadActionParams {
|
|
|
102
146
|
checkpointsTableName: string;
|
|
103
147
|
writesTableName: string;
|
|
104
148
|
threadId: string;
|
|
149
|
+
/** Optional S3 offloader for cleaning up offloaded payloads */
|
|
150
|
+
s3Offloader?: S3Offloader;
|
|
105
151
|
}
|
|
106
152
|
/**
|
|
107
153
|
* Parameters for getTuple action
|
|
@@ -118,6 +164,10 @@ export interface GetTupleActionParams {
|
|
|
118
164
|
writesTableName: string;
|
|
119
165
|
serde: SerializerProtocol;
|
|
120
166
|
config: RunnableConfig;
|
|
167
|
+
/** Optional compressor for decompressing checkpoint data */
|
|
168
|
+
compressor?: Compressor;
|
|
169
|
+
/** Optional S3 offloader for downloading offloaded payloads */
|
|
170
|
+
s3Offloader?: S3Offloader;
|
|
121
171
|
}
|
|
122
172
|
/**
|
|
123
173
|
* Parameters for put action
|
|
@@ -138,6 +188,12 @@ export interface PutActionParams {
|
|
|
138
188
|
checkpoint: Checkpoint;
|
|
139
189
|
metadata: CheckpointMetadata;
|
|
140
190
|
ttlDays?: number;
|
|
191
|
+
/** TTL in seconds (overrides ttlDays if both set) */
|
|
192
|
+
ttlSeconds?: number;
|
|
193
|
+
/** Optional compressor for compressing checkpoint data */
|
|
194
|
+
compressor?: Compressor;
|
|
195
|
+
/** Optional S3 offloader for large payloads */
|
|
196
|
+
s3Offloader?: S3Offloader;
|
|
141
197
|
}
|
|
142
198
|
/**
|
|
143
199
|
* Parameters for putWrites action
|
|
@@ -158,5 +214,11 @@ export interface PutWritesActionParams {
|
|
|
158
214
|
writes: PendingWrite[];
|
|
159
215
|
taskId: string;
|
|
160
216
|
ttlDays?: number;
|
|
217
|
+
/** TTL in seconds (overrides ttlDays if both set) */
|
|
218
|
+
ttlSeconds?: number;
|
|
219
|
+
/** Optional compressor for compressing write data */
|
|
220
|
+
compressor?: Compressor;
|
|
221
|
+
/** Optional S3 offloader for large write payloads */
|
|
222
|
+
s3Offloader?: S3Offloader;
|
|
161
223
|
}
|
|
162
224
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/checkpointer/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/checkpointer/types/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PAYLOAD_SK_PREFIX = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Sort key prefix for payload items in the checkpoints table.
|
|
6
|
+
* Payload items store the heavy checkpoint blob separately from metadata
|
|
7
|
+
* to reduce RCU consumption on list() queries.
|
|
8
|
+
*
|
|
9
|
+
* UUID checkpoint IDs (hex chars 0-9, a-f) sort before 'PAYLOAD#' in ASCII,
|
|
10
|
+
* so key condition `checkpoint_id < PAYLOAD#` naturally excludes payload items.
|
|
11
|
+
*/
|
|
12
|
+
exports.PAYLOAD_SK_PREFIX = 'PAYLOAD#';
|
|
3
13
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/checkpointer/types/index.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/checkpointer/types/index.ts"],"names":[],"mappings":";;;AAkFA;;;;;;;GAOG;AACU,QAAA,iBAAiB,GAAG,UAAU,CAAC"}
|
|
@@ -3,13 +3,18 @@
|
|
|
3
3
|
* Provides centralized checkpoint tuple conversion
|
|
4
4
|
*/
|
|
5
5
|
import type { CheckpointTuple, SerializerProtocol } from '@langchain/langgraph-checkpoint';
|
|
6
|
+
import type { Compressor, S3Offloader } from '../../shared';
|
|
6
7
|
import type { CheckpointItem } from '../types';
|
|
7
8
|
/**
|
|
8
|
-
* Deserialize a DynamoDB checkpoint item into a CheckpointTuple
|
|
9
|
+
* Deserialize a DynamoDB checkpoint metadata item into a CheckpointTuple.
|
|
10
|
+
* The heavy checkpoint blob is provided separately (from a payload item or S3).
|
|
9
11
|
*
|
|
10
|
-
* @param item - DynamoDB checkpoint item
|
|
12
|
+
* @param item - DynamoDB checkpoint metadata item
|
|
13
|
+
* @param checkpointData - Raw checkpoint blob (from payload item, S3, or legacy inline field)
|
|
11
14
|
* @param serde - Serializer protocol for deserialization
|
|
15
|
+
* @param compressor - Optional compressor for decompression (auto-detects gzip)
|
|
16
|
+
* @param s3Offloader - Optional S3 offloader for downloading offloaded metadata
|
|
12
17
|
* @returns CheckpointTuple with deserialized checkpoint and metadata
|
|
13
18
|
*/
|
|
14
|
-
export declare function deserializeCheckpointTuple(item: CheckpointItem, serde: SerializerProtocol): Promise<CheckpointTuple>;
|
|
19
|
+
export declare function deserializeCheckpointTuple(item: CheckpointItem, checkpointData: Uint8Array, serde: SerializerProtocol, compressor?: Compressor, s3Offloader?: S3Offloader): Promise<CheckpointTuple>;
|
|
15
20
|
//# sourceMappingURL=deserialization.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deserialization.d.ts","sourceRoot":"","sources":["../../../src/checkpointer/utils/deserialization.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAGV,eAAe,EACf,kBAAkB,EACnB,MAAM,iCAAiC,CAAC;AAEzC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE/C
|
|
1
|
+
{"version":3,"file":"deserialization.d.ts","sourceRoot":"","sources":["../../../src/checkpointer/utils/deserialization.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAGV,eAAe,EACf,kBAAkB,EACnB,MAAM,iCAAiC,CAAC;AAEzC,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE/C;;;;;;;;;;GAUG;AACH,wBAAsB,0BAA0B,CAC9C,IAAI,EAAE,cAAc,EACpB,cAAc,EAAE,UAAU,EAC1B,KAAK,EAAE,kBAAkB,EACzB,UAAU,CAAC,EAAE,UAAU,EACvB,WAAW,CAAC,EAAE,WAAW,GACxB,OAAO,CAAC,eAAe,CAAC,CAyC1B"}
|
|
@@ -6,15 +6,33 @@
|
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
7
|
exports.deserializeCheckpointTuple = deserializeCheckpointTuple;
|
|
8
8
|
/**
|
|
9
|
-
* Deserialize a DynamoDB checkpoint item into a CheckpointTuple
|
|
9
|
+
* Deserialize a DynamoDB checkpoint metadata item into a CheckpointTuple.
|
|
10
|
+
* The heavy checkpoint blob is provided separately (from a payload item or S3).
|
|
10
11
|
*
|
|
11
|
-
* @param item - DynamoDB checkpoint item
|
|
12
|
+
* @param item - DynamoDB checkpoint metadata item
|
|
13
|
+
* @param checkpointData - Raw checkpoint blob (from payload item, S3, or legacy inline field)
|
|
12
14
|
* @param serde - Serializer protocol for deserialization
|
|
15
|
+
* @param compressor - Optional compressor for decompression (auto-detects gzip)
|
|
16
|
+
* @param s3Offloader - Optional S3 offloader for downloading offloaded metadata
|
|
13
17
|
* @returns CheckpointTuple with deserialized checkpoint and metadata
|
|
14
18
|
*/
|
|
15
|
-
async function deserializeCheckpointTuple(item, serde) {
|
|
16
|
-
|
|
17
|
-
|
|
19
|
+
async function deserializeCheckpointTuple(item, checkpointData, serde, compressor, s3Offloader) {
|
|
20
|
+
// Download checkpoint from S3 if offloaded (checked first to maintain original S3 call order)
|
|
21
|
+
let rawCheckpoint = checkpointData;
|
|
22
|
+
if (item.s3_checkpoint_key && s3Offloader) {
|
|
23
|
+
rawCheckpoint = await s3Offloader.download(item.s3_checkpoint_key);
|
|
24
|
+
}
|
|
25
|
+
// Download metadata from S3 if offloaded, otherwise use DynamoDB data
|
|
26
|
+
let rawMetadata = item.metadata;
|
|
27
|
+
if (item.s3_metadata_key && s3Offloader) {
|
|
28
|
+
rawMetadata = await s3Offloader.download(item.s3_metadata_key);
|
|
29
|
+
}
|
|
30
|
+
const decompressedCheckpoint = compressor
|
|
31
|
+
? await compressor.decompress(rawCheckpoint)
|
|
32
|
+
: rawCheckpoint;
|
|
33
|
+
const decompressedMetadata = compressor ? await compressor.decompress(rawMetadata) : rawMetadata;
|
|
34
|
+
const checkpoint = (await serde.loadsTyped(item.type, decompressedCheckpoint));
|
|
35
|
+
const metadata = (await serde.loadsTyped(item.type, decompressedMetadata));
|
|
18
36
|
return {
|
|
19
37
|
config: {
|
|
20
38
|
configurable: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deserialization.js","sourceRoot":"","sources":["../../../src/checkpointer/utils/deserialization.ts"],"names":[],"mappings":";AAAA;;;GAGG;;
|
|
1
|
+
{"version":3,"file":"deserialization.js","sourceRoot":"","sources":["../../../src/checkpointer/utils/deserialization.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAuBH,gEA+CC;AA1DD;;;;;;;;;;GAUG;AACI,KAAK,UAAU,0BAA0B,CAC9C,IAAoB,EACpB,cAA0B,EAC1B,KAAyB,EACzB,UAAuB,EACvB,WAAyB;IAEzB,8FAA8F;IAC9F,IAAI,aAAa,GAAe,cAAc,CAAC;IAC/C,IAAI,IAAI,CAAC,iBAAiB,IAAI,WAAW,EAAE,CAAC;QAC1C,aAAa,GAAG,MAAM,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IACrE,CAAC;IAED,sEAAsE;IACtE,IAAI,WAAW,GAAe,IAAI,CAAC,QAAQ,CAAC;IAC5C,IAAI,IAAI,CAAC,eAAe,IAAI,WAAW,EAAE,CAAC;QACxC,WAAW,GAAG,MAAM,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IACjE,CAAC;IAED,MAAM,sBAAsB,GAAG,UAAU;QACvC,CAAC,CAAC,MAAM,UAAU,CAAC,UAAU,CAAC,aAAa,CAAC;QAC5C,CAAC,CAAC,aAAa,CAAC;IAClB,MAAM,oBAAoB,GAAG,UAAU,CAAC,CAAC,CAAC,MAAM,UAAU,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC;IAEjG,MAAM,UAAU,GAAG,CAAC,MAAM,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,sBAAsB,CAAC,CAAe,CAAC;IAC7F,MAAM,QAAQ,GAAG,CAAC,MAAM,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,oBAAoB,CAAC,CAAuB,CAAC;IAEjG,OAAO;QACL,MAAM,EAAE;YACN,YAAY,EAAE;gBACZ,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,aAAa,EAAE,IAAI,CAAC,aAAa;gBACjC,aAAa,EAAE,IAAI,CAAC,aAAa;aAClC;SACF;QACD,UAAU;QACV,QAAQ;QACR,YAAY,EAAE,IAAI,CAAC,oBAAoB;YACrC,CAAC,CAAC;gBACE,YAAY,EAAE;oBACZ,SAAS,EAAE,IAAI,CAAC,SAAS;oBACzB,aAAa,EAAE,IAAI,CAAC,aAAa;oBACjC,aAAa,EAAE,IAAI,CAAC,oBAAoB;iBACzC;aACF;YACH,CAAC,CAAC,SAAS;KACd,CAAC;AACJ,CAAC"}
|
|
@@ -40,7 +40,7 @@ export declare function validateTTLDays(ttlDays: number | undefined): void;
|
|
|
40
40
|
* Export constants for use in other modules
|
|
41
41
|
*/
|
|
42
42
|
export declare const CheckpointerValidationConstants: {
|
|
43
|
-
readonly MAX_DELETE_BATCH_SIZE:
|
|
43
|
+
readonly MAX_DELETE_BATCH_SIZE: 1000;
|
|
44
44
|
readonly MAX_WRITES_PER_BATCH: 1000;
|
|
45
45
|
readonly MAX_LIST_LIMIT: 1000;
|
|
46
46
|
readonly SEPARATOR: ":::";
|
|
@@ -20,7 +20,7 @@ const MAX_TASK_ID_LENGTH = 256;
|
|
|
20
20
|
const MAX_CHANNEL_LENGTH = 256;
|
|
21
21
|
const MAX_WRITES_PER_BATCH = 1000;
|
|
22
22
|
const MAX_LIST_LIMIT = 1000;
|
|
23
|
-
const MAX_DELETE_BATCH_SIZE =
|
|
23
|
+
const MAX_DELETE_BATCH_SIZE = 1000; // Maximum items (metadata + payload) to delete at once
|
|
24
24
|
const SEPARATOR = ':::';
|
|
25
25
|
class CheckpointerValidationError extends Error {
|
|
26
26
|
constructor(message) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../../src/checkpointer/utils/validation.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAwBH,4CAyBC;AAKD,oDAgCC;AAKD,oDAyBC;AAKD,wCAmBC;AAKD,0CAcC;AAKD,kDAcC;AAKD,8CAgBC;AAKD,0CAOC;AAjND,8CAA0E;AAE1E,MAAM,oBAAoB,GAAG,GAAG,CAAC;AACjC,MAAM,wBAAwB,GAAG,GAAG,CAAC;AACrC,MAAM,wBAAwB,GAAG,GAAG,CAAC;AACrC,MAAM,kBAAkB,GAAG,GAAG,CAAC;AAC/B,MAAM,kBAAkB,GAAG,GAAG,CAAC;AAC/B,MAAM,oBAAoB,GAAG,IAAI,CAAC;AAClC,MAAM,cAAc,GAAG,IAAI,CAAC;AAC5B,MAAM,qBAAqB,GAAG,
|
|
1
|
+
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../../src/checkpointer/utils/validation.ts"],"names":[],"mappings":"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"}
|
package/dist/factory.d.ts
CHANGED
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
* Factory for creating DynamoDB persistence instances with sensible defaults
|
|
3
3
|
* Provides convenient methods for instantiating checkpointer, store, and chat history
|
|
4
4
|
*/
|
|
5
|
-
import type
|
|
6
|
-
import type {
|
|
5
|
+
import { type DynamoDBClientConfig } from '@aws-sdk/client-dynamodb';
|
|
6
|
+
import type { EmbeddingsInterface } from '@langchain/core/embeddings';
|
|
7
7
|
import type { SerializerProtocol } from '@langchain/langgraph-checkpoint';
|
|
8
8
|
import { DynamoDBSaver } from './checkpointer';
|
|
9
|
-
import { DynamoDBStore } from './store';
|
|
10
|
-
import { DynamoDBChatMessageHistory } from './history';
|
|
11
9
|
import type { DynamoDBSaverOptions } from './checkpointer/types';
|
|
12
|
-
import
|
|
10
|
+
import { DynamoDBChatMessageHistory } from './history';
|
|
13
11
|
import type { DynamoDBChatMessageHistoryOptions } from './history/types';
|
|
12
|
+
import { DynamoDBStore } from './store';
|
|
13
|
+
import type { DynamoDBStoreOptions } from './store/types';
|
|
14
14
|
/**
|
|
15
15
|
* Factory class for creating DynamoDB persistence instances
|
|
16
16
|
*/
|
|
@@ -126,12 +126,14 @@ export declare class DynamoDBFactory {
|
|
|
126
126
|
tablePrefix?: string;
|
|
127
127
|
ttlDays?: number;
|
|
128
128
|
clientConfig?: DynamoDBClientConfig;
|
|
129
|
-
embedding?:
|
|
129
|
+
embedding?: EmbeddingsInterface;
|
|
130
130
|
serde?: SerializerProtocol;
|
|
131
131
|
}): {
|
|
132
132
|
checkpointer: DynamoDBSaver;
|
|
133
133
|
store: DynamoDBStore;
|
|
134
134
|
chatHistory: DynamoDBChatMessageHistory;
|
|
135
|
+
/** Destroy the shared DynamoDB client created by createAll(). Call when no longer needed. */
|
|
136
|
+
destroy: () => void;
|
|
135
137
|
};
|
|
136
138
|
}
|
|
137
139
|
//# sourceMappingURL=factory.d.ts.map
|
package/dist/factory.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAkB,KAAK,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAErF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAE1E,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,EAAE,0BAA0B,EAAE,MAAM,WAAW,CAAC;AACvD,OAAO,KAAK,EAAE,iCAAiC,EAAE,MAAM,iBAAiB,CAAC;AACzE,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAO1D;;GAEG;AACH,qBAAa,eAAe;IAC1B;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACH,MAAM,CAAC,WAAW,CAAC,OAAO,GAAE,OAAO,CAAC,oBAAoB,CAAM,GAAG,aAAa;IAgB9E;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACH,MAAM,CAAC,WAAW,CAAC,OAAO,GAAE,OAAO,CAAC,oBAAoB,CAAM,GAAG,aAAa;IAY9E;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,MAAM,CAAC,wBAAwB,CAC7B,OAAO,GAAE,OAAO,CAAC,iCAAiC,CAAM,GACvD,0BAA0B;IAW7B;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACH,MAAM,CAAC,SAAS,CACd,OAAO,GAAE;QACP,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,YAAY,CAAC,EAAE,oBAAoB,CAAC;QACpC,SAAS,CAAC,EAAE,mBAAmB,CAAC;QAChC,KAAK,CAAC,EAAE,kBAAkB,CAAC;KACvB,GACL;QACD,YAAY,EAAE,aAAa,CAAC;QAC5B,KAAK,EAAE,aAAa,CAAC;QACrB,WAAW,EAAE,0BAA0B,CAAC;QACxC,6FAA6F;QAC7F,OAAO,EAAE,MAAM,IAAI,CAAC;KACrB;CA6BF"}
|
package/dist/factory.js
CHANGED
|
@@ -5,9 +5,11 @@
|
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
7
|
exports.DynamoDBFactory = void 0;
|
|
8
|
+
const client_dynamodb_1 = require("@aws-sdk/client-dynamodb");
|
|
9
|
+
const lib_dynamodb_1 = require("@aws-sdk/lib-dynamodb");
|
|
8
10
|
const checkpointer_1 = require("./checkpointer");
|
|
9
|
-
const store_1 = require("./store");
|
|
10
11
|
const history_1 = require("./history");
|
|
12
|
+
const store_1 = require("./store");
|
|
11
13
|
/**
|
|
12
14
|
* Default table names with standard prefix
|
|
13
15
|
*/
|
|
@@ -47,8 +49,12 @@ class DynamoDBFactory {
|
|
|
47
49
|
checkpointsTableName: options.checkpointsTableName ?? `${DEFAULT_TABLE_PREFIX}-checkpoints`,
|
|
48
50
|
writesTableName: options.writesTableName ?? `${DEFAULT_TABLE_PREFIX}-writes`,
|
|
49
51
|
ttlDays: options.ttlDays,
|
|
52
|
+
ttlSeconds: options.ttlSeconds,
|
|
53
|
+
compression: options.compression,
|
|
54
|
+
s3OffloadConfig: options.s3OffloadConfig,
|
|
50
55
|
serde: options.serde,
|
|
51
56
|
clientConfig: options.clientConfig,
|
|
57
|
+
client: options.client,
|
|
52
58
|
};
|
|
53
59
|
return new checkpointer_1.DynamoDBSaver(config);
|
|
54
60
|
}
|
|
@@ -86,6 +92,7 @@ class DynamoDBFactory {
|
|
|
86
92
|
embedding: options.embedding,
|
|
87
93
|
ttlDays: options.ttlDays,
|
|
88
94
|
clientConfig: options.clientConfig,
|
|
95
|
+
client: options.client,
|
|
89
96
|
};
|
|
90
97
|
return new store_1.DynamoDBStore(config);
|
|
91
98
|
}
|
|
@@ -117,6 +124,7 @@ class DynamoDBFactory {
|
|
|
117
124
|
tableName: options.tableName ?? `${DEFAULT_TABLE_PREFIX}-chat-history`,
|
|
118
125
|
ttlDays: options.ttlDays,
|
|
119
126
|
clientConfig: options.clientConfig,
|
|
127
|
+
client: options.client,
|
|
120
128
|
};
|
|
121
129
|
return new history_1.DynamoDBChatMessageHistory(config);
|
|
122
130
|
}
|
|
@@ -149,25 +157,29 @@ class DynamoDBFactory {
|
|
|
149
157
|
*/
|
|
150
158
|
static createAll(options = {}) {
|
|
151
159
|
const prefix = options.tablePrefix ?? DEFAULT_TABLE_PREFIX;
|
|
160
|
+
// Create a single shared DynamoDB client for all modules
|
|
161
|
+
const ddbClient = new client_dynamodb_1.DynamoDBClient(options.clientConfig || {});
|
|
162
|
+
const sharedClient = lib_dynamodb_1.DynamoDBDocument.from(ddbClient);
|
|
152
163
|
return {
|
|
153
164
|
checkpointer: this.createSaver({
|
|
154
165
|
checkpointsTableName: `${prefix}-checkpoints`,
|
|
155
166
|
writesTableName: `${prefix}-writes`,
|
|
156
167
|
ttlDays: options.ttlDays,
|
|
157
168
|
serde: options.serde,
|
|
158
|
-
|
|
169
|
+
client: sharedClient,
|
|
159
170
|
}),
|
|
160
171
|
store: this.createStore({
|
|
161
172
|
memoryTableName: `${prefix}-memory`,
|
|
162
173
|
embedding: options.embedding,
|
|
163
174
|
ttlDays: options.ttlDays,
|
|
164
|
-
|
|
175
|
+
client: sharedClient,
|
|
165
176
|
}),
|
|
166
177
|
chatHistory: this.createChatMessageHistory({
|
|
167
178
|
tableName: `${prefix}-chat-history`,
|
|
168
179
|
ttlDays: options.ttlDays,
|
|
169
|
-
|
|
180
|
+
client: sharedClient,
|
|
170
181
|
}),
|
|
182
|
+
destroy: () => ddbClient.destroy(),
|
|
171
183
|
};
|
|
172
184
|
}
|
|
173
185
|
}
|
package/dist/factory.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory.js","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;
|
|
1
|
+
{"version":3,"file":"factory.js","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Add a single message to a session
|
|
3
|
+
* Uses an atomic counter to claim a unique message index, preventing race conditions
|
|
3
4
|
*/
|
|
4
5
|
import type { AddMessageActionParams } from '../types';
|
|
5
6
|
/**
|
|
6
7
|
* Add a single message to a session
|
|
7
|
-
*
|
|
8
|
+
* Atomically claims a message index via DynamoDB's ADD operation, then writes the message item
|
|
8
9
|
*
|
|
9
10
|
* @param params - Parameters for the add message operation
|
|
10
11
|
* @throws Error if the operation fails or validation fails
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add-message.d.ts","sourceRoot":"","sources":["../../../src/history/actions/add-message.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"add-message.d.ts","sourceRoot":"","sources":["../../../src/history/actions/add-message.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAavD;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,GAAU,QAAQ,sBAAsB,KAAG,OAAO,CAAC,IAAI,CA4CnF,CAAC"}
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
3
|
* Add a single message to a session
|
|
4
|
+
* Uses an atomic counter to claim a unique message index, preventing race conditions
|
|
4
5
|
*/
|
|
5
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
7
|
exports.addMessageAction = void 0;
|
|
7
8
|
const utils_1 = require("../utils");
|
|
8
9
|
/**
|
|
9
10
|
* Add a single message to a session
|
|
10
|
-
*
|
|
11
|
+
* Atomically claims a message index via DynamoDB's ADD operation, then writes the message item
|
|
11
12
|
*
|
|
12
13
|
* @param params - Parameters for the add message operation
|
|
13
14
|
* @throws Error if the operation fails or validation fails
|
|
@@ -21,26 +22,29 @@ const addMessageAction = async (params) => {
|
|
|
21
22
|
(0, utils_1.validateTitle)(title);
|
|
22
23
|
(0, utils_1.validateTTLDays)(ttlDays);
|
|
23
24
|
// Generate a title if this is the first message and no title provided
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
messages: message,
|
|
31
|
-
title: sessionTitle,
|
|
32
|
-
ttlDays,
|
|
33
|
-
});
|
|
34
|
-
// Execute with retry logic
|
|
35
|
-
await (0, utils_1.withDynamoDBRetry)(async () => {
|
|
36
|
-
await client.update({
|
|
25
|
+
const sessionTitle = title ?? (0, utils_1.generateTitle)(message);
|
|
26
|
+
// Atomically claim a message index via ADD messageCount
|
|
27
|
+
const { updateExpression, expressionAttributeValues } = (0, utils_1.buildAtomicMetadataUpdate)(sessionTitle, 1, // Claiming 1 index
|
|
28
|
+
ttlDays);
|
|
29
|
+
const updateResult = await (0, utils_1.withDynamoDBRetry)(async () => {
|
|
30
|
+
return await client.update({
|
|
37
31
|
TableName: tableName,
|
|
38
|
-
Key: {
|
|
39
|
-
userId,
|
|
40
|
-
sessionId,
|
|
41
|
-
},
|
|
32
|
+
Key: { userId, sessionId },
|
|
42
33
|
UpdateExpression: updateExpression,
|
|
43
34
|
ExpressionAttributeValues: expressionAttributeValues,
|
|
35
|
+
ReturnValues: 'ALL_NEW',
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
// The new messageCount is the count AFTER incrementing by 1
|
|
39
|
+
// So our claimed index is newCount - 1
|
|
40
|
+
const newCount = updateResult.Attributes?.messageCount ?? 1;
|
|
41
|
+
const startIndex = newCount - 1;
|
|
42
|
+
// Build and write the message item
|
|
43
|
+
const [messageItem] = (0, utils_1.buildMessageItems)(userId, sessionId, [message], startIndex, ttlDays);
|
|
44
|
+
await (0, utils_1.withDynamoDBRetry)(async () => {
|
|
45
|
+
await client.put({
|
|
46
|
+
TableName: tableName,
|
|
47
|
+
Item: messageItem,
|
|
44
48
|
});
|
|
45
49
|
});
|
|
46
50
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add-message.js","sourceRoot":"","sources":["../../../src/history/actions/add-message.ts"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"add-message.js","sourceRoot":"","sources":["../../../src/history/actions/add-message.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAGH,oCAUkB;AAElB;;;;;;GAMG;AACI,MAAM,gBAAgB,GAAG,KAAK,EAAE,MAA8B,EAAiB,EAAE;IACtF,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;IAEjF,kBAAkB;IAClB,IAAA,sBAAc,EAAC,MAAM,CAAC,CAAC;IACvB,IAAA,yBAAiB,EAAC,SAAS,CAAC,CAAC;IAC7B,IAAA,uBAAe,EAAC,OAAO,CAAC,CAAC;IACzB,IAAA,qBAAa,EAAC,KAAK,CAAC,CAAC;IACrB,IAAA,uBAAe,EAAC,OAAO,CAAC,CAAC;IAEzB,sEAAsE;IACtE,MAAM,YAAY,GAAG,KAAK,IAAI,IAAA,qBAAa,EAAC,OAAO,CAAC,CAAC;IAErD,wDAAwD;IACxD,MAAM,EAAE,gBAAgB,EAAE,yBAAyB,EAAE,GAAG,IAAA,iCAAyB,EAC/E,YAAY,EACZ,CAAC,EAAE,mBAAmB;IACtB,OAAO,CACR,CAAC;IAEF,MAAM,YAAY,GAAG,MAAM,IAAA,yBAAiB,EAAC,KAAK,IAAI,EAAE;QACtD,OAAO,MAAM,MAAM,CAAC,MAAM,CAAC;YACzB,SAAS,EAAE,SAAS;YACpB,GAAG,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE;YAC1B,gBAAgB,EAAE,gBAAgB;YAClC,yBAAyB,EAAE,yBAAyB;YACpD,YAAY,EAAE,SAAS;SACxB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,4DAA4D;IAC5D,uCAAuC;IACvC,MAAM,QAAQ,GAAI,YAAY,CAAC,UAAU,EAAE,YAAuB,IAAI,CAAC,CAAC;IACxE,MAAM,UAAU,GAAG,QAAQ,GAAG,CAAC,CAAC;IAEhC,mCAAmC;IACnC,MAAM,CAAC,WAAW,CAAC,GAAG,IAAA,yBAAiB,EAAC,MAAM,EAAE,SAAS,EAAE,CAAC,OAAO,CAAC,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;IAE3F,MAAM,IAAA,yBAAiB,EAAC,KAAK,IAAI,EAAE;QACjC,MAAM,MAAM,CAAC,GAAG,CAAC;YACf,SAAS,EAAE,SAAS;YACpB,IAAI,EAAE,WAAW;SAClB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AA5CW,QAAA,gBAAgB,oBA4C3B"}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Add multiple messages to a session
|
|
3
|
+
* Uses an atomic counter to claim a unique message index range, preventing race conditions
|
|
4
|
+
* Uses transactWrite for message items (≤100, enforced by validation)
|
|
3
5
|
*/
|
|
4
6
|
import type { AddMessagesActionParams } from '../types';
|
|
5
7
|
/**
|
|
6
8
|
* Add multiple messages to a session
|
|
7
|
-
*
|
|
8
|
-
* Preferred over calling addMessage multiple times
|
|
9
|
+
* Atomically claims message indices via DynamoDB's ADD operation, then writes message items
|
|
9
10
|
*
|
|
10
11
|
* @param params - Parameters for the add messages operation
|
|
11
12
|
* @throws Error if the operation fails or validation fails
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add-messages.d.ts","sourceRoot":"","sources":["../../../src/history/actions/add-messages.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"add-messages.d.ts","sourceRoot":"","sources":["../../../src/history/actions/add-messages.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AAcxD;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,GAAU,QAAQ,uBAAuB,KAAG,OAAO,CAAC,IAAI,CAkDrF,CAAC"}
|
|
@@ -1,47 +1,57 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
3
|
* Add multiple messages to a session
|
|
4
|
+
* Uses an atomic counter to claim a unique message index range, preventing race conditions
|
|
5
|
+
* Uses transactWrite for message items (≤100, enforced by validation)
|
|
4
6
|
*/
|
|
5
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
8
|
exports.addMessagesAction = void 0;
|
|
7
9
|
const utils_1 = require("../utils");
|
|
8
10
|
/**
|
|
9
11
|
* Add multiple messages to a session
|
|
10
|
-
*
|
|
11
|
-
* Preferred over calling addMessage multiple times
|
|
12
|
+
* Atomically claims message indices via DynamoDB's ADD operation, then writes message items
|
|
12
13
|
*
|
|
13
14
|
* @param params - Parameters for the add messages operation
|
|
14
15
|
* @throws Error if the operation fails or validation fails
|
|
15
16
|
*/
|
|
16
17
|
const addMessagesAction = async (params) => {
|
|
17
18
|
const { client, tableName, userId, sessionId, messages, title, ttlDays } = params;
|
|
18
|
-
// Validate inputs
|
|
19
|
+
// Validate inputs (enforces max 100 messages per batch)
|
|
19
20
|
(0, utils_1.validateUserId)(userId);
|
|
20
21
|
(0, utils_1.validateSessionId)(sessionId);
|
|
21
22
|
(0, utils_1.validateMessages)(messages);
|
|
23
|
+
(0, utils_1.validateMessagesSize)(messages);
|
|
22
24
|
(0, utils_1.validateTitle)(title);
|
|
23
25
|
(0, utils_1.validateTTLDays)(ttlDays);
|
|
24
26
|
// Generate a title if this is the first message batch and no title provided
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
messages,
|
|
32
|
-
title: sessionTitle,
|
|
33
|
-
ttlDays,
|
|
34
|
-
});
|
|
35
|
-
// Execute with retry logic
|
|
36
|
-
await (0, utils_1.withDynamoDBRetry)(async () => {
|
|
37
|
-
await client.update({
|
|
27
|
+
const sessionTitle = title ?? (0, utils_1.generateTitle)(messages[0]);
|
|
28
|
+
// Atomically claim a range of message indices via ADD messageCount
|
|
29
|
+
const { updateExpression, expressionAttributeValues } = (0, utils_1.buildAtomicMetadataUpdate)(sessionTitle, messages.length, // Claiming N indices
|
|
30
|
+
ttlDays);
|
|
31
|
+
const updateResult = await (0, utils_1.withDynamoDBRetry)(async () => {
|
|
32
|
+
return await client.update({
|
|
38
33
|
TableName: tableName,
|
|
39
|
-
Key: {
|
|
40
|
-
userId,
|
|
41
|
-
sessionId,
|
|
42
|
-
},
|
|
34
|
+
Key: { userId, sessionId },
|
|
43
35
|
UpdateExpression: updateExpression,
|
|
44
36
|
ExpressionAttributeValues: expressionAttributeValues,
|
|
37
|
+
ReturnValues: 'ALL_NEW',
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
// The new messageCount is the count AFTER incrementing by messages.length
|
|
41
|
+
// So our claimed starting index is newCount - messages.length
|
|
42
|
+
const newCount = updateResult.Attributes?.messageCount ?? messages.length;
|
|
43
|
+
const startIndex = newCount - messages.length;
|
|
44
|
+
// Build all message items
|
|
45
|
+
const messageItems = (0, utils_1.buildMessageItems)(userId, sessionId, messages, startIndex, ttlDays);
|
|
46
|
+
// Write all message items in a single transaction (max 100 items, enforced by validation)
|
|
47
|
+
await (0, utils_1.withDynamoDBRetry)(async () => {
|
|
48
|
+
await client.transactWrite({
|
|
49
|
+
TransactItems: messageItems.map((item) => ({
|
|
50
|
+
Put: {
|
|
51
|
+
TableName: tableName,
|
|
52
|
+
Item: item,
|
|
53
|
+
},
|
|
54
|
+
})),
|
|
45
55
|
});
|
|
46
56
|
});
|
|
47
57
|
};
|