Skip to content

Commit 3ff7702

Browse files
authored
core[patch]: Expose graph endpoint from core (#5979)
* Expose graph endpoint from core * Add exports * Update extend method * Allow adding conditional edges * Fix
1 parent db9e352 commit 3ff7702

File tree

4 files changed

+63
-7
lines changed

4 files changed

+63
-7
lines changed

langchain-core/.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,10 @@ runnables.cjs
102102
runnables.js
103103
runnables.d.ts
104104
runnables.d.cts
105+
runnables/graph.cjs
106+
runnables/graph.js
107+
runnables/graph.d.ts
108+
runnables/graph.d.cts
105109
runnables/remote.cjs
106110
runnables/remote.js
107111
runnables/remote.d.ts

langchain-core/langchain.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ export const config = {
3838
prompts: "prompts/index",
3939
prompt_values: "prompt_values",
4040
runnables: "runnables/index",
41+
"runnables/graph": "runnables/graph",
4142
"runnables/remote": "runnables/remote",
4243
retrievers: "retrievers/index",
4344
"retrievers/document_compressors": "retrievers/document_compressors/base",

langchain-core/package.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,15 @@
329329
"import": "./runnables.js",
330330
"require": "./runnables.cjs"
331331
},
332+
"./runnables/graph": {
333+
"types": {
334+
"import": "./runnables/graph.d.ts",
335+
"require": "./runnables/graph.d.cts",
336+
"default": "./runnables/graph.d.ts"
337+
},
338+
"import": "./runnables/graph.js",
339+
"require": "./runnables/graph.cjs"
340+
},
332341
"./runnables/remote": {
333342
"types": {
334343
"import": "./runnables/remote.d.ts",
@@ -698,6 +707,10 @@
698707
"runnables.js",
699708
"runnables.d.ts",
700709
"runnables.d.cts",
710+
"runnables/graph.cjs",
711+
"runnables/graph.js",
712+
"runnables/graph.d.ts",
713+
"runnables/graph.d.cts",
701714
"runnables/remote.cjs",
702715
"runnables/remote.js",
703716
"runnables/remote.d.ts",

langchain-core/src/runnables/graph.ts

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ import { drawMermaid, drawMermaidPng } from "./graph_mermaid.js";
1111

1212
const MAX_DATA_DISPLAY_NAME_LENGTH = 42;
1313

14-
export function nodeDataStr(node: Node): string {
14+
export { Node, Edge };
15+
16+
function nodeDataStr(node: Node): string {
1517
if (!isUuid(node.id)) {
1618
return node.id;
1719
} else if (isRunnableInterface(node.data)) {
@@ -101,14 +103,24 @@ export class Graph {
101103
);
102104
}
103105

104-
addEdge(source: Node, target: Node, data?: string): Edge {
106+
addEdge(
107+
source: Node,
108+
target: Node,
109+
data?: string,
110+
conditional?: boolean
111+
): Edge {
105112
if (this.nodes[source.id] === undefined) {
106113
throw new Error(`Source node ${source.id} not in graph`);
107114
}
108115
if (this.nodes[target.id] === undefined) {
109116
throw new Error(`Target node ${target.id} not in graph`);
110117
}
111-
const edge: Edge = { source: source.id, target: target.id, data };
118+
const edge: Edge = {
119+
source: source.id,
120+
target: target.id,
121+
data,
122+
conditional,
123+
};
112124
this.edges.push(edge);
113125
return edge;
114126
}
@@ -135,14 +147,40 @@ export class Graph {
135147
return found[0];
136148
}
137149

138-
extend(graph: Graph): void {
139-
// Add all nodes from the other graph, taking care to avoid duplicates
150+
/**
151+
* Add all nodes and edges from another graph.
152+
* Note this doesn't check for duplicates, nor does it connect the graphs.
153+
*/
154+
extend(graph: Graph, prefix: string = "") {
155+
let finalPrefix = prefix;
156+
const nodeIds = Object.values(graph.nodes).map((node) => node.id);
157+
if (nodeIds.every(isUuid)) {
158+
finalPrefix = "";
159+
}
160+
161+
const prefixed = (id: string) => {
162+
return finalPrefix ? `${finalPrefix}:${id}` : id;
163+
};
164+
140165
Object.entries(graph.nodes).forEach(([key, value]) => {
141-
this.nodes[key] = value;
166+
this.nodes[prefixed(key)] = { ...value, id: prefixed(key) };
142167
});
143168

169+
const newEdges = graph.edges.map((edge) => {
170+
return {
171+
...edge,
172+
source: prefixed(edge.source),
173+
target: prefixed(edge.target),
174+
};
175+
});
144176
// Add all edges from the other graph
145-
this.edges = [...this.edges, ...graph.edges];
177+
this.edges = [...this.edges, ...newEdges];
178+
const first = graph.firstNode();
179+
const last = graph.lastNode();
180+
return [
181+
first ? { id: prefixed(first.id), data: first.data } : undefined,
182+
last ? { id: prefixed(last.id), data: last.data } : undefined,
183+
];
146184
}
147185

148186
trimFirstNode(): void {

0 commit comments

Comments
 (0)