@langchain/langgraph-checkpoint-mongodb 0.0.1 → 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/dist/index.cjs +236 -0
- package/dist/index.d.ts +41 -0
- package/dist/index.js +232 -0
- package/index.cjs +1 -0
- package/index.d.cts +1 -0
- package/index.d.ts +1 -0
- package/index.js +1 -0
- package/package.json +6 -4
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MongoDBSaver = void 0;
|
|
4
|
+
const langgraph_checkpoint_1 = require("@langchain/langgraph-checkpoint");
|
|
5
|
+
/**
|
|
6
|
+
* A LangGraph checkpoint saver backed by a MongoDB database.
|
|
7
|
+
*/
|
|
8
|
+
class MongoDBSaver extends langgraph_checkpoint_1.BaseCheckpointSaver {
|
|
9
|
+
constructor({ client, dbName, checkpointCollectionName, checkpointWritesCollectionName, }, serde) {
|
|
10
|
+
super(serde);
|
|
11
|
+
Object.defineProperty(this, "client", {
|
|
12
|
+
enumerable: true,
|
|
13
|
+
configurable: true,
|
|
14
|
+
writable: true,
|
|
15
|
+
value: void 0
|
|
16
|
+
});
|
|
17
|
+
Object.defineProperty(this, "db", {
|
|
18
|
+
enumerable: true,
|
|
19
|
+
configurable: true,
|
|
20
|
+
writable: true,
|
|
21
|
+
value: void 0
|
|
22
|
+
});
|
|
23
|
+
Object.defineProperty(this, "checkpointCollectionName", {
|
|
24
|
+
enumerable: true,
|
|
25
|
+
configurable: true,
|
|
26
|
+
writable: true,
|
|
27
|
+
value: "checkpoints"
|
|
28
|
+
});
|
|
29
|
+
Object.defineProperty(this, "checkpointWritesCollectionName", {
|
|
30
|
+
enumerable: true,
|
|
31
|
+
configurable: true,
|
|
32
|
+
writable: true,
|
|
33
|
+
value: "checkpoint_writes"
|
|
34
|
+
});
|
|
35
|
+
this.client = client;
|
|
36
|
+
this.db = this.client.db(dbName);
|
|
37
|
+
this.checkpointCollectionName =
|
|
38
|
+
checkpointCollectionName ?? this.checkpointCollectionName;
|
|
39
|
+
this.checkpointWritesCollectionName =
|
|
40
|
+
checkpointWritesCollectionName ?? this.checkpointWritesCollectionName;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Retrieves a checkpoint from the MongoDB database based on the
|
|
44
|
+
* provided config. If the config contains a "checkpoint_id" key, the checkpoint with
|
|
45
|
+
* the matching thread ID and checkpoint ID is retrieved. Otherwise, the latest checkpoint
|
|
46
|
+
* for the given thread ID is retrieved.
|
|
47
|
+
*/
|
|
48
|
+
async getTuple(config) {
|
|
49
|
+
const { thread_id, checkpoint_ns = "", checkpoint_id, } = config.configurable ?? {};
|
|
50
|
+
let query;
|
|
51
|
+
if (checkpoint_id) {
|
|
52
|
+
query = {
|
|
53
|
+
thread_id,
|
|
54
|
+
checkpoint_ns,
|
|
55
|
+
checkpoint_id,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
query = { thread_id, checkpoint_ns };
|
|
60
|
+
}
|
|
61
|
+
const result = await this.db
|
|
62
|
+
.collection(this.checkpointCollectionName)
|
|
63
|
+
.find(query)
|
|
64
|
+
.sort("checkpoint_id", -1)
|
|
65
|
+
.limit(1)
|
|
66
|
+
.toArray();
|
|
67
|
+
if (result.length === 0) {
|
|
68
|
+
return undefined;
|
|
69
|
+
}
|
|
70
|
+
const doc = result[0];
|
|
71
|
+
const configurableValues = {
|
|
72
|
+
thread_id,
|
|
73
|
+
checkpoint_ns,
|
|
74
|
+
checkpoint_id: doc.checkpoint_id,
|
|
75
|
+
};
|
|
76
|
+
const checkpoint = (await this.serde.loadsTyped(doc.type, doc.checkpoint.value()));
|
|
77
|
+
const serializedWrites = await this.db
|
|
78
|
+
.collection(this.checkpointWritesCollectionName)
|
|
79
|
+
.find(configurableValues)
|
|
80
|
+
.toArray();
|
|
81
|
+
const pendingWrites = await Promise.all(serializedWrites.map(async (serializedWrite) => {
|
|
82
|
+
return [
|
|
83
|
+
serializedWrite.task_id,
|
|
84
|
+
serializedWrite.channel,
|
|
85
|
+
await this.serde.loadsTyped(serializedWrite.type, serializedWrite.value.value()),
|
|
86
|
+
];
|
|
87
|
+
}));
|
|
88
|
+
return {
|
|
89
|
+
config: { configurable: configurableValues },
|
|
90
|
+
checkpoint,
|
|
91
|
+
pendingWrites,
|
|
92
|
+
metadata: (await this.serde.loadsTyped(doc.type, doc.metadata.value())),
|
|
93
|
+
parentConfig: doc.parent_checkpoint_id != null
|
|
94
|
+
? {
|
|
95
|
+
configurable: {
|
|
96
|
+
thread_id,
|
|
97
|
+
checkpoint_ns,
|
|
98
|
+
checkpoint_id: doc.parent_checkpoint_id,
|
|
99
|
+
},
|
|
100
|
+
}
|
|
101
|
+
: undefined,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Retrieve a list of checkpoint tuples from the MongoDB database based
|
|
106
|
+
* on the provided config. The checkpoints are ordered by checkpoint ID
|
|
107
|
+
* in descending order (newest first).
|
|
108
|
+
*/
|
|
109
|
+
async *list(config, options) {
|
|
110
|
+
const { limit, before, filter } = options ?? {};
|
|
111
|
+
let query = {};
|
|
112
|
+
if (config?.configurable) {
|
|
113
|
+
query = {
|
|
114
|
+
thread_id: config.configurable.thread_id,
|
|
115
|
+
checkpoint_ns: config.configurable.checkpoint_ns ?? "",
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
if (filter) {
|
|
119
|
+
Object.entries(filter).forEach(([key, value]) => {
|
|
120
|
+
query[`metadata.${key}`] = value;
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
if (before) {
|
|
124
|
+
query.checkpoint_id = { $lt: before.configurable?.checkpoint_id };
|
|
125
|
+
}
|
|
126
|
+
let result = this.db
|
|
127
|
+
.collection(this.checkpointCollectionName)
|
|
128
|
+
.find(query)
|
|
129
|
+
.sort("checkpoint_id", -1);
|
|
130
|
+
if (limit !== undefined) {
|
|
131
|
+
result = result.limit(limit);
|
|
132
|
+
}
|
|
133
|
+
for await (const doc of result) {
|
|
134
|
+
const checkpoint = (await this.serde.loadsTyped(doc.type, doc.checkpoint.value()));
|
|
135
|
+
const metadata = (await this.serde.loadsTyped(doc.type, doc.metadata.value()));
|
|
136
|
+
yield {
|
|
137
|
+
config: {
|
|
138
|
+
configurable: {
|
|
139
|
+
thread_id: doc.thread_id,
|
|
140
|
+
checkpoint_ns: doc.checkpoint_ns,
|
|
141
|
+
checkpoint_id: doc.checkpoint_id,
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
checkpoint,
|
|
145
|
+
metadata,
|
|
146
|
+
parentConfig: doc.parent_checkpoint_id
|
|
147
|
+
? {
|
|
148
|
+
configurable: {
|
|
149
|
+
thread_id: doc.thread_id,
|
|
150
|
+
checkpoint_ns: doc.checkpoint_ns,
|
|
151
|
+
checkpoint_id: doc.parent_checkpoint_id,
|
|
152
|
+
},
|
|
153
|
+
}
|
|
154
|
+
: undefined,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Saves a checkpoint to the MongoDB database. The checkpoint is associated
|
|
160
|
+
* with the provided config and its parent config (if any).
|
|
161
|
+
*/
|
|
162
|
+
async put(config, checkpoint, metadata) {
|
|
163
|
+
const thread_id = config.configurable?.thread_id;
|
|
164
|
+
const checkpoint_ns = config.configurable?.checkpoint_ns ?? "";
|
|
165
|
+
const checkpoint_id = checkpoint.id;
|
|
166
|
+
if (thread_id === undefined) {
|
|
167
|
+
throw new Error(`The provided config must contain a configurable field with a "thread_id" field.`);
|
|
168
|
+
}
|
|
169
|
+
const [checkpointType, serializedCheckpoint] = this.serde.dumpsTyped(checkpoint);
|
|
170
|
+
const [metadataType, serializedMetadata] = this.serde.dumpsTyped(metadata);
|
|
171
|
+
if (checkpointType !== metadataType) {
|
|
172
|
+
throw new Error("Mismatched checkpoint and metadata types.");
|
|
173
|
+
}
|
|
174
|
+
const doc = {
|
|
175
|
+
parent_checkpoint_id: config.configurable?.checkpoint_id,
|
|
176
|
+
type: checkpointType,
|
|
177
|
+
checkpoint: serializedCheckpoint,
|
|
178
|
+
metadata: serializedMetadata,
|
|
179
|
+
};
|
|
180
|
+
const upsertQuery = {
|
|
181
|
+
thread_id,
|
|
182
|
+
checkpoint_ns,
|
|
183
|
+
checkpoint_id,
|
|
184
|
+
};
|
|
185
|
+
await this.db.collection(this.checkpointCollectionName).updateOne(upsertQuery, {
|
|
186
|
+
$set: doc,
|
|
187
|
+
}, { upsert: true });
|
|
188
|
+
return {
|
|
189
|
+
configurable: {
|
|
190
|
+
thread_id,
|
|
191
|
+
checkpoint_ns,
|
|
192
|
+
checkpoint_id,
|
|
193
|
+
},
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Saves intermediate writes associated with a checkpoint to the MongoDB database.
|
|
198
|
+
*/
|
|
199
|
+
async putWrites(config, writes, taskId) {
|
|
200
|
+
const thread_id = config.configurable?.thread_id;
|
|
201
|
+
const checkpoint_ns = config.configurable?.checkpoint_ns;
|
|
202
|
+
const checkpoint_id = config.configurable?.checkpoint_id;
|
|
203
|
+
if (thread_id === undefined ||
|
|
204
|
+
checkpoint_ns === undefined ||
|
|
205
|
+
checkpoint_id === undefined) {
|
|
206
|
+
throw new Error(`The provided config must contain a configurable field with "thread_id", "checkpoint_ns" and "checkpoint_id" fields.`);
|
|
207
|
+
}
|
|
208
|
+
const operations = writes.map(([channel, value], idx) => {
|
|
209
|
+
const upsertQuery = {
|
|
210
|
+
thread_id,
|
|
211
|
+
checkpoint_ns,
|
|
212
|
+
checkpoint_id,
|
|
213
|
+
task_id: taskId,
|
|
214
|
+
idx,
|
|
215
|
+
};
|
|
216
|
+
const [type, serializedValue] = this.serde.dumpsTyped(value);
|
|
217
|
+
return {
|
|
218
|
+
updateOne: {
|
|
219
|
+
filter: upsertQuery,
|
|
220
|
+
update: {
|
|
221
|
+
$set: {
|
|
222
|
+
channel,
|
|
223
|
+
type,
|
|
224
|
+
value: serializedValue,
|
|
225
|
+
},
|
|
226
|
+
},
|
|
227
|
+
upsert: true,
|
|
228
|
+
},
|
|
229
|
+
};
|
|
230
|
+
});
|
|
231
|
+
await this.db
|
|
232
|
+
.collection(this.checkpointWritesCollectionName)
|
|
233
|
+
.bulkWrite(operations);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
exports.MongoDBSaver = MongoDBSaver;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { type MongoClient, type Db as MongoDatabase } from "mongodb";
|
|
2
|
+
import type { RunnableConfig } from "@langchain/core/runnables";
|
|
3
|
+
import { BaseCheckpointSaver, type Checkpoint, type CheckpointListOptions, type CheckpointTuple, type SerializerProtocol, type PendingWrite, type CheckpointMetadata } from "@langchain/langgraph-checkpoint";
|
|
4
|
+
export type MongoDBSaverParams = {
|
|
5
|
+
client: MongoClient;
|
|
6
|
+
dbName?: string;
|
|
7
|
+
checkpointCollectionName?: string;
|
|
8
|
+
checkpointWritesCollectionName?: string;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* A LangGraph checkpoint saver backed by a MongoDB database.
|
|
12
|
+
*/
|
|
13
|
+
export declare class MongoDBSaver extends BaseCheckpointSaver {
|
|
14
|
+
protected client: MongoClient;
|
|
15
|
+
protected db: MongoDatabase;
|
|
16
|
+
checkpointCollectionName: string;
|
|
17
|
+
checkpointWritesCollectionName: string;
|
|
18
|
+
constructor({ client, dbName, checkpointCollectionName, checkpointWritesCollectionName, }: MongoDBSaverParams, serde?: SerializerProtocol);
|
|
19
|
+
/**
|
|
20
|
+
* Retrieves a checkpoint from the MongoDB database based on the
|
|
21
|
+
* provided config. If the config contains a "checkpoint_id" key, the checkpoint with
|
|
22
|
+
* the matching thread ID and checkpoint ID is retrieved. Otherwise, the latest checkpoint
|
|
23
|
+
* for the given thread ID is retrieved.
|
|
24
|
+
*/
|
|
25
|
+
getTuple(config: RunnableConfig): Promise<CheckpointTuple | undefined>;
|
|
26
|
+
/**
|
|
27
|
+
* Retrieve a list of checkpoint tuples from the MongoDB database based
|
|
28
|
+
* on the provided config. The checkpoints are ordered by checkpoint ID
|
|
29
|
+
* in descending order (newest first).
|
|
30
|
+
*/
|
|
31
|
+
list(config: RunnableConfig, options?: CheckpointListOptions): AsyncGenerator<CheckpointTuple>;
|
|
32
|
+
/**
|
|
33
|
+
* Saves a checkpoint to the MongoDB database. The checkpoint is associated
|
|
34
|
+
* with the provided config and its parent config (if any).
|
|
35
|
+
*/
|
|
36
|
+
put(config: RunnableConfig, checkpoint: Checkpoint, metadata: CheckpointMetadata): Promise<RunnableConfig>;
|
|
37
|
+
/**
|
|
38
|
+
* Saves intermediate writes associated with a checkpoint to the MongoDB database.
|
|
39
|
+
*/
|
|
40
|
+
putWrites(config: RunnableConfig, writes: PendingWrite[], taskId: string): Promise<void>;
|
|
41
|
+
}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import { BaseCheckpointSaver, } from "@langchain/langgraph-checkpoint";
|
|
2
|
+
/**
|
|
3
|
+
* A LangGraph checkpoint saver backed by a MongoDB database.
|
|
4
|
+
*/
|
|
5
|
+
export class MongoDBSaver extends BaseCheckpointSaver {
|
|
6
|
+
constructor({ client, dbName, checkpointCollectionName, checkpointWritesCollectionName, }, serde) {
|
|
7
|
+
super(serde);
|
|
8
|
+
Object.defineProperty(this, "client", {
|
|
9
|
+
enumerable: true,
|
|
10
|
+
configurable: true,
|
|
11
|
+
writable: true,
|
|
12
|
+
value: void 0
|
|
13
|
+
});
|
|
14
|
+
Object.defineProperty(this, "db", {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
configurable: true,
|
|
17
|
+
writable: true,
|
|
18
|
+
value: void 0
|
|
19
|
+
});
|
|
20
|
+
Object.defineProperty(this, "checkpointCollectionName", {
|
|
21
|
+
enumerable: true,
|
|
22
|
+
configurable: true,
|
|
23
|
+
writable: true,
|
|
24
|
+
value: "checkpoints"
|
|
25
|
+
});
|
|
26
|
+
Object.defineProperty(this, "checkpointWritesCollectionName", {
|
|
27
|
+
enumerable: true,
|
|
28
|
+
configurable: true,
|
|
29
|
+
writable: true,
|
|
30
|
+
value: "checkpoint_writes"
|
|
31
|
+
});
|
|
32
|
+
this.client = client;
|
|
33
|
+
this.db = this.client.db(dbName);
|
|
34
|
+
this.checkpointCollectionName =
|
|
35
|
+
checkpointCollectionName ?? this.checkpointCollectionName;
|
|
36
|
+
this.checkpointWritesCollectionName =
|
|
37
|
+
checkpointWritesCollectionName ?? this.checkpointWritesCollectionName;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Retrieves a checkpoint from the MongoDB database based on the
|
|
41
|
+
* provided config. If the config contains a "checkpoint_id" key, the checkpoint with
|
|
42
|
+
* the matching thread ID and checkpoint ID is retrieved. Otherwise, the latest checkpoint
|
|
43
|
+
* for the given thread ID is retrieved.
|
|
44
|
+
*/
|
|
45
|
+
async getTuple(config) {
|
|
46
|
+
const { thread_id, checkpoint_ns = "", checkpoint_id, } = config.configurable ?? {};
|
|
47
|
+
let query;
|
|
48
|
+
if (checkpoint_id) {
|
|
49
|
+
query = {
|
|
50
|
+
thread_id,
|
|
51
|
+
checkpoint_ns,
|
|
52
|
+
checkpoint_id,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
query = { thread_id, checkpoint_ns };
|
|
57
|
+
}
|
|
58
|
+
const result = await this.db
|
|
59
|
+
.collection(this.checkpointCollectionName)
|
|
60
|
+
.find(query)
|
|
61
|
+
.sort("checkpoint_id", -1)
|
|
62
|
+
.limit(1)
|
|
63
|
+
.toArray();
|
|
64
|
+
if (result.length === 0) {
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
67
|
+
const doc = result[0];
|
|
68
|
+
const configurableValues = {
|
|
69
|
+
thread_id,
|
|
70
|
+
checkpoint_ns,
|
|
71
|
+
checkpoint_id: doc.checkpoint_id,
|
|
72
|
+
};
|
|
73
|
+
const checkpoint = (await this.serde.loadsTyped(doc.type, doc.checkpoint.value()));
|
|
74
|
+
const serializedWrites = await this.db
|
|
75
|
+
.collection(this.checkpointWritesCollectionName)
|
|
76
|
+
.find(configurableValues)
|
|
77
|
+
.toArray();
|
|
78
|
+
const pendingWrites = await Promise.all(serializedWrites.map(async (serializedWrite) => {
|
|
79
|
+
return [
|
|
80
|
+
serializedWrite.task_id,
|
|
81
|
+
serializedWrite.channel,
|
|
82
|
+
await this.serde.loadsTyped(serializedWrite.type, serializedWrite.value.value()),
|
|
83
|
+
];
|
|
84
|
+
}));
|
|
85
|
+
return {
|
|
86
|
+
config: { configurable: configurableValues },
|
|
87
|
+
checkpoint,
|
|
88
|
+
pendingWrites,
|
|
89
|
+
metadata: (await this.serde.loadsTyped(doc.type, doc.metadata.value())),
|
|
90
|
+
parentConfig: doc.parent_checkpoint_id != null
|
|
91
|
+
? {
|
|
92
|
+
configurable: {
|
|
93
|
+
thread_id,
|
|
94
|
+
checkpoint_ns,
|
|
95
|
+
checkpoint_id: doc.parent_checkpoint_id,
|
|
96
|
+
},
|
|
97
|
+
}
|
|
98
|
+
: undefined,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Retrieve a list of checkpoint tuples from the MongoDB database based
|
|
103
|
+
* on the provided config. The checkpoints are ordered by checkpoint ID
|
|
104
|
+
* in descending order (newest first).
|
|
105
|
+
*/
|
|
106
|
+
async *list(config, options) {
|
|
107
|
+
const { limit, before, filter } = options ?? {};
|
|
108
|
+
let query = {};
|
|
109
|
+
if (config?.configurable) {
|
|
110
|
+
query = {
|
|
111
|
+
thread_id: config.configurable.thread_id,
|
|
112
|
+
checkpoint_ns: config.configurable.checkpoint_ns ?? "",
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
if (filter) {
|
|
116
|
+
Object.entries(filter).forEach(([key, value]) => {
|
|
117
|
+
query[`metadata.${key}`] = value;
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
if (before) {
|
|
121
|
+
query.checkpoint_id = { $lt: before.configurable?.checkpoint_id };
|
|
122
|
+
}
|
|
123
|
+
let result = this.db
|
|
124
|
+
.collection(this.checkpointCollectionName)
|
|
125
|
+
.find(query)
|
|
126
|
+
.sort("checkpoint_id", -1);
|
|
127
|
+
if (limit !== undefined) {
|
|
128
|
+
result = result.limit(limit);
|
|
129
|
+
}
|
|
130
|
+
for await (const doc of result) {
|
|
131
|
+
const checkpoint = (await this.serde.loadsTyped(doc.type, doc.checkpoint.value()));
|
|
132
|
+
const metadata = (await this.serde.loadsTyped(doc.type, doc.metadata.value()));
|
|
133
|
+
yield {
|
|
134
|
+
config: {
|
|
135
|
+
configurable: {
|
|
136
|
+
thread_id: doc.thread_id,
|
|
137
|
+
checkpoint_ns: doc.checkpoint_ns,
|
|
138
|
+
checkpoint_id: doc.checkpoint_id,
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
checkpoint,
|
|
142
|
+
metadata,
|
|
143
|
+
parentConfig: doc.parent_checkpoint_id
|
|
144
|
+
? {
|
|
145
|
+
configurable: {
|
|
146
|
+
thread_id: doc.thread_id,
|
|
147
|
+
checkpoint_ns: doc.checkpoint_ns,
|
|
148
|
+
checkpoint_id: doc.parent_checkpoint_id,
|
|
149
|
+
},
|
|
150
|
+
}
|
|
151
|
+
: undefined,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Saves a checkpoint to the MongoDB database. The checkpoint is associated
|
|
157
|
+
* with the provided config and its parent config (if any).
|
|
158
|
+
*/
|
|
159
|
+
async put(config, checkpoint, metadata) {
|
|
160
|
+
const thread_id = config.configurable?.thread_id;
|
|
161
|
+
const checkpoint_ns = config.configurable?.checkpoint_ns ?? "";
|
|
162
|
+
const checkpoint_id = checkpoint.id;
|
|
163
|
+
if (thread_id === undefined) {
|
|
164
|
+
throw new Error(`The provided config must contain a configurable field with a "thread_id" field.`);
|
|
165
|
+
}
|
|
166
|
+
const [checkpointType, serializedCheckpoint] = this.serde.dumpsTyped(checkpoint);
|
|
167
|
+
const [metadataType, serializedMetadata] = this.serde.dumpsTyped(metadata);
|
|
168
|
+
if (checkpointType !== metadataType) {
|
|
169
|
+
throw new Error("Mismatched checkpoint and metadata types.");
|
|
170
|
+
}
|
|
171
|
+
const doc = {
|
|
172
|
+
parent_checkpoint_id: config.configurable?.checkpoint_id,
|
|
173
|
+
type: checkpointType,
|
|
174
|
+
checkpoint: serializedCheckpoint,
|
|
175
|
+
metadata: serializedMetadata,
|
|
176
|
+
};
|
|
177
|
+
const upsertQuery = {
|
|
178
|
+
thread_id,
|
|
179
|
+
checkpoint_ns,
|
|
180
|
+
checkpoint_id,
|
|
181
|
+
};
|
|
182
|
+
await this.db.collection(this.checkpointCollectionName).updateOne(upsertQuery, {
|
|
183
|
+
$set: doc,
|
|
184
|
+
}, { upsert: true });
|
|
185
|
+
return {
|
|
186
|
+
configurable: {
|
|
187
|
+
thread_id,
|
|
188
|
+
checkpoint_ns,
|
|
189
|
+
checkpoint_id,
|
|
190
|
+
},
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Saves intermediate writes associated with a checkpoint to the MongoDB database.
|
|
195
|
+
*/
|
|
196
|
+
async putWrites(config, writes, taskId) {
|
|
197
|
+
const thread_id = config.configurable?.thread_id;
|
|
198
|
+
const checkpoint_ns = config.configurable?.checkpoint_ns;
|
|
199
|
+
const checkpoint_id = config.configurable?.checkpoint_id;
|
|
200
|
+
if (thread_id === undefined ||
|
|
201
|
+
checkpoint_ns === undefined ||
|
|
202
|
+
checkpoint_id === undefined) {
|
|
203
|
+
throw new Error(`The provided config must contain a configurable field with "thread_id", "checkpoint_ns" and "checkpoint_id" fields.`);
|
|
204
|
+
}
|
|
205
|
+
const operations = writes.map(([channel, value], idx) => {
|
|
206
|
+
const upsertQuery = {
|
|
207
|
+
thread_id,
|
|
208
|
+
checkpoint_ns,
|
|
209
|
+
checkpoint_id,
|
|
210
|
+
task_id: taskId,
|
|
211
|
+
idx,
|
|
212
|
+
};
|
|
213
|
+
const [type, serializedValue] = this.serde.dumpsTyped(value);
|
|
214
|
+
return {
|
|
215
|
+
updateOne: {
|
|
216
|
+
filter: upsertQuery,
|
|
217
|
+
update: {
|
|
218
|
+
$set: {
|
|
219
|
+
channel,
|
|
220
|
+
type,
|
|
221
|
+
value: serializedValue,
|
|
222
|
+
},
|
|
223
|
+
},
|
|
224
|
+
upsert: true,
|
|
225
|
+
},
|
|
226
|
+
};
|
|
227
|
+
});
|
|
228
|
+
await this.db
|
|
229
|
+
.collection(this.checkpointWritesCollectionName)
|
|
230
|
+
.bulkWrite(operations);
|
|
231
|
+
}
|
|
232
|
+
}
|
package/index.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require('./dist/index.cjs');
|
package/index.d.cts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './dist/index.js'
|
package/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './dist/index.js'
|
package/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './dist/index.js'
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@langchain/langgraph-checkpoint-mongodb",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"description": "LangGraph",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -13,8 +13,9 @@
|
|
|
13
13
|
"url": "git@github.com:langchain-ai/langgraphjs.git"
|
|
14
14
|
},
|
|
15
15
|
"scripts": {
|
|
16
|
-
"build": "yarn turbo:command build:internal --filter=@langchain/langgraph-checkpoint-
|
|
17
|
-
"build:internal": "yarn
|
|
16
|
+
"build": "yarn turbo:command build:internal --filter=@langchain/langgraph-checkpoint-mongodb",
|
|
17
|
+
"build:internal": "yarn clean && yarn lc_build --create-entrypoints --pre --tree-shaking",
|
|
18
|
+
"clean": "rm -rf dist/ dist-cjs/ .turbo/",
|
|
18
19
|
"lint:eslint": "NODE_OPTIONS=--max-old-space-size=4096 eslint --cache --ext .ts,.js src/",
|
|
19
20
|
"lint:dpdm": "dpdm --exit-code circular:1 --no-warning --no-tree src/*.ts src/**/*.ts",
|
|
20
21
|
"lint": "yarn lint:eslint && yarn lint:dpdm",
|
|
@@ -38,7 +39,8 @@
|
|
|
38
39
|
},
|
|
39
40
|
"devDependencies": {
|
|
40
41
|
"@jest/globals": "^29.5.0",
|
|
41
|
-
"@langchain/
|
|
42
|
+
"@langchain/langgraph-checkpoint": "workspace:*",
|
|
43
|
+
"@langchain/scripts": ">=0.1.2 <0.2.0",
|
|
42
44
|
"@swc/core": "^1.3.90",
|
|
43
45
|
"@swc/jest": "^0.2.29",
|
|
44
46
|
"@tsconfig/recommended": "^1.0.3",
|