Add langgraph4j module: a loan-approval graph with checkpoints and human-in-the-loop on LangGraph4j 1.9.5

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01RjfyTgmERTWLqzafu34Cth
This commit is contained in:
2026-10-14 06:47:05 +00:00
co-authored by Claude Sonnet 5.5
parent 280cbe7d56
commit 3b52a434f5
13 changed files with 364 additions and 0 deletions
@@ -0,0 +1,43 @@
package com.ankurm.lg4j;
import org.bsc.langgraph4j.state.AgentState;
import org.bsc.langgraph4j.state.Channel;
import org.bsc.langgraph4j.state.Channels;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* The shared state every node reads and writes.
*
* <p>State is just a {@code Map<String,Object>} with typed accessors. A key with an
* <em>appender</em> channel ({@code trail}) accumulates values; any other key is
* overwritten by the latest node that writes it.
*/
public class LoanState extends AgentState {
public static final String APPLICANT = "applicant";
public static final String AMOUNT = "amount";
public static final String INCOME = "income";
public static final String CREDIT_SCORE = "creditScore";
public static final String RISK = "risk";
public static final String DECISION = "decision";
public static final String TRAIL = "trail";
/** Channel schema: {@code trail} appends, everything else replaces. */
public static final Map<String, Channel<?>> SCHEMA =
Map.of(TRAIL, Channels.appender(ArrayList::new));
public LoanState(Map<String, Object> data) {
super(data);
}
public String applicant() { return this.<String>value(APPLICANT).orElse("?"); }
public int amount() { return this.<Integer>value(AMOUNT).orElse(0); }
public int income() { return this.<Integer>value(INCOME).orElse(0); }
public int creditScore() { return this.<Integer>value(CREDIT_SCORE).orElse(0); }
public String risk() { return this.<String>value(RISK).orElse("UNKNOWN"); }
public String decision() { return this.<String>value(DECISION).orElse("PENDING"); }
public List<String> trail() { return this.<List<String>>value(TRAIL).orElse(List.of()); }
}