@langchain/langgraph-checkpoint 0.1.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/_virtual/rolldown_runtime.cjs +25 -0
  3. package/dist/base.cjs +74 -88
  4. package/dist/base.cjs.map +1 -0
  5. package/dist/base.d.cts +95 -0
  6. package/dist/base.d.cts.map +1 -0
  7. package/dist/base.d.ts +79 -73
  8. package/dist/base.d.ts.map +1 -0
  9. package/dist/base.js +69 -80
  10. package/dist/base.js.map +1 -1
  11. package/dist/cache/base.cjs +17 -21
  12. package/dist/cache/base.cjs.map +1 -0
  13. package/dist/cache/base.d.cts +43 -0
  14. package/dist/cache/base.d.cts.map +1 -0
  15. package/dist/cache/base.d.ts +41 -36
  16. package/dist/cache/base.d.ts.map +1 -0
  17. package/dist/cache/base.js +16 -16
  18. package/dist/cache/base.js.map +1 -1
  19. package/dist/cache/index.cjs +2 -19
  20. package/dist/cache/index.js +4 -3
  21. package/dist/cache/memory.cjs +53 -58
  22. package/dist/cache/memory.cjs.map +1 -0
  23. package/dist/cache/memory.d.cts +19 -0
  24. package/dist/cache/memory.d.cts.map +1 -0
  25. package/dist/cache/memory.d.ts +18 -13
  26. package/dist/cache/memory.d.ts.map +1 -0
  27. package/dist/cache/memory.js +52 -53
  28. package/dist/cache/memory.js.map +1 -1
  29. package/dist/id.cjs +12 -16
  30. package/dist/id.cjs.map +1 -0
  31. package/dist/id.d.cts +10 -0
  32. package/dist/id.d.cts.map +1 -0
  33. package/dist/id.d.ts +10 -2
  34. package/dist/id.d.ts.map +1 -0
  35. package/dist/id.js +10 -12
  36. package/dist/id.js.map +1 -1
  37. package/dist/index.cjs +36 -27
  38. package/dist/index.d.cts +12 -0
  39. package/dist/index.d.ts +12 -8
  40. package/dist/index.js +12 -9
  41. package/dist/memory.cjs +194 -268
  42. package/dist/memory.cjs.map +1 -0
  43. package/dist/memory.d.cts +22 -0
  44. package/dist/memory.d.cts.map +1 -0
  45. package/dist/memory.d.ts +19 -12
  46. package/dist/memory.d.ts.map +1 -0
  47. package/dist/memory.js +193 -263
  48. package/dist/memory.js.map +1 -1
  49. package/dist/serde/base.d.cts +10 -0
  50. package/dist/serde/base.d.cts.map +1 -0
  51. package/dist/serde/base.d.ts +9 -3
  52. package/dist/serde/base.d.ts.map +1 -0
  53. package/dist/serde/jsonplus.cjs +92 -141
  54. package/dist/serde/jsonplus.cjs.map +1 -0
  55. package/dist/serde/jsonplus.js +90 -136
  56. package/dist/serde/jsonplus.js.map +1 -1
  57. package/dist/serde/types.cjs +15 -9
  58. package/dist/serde/types.cjs.map +1 -0
  59. package/dist/serde/types.d.cts +55 -0
  60. package/dist/serde/types.d.cts.map +1 -0
  61. package/dist/serde/types.d.ts +53 -47
  62. package/dist/serde/types.d.ts.map +1 -0
  63. package/dist/serde/types.js +9 -5
  64. package/dist/serde/types.js.map +1 -1
  65. package/dist/serde/utils/fast-safe-stringify/index.cjs +88 -208
  66. package/dist/serde/utils/fast-safe-stringify/index.cjs.map +1 -0
  67. package/dist/serde/utils/fast-safe-stringify/index.js +87 -205
  68. package/dist/serde/utils/fast-safe-stringify/index.js.map +1 -1
  69. package/dist/store/base.cjs +200 -209
  70. package/dist/store/base.cjs.map +1 -0
  71. package/dist/store/base.d.cts +392 -0
  72. package/dist/store/base.d.cts.map +1 -0
  73. package/dist/store/base.d.ts +336 -332
  74. package/dist/store/base.d.ts.map +1 -0
  75. package/dist/store/base.js +198 -204
  76. package/dist/store/base.js.map +1 -1
  77. package/dist/store/batch.cjs +116 -147
  78. package/dist/store/batch.cjs.map +1 -0
  79. package/dist/store/batch.d.cts +49 -0
  80. package/dist/store/batch.d.cts.map +1 -0
  81. package/dist/store/batch.d.ts +48 -40
  82. package/dist/store/batch.d.ts.map +1 -0
  83. package/dist/store/batch.js +116 -143
  84. package/dist/store/batch.js.map +1 -1
  85. package/dist/store/memory.cjs +262 -363
  86. package/dist/store/memory.cjs.map +1 -0
  87. package/dist/store/memory.d.cts +64 -0
  88. package/dist/store/memory.d.cts.map +1 -0
  89. package/dist/store/memory.d.ts +30 -24
  90. package/dist/store/memory.d.ts.map +1 -0
  91. package/dist/store/memory.js +261 -358
  92. package/dist/store/memory.js.map +1 -1
  93. package/dist/store/utils.cjs +141 -249
  94. package/dist/store/utils.cjs.map +1 -0
  95. package/dist/store/utils.js +140 -245
  96. package/dist/store/utils.js.map +1 -1
  97. package/dist/types.d.cts +35 -0
  98. package/dist/types.d.cts.map +1 -0
  99. package/dist/types.d.ts +29 -28
  100. package/dist/types.d.ts.map +1 -0
  101. package/package.json +16 -18
  102. package/dist/cache/index.d.ts +0 -2
  103. package/dist/cache/index.js.map +0 -1
  104. package/dist/index.js.map +0 -1
  105. package/dist/serde/base.cjs +0 -3
  106. package/dist/serde/base.js +0 -2
  107. package/dist/serde/base.js.map +0 -1
  108. package/dist/serde/jsonplus.d.ts +0 -7
  109. package/dist/serde/utils/fast-safe-stringify/index.d.ts +0 -1
  110. package/dist/store/index.cjs +0 -20
  111. package/dist/store/index.d.ts +0 -3
  112. package/dist/store/index.js +0 -4
  113. package/dist/store/index.js.map +0 -1
  114. package/dist/store/utils.d.ts +0 -26
  115. package/dist/types.cjs +0 -3
  116. package/dist/types.js +0 -2
  117. package/dist/types.js.map +0 -1
  118. package/index.cjs +0 -1
  119. package/index.d.cts +0 -1
  120. package/index.d.ts +0 -1
  121. package/index.js +0 -1
