Subgraph as compiled graph sample¶
InĀ [1]:
Copied!
var userHomeDir = System.getProperty("user.home");
var localRespoUrl = "file://" + userHomeDir + "/.m2/repository/";
var langchain4jVersion = "1.0.1";
var langchain4jbeta = "1.0.1-beta6";
var langgraph4jVersion = "1.6-SNAPSHOT";
var userHomeDir = System.getProperty("user.home");
var localRespoUrl = "file://" + userHomeDir + "/.m2/repository/";
var langchain4jVersion = "1.0.1";
var langchain4jbeta = "1.0.1-beta6";
var langgraph4jVersion = "1.6-SNAPSHOT";
InĀ [2]:
Copied!
%%bash
rm -rf \{userHomeDir}/Library/Jupyter/kernels/rapaio-jupyter-kernel/mima_cache/org/bsc/langgraph4j
%%bash
rm -rf \{userHomeDir}/Library/Jupyter/kernels/rapaio-jupyter-kernel/mima_cache/org/bsc/langgraph4j
InĀ [Ā ]:
Copied!
%dependency /add-repo local \{localRespoUrl} release|never snapshot|always
// %dependency /list-repos
%dependency /add org.slf4j:slf4j-jdk14:2.0.9
%dependency /add org.bsc.langgraph4j:langgraph4j-core:\{langgraph4jVersion}
%dependency /add org.bsc.langgraph4j:langgraph4j-langchain4j:\{langgraph4jVersion}
%dependency /add dev.langchain4j:langchain4j:\{langchain4jVersion}
%dependency /add dev.langchain4j:langchain4j-open-ai:\{langchain4jVersion}
%dependency /add net.sourceforge.plantuml:plantuml-mit:1.2024.8
%dependency /resolve
%dependency /add-repo local \{localRespoUrl} release|never snapshot|always
// %dependency /list-repos
%dependency /add org.slf4j:slf4j-jdk14:2.0.9
%dependency /add org.bsc.langgraph4j:langgraph4j-core:\{langgraph4jVersion}
%dependency /add org.bsc.langgraph4j:langgraph4j-langchain4j:\{langgraph4jVersion}
%dependency /add dev.langchain4j:langchain4j:\{langchain4jVersion}
%dependency /add dev.langchain4j:langchain4j-open-ai:\{langchain4jVersion}
%dependency /add net.sourceforge.plantuml:plantuml-mit:1.2024.8
%dependency /resolve
utility to render graph respresentation in PlantUML
InĀ [4]:
Copied!
import net.sourceforge.plantuml.SourceStringReader;
import net.sourceforge.plantuml.FileFormatOption;
import net.sourceforge.plantuml.FileFormat;
import org.bsc.langgraph4j.GraphRepresentation;
void displayDiagram( GraphRepresentation representation ) throws IOException {
var reader = new SourceStringReader(representation.getContent());
try(var imageOutStream = new java.io.ByteArrayOutputStream()) {
var description = reader.outputImage( imageOutStream, 0, new FileFormatOption(FileFormat.PNG));
var imageInStream = new java.io.ByteArrayInputStream( imageOutStream.toByteArray() );
var image = javax.imageio.ImageIO.read( imageInStream );
display( image );
}
}
import net.sourceforge.plantuml.SourceStringReader;
import net.sourceforge.plantuml.FileFormatOption;
import net.sourceforge.plantuml.FileFormat;
import org.bsc.langgraph4j.GraphRepresentation;
void displayDiagram( GraphRepresentation representation ) throws IOException {
var reader = new SourceStringReader(representation.getContent());
try(var imageOutStream = new java.io.ByteArrayOutputStream()) {
var description = reader.outputImage( imageOutStream, 0, new FileFormatOption(FileFormat.PNG));
var imageInStream = new java.io.ByteArrayInputStream( imageOutStream.toByteArray() );
var image = javax.imageio.ImageIO.read( imageInStream );
display( image );
}
}
Graph State
InĀ [5]:
Copied!
import org.bsc.langgraph4j.prebuilt.MessagesState;
import org.bsc.langgraph4j.state.Channel;
public class State extends MessagesState<String> {
public State(Map<String, Object> initData) {
super( initData );
}
}
import org.bsc.langgraph4j.prebuilt.MessagesState;
import org.bsc.langgraph4j.state.Channel;
public class State extends MessagesState {
public State(Map initData) {
super( initData );
}
}
Utility action to simplify node creation
InĀ [6]:
Copied!
import org.bsc.langgraph4j.action.AsyncNodeAction;
AsyncNodeAction<State> makeNode( String id ) {
return node_async(state ->
Map.of("messages", id)
);
}
import org.bsc.langgraph4j.action.AsyncNodeAction;
AsyncNodeAction makeNode( String id ) {
return node_async(state ->
Map.of("messages", id)
);
}
Create a subgraph as compiled graph
InĀ [7]:
Copied!
import org.bsc.langgraph4j.StateGraph;
import org.bsc.langgraph4j.action.AsyncNodeAction;
import static org.bsc.langgraph4j.action.AsyncNodeAction.node_async;
import static org.bsc.langgraph4j.action.AsyncEdgeAction.edge_async;
import static org.bsc.langgraph4j.StateGraph.END;
import static org.bsc.langgraph4j.StateGraph.START;
var workflowChild = new StateGraph<>(State.SCHEMA, State::new)
.addNode("child:step_1", makeNode("child:step1") )
.addNode("child:step_2", makeNode("child:step2"))
.addNode("child:step_3", makeNode("child:step3"))
.addEdge(START, "child:step_1")
.addEdge("child:step_1", "child:step_2")
.addConditionalEdges( "child:step_2",
edge_async(state -> "continue"),
Map.of( END, END, "continue", "child:step_3") )
.addEdge("child:step_3", END)
;
var compiledWorkflowChild = workflowChild.compile();
import org.bsc.langgraph4j.StateGraph;
import org.bsc.langgraph4j.action.AsyncNodeAction;
import static org.bsc.langgraph4j.action.AsyncNodeAction.node_async;
import static org.bsc.langgraph4j.action.AsyncEdgeAction.edge_async;
import static org.bsc.langgraph4j.StateGraph.END;
import static org.bsc.langgraph4j.StateGraph.START;
var workflowChild = new StateGraph<>(State.SCHEMA, State::new)
.addNode("child:step_1", makeNode("child:step1") )
.addNode("child:step_2", makeNode("child:step2"))
.addNode("child:step_3", makeNode("child:step3"))
.addEdge(START, "child:step_1")
.addEdge("child:step_1", "child:step_2")
.addConditionalEdges( "child:step_2",
edge_async(state -> "continue"),
Map.of( END, END, "continue", "child:step_3") )
.addEdge("child:step_3", END)
;
var compiledWorkflowChild = workflowChild.compile();
Create graph with a sub graph as compiled graph
The subgraph will be executed independently to the parent sharing its state but not
CompileConfig
InĀ [8]:
Copied!
var workflow = new StateGraph<>(State.SCHEMA, State::new)
.addNode("step_1", makeNode("step1"))
.addNode("step_2", makeNode("step2"))
.addNode("step_3", makeNode("step3"))
.addNode( "subgraph", compiledWorkflowChild )
.addEdge(START, "step_1")
.addEdge("step_1", "step_2")
.addEdge("step_2", "subgraph")
.addEdge("subgraph", "step_3")
.addEdge("step_3", END)
;
var compiledWorkflow = workflow.compile();
for( var step : compiledWorkflow.stream( Map.of() )) {
System.out.println( step );
}
var workflow = new StateGraph<>(State.SCHEMA, State::new)
.addNode("step_1", makeNode("step1"))
.addNode("step_2", makeNode("step2"))
.addNode("step_3", makeNode("step3"))
.addNode( "subgraph", compiledWorkflowChild )
.addEdge(START, "step_1")
.addEdge("step_1", "step_2")
.addEdge("step_2", "subgraph")
.addEdge("subgraph", "step_3")
.addEdge("step_3", END)
;
var compiledWorkflow = workflow.compile();
for( var step : compiledWorkflow.stream( Map.of() )) {
System.out.println( step );
}
NodeOutput{node=__START__, state={messages=[]}} NodeOutput{node=step_1, state={messages=[step1]}} NodeOutput{node=step_2, state={messages=[step1, step2]}} NodeOutput{node=__START__, state={messages=[step1, step2]}} NodeOutput{node=child:step_1, state={messages=[step1, step2, child:step1]}} NodeOutput{node=child:step_2, state={messages=[step1, step2, child:step1, child:step2]}} NodeOutput{node=child:step_3, state={messages=[step1, step2, child:step1, child:step2, child:step3]}} NodeOutput{node=__END__, state={messages=[step1, step2, child:step1, child:step2, child:step3]}} NodeOutput{node=subgraph, state={messages=[step1, step2, child:step1, child:step2, child:step3]}} NodeOutput{node=step_3, state={messages=[step1, step2, child:step1, child:step2, child:step3, step3]}} NodeOutput{node=__END__, state={messages=[step1, step2, child:step1, child:step2, child:step3, step3]}}
Display StateGraph as you defined
InĀ [9]:
Copied!
var representation = compiledWorkflow.getGraph( GraphRepresentation.Type.PLANTUML, "sub graph", false );
displayDiagram( representation );
var representation = compiledWorkflow.getGraph( GraphRepresentation.Type.PLANTUML, "sub graph", false );
displayDiagram( representation );
Display Compiled Graph result as graph processing
in such case the result will be the same of previous one because no merge will be done
InĀ [10]:
Copied!
var representation = compiledWorkflow.getGraph( GraphRepresentation.Type.PLANTUML, "merged sub graph", false );
displayDiagram( representation );
var representation = compiledWorkflow.getGraph( GraphRepresentation.Type.PLANTUML, "merged sub graph", false );
displayDiagram( representation );