@langchain/langgraph-checkpoint 0.0.4 → 0.0.6

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/memory.cjs CHANGED
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MemorySaver = void 0;
4
4
  const base_js_1 = require("./base.cjs");
5
+ const types_js_1 = require("./serde/types.cjs");
5
6
  function _generateKey(threadId, checkpointNamespace, checkpointId) {
6
7
  return JSON.stringify([threadId, checkpointNamespace, checkpointId]);
7
8
  }
@@ -22,6 +23,19 @@ class MemorySaver extends base_js_1.BaseCheckpointSaver {
22
23
  value: {}
23
24
  });
24
25
  }
26
+ async _getPendingSends(threadId, checkpointNs, parentCheckpointId) {
27
+ let pendingSends = [];
28
+ if (parentCheckpointId !== undefined) {
29
+ pendingSends = await Promise.all(this.writes[_generateKey(threadId, checkpointNs, parentCheckpointId)]
30
+ ?.filter(([_taskId, channel]) => {
31
+ return channel === types_js_1.TASKS;
32
+ })
33
+ .map(([_taskId, _channel, writes]) => {
34
+ return this.serde.loadsTyped("json", writes);
35
+ }) ?? []);
36
+ }
37
+ return pendingSends;
38
+ }
25
39
  async getTuple(config) {
26
40
  const thread_id = config.configurable?.thread_id;
27
41
  const checkpoint_ns = config.configurable?.checkpoint_ns ?? "";
@@ -32,6 +46,11 @@ class MemorySaver extends base_js_1.BaseCheckpointSaver {
32
46
  const [checkpoint, metadata, parentCheckpointId] = saved;
33
47
  const writes = this.writes[_generateKey(thread_id, checkpoint_ns, checkpoint_id)] ??
34
48
  [];
49
+ const pending_sends = await this._getPendingSends(thread_id, checkpoint_ns, parentCheckpointId);
50
+ const deserializedCheckpoint = {
51
+ ...(await this.serde.loadsTyped("json", checkpoint)),
52
+ pending_sends,
53
+ };
35
54
  const pendingWrites = await Promise.all(writes.map(async ([taskId, channel, value]) => {
36
55
  return [
37
56
  taskId,
@@ -41,7 +60,7 @@ class MemorySaver extends base_js_1.BaseCheckpointSaver {
41
60
  }));
42
61
  const checkpointTuple = {
43
62
  config,
44
- checkpoint: (await this.serde.loadsTyped("json", checkpoint)),
63
+ checkpoint: deserializedCheckpoint,
45
64
  metadata: (await this.serde.loadsTyped("json", metadata)),
46
65
  pendingWrites,
47
66
  };
@@ -66,6 +85,11 @@ class MemorySaver extends base_js_1.BaseCheckpointSaver {
66
85
  const [checkpoint, metadata, parentCheckpointId] = saved;
67
86
  const writes = this.writes[_generateKey(thread_id, checkpoint_ns, checkpoint_id)] ??
68
87
  [];
88
+ const pending_sends = await this._getPendingSends(thread_id, checkpoint_ns, parentCheckpointId);
89
+ const deserializedCheckpoint = {
90
+ ...(await this.serde.loadsTyped("json", checkpoint)),
91
+ pending_sends,
92
+ };
69
93
  const pendingWrites = await Promise.all(writes.map(async ([taskId, channel, value]) => {
70
94
  return [
71
95
  taskId,
@@ -81,7 +105,7 @@ class MemorySaver extends base_js_1.BaseCheckpointSaver {
81
105
  checkpoint_ns,
82
106
  },
83
107
  },
84
- checkpoint: (await this.serde.loadsTyped("json", checkpoint)),
108
+ checkpoint: deserializedCheckpoint,
85
109
  metadata: (await this.serde.loadsTyped("json", metadata)),
86
110
  pendingWrites,
87
111
  };
@@ -126,6 +150,7 @@ class MemorySaver extends base_js_1.BaseCheckpointSaver {
126
150
  limit -= 1;
127
151
  }
128
152
  const writes = this.writes[_generateKey(threadId, checkpointNamespace, checkpointId)] ?? [];
153
+ const pending_sends = await this._getPendingSends(threadId, checkpointNamespace, parentCheckpointId);
129
154
  const pendingWrites = await Promise.all(writes.map(async ([taskId, channel, value]) => {
130
155
  return [
131
156
  taskId,
@@ -133,6 +158,10 @@ class MemorySaver extends base_js_1.BaseCheckpointSaver {
133
158
  await this.serde.loadsTyped("json", value),
134
159
  ];
135
160
  }));
161
+ const deserializedCheckpoint = {
162
+ ...(await this.serde.loadsTyped("json", checkpoint)),
163
+ pending_sends,
164
+ };
136
165
  const checkpointTuple = {
137
166
  config: {
138
167
  configurable: {
@@ -141,7 +170,7 @@ class MemorySaver extends base_js_1.BaseCheckpointSaver {
141
170
  checkpoint_id: checkpointId,
142
171
  },
143
172
  },
144
- checkpoint: (await this.serde.loadsTyped("json", checkpoint)),
173
+ checkpoint: deserializedCheckpoint,
145
174
  metadata,
146
175
  pendingWrites,
147
176
  };
@@ -159,6 +188,8 @@ class MemorySaver extends base_js_1.BaseCheckpointSaver {
159
188
  }
160
189
  }
161
190
  async put(config, checkpoint, metadata) {
191
+ const preparedCheckpoint = (0, base_js_1.copyCheckpoint)(checkpoint);
192
+ delete preparedCheckpoint.pending_sends;
162
193
  const threadId = config.configurable?.thread_id;
163
194
  const checkpointNamespace = config.configurable?.checkpoint_ns;
164
195
  if (threadId === undefined) {
@@ -173,7 +204,7 @@ class MemorySaver extends base_js_1.BaseCheckpointSaver {
173
204
  if (!this.storage[threadId][checkpointNamespace]) {
174
205
  this.storage[threadId][checkpointNamespace] = {};
175
206
  }
176
- const [, serializedCheckpoint] = this.serde.dumpsTyped(checkpoint);
207
+ const [, serializedCheckpoint] = this.serde.dumpsTyped(preparedCheckpoint);
177
208
  const [, serializedMetadata] = this.serde.dumpsTyped(metadata);
178
209
  this.storage[threadId][checkpointNamespace][checkpoint.id] = [
179
210
  serializedCheckpoint,
package/dist/memory.d.ts CHANGED
@@ -2,10 +2,12 @@ import type { RunnableConfig } from "@langchain/core/runnables";
2
2
  import { BaseCheckpointSaver, Checkpoint, CheckpointListOptions, CheckpointTuple } from "./base.js";
3
3
  import { SerializerProtocol } from "./serde/base.js";
4
4
  import { CheckpointMetadata, CheckpointPendingWrite, PendingWrite } from "./types.js";
5
+ import { SendProtocol } from "./serde/types.js";
5
6
  export declare class MemorySaver extends BaseCheckpointSaver {
6
7
  storage: Record<string, Record<string, Record<string, [Uint8Array, Uint8Array, string | undefined]>>>;
7
8
  writes: Record<string, CheckpointPendingWrite[]>;
8
9
  constructor(serde?: SerializerProtocol);
10
+ _getPendingSends(threadId: string, checkpointNs: string, parentCheckpointId?: string): Promise<SendProtocol[]>;
9
11
  getTuple(config: RunnableConfig): Promise<CheckpointTuple | undefined>;
10
12
  list(config: RunnableConfig, options?: CheckpointListOptions): AsyncGenerator<CheckpointTuple>;
11
13
  put(config: RunnableConfig, checkpoint: Checkpoint, metadata: CheckpointMetadata): Promise<RunnableConfig>;
package/dist/memory.js CHANGED
@@ -1,4 +1,5 @@
1
- import { BaseCheckpointSaver, } from "./base.js";
1
+ import { BaseCheckpointSaver, copyCheckpoint, } from "./base.js";
2
+ import { TASKS } from "./serde/types.js";
2
3
  function _generateKey(threadId, checkpointNamespace, checkpointId) {
3
4
  return JSON.stringify([threadId, checkpointNamespace, checkpointId]);
4
5
  }
@@ -19,6 +20,19 @@ export class MemorySaver extends BaseCheckpointSaver {
19
20
  value: {}
20
21
  });
21
22
  }
23
+ async _getPendingSends(threadId, checkpointNs, parentCheckpointId) {
24
+ let pendingSends = [];
25
+ if (parentCheckpointId !== undefined) {
26
+ pendingSends = await Promise.all(this.writes[_generateKey(threadId, checkpointNs, parentCheckpointId)]
27
+ ?.filter(([_taskId, channel]) => {
28
+ return channel === TASKS;
29
+ })
30
+ .map(([_taskId, _channel, writes]) => {
31
+ return this.serde.loadsTyped("json", writes);
32
+ }) ?? []);
33
+ }
34
+ return pendingSends;
35
+ }
22
36
  async getTuple(config) {
23
37
  const thread_id = config.configurable?.thread_id;
24
38
  const checkpoint_ns = config.configurable?.checkpoint_ns ?? "";
@@ -29,6 +43,11 @@ export class MemorySaver extends BaseCheckpointSaver {
29
43
  const [checkpoint, metadata, parentCheckpointId] = saved;
30
44
  const writes = this.writes[_generateKey(thread_id, checkpoint_ns, checkpoint_id)] ??
31
45
  [];
46
+ const pending_sends = await this._getPendingSends(thread_id, checkpoint_ns, parentCheckpointId);
47
+ const deserializedCheckpoint = {
48
+ ...(await this.serde.loadsTyped("json", checkpoint)),
49
+ pending_sends,
50
+ };
32
51
  const pendingWrites = await Promise.all(writes.map(async ([taskId, channel, value]) => {
33
52
  return [
34
53
  taskId,
@@ -38,7 +57,7 @@ export class MemorySaver extends BaseCheckpointSaver {
38
57
  }));
39
58
  const checkpointTuple = {
40
59
  config,
41
- checkpoint: (await this.serde.loadsTyped("json", checkpoint)),
60
+ checkpoint: deserializedCheckpoint,
42
61
  metadata: (await this.serde.loadsTyped("json", metadata)),
43
62
  pendingWrites,
44
63
  };
@@ -63,6 +82,11 @@ export class MemorySaver extends BaseCheckpointSaver {
63
82
  const [checkpoint, metadata, parentCheckpointId] = saved;
64
83
  const writes = this.writes[_generateKey(thread_id, checkpoint_ns, checkpoint_id)] ??
65
84
  [];
85
+ const pending_sends = await this._getPendingSends(thread_id, checkpoint_ns, parentCheckpointId);
86
+ const deserializedCheckpoint = {
87
+ ...(await this.serde.loadsTyped("json", checkpoint)),
88
+ pending_sends,
89
+ };
66
90
  const pendingWrites = await Promise.all(writes.map(async ([taskId, channel, value]) => {
67
91
  return [
68
92
  taskId,
@@ -78,7 +102,7 @@ export class MemorySaver extends BaseCheckpointSaver {
78
102
  checkpoint_ns,
79
103
  },
80
104
  },
81
- checkpoint: (await this.serde.loadsTyped("json", checkpoint)),
105
+ checkpoint: deserializedCheckpoint,
82
106
  metadata: (await this.serde.loadsTyped("json", metadata)),
83
107
  pendingWrites,
84
108
  };
@@ -123,6 +147,7 @@ export class MemorySaver extends BaseCheckpointSaver {
123
147
  limit -= 1;
124
148
  }
125
149
  const writes = this.writes[_generateKey(threadId, checkpointNamespace, checkpointId)] ?? [];
150
+ const pending_sends = await this._getPendingSends(threadId, checkpointNamespace, parentCheckpointId);
126
151
  const pendingWrites = await Promise.all(writes.map(async ([taskId, channel, value]) => {
127
152
  return [
128
153
  taskId,
@@ -130,6 +155,10 @@ export class MemorySaver extends BaseCheckpointSaver {
130
155
  await this.serde.loadsTyped("json", value),
131
156
  ];
132
157
  }));
158
+ const deserializedCheckpoint = {
159
+ ...(await this.serde.loadsTyped("json", checkpoint)),
160
+ pending_sends,
161
+ };
133
162
  const checkpointTuple = {
134
163
  config: {
135
164
  configurable: {
@@ -138,7 +167,7 @@ export class MemorySaver extends BaseCheckpointSaver {
138
167
  checkpoint_id: checkpointId,
139
168
  },
140
169
  },
141
- checkpoint: (await this.serde.loadsTyped("json", checkpoint)),
170
+ checkpoint: deserializedCheckpoint,
142
171
  metadata,
143
172
  pendingWrites,
144
173
  };
@@ -156,6 +185,8 @@ export class MemorySaver extends BaseCheckpointSaver {
156
185
  }
157
186
  }
158
187
  async put(config, checkpoint, metadata) {
188
+ const preparedCheckpoint = copyCheckpoint(checkpoint);
189
+ delete preparedCheckpoint.pending_sends;
159
190
  const threadId = config.configurable?.thread_id;
160
191
  const checkpointNamespace = config.configurable?.checkpoint_ns;
161
192
  if (threadId === undefined) {
@@ -170,7 +201,7 @@ export class MemorySaver extends BaseCheckpointSaver {
170
201
  if (!this.storage[threadId][checkpointNamespace]) {
171
202
  this.storage[threadId][checkpointNamespace] = {};
172
203
  }
173
- const [, serializedCheckpoint] = this.serde.dumpsTyped(checkpoint);
204
+ const [, serializedCheckpoint] = this.serde.dumpsTyped(preparedCheckpoint);
174
205
  const [, serializedMetadata] = this.serde.dumpsTyped(metadata);
175
206
  this.storage[threadId][checkpointNamespace][checkpoint.id] = [
176
207
  serializedCheckpoint,
@@ -133,6 +133,13 @@ function _default(_key, obj) {
133
133
  }
134
134
  else if (obj instanceof Error) {
135
135
  return _encodeConstructorArgs(obj.constructor, undefined, [obj.message]);
136
+ // TODO: Remove special case
137
+ }
138
+ else if (obj?.lg_name === "Send") {
139
+ return {
140
+ node: obj.node,
141
+ args: obj.args,
142
+ };
136
143
  }
137
144
  else {
138
145
  return obj;
@@ -130,6 +130,13 @@ function _default(_key, obj) {
130
130
  }
131
131
  else if (obj instanceof Error) {
132
132
  return _encodeConstructorArgs(obj.constructor, undefined, [obj.message]);
133
+ // TODO: Remove special case
134
+ }
135
+ else if (obj?.lg_name === "Send") {
136
+ return {
137
+ node: obj.node,
138
+ args: obj.args,
139
+ };
133
140
  }
134
141
  else {
135
142
  return obj;
@@ -1,2 +1,4 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TASKS = void 0;
4
+ exports.TASKS = "__pregel_tasks";
@@ -1,3 +1,4 @@
1
+ export declare const TASKS = "__pregel_tasks";
1
2
  export interface ChannelProtocol<ValueType = unknown, UpdateType = unknown, CheckpointType = unknown> {
2
3
  ValueType: ValueType;
3
4
  UpdateType: UpdateType;
@@ -1 +1 @@
1
- export {};
1
+ export const TASKS = "__pregel_tasks";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@langchain/langgraph-checkpoint",
3
- "version": "0.0.4",
3
+ "version": "0.0.6",
4
4
  "description": "Library with base interfaces for LangGraph checkpoint savers.",
5
5
  "type": "module",
6
6
  "engines": {
@@ -34,7 +34,7 @@
34
34
  "uuid": "^10.0.0"
35
35
  },
36
36
  "peerDependencies": {
37
- "@langchain/core": ">=0.2.20 <0.3.0"
37
+ "@langchain/core": ">=0.2.31 <0.4.0"
38
38
  },
39
39
  "devDependencies": {
40
40
  "@jest/globals": "^29.5.0",