@@ -1,221 +1,212 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.BaseStore = exports.InvalidNamespaceError = void 0;
4
- exports.getTextAtPath = getTextAtPath;
5
- exports.tokenizePath = tokenizePath;
1
+
2
+ //#region src/store/base.ts
6
3
  /**
7
- * Error thrown when an invalid namespace is provided.
8
- */
9
- class InvalidNamespaceError extends Error {
10
- constructor(message) {
11
- super(message);
12
- this.name = "InvalidNamespaceError";
13
- }
14
- }
15
- exports.InvalidNamespaceError = InvalidNamespaceError;
4
+ * Error thrown when an invalid namespace is provided.
5
+ */
6
+ var InvalidNamespaceError = class extends Error {
7
+ constructor(message) {
8
+ super(message);
9
+ this.name = "InvalidNamespaceError";
10
+ }
11
+ };
16
12
  /**
17
- * Validates the provided namespace.
18
- * @param namespace The namespace to validate.
19
- * @throws {InvalidNamespaceError} If the namespace is invalid.
20
- */
13
+ * Validates the provided namespace.
14
+ * @param namespace The namespace to validate.
15
+ * @throws {InvalidNamespaceError} If the namespace is invalid.
16
+ */
21
17
  function validateNamespace(namespace) {
22
- if (namespace.length === 0) {
23
- throw new InvalidNamespaceError("Namespace cannot be empty.");
24
- }
25
- for (const label of namespace) {
26
- if (typeof label !== "string") {
27
- throw new InvalidNamespaceError(`Invalid namespace label '${label}' found in ${namespace}. Namespace labels ` +
28
- `must be strings, but got ${typeof label}.`);
29
- }
30
- if (label.includes(".")) {
31
- throw new InvalidNamespaceError(`Invalid namespace label '${label}' found in ${namespace}. Namespace labels cannot contain periods ('.').`);
32
- }
33
- if (label === "") {
34
- throw new InvalidNamespaceError(`Namespace labels cannot be empty strings. Got ${label} in ${namespace}`);
35
- }
36
- }
37
- if (namespace[0] === "langgraph") {
38
- throw new InvalidNamespaceError(`Root label for namespace cannot be "langgraph". Got: ${namespace}`);
39
- }
18
+ if (namespace.length === 0) throw new InvalidNamespaceError("Namespace cannot be empty.");
19
+ for (const label of namespace) {
20
+ if (typeof label !== "string") throw new InvalidNamespaceError(`Invalid namespace label '${label}' found in ${namespace}. Namespace labels must be strings, but got ${typeof label}.`);
21
+ if (label.includes(".")) throw new InvalidNamespaceError(`Invalid namespace label '${label}' found in ${namespace}. Namespace labels cannot contain periods ('.').`);
22
+ if (label === "") throw new InvalidNamespaceError(`Namespace labels cannot be empty strings. Got ${label} in ${namespace}`);
23
+ }
24
+ if (namespace[0] === "langgraph") throw new InvalidNamespaceError(`Root label for namespace cannot be "langgraph". Got: ${namespace}`);
40
25
  }
