@farukada/aws-langgraph-dynamodb-ts 0.0.2
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/LICENSE +21 -0
- package/README.md +960 -0
- package/dist/checkpointer/actions/delete-thread.d.ts +9 -0
- package/dist/checkpointer/actions/delete-thread.d.ts.map +1 -0
- package/dist/checkpointer/actions/delete-thread.js +109 -0
- package/dist/checkpointer/actions/delete-thread.js.map +1 -0
- package/dist/checkpointer/actions/get-tuple.d.ts +11 -0
- package/dist/checkpointer/actions/get-tuple.d.ts.map +1 -0
- package/dist/checkpointer/actions/get-tuple.js +96 -0
- package/dist/checkpointer/actions/get-tuple.js.map +1 -0
- package/dist/checkpointer/actions/index.d.ts +5 -0
- package/dist/checkpointer/actions/index.d.ts.map +1 -0
- package/dist/checkpointer/actions/index.js +21 -0
- package/dist/checkpointer/actions/index.js.map +1 -0
- package/dist/checkpointer/actions/put-writes.d.ts +9 -0
- package/dist/checkpointer/actions/put-writes.d.ts.map +1 -0
- package/dist/checkpointer/actions/put-writes.js +63 -0
- package/dist/checkpointer/actions/put-writes.js.map +1 -0
- package/dist/checkpointer/actions/put.d.ts +11 -0
- package/dist/checkpointer/actions/put.d.ts.map +1 -0
- package/dist/checkpointer/actions/put.js +55 -0
- package/dist/checkpointer/actions/put.js.map +1 -0
- package/dist/checkpointer/actions/validate-configurable.d.ts +10 -0
- package/dist/checkpointer/actions/validate-configurable.d.ts.map +1 -0
- package/dist/checkpointer/actions/validate-configurable.js +39 -0
- package/dist/checkpointer/actions/validate-configurable.js.map +1 -0
- package/dist/checkpointer/actions/writer.d.ts +50 -0
- package/dist/checkpointer/actions/writer.d.ts.map +1 -0
- package/dist/checkpointer/actions/writer.js +109 -0
- package/dist/checkpointer/actions/writer.js.map +1 -0
- package/dist/checkpointer/index.d.ts +70 -0
- package/dist/checkpointer/index.d.ts.map +1 -0
- package/dist/checkpointer/index.js +172 -0
- package/dist/checkpointer/index.js.map +1 -0
- package/dist/checkpointer/types/index.d.ts +162 -0
- package/dist/checkpointer/types/index.d.ts.map +1 -0
- package/dist/checkpointer/types/index.js +3 -0
- package/dist/checkpointer/types/index.js.map +1 -0
- package/dist/checkpointer/utils/index.d.ts +6 -0
- package/dist/checkpointer/utils/index.d.ts.map +1 -0
- package/dist/checkpointer/utils/index.js +26 -0
- package/dist/checkpointer/utils/index.js.map +1 -0
- package/dist/checkpointer/utils/validation.d.ts +48 -0
- package/dist/checkpointer/utils/validation.d.ts.map +1 -0
- package/dist/checkpointer/utils/validation.js +190 -0
- package/dist/checkpointer/utils/validation.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/shared/index.d.ts +5 -0
- package/dist/shared/index.d.ts.map +1 -0
- package/dist/shared/index.js +21 -0
- package/dist/shared/index.js.map +1 -0
- package/dist/shared/utils/constants.d.ts +11 -0
- package/dist/shared/utils/constants.d.ts.map +1 -0
- package/dist/shared/utils/constants.js +35 -0
- package/dist/shared/utils/constants.js.map +1 -0
- package/dist/shared/utils/index.d.ts +6 -0
- package/dist/shared/utils/index.d.ts.map +1 -0
- package/dist/shared/utils/index.js +22 -0
- package/dist/shared/utils/index.js.map +1 -0
- package/dist/shared/utils/retry.d.ts +19 -0
- package/dist/shared/utils/retry.d.ts.map +1 -0
- package/dist/shared/utils/retry.js +102 -0
- package/dist/shared/utils/retry.js.map +1 -0
- package/dist/store/actions/get-operation.d.ts +11 -0
- package/dist/store/actions/get-operation.d.ts.map +1 -0
- package/dist/store/actions/get-operation.js +42 -0
- package/dist/store/actions/get-operation.js.map +1 -0
- package/dist/store/actions/index.d.ts +5 -0
- package/dist/store/actions/index.d.ts.map +1 -0
- package/dist/store/actions/index.js +21 -0
- package/dist/store/actions/index.js.map +1 -0
- package/dist/store/actions/list-namespaces-operation.d.ts +10 -0
- package/dist/store/actions/list-namespaces-operation.d.ts.map +1 -0
- package/dist/store/actions/list-namespaces-operation.js +212 -0
- package/dist/store/actions/list-namespaces-operation.js.map +1 -0
- package/dist/store/actions/put-operation.d.ts +9 -0
- package/dist/store/actions/put-operation.d.ts.map +1 -0
- package/dist/store/actions/put-operation.js +94 -0
- package/dist/store/actions/put-operation.js.map +1 -0
- package/dist/store/actions/search-operation.d.ts +11 -0
- package/dist/store/actions/search-operation.d.ts.map +1 -0
- package/dist/store/actions/search-operation.js +150 -0
- package/dist/store/actions/search-operation.js.map +1 -0
- package/dist/store/index.d.ts +73 -0
- package/dist/store/index.d.ts.map +1 -0
- package/dist/store/index.js +145 -0
- package/dist/store/index.js.map +1 -0
- package/dist/store/types/index.d.ts +97 -0
- package/dist/store/types/index.d.ts.map +1 -0
- package/dist/store/types/index.js +3 -0
- package/dist/store/types/index.js.map +1 -0
- package/dist/store/utils/filter.d.ts +16 -0
- package/dist/store/utils/filter.d.ts.map +1 -0
- package/dist/store/utils/filter.js +71 -0
- package/dist/store/utils/filter.js.map +1 -0
- package/dist/store/utils/index.d.ts +8 -0
- package/dist/store/utils/index.d.ts.map +1 -0
- package/dist/store/utils/index.js +28 -0
- package/dist/store/utils/index.js.map +1 -0
- package/dist/store/utils/result.d.ts +42 -0
- package/dist/store/utils/result.d.ts.map +1 -0
- package/dist/store/utils/result.js +51 -0
- package/dist/store/utils/result.js.map +1 -0
- package/dist/store/utils/validation.d.ts +57 -0
- package/dist/store/utils/validation.d.ts.map +1 -0
- package/dist/store/utils/validation.js +243 -0
- package/dist/store/utils/validation.js.map +1 -0
- package/package.json +85 -0
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.listNamespacesOperationAction = void 0;
|
|
4
|
+
const utils_1 = require("../utils");
|
|
5
|
+
/**
|
|
6
|
+
* List unique namespaces from DynamoDB with filtering and pagination
|
|
7
|
+
*
|
|
8
|
+
* @param params - Parameters for the list namespaces operation
|
|
9
|
+
* @returns Array of namespace paths (each path is an array of strings including userId)
|
|
10
|
+
* @throws Error if the operation fails or validation fails
|
|
11
|
+
*/
|
|
12
|
+
const listNamespacesOperationAction = async (params) => {
|
|
13
|
+
const { client, memoryTableName, userId, op } = params;
|
|
14
|
+
const limit = op.limit;
|
|
15
|
+
const offset = op.offset;
|
|
16
|
+
const matchConditions = op.matchConditions ?? [];
|
|
17
|
+
const maxDepth = op.maxDepth;
|
|
18
|
+
// Validate inputs
|
|
19
|
+
(0, utils_1.validateUserId)(userId);
|
|
20
|
+
(0, utils_1.validatePagination)(limit, offset);
|
|
21
|
+
(0, utils_1.validateMaxDepth)(maxDepth);
|
|
22
|
+
// Determine if we can optimize with KeyConditionExpression
|
|
23
|
+
const prefixCondition = matchConditions.find((c) => c.matchType === 'prefix');
|
|
24
|
+
const namespacePrefix = prefixCondition ? extractConcretePrefix(prefixCondition.path) : '';
|
|
25
|
+
// Build query parameters
|
|
26
|
+
const queryParams = {
|
|
27
|
+
TableName: memoryTableName,
|
|
28
|
+
KeyConditionExpression: 'user_id = :uid',
|
|
29
|
+
ExpressionAttributeValues: {
|
|
30
|
+
':uid': userId,
|
|
31
|
+
},
|
|
32
|
+
ExpressionAttributeNames: {},
|
|
33
|
+
ProjectionExpression: 'namespace',
|
|
34
|
+
};
|
|
35
|
+
// Optimize a query with begins_with for prefix conditions
|
|
36
|
+
if (namespacePrefix) {
|
|
37
|
+
queryParams.KeyConditionExpression += ' AND begins_with(namespace_key, :nsPrefix)';
|
|
38
|
+
queryParams.ExpressionAttributeValues[':nsPrefix'] = `${namespacePrefix}#`;
|
|
39
|
+
}
|
|
40
|
+
// Build FilterExpression for suffix conditions using contains()
|
|
41
|
+
const filterExpressions = [];
|
|
42
|
+
const suffixConditions = matchConditions.filter((c) => c.matchType === 'suffix');
|
|
43
|
+
suffixConditions.forEach((condition, index) => {
|
|
44
|
+
const concreteSuffix = extractConcreteSuffix(condition.path);
|
|
45
|
+
if (concreteSuffix) {
|
|
46
|
+
const attrName = `#ns${index}`;
|
|
47
|
+
const valueName = `:suffix${index}`;
|
|
48
|
+
queryParams.ExpressionAttributeNames[attrName] = 'namespace';
|
|
49
|
+
queryParams.ExpressionAttributeValues[valueName] = concreteSuffix;
|
|
50
|
+
filterExpressions.push(`contains(${attrName}, ${valueName})`);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
if (filterExpressions.length > 0) {
|
|
54
|
+
queryParams.FilterExpression = filterExpressions.join(' AND ');
|
|
55
|
+
}
|
|
56
|
+
// Use a Set to track unique namespaces
|
|
57
|
+
const namespaceSet = new Set();
|
|
58
|
+
let lastEvaluatedKey;
|
|
59
|
+
let iterationCount = 0;
|
|
60
|
+
// Fetch all matching items with retry logic and safety limits
|
|
61
|
+
const CANDIDATE_MULTIPLIER = 10; // Fetch 10x more candidates to account for filtering
|
|
62
|
+
// Cap the target size to prevent excessive memory usage
|
|
63
|
+
const targetSize = Math.min((limit + offset) * CANDIDATE_MULTIPLIER, utils_1.ValidationConstants.MAX_TOTAL_ITEMS_IN_MEMORY);
|
|
64
|
+
do {
|
|
65
|
+
// Prevent infinite loops
|
|
66
|
+
iterationCount++;
|
|
67
|
+
if (iterationCount > utils_1.ValidationConstants.MAX_LOOP_ITERATIONS) {
|
|
68
|
+
throw new Error('List namespaces operation exceeded maximum iteration limit');
|
|
69
|
+
}
|
|
70
|
+
if (lastEvaluatedKey) {
|
|
71
|
+
queryParams.ExclusiveStartKey = lastEvaluatedKey;
|
|
72
|
+
}
|
|
73
|
+
const response = await (0, utils_1.withDynamoDBRetry)(async () => {
|
|
74
|
+
return await client.query(queryParams);
|
|
75
|
+
});
|
|
76
|
+
// Extract and deduplicate namespaces
|
|
77
|
+
response.Items?.forEach((item) => {
|
|
78
|
+
if (item.namespace !== undefined && item.namespace !== null) {
|
|
79
|
+
// Prevent memory exhaustion
|
|
80
|
+
if (namespaceSet.size >= utils_1.ValidationConstants.MAX_TOTAL_ITEMS_IN_MEMORY) {
|
|
81
|
+
return; // Stop adding more items
|
|
82
|
+
}
|
|
83
|
+
namespaceSet.add(item.namespace);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
lastEvaluatedKey = response.LastEvaluatedKey;
|
|
87
|
+
// Stop after collecting enough candidates
|
|
88
|
+
if (namespaceSet.size >= targetSize) {
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
} while (lastEvaluatedKey);
|
|
92
|
+
// Convert Set to an array of namespace arrays (include userId)
|
|
93
|
+
const allNamespaces = Array.from(namespaceSet).map((ns) => {
|
|
94
|
+
const parts = ns ? ns.split('/') : [];
|
|
95
|
+
return [userId, ...parts];
|
|
96
|
+
});
|
|
97
|
+
// Apply all match conditions
|
|
98
|
+
const filteredNamespaces = allNamespaces.filter((namespacePath) => {
|
|
99
|
+
// Check all match conditions (must match ALL)
|
|
100
|
+
for (const condition of matchConditions) {
|
|
101
|
+
// Always check the condition, regardless of wildcards
|
|
102
|
+
// DynamoDB filtering is just an optimization, we verify all conditions here
|
|
103
|
+
if (!matchesCondition(namespacePath, condition)) {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
// Check maxDepth if specified
|
|
108
|
+
if (maxDepth !== undefined) {
|
|
109
|
+
// Depth is measured from userId (first element)
|
|
110
|
+
const depth = namespacePath.length;
|
|
111
|
+
if (depth > maxDepth) {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return true;
|
|
116
|
+
});
|
|
117
|
+
// Sort namespaces for consistent ordering
|
|
118
|
+
filteredNamespaces.sort((a, b) => a.join('/').localeCompare(b.join('/')));
|
|
119
|
+
// Apply offset and limit
|
|
120
|
+
return filteredNamespaces.slice(offset, offset + limit);
|
|
121
|
+
};
|
|
122
|
+
exports.listNamespacesOperationAction = listNamespacesOperationAction;
|
|
123
|
+
/**
|
|
124
|
+
* Extract a concrete prefix (before any wildcards) from a path for DynamoDB optimization
|
|
125
|
+
*/
|
|
126
|
+
function extractConcretePrefix(path) {
|
|
127
|
+
const concreteParts = [];
|
|
128
|
+
for (let i = 0; i < path.length; i++) {
|
|
129
|
+
if (path[i] === '*') {
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
concreteParts.push(path[i]);
|
|
133
|
+
}
|
|
134
|
+
return concreteParts.join('/');
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Extract concrete suffix (after any wildcards) from a path for DynamoDB contains()
|
|
138
|
+
* Returns the suffix pattern for contains() matching
|
|
139
|
+
*/
|
|
140
|
+
function extractConcreteSuffix(path) {
|
|
141
|
+
const concreteParts = [];
|
|
142
|
+
// Collect concrete parts from the end, working backwards until we hit a wildcard
|
|
143
|
+
for (let i = path.length - 1; i >= 0; i--) {
|
|
144
|
+
if (path[i] === '*') {
|
|
145
|
+
break;
|
|
146
|
+
}
|
|
147
|
+
concreteParts.unshift(path[i]);
|
|
148
|
+
}
|
|
149
|
+
// Return as a path string (e.g., "reports/2024")
|
|
150
|
+
return concreteParts.join('/');
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Check if a namespace matches a single condition
|
|
154
|
+
*/
|
|
155
|
+
function matchesCondition(namespacePath, condition) {
|
|
156
|
+
const { matchType, path } = condition;
|
|
157
|
+
if (matchType === 'prefix') {
|
|
158
|
+
return matchesPrefix(namespacePath, path);
|
|
159
|
+
}
|
|
160
|
+
else if (matchType === 'suffix') {
|
|
161
|
+
return matchesSuffix(namespacePath, path);
|
|
162
|
+
}
|
|
163
|
+
return false;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Check if a namespace matches a prefix pattern (supports wildcards)
|
|
167
|
+
*/
|
|
168
|
+
function matchesPrefix(namespacePath, pattern) {
|
|
169
|
+
// Pattern must not be longer than the namespace
|
|
170
|
+
if (pattern.length > namespacePath.length) {
|
|
171
|
+
return false;
|
|
172
|
+
}
|
|
173
|
+
// Check each position in the pattern
|
|
174
|
+
for (let i = 0; i < pattern.length; i++) {
|
|
175
|
+
const patternPart = pattern[i];
|
|
176
|
+
const namespacePart = namespacePath[i];
|
|
177
|
+
// Wildcard matches anything
|
|
178
|
+
if (patternPart === '*') {
|
|
179
|
+
continue;
|
|
180
|
+
}
|
|
181
|
+
// Concrete value must match exactly
|
|
182
|
+
if (patternPart !== namespacePart) {
|
|
183
|
+
return false;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return true;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Check if a namespace matches a suffix pattern (supports wildcards)
|
|
190
|
+
*/
|
|
191
|
+
function matchesSuffix(namespacePath, pattern) {
|
|
192
|
+
// Pattern must not be longer than the namespace
|
|
193
|
+
if (pattern.length > namespacePath.length) {
|
|
194
|
+
return false;
|
|
195
|
+
}
|
|
196
|
+
// Check from the end
|
|
197
|
+
const offset = namespacePath.length - pattern.length;
|
|
198
|
+
for (let i = 0; i < pattern.length; i++) {
|
|
199
|
+
const patternPart = pattern[i];
|
|
200
|
+
const namespacePart = namespacePath[offset + i];
|
|
201
|
+
// Wildcard matches anything
|
|
202
|
+
if (patternPart === '*') {
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
205
|
+
// Concrete value must match exactly
|
|
206
|
+
if (patternPart !== namespacePart) {
|
|
207
|
+
return false;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return true;
|
|
211
|
+
}
|
|
212
|
+
//# sourceMappingURL=list-namespaces-operation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-namespaces-operation.js","sourceRoot":"","sources":["../../../src/store/actions/list-namespaces-operation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { PutOperationActionParams } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Put a memory item into DynamoDB
|
|
4
|
+
*
|
|
5
|
+
* @param params - Parameters for the put operation
|
|
6
|
+
* @throws Error if the operation fails or validation fails
|
|
7
|
+
*/
|
|
8
|
+
export declare const putOperationAction: (params: PutOperationActionParams) => Promise<void>;
|
|
9
|
+
//# sourceMappingURL=put-operation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"put-operation.d.ts","sourceRoot":"","sources":["../../../src/store/actions/put-operation.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,wBAAwB,EAAE,MAAM,UAAU,CAAC;AAYpD;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAAU,QAAQ,wBAAwB,KAAG,OAAO,CAAC,IAAI,CAqFvF,CAAC"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.putOperationAction = void 0;
|
|
7
|
+
const jsonpath_1 = __importDefault(require("jsonpath"));
|
|
8
|
+
const utils_1 = require("../utils");
|
|
9
|
+
/**
|
|
10
|
+
* Put a memory item into DynamoDB
|
|
11
|
+
*
|
|
12
|
+
* @param params - Parameters for the put operation
|
|
13
|
+
* @throws Error if the operation fails or validation fails
|
|
14
|
+
*/
|
|
15
|
+
const putOperationAction = async (params) => {
|
|
16
|
+
const { client, embedding, memoryTableName, userId, op, ttlDays } = params;
|
|
17
|
+
// Validate inputs
|
|
18
|
+
(0, utils_1.validateUserId)(userId);
|
|
19
|
+
(0, utils_1.validateNamespace)(op.namespace);
|
|
20
|
+
(0, utils_1.validateKey)(op.key);
|
|
21
|
+
(0, utils_1.validateValue)(op.value);
|
|
22
|
+
(0, utils_1.validateTTL)(ttlDays);
|
|
23
|
+
const namespacePath = op.namespace.join('/');
|
|
24
|
+
const namespace_key = `${namespacePath}#${op.key}`;
|
|
25
|
+
const now = Date.now();
|
|
26
|
+
// Generate embeddings if requested
|
|
27
|
+
let embeddings;
|
|
28
|
+
if (embedding && op.index && op.index.length > 0) {
|
|
29
|
+
// Validate JSONPath expressions before use
|
|
30
|
+
(0, utils_1.validateJSONPath)(op.index);
|
|
31
|
+
const textToEmbed = [];
|
|
32
|
+
for (const path of op.index) {
|
|
33
|
+
const value = jsonpath_1.default.query(op.value, path);
|
|
34
|
+
for (const v of value) {
|
|
35
|
+
if (typeof v === 'string') {
|
|
36
|
+
textToEmbed.push(v);
|
|
37
|
+
}
|
|
38
|
+
else if (typeof v === 'number' || typeof v === 'boolean') {
|
|
39
|
+
textToEmbed.push(v.toString());
|
|
40
|
+
}
|
|
41
|
+
else if (v !== null && v !== undefined) {
|
|
42
|
+
textToEmbed.push(JSON.stringify(v));
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
if (textToEmbed.length > 0) {
|
|
47
|
+
embeddings = await embedding.embedDocuments(textToEmbed);
|
|
48
|
+
(0, utils_1.validateEmbeddings)(embeddings);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// Build update expression
|
|
52
|
+
const updateExpressionParts = [
|
|
53
|
+
'namespace = :namespace',
|
|
54
|
+
'#key = :key',
|
|
55
|
+
'#value = :value',
|
|
56
|
+
'updatedAt = :updatedAt',
|
|
57
|
+
];
|
|
58
|
+
const expressionAttributeNames = {
|
|
59
|
+
'#key': 'key',
|
|
60
|
+
'#value': 'value',
|
|
61
|
+
};
|
|
62
|
+
const expressionAttributeValues = {
|
|
63
|
+
':namespace': namespacePath,
|
|
64
|
+
':key': op.key,
|
|
65
|
+
':value': op.value,
|
|
66
|
+
':updatedAt': now,
|
|
67
|
+
':createdAt': now,
|
|
68
|
+
};
|
|
69
|
+
// Add embedding if generated
|
|
70
|
+
if (embeddings) {
|
|
71
|
+
updateExpressionParts.push('embedding = :embedding');
|
|
72
|
+
expressionAttributeValues[':embedding'] = embeddings;
|
|
73
|
+
}
|
|
74
|
+
// Add TTL if configured
|
|
75
|
+
if (ttlDays && ttlDays > 0) {
|
|
76
|
+
updateExpressionParts.push('ttl = :ttl');
|
|
77
|
+
expressionAttributeValues[':ttl'] = Math.floor(Date.now() / 1000) + ttlDays * 24 * 60 * 60;
|
|
78
|
+
}
|
|
79
|
+
// Execute with retry logic
|
|
80
|
+
await (0, utils_1.withDynamoDBRetry)(async () => {
|
|
81
|
+
await client.update({
|
|
82
|
+
TableName: memoryTableName,
|
|
83
|
+
Key: {
|
|
84
|
+
user_id: userId,
|
|
85
|
+
namespace_key: namespace_key,
|
|
86
|
+
},
|
|
87
|
+
UpdateExpression: `SET ${updateExpressionParts.join(', ')}, createdAt = if_not_exists(createdAt, :createdAt)`,
|
|
88
|
+
ExpressionAttributeNames: expressionAttributeNames,
|
|
89
|
+
ExpressionAttributeValues: expressionAttributeValues,
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
};
|
|
93
|
+
exports.putOperationAction = putOperationAction;
|
|
94
|
+
//# sourceMappingURL=put-operation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"put-operation.js","sourceRoot":"","sources":["../../../src/store/actions/put-operation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { SearchItem } from '@langchain/langgraph-checkpoint';
|
|
2
|
+
import { SearchOperationActionParams } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* Search for memory items in DynamoDB
|
|
5
|
+
*
|
|
6
|
+
* @param params - Parameters for the search operation
|
|
7
|
+
* @returns Array of matching items with optional similarity scores
|
|
8
|
+
* @throws Error if the operation fails or validation fails
|
|
9
|
+
*/
|
|
10
|
+
export declare const searchOperationAction: (params: SearchOperationActionParams) => Promise<SearchItem[]>;
|
|
11
|
+
//# sourceMappingURL=search-operation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-operation.d.ts","sourceRoot":"","sources":["../../../src/store/actions/search-operation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EAAE,2BAA2B,EAAE,MAAM,UAAU,CAAC;AAYvD;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,GAChC,QAAQ,2BAA2B,KAClC,OAAO,CAAC,UAAU,EAAE,CAkHtB,CAAC"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.searchOperationAction = void 0;
|
|
4
|
+
const utils_1 = require("../utils");
|
|
5
|
+
/**
|
|
6
|
+
* Search for memory items in DynamoDB
|
|
7
|
+
*
|
|
8
|
+
* @param params - Parameters for the search operation
|
|
9
|
+
* @returns Array of matching items with optional similarity scores
|
|
10
|
+
* @throws Error if the operation fails or validation fails
|
|
11
|
+
*/
|
|
12
|
+
const searchOperationAction = async (params) => {
|
|
13
|
+
const { client, embedding, memoryTableName, userId, op } = params;
|
|
14
|
+
const limit = op.limit ?? 100;
|
|
15
|
+
const offset = op.offset ?? 0;
|
|
16
|
+
// Validate inputs
|
|
17
|
+
(0, utils_1.validateUserId)(userId);
|
|
18
|
+
// Allow empty namespace prefix to search all namespaces
|
|
19
|
+
if (op.namespacePrefix.length > 0) {
|
|
20
|
+
(0, utils_1.validateNamespace)(op.namespacePrefix);
|
|
21
|
+
}
|
|
22
|
+
(0, utils_1.validatePagination)(limit, offset);
|
|
23
|
+
const namespacePrefix = op.namespacePrefix.join('/');
|
|
24
|
+
const queryParams = {
|
|
25
|
+
TableName: memoryTableName,
|
|
26
|
+
};
|
|
27
|
+
// Build ExpressionAttributeValues and ExpressionAttributeNames
|
|
28
|
+
const expressionAttributeValues = {
|
|
29
|
+
':uid': userId,
|
|
30
|
+
};
|
|
31
|
+
const expressionAttributeNames = {};
|
|
32
|
+
// Build KeyConditionExpression
|
|
33
|
+
let keyConditionExpression = 'user_id = :uid';
|
|
34
|
+
if (namespacePrefix) {
|
|
35
|
+
// Use begins_with on namespace_key for hierarchical search
|
|
36
|
+
expressionAttributeValues[':nsp'] = `${namespacePrefix}#`;
|
|
37
|
+
keyConditionExpression += ' AND begins_with(namespace_key, :nsp)';
|
|
38
|
+
}
|
|
39
|
+
queryParams.KeyConditionExpression = keyConditionExpression;
|
|
40
|
+
queryParams.ExpressionAttributeValues = expressionAttributeValues;
|
|
41
|
+
// Build filter expression if provided
|
|
42
|
+
if (op.filter && Object.keys(op.filter).length > 0) {
|
|
43
|
+
const filterResult = (0, utils_1.buildFilterExpression)(op.filter, expressionAttributeNames, expressionAttributeValues);
|
|
44
|
+
if (filterResult.filterExpression) {
|
|
45
|
+
queryParams.FilterExpression = filterResult.filterExpression;
|
|
46
|
+
queryParams.ExpressionAttributeNames = expressionAttributeNames;
|
|
47
|
+
queryParams.ExpressionAttributeValues = expressionAttributeValues;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
const items = [];
|
|
51
|
+
let lastEvaluatedKey;
|
|
52
|
+
let scannedCount = 0;
|
|
53
|
+
let iterationCount = 0;
|
|
54
|
+
// Execute a query with retry logic and safety limits
|
|
55
|
+
do {
|
|
56
|
+
// Prevent infinite loops
|
|
57
|
+
iterationCount++;
|
|
58
|
+
if (iterationCount > utils_1.ValidationConstants.MAX_LOOP_ITERATIONS) {
|
|
59
|
+
throw new Error('Search operation exceeded maximum iteration limit');
|
|
60
|
+
}
|
|
61
|
+
queryParams.Limit = Math.max(1, limit + offset - scannedCount);
|
|
62
|
+
if (lastEvaluatedKey) {
|
|
63
|
+
queryParams.ExclusiveStartKey = lastEvaluatedKey;
|
|
64
|
+
}
|
|
65
|
+
const response = await (0, utils_1.withDynamoDBRetry)(async () => {
|
|
66
|
+
return await client.query(queryParams);
|
|
67
|
+
});
|
|
68
|
+
scannedCount += response.ScannedCount ?? 0;
|
|
69
|
+
if (response.Items && response.Items.length > 0) {
|
|
70
|
+
// Prevent memory exhaustion
|
|
71
|
+
if (items.length + response.Items.length > utils_1.ValidationConstants.MAX_TOTAL_ITEMS_IN_MEMORY) {
|
|
72
|
+
throw new Error('Search operation exceeded maximum items in memory limit');
|
|
73
|
+
}
|
|
74
|
+
items.push(...response.Items);
|
|
75
|
+
}
|
|
76
|
+
lastEvaluatedKey = response.LastEvaluatedKey;
|
|
77
|
+
if (!lastEvaluatedKey)
|
|
78
|
+
break;
|
|
79
|
+
if (items.length >= limit + offset)
|
|
80
|
+
break;
|
|
81
|
+
if (scannedCount >= limit + offset)
|
|
82
|
+
break;
|
|
83
|
+
} while (
|
|
84
|
+
// eslint-disable-next-line no-constant-condition
|
|
85
|
+
true);
|
|
86
|
+
if (items.length > 0) {
|
|
87
|
+
let paginatedItems = items.slice(offset, offset + limit);
|
|
88
|
+
if (op.query && embedding) {
|
|
89
|
+
paginatedItems = await applySemanticSearch(paginatedItems, op.query, embedding);
|
|
90
|
+
}
|
|
91
|
+
return paginatedItems.map((item) => ({
|
|
92
|
+
namespace: item.namespace.split('/'),
|
|
93
|
+
key: item.key,
|
|
94
|
+
value: item.value,
|
|
95
|
+
createdAt: item.createdAt,
|
|
96
|
+
updatedAt: item.updatedAt,
|
|
97
|
+
score: item.score,
|
|
98
|
+
}));
|
|
99
|
+
}
|
|
100
|
+
return [];
|
|
101
|
+
};
|
|
102
|
+
exports.searchOperationAction = searchOperationAction;
|
|
103
|
+
/**
|
|
104
|
+
* Apply semantic search using vector embeddings and cosine similarity
|
|
105
|
+
* Falls back to returning original items if embedding generation fails
|
|
106
|
+
*/
|
|
107
|
+
async function applySemanticSearch(items, query, embedding) {
|
|
108
|
+
try {
|
|
109
|
+
const queryEmbedding = await embedding.embedQuery(query);
|
|
110
|
+
const itemsWithScores = items
|
|
111
|
+
.map((item) => {
|
|
112
|
+
if (!item.embedding || !Array.isArray(item.embedding) || item.embedding.length === 0) {
|
|
113
|
+
// Items without embeddings get score 0
|
|
114
|
+
return { item: { ...item, score: 0 }, score: 0 };
|
|
115
|
+
}
|
|
116
|
+
// Calculate similarity for each embedding (multiple fields can be embedded)
|
|
117
|
+
// Take the maximum similarity across all embeddings
|
|
118
|
+
const similarities = item.embedding.map((emb) => cosineSimilarity(queryEmbedding, emb));
|
|
119
|
+
const maxSimilarity = Math.max(...similarities);
|
|
120
|
+
return {
|
|
121
|
+
item: { ...item, score: maxSimilarity },
|
|
122
|
+
score: maxSimilarity,
|
|
123
|
+
};
|
|
124
|
+
})
|
|
125
|
+
.filter((result) => result.score > 0); // Only include items with embeddings
|
|
126
|
+
// Sort by similarity score (highest first)
|
|
127
|
+
itemsWithScores.sort((a, b) => b.score - a.score);
|
|
128
|
+
return itemsWithScores.map((result) => result.item);
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
// Fall back to returning original items if semantic search fails
|
|
132
|
+
return items;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Calculate cosine similarity between two vectors
|
|
137
|
+
*/
|
|
138
|
+
function cosineSimilarity(vecA, vecB) {
|
|
139
|
+
if (!vecA || !vecB || vecA.length !== vecB.length || vecA.length === 0) {
|
|
140
|
+
return 0;
|
|
141
|
+
}
|
|
142
|
+
const dotProduct = vecA.reduce((sum, a, i) => sum + a * vecB[i], 0);
|
|
143
|
+
const magnitudeA = Math.sqrt(vecA.reduce((sum, a) => sum + a * a, 0));
|
|
144
|
+
const magnitudeB = Math.sqrt(vecB.reduce((sum, b) => sum + b * b, 0));
|
|
145
|
+
if (magnitudeA === 0 || magnitudeB === 0) {
|
|
146
|
+
return 0;
|
|
147
|
+
}
|
|
148
|
+
return dotProduct / (magnitudeA * magnitudeB);
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=search-operation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-operation.js","sourceRoot":"","sources":["../../../src/store/actions/search-operation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { BaseStore, type Operation, type OperationResults } from '@langchain/langgraph';
|
|
2
|
+
import type { RunnableConfig } from '@langchain/core/runnables';
|
|
3
|
+
import type { DynamoDBStoreOptions } from './types';
|
|
4
|
+
/**
|
|
5
|
+
* DynamoDB-based store implementation for LangGraph
|
|
6
|
+
* Provides persistent storage for memory items with optional semantic search via embeddings
|
|
7
|
+
*/
|
|
8
|
+
export declare class DynamoDBStore extends BaseStore {
|
|
9
|
+
private readonly ddbClient;
|
|
10
|
+
private readonly client;
|
|
11
|
+
private readonly memoryTableName;
|
|
12
|
+
private readonly embedding?;
|
|
13
|
+
private readonly ttlDays?;
|
|
14
|
+
/**
|
|
15
|
+
* Create a new DynamoDB store instance
|
|
16
|
+
*
|
|
17
|
+
* @param options - Configuration options for the store
|
|
18
|
+
* @param options.memoryTableName - Name of the DynamoDB table to use
|
|
19
|
+
* @param options.embedding - Optional Bedrock embeddings for semantic search
|
|
20
|
+
* @param options.clientConfig - Optional DynamoDB client configuration
|
|
21
|
+
* @param options.ttlDays - Optional TTL in days for stored items
|
|
22
|
+
*/
|
|
23
|
+
constructor(options: DynamoDBStoreOptions);
|
|
24
|
+
/**
|
|
25
|
+
* Extract and validate user ID from config
|
|
26
|
+
*
|
|
27
|
+
* @param config - Runnable configuration
|
|
28
|
+
* @returns User ID string
|
|
29
|
+
* @throws Error if user_id is not provided or invalid
|
|
30
|
+
*/
|
|
31
|
+
private getUserId;
|
|
32
|
+
/**
|
|
33
|
+
* Execute a batch of operations in parallel
|
|
34
|
+
*
|
|
35
|
+
* @param operations - Array of operations to execute
|
|
36
|
+
* @param config - Runnable configuration containing user_id
|
|
37
|
+
* @returns Array of results corresponding to each operation
|
|
38
|
+
* @throws Error if user_id is not provided in config or if any operation fails
|
|
39
|
+
*/
|
|
40
|
+
batch<Op extends Operation[]>(operations: Op, config?: RunnableConfig): Promise<OperationResults<Op>>;
|
|
41
|
+
/**
|
|
42
|
+
* Get a single item from the store
|
|
43
|
+
*
|
|
44
|
+
* @param userId - User ID for the item
|
|
45
|
+
* @param op - Get operation parameters
|
|
46
|
+
* @returns The item if found, null otherwise
|
|
47
|
+
*/
|
|
48
|
+
private getOperation;
|
|
49
|
+
/**
|
|
50
|
+
* Put an item into the store
|
|
51
|
+
*
|
|
52
|
+
* @param userId - User ID for the item
|
|
53
|
+
* @param op - Put operation parameters
|
|
54
|
+
*/
|
|
55
|
+
private putOperation;
|
|
56
|
+
/**
|
|
57
|
+
* Search for items in the store with optional semantic search
|
|
58
|
+
*
|
|
59
|
+
* @param userId - User ID for filtering items
|
|
60
|
+
* @param op - Search operation parameters
|
|
61
|
+
* @returns Array of matching items with optional similarity scores
|
|
62
|
+
*/
|
|
63
|
+
private searchOperation;
|
|
64
|
+
/**
|
|
65
|
+
* List unique namespaces in the store
|
|
66
|
+
*
|
|
67
|
+
* @param userId - User ID for filtering namespaces
|
|
68
|
+
* @param op - List namespaces operation parameters
|
|
69
|
+
* @returns Array of namespace paths
|
|
70
|
+
*/
|
|
71
|
+
private listNamespacesOperation;
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/store/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EAMT,KAAK,SAAS,EACd,KAAK,gBAAgB,EACtB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAEhE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAWpD;;;GAGG;AACH,qBAAa,aAAc,SAAQ,SAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAiB;IAC3C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmB;IAC1C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAoB;IAC/C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAS;IAElC;;;;;;;;OAQG;gBACS,OAAO,EAAE,oBAAoB;IASzC;;;;;;OAMG;IACH,OAAO,CAAC,SAAS;IAQjB;;;;;;;OAOG;IACG,KAAK,CAAC,EAAE,SAAS,SAAS,EAAE,EAChC,UAAU,EAAE,EAAE,EACd,MAAM,CAAC,EAAE,cAAc,GACtB,OAAO,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;IA4BhC;;;;;;OAMG;YACW,YAAY;IAS1B;;;;;OAKG;YACW,YAAY;IAW1B;;;;;;OAMG;YACW,eAAe;IAU7B;;;;;;OAMG;YACW,uBAAuB;CAWtC"}
|