@langchain/langgraph 0.2.10 → 0.2.11
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 +1 -1
- package/dist/graph/graph.cjs +112 -29
- package/dist/graph/graph.d.ts +2 -2
- package/dist/graph/graph.js +115 -32
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -59,7 +59,7 @@ import { AIMessage, BaseMessage, HumanMessage } from "@langchain/core/messages";
|
|
|
59
59
|
import { tool } from "@langchain/core/tools";
|
|
60
60
|
import { z } from "zod";
|
|
61
61
|
import { ChatAnthropic } from "@langchain/anthropic";
|
|
62
|
-
import { StateGraph
|
|
62
|
+
import { StateGraph } from "@langchain/langgraph";
|
|
63
63
|
import { MemorySaver, Annotation } from "@langchain/langgraph";
|
|
64
64
|
import { ToolNode } from "@langchain/langgraph/prebuilt";
|
|
65
65
|
|
package/dist/graph/graph.cjs
CHANGED
|
@@ -5,6 +5,7 @@ exports.CompiledGraph = exports.Graph = exports.Branch = exports.END = exports.S
|
|
|
5
5
|
const runnables_1 = require("@langchain/core/runnables");
|
|
6
6
|
const graph_1 = require("@langchain/core/runnables/graph");
|
|
7
7
|
const zod_1 = require("zod");
|
|
8
|
+
const uuid_1 = require("uuid");
|
|
8
9
|
const read_js_1 = require("../pregel/read.cjs");
|
|
9
10
|
const index_js_1 = require("../pregel/index.cjs");
|
|
10
11
|
const ephemeral_value_js_1 = require("../channels/ephemeral_value.cjs");
|
|
@@ -358,50 +359,126 @@ class CompiledGraph extends index_js_1.Pregel {
|
|
|
358
359
|
schema: zod_1.z.any(),
|
|
359
360
|
}, exports.START),
|
|
360
361
|
};
|
|
361
|
-
const endNodes = {
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
362
|
+
const endNodes = {};
|
|
363
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
364
|
+
let subgraphs = {};
|
|
365
|
+
if (xray) {
|
|
366
|
+
subgraphs = Object.fromEntries((0, utils_js_1.gatherIteratorSync)(this.getSubgraphs()).filter(
|
|
367
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
368
|
+
(x) => isCompiledGraph(x[1])));
|
|
369
|
+
}
|
|
370
|
+
function addEdge(start, end, label, conditional = false) {
|
|
371
|
+
if (end === exports.END && endNodes[exports.END] === undefined) {
|
|
372
|
+
endNodes[exports.END] = graph.addNode({ schema: zod_1.z.any() }, exports.END);
|
|
373
|
+
}
|
|
374
|
+
return graph.addEdge(startNodes[start], endNodes[end], label !== end ? label : undefined, conditional);
|
|
375
|
+
}
|
|
376
|
+
for (const [key, nodeSpec] of Object.entries(this.builder.nodes)) {
|
|
377
|
+
const displayKey = _escapeMermaidKeywords(key);
|
|
378
|
+
const node = nodeSpec.runnable;
|
|
379
|
+
const metadata = nodeSpec.metadata ?? {};
|
|
380
|
+
if (this.interruptBefore?.includes(key) &&
|
|
381
|
+
this.interruptAfter?.includes(key)) {
|
|
382
|
+
metadata.__interrupt = "before,after";
|
|
383
|
+
}
|
|
384
|
+
else if (this.interruptBefore?.includes(key)) {
|
|
385
|
+
metadata.__interrupt = "before";
|
|
386
|
+
}
|
|
387
|
+
else if (this.interruptAfter?.includes(key)) {
|
|
388
|
+
metadata.__interrupt = "after";
|
|
389
|
+
}
|
|
390
|
+
if (xray) {
|
|
391
|
+
const newXrayValue = typeof xray === "number" ? xray - 1 : xray;
|
|
392
|
+
const drawableSubgraph = subgraphs[key] !== undefined
|
|
393
|
+
? subgraphs[key].getGraph({
|
|
370
394
|
...config,
|
|
371
|
-
xray:
|
|
395
|
+
xray: newXrayValue,
|
|
372
396
|
})
|
|
373
|
-
: node.
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
if (Object.keys(
|
|
377
|
-
const [
|
|
378
|
-
if (
|
|
379
|
-
|
|
397
|
+
: node.getGraph(config);
|
|
398
|
+
drawableSubgraph.trimFirstNode();
|
|
399
|
+
drawableSubgraph.trimLastNode();
|
|
400
|
+
if (Object.keys(drawableSubgraph.nodes).length > 1) {
|
|
401
|
+
const [e, s] = graph.extend(drawableSubgraph, displayKey);
|
|
402
|
+
if (e === undefined) {
|
|
403
|
+
throw new Error(`Could not extend subgraph "${key}" due to missing entrypoint.`);
|
|
404
|
+
}
|
|
405
|
+
// TODO: Remove default name once we stop supporting core 0.2.0
|
|
406
|
+
// eslint-disable-next-line no-inner-declarations
|
|
407
|
+
function _isRunnableInterface(
|
|
408
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
409
|
+
thing) {
|
|
410
|
+
return thing ? thing.lc_runnable : false;
|
|
380
411
|
}
|
|
381
|
-
|
|
382
|
-
|
|
412
|
+
// eslint-disable-next-line no-inner-declarations
|
|
413
|
+
function _nodeDataStr(id, data) {
|
|
414
|
+
if (id !== undefined && !(0, uuid_1.validate)(id)) {
|
|
415
|
+
return id;
|
|
416
|
+
}
|
|
417
|
+
else if (_isRunnableInterface(data)) {
|
|
418
|
+
try {
|
|
419
|
+
let dataStr = data.getName();
|
|
420
|
+
dataStr = dataStr.startsWith("Runnable")
|
|
421
|
+
? dataStr.slice("Runnable".length)
|
|
422
|
+
: dataStr;
|
|
423
|
+
return dataStr;
|
|
424
|
+
}
|
|
425
|
+
catch (error) {
|
|
426
|
+
return data.getName();
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
else {
|
|
430
|
+
return data.name ?? "UnknownSchema";
|
|
431
|
+
}
|
|
383
432
|
}
|
|
433
|
+
// TODO: Remove casts when we stop supporting core 0.2.0
|
|
434
|
+
if (s !== undefined) {
|
|
435
|
+
startNodes[displayKey] = {
|
|
436
|
+
name: _nodeDataStr(s.id, s.data),
|
|
437
|
+
...s,
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
endNodes[displayKey] = {
|
|
441
|
+
name: _nodeDataStr(e.id, e.data),
|
|
442
|
+
...e,
|
|
443
|
+
};
|
|
384
444
|
}
|
|
385
445
|
else {
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
446
|
+
// TODO: Remove when we stop supporting core 0.2.0
|
|
447
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
448
|
+
// @ts-ignore
|
|
449
|
+
const newNode = graph.addNode(node, displayKey, metadata);
|
|
450
|
+
startNodes[displayKey] = newNode;
|
|
451
|
+
endNodes[displayKey] = newNode;
|
|
389
452
|
}
|
|
390
453
|
}
|
|
391
454
|
else {
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
455
|
+
// TODO: Remove when we stop supporting core 0.2.0
|
|
456
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
457
|
+
// @ts-ignore
|
|
458
|
+
const newNode = graph.addNode(node, displayKey, metadata);
|
|
459
|
+
startNodes[displayKey] = newNode;
|
|
460
|
+
endNodes[displayKey] = newNode;
|
|
395
461
|
}
|
|
396
462
|
}
|
|
397
|
-
|
|
398
|
-
|
|
463
|
+
const sortedEdges = [...this.builder.allEdges].sort(([a], [b]) => {
|
|
464
|
+
if (a < b) {
|
|
465
|
+
return -1;
|
|
466
|
+
}
|
|
467
|
+
else if (b > a) {
|
|
468
|
+
return 1;
|
|
469
|
+
}
|
|
470
|
+
else {
|
|
471
|
+
return 0;
|
|
472
|
+
}
|
|
473
|
+
});
|
|
474
|
+
for (const [start, end] of sortedEdges) {
|
|
475
|
+
addEdge(_escapeMermaidKeywords(start), _escapeMermaidKeywords(end));
|
|
399
476
|
}
|
|
400
477
|
for (const [start, branches] of Object.entries(this.builder.branches)) {
|
|
401
478
|
const defaultEnds = {
|
|
402
479
|
...Object.fromEntries(Object.keys(this.builder.nodes)
|
|
403
480
|
.filter((k) => k !== start)
|
|
404
|
-
.map((k) => [k, k])),
|
|
481
|
+
.map((k) => [_escapeMermaidKeywords(k), _escapeMermaidKeywords(k)])),
|
|
405
482
|
[exports.END]: exports.END,
|
|
406
483
|
};
|
|
407
484
|
for (const branch of Object.values(branches)) {
|
|
@@ -413,7 +490,7 @@ class CompiledGraph extends index_js_1.Pregel {
|
|
|
413
490
|
ends = defaultEnds;
|
|
414
491
|
}
|
|
415
492
|
for (const [label, end] of Object.entries(ends)) {
|
|
416
|
-
|
|
493
|
+
addEdge(_escapeMermaidKeywords(start), _escapeMermaidKeywords(end), label, true);
|
|
417
494
|
}
|
|
418
495
|
}
|
|
419
496
|
}
|
|
@@ -429,3 +506,9 @@ function isCompiledGraph(x) {
|
|
|
429
506
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
430
507
|
typeof x.attachEdge === "function");
|
|
431
508
|
}
|
|
509
|
+
function _escapeMermaidKeywords(key) {
|
|
510
|
+
if (key === "subgraph") {
|
|
511
|
+
return `"${key}"`;
|
|
512
|
+
}
|
|
513
|
+
return key;
|
|
514
|
+
}
|
package/dist/graph/graph.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Runnable, RunnableConfig, RunnableLike } from "@langchain/core/runnables";
|
|
2
|
-
import { Graph as
|
|
2
|
+
import { Graph as DrawableGraph } from "@langchain/core/runnables/graph";
|
|
3
3
|
import { All, BaseCheckpointSaver } from "@langchain/langgraph-checkpoint";
|
|
4
4
|
import { PregelNode } from "../pregel/read.js";
|
|
5
5
|
import { Pregel } from "../pregel/index.js";
|
|
@@ -74,5 +74,5 @@ export declare class CompiledGraph<N extends string, RunInput = any, RunOutput =
|
|
|
74
74
|
*/
|
|
75
75
|
getGraph(config?: RunnableConfig & {
|
|
76
76
|
xray?: boolean | number;
|
|
77
|
-
}):
|
|
77
|
+
}): DrawableGraph;
|
|
78
78
|
}
|
package/dist/graph/graph.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-use-before-define */
|
|
2
2
|
import { _coerceToRunnable, } from "@langchain/core/runnables";
|
|
3
|
-
import { Graph as
|
|
3
|
+
import { Graph as DrawableGraph, } from "@langchain/core/runnables/graph";
|
|
4
4
|
import { z } from "zod";
|
|
5
|
+
import { validate as isUuid } from "uuid";
|
|
5
6
|
import { PregelNode } from "../pregel/read.js";
|
|
6
7
|
import { Channel, Pregel } from "../pregel/index.js";
|
|
7
8
|
import { EphemeralValue } from "../channels/ephemeral_value.js";
|
|
8
9
|
import { ChannelWrite, PASSTHROUGH } from "../pregel/write.js";
|
|
9
10
|
import { _isSend, CHECKPOINT_NAMESPACE_END, CHECKPOINT_NAMESPACE_SEPARATOR, TAG_HIDDEN, } from "../constants.js";
|
|
10
|
-
import { RunnableCallable } from "../utils.js";
|
|
11
|
+
import { gatherIteratorSync, RunnableCallable } from "../utils.js";
|
|
11
12
|
import { InvalidUpdateError, NodeInterrupt } from "../errors.js";
|
|
12
13
|
/** Special reserved node name denoting the start of a graph. */
|
|
13
14
|
export const START = "__start__";
|
|
@@ -347,56 +348,132 @@ export class CompiledGraph extends Pregel {
|
|
|
347
348
|
*/
|
|
348
349
|
getGraph(config) {
|
|
349
350
|
const xray = config?.xray;
|
|
350
|
-
const graph = new
|
|
351
|
+
const graph = new DrawableGraph();
|
|
351
352
|
const startNodes = {
|
|
352
353
|
[START]: graph.addNode({
|
|
353
354
|
schema: z.any(),
|
|
354
355
|
}, START),
|
|
355
356
|
};
|
|
356
|
-
const endNodes = {
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
357
|
+
const endNodes = {};
|
|
358
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
359
|
+
let subgraphs = {};
|
|
360
|
+
if (xray) {
|
|
361
|
+
subgraphs = Object.fromEntries(gatherIteratorSync(this.getSubgraphs()).filter(
|
|
362
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
363
|
+
(x) => isCompiledGraph(x[1])));
|
|
364
|
+
}
|
|
365
|
+
function addEdge(start, end, label, conditional = false) {
|
|
366
|
+
if (end === END && endNodes[END] === undefined) {
|
|
367
|
+
endNodes[END] = graph.addNode({ schema: z.any() }, END);
|
|
368
|
+
}
|
|
369
|
+
return graph.addEdge(startNodes[start], endNodes[end], label !== end ? label : undefined, conditional);
|
|
370
|
+
}
|
|
371
|
+
for (const [key, nodeSpec] of Object.entries(this.builder.nodes)) {
|
|
372
|
+
const displayKey = _escapeMermaidKeywords(key);
|
|
373
|
+
const node = nodeSpec.runnable;
|
|
374
|
+
const metadata = nodeSpec.metadata ?? {};
|
|
375
|
+
if (this.interruptBefore?.includes(key) &&
|
|
376
|
+
this.interruptAfter?.includes(key)) {
|
|
377
|
+
metadata.__interrupt = "before,after";
|
|
378
|
+
}
|
|
379
|
+
else if (this.interruptBefore?.includes(key)) {
|
|
380
|
+
metadata.__interrupt = "before";
|
|
381
|
+
}
|
|
382
|
+
else if (this.interruptAfter?.includes(key)) {
|
|
383
|
+
metadata.__interrupt = "after";
|
|
384
|
+
}
|
|
385
|
+
if (xray) {
|
|
386
|
+
const newXrayValue = typeof xray === "number" ? xray - 1 : xray;
|
|
387
|
+
const drawableSubgraph = subgraphs[key] !== undefined
|
|
388
|
+
? subgraphs[key].getGraph({
|
|
365
389
|
...config,
|
|
366
|
-
xray:
|
|
390
|
+
xray: newXrayValue,
|
|
367
391
|
})
|
|
368
|
-
: node.
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
if (Object.keys(
|
|
372
|
-
const [
|
|
373
|
-
if (
|
|
374
|
-
|
|
392
|
+
: node.getGraph(config);
|
|
393
|
+
drawableSubgraph.trimFirstNode();
|
|
394
|
+
drawableSubgraph.trimLastNode();
|
|
395
|
+
if (Object.keys(drawableSubgraph.nodes).length > 1) {
|
|
396
|
+
const [e, s] = graph.extend(drawableSubgraph, displayKey);
|
|
397
|
+
if (e === undefined) {
|
|
398
|
+
throw new Error(`Could not extend subgraph "${key}" due to missing entrypoint.`);
|
|
399
|
+
}
|
|
400
|
+
// TODO: Remove default name once we stop supporting core 0.2.0
|
|
401
|
+
// eslint-disable-next-line no-inner-declarations
|
|
402
|
+
function _isRunnableInterface(
|
|
403
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
404
|
+
thing) {
|
|
405
|
+
return thing ? thing.lc_runnable : false;
|
|
375
406
|
}
|
|
376
|
-
|
|
377
|
-
|
|
407
|
+
// eslint-disable-next-line no-inner-declarations
|
|
408
|
+
function _nodeDataStr(id, data) {
|
|
409
|
+
if (id !== undefined && !isUuid(id)) {
|
|
410
|
+
return id;
|
|
411
|
+
}
|
|
412
|
+
else if (_isRunnableInterface(data)) {
|
|
413
|
+
try {
|
|
414
|
+
let dataStr = data.getName();
|
|
415
|
+
dataStr = dataStr.startsWith("Runnable")
|
|
416
|
+
? dataStr.slice("Runnable".length)
|
|
417
|
+
: dataStr;
|
|
418
|
+
return dataStr;
|
|
419
|
+
}
|
|
420
|
+
catch (error) {
|
|
421
|
+
return data.getName();
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
else {
|
|
425
|
+
return data.name ?? "UnknownSchema";
|
|
426
|
+
}
|
|
378
427
|
}
|
|
428
|
+
// TODO: Remove casts when we stop supporting core 0.2.0
|
|
429
|
+
if (s !== undefined) {
|
|
430
|
+
startNodes[displayKey] = {
|
|
431
|
+
name: _nodeDataStr(s.id, s.data),
|
|
432
|
+
...s,
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
endNodes[displayKey] = {
|
|
436
|
+
name: _nodeDataStr(e.id, e.data),
|
|
437
|
+
...e,
|
|
438
|
+
};
|
|
379
439
|
}
|
|
380
440
|
else {
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
441
|
+
// TODO: Remove when we stop supporting core 0.2.0
|
|
442
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
443
|
+
// @ts-ignore
|
|
444
|
+
const newNode = graph.addNode(node, displayKey, metadata);
|
|
445
|
+
startNodes[displayKey] = newNode;
|
|
446
|
+
endNodes[displayKey] = newNode;
|
|
384
447
|
}
|
|
385
448
|
}
|
|
386
449
|
else {
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
450
|
+
// TODO: Remove when we stop supporting core 0.2.0
|
|
451
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
452
|
+
// @ts-ignore
|
|
453
|
+
const newNode = graph.addNode(node, displayKey, metadata);
|
|
454
|
+
startNodes[displayKey] = newNode;
|
|
455
|
+
endNodes[displayKey] = newNode;
|
|
390
456
|
}
|
|
391
457
|
}
|
|
392
|
-
|
|
393
|
-
|
|
458
|
+
const sortedEdges = [...this.builder.allEdges].sort(([a], [b]) => {
|
|
459
|
+
if (a < b) {
|
|
460
|
+
return -1;
|
|
461
|
+
}
|
|
462
|
+
else if (b > a) {
|
|
463
|
+
return 1;
|
|
464
|
+
}
|
|
465
|
+
else {
|
|
466
|
+
return 0;
|
|
467
|
+
}
|
|
468
|
+
});
|
|
469
|
+
for (const [start, end] of sortedEdges) {
|
|
470
|
+
addEdge(_escapeMermaidKeywords(start), _escapeMermaidKeywords(end));
|
|
394
471
|
}
|
|
395
472
|
for (const [start, branches] of Object.entries(this.builder.branches)) {
|
|
396
473
|
const defaultEnds = {
|
|
397
474
|
...Object.fromEntries(Object.keys(this.builder.nodes)
|
|
398
475
|
.filter((k) => k !== start)
|
|
399
|
-
.map((k) => [k, k])),
|
|
476
|
+
.map((k) => [_escapeMermaidKeywords(k), _escapeMermaidKeywords(k)])),
|
|
400
477
|
[END]: END,
|
|
401
478
|
};
|
|
402
479
|
for (const branch of Object.values(branches)) {
|
|
@@ -408,7 +485,7 @@ export class CompiledGraph extends Pregel {
|
|
|
408
485
|
ends = defaultEnds;
|
|
409
486
|
}
|
|
410
487
|
for (const [label, end] of Object.entries(ends)) {
|
|
411
|
-
|
|
488
|
+
addEdge(_escapeMermaidKeywords(start), _escapeMermaidKeywords(end), label, true);
|
|
412
489
|
}
|
|
413
490
|
}
|
|
414
491
|
}
|
|
@@ -423,3 +500,9 @@ function isCompiledGraph(x) {
|
|
|
423
500
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
424
501
|
typeof x.attachEdge === "function");
|
|
425
502
|
}
|
|
503
|
+
function _escapeMermaidKeywords(key) {
|
|
504
|
+
if (key === "subgraph") {
|
|
505
|
+
return `"${key}"`;
|
|
506
|
+
}
|
|
507
|
+
return key;
|
|
508
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@langchain/langgraph",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.11",
|
|
4
4
|
"description": "LangGraph",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"@jest/globals": "^29.5.0",
|
|
44
44
|
"@langchain/anthropic": "^0.3.0",
|
|
45
45
|
"@langchain/community": "^0.3.0",
|
|
46
|
-
"@langchain/core": "^0.3.
|
|
46
|
+
"@langchain/core": "^0.3.6",
|
|
47
47
|
"@langchain/langgraph-checkpoint-sqlite": "workspace:*",
|
|
48
48
|
"@langchain/openai": "^0.3.0",
|
|
49
49
|
"@langchain/scripts": ">=0.1.3 <0.2.0",
|