41
26
  /**
42
- * Utility function to get text at a specific JSON path
43
- */
27
+ * Utility function to get text at a specific JSON path
28
+ */
44
29
  function getTextAtPath(obj, path) {
45
- const parts = path.split(".");
46
- let current = obj;
47
- for (const part of parts) {
48
- if (part.includes("[")) {
49
- const [arrayName, indexStr] = part.split("[");
50
- const index = indexStr.replace("]", "");
51
- if (!current[arrayName])
52
- return [];
53
- if (index === "*") {
54
- const results = [];
55
- for (const item of current[arrayName]) {
56
- if (typeof item === "string")
57
- results.push(item);
58
- }
59
- return results;
60
- }
61
- const idx = parseInt(index, 10);
62
- if (Number.isNaN(idx))
63
- return [];
64
- current = current[arrayName][idx];
65
- }
66
- else {
67
- current = current[part];
68
- }
69
- if (current === undefined)
70
- return [];
71
- }
72
- return typeof current === "string" ? [current] : [];
30
+ const parts = path.split(".");
31
+ let current = obj;
32
+ for (const part of parts) {
33
+ if (part.includes("[")) {
34
+ const [arrayName, indexStr] = part.split("[");
35
+ const index = indexStr.replace("]", "");
36
+ if (!current[arrayName]) return [];
37
+ if (index === "*") {
38
+ const results = [];
39
+ for (const item of current[arrayName]) if (typeof item === "string") results.push(item);
40
+ return results;
41
+ }
42
+ const idx = parseInt(index, 10);
43
+ if (Number.isNaN(idx)) return [];
44
+ current = current[arrayName][idx];
45
+ } else current = current[part];
46
+ if (current === void 0) return [];
47
+ }
48
+ return typeof current === "string" ? [current] : [];
73
49
  }
74
50
  /**
75
- * Tokenizes a JSON path into parts
76
- */
51
+ * Tokenizes a JSON path into parts
52
+ */
77
53
  function tokenizePath(path) {
78
- return path.split(".");
54
+ return path.split(".");
79
55
  }
