Hooks Samples¶
In [1]:
Copied!
var userHomeDir = System.getProperty("user.home");
var localRespoUrl = "file://" + userHomeDir + "/.m2/repository/";
var langgraph4jVersion = "1.8-SNAPSHOT";
var userHomeDir = System.getProperty("user.home");
var localRespoUrl = "file://" + userHomeDir + "/.m2/repository/";
var langgraph4jVersion = "1.8-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 [3]:
Copied!
%dependency /add-repo local \{localRespoUrl} release|never snapshot|always
%dependency /add org.slf4j:slf4j-jdk14:2.0.9
%dependency /add org.bsc.langgraph4j:langgraph4j-core:\{langgraph4jVersion}
%dependency /resolve
%dependency /add-repo local \{localRespoUrl} release|never snapshot|always
%dependency /add org.slf4j:slf4j-jdk14:2.0.9
%dependency /add org.bsc.langgraph4j:langgraph4j-core:\{langgraph4jVersion}
%dependency /resolve
Repository local url: file:///Users/bsorrentino/.m2/repository/ added. Adding dependency org.slf4j:slf4j-jdk14:2.0.9 Adding dependency org.bsc.langgraph4j:langgraph4j-core:1.7-SNAPSHOT Solving dependencies Resolved artifacts count: 4 Add to classpath: /Users/bsorrentino/Library/Jupyter/kernels/rapaio-jupyter-kernel/mima_cache/org/slf4j/slf4j-jdk14/2.0.9/slf4j-jdk14-2.0.9.jar Add to classpath: /Users/bsorrentino/Library/Jupyter/kernels/rapaio-jupyter-kernel/mima_cache/org/slf4j/slf4j-api/2.0.9/slf4j-api-2.0.9.jar Add to classpath: /Users/bsorrentino/Library/Jupyter/kernels/rapaio-jupyter-kernel/mima_cache/org/bsc/langgraph4j/langgraph4j-core/1.7-SNAPSHOT/langgraph4j-core-1.7-SNAPSHOT.jar Add to classpath: /Users/bsorrentino/Library/Jupyter/kernels/rapaio-jupyter-kernel/mima_cache/org/bsc/async/async-generator/4.0.0-beta2/async-generator-4.0.0-beta2.jar
Imports¶
In [ ]:
Copied!
import org.bsc.langgraph4j.*;
import org.slf4j.*;
import org.bsc.langgraph4j.action.AsyncNodeActionWithConfig;
import org.bsc.langgraph4j.hook.NodeHook;
import org.bsc.langgraph4j.prebuilt.MessagesState;
import org.bsc.langgraph4j.state.AgentState;
import org.bsc.langgraph4j.utils.CollectionsUtils;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import static org.bsc.langgraph4j.GraphDefinition.END;
import static org.bsc.langgraph4j.GraphDefinition.START;
import static org.bsc.langgraph4j.action.AsyncNodeActionWithConfig.node_async;
try( var file = new java.io.FileInputStream("./logging.properties")) { // INITIALIZE LOGGING
java.util.logging.LogManager.getLogManager().readConfiguration( file );
}
import org.bsc.langgraph4j.*;
import org.slf4j.*;
import org.bsc.langgraph4j.action.AsyncNodeActionWithConfig;
import org.bsc.langgraph4j.hook.NodeHook;
import org.bsc.langgraph4j.prebuilt.MessagesState;
import org.bsc.langgraph4j.state.AgentState;
import org.bsc.langgraph4j.utils.CollectionsUtils;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import static org.bsc.langgraph4j.GraphDefinition.END;
import static org.bsc.langgraph4j.GraphDefinition.START;
import static org.bsc.langgraph4j.action.AsyncNodeActionWithConfig.node_async;
try( var file = new java.io.FileInputStream("./logging.properties")) { // INITIALIZE LOGGING
java.util.logging.LogManager.getLogManager().readConfiguration( file );
}
Hooks for logging¶
In [11]:
Copied!
public record LoggingNodeHook<State extends AgentState>(Logger log)
implements NodeHook.WrapCall<State> {
@Override
public CompletableFuture<Map<String, Object>> applyWrap( String nodeId, State state, RunnableConfig config, AsyncNodeActionWithConfig<State> action) {
log.info("node action fo node '{}' start with state:%n{}", nodeId, state);
return action.apply(state, config)
.whenComplete( ( result, exception ) -> {
log.info("node action fo node '{}' end with request update:%n{}", nodeId, CollectionsUtils.toString(result));
});
}
}
public record LoggingNodeHook(Logger log)
implements NodeHook.WrapCall {
@Override
public CompletableFuture
In [ ]:
Copied!
static class State extends MessagesState<String> {
public State(Map<String, Object> initData) {
super(initData);
}
}
static class State extends MessagesState {
public State(Map initData) {
super(initData);
}
}
Apply Logging Hook¶
In [16]:
Copied!
AsyncNodeActionWithConfig<State> simpleAction() {
return node_async( ( state, config ) -> Map.of( "messages", config.nodeId() ) );
}
var log = LoggerFactory.getLogger("LG4J");
var workflow = new StateGraph<>(MessagesState.SCHEMA, State::new)
.addWrapCallNodeHook( new LoggingNodeHook<>(log) )
.addNode("node_1", simpleAction() )
.addNode("node_2", simpleAction() )
.addNode("node_3", simpleAction() )
.addNode("node_4", simpleAction() )
.addEdge(START, "node_1")
.addEdge("node_1", "node_2")
.addEdge("node_2", "node_3")
.addEdge("node_3", "node_4")
.addEdge("node_4", END)
.compile();
var result = workflow.invoke( GraphInput.noArgs(), RunnableConfig.builder().build());
log.info( "Workflow execution result:{}", result.orElseThrow() );
AsyncNodeActionWithConfig simpleAction() {
return node_async( ( state, config ) -> Map.of( "messages", config.nodeId() ) );
}
var log = LoggerFactory.getLogger("LG4J");
var workflow = new StateGraph<>(MessagesState.SCHEMA, State::new)
.addWrapCallNodeHook( new LoggingNodeHook<>(log) )
.addNode("node_1", simpleAction() )
.addNode("node_2", simpleAction() )
.addNode("node_3", simpleAction() )
.addNode("node_4", simpleAction() )
.addEdge(START, "node_1")
.addEdge("node_1", "node_2")
.addEdge("node_2", "node_3")
.addEdge("node_3", "node_4")
.addEdge("node_4", END)
.compile();
var result = workflow.invoke( GraphInput.noArgs(), RunnableConfig.builder().build());
log.info( "Workflow execution result:{}", result.orElseThrow() );
node action fo node 'node_1' start with state:%n{
messages=[]
}
node action fo node 'node_1' end with request update:%n{
messages=node_1
}
node action fo node 'node_2' start with state:%n{
messages=[
node_1
]
}
node action fo node 'node_2' end with request update:%n{
messages=node_2
}
node action fo node 'node_3' start with state:%n{
messages=[
node_1
node_2
]
}
node action fo node 'node_3' end with request update:%n{
messages=node_3
}
node action fo node 'node_4' start with state:%n{
messages=[
node_1
node_2
node_3
]
}
node action fo node 'node_4' end with request update:%n{
messages=node_4
}
Workflow execution result:{
messages=[
node_1
node_2
node_3
node_4
]
}