@langchain/langgraph 0.1.0-rc.0 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/dist/channels/base.cjs +20 -15
- package/dist/channels/base.d.ts +2 -3
- package/dist/channels/base.js +18 -13
- package/dist/checkpoint/sqlite.cjs +14 -199
- package/dist/checkpoint/sqlite.d.ts +1 -16
- package/dist/checkpoint/sqlite.js +1 -195
- package/dist/graph/graph.d.ts +1 -1
- package/dist/graph/message.d.ts +0 -3
- package/dist/graph/messages_annotation.cjs +12 -0
- package/dist/graph/messages_annotation.d.ts +4 -0
- package/dist/graph/messages_annotation.js +9 -0
- package/dist/graph/state.cjs +2 -1
- package/dist/graph/state.d.ts +1 -1
- package/dist/graph/state.js +2 -1
- package/dist/index.cjs +3 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/prebuilt/react_agent_executor.d.ts +3 -3
- package/dist/prebuilt/tool_node.d.ts +3 -3
- package/dist/pregel/algo.cjs +112 -105
- package/dist/pregel/algo.d.ts +8 -5
- package/dist/pregel/algo.js +109 -102
- package/dist/pregel/debug.cjs +9 -12
- package/dist/pregel/debug.d.ts +3 -2
- package/dist/pregel/debug.js +6 -10
- package/dist/pregel/index.cjs +92 -26
- package/dist/pregel/index.d.ts +41 -3
- package/dist/pregel/index.js +90 -24
- package/dist/pregel/io.d.ts +1 -1
- package/dist/pregel/loop.cjs +13 -9
- package/dist/pregel/loop.d.ts +1 -2
- package/dist/pregel/loop.js +8 -4
- package/dist/pregel/types.d.ts +5 -2
- package/dist/pregel/utils.cjs +25 -10
- package/dist/pregel/utils.d.ts +8 -1
- package/dist/pregel/utils.js +22 -9
- package/dist/web.cjs +6 -7
- package/dist/web.d.ts +1 -4
- package/dist/web.js +1 -2
- package/package.json +12 -12
- package/dist/checkpoint/base.cjs +0 -75
- package/dist/checkpoint/base.d.ts +0 -78
- package/dist/checkpoint/base.js +0 -66
- package/dist/checkpoint/id.cjs +0 -20
- package/dist/checkpoint/id.d.ts +0 -2
- package/dist/checkpoint/id.js +0 -15
- package/dist/checkpoint/index.cjs +0 -9
- package/dist/checkpoint/index.d.ts +0 -3
- package/dist/checkpoint/index.js +0 -2
- package/dist/checkpoint/memory.cjs +0 -195
- package/dist/checkpoint/memory.d.ts +0 -13
- package/dist/checkpoint/memory.js +0 -191
- package/dist/checkpoint/serde/types.cjs +0 -2
- package/dist/checkpoint/serde/types.d.ts +0 -40
- package/dist/checkpoint/serde/types.js +0 -1
- package/dist/checkpoint/types.cjs +0 -2
- package/dist/checkpoint/types.d.ts +0 -28
- package/dist/checkpoint/types.js +0 -1
- package/dist/serde/base.cjs +0 -8
- package/dist/serde/base.d.ts +0 -12
- package/dist/serde/base.js +0 -5
package/dist/checkpoint/base.cjs
DELETED
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.BaseCheckpointSaver = exports.copyCheckpoint = exports.emptyCheckpoint = exports.deepCopy = exports.getVersionSeen = exports.getChannelVersion = void 0;
|
|
4
|
-
const base_js_1 = require("../serde/base.cjs");
|
|
5
|
-
const id_js_1 = require("./id.cjs");
|
|
6
|
-
function getChannelVersion(checkpoint, channel) {
|
|
7
|
-
return checkpoint.channel_versions[channel] ?? 0;
|
|
8
|
-
}
|
|
9
|
-
exports.getChannelVersion = getChannelVersion;
|
|
10
|
-
function getVersionSeen(checkpoint, node, channel) {
|
|
11
|
-
return checkpoint.versions_seen[node]?.[channel] ?? 0;
|
|
12
|
-
}
|
|
13
|
-
exports.getVersionSeen = getVersionSeen;
|
|
14
|
-
function deepCopy(obj) {
|
|
15
|
-
if (typeof obj !== "object" || obj === null) {
|
|
16
|
-
return obj;
|
|
17
|
-
}
|
|
18
|
-
const newObj = Array.isArray(obj) ? [] : {};
|
|
19
|
-
for (const key in obj) {
|
|
20
|
-
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
21
|
-
newObj[key] = deepCopy(obj[key]);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
return newObj;
|
|
25
|
-
}
|
|
26
|
-
exports.deepCopy = deepCopy;
|
|
27
|
-
function emptyCheckpoint() {
|
|
28
|
-
return {
|
|
29
|
-
v: 1,
|
|
30
|
-
id: (0, id_js_1.uuid6)(-2),
|
|
31
|
-
ts: new Date().toISOString(),
|
|
32
|
-
channel_values: {},
|
|
33
|
-
channel_versions: {},
|
|
34
|
-
versions_seen: {},
|
|
35
|
-
pending_sends: [],
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
exports.emptyCheckpoint = emptyCheckpoint;
|
|
39
|
-
function copyCheckpoint(checkpoint) {
|
|
40
|
-
return {
|
|
41
|
-
v: checkpoint.v,
|
|
42
|
-
id: checkpoint.id,
|
|
43
|
-
ts: checkpoint.ts,
|
|
44
|
-
channel_values: { ...checkpoint.channel_values },
|
|
45
|
-
channel_versions: { ...checkpoint.channel_versions },
|
|
46
|
-
versions_seen: deepCopy(checkpoint.versions_seen),
|
|
47
|
-
pending_sends: [...checkpoint.pending_sends],
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
exports.copyCheckpoint = copyCheckpoint;
|
|
51
|
-
class BaseCheckpointSaver {
|
|
52
|
-
constructor(serde) {
|
|
53
|
-
Object.defineProperty(this, "serde", {
|
|
54
|
-
enumerable: true,
|
|
55
|
-
configurable: true,
|
|
56
|
-
writable: true,
|
|
57
|
-
value: base_js_1.DefaultSerializer
|
|
58
|
-
});
|
|
59
|
-
this.serde = serde || this.serde;
|
|
60
|
-
}
|
|
61
|
-
async get(config) {
|
|
62
|
-
const value = await this.getTuple(config);
|
|
63
|
-
return value ? value.checkpoint : undefined;
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Generate the next version ID for a channel.
|
|
67
|
-
*
|
|
68
|
-
* Default is to use integer versions, incrementing by 1. If you override, you can use str/int/float versions,
|
|
69
|
-
* as long as they are monotonically increasing.
|
|
70
|
-
*/
|
|
71
|
-
getNextVersion(current, _channel) {
|
|
72
|
-
return current !== undefined ? current + 1 : 1;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
exports.BaseCheckpointSaver = BaseCheckpointSaver;
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import { RunnableConfig } from "@langchain/core/runnables";
|
|
2
|
-
import { SerializerProtocol } from "../serde/base.js";
|
|
3
|
-
import { SendInterface } from "../constants.js";
|
|
4
|
-
import type { PendingWrite, CheckpointPendingWrite, CheckpointMetadata } from "./types.js";
|
|
5
|
-
import { ChannelProtocol } from "./serde/types.js";
|
|
6
|
-
export type ChannelVersions = Record<string, string | number>;
|
|
7
|
-
export interface Checkpoint<N extends string = string, C extends string = string> {
|
|
8
|
-
/**
|
|
9
|
-
* Version number
|
|
10
|
-
*/
|
|
11
|
-
v: number;
|
|
12
|
-
/**
|
|
13
|
-
* Checkpoint ID {uuid6}
|
|
14
|
-
*/
|
|
15
|
-
id: string;
|
|
16
|
-
/**
|
|
17
|
-
* Timestamp {new Date().toISOString()}
|
|
18
|
-
*/
|
|
19
|
-
ts: string;
|
|
20
|
-
/**
|
|
21
|
-
* @default {}
|
|
22
|
-
*/
|
|
23
|
-
channel_values: Record<C, unknown>;
|
|
24
|
-
/**
|
|
25
|
-
* @default {}
|
|
26
|
-
*/
|
|
27
|
-
channel_versions: Record<C, number>;
|
|
28
|
-
/**
|
|
29
|
-
* @default {}
|
|
30
|
-
*/
|
|
31
|
-
versions_seen: Record<N, Record<C, number>>;
|
|
32
|
-
/**
|
|
33
|
-
* List of packets sent to nodes but not yet processed.
|
|
34
|
-
* Cleared by the next checkpoint.
|
|
35
|
-
*/
|
|
36
|
-
pending_sends: SendInterface[];
|
|
37
|
-
}
|
|
38
|
-
export interface ReadonlyCheckpoint extends Readonly<Checkpoint> {
|
|
39
|
-
readonly channel_values: Readonly<Record<string, unknown>>;
|
|
40
|
-
readonly channel_versions: Readonly<Record<string, number>>;
|
|
41
|
-
readonly versions_seen: Readonly<Record<string, Readonly<Record<string, number>>>>;
|
|
42
|
-
}
|
|
43
|
-
export declare function getChannelVersion(checkpoint: ReadonlyCheckpoint, channel: string): number;
|
|
44
|
-
export declare function getVersionSeen(checkpoint: ReadonlyCheckpoint, node: string, channel: string): number;
|
|
45
|
-
export declare function deepCopy<T>(obj: T): T;
|
|
46
|
-
export declare function emptyCheckpoint(): Checkpoint;
|
|
47
|
-
export declare function copyCheckpoint(checkpoint: ReadonlyCheckpoint): Checkpoint;
|
|
48
|
-
export interface CheckpointTuple {
|
|
49
|
-
config: RunnableConfig;
|
|
50
|
-
checkpoint: Checkpoint;
|
|
51
|
-
metadata?: CheckpointMetadata;
|
|
52
|
-
parentConfig?: RunnableConfig;
|
|
53
|
-
pendingWrites?: CheckpointPendingWrite[];
|
|
54
|
-
}
|
|
55
|
-
export type CheckpointListOptions = {
|
|
56
|
-
limit?: number;
|
|
57
|
-
before?: RunnableConfig;
|
|
58
|
-
filter?: Record<string, any>;
|
|
59
|
-
};
|
|
60
|
-
export declare abstract class BaseCheckpointSaver<V = number> {
|
|
61
|
-
serde: SerializerProtocol<unknown>;
|
|
62
|
-
constructor(serde?: SerializerProtocol<unknown>);
|
|
63
|
-
get(config: RunnableConfig): Promise<Checkpoint | undefined>;
|
|
64
|
-
abstract getTuple(config: RunnableConfig): Promise<CheckpointTuple | undefined>;
|
|
65
|
-
abstract list(config: RunnableConfig, options?: CheckpointListOptions): AsyncGenerator<CheckpointTuple>;
|
|
66
|
-
abstract put(config: RunnableConfig, checkpoint: Checkpoint, metadata: CheckpointMetadata, newVersions: ChannelVersions): Promise<RunnableConfig>;
|
|
67
|
-
/**
|
|
68
|
-
* Store intermediate writes linked to a checkpoint.
|
|
69
|
-
*/
|
|
70
|
-
abstract putWrites(config: RunnableConfig, writes: PendingWrite[], taskId: string): Promise<void>;
|
|
71
|
-
/**
|
|
72
|
-
* Generate the next version ID for a channel.
|
|
73
|
-
*
|
|
74
|
-
* Default is to use integer versions, incrementing by 1. If you override, you can use str/int/float versions,
|
|
75
|
-
* as long as they are monotonically increasing.
|
|
76
|
-
*/
|
|
77
|
-
getNextVersion(current: V | undefined, _channel: ChannelProtocol): number;
|
|
78
|
-
}
|
package/dist/checkpoint/base.js
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { DefaultSerializer } from "../serde/base.js";
|
|
2
|
-
import { uuid6 } from "./id.js";
|
|
3
|
-
export function getChannelVersion(checkpoint, channel) {
|
|
4
|
-
return checkpoint.channel_versions[channel] ?? 0;
|
|
5
|
-
}
|
|
6
|
-
export function getVersionSeen(checkpoint, node, channel) {
|
|
7
|
-
return checkpoint.versions_seen[node]?.[channel] ?? 0;
|
|
8
|
-
}
|
|
9
|
-
export function deepCopy(obj) {
|
|
10
|
-
if (typeof obj !== "object" || obj === null) {
|
|
11
|
-
return obj;
|
|
12
|
-
}
|
|
13
|
-
const newObj = Array.isArray(obj) ? [] : {};
|
|
14
|
-
for (const key in obj) {
|
|
15
|
-
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
16
|
-
newObj[key] = deepCopy(obj[key]);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
return newObj;
|
|
20
|
-
}
|
|
21
|
-
export function emptyCheckpoint() {
|
|
22
|
-
return {
|
|
23
|
-
v: 1,
|
|
24
|
-
id: uuid6(-2),
|
|
25
|
-
ts: new Date().toISOString(),
|
|
26
|
-
channel_values: {},
|
|
27
|
-
channel_versions: {},
|
|
28
|
-
versions_seen: {},
|
|
29
|
-
pending_sends: [],
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
export function copyCheckpoint(checkpoint) {
|
|
33
|
-
return {
|
|
34
|
-
v: checkpoint.v,
|
|
35
|
-
id: checkpoint.id,
|
|
36
|
-
ts: checkpoint.ts,
|
|
37
|
-
channel_values: { ...checkpoint.channel_values },
|
|
38
|
-
channel_versions: { ...checkpoint.channel_versions },
|
|
39
|
-
versions_seen: deepCopy(checkpoint.versions_seen),
|
|
40
|
-
pending_sends: [...checkpoint.pending_sends],
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
export class BaseCheckpointSaver {
|
|
44
|
-
constructor(serde) {
|
|
45
|
-
Object.defineProperty(this, "serde", {
|
|
46
|
-
enumerable: true,
|
|
47
|
-
configurable: true,
|
|
48
|
-
writable: true,
|
|
49
|
-
value: DefaultSerializer
|
|
50
|
-
});
|
|
51
|
-
this.serde = serde || this.serde;
|
|
52
|
-
}
|
|
53
|
-
async get(config) {
|
|
54
|
-
const value = await this.getTuple(config);
|
|
55
|
-
return value ? value.checkpoint : undefined;
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* Generate the next version ID for a channel.
|
|
59
|
-
*
|
|
60
|
-
* Default is to use integer versions, incrementing by 1. If you override, you can use str/int/float versions,
|
|
61
|
-
* as long as they are monotonically increasing.
|
|
62
|
-
*/
|
|
63
|
-
getNextVersion(current, _channel) {
|
|
64
|
-
return current !== undefined ? current + 1 : 1;
|
|
65
|
-
}
|
|
66
|
-
}
|
package/dist/checkpoint/id.cjs
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.uuid5 = exports.uuid6 = void 0;
|
|
4
|
-
const uuid_1 = require("uuid");
|
|
5
|
-
function uuid6(clockseq) {
|
|
6
|
-
return (0, uuid_1.v6)({ clockseq });
|
|
7
|
-
}
|
|
8
|
-
exports.uuid6 = uuid6;
|
|
9
|
-
// Skip UUID validation check, since UUID6s
|
|
10
|
-
// generated with negative clockseq are not
|
|
11
|
-
// technically compliant, but still work.
|
|
12
|
-
// See: https://github.com/uuidjs/uuid/issues/511
|
|
13
|
-
function uuid5(name, namespace) {
|
|
14
|
-
const namespaceBytes = namespace
|
|
15
|
-
.replace(/-/g, "")
|
|
16
|
-
.match(/.{2}/g)
|
|
17
|
-
.map((byte) => parseInt(byte, 16));
|
|
18
|
-
return (0, uuid_1.v5)(name, new Uint8Array(namespaceBytes));
|
|
19
|
-
}
|
|
20
|
-
exports.uuid5 = uuid5;
|
package/dist/checkpoint/id.d.ts
DELETED
package/dist/checkpoint/id.js
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { v5, v6 } from "uuid";
|
|
2
|
-
export function uuid6(clockseq) {
|
|
3
|
-
return v6({ clockseq });
|
|
4
|
-
}
|
|
5
|
-
// Skip UUID validation check, since UUID6s
|
|
6
|
-
// generated with negative clockseq are not
|
|
7
|
-
// technically compliant, but still work.
|
|
8
|
-
// See: https://github.com/uuidjs/uuid/issues/511
|
|
9
|
-
export function uuid5(name, namespace) {
|
|
10
|
-
const namespaceBytes = namespace
|
|
11
|
-
.replace(/-/g, "")
|
|
12
|
-
.match(/.{2}/g)
|
|
13
|
-
.map((byte) => parseInt(byte, 16));
|
|
14
|
-
return v5(name, new Uint8Array(namespaceBytes));
|
|
15
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.BaseCheckpointSaver = exports.emptyCheckpoint = exports.copyCheckpoint = exports.MemorySaver = void 0;
|
|
4
|
-
var memory_js_1 = require("./memory.cjs");
|
|
5
|
-
Object.defineProperty(exports, "MemorySaver", { enumerable: true, get: function () { return memory_js_1.MemorySaver; } });
|
|
6
|
-
var base_js_1 = require("./base.cjs");
|
|
7
|
-
Object.defineProperty(exports, "copyCheckpoint", { enumerable: true, get: function () { return base_js_1.copyCheckpoint; } });
|
|
8
|
-
Object.defineProperty(exports, "emptyCheckpoint", { enumerable: true, get: function () { return base_js_1.emptyCheckpoint; } });
|
|
9
|
-
Object.defineProperty(exports, "BaseCheckpointSaver", { enumerable: true, get: function () { return base_js_1.BaseCheckpointSaver; } });
|
package/dist/checkpoint/index.js
DELETED
|
@@ -1,195 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MemorySaver = void 0;
|
|
4
|
-
const base_js_1 = require("./base.cjs");
|
|
5
|
-
function _generateKey(threadId, checkpointNamespace, checkpointId) {
|
|
6
|
-
return JSON.stringify([threadId, checkpointNamespace, checkpointId]);
|
|
7
|
-
}
|
|
8
|
-
class MemorySaver extends base_js_1.BaseCheckpointSaver {
|
|
9
|
-
constructor(serde) {
|
|
10
|
-
super(serde);
|
|
11
|
-
// thread ID -> checkpoint namespace -> checkpoint ID -> checkpoint mapping
|
|
12
|
-
Object.defineProperty(this, "storage", {
|
|
13
|
-
enumerable: true,
|
|
14
|
-
configurable: true,
|
|
15
|
-
writable: true,
|
|
16
|
-
value: {}
|
|
17
|
-
});
|
|
18
|
-
Object.defineProperty(this, "writes", {
|
|
19
|
-
enumerable: true,
|
|
20
|
-
configurable: true,
|
|
21
|
-
writable: true,
|
|
22
|
-
value: {}
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
async getTuple(config) {
|
|
26
|
-
const thread_id = config.configurable?.thread_id;
|
|
27
|
-
const checkpoint_ns = config.configurable?.checkpoint_ns ?? "";
|
|
28
|
-
const checkpoint_id = config.configurable?.checkpoint_id;
|
|
29
|
-
if (checkpoint_id) {
|
|
30
|
-
const saved = this.storage[thread_id]?.[checkpoint_ns]?.[checkpoint_id];
|
|
31
|
-
if (saved !== undefined) {
|
|
32
|
-
const [checkpoint, metadata, parentCheckpointId] = saved;
|
|
33
|
-
const writes = this.writes[_generateKey(thread_id, checkpoint_ns, checkpoint_id)] ??
|
|
34
|
-
[];
|
|
35
|
-
const pendingWrites = await Promise.all(writes.map(async ([taskId, channel, value]) => {
|
|
36
|
-
return [taskId, channel, await this.serde.parse(value)];
|
|
37
|
-
}));
|
|
38
|
-
const parentConfig = parentCheckpointId !== undefined
|
|
39
|
-
? {
|
|
40
|
-
configurable: {
|
|
41
|
-
thread_id,
|
|
42
|
-
checkpoint_ns,
|
|
43
|
-
checkpoint_id,
|
|
44
|
-
},
|
|
45
|
-
}
|
|
46
|
-
: undefined;
|
|
47
|
-
return {
|
|
48
|
-
config,
|
|
49
|
-
checkpoint: (await this.serde.parse(checkpoint)),
|
|
50
|
-
metadata: (await this.serde.parse(metadata)),
|
|
51
|
-
pendingWrites,
|
|
52
|
-
parentConfig,
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
else {
|
|
57
|
-
const checkpoints = this.storage[thread_id]?.[checkpoint_ns];
|
|
58
|
-
if (checkpoints !== undefined) {
|
|
59
|
-
const maxThreadTs = Object.keys(checkpoints).sort((a, b) => b.localeCompare(a))[0];
|
|
60
|
-
const saved = checkpoints[maxThreadTs];
|
|
61
|
-
const [checkpoint, metadata, parentCheckpointId] = saved;
|
|
62
|
-
const writes = this.writes[_generateKey(thread_id, checkpoint_ns, checkpoint_id)] ??
|
|
63
|
-
[];
|
|
64
|
-
const pendingWrites = await Promise.all(writes.map(async ([taskId, channel, value]) => {
|
|
65
|
-
return [taskId, channel, await this.serde.parse(value)];
|
|
66
|
-
}));
|
|
67
|
-
const parentConfig = parentCheckpointId !== undefined
|
|
68
|
-
? {
|
|
69
|
-
configurable: {
|
|
70
|
-
thread_id,
|
|
71
|
-
checkpoint_ns,
|
|
72
|
-
checkpoint_id: parentCheckpointId,
|
|
73
|
-
},
|
|
74
|
-
}
|
|
75
|
-
: undefined;
|
|
76
|
-
return {
|
|
77
|
-
config: {
|
|
78
|
-
configurable: {
|
|
79
|
-
thread_id,
|
|
80
|
-
checkpoint_id: maxThreadTs,
|
|
81
|
-
checkpoint_ns,
|
|
82
|
-
},
|
|
83
|
-
},
|
|
84
|
-
checkpoint: (await this.serde.parse(checkpoint)),
|
|
85
|
-
metadata: (await this.serde.parse(metadata)),
|
|
86
|
-
pendingWrites,
|
|
87
|
-
parentConfig,
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
return undefined;
|
|
92
|
-
}
|
|
93
|
-
async *list(config, options) {
|
|
94
|
-
// eslint-disable-next-line prefer-const
|
|
95
|
-
let { before, limit } = options ?? {};
|
|
96
|
-
const threadIds = config.configurable?.thread_id
|
|
97
|
-
? [config.configurable?.thread_id]
|
|
98
|
-
: Object.keys(this.storage);
|
|
99
|
-
const checkpointNamespace = config.configurable?.checkpoint_ns ?? "";
|
|
100
|
-
for (const threadId of threadIds) {
|
|
101
|
-
const checkpoints = this.storage[threadId]?.[checkpointNamespace] ?? {};
|
|
102
|
-
const sortedCheckpoints = Object.entries(checkpoints).sort((a, b) => b[0].localeCompare(a[0]));
|
|
103
|
-
for (const [checkpointId, [checkpoint, metadataStr, parentCheckpointId],] of sortedCheckpoints) {
|
|
104
|
-
// Filter by checkpoint ID
|
|
105
|
-
if (before &&
|
|
106
|
-
before.configurable?.checkpoint_id &&
|
|
107
|
-
checkpointId >= before.configurable.checkpoint_id) {
|
|
108
|
-
continue;
|
|
109
|
-
}
|
|
110
|
-
// Parse metadata
|
|
111
|
-
const metadata = (await this.serde.parse(metadataStr));
|
|
112
|
-
// Limit search results
|
|
113
|
-
if (limit !== undefined) {
|
|
114
|
-
if (limit <= 0)
|
|
115
|
-
break;
|
|
116
|
-
// eslint-disable-next-line no-param-reassign
|
|
117
|
-
limit -= 1;
|
|
118
|
-
}
|
|
119
|
-
const writes = this.writes[_generateKey(threadId, checkpointNamespace, checkpointId)] ?? [];
|
|
120
|
-
const pendingWrites = await Promise.all(writes.map(async ([taskId, channel, value]) => {
|
|
121
|
-
return [taskId, channel, await this.serde.parse(value)];
|
|
122
|
-
}));
|
|
123
|
-
yield {
|
|
124
|
-
config: {
|
|
125
|
-
configurable: {
|
|
126
|
-
thread_id: threadId,
|
|
127
|
-
checkpoint_ns: checkpointNamespace,
|
|
128
|
-
checkpoint_id: checkpointId,
|
|
129
|
-
},
|
|
130
|
-
},
|
|
131
|
-
checkpoint: (await this.serde.parse(checkpoint)),
|
|
132
|
-
metadata,
|
|
133
|
-
pendingWrites,
|
|
134
|
-
parentConfig: parentCheckpointId
|
|
135
|
-
? {
|
|
136
|
-
configurable: {
|
|
137
|
-
thread_id: threadId,
|
|
138
|
-
checkpoint_ns: checkpointNamespace,
|
|
139
|
-
checkpoint_id: parentCheckpointId,
|
|
140
|
-
},
|
|
141
|
-
}
|
|
142
|
-
: undefined,
|
|
143
|
-
};
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
async put(config, checkpoint, metadata) {
|
|
148
|
-
const threadId = config.configurable?.thread_id;
|
|
149
|
-
const checkpointNamespace = config.configurable?.checkpoint_ns;
|
|
150
|
-
if (threadId === undefined) {
|
|
151
|
-
throw new Error(`Failed to put checkpoint. The passed RunnableConfig is missing a required "thread_id" field in its "configurable" property.`);
|
|
152
|
-
}
|
|
153
|
-
if (checkpointNamespace === undefined) {
|
|
154
|
-
throw new Error(`Failed to put checkpoint. The passed RunnableConfig is missing a required "checkpoint_ns" field in its "configurable" property.`);
|
|
155
|
-
}
|
|
156
|
-
if (!this.storage[threadId]) {
|
|
157
|
-
this.storage[threadId] = {};
|
|
158
|
-
}
|
|
159
|
-
if (!this.storage[threadId][checkpointNamespace]) {
|
|
160
|
-
this.storage[threadId][checkpointNamespace] = {};
|
|
161
|
-
}
|
|
162
|
-
this.storage[threadId][checkpointNamespace][checkpoint.id] = [
|
|
163
|
-
this.serde.stringify(checkpoint),
|
|
164
|
-
this.serde.stringify(metadata),
|
|
165
|
-
config.configurable?.checkpoint_id, // parent
|
|
166
|
-
];
|
|
167
|
-
return {
|
|
168
|
-
configurable: {
|
|
169
|
-
thread_id: threadId,
|
|
170
|
-
checkpoint_ns: checkpointNamespace,
|
|
171
|
-
checkpoint_id: checkpoint.id,
|
|
172
|
-
},
|
|
173
|
-
};
|
|
174
|
-
}
|
|
175
|
-
async putWrites(config, writes, taskId) {
|
|
176
|
-
const threadId = config.configurable?.thread_id;
|
|
177
|
-
const checkpointNamespace = config.configurable?.checkpoint_ns;
|
|
178
|
-
const checkpointId = config.configurable?.checkpoint_id;
|
|
179
|
-
if (threadId === undefined) {
|
|
180
|
-
throw new Error(`Failed to put writes. The passed RunnableConfig is missing a required "thread_id" field in its "configurable" property`);
|
|
181
|
-
}
|
|
182
|
-
if (checkpointId === undefined) {
|
|
183
|
-
throw new Error(`Failed to put writes. The passed RunnableConfig is missing a required "checkpoint_id" field in its "configurable" property.`);
|
|
184
|
-
}
|
|
185
|
-
const key = _generateKey(threadId, checkpointNamespace, checkpointId);
|
|
186
|
-
if (this.writes[key] === undefined) {
|
|
187
|
-
this.writes[key] = [];
|
|
188
|
-
}
|
|
189
|
-
const pendingWrites = writes.map(([channel, value]) => {
|
|
190
|
-
return [taskId, channel, this.serde.stringify(value)];
|
|
191
|
-
});
|
|
192
|
-
this.writes[key].push(...pendingWrites);
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
exports.MemorySaver = MemorySaver;
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { RunnableConfig } from "@langchain/core/runnables";
|
|
2
|
-
import { BaseCheckpointSaver, Checkpoint, CheckpointListOptions, CheckpointTuple } from "./base.js";
|
|
3
|
-
import { SerializerProtocol } from "../serde/base.js";
|
|
4
|
-
import { CheckpointMetadata, CheckpointPendingWrite, PendingWrite } from "../checkpoint/types.js";
|
|
5
|
-
export declare class MemorySaver extends BaseCheckpointSaver {
|
|
6
|
-
storage: Record<string, Record<string, Record<string, [string, string, string | undefined]>>>;
|
|
7
|
-
writes: Record<string, CheckpointPendingWrite[]>;
|
|
8
|
-
constructor(serde?: SerializerProtocol<unknown>);
|
|
9
|
-
getTuple(config: RunnableConfig): Promise<CheckpointTuple | undefined>;
|
|
10
|
-
list(config: RunnableConfig, options?: CheckpointListOptions): AsyncGenerator<CheckpointTuple>;
|
|
11
|
-
put(config: RunnableConfig, checkpoint: Checkpoint, metadata: CheckpointMetadata): Promise<RunnableConfig>;
|
|
12
|
-
putWrites(config: RunnableConfig, writes: PendingWrite[], taskId: string): Promise<void>;
|
|
13
|
-
}
|
|
@@ -1,191 +0,0 @@
|
|
|
1
|
-
import { BaseCheckpointSaver, } from "./base.js";
|
|
2
|
-
function _generateKey(threadId, checkpointNamespace, checkpointId) {
|
|
3
|
-
return JSON.stringify([threadId, checkpointNamespace, checkpointId]);
|
|
4
|
-
}
|
|
5
|
-
export class MemorySaver extends BaseCheckpointSaver {
|
|
6
|
-
constructor(serde) {
|
|
7
|
-
super(serde);
|
|
8
|
-
// thread ID -> checkpoint namespace -> checkpoint ID -> checkpoint mapping
|
|
9
|
-
Object.defineProperty(this, "storage", {
|
|
10
|
-
enumerable: true,
|
|
11
|
-
configurable: true,
|
|
12
|
-
writable: true,
|
|
13
|
-
value: {}
|
|
14
|
-
});
|
|
15
|
-
Object.defineProperty(this, "writes", {
|
|
16
|
-
enumerable: true,
|
|
17
|
-
configurable: true,
|
|
18
|
-
writable: true,
|
|
19
|
-
value: {}
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
async getTuple(config) {
|
|
23
|
-
const thread_id = config.configurable?.thread_id;
|
|
24
|
-
const checkpoint_ns = config.configurable?.checkpoint_ns ?? "";
|
|
25
|
-
const checkpoint_id = config.configurable?.checkpoint_id;
|
|
26
|
-
if (checkpoint_id) {
|
|
27
|
-
const saved = this.storage[thread_id]?.[checkpoint_ns]?.[checkpoint_id];
|
|
28
|
-
if (saved !== undefined) {
|
|
29
|
-
const [checkpoint, metadata, parentCheckpointId] = saved;
|
|
30
|
-
const writes = this.writes[_generateKey(thread_id, checkpoint_ns, checkpoint_id)] ??
|
|
31
|
-
[];
|
|
32
|
-
const pendingWrites = await Promise.all(writes.map(async ([taskId, channel, value]) => {
|
|
33
|
-
return [taskId, channel, await this.serde.parse(value)];
|
|
34
|
-
}));
|
|
35
|
-
const parentConfig = parentCheckpointId !== undefined
|
|
36
|
-
? {
|
|
37
|
-
configurable: {
|
|
38
|
-
thread_id,
|
|
39
|
-
checkpoint_ns,
|
|
40
|
-
checkpoint_id,
|
|
41
|
-
},
|
|
42
|
-
}
|
|
43
|
-
: undefined;
|
|
44
|
-
return {
|
|
45
|
-
config,
|
|
46
|
-
checkpoint: (await this.serde.parse(checkpoint)),
|
|
47
|
-
metadata: (await this.serde.parse(metadata)),
|
|
48
|
-
pendingWrites,
|
|
49
|
-
parentConfig,
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
else {
|
|
54
|
-
const checkpoints = this.storage[thread_id]?.[checkpoint_ns];
|
|
55
|
-
if (checkpoints !== undefined) {
|
|
56
|
-
const maxThreadTs = Object.keys(checkpoints).sort((a, b) => b.localeCompare(a))[0];
|
|
57
|
-
const saved = checkpoints[maxThreadTs];
|
|
58
|
-
const [checkpoint, metadata, parentCheckpointId] = saved;
|
|
59
|
-
const writes = this.writes[_generateKey(thread_id, checkpoint_ns, checkpoint_id)] ??
|
|
60
|
-
[];
|
|
61
|
-
const pendingWrites = await Promise.all(writes.map(async ([taskId, channel, value]) => {
|
|
62
|
-
return [taskId, channel, await this.serde.parse(value)];
|
|
63
|
-
}));
|
|
64
|
-
const parentConfig = parentCheckpointId !== undefined
|
|
65
|
-
? {
|
|
66
|
-
configurable: {
|
|
67
|
-
thread_id,
|
|
68
|
-
checkpoint_ns,
|
|
69
|
-
checkpoint_id: parentCheckpointId,
|
|
70
|
-
},
|
|
71
|
-
}
|
|
72
|
-
: undefined;
|
|
73
|
-
return {
|
|
74
|
-
config: {
|
|
75
|
-
configurable: {
|
|
76
|
-
thread_id,
|
|
77
|
-
checkpoint_id: maxThreadTs,
|
|
78
|
-
checkpoint_ns,
|
|
79
|
-
},
|
|
80
|
-
},
|
|
81
|
-
checkpoint: (await this.serde.parse(checkpoint)),
|
|
82
|
-
metadata: (await this.serde.parse(metadata)),
|
|
83
|
-
pendingWrites,
|
|
84
|
-
parentConfig,
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
return undefined;
|
|
89
|
-
}
|
|
90
|
-
async *list(config, options) {
|
|
91
|
-
// eslint-disable-next-line prefer-const
|
|
92
|
-
let { before, limit } = options ?? {};
|
|
93
|
-
const threadIds = config.configurable?.thread_id
|
|
94
|
-
? [config.configurable?.thread_id]
|
|
95
|
-
: Object.keys(this.storage);
|
|
96
|
-
const checkpointNamespace = config.configurable?.checkpoint_ns ?? "";
|
|
97
|
-
for (const threadId of threadIds) {
|
|
98
|
-
const checkpoints = this.storage[threadId]?.[checkpointNamespace] ?? {};
|
|
99
|
-
const sortedCheckpoints = Object.entries(checkpoints).sort((a, b) => b[0].localeCompare(a[0]));
|
|
100
|
-
for (const [checkpointId, [checkpoint, metadataStr, parentCheckpointId],] of sortedCheckpoints) {
|
|
101
|
-
// Filter by checkpoint ID
|
|
102
|
-
if (before &&
|
|
103
|
-
before.configurable?.checkpoint_id &&
|
|
104
|
-
checkpointId >= before.configurable.checkpoint_id) {
|
|
105
|
-
continue;
|
|
106
|
-
}
|
|
107
|
-
// Parse metadata
|
|
108
|
-
const metadata = (await this.serde.parse(metadataStr));
|
|
109
|
-
// Limit search results
|
|
110
|
-
if (limit !== undefined) {
|
|
111
|
-
if (limit <= 0)
|
|
112
|
-
break;
|
|
113
|
-
// eslint-disable-next-line no-param-reassign
|
|
114
|
-
limit -= 1;
|
|
115
|
-
}
|
|
116
|
-
const writes = this.writes[_generateKey(threadId, checkpointNamespace, checkpointId)] ?? [];
|
|
117
|
-
const pendingWrites = await Promise.all(writes.map(async ([taskId, channel, value]) => {
|
|
118
|
-
return [taskId, channel, await this.serde.parse(value)];
|
|
119
|
-
}));
|
|
120
|
-
yield {
|
|
121
|
-
config: {
|
|
122
|
-
configurable: {
|
|
123
|
-
thread_id: threadId,
|
|
124
|
-
checkpoint_ns: checkpointNamespace,
|
|
125
|
-
checkpoint_id: checkpointId,
|
|
126
|
-
},
|
|
127
|
-
},
|
|
128
|
-
checkpoint: (await this.serde.parse(checkpoint)),
|
|
129
|
-
metadata,
|
|
130
|
-
pendingWrites,
|
|
131
|
-
parentConfig: parentCheckpointId
|
|
132
|
-
? {
|
|
133
|
-
configurable: {
|
|
134
|
-
thread_id: threadId,
|
|
135
|
-
checkpoint_ns: checkpointNamespace,
|
|
136
|
-
checkpoint_id: parentCheckpointId,
|
|
137
|
-
},
|
|
138
|
-
}
|
|
139
|
-
: undefined,
|
|
140
|
-
};
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
async put(config, checkpoint, metadata) {
|
|
145
|
-
const threadId = config.configurable?.thread_id;
|
|
146
|
-
const checkpointNamespace = config.configurable?.checkpoint_ns;
|
|
147
|
-
if (threadId === undefined) {
|
|
148
|
-
throw new Error(`Failed to put checkpoint. The passed RunnableConfig is missing a required "thread_id" field in its "configurable" property.`);
|
|
149
|
-
}
|
|
150
|
-
if (checkpointNamespace === undefined) {
|
|
151
|
-
throw new Error(`Failed to put checkpoint. The passed RunnableConfig is missing a required "checkpoint_ns" field in its "configurable" property.`);
|
|
152
|
-
}
|
|
153
|
-
if (!this.storage[threadId]) {
|
|
154
|
-
this.storage[threadId] = {};
|
|
155
|
-
}
|
|
156
|
-
if (!this.storage[threadId][checkpointNamespace]) {
|
|
157
|
-
this.storage[threadId][checkpointNamespace] = {};
|
|
158
|
-
}
|
|
159
|
-
this.storage[threadId][checkpointNamespace][checkpoint.id] = [
|
|
160
|
-
this.serde.stringify(checkpoint),
|
|
161
|
-
this.serde.stringify(metadata),
|
|
162
|
-
config.configurable?.checkpoint_id, // parent
|
|
163
|
-
];
|
|
164
|
-
return {
|
|
165
|
-
configurable: {
|
|
166
|
-
thread_id: threadId,
|
|
167
|
-
checkpoint_ns: checkpointNamespace,
|
|
168
|
-
checkpoint_id: checkpoint.id,
|
|
169
|
-
},
|
|
170
|
-
};
|
|
171
|
-
}
|
|
172
|
-
async putWrites(config, writes, taskId) {
|
|
173
|
-
const threadId = config.configurable?.thread_id;
|
|
174
|
-
const checkpointNamespace = config.configurable?.checkpoint_ns;
|
|
175
|
-
const checkpointId = config.configurable?.checkpoint_id;
|
|
176
|
-
if (threadId === undefined) {
|
|
177
|
-
throw new Error(`Failed to put writes. The passed RunnableConfig is missing a required "thread_id" field in its "configurable" property`);
|
|
178
|
-
}
|
|
179
|
-
if (checkpointId === undefined) {
|
|
180
|
-
throw new Error(`Failed to put writes. The passed RunnableConfig is missing a required "checkpoint_id" field in its "configurable" property.`);
|
|
181
|
-
}
|
|
182
|
-
const key = _generateKey(threadId, checkpointNamespace, checkpointId);
|
|
183
|
-
if (this.writes[key] === undefined) {
|
|
184
|
-
this.writes[key] = [];
|
|
185
|
-
}
|
|
186
|
-
const pendingWrites = writes.map(([channel, value]) => {
|
|
187
|
-
return [taskId, channel, this.serde.stringify(value)];
|
|
188
|
-
});
|
|
189
|
-
this.writes[key].push(...pendingWrites);
|
|
190
|
-
}
|
|
191
|
-
}
|