80
56
  /**
81
- * Abstract base class for persistent key-value stores.
82
- *
83
- * Stores enable persistence and memory that can be shared across threads,
84
- * scoped to user IDs, assistant IDs, or other arbitrary namespaces.
85
- *
86
- * Features:
87
- * - Hierarchical namespaces for organization
88
- * - Key-value storage with metadata
89
- * - Vector similarity search (if configured)
90
- * - Filtering and pagination
91
- */
92
- class BaseStore {
93
- /**
94
- * Retrieve a single item by its namespace and key.
95
- *
96
- * @param namespace Hierarchical path for the item
97
- * @param key Unique identifier within the namespace
98
- * @returns Promise resolving to the item or null if not found
99
- */
100
- async get(namespace, key) {
101
- return (await this.batch([{ namespace, key }]))[0];
102
- }
103
- /**
104
- * Search for items within a namespace prefix.
105
- * Supports both metadata filtering and vector similarity search.
106
- *
107
- * @param namespacePrefix Hierarchical path prefix to search within
108
- * @param options Search options for filtering and pagination
109
- * @returns Promise resolving to list of matching items with relevance scores
110
- *
111
- * @example
112
- * // Search with filters
113
- * await store.search(["documents"], {
114
- * filter: { type: "report", status: "active" },
115
- * limit: 5,
116
- * offset: 10
117
- * });
118
- *
119
- * // Vector similarity search
120
- * await store.search(["users", "content"], {
121
- * query: "technical documentation about APIs",
122
- * limit: 20
123
- * });
124
- */
125
- async search(namespacePrefix, options = {}) {
126
- const { filter, limit = 10, offset = 0, query } = options;
127
- return (await this.batch([
128
- {
129
- namespacePrefix,
130
- filter,
131
- limit,
132
- offset,
133
- query,
134
- },
135
- ]))[0];
136
- }
137
- /**
138
- * Store or update an item.
139
- *
140
- * @param namespace Hierarchical path for the item
141
- * @param key Unique identifier within the namespace
142
- * @param value Object containing the item's data
143
- * @param index Optional indexing configuration
144
- *
145
- * @example
146
- * // Simple storage
147
- * await store.put(["docs"], "report", { title: "Annual Report" });
148
- *
149
- * // With specific field indexing
150
- * await store.put(
151
- * ["docs"],
152
- * "report",
153
- * {
154
- * title: "Q4 Report",
155
- * chapters: [{ content: "..." }, { content: "..." }]
156
- * },
157
- * ["title", "chapters[*].content"]
158
- * );
159
- */
160
- async put(namespace, key, value, index) {
161
- validateNamespace(namespace);
162
- await this.batch([{ namespace, key, value, index }]);
163
- }
164
- /**
165
- * Delete an item from the store.
166
- *
167
- * @param namespace Hierarchical path for the item
168
- * @param key Unique identifier within the namespace
169
- */
170
- async delete(namespace, key) {
171
- await this.batch([{ namespace, key, value: null }]);
172
- }
173
- /**
174
- * List and filter namespaces in the store.
175
- * Used to explore data organization and navigate the namespace hierarchy.
176
- *
177
- * @param options Options for listing namespaces
178
- * @returns Promise resolving to list of namespace paths
179
- *
180
- * @example
181
- * // List all namespaces under "documents"
182
- * await store.listNamespaces({
183
- * prefix: ["documents"],
184
- * maxDepth: 2
185
- * });
186
- *
187
- * // List namespaces ending with "v1"
188
- * await store.listNamespaces({
189
- * suffix: ["v1"],
190
- * limit: 50
191
- * });
192
- */
193
- async listNamespaces(options = {}) {
194
- const { prefix, suffix, maxDepth, limit = 100, offset = 0 } = options;
195
- const matchConditions = [];
196
- if (prefix) {
197
- matchConditions.push({ matchType: "prefix", path: prefix });
198
- }
199
- if (suffix) {
200
- matchConditions.push({ matchType: "suffix", path: suffix });
201
- }
202
- return (await this.batch([
203
- {
204
- matchConditions: matchConditions.length ? matchConditions : undefined,
205
- maxDepth,
206
- limit,
207
- offset,
208
- },
209
- ]))[0];
210
- }
211
- /**
212
- * Start the store. Override if initialization is needed.
213
- */
214
- start() { }
215
- /**
216
- * Stop the store. Override if cleanup is needed.
217
- */
218
- stop() { }
219
- }
57
+ * Abstract base class for persistent key-value stores.
58
+ *
59
+ * Stores enable persistence and memory that can be shared across threads,
60
+ * scoped to user IDs, assistant IDs, or other arbitrary namespaces.
61
+ *
62
+ * Features:
63
+ * - Hierarchical namespaces for organization
64
+ * - Key-value storage with metadata
65
+ * - Vector similarity search (if configured)
66
+ * - Filtering and pagination
67
+ */
68
+ var BaseStore = class {
69
+ /**
70
+ * Retrieve a single item by its namespace and key.
71
+ *
72
+ * @param namespace Hierarchical path for the item
73
+ * @param key Unique identifier within the namespace
74
+ * @returns Promise resolving to the item or null if not found
75
+ */
76
+ async get(namespace, key) {
77
+ return (await this.batch([{
78
+ namespace,
79
+ key
80
+ }]))[0];
81
+ }
82
+ /**
83
+ * Search for items within a namespace prefix.
84
+ * Supports both metadata filtering and vector similarity search.
85
+ *
86
+ * @param namespacePrefix Hierarchical path prefix to search within
87
+ * @param options Search options for filtering and pagination
88
+ * @returns Promise resolving to list of matching items with relevance scores
89
+ *
90
+ * @example
91
+ * // Search with filters
92
+ * await store.search(["documents"], {
93
+ * filter: { type: "report", status: "active" },
94
+ * limit: 5,
95
+ * offset: 10
96
+ * });
97
+ *
98
+ * // Vector similarity search
99
+ * await store.search(["users", "content"], {
100
+ * query: "technical documentation about APIs",
101
+ * limit: 20
102
+ * });
103
+ */
104
+ async search(namespacePrefix, options = {}) {
105
+ const { filter, limit = 10, offset = 0, query } = options;
106
+ return (await this.batch([{
107
+ namespacePrefix,
108
+ filter,
109
+ limit,
110
+ offset,
111
+ query
112
+ }]))[0];
113
+ }
114
+ /**
115
+ * Store or update an item.
116
+ *
117
+ * @param namespace Hierarchical path for the item
118
+ * @param key Unique identifier within the namespace
119
+ * @param value Object containing the item's data
120
+ * @param index Optional indexing configuration
121
+ *
122
+ * @example
123
+ * // Simple storage
124
+ * await store.put(["docs"], "report", { title: "Annual Report" });
125
+ *
126
+ * // With specific field indexing
127
+ * await store.put(
128
+ * ["docs"],
129
+ * "report",
130
+ * {
131
+ * title: "Q4 Report",
132
+ * chapters: [{ content: "..." }, { content: "..." }]
133
+ * },
134
+ * ["title", "chapters[*].content"]
135
+ * );
136
+ */
137
+ async put(namespace, key, value, index) {
138
+ validateNamespace(namespace);
139
+ await this.batch([{
140
+ namespace,
141
+ key,
142
+ value,
143
+ index
144
+ }]);
145
+ }
146
+ /**
147
+ * Delete an item from the store.
148
+ *
149
+ * @param namespace Hierarchical path for the item
150
+ * @param key Unique identifier within the namespace
151
+ */
152
+ async delete(namespace, key) {
153
+ await this.batch([{
154
+ namespace,
155
+ key,
156
+ value: null
157
+ }]);
158
+ }
159
+ /**
160
+ * List and filter namespaces in the store.
161
+ * Used to explore data organization and navigate the namespace hierarchy.
162
+ *
163
+ * @param options Options for listing namespaces
164
+ * @returns Promise resolving to list of namespace paths
165
+ *
166
+ * @example
167
+ * // List all namespaces under "documents"
168
+ * await store.listNamespaces({
169
+ * prefix: ["documents"],
170
+ * maxDepth: 2
171
+ * });
172
+ *
173
+ * // List namespaces ending with "v1"
174
+ * await store.listNamespaces({
175
+ * suffix: ["v1"],
176
+ * limit: 50
177
+ * });
178
+ */
179
+ async listNamespaces(options = {}) {
180
+ const { prefix, suffix, maxDepth, limit = 100, offset = 0 } = options;
181
+ const matchConditions = [];
182
+ if (prefix) matchConditions.push({
183
+ matchType: "prefix",
184
+ path: prefix
185
+ });
186
+ if (suffix) matchConditions.push({
187
+ matchType: "suffix",
188
+ path: suffix
189
+ });
190
+ return (await this.batch([{
191
+ matchConditions: matchConditions.length ? matchConditions : void 0,
192
+ maxDepth,
193
+ limit,
194
+ offset
195
+ }]))[0];
196
+ }
197
+ /**
198
+ * Start the store. Override if initialization is needed.
199
+ */
200
+ start() {}
201
+ /**
202
+ * Stop the store. Override if cleanup is needed.
203
+ */
204
+ stop() {}
205
+ };
206
+
207
+ //#endregion
220
208
  exports.BaseStore = BaseStore;
221
- //# sourceMappingURL=base.js.map
209
+ exports.InvalidNamespaceError = InvalidNamespaceError;
210
+ exports.getTextAtPath = getTextAtPath;
211
+ exports.tokenizePath = tokenizePath;
212
+ //# sourceMappingURL=base.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.cjs","names":["current: any","results: string[]","matchConditions: MatchCondition[]"],"sources":["../../src/store/base.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { Embeddings } from \"@langchain/core/embeddings\";\n\n/**\n * Error thrown when an invalid namespace is provided.\n */\nexport class InvalidNamespaceError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"InvalidNamespaceError\";\n }\n}\n\n/**\n * Validates the provided namespace.\n * @param namespace The namespace to validate.\n * @throws {InvalidNamespaceError} If the namespace is invalid.\n */\nfunction validateNamespace(namespace: string[]): void {\n if (namespace.length === 0) {\n throw new InvalidNamespaceError(\"Namespace cannot be empty.\");\n }\n for (const label of namespace) {\n if (typeof label !== \"string\") {\n throw new InvalidNamespaceError(\n `Invalid namespace label '${label}' found in ${namespace}. Namespace labels ` +\n `must be strings, but got ${typeof label}.`\n );\n }\n if (label.includes(\".\")) {\n throw new InvalidNamespaceError(\n `Invalid namespace label '${label}' found in ${namespace}. Namespace labels cannot contain periods ('.').`\n );\n }\n if (label === \"\") {\n throw new InvalidNamespaceError(\n `Namespace labels cannot be empty strings. Got ${label} in ${namespace}`\n );\n }\n }\n if (namespace[0] === \"langgraph\") {\n throw new InvalidNamespaceError(\n `Root label for namespace cannot be \"langgraph\". Got: ${namespace}`\n );\n }\n}\n\n/**\n * Represents a stored item with metadata.\n */\nexport interface Item {\n /**\n * The stored data as an object. Keys are filterable.\n */\n value: Record<string, any>;\n /**\n * Unique identifier within the namespace.\n */\n key: string;\n /**\n * Hierarchical path defining the collection in which this document resides.\n * Represented as an array of strings, allowing for nested categorization.\n * For example: [\"documents\", \"user123\"]\n */\n namespace: string[];\n /**\n * Timestamp of item creation.\n */\n createdAt: Date;\n /**\n * Timestamp of last update.\n */\n updatedAt: Date;\n}\n\n/**\n * Represents a search result item with relevance score.\n * Extends the base Item interface with an optional similarity score.\n */\nexport interface SearchItem extends Item {\n /**\n * Relevance/similarity score if from a ranked operation.\n * Higher scores indicate better matches.\n *\n * This is typically a cosine similarity score between -1 and 1,\n * where 1 indicates identical vectors and -1 indicates opposite vectors.\n */\n score?: number;\n}\n\n/**\n * Operation to retrieve an item by namespace and ID.\n */\nexport interface GetOperation {\n /**\n * Hierarchical path for the item.\n *\n * @example\n * // Get a user profile\n * namespace: [\"users\", \"profiles\"]\n */\n namespace: string[];\n\n /**\n * Unique identifier within the namespace.\n * Together with namespace forms the complete path to the item.\n *\n * @example\n * key: \"user123\" // For a user profile\n * key: \"doc456\" // For a document\n */\n key: string;\n}\n\n/**\n * Operation to search for items within a namespace prefix.\n */\nexport interface SearchOperation {\n /**\n * Hierarchical path prefix to search within.\n * Only items under this prefix will be searched.\n *\n * @example\n * // Search all user documents\n * namespacePrefix: [\"users\", \"documents\"]\n *\n * // Search everything\n * namespacePrefix: []\n */\n namespacePrefix: string[];\n\n /**\n * Key-value pairs to filter results based on exact matches or comparison operators.\n *\n * Supports both exact matches and operator-based comparisons:\n * - $eq: Equal to (same as direct value comparison)\n * - $ne: Not equal to\n * - $gt: Greater than\n * - $gte: Greater than or equal to\n * - $lt: Less than\n * - $lte: Less than or equal to\n *\n * @example\n * // Exact match\n * filter: { status: \"active\" }\n *\n * // With operators\n * filter: { score: { $gt: 4.99 } }\n *\n * // Multiple conditions\n * filter: {\n * score: { $gte: 3.0 },\n * color: \"red\"\n * }\n */\n filter?: Record<string, any>;\n\n /**\n * Maximum number of items to return.\n * @default 10\n */\n limit?: number;\n\n /**\n * Number of items to skip before returning results.\n * Useful for pagination.\n * @default 0\n */\n offset?: number;\n\n /**\n * Natural language search query for semantic search.\n * When provided, results will be ranked by relevance to this query\n * using vector similarity search.\n *\n * @example\n * // Find technical documentation about APIs\n * query: \"technical documentation about REST APIs\"\n *\n * // Find recent ML papers\n * query: \"machine learning papers from 2023\"\n */\n query?: string;\n}\n\n/**\n * Operation to store, update, or delete an item.\n */\nexport interface PutOperation {\n /**\n * Hierarchical path for the item.\n * Acts as a folder-like structure to organize items.\n * Each element represents one level in the hierarchy.\n *\n * @example\n * // Root level documents\n * namespace: [\"documents\"]\n *\n * // User-specific documents\n * namespace: [\"documents\", \"user123\"]\n *\n * // Nested cache structure\n * namespace: [\"cache\", \"docs\", \"v1\"]\n */\n namespace: string[];\n\n /**\n * Unique identifier for the document within its namespace.\n * Together with namespace forms the complete path to the item.\n *\n * Example: If namespace is [\"documents\", \"user123\"] and key is \"report1\",\n * the full path would effectively be \"documents/user123/report1\"\n */\n key: string;\n\n /**\n * Data to be stored, or null to delete the item.\n * Must be a JSON-serializable object with string keys.\n * Setting to null signals that the item should be deleted.\n *\n * @example\n * {\n * field1: \"string value\",\n * field2: 123,\n * nested: { can: \"contain\", any: \"serializable data\" }\n * }\n */\n value: Record<string, any> | null;\n\n /**\n * Controls how the item's fields are indexed for search operations.\n *\n * - undefined: Uses store's default indexing configuration\n * - false: Disables indexing for this item\n * - string[]: List of field paths to index\n *\n * Path syntax supports:\n * - Nested fields: \"metadata.title\"\n * - Array access: \"chapters[*].content\" (each indexed separately)\n * - Specific indices: \"authors[0].name\"\n *\n * @example\n * // Index specific fields\n * index: [\"metadata.title\", \"chapters[*].content\"]\n *\n * // Disable indexing\n * index: false\n */\n index?: false | string[];\n}\n\n/**\n * Operation to list and filter namespaces in the store.\n */\nexport interface ListNamespacesOperation {\n matchConditions?: MatchCondition[];\n maxDepth?: number;\n limit: number;\n offset: number;\n}\n\nexport type NameSpacePath = (string | \"*\")[];\n\nexport type NamespaceMatchType = \"prefix\" | \"suffix\";\n\nexport interface MatchCondition {\n matchType: NamespaceMatchType;\n path: NameSpacePath;\n}\n\nexport type Operation =\n | GetOperation\n | SearchOperation\n | PutOperation\n | ListNamespacesOperation;\n\nexport type OperationResults<Tuple extends readonly Operation[]> = {\n [K in keyof Tuple]: Tuple[K] extends PutOperation\n ? void\n : Tuple[K] extends SearchOperation\n ? SearchItem[]\n : Tuple[K] extends GetOperation\n ? Item | null\n : Tuple[K] extends ListNamespacesOperation\n ? string[][]\n : never;\n};\n\n/**\n * Configuration for indexing documents for semantic search in the store.\n *\n * This configures how documents are embedded and indexed for vector similarity search.\n */\nexport interface IndexConfig {\n /**\n * Number of dimensions in the embedding vectors.\n *\n * Common embedding model dimensions:\n * - OpenAI text-embedding-3-large: 256, 1024, or 3072\n * - OpenAI text-embedding-3-small: 512 or 1536\n * - OpenAI text-embedding-ada-002: 1536\n * - Cohere embed-english-v3.0: 1024\n * - Cohere embed-english-light-v3.0: 384\n * - Cohere embed-multilingual-v3.0: 1024\n * - Cohere embed-multilingual-light-v3.0: 384\n */\n dims: number;\n\n /**\n * The embeddings model to use for generating vectors.\n * This should be a LangChain Embeddings implementation.\n */\n embeddings: Embeddings;\n\n /**\n * Fields to extract text from for embedding generation.\n *\n * Path syntax supports:\n * - Simple field access: \"field\"\n * - Nested fields: \"metadata.title\"\n * - Array indexing:\n * - All elements: \"chapters[*].content\"\n * - Specific index: \"authors[0].name\"\n * - Last element: \"array[-1]\"\n *\n * @default [\"$\"] Embeds the entire document as one vector\n */\n fields?: string[];\n}\n\n/**\n * Utility function to get text at a specific JSON path\n */\nexport function getTextAtPath(obj: any, path: string): string[] {\n const parts = path.split(\".\");\n let current: any = obj;\n\n for (const part of parts) {\n if (part.includes(\"[\")) {\n const [arrayName, indexStr] = part.split(\"[\");\n const index = indexStr.replace(\"]\", \"\");\n\n if (!current[arrayName]) return [];\n\n if (index === \"*\") {\n const results: string[] = [];\n for (const item of current[arrayName]) {\n if (typeof item === \"string\") results.push(item);\n }\n return results;\n }\n\n const idx = parseInt(index, 10);\n if (Number.isNaN(idx)) return [];\n current = current[arrayName][idx];\n } else {\n current = current[part];\n }\n\n if (current === undefined) return [];\n }\n\n return typeof current === \"string\" ? [current] : [];\n}\n\n/**\n * Tokenizes a JSON path into parts\n */\nexport function tokenizePath(path: string): string[] {\n return path.split(\".\");\n}\n\n/**\n * Abstract base class for persistent key-value stores.\n *\n * Stores enable persistence and memory that can be shared across threads,\n * scoped to user IDs, assistant IDs, or other arbitrary namespaces.\n *\n * Features:\n * - Hierarchical namespaces for organization\n * - Key-value storage with metadata\n * - Vector similarity search (if configured)\n * - Filtering and pagination\n */\nexport abstract class BaseStore {\n /**\n * Execute multiple operations in a single batch.\n * This is more efficient than executing operations individually.\n *\n * @param operations Array of operations to execute\n * @returns Promise resolving to results matching the operations\n */\n abstract batch<Op extends Operation[]>(\n operations: Op\n ): Promise<OperationResults<Op>>;\n\n /**\n * Retrieve a single item by its namespace and key.\n *\n * @param namespace Hierarchical path for the item\n * @param key Unique identifier within the namespace\n * @returns Promise resolving to the item or null if not found\n */\n async get(namespace: string[], key: string): Promise<Item | null> {\n return (await this.batch<[GetOperation]>([{ namespace, key }]))[0];\n }\n\n /**\n * Search for items within a namespace prefix.\n * Supports both metadata filtering and vector similarity search.\n *\n * @param namespacePrefix Hierarchical path prefix to search within\n * @param options Search options for filtering and pagination\n * @returns Promise resolving to list of matching items with relevance scores\n *\n * @example\n * // Search with filters\n * await store.search([\"documents\"], {\n * filter: { type: \"report\", status: \"active\" },\n * limit: 5,\n * offset: 10\n * });\n *\n * // Vector similarity search\n * await store.search([\"users\", \"content\"], {\n * query: \"technical documentation about APIs\",\n * limit: 20\n * });\n */\n async search(\n namespacePrefix: string[],\n options: {\n filter?: Record<string, any>;\n limit?: number;\n offset?: number;\n query?: string;\n } = {}\n ): Promise<SearchItem[]> {\n const { filter, limit = 10, offset = 0, query } = options;\n return (\n await this.batch<[SearchOperation]>([\n {\n namespacePrefix,\n filter,\n limit,\n offset,\n query,\n },\n ])\n )[0];\n }\n\n /**\n * Store or update an item.\n *\n * @param namespace Hierarchical path for the item\n * @param key Unique identifier within the namespace\n * @param value Object containing the item's data\n * @param index Optional indexing configuration\n *\n * @example\n * // Simple storage\n * await store.put([\"docs\"], \"report\", { title: \"Annual Report\" });\n *\n * // With specific field indexing\n * await store.put(\n * [\"docs\"],\n * \"report\",\n * {\n * title: \"Q4 Report\",\n * chapters: [{ content: \"...\" }, { content: \"...\" }]\n * },\n * [\"title\", \"chapters[*].content\"]\n * );\n */\n async put(\n namespace: string[],\n key: string,\n value: Record<string, any>,\n index?: false | string[]\n ): Promise<void> {\n validateNamespace(namespace);\n await this.batch<[PutOperation]>([{ namespace, key, value, index }]);\n }\n\n /**\n * Delete an item from the store.\n *\n * @param namespace Hierarchical path for the item\n * @param key Unique identifier within the namespace\n */\n async delete(namespace: string[], key: string): Promise<void> {\n await this.batch<[PutOperation]>([{ namespace, key, value: null }]);\n }\n\n /**\n * List and filter namespaces in the store.\n * Used to explore data organization and navigate the namespace hierarchy.\n *\n * @param options Options for listing namespaces\n * @returns Promise resolving to list of namespace paths\n *\n * @example\n * // List all namespaces under \"documents\"\n * await store.listNamespaces({\n * prefix: [\"documents\"],\n * maxDepth: 2\n * });\n *\n * // List namespaces ending with \"v1\"\n * await store.listNamespaces({\n * suffix: [\"v1\"],\n * limit: 50\n * });\n */\n async listNamespaces(\n options: {\n prefix?: string[];\n suffix?: string[];\n maxDepth?: number;\n limit?: number;\n offset?: number;\n } = {}\n ): Promise<string[][]> {\n const { prefix, suffix, maxDepth, limit = 100, offset = 0 } = options;\n\n const matchConditions: MatchCondition[] = [];\n if (prefix) {\n matchConditions.push({ matchType: \"prefix\", path: prefix });\n }\n if (suffix) {\n matchConditions.push({ matchType: \"suffix\", path: suffix });\n }\n\n return (\n await this.batch<[ListNamespacesOperation]>([\n {\n matchConditions: matchConditions.length ? matchConditions : undefined,\n maxDepth,\n limit,\n offset,\n },\n ])\n )[0];\n }\n\n /**\n * Start the store. Override if initialization is needed.\n */\n start(): void | Promise<void> {}\n\n /**\n * Stop the store. Override if cleanup is needed.\n */\n stop(): void | Promise<void> {}\n}\n"],"mappings":";;;;;AAMA,IAAa,wBAAb,cAA2C,MAAM;CAC/C,YAAY,SAAiB;AAC3B,QAAM;AACN,OAAK,OAAO;;;;;;;;AAShB,SAAS,kBAAkB,WAA2B;AACpD,KAAI,UAAU,WAAW,EACvB,OAAM,IAAI,sBAAsB;AAElC,MAAK,MAAM,SAAS,WAAW;AAC7B,MAAI,OAAO,UAAU,SACnB,OAAM,IAAI,sBACR,4BAA4B,MAAM,aAAa,UAAU,8CAC3B,OAAO,MAAM;AAG/C,MAAI,MAAM,SAAS,KACjB,OAAM,IAAI,sBACR,4BAA4B,MAAM,aAAa,UAAU;AAG7D,MAAI,UAAU,GACZ,OAAM,IAAI,sBACR,iDAAiD,MAAM,MAAM;;AAInE,KAAI,UAAU,OAAO,YACnB,OAAM,IAAI,sBACR,wDAAwD;;;;;AAmS9D,SAAgB,cAAc,KAAU,MAAwB;CAC9D,MAAM,QAAQ,KAAK,MAAM;CACzB,IAAIA,UAAe;AAEnB,MAAK,MAAM,QAAQ,OAAO;AACxB,MAAI,KAAK,SAAS,MAAM;GACtB,MAAM,CAAC,WAAW,YAAY,KAAK,MAAM;GACzC,MAAM,QAAQ,SAAS,QAAQ,KAAK;AAEpC,OAAI,CAAC,QAAQ,WAAY,QAAO;AAEhC,OAAI,UAAU,KAAK;IACjB,MAAMC,UAAoB;AAC1B,SAAK,MAAM,QAAQ,QAAQ,WACzB,KAAI,OAAO,SAAS,SAAU,SAAQ,KAAK;AAE7C,WAAO;;GAGT,MAAM,MAAM,SAAS,OAAO;AAC5B,OAAI,OAAO,MAAM,KAAM,QAAO;AAC9B,aAAU,QAAQ,WAAW;QAE7B,WAAU,QAAQ;AAGpB,MAAI,YAAY,OAAW,QAAO;;AAGpC,QAAO,OAAO,YAAY,WAAW,CAAC,WAAW;;;;;AAMnD,SAAgB,aAAa,MAAwB;AACnD,QAAO,KAAK,MAAM;;;;;;;;;;;;;;AAepB,IAAsB,YAAtB,MAAgC;;;;;;;;CAmB9B,MAAM,IAAI,WAAqB,KAAmC;AAChE,UAAQ,MAAM,KAAK,MAAsB,CAAC;GAAE;GAAW;OAAS;;;;;;;;;;;;;;;;;;;;;;;;CAyBlE,MAAM,OACJ,iBACA,UAKI,IACmB;EACvB,MAAM,EAAE,QAAQ,QAAQ,IAAI,SAAS,GAAG,UAAU;AAClD,UACE,MAAM,KAAK,MAAyB,CAClC;GACE;GACA;GACA;GACA;GACA;OAGJ;;;;;;;;;;;;;;;;;;;;;;;;;CA0BJ,MAAM,IACJ,WACA,KACA,OACA,OACe;AACf,oBAAkB;AAClB,QAAM,KAAK,MAAsB,CAAC;GAAE;GAAW;GAAK;GAAO;;;;;;;;;CAS7D,MAAM,OAAO,WAAqB,KAA4B;AAC5D,QAAM,KAAK,MAAsB,CAAC;GAAE;GAAW;GAAK,OAAO;;;;;;;;;;;;;;;;;;;;;;;CAuB7D,MAAM,eACJ,UAMI,IACiB;EACrB,MAAM,EAAE,QAAQ,QAAQ,UAAU,QAAQ,KAAK,SAAS,MAAM;EAE9D,MAAMC,kBAAoC;AAC1C,MAAI,OACF,iBAAgB,KAAK;GAAE,WAAW;GAAU,MAAM;;AAEpD,MAAI,OACF,iBAAgB,KAAK;GAAE,WAAW;GAAU,MAAM;;AAGpD,UACE,MAAM,KAAK,MAAiC,CAC1C;GACE,iBAAiB,gBAAgB,SAAS,kBAAkB;GAC5D;GACA;GACA;OAGJ;;;;;CAMJ,QAA8B;;;;CAK9B,OAA6B"}