langgraph-api 0.1.15__py3-none-any.whl → 0.1.17__py3-none-any.whl
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.
Potentially problematic release.
This version of langgraph-api might be problematic. Click here for more details.
- langgraph_api/__init__.py +1 -1
- langgraph_api/config.py +6 -0
- langgraph_api/graph.py +1 -1
- langgraph_api/js/base.py +3 -0
- langgraph_api/js/build.mts +28 -5
- langgraph_api/js/client.mts +98 -42
- langgraph_api/js/package.json +2 -2
- langgraph_api/js/remote.py +33 -14
- langgraph_api/js/src/graph.mts +0 -3
- langgraph_api/js/src/load.hooks.mjs +61 -0
- langgraph_api/js/src/parser/parser.mts +77 -51
- langgraph_api/js/src/preload.mjs +21 -0
- langgraph_api/js/tests/api.test.mts +6 -3
- langgraph_api/js/tests/auth.test.mts +1 -1
- langgraph_api/js/tests/graphs/package.json +1 -1
- langgraph_api/js/tests/graphs/yarn.lock +9 -9
- langgraph_api/js/tests/parser.test.mts +18 -18
- langgraph_api/js/tsconfig.json +15 -0
- langgraph_api/js/yarn.lock +15 -9
- langgraph_api/models/run.py +78 -22
- langgraph_api/server.py +2 -1
- langgraph_api/sse.py +1 -1
- langgraph_api/stream.py +10 -1
- {langgraph_api-0.1.15.dist-info → langgraph_api-0.1.17.dist-info}/METADATA +5 -5
- {langgraph_api-0.1.15.dist-info → langgraph_api-0.1.17.dist-info}/RECORD +30 -28
- langgraph_api/js/src/hooks.mjs +0 -17
- /langgraph_api/js/src/{schema → parser/schema}/types.mts +0 -0
- /langgraph_api/js/src/{schema → parser/schema}/types.template.mts +0 -0
- {langgraph_api-0.1.15.dist-info → langgraph_api-0.1.17.dist-info}/LICENSE +0 -0
- {langgraph_api-0.1.15.dist-info → langgraph_api-0.1.17.dist-info}/WHEEL +0 -0
- {langgraph_api-0.1.15.dist-info → langgraph_api-0.1.17.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// This module hook is used to ensure that @langchain/langgraph package
|
|
2
|
+
// is imported from a consistent location.
|
|
3
|
+
// Accepts `{ parentURL: string }` as argument when registering the hook.
|
|
4
|
+
const OVERRIDE_RESOLVE = [
|
|
5
|
+
// Override `@langchain/langgraph` or `@langchain/langgraph/prebuilt`,
|
|
6
|
+
// but not `@langchain/langgraph-sdk`
|
|
7
|
+
new RegExp(`^@langchain\/langgraph(\/.+)?$`),
|
|
8
|
+
new RegExp(`^@langchain\/langgraph-checkpoint(\/.+)?$`),
|
|
9
|
+
];
|
|
10
|
+
|
|
11
|
+
let parentURL;
|
|
12
|
+
let langgraphPackageURL;
|
|
13
|
+
|
|
14
|
+
export async function initialize(args) {
|
|
15
|
+
parentURL = args.parentURL;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export async function resolve(specifier, context, nextResolve) {
|
|
19
|
+
// HACK: @tailwindcss/node internally uses an ESM loader cache, which does not play nicely with `tsx`.
|
|
20
|
+
// Node.js crashes with "TypeError [ERR_INVALID_URL_SCHEME]: The URL must be of scheme file".
|
|
21
|
+
// As it already is a valid URI, we can just short-circuit the resolution and avoid `tsx`.
|
|
22
|
+
if (
|
|
23
|
+
specifier.includes("@tailwindcss/node/dist/esm-cache.loader") &&
|
|
24
|
+
specifier.startsWith("file://")
|
|
25
|
+
) {
|
|
26
|
+
return {
|
|
27
|
+
shortCircuit: true,
|
|
28
|
+
// Node 18.x will for some reason attempt to load `.mts` instead of `.mjs`
|
|
29
|
+
url: specifier.replace(".mts", ".mjs"),
|
|
30
|
+
format: "module",
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (specifier === "@langchain/langgraph-checkpoint") {
|
|
35
|
+
// resolve relative to @langchain/langgraph package instead
|
|
36
|
+
// This is done to avoid adding a direct dependency on @langchain/langgraph-checkpoint
|
|
37
|
+
// in project, which if not present will cause `pnpm` to not find the package.
|
|
38
|
+
if (!langgraphPackageURL) {
|
|
39
|
+
const main = await nextResolve("@langchain/langgraph", {
|
|
40
|
+
...context,
|
|
41
|
+
parentURL,
|
|
42
|
+
});
|
|
43
|
+
langgraphPackageURL = main.url.toString();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return await nextResolve(specifier, {
|
|
47
|
+
...context,
|
|
48
|
+
parentURL: langgraphPackageURL,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (OVERRIDE_RESOLVE.some((regex) => regex.test(specifier))) {
|
|
53
|
+
const resolved = await nextResolve(specifier, { ...context, parentURL });
|
|
54
|
+
|
|
55
|
+
// If @langchain/langgraph is resolved first, cache it!
|
|
56
|
+
if (specifier === "@langchain/langgraph" && !langgraphPackageURL) {
|
|
57
|
+
langgraphPackageURL = resolved.url.toString();
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return nextResolve(specifier, context);
|
|
61
|
+
}
|
|
@@ -2,9 +2,17 @@ import * as ts from "typescript";
|
|
|
2
2
|
import * as vfs from "@typescript/vfs";
|
|
3
3
|
import * as path from "node:path";
|
|
4
4
|
import dedent from "dedent";
|
|
5
|
-
import { buildGenerator } from "
|
|
5
|
+
import { buildGenerator } from "./schema/types.mjs";
|
|
6
|
+
import { fileURLToPath } from "node:url";
|
|
6
7
|
|
|
7
|
-
const __dirname = new URL(".", import.meta.url)
|
|
8
|
+
const __dirname = fileURLToPath(new URL(".", import.meta.url));
|
|
9
|
+
|
|
10
|
+
const OVERRIDE_RESOLVE = [
|
|
11
|
+
// Override `@langchain/langgraph` or `@langchain/langgraph/prebuilt`,
|
|
12
|
+
// but not `@langchain/langgraph-sdk`
|
|
13
|
+
new RegExp(`^@langchain\/langgraph(\/.+)?$`),
|
|
14
|
+
new RegExp(`^@langchain\/langgraph-checkpoint(\/.+)?$`),
|
|
15
|
+
];
|
|
8
16
|
|
|
9
17
|
const compilerOptions = {
|
|
10
18
|
noEmit: true,
|
|
@@ -27,7 +35,7 @@ export class SubgraphExtractor {
|
|
|
27
35
|
program: ts.Program,
|
|
28
36
|
sourceFile: ts.SourceFile,
|
|
29
37
|
inferFile: ts.SourceFile,
|
|
30
|
-
options?: { strict?: boolean }
|
|
38
|
+
options?: { strict?: boolean },
|
|
31
39
|
) {
|
|
32
40
|
this.program = program;
|
|
33
41
|
this.sourceFile = sourceFile;
|
|
@@ -64,7 +72,7 @@ export class SubgraphExtractor {
|
|
|
64
72
|
|
|
65
73
|
private find = (
|
|
66
74
|
root: ts.Node,
|
|
67
|
-
predicate: (node: ts.Node) => boolean
|
|
75
|
+
predicate: (node: ts.Node) => boolean,
|
|
68
76
|
): ts.Node | undefined => {
|
|
69
77
|
let result: ts.Node | undefined = undefined;
|
|
70
78
|
|
|
@@ -83,7 +91,7 @@ export class SubgraphExtractor {
|
|
|
83
91
|
|
|
84
92
|
protected findSubgraphs = (
|
|
85
93
|
node: ts.Node,
|
|
86
|
-
namespace: string[] = []
|
|
94
|
+
namespace: string[] = [],
|
|
87
95
|
): {
|
|
88
96
|
node: string;
|
|
89
97
|
namespace: string[];
|
|
@@ -95,7 +103,7 @@ export class SubgraphExtractor {
|
|
|
95
103
|
namespace: string[];
|
|
96
104
|
subgraph: { name: string; node: ts.Node };
|
|
97
105
|
}[],
|
|
98
|
-
node: ts.Node
|
|
106
|
+
node: ts.Node,
|
|
99
107
|
) => {
|
|
100
108
|
if (ts.isCallExpression(node)) {
|
|
101
109
|
const firstChild = node.getChildAt(0);
|
|
@@ -127,7 +135,7 @@ export class SubgraphExtractor {
|
|
|
127
135
|
variables = this.reduceChildren(
|
|
128
136
|
callArg,
|
|
129
137
|
this.findSubgraphIdentifiers,
|
|
130
|
-
[]
|
|
138
|
+
[],
|
|
131
139
|
);
|
|
132
140
|
} else if (ts.isIdentifier(callArg)) {
|
|
133
141
|
variables = this.findSubgraphIdentifiers([], callArg);
|
|
@@ -165,13 +173,13 @@ export class SubgraphExtractor {
|
|
|
165
173
|
type InternalFlowNode = ts.Node & { flowNode?: { node: ts.Node } };
|
|
166
174
|
const candidate = this.find(
|
|
167
175
|
node,
|
|
168
|
-
(node: any) => node && "flowNode" in node && node.flowNode
|
|
176
|
+
(node: any) => node && "flowNode" in node && node.flowNode,
|
|
169
177
|
) as InternalFlowNode | undefined;
|
|
170
178
|
|
|
171
179
|
if (
|
|
172
180
|
candidate?.flowNode &&
|
|
173
181
|
this.isGraphOrPregelType(
|
|
174
|
-
this.checker.getTypeAtLocation(candidate.flowNode.node)
|
|
182
|
+
this.checker.getTypeAtLocation(candidate.flowNode.node),
|
|
175
183
|
)
|
|
176
184
|
) {
|
|
177
185
|
subgraphs = this.findSubgraphs(candidate.flowNode.node, namespace);
|
|
@@ -183,7 +191,7 @@ export class SubgraphExtractor {
|
|
|
183
191
|
return [
|
|
184
192
|
...subgraphs,
|
|
185
193
|
...subgraphs.map(({ subgraph, node }) =>
|
|
186
|
-
this.findSubgraphs(subgraph.node, [...namespace, node])
|
|
194
|
+
this.findSubgraphs(subgraph.node, [...namespace, node]),
|
|
187
195
|
),
|
|
188
196
|
].flat();
|
|
189
197
|
}
|
|
@@ -198,7 +206,7 @@ export class SubgraphExtractor {
|
|
|
198
206
|
const targetExport = exports.find((item) => item.name === name);
|
|
199
207
|
if (!targetExport) throw new Error(`Failed to find export "${name}"`);
|
|
200
208
|
const varDecls = (targetExport.declarations ?? []).filter(
|
|
201
|
-
ts.isVariableDeclaration
|
|
209
|
+
ts.isVariableDeclaration,
|
|
202
210
|
);
|
|
203
211
|
|
|
204
212
|
return varDecls.flatMap((varDecl) => {
|
|
@@ -208,7 +216,7 @@ export class SubgraphExtractor {
|
|
|
208
216
|
};
|
|
209
217
|
|
|
210
218
|
public getAugmentedSourceFile = (
|
|
211
|
-
name: string
|
|
219
|
+
name: string,
|
|
212
220
|
): {
|
|
213
221
|
files: [filePath: string, contents: string][];
|
|
214
222
|
exports: { typeName: string; valueName: string; graphName: string }[];
|
|
@@ -237,7 +245,7 @@ export class SubgraphExtractor {
|
|
|
237
245
|
this.getText(this.sourceFile),
|
|
238
246
|
...typeExports.map(
|
|
239
247
|
({ typeName, valueName }) =>
|
|
240
|
-
`export type ${typeName} = typeof ${valueName}
|
|
248
|
+
`export type ${typeName} = typeof ${valueName}`,
|
|
241
249
|
),
|
|
242
250
|
].join("\n\n");
|
|
243
251
|
|
|
@@ -245,7 +253,7 @@ export class SubgraphExtractor {
|
|
|
245
253
|
const inferContents = [
|
|
246
254
|
...typeExports.map(
|
|
247
255
|
({ typeName }) =>
|
|
248
|
-
`import type { ${typeName}} from "./__langgraph__source.mts"
|
|
256
|
+
`import type { ${typeName}} from "./__langgraph__source.mts"`,
|
|
249
257
|
),
|
|
250
258
|
this.inferFile.getText(this.inferFile),
|
|
251
259
|
|
|
@@ -276,7 +284,7 @@ export class SubgraphExtractor {
|
|
|
276
284
|
|
|
277
285
|
protected findSubgraphIdentifiers = (
|
|
278
286
|
acc: { node: ts.Node; name: string }[],
|
|
279
|
-
node: ts.Node
|
|
287
|
+
node: ts.Node,
|
|
280
288
|
) => {
|
|
281
289
|
if (ts.isIdentifier(node)) {
|
|
282
290
|
const smb = this.checker.getSymbolAtLocation(node);
|
|
@@ -321,11 +329,12 @@ export class SubgraphExtractor {
|
|
|
321
329
|
protected reduceChildren<Acc>(
|
|
322
330
|
node: ts.Node,
|
|
323
331
|
fn: (acc: Acc, node: ts.Node) => Acc,
|
|
324
|
-
initial: Acc
|
|
332
|
+
initial: Acc,
|
|
325
333
|
): Acc {
|
|
326
334
|
let acc = initial;
|
|
327
335
|
function it(node: ts.Node) {
|
|
328
336
|
acc = fn(acc, node);
|
|
337
|
+
// @ts-expect-error
|
|
329
338
|
ts.forEachChild(node, it.bind(this));
|
|
330
339
|
}
|
|
331
340
|
|
|
@@ -341,19 +350,27 @@ export class SubgraphExtractor {
|
|
|
341
350
|
files?: [fileName: string, contents: string][];
|
|
342
351
|
},
|
|
343
352
|
name: string,
|
|
344
|
-
options?: { strict?: boolean }
|
|
353
|
+
options?: { strict?: boolean },
|
|
345
354
|
) {
|
|
346
355
|
const dirname =
|
|
347
356
|
typeof target === "string" ? path.dirname(target) : __dirname;
|
|
348
357
|
|
|
358
|
+
// This API is not well made for Windows, ensure that the paths are UNIX slashes
|
|
349
359
|
const fsMap = new Map<string, string>();
|
|
350
360
|
const system = vfs.createFSBackedSystem(fsMap, dirname, ts);
|
|
351
361
|
|
|
352
362
|
// TODO: investigate if we should create a PR in @typescript/vfs
|
|
353
363
|
const oldReadFile = system.readFile.bind(system);
|
|
354
|
-
system.readFile = (fileName) =>
|
|
364
|
+
system.readFile = (fileName) =>
|
|
365
|
+
oldReadFile(fileName) ?? "// Non-existent file";
|
|
366
|
+
|
|
367
|
+
const vfsPath = (inputPath: string) => {
|
|
368
|
+
if (process.platform === "win32") return inputPath.replace(/\\/g, "/");
|
|
369
|
+
return inputPath;
|
|
370
|
+
};
|
|
355
371
|
|
|
356
|
-
const
|
|
372
|
+
const vfsHost = vfs.createVirtualCompilerHost(system, compilerOptions, ts);
|
|
373
|
+
const host = vfsHost.compilerHost;
|
|
357
374
|
|
|
358
375
|
const targetPath =
|
|
359
376
|
typeof target === "string"
|
|
@@ -362,65 +379,71 @@ export class SubgraphExtractor {
|
|
|
362
379
|
|
|
363
380
|
const inferTemplatePath = path.resolve(
|
|
364
381
|
__dirname,
|
|
365
|
-
"
|
|
382
|
+
"./schema/types.template.mts",
|
|
366
383
|
);
|
|
367
384
|
|
|
368
385
|
if (typeof target !== "string") {
|
|
369
|
-
fsMap.set(targetPath, target.contents);
|
|
386
|
+
fsMap.set(vfsPath(targetPath), target.contents);
|
|
370
387
|
for (const [name, contents] of target.files ?? []) {
|
|
371
|
-
fsMap.set(path.resolve(dirname, name), contents);
|
|
388
|
+
fsMap.set(vfsPath(path.resolve(dirname, name)), contents);
|
|
372
389
|
}
|
|
373
390
|
}
|
|
374
391
|
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
392
|
+
const moduleCache = ts.createModuleResolutionCache(dirname, (x) => x);
|
|
393
|
+
host.resolveModuleNameLiterals = (
|
|
394
|
+
entries,
|
|
395
|
+
containingFile,
|
|
396
|
+
redirectedReference,
|
|
397
|
+
options,
|
|
398
|
+
) =>
|
|
399
|
+
entries.flatMap((entry) => {
|
|
400
|
+
const specifier = entry.text;
|
|
401
|
+
|
|
402
|
+
// Force module resolution to use @langchain/langgraph from the local project
|
|
403
|
+
// rather than from API/CLI.
|
|
404
|
+
let targetFile = containingFile;
|
|
405
|
+
if (OVERRIDE_RESOLVE.some((regex) => regex.test(specifier))) {
|
|
406
|
+
// check if we're not already importing from node_modules
|
|
407
|
+
if (!containingFile.split(path.sep).includes("node_modules")) {
|
|
408
|
+
// Doesn't matter if the file exists, only used to nudge `ts.resolveModuleName`
|
|
409
|
+
targetFile = path.resolve(dirname, "__langgraph__resolve.mts");
|
|
410
|
+
}
|
|
387
411
|
}
|
|
388
412
|
|
|
389
|
-
|
|
413
|
+
return [
|
|
390
414
|
ts.resolveModuleName(
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
host
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
};
|
|
415
|
+
specifier,
|
|
416
|
+
targetFile,
|
|
417
|
+
options,
|
|
418
|
+
host,
|
|
419
|
+
moduleCache,
|
|
420
|
+
redirectedReference,
|
|
421
|
+
),
|
|
422
|
+
];
|
|
423
|
+
});
|
|
401
424
|
|
|
402
425
|
const research = ts.createProgram({
|
|
403
426
|
rootNames: [inferTemplatePath, targetPath],
|
|
404
427
|
options: compilerOptions,
|
|
405
|
-
host
|
|
428
|
+
host,
|
|
406
429
|
});
|
|
407
430
|
|
|
408
431
|
const extractor = new SubgraphExtractor(
|
|
409
432
|
research,
|
|
410
433
|
research.getSourceFile(targetPath)!,
|
|
411
434
|
research.getSourceFile(inferTemplatePath)!,
|
|
412
|
-
options
|
|
435
|
+
options,
|
|
413
436
|
);
|
|
414
437
|
|
|
415
438
|
const { files, exports } = extractor.getAugmentedSourceFile(name);
|
|
416
439
|
for (const [name, source] of files) {
|
|
417
|
-
system.writeFile(path.resolve(dirname, name), source);
|
|
440
|
+
system.writeFile(vfsPath(path.resolve(dirname, name)), source);
|
|
418
441
|
}
|
|
419
442
|
|
|
420
443
|
const extract = ts.createProgram({
|
|
421
444
|
rootNames: [path.resolve(dirname, "./__langraph__infer.mts")],
|
|
422
445
|
options: compilerOptions,
|
|
423
|
-
host
|
|
446
|
+
host,
|
|
424
447
|
});
|
|
425
448
|
|
|
426
449
|
const schemaGenerator = buildGenerator(extract);
|
|
@@ -428,7 +451,10 @@ export class SubgraphExtractor {
|
|
|
428
451
|
try {
|
|
429
452
|
return schema?.getSchemaForSymbol(symbol) ?? undefined;
|
|
430
453
|
} catch (e) {
|
|
431
|
-
console.warn(
|
|
454
|
+
console.warn(
|
|
455
|
+
`Failed to obtain symbol "${symbol}":`,
|
|
456
|
+
(e as Error)?.message,
|
|
457
|
+
);
|
|
432
458
|
}
|
|
433
459
|
return undefined;
|
|
434
460
|
};
|
|
@@ -442,7 +468,7 @@ export class SubgraphExtractor {
|
|
|
442
468
|
state: trySymbol(schemaGenerator, `${typeName}__update`),
|
|
443
469
|
config: trySymbol(schemaGenerator, `${typeName}__config`),
|
|
444
470
|
},
|
|
445
|
-
])
|
|
471
|
+
]),
|
|
446
472
|
);
|
|
447
473
|
}
|
|
448
474
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { register } from "node:module";
|
|
2
|
+
import { pathToFileURL } from "node:url";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
|
|
5
|
+
// we only care about the payload, which contains the server definition
|
|
6
|
+
const graphs = JSON.parse(process.env.LANGSERVE_GRAPHS || "{}");
|
|
7
|
+
const cwd = process.cwd();
|
|
8
|
+
|
|
9
|
+
// find the first file, as `parentURL` needs to be a valid file URL
|
|
10
|
+
// if no graph found, just assume a dummy default file, which should
|
|
11
|
+
// be working fine as well.
|
|
12
|
+
const firstGraphFile =
|
|
13
|
+
Object.values(graphs)
|
|
14
|
+
.flatMap((i) => i.split(":").at(0))
|
|
15
|
+
.at(0) || "index.mts";
|
|
16
|
+
|
|
17
|
+
// enforce API @langchain/langgraph resolution
|
|
18
|
+
register("./load.hooks.mjs", import.meta.url, {
|
|
19
|
+
parentURL: "data:",
|
|
20
|
+
data: { parentURL: pathToFileURL(join(cwd, firstGraphFile)).toString() },
|
|
21
|
+
});
|
|
@@ -488,7 +488,7 @@ describe("runs", () => {
|
|
|
488
488
|
expect(runs.length).toBe(1);
|
|
489
489
|
});
|
|
490
490
|
|
|
491
|
-
it.concurrent("stream values", async () => {
|
|
491
|
+
it.concurrent("stream values", { retry: 3 }, async () => {
|
|
492
492
|
const assistant = await client.assistants.create({ graphId: "agent" });
|
|
493
493
|
const thread = await client.threads.create();
|
|
494
494
|
const input = {
|
|
@@ -1991,8 +1991,11 @@ it("dynamic graph", async () => {
|
|
|
1991
1991
|
|
|
1992
1992
|
it("generative ui", async () => {
|
|
1993
1993
|
const ui = await client["~ui"].getComponent("agent", "weather-component");
|
|
1994
|
-
expect(ui).
|
|
1995
|
-
`<
|
|
1994
|
+
expect(ui).toContain(
|
|
1995
|
+
`<link rel="stylesheet" href="//localhost:9123/ui/agent/entrypoint.css" />`,
|
|
1996
|
+
);
|
|
1997
|
+
expect(ui).toContain(
|
|
1998
|
+
`<script src="//localhost:9123/ui/agent/entrypoint.js" onload='__LGUI_agent.render("weather-component", "{{shadowRootId}}")'></script>`,
|
|
1996
1999
|
);
|
|
1997
2000
|
|
|
1998
2001
|
const match = /src="(?<src>[^"]+)"/.exec(ui);
|
|
@@ -458,7 +458,7 @@ it("stream run other user thread", async () => {
|
|
|
458
458
|
]);
|
|
459
459
|
});
|
|
460
460
|
|
|
461
|
-
it("cancel run other user thread", async () => {
|
|
461
|
+
it("cancel run other user thread", { retry: 3 }, async () => {
|
|
462
462
|
const owner = await createJwtClient("johndoe", ["me"]);
|
|
463
463
|
const otherUser = await createJwtClient("alice", ["me"]);
|
|
464
464
|
|
|
@@ -25,10 +25,10 @@
|
|
|
25
25
|
zod "^3.22.4"
|
|
26
26
|
zod-to-json-schema "^3.22.3"
|
|
27
27
|
|
|
28
|
-
"@langchain/langgraph-checkpoint@~0.0.
|
|
29
|
-
version "0.0.
|
|
30
|
-
resolved "https://registry.yarnpkg.com/@langchain/langgraph-checkpoint/-/langgraph-checkpoint-0.0.
|
|
31
|
-
integrity sha512-
|
|
28
|
+
"@langchain/langgraph-checkpoint@~0.0.17":
|
|
29
|
+
version "0.0.17"
|
|
30
|
+
resolved "https://registry.yarnpkg.com/@langchain/langgraph-checkpoint/-/langgraph-checkpoint-0.0.17.tgz#d0a8824eb0769567da54262adebe65db4ee6d58f"
|
|
31
|
+
integrity sha512-6b3CuVVYx+7x0uWLG+7YXz9j2iBa+tn2AXvkLxzEvaAsLE6Sij++8PPbS2BZzC+S/FPJdWsz6I5bsrqL0BYrCA==
|
|
32
32
|
dependencies:
|
|
33
33
|
uuid "^10.0.0"
|
|
34
34
|
|
|
@@ -42,12 +42,12 @@
|
|
|
42
42
|
p-retry "4"
|
|
43
43
|
uuid "^9.0.0"
|
|
44
44
|
|
|
45
|
-
"@langchain/langgraph
|
|
46
|
-
version "0.2.
|
|
47
|
-
resolved "https://registry.yarnpkg.com/@langchain/langgraph/-/langgraph-0.2.
|
|
48
|
-
integrity sha512
|
|
45
|
+
"@langchain/langgraph@0.2.65":
|
|
46
|
+
version "0.2.65"
|
|
47
|
+
resolved "https://registry.yarnpkg.com/@langchain/langgraph/-/langgraph-0.2.65.tgz#f080add1c26a3eb3744af2ef23b8b53eddbf5cb2"
|
|
48
|
+
integrity sha512-g/Xap2KSEaEBXMJXGZTh31fd0qrdfaWA1l8NJzweJg6AkvVSf+d6DmMk9DtzGW8W1H1qQ2I6FWZ3AdP61Kkaig==
|
|
49
49
|
dependencies:
|
|
50
|
-
"@langchain/langgraph-checkpoint" "~0.0.
|
|
50
|
+
"@langchain/langgraph-checkpoint" "~0.0.17"
|
|
51
51
|
"@langchain/langgraph-sdk" "~0.0.32"
|
|
52
52
|
uuid "^10.0.0"
|
|
53
53
|
zod "^3.23.8"
|
|
@@ -61,7 +61,7 @@ describe
|
|
|
61
61
|
])("%s", { timeout: 10_000 }, ([prop]) => {
|
|
62
62
|
const schemas = SubgraphExtractor.extractSchemas(
|
|
63
63
|
{ contents: `${common}\n\nexport const graph = ${prop};` },
|
|
64
|
-
"graph"
|
|
64
|
+
"graph",
|
|
65
65
|
);
|
|
66
66
|
|
|
67
67
|
expect(schemas.graph.input).toMatchObject(MessagesSchema);
|
|
@@ -114,7 +114,7 @@ describe
|
|
|
114
114
|
.compile();
|
|
115
115
|
`,
|
|
116
116
|
},
|
|
117
|
-
"graph"
|
|
117
|
+
"graph",
|
|
118
118
|
);
|
|
119
119
|
expect(schemas["graph|child"].input).toMatchObject({
|
|
120
120
|
type: "object",
|
|
@@ -233,7 +233,7 @@ describe
|
|
|
233
233
|
.compile();
|
|
234
234
|
`,
|
|
235
235
|
},
|
|
236
|
-
"parent"
|
|
236
|
+
"parent",
|
|
237
237
|
);
|
|
238
238
|
|
|
239
239
|
expect(Object.keys(schemas)).toEqual(
|
|
@@ -241,7 +241,7 @@ describe
|
|
|
241
241
|
"parent",
|
|
242
242
|
"parent|parent_two",
|
|
243
243
|
"parent|parent_two|child_two",
|
|
244
|
-
])
|
|
244
|
+
]),
|
|
245
245
|
);
|
|
246
246
|
|
|
247
247
|
expect(schemas.parent.state).toMatchObject({
|
|
@@ -362,12 +362,12 @@ describe
|
|
|
362
362
|
`,
|
|
363
363
|
},
|
|
364
364
|
"parent",
|
|
365
|
-
{ strict: true }
|
|
365
|
+
{ strict: true },
|
|
366
366
|
);
|
|
367
367
|
}).toThrowError(
|
|
368
|
-
`Multiple unique subgraph invocations found for "parent|parent_one"
|
|
368
|
+
`Multiple unique subgraph invocations found for "parent|parent_one"`,
|
|
369
369
|
);
|
|
370
|
-
}
|
|
370
|
+
},
|
|
371
371
|
);
|
|
372
372
|
|
|
373
373
|
test.concurrent("imported subgraphs", { timeout: 10_000 }, () => {
|
|
@@ -425,11 +425,11 @@ describe
|
|
|
425
425
|
],
|
|
426
426
|
],
|
|
427
427
|
},
|
|
428
|
-
"graph"
|
|
428
|
+
"graph",
|
|
429
429
|
);
|
|
430
430
|
|
|
431
431
|
expect(Object.keys(schemas)).toEqual(
|
|
432
|
-
expect.arrayContaining(["graph", "graph|child"])
|
|
432
|
+
expect.arrayContaining(["graph", "graph|child"]),
|
|
433
433
|
);
|
|
434
434
|
|
|
435
435
|
expect(schemas["graph|child"].input).toMatchObject({
|
|
@@ -561,11 +561,11 @@ describe
|
|
|
561
561
|
],
|
|
562
562
|
],
|
|
563
563
|
},
|
|
564
|
-
"graph"
|
|
564
|
+
"graph",
|
|
565
565
|
);
|
|
566
566
|
|
|
567
567
|
expect(Object.keys(schemas)).toEqual(
|
|
568
|
-
expect.arrayContaining(["graph", "graph|child"])
|
|
568
|
+
expect.arrayContaining(["graph", "graph|child"]),
|
|
569
569
|
);
|
|
570
570
|
|
|
571
571
|
expect(schemas["graph|child"].input).toMatchObject({
|
|
@@ -638,7 +638,7 @@ describe
|
|
|
638
638
|
type: "object",
|
|
639
639
|
$schema: "http://json-schema.org/draft-07/schema#",
|
|
640
640
|
});
|
|
641
|
-
}
|
|
641
|
+
},
|
|
642
642
|
);
|
|
643
643
|
|
|
644
644
|
test.concurrent("indirect", { timeout: 10_000 }, () => {
|
|
@@ -680,7 +680,7 @@ describe
|
|
|
680
680
|
export const graph = parent.compile()
|
|
681
681
|
`,
|
|
682
682
|
},
|
|
683
|
-
"graph"
|
|
683
|
+
"graph",
|
|
684
684
|
);
|
|
685
685
|
expect(schemas["graph|child"].input).toMatchObject({
|
|
686
686
|
type: "object",
|
|
@@ -755,7 +755,7 @@ describe
|
|
|
755
755
|
});
|
|
756
756
|
});
|
|
757
757
|
|
|
758
|
-
test.skipIf(isParserSkipped).concurrent("weather", { timeout:
|
|
758
|
+
test.skipIf(isParserSkipped).concurrent("weather", { timeout: 20_000 }, () => {
|
|
759
759
|
const schemas = SubgraphExtractor.extractSchemas(
|
|
760
760
|
{
|
|
761
761
|
contents: dedent`
|
|
@@ -818,11 +818,11 @@ test.skipIf(isParserSkipped).concurrent("weather", { timeout: 10_000 }, () => {
|
|
|
818
818
|
export const graph = router.compile();
|
|
819
819
|
`,
|
|
820
820
|
},
|
|
821
|
-
"graph"
|
|
821
|
+
"graph",
|
|
822
822
|
);
|
|
823
823
|
|
|
824
824
|
expect(Object.keys(schemas)).toEqual(
|
|
825
|
-
expect.arrayContaining(["graph", "graph|weather_graph"])
|
|
825
|
+
expect.arrayContaining(["graph", "graph|weather_graph"]),
|
|
826
826
|
);
|
|
827
827
|
});
|
|
828
828
|
|
|
@@ -876,10 +876,10 @@ test.skipIf(isParserSkipped).concurrent("nested", { timeout: 10_000 }, () => {
|
|
|
876
876
|
export const graph = grandParent.compile();
|
|
877
877
|
`,
|
|
878
878
|
},
|
|
879
|
-
"graph"
|
|
879
|
+
"graph",
|
|
880
880
|
);
|
|
881
881
|
|
|
882
882
|
expect(Object.keys(schemas)).toEqual(
|
|
883
|
-
expect.arrayContaining(["graph", "graph|gp_two", "graph|gp_two|p_two"])
|
|
883
|
+
expect.arrayContaining(["graph", "graph|gp_two", "graph|gp_two|p_two"]),
|
|
884
884
|
);
|
|
885
885
|
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"module": "NodeNext",
|
|
4
|
+
"jsx": "react-jsx",
|
|
5
|
+
"noEmit": true,
|
|
6
|
+
"strict": true,
|
|
7
|
+
"allowJs": true,
|
|
8
|
+
"skipLibCheck": true,
|
|
9
|
+
"noUnusedLocals": true,
|
|
10
|
+
"esModuleInterop": true,
|
|
11
|
+
"resolveJsonModule": true,
|
|
12
|
+
"allowImportingTsExtensions": true,
|
|
13
|
+
"forceConsistentCasingInFileNames": true
|
|
14
|
+
}
|
|
15
|
+
}
|
langgraph_api/js/yarn.lock
CHANGED
|
@@ -203,15 +203,15 @@
|
|
|
203
203
|
zod "^3.22.4"
|
|
204
204
|
zod-to-json-schema "^3.22.3"
|
|
205
205
|
|
|
206
|
-
"@langchain/langgraph-api@~0.0.
|
|
207
|
-
version "0.0.
|
|
208
|
-
resolved "https://registry.yarnpkg.com/@langchain/langgraph-api/-/langgraph-api-0.0.
|
|
209
|
-
integrity sha512-
|
|
206
|
+
"@langchain/langgraph-api@~0.0.29":
|
|
207
|
+
version "0.0.29"
|
|
208
|
+
resolved "https://registry.yarnpkg.com/@langchain/langgraph-api/-/langgraph-api-0.0.29.tgz#787e01675250720d293e3363ff579b601a9c94ab"
|
|
209
|
+
integrity sha512-WJVOWFJBEo7sCUtzchFRhFWT4+Zn3evKakmLGDJihMZ2nrNeoaordEUmbsXMLiQVOe3bP7Fpweq3mSPIwxQyyQ==
|
|
210
210
|
dependencies:
|
|
211
211
|
"@babel/code-frame" "^7.26.2"
|
|
212
212
|
"@hono/node-server" "^1.12.0"
|
|
213
213
|
"@hono/zod-validator" "^0.2.2"
|
|
214
|
-
"@langchain/langgraph-ui" "0.0.
|
|
214
|
+
"@langchain/langgraph-ui" "0.0.29"
|
|
215
215
|
"@types/json-schema" "^7.0.15"
|
|
216
216
|
"@typescript/vfs" "^1.6.0"
|
|
217
217
|
dedent "^1.5.3"
|
|
@@ -220,6 +220,7 @@
|
|
|
220
220
|
hono "^4.5.4"
|
|
221
221
|
langsmith "^0.2.15"
|
|
222
222
|
open "^10.1.0"
|
|
223
|
+
semver "^7.7.1"
|
|
223
224
|
stacktrace-parser "^0.1.10"
|
|
224
225
|
superjson "^2.2.2"
|
|
225
226
|
tsx "^4.19.3"
|
|
@@ -255,10 +256,10 @@
|
|
|
255
256
|
p-retry "4"
|
|
256
257
|
uuid "^9.0.0"
|
|
257
258
|
|
|
258
|
-
"@langchain/langgraph-ui@0.0.
|
|
259
|
-
version "0.0.
|
|
260
|
-
resolved "https://registry.yarnpkg.com/@langchain/langgraph-ui/-/langgraph-ui-0.0.
|
|
261
|
-
integrity sha512-
|
|
259
|
+
"@langchain/langgraph-ui@0.0.29", "@langchain/langgraph-ui@~0.0.29":
|
|
260
|
+
version "0.0.29"
|
|
261
|
+
resolved "https://registry.yarnpkg.com/@langchain/langgraph-ui/-/langgraph-ui-0.0.29.tgz#98659cc56f0e8e074a9a0b2e33e967dc5f30e79f"
|
|
262
|
+
integrity sha512-FADBt6B1/egKSpZFmTa6vxonBK9lF6EmeKoBEWh/XTkO6lD5zsejWoRgT+LR2x22CHJvfvCQtXxgP5y8AtxsQw==
|
|
262
263
|
dependencies:
|
|
263
264
|
"@commander-js/extra-typings" "^13.0.0"
|
|
264
265
|
commander "^13.0.0"
|
|
@@ -1440,6 +1441,11 @@ semver@^7.6.3:
|
|
|
1440
1441
|
resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143"
|
|
1441
1442
|
integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==
|
|
1442
1443
|
|
|
1444
|
+
semver@^7.7.1:
|
|
1445
|
+
version "7.7.1"
|
|
1446
|
+
resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.1.tgz#abd5098d82b18c6c81f6074ff2647fd3e7220c9f"
|
|
1447
|
+
integrity sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==
|
|
1448
|
+
|
|
1443
1449
|
siginfo@^2.0.0:
|
|
1444
1450
|
version "2.0.0"
|
|
1445
1451
|
resolved "https://registry.yarnpkg.com/siginfo/-/siginfo-2.0.0.tgz#32e76c70b79724e3bb567cb9d543eb858ccfaf30"
|