@langchain/langgraph 0.2.62 → 0.2.63
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/README.md +14 -0
- package/dist/prebuilt/react_agent_executor.cjs +34 -13
- package/dist/prebuilt/react_agent_executor.d.ts +3 -0
- package/dist/prebuilt/react_agent_executor.js +34 -15
- package/dist/prebuilt/react_agent_executor.js.map +1 -1
- package/dist/prebuilt/tool_node.cjs +26 -4
- package/dist/prebuilt/tool_node.js +27 -5
- package/dist/prebuilt/tool_node.js.map +1 -1
- package/dist/pregel/debug.cjs +9 -7
- package/dist/pregel/debug.d.ts +10 -0
- package/dist/pregel/debug.js +2 -2
- package/dist/pregel/debug.js.map +1 -1
- package/dist/pregel/debug.test.cjs +189 -0
- package/dist/pregel/debug.test.d.ts +1 -0
- package/dist/pregel/debug.test.js +187 -0
- package/dist/pregel/debug.test.js.map +1 -0
- package/dist/pregel/io.mapCommand.test.cjs +151 -0
- package/dist/pregel/io.mapCommand.test.d.ts +1 -0
- package/dist/pregel/io.mapCommand.test.js +149 -0
- package/dist/pregel/io.mapCommand.test.js.map +1 -0
- package/dist/pregel/messages.test.cjs +351 -0
- package/dist/pregel/messages.test.d.ts +1 -0
- package/dist/pregel/messages.test.js +349 -0
- package/dist/pregel/messages.test.js.map +1 -0
- package/dist/pregel/read.cjs +1 -1
- package/dist/pregel/read.js +1 -1
- package/dist/pregel/read.js.map +1 -1
- package/dist/pregel/read.test.cjs +194 -0
- package/dist/pregel/read.test.d.ts +1 -0
- package/dist/pregel/read.test.js +192 -0
- package/dist/pregel/read.test.js.map +1 -0
- package/dist/pregel/runner.test.cjs +66 -0
- package/dist/pregel/runner.test.d.ts +1 -0
- package/dist/pregel/runner.test.js +64 -0
- package/dist/pregel/runner.test.js.map +1 -0
- package/dist/pregel/utils/config.test.cjs +214 -0
- package/dist/pregel/utils/config.test.d.ts +1 -0
- package/dist/pregel/utils/config.test.js +212 -0
- package/dist/pregel/utils/config.test.js.map +1 -0
- package/dist/pregel/utils/subgraph.test.cjs +83 -0
- package/dist/pregel/utils/subgraph.test.d.ts +1 -0
- package/dist/pregel/utils/subgraph.test.js +81 -0
- package/dist/pregel/utils/subgraph.test.js.map +1 -0
- package/dist/pregel/validate.test.cjs +220 -0
- package/dist/pregel/validate.test.d.ts +1 -0
- package/dist/pregel/validate.test.js +218 -0
- package/dist/pregel/validate.test.js.map +1 -0
- package/dist/pregel/write.test.cjs +181 -0
- package/dist/pregel/write.test.d.ts +1 -0
- package/dist/pregel/write.test.js +179 -0
- package/dist/pregel/write.test.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import { jest } from "@jest/globals";
|
|
2
|
+
import { AsyncLocalStorageProviderSingleton } from "@langchain/core/singletons";
|
|
3
|
+
import { ensureLangGraphConfig, getStore, getWriter, getConfig, recastCheckpointNamespace, getParentCheckpointNamespace, } from "./config.js";
|
|
4
|
+
import { CHECKPOINT_NAMESPACE_SEPARATOR, CHECKPOINT_NAMESPACE_END, } from "../../constants.js";
|
|
5
|
+
describe("ensureLangGraphConfig", () => {
|
|
6
|
+
// Save original to restore after tests
|
|
7
|
+
const originalGetRunnableConfig = AsyncLocalStorageProviderSingleton.getRunnableConfig;
|
|
8
|
+
beforeEach(() => {
|
|
9
|
+
// Reset the mock before each test
|
|
10
|
+
AsyncLocalStorageProviderSingleton.getRunnableConfig = jest.fn();
|
|
11
|
+
});
|
|
12
|
+
afterAll(() => {
|
|
13
|
+
// Restore the original after all tests
|
|
14
|
+
AsyncLocalStorageProviderSingleton.getRunnableConfig =
|
|
15
|
+
originalGetRunnableConfig;
|
|
16
|
+
});
|
|
17
|
+
it("should return a default config when no arguments provided", () => {
|
|
18
|
+
// Mock the AsyncLocalStorage to return undefined
|
|
19
|
+
AsyncLocalStorageProviderSingleton.getRunnableConfig = jest
|
|
20
|
+
.fn()
|
|
21
|
+
.mockReturnValue(undefined);
|
|
22
|
+
const result = ensureLangGraphConfig();
|
|
23
|
+
expect(result).toEqual({
|
|
24
|
+
tags: [],
|
|
25
|
+
metadata: {},
|
|
26
|
+
callbacks: undefined,
|
|
27
|
+
recursionLimit: 25,
|
|
28
|
+
configurable: {},
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
it("should merge multiple configs, with later configs taking precedence", () => {
|
|
32
|
+
// Mock the AsyncLocalStorage to return undefined
|
|
33
|
+
AsyncLocalStorageProviderSingleton.getRunnableConfig = jest
|
|
34
|
+
.fn()
|
|
35
|
+
.mockReturnValue(undefined);
|
|
36
|
+
const config1 = {
|
|
37
|
+
tags: ["tag1"],
|
|
38
|
+
metadata: { key1: "value1" },
|
|
39
|
+
configurable: { option1: "value1" },
|
|
40
|
+
};
|
|
41
|
+
const config2 = {
|
|
42
|
+
tags: ["tag2"],
|
|
43
|
+
metadata: { key2: "value2" },
|
|
44
|
+
configurable: { option2: "value2" },
|
|
45
|
+
};
|
|
46
|
+
const result = ensureLangGraphConfig(config1, config2);
|
|
47
|
+
// The implementation completely replaces objects rather than merging them
|
|
48
|
+
expect(result).toEqual({
|
|
49
|
+
tags: ["tag2"],
|
|
50
|
+
metadata: { key2: "value2", option2: "value2" },
|
|
51
|
+
callbacks: undefined,
|
|
52
|
+
recursionLimit: 25,
|
|
53
|
+
configurable: { option2: "value2" },
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
it("should copy values from AsyncLocalStorage if available", () => {
|
|
57
|
+
// Mock values from AsyncLocalStorage
|
|
58
|
+
const asyncLocalStorageConfig = {
|
|
59
|
+
tags: ["storage-tag"],
|
|
60
|
+
metadata: { storage: "value" },
|
|
61
|
+
callbacks: { copy: () => ({ type: "copied-callback" }) },
|
|
62
|
+
configurable: { storageOption: "value" },
|
|
63
|
+
};
|
|
64
|
+
AsyncLocalStorageProviderSingleton.getRunnableConfig = jest
|
|
65
|
+
.fn()
|
|
66
|
+
.mockReturnValue(asyncLocalStorageConfig);
|
|
67
|
+
const result = ensureLangGraphConfig();
|
|
68
|
+
expect(result.tags).toEqual(["storage-tag"]);
|
|
69
|
+
expect(result.metadata || {}).toEqual({
|
|
70
|
+
storage: "value",
|
|
71
|
+
storageOption: "value",
|
|
72
|
+
});
|
|
73
|
+
expect(result.configurable).toEqual({ storageOption: "value" });
|
|
74
|
+
expect(result.callbacks).toEqual({ type: "copied-callback" });
|
|
75
|
+
});
|
|
76
|
+
it("should handle undefined config values", () => {
|
|
77
|
+
AsyncLocalStorageProviderSingleton.getRunnableConfig = jest
|
|
78
|
+
.fn()
|
|
79
|
+
.mockReturnValue(undefined);
|
|
80
|
+
const config1 = undefined;
|
|
81
|
+
const config2 = {
|
|
82
|
+
tags: ["tag2"],
|
|
83
|
+
metadata: undefined,
|
|
84
|
+
};
|
|
85
|
+
const result = ensureLangGraphConfig(config1, config2);
|
|
86
|
+
expect(result.tags).toEqual(["tag2"]);
|
|
87
|
+
expect(result.metadata).toEqual({});
|
|
88
|
+
});
|
|
89
|
+
it("should copy scalar values to metadata from configurable", () => {
|
|
90
|
+
AsyncLocalStorageProviderSingleton.getRunnableConfig = jest
|
|
91
|
+
.fn()
|
|
92
|
+
.mockReturnValue(undefined);
|
|
93
|
+
const config = {
|
|
94
|
+
configurable: {
|
|
95
|
+
stringValue: "string",
|
|
96
|
+
numberValue: 42,
|
|
97
|
+
booleanValue: true,
|
|
98
|
+
objectValue: { should: "not be copied" },
|
|
99
|
+
__privateValue: "should not be copied",
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
const result = ensureLangGraphConfig(config);
|
|
103
|
+
expect(result.metadata).toEqual({
|
|
104
|
+
stringValue: "string",
|
|
105
|
+
numberValue: 42,
|
|
106
|
+
booleanValue: true,
|
|
107
|
+
// objectValue and __privateValue should not be copied
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
it("should not overwrite existing metadata values with configurable values", () => {
|
|
111
|
+
AsyncLocalStorageProviderSingleton.getRunnableConfig = jest
|
|
112
|
+
.fn()
|
|
113
|
+
.mockReturnValue(undefined);
|
|
114
|
+
const config = {
|
|
115
|
+
metadata: { key: "original value" },
|
|
116
|
+
configurable: {
|
|
117
|
+
key: "should not overwrite",
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
const result = ensureLangGraphConfig(config);
|
|
121
|
+
expect(result.metadata?.key).toEqual("original value");
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
describe("getStore, getWriter, getConfig", () => {
|
|
125
|
+
// Save original to restore after tests
|
|
126
|
+
const originalGetRunnableConfig = AsyncLocalStorageProviderSingleton.getRunnableConfig;
|
|
127
|
+
beforeEach(() => {
|
|
128
|
+
// Reset the mock before each test
|
|
129
|
+
AsyncLocalStorageProviderSingleton.getRunnableConfig = jest.fn();
|
|
130
|
+
});
|
|
131
|
+
afterAll(() => {
|
|
132
|
+
// Restore the original after all tests
|
|
133
|
+
AsyncLocalStorageProviderSingleton.getRunnableConfig =
|
|
134
|
+
originalGetRunnableConfig;
|
|
135
|
+
});
|
|
136
|
+
it("getStore should return store from config", () => {
|
|
137
|
+
const mockStore = {};
|
|
138
|
+
AsyncLocalStorageProviderSingleton.getRunnableConfig = jest
|
|
139
|
+
.fn()
|
|
140
|
+
.mockReturnValue({
|
|
141
|
+
store: mockStore,
|
|
142
|
+
});
|
|
143
|
+
const result = getStore();
|
|
144
|
+
expect(result).toBe(mockStore);
|
|
145
|
+
});
|
|
146
|
+
it("getWriter should return writer from configurable", () => {
|
|
147
|
+
const mockWriter = () => { };
|
|
148
|
+
AsyncLocalStorageProviderSingleton.getRunnableConfig = jest
|
|
149
|
+
.fn()
|
|
150
|
+
.mockReturnValue({
|
|
151
|
+
configurable: {
|
|
152
|
+
writer: mockWriter,
|
|
153
|
+
},
|
|
154
|
+
});
|
|
155
|
+
const result = getWriter();
|
|
156
|
+
expect(result).toBe(mockWriter);
|
|
157
|
+
});
|
|
158
|
+
it("getConfig should return the full config", () => {
|
|
159
|
+
const mockConfig = { key: "value" };
|
|
160
|
+
AsyncLocalStorageProviderSingleton.getRunnableConfig = jest
|
|
161
|
+
.fn()
|
|
162
|
+
.mockReturnValue(mockConfig);
|
|
163
|
+
const result = getConfig();
|
|
164
|
+
expect(result).toBe(mockConfig);
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
describe("recastCheckpointNamespace", () => {
|
|
168
|
+
it("should filter out numeric parts of the namespace", () => {
|
|
169
|
+
const namespace = `parent${CHECKPOINT_NAMESPACE_SEPARATOR}123${CHECKPOINT_NAMESPACE_SEPARATOR}child`;
|
|
170
|
+
const result = recastCheckpointNamespace(namespace);
|
|
171
|
+
expect(result).toBe(`parent${CHECKPOINT_NAMESPACE_SEPARATOR}child`);
|
|
172
|
+
});
|
|
173
|
+
it("should remove parts after CHECKPOINT_NAMESPACE_END", () => {
|
|
174
|
+
const namespace = `part1${CHECKPOINT_NAMESPACE_SEPARATOR}part2${CHECKPOINT_NAMESPACE_END}extra`;
|
|
175
|
+
const result = recastCheckpointNamespace(namespace);
|
|
176
|
+
expect(result).toBe(`part1${CHECKPOINT_NAMESPACE_SEPARATOR}part2`);
|
|
177
|
+
});
|
|
178
|
+
it("should handle complex namespace with numeric parts and CHECKPOINT_NAMESPACE_END", () => {
|
|
179
|
+
const namespace = `root${CHECKPOINT_NAMESPACE_SEPARATOR}123${CHECKPOINT_NAMESPACE_SEPARATOR}child${CHECKPOINT_NAMESPACE_END}extra${CHECKPOINT_NAMESPACE_SEPARATOR}456`;
|
|
180
|
+
const result = recastCheckpointNamespace(namespace);
|
|
181
|
+
expect(result).toBe(`root${CHECKPOINT_NAMESPACE_SEPARATOR}child`);
|
|
182
|
+
});
|
|
183
|
+
it("should return the original namespace when no filtering needed", () => {
|
|
184
|
+
const namespace = `part1${CHECKPOINT_NAMESPACE_SEPARATOR}part2`;
|
|
185
|
+
const result = recastCheckpointNamespace(namespace);
|
|
186
|
+
expect(result).toBe(namespace);
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
describe("getParentCheckpointNamespace", () => {
|
|
190
|
+
it("should return the parent namespace by removing the last part", () => {
|
|
191
|
+
const namespace = `parent${CHECKPOINT_NAMESPACE_SEPARATOR}child`;
|
|
192
|
+
const result = getParentCheckpointNamespace(namespace);
|
|
193
|
+
expect(result).toBe("parent");
|
|
194
|
+
});
|
|
195
|
+
it("should skip trailing numeric parts", () => {
|
|
196
|
+
const namespace = `parent${CHECKPOINT_NAMESPACE_SEPARATOR}child${CHECKPOINT_NAMESPACE_SEPARATOR}123${CHECKPOINT_NAMESPACE_SEPARATOR}456`;
|
|
197
|
+
const result = getParentCheckpointNamespace(namespace);
|
|
198
|
+
expect(result).toBe("parent");
|
|
199
|
+
});
|
|
200
|
+
it("should return empty string for top-level namespace", () => {
|
|
201
|
+
const namespace = "singlePart";
|
|
202
|
+
const result = getParentCheckpointNamespace(namespace);
|
|
203
|
+
expect(result).toBe("");
|
|
204
|
+
});
|
|
205
|
+
it("should handle namespace with mixed numeric and non-numeric parts", () => {
|
|
206
|
+
const namespace = `root${CHECKPOINT_NAMESPACE_SEPARATOR}sub1${CHECKPOINT_NAMESPACE_SEPARATOR}123${CHECKPOINT_NAMESPACE_SEPARATOR}sub2`;
|
|
207
|
+
const result = getParentCheckpointNamespace(namespace);
|
|
208
|
+
// The implementation stops at the first numeric part, not at the last non-numeric part
|
|
209
|
+
expect(result).toBe(`root${CHECKPOINT_NAMESPACE_SEPARATOR}sub1${CHECKPOINT_NAMESPACE_SEPARATOR}123`);
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
//# sourceMappingURL=config.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.test.js","sourceRoot":"","sources":["../../../src/pregel/utils/config.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const globals_1 = require("@jest/globals");
|
|
4
|
+
const subgraph_js_1 = require("./subgraph.cjs");
|
|
5
|
+
(0, globals_1.describe)("isPregelLike", () => {
|
|
6
|
+
(0, globals_1.it)("should return true for objects with lg_is_pregel=true", () => {
|
|
7
|
+
const mockPregelObj = {
|
|
8
|
+
lg_is_pregel: true,
|
|
9
|
+
invoke: () => { },
|
|
10
|
+
someOtherProp: "value",
|
|
11
|
+
};
|
|
12
|
+
// Cast to any to test just the logic, not the type constraints
|
|
13
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
14
|
+
(0, globals_1.expect)((0, subgraph_js_1.isPregelLike)(mockPregelObj)).toBe(true);
|
|
15
|
+
});
|
|
16
|
+
(0, globals_1.it)("should return false for objects without lg_is_pregel property", () => {
|
|
17
|
+
const nonPregelObj = {
|
|
18
|
+
invoke: () => { },
|
|
19
|
+
someOtherProp: "value",
|
|
20
|
+
};
|
|
21
|
+
// Cast to any to test just the logic, not the type constraints
|
|
22
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
23
|
+
(0, globals_1.expect)((0, subgraph_js_1.isPregelLike)(nonPregelObj)).toBe(false);
|
|
24
|
+
});
|
|
25
|
+
(0, globals_1.it)("should return false for objects with lg_is_pregel=false", () => {
|
|
26
|
+
const nonPregelObj = {
|
|
27
|
+
lg_is_pregel: false,
|
|
28
|
+
invoke: () => { },
|
|
29
|
+
someOtherProp: "value",
|
|
30
|
+
};
|
|
31
|
+
// Cast to any to test just the logic, not the type constraints
|
|
32
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
33
|
+
(0, globals_1.expect)((0, subgraph_js_1.isPregelLike)(nonPregelObj)).toBe(false);
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
(0, globals_1.describe)("findSubgraphPregel", () => {
|
|
37
|
+
(0, globals_1.it)("should find Pregel object at the top level", () => {
|
|
38
|
+
const mockPregelObj = {
|
|
39
|
+
lg_is_pregel: true,
|
|
40
|
+
invoke: () => { },
|
|
41
|
+
someOtherProp: "value",
|
|
42
|
+
};
|
|
43
|
+
// Cast to Runnable to test the behavior
|
|
44
|
+
(0, globals_1.expect)((0, subgraph_js_1.findSubgraphPregel)(mockPregelObj)).toBe(mockPregelObj);
|
|
45
|
+
});
|
|
46
|
+
(0, globals_1.it)("should find Pregel object in a RunnableSequence", () => {
|
|
47
|
+
const mockPregelObj = {
|
|
48
|
+
lg_is_pregel: true,
|
|
49
|
+
invoke: () => { },
|
|
50
|
+
someOtherProp: "value",
|
|
51
|
+
};
|
|
52
|
+
const mockSequence = {
|
|
53
|
+
steps: [{ someProperty: "value", invoke: () => { } }, mockPregelObj],
|
|
54
|
+
};
|
|
55
|
+
(0, globals_1.expect)((0, subgraph_js_1.findSubgraphPregel)(mockSequence)).toBe(mockPregelObj);
|
|
56
|
+
});
|
|
57
|
+
(0, globals_1.it)("should find Pregel object in a nested RunnableSequence", () => {
|
|
58
|
+
const mockPregelObj = {
|
|
59
|
+
lg_is_pregel: true,
|
|
60
|
+
invoke: () => { },
|
|
61
|
+
someOtherProp: "value",
|
|
62
|
+
};
|
|
63
|
+
const innerSequence = {
|
|
64
|
+
steps: [{ someProperty: "value", invoke: () => { } }, mockPregelObj],
|
|
65
|
+
};
|
|
66
|
+
const outerSequence = {
|
|
67
|
+
steps: [{ someProperty: "otherValue", invoke: () => { } }, innerSequence],
|
|
68
|
+
};
|
|
69
|
+
(0, globals_1.expect)((0, subgraph_js_1.findSubgraphPregel)(outerSequence)).toBe(mockPregelObj);
|
|
70
|
+
});
|
|
71
|
+
(0, globals_1.it)("should return undefined if no Pregel object is found", () => {
|
|
72
|
+
const nonPregelRunnable = {
|
|
73
|
+
someProperty: "value",
|
|
74
|
+
invoke: () => { },
|
|
75
|
+
};
|
|
76
|
+
const sequence = {
|
|
77
|
+
steps: [{ someProperty: "value1" }, { someProperty: "value2" }],
|
|
78
|
+
};
|
|
79
|
+
(0, globals_1.expect)((0, subgraph_js_1.findSubgraphPregel)(nonPregelRunnable)).toBeUndefined();
|
|
80
|
+
(0, globals_1.expect)((0, subgraph_js_1.findSubgraphPregel)(sequence)).toBeUndefined();
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
//# sourceMappingURL=subgraph.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { describe, expect, it } from "@jest/globals";
|
|
2
|
+
import { isPregelLike, findSubgraphPregel } from "./subgraph.js";
|
|
3
|
+
describe("isPregelLike", () => {
|
|
4
|
+
it("should return true for objects with lg_is_pregel=true", () => {
|
|
5
|
+
const mockPregelObj = {
|
|
6
|
+
lg_is_pregel: true,
|
|
7
|
+
invoke: () => { },
|
|
8
|
+
someOtherProp: "value",
|
|
9
|
+
};
|
|
10
|
+
// Cast to any to test just the logic, not the type constraints
|
|
11
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
12
|
+
expect(isPregelLike(mockPregelObj)).toBe(true);
|
|
13
|
+
});
|
|
14
|
+
it("should return false for objects without lg_is_pregel property", () => {
|
|
15
|
+
const nonPregelObj = {
|
|
16
|
+
invoke: () => { },
|
|
17
|
+
someOtherProp: "value",
|
|
18
|
+
};
|
|
19
|
+
// Cast to any to test just the logic, not the type constraints
|
|
20
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
21
|
+
expect(isPregelLike(nonPregelObj)).toBe(false);
|
|
22
|
+
});
|
|
23
|
+
it("should return false for objects with lg_is_pregel=false", () => {
|
|
24
|
+
const nonPregelObj = {
|
|
25
|
+
lg_is_pregel: false,
|
|
26
|
+
invoke: () => { },
|
|
27
|
+
someOtherProp: "value",
|
|
28
|
+
};
|
|
29
|
+
// Cast to any to test just the logic, not the type constraints
|
|
30
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
31
|
+
expect(isPregelLike(nonPregelObj)).toBe(false);
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
describe("findSubgraphPregel", () => {
|
|
35
|
+
it("should find Pregel object at the top level", () => {
|
|
36
|
+
const mockPregelObj = {
|
|
37
|
+
lg_is_pregel: true,
|
|
38
|
+
invoke: () => { },
|
|
39
|
+
someOtherProp: "value",
|
|
40
|
+
};
|
|
41
|
+
// Cast to Runnable to test the behavior
|
|
42
|
+
expect(findSubgraphPregel(mockPregelObj)).toBe(mockPregelObj);
|
|
43
|
+
});
|
|
44
|
+
it("should find Pregel object in a RunnableSequence", () => {
|
|
45
|
+
const mockPregelObj = {
|
|
46
|
+
lg_is_pregel: true,
|
|
47
|
+
invoke: () => { },
|
|
48
|
+
someOtherProp: "value",
|
|
49
|
+
};
|
|
50
|
+
const mockSequence = {
|
|
51
|
+
steps: [{ someProperty: "value", invoke: () => { } }, mockPregelObj],
|
|
52
|
+
};
|
|
53
|
+
expect(findSubgraphPregel(mockSequence)).toBe(mockPregelObj);
|
|
54
|
+
});
|
|
55
|
+
it("should find Pregel object in a nested RunnableSequence", () => {
|
|
56
|
+
const mockPregelObj = {
|
|
57
|
+
lg_is_pregel: true,
|
|
58
|
+
invoke: () => { },
|
|
59
|
+
someOtherProp: "value",
|
|
60
|
+
};
|
|
61
|
+
const innerSequence = {
|
|
62
|
+
steps: [{ someProperty: "value", invoke: () => { } }, mockPregelObj],
|
|
63
|
+
};
|
|
64
|
+
const outerSequence = {
|
|
65
|
+
steps: [{ someProperty: "otherValue", invoke: () => { } }, innerSequence],
|
|
66
|
+
};
|
|
67
|
+
expect(findSubgraphPregel(outerSequence)).toBe(mockPregelObj);
|
|
68
|
+
});
|
|
69
|
+
it("should return undefined if no Pregel object is found", () => {
|
|
70
|
+
const nonPregelRunnable = {
|
|
71
|
+
someProperty: "value",
|
|
72
|
+
invoke: () => { },
|
|
73
|
+
};
|
|
74
|
+
const sequence = {
|
|
75
|
+
steps: [{ someProperty: "value1" }, { someProperty: "value2" }],
|
|
76
|
+
};
|
|
77
|
+
expect(findSubgraphPregel(nonPregelRunnable)).toBeUndefined();
|
|
78
|
+
expect(findSubgraphPregel(sequence)).toBeUndefined();
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
//# sourceMappingURL=subgraph.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subgraph.test.js","sourceRoot":"","sources":["../../../src/pregel/utils/subgraph.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const globals_1 = require("@jest/globals");
|
|
4
|
+
const validate_js_1 = require("./validate.cjs");
|
|
5
|
+
const read_js_1 = require("./read.cjs");
|
|
6
|
+
const constants_js_1 = require("../constants.cjs");
|
|
7
|
+
const last_value_js_1 = require("../channels/last_value.cjs");
|
|
8
|
+
// Common test setup
|
|
9
|
+
const setupValidGraph = () => {
|
|
10
|
+
// Create test channels
|
|
11
|
+
const inputChannel = new last_value_js_1.LastValue();
|
|
12
|
+
const outputChannel = new last_value_js_1.LastValue();
|
|
13
|
+
// Create test nodes
|
|
14
|
+
const testNode = new read_js_1.PregelNode({
|
|
15
|
+
channels: {},
|
|
16
|
+
triggers: ["input"],
|
|
17
|
+
});
|
|
18
|
+
return {
|
|
19
|
+
nodes: { testNode },
|
|
20
|
+
channels: {
|
|
21
|
+
input: inputChannel,
|
|
22
|
+
output: outputChannel,
|
|
23
|
+
},
|
|
24
|
+
inputChannels: "input",
|
|
25
|
+
outputChannels: "output",
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
(0, globals_1.describe)("GraphValidationError", () => {
|
|
29
|
+
(0, globals_1.it)("should be properly constructed with the right name", () => {
|
|
30
|
+
const error = new validate_js_1.GraphValidationError("Test error message");
|
|
31
|
+
(0, globals_1.expect)(error).toBeInstanceOf(Error);
|
|
32
|
+
(0, globals_1.expect)(error.name).toBe("GraphValidationError");
|
|
33
|
+
(0, globals_1.expect)(error.message).toBe("Test error message");
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
(0, globals_1.describe)("validateGraph", () => {
|
|
37
|
+
(0, globals_1.it)("should validate a correct graph without errors", () => {
|
|
38
|
+
const { nodes, channels, inputChannels, outputChannels } = setupValidGraph();
|
|
39
|
+
// Act & Assert: Should not throw
|
|
40
|
+
(0, globals_1.expect)(() => (0, validate_js_1.validateGraph)({
|
|
41
|
+
nodes,
|
|
42
|
+
channels,
|
|
43
|
+
inputChannels,
|
|
44
|
+
outputChannels,
|
|
45
|
+
})).not.toThrow();
|
|
46
|
+
});
|
|
47
|
+
(0, globals_1.it)("should throw when channels are not provided", () => {
|
|
48
|
+
const { nodes, inputChannels, outputChannels } = setupValidGraph();
|
|
49
|
+
// Act & Assert: Should throw with specific message
|
|
50
|
+
(0, globals_1.expect)(() => (0, validate_js_1.validateGraph)({
|
|
51
|
+
nodes,
|
|
52
|
+
channels: null,
|
|
53
|
+
inputChannels,
|
|
54
|
+
outputChannels,
|
|
55
|
+
})).toThrow("Channels not provided");
|
|
56
|
+
});
|
|
57
|
+
(0, globals_1.it)("should throw when a node is named INTERRUPT", () => {
|
|
58
|
+
const { channels, inputChannels, outputChannels } = setupValidGraph();
|
|
59
|
+
// Create a node with the reserved name
|
|
60
|
+
const badNode = new read_js_1.PregelNode({
|
|
61
|
+
channels: {},
|
|
62
|
+
triggers: ["input"],
|
|
63
|
+
});
|
|
64
|
+
// Create nodes object with the reserved name
|
|
65
|
+
const nodes = { [constants_js_1.INTERRUPT]: badNode };
|
|
66
|
+
// Act & Assert: Should throw specific error
|
|
67
|
+
(0, globals_1.expect)(() => (0, validate_js_1.validateGraph)({
|
|
68
|
+
nodes,
|
|
69
|
+
channels,
|
|
70
|
+
inputChannels,
|
|
71
|
+
outputChannels,
|
|
72
|
+
})).toThrow(`"Node name ${constants_js_1.INTERRUPT} is reserved"`);
|
|
73
|
+
});
|
|
74
|
+
(0, globals_1.it)("should throw when a node is not a PregelNode instance", () => {
|
|
75
|
+
const { channels, inputChannels, outputChannels } = setupValidGraph();
|
|
76
|
+
// Create an invalid node (not a PregelNode)
|
|
77
|
+
const badNode = {
|
|
78
|
+
triggers: ["input"],
|
|
79
|
+
func: () => "not a pregel node",
|
|
80
|
+
};
|
|
81
|
+
// Create nodes object with invalid node
|
|
82
|
+
const nodes = {
|
|
83
|
+
badNode: badNode,
|
|
84
|
+
};
|
|
85
|
+
// Act & Assert: Should throw specific error
|
|
86
|
+
(0, globals_1.expect)(() => (0, validate_js_1.validateGraph)({
|
|
87
|
+
nodes,
|
|
88
|
+
channels,
|
|
89
|
+
inputChannels,
|
|
90
|
+
outputChannels,
|
|
91
|
+
})).toThrow("Invalid node type object, expected PregelNode");
|
|
92
|
+
});
|
|
93
|
+
(0, globals_1.it)("should throw when a subscribed channel is not in channels", () => {
|
|
94
|
+
const { channels, inputChannels, outputChannels } = setupValidGraph();
|
|
95
|
+
// Create a node that subscribes to a non-existent channel
|
|
96
|
+
const badNode = new read_js_1.PregelNode({
|
|
97
|
+
channels: {},
|
|
98
|
+
triggers: ["nonexistent"],
|
|
99
|
+
});
|
|
100
|
+
const nodes = { badNode };
|
|
101
|
+
// Act & Assert: Should throw specific error
|
|
102
|
+
(0, globals_1.expect)(() => (0, validate_js_1.validateGraph)({
|
|
103
|
+
nodes,
|
|
104
|
+
channels,
|
|
105
|
+
inputChannels,
|
|
106
|
+
outputChannels,
|
|
107
|
+
})).toThrow("Subcribed channel 'nonexistent' not in channels");
|
|
108
|
+
});
|
|
109
|
+
(0, globals_1.it)("should throw when a singular input channel is not subscribed by any node", () => {
|
|
110
|
+
const { nodes, channels } = setupValidGraph();
|
|
111
|
+
// Act & Assert: Should throw specific error for an unused input
|
|
112
|
+
(0, globals_1.expect)(() => (0, validate_js_1.validateGraph)({
|
|
113
|
+
nodes,
|
|
114
|
+
channels,
|
|
115
|
+
inputChannels: "output",
|
|
116
|
+
outputChannels: "output",
|
|
117
|
+
})).toThrow("Input channel output is not subscribed to by any node");
|
|
118
|
+
});
|
|
119
|
+
(0, globals_1.it)("should throw when none of the array input channels are subscribed by any node", () => {
|
|
120
|
+
const { nodes, channels } = setupValidGraph();
|
|
121
|
+
// Act & Assert: Should throw specific error for unused inputs
|
|
122
|
+
(0, globals_1.expect)(() => (0, validate_js_1.validateGraph)({
|
|
123
|
+
nodes,
|
|
124
|
+
channels,
|
|
125
|
+
inputChannels: [
|
|
126
|
+
"output",
|
|
127
|
+
"nonexistent",
|
|
128
|
+
],
|
|
129
|
+
outputChannels: "output",
|
|
130
|
+
})).toThrow("None of the input channels output,nonexistent are subscribed to by any node");
|
|
131
|
+
});
|
|
132
|
+
(0, globals_1.it)("should throw when an output channel is not in channels", () => {
|
|
133
|
+
const { nodes, channels, inputChannels } = setupValidGraph();
|
|
134
|
+
// Act & Assert: Should throw specific error
|
|
135
|
+
(0, globals_1.expect)(() => (0, validate_js_1.validateGraph)({
|
|
136
|
+
nodes,
|
|
137
|
+
channels,
|
|
138
|
+
inputChannels,
|
|
139
|
+
outputChannels: "nonexistent",
|
|
140
|
+
})).toThrow("Output channel 'nonexistent' not in channels");
|
|
141
|
+
});
|
|
142
|
+
(0, globals_1.it)("should throw when a stream channel is not in channels", () => {
|
|
143
|
+
const { nodes, channels, inputChannels, outputChannels } = setupValidGraph();
|
|
144
|
+
// Act & Assert: Should throw specific error
|
|
145
|
+
(0, globals_1.expect)(() => (0, validate_js_1.validateGraph)({
|
|
146
|
+
nodes,
|
|
147
|
+
channels,
|
|
148
|
+
inputChannels,
|
|
149
|
+
outputChannels,
|
|
150
|
+
streamChannels: "nonexistent",
|
|
151
|
+
})).toThrow("Output channel 'nonexistent' not in channels");
|
|
152
|
+
});
|
|
153
|
+
(0, globals_1.it)("should throw when an interruptAfterNode is not in nodes", () => {
|
|
154
|
+
const { nodes, channels, inputChannels, outputChannels } = setupValidGraph();
|
|
155
|
+
// Act & Assert: Should throw specific error
|
|
156
|
+
(0, globals_1.expect)(() => (0, validate_js_1.validateGraph)({
|
|
157
|
+
nodes,
|
|
158
|
+
channels,
|
|
159
|
+
inputChannels,
|
|
160
|
+
outputChannels,
|
|
161
|
+
interruptAfterNodes: [
|
|
162
|
+
"nonexistentNode",
|
|
163
|
+
],
|
|
164
|
+
})).toThrow("Node nonexistentNode not in nodes");
|
|
165
|
+
});
|
|
166
|
+
(0, globals_1.it)("should throw when an interruptBeforeNode is not in nodes", () => {
|
|
167
|
+
const { nodes, channels, inputChannels, outputChannels } = setupValidGraph();
|
|
168
|
+
// Act & Assert: Should throw specific error
|
|
169
|
+
(0, globals_1.expect)(() => (0, validate_js_1.validateGraph)({
|
|
170
|
+
nodes,
|
|
171
|
+
channels,
|
|
172
|
+
inputChannels,
|
|
173
|
+
outputChannels,
|
|
174
|
+
interruptBeforeNodes: [
|
|
175
|
+
"nonexistentNode",
|
|
176
|
+
],
|
|
177
|
+
})).toThrow("Node nonexistentNode not in nodes");
|
|
178
|
+
});
|
|
179
|
+
(0, globals_1.it)("should accept '*' as a valid value for interruptAfterNodes", () => {
|
|
180
|
+
const { nodes, channels, inputChannels, outputChannels } = setupValidGraph();
|
|
181
|
+
// Act & Assert: Should not throw
|
|
182
|
+
(0, globals_1.expect)(() => (0, validate_js_1.validateGraph)({
|
|
183
|
+
nodes,
|
|
184
|
+
channels,
|
|
185
|
+
inputChannels,
|
|
186
|
+
outputChannels,
|
|
187
|
+
interruptAfterNodes: "*",
|
|
188
|
+
})).not.toThrow();
|
|
189
|
+
});
|
|
190
|
+
(0, globals_1.it)("should accept '*' as a valid value for interruptBeforeNodes", () => {
|
|
191
|
+
const { nodes, channels, inputChannels, outputChannels } = setupValidGraph();
|
|
192
|
+
// Act & Assert: Should not throw
|
|
193
|
+
(0, globals_1.expect)(() => (0, validate_js_1.validateGraph)({
|
|
194
|
+
nodes,
|
|
195
|
+
channels,
|
|
196
|
+
inputChannels,
|
|
197
|
+
outputChannels,
|
|
198
|
+
interruptBeforeNodes: "*",
|
|
199
|
+
})).not.toThrow();
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
(0, globals_1.describe)("validateKeys", () => {
|
|
203
|
+
(0, globals_1.it)("should validate keys that exist in channels", () => {
|
|
204
|
+
const { channels } = setupValidGraph();
|
|
205
|
+
// Act & Assert: Should not throw for valid keys
|
|
206
|
+
(0, globals_1.expect)(() => (0, validate_js_1.validateKeys)("input", channels)).not.toThrow();
|
|
207
|
+
(0, globals_1.expect)(() => (0, validate_js_1.validateKeys)(["input", "output"], channels)).not.toThrow();
|
|
208
|
+
});
|
|
209
|
+
(0, globals_1.it)("should throw when a single key doesn't exist in channels", () => {
|
|
210
|
+
const { channels } = setupValidGraph();
|
|
211
|
+
// Act & Assert: Should throw with specific message
|
|
212
|
+
(0, globals_1.expect)(() => (0, validate_js_1.validateKeys)("nonexistent", channels)).toThrow("Key nonexistent not found in channels");
|
|
213
|
+
});
|
|
214
|
+
(0, globals_1.it)("should throw when any key in an array doesn't exist in channels", () => {
|
|
215
|
+
const { channels } = setupValidGraph();
|
|
216
|
+
// Act & Assert: Should throw with specific message
|
|
217
|
+
(0, globals_1.expect)(() => (0, validate_js_1.validateKeys)(["input", "nonexistent"], channels)).toThrow("Key nonexistent not found in channels");
|
|
218
|
+
});
|
|
219
|
+
});
|
|
220
|
+
//# sourceMappingURL=validate.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|