CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-bsc-langgraph4j--langgraph4j-core

A library for building stateful, multi-agents applications with LLMs

Overview
Eval results
Files

configuration.mddocs/

Configuration

Configure graph compilation and execution behavior with interrupts, thread management, metadata handling, and runtime control options.

Capabilities

Compile Configuration

Configure how graphs are compiled and prepared for execution.

/**
 * Configuration for graph compilation behavior
 */
class CompileConfig {
    /**
     * Creates new configuration builder
     * @return Builder instance for configuration
     */
    static Builder builder();

    /**
     * Creates builder from existing configuration
     * @param config Base configuration to copy
     * @return Builder with copied configuration
     */
    static Builder builder(CompileConfig config);

    /**
     * Get configured checkpoint saver
     * @return Optional containing checkpoint saver if configured
     */
    Optional<BaseCheckpointSaver> checkpointSaver();

    /**
     * Get nodes where execution should interrupt before execution
     * @return Unmodifiable set of node IDs for before-interruption
     */
    Set<String> interruptsBefore();

    /**
     * Get nodes where execution should interrupt after execution
     * @return Unmodifiable set of node IDs for after-interruption
     */
    Set<String> interruptsAfter();

    /**
     * Check if threads should be released after execution
     * @return true if thread release is enabled
     */
    boolean releaseThread();

    /**
     * Check if interruption should occur before evaluating conditional edges
     * @return true if edge interruption is enabled
     */
    boolean interruptBeforeEdge();
}

Usage Examples:

// Basic compilation configuration
CompileConfig basicConfig = CompileConfig.builder()
    .checkpointSaver(new MemorySaver())
    .build();

// Advanced configuration with interruptions
CompileConfig advancedConfig = CompileConfig.builder()
    .checkpointSaver(new FileSystemSaver(Paths.get("/app/checkpoints")))
    .interruptBefore("human_review", "approval_step")
    .interruptAfter("critical_operation", "data_validation")
    .releaseThread(true)
    .interruptBeforeEdge(true)
    .build();

// Copy and modify existing configuration
CompileConfig modifiedConfig = CompileConfig.builder(advancedConfig)
    .interruptBefore("additional_node")
    .build();

// Compile graph with configuration
CompiledGraph<MyState> app = workflow.compile(advancedConfig);

Compile Configuration Builder

Fluent builder for constructing compile configurations.

/**
 * Builder for CompileConfig instances
 */
class CompileConfig.Builder {
    /**
     * Sets checkpoint saver for persistent state
     * @param checkpointSaver Checkpoint saver implementation
     * @return Builder for method chaining
     */
    Builder checkpointSaver(BaseCheckpointSaver checkpointSaver);

    /**
     * Sets nodes to interrupt before execution
     * @param interruptBefore Node IDs to interrupt before
     * @return Builder for method chaining
     */
    Builder interruptBefore(String... interruptBefore);

    /**
     * Sets nodes to interrupt after execution
     * @param interruptAfter Node IDs to interrupt after
     * @return Builder for method chaining
     */
    Builder interruptAfter(String... interruptAfter);

    /**
     * Sets collection of nodes to interrupt before execution
     * @param interruptsBefore Collection of node IDs
     * @return Builder for method chaining
     */
    Builder interruptsBefore(Collection<String> interruptsBefore);

    /**
     * Sets collection of nodes to interrupt after execution
     * @param interruptsAfter Collection of node IDs
     * @return Builder for method chaining
     */
    Builder interruptsAfter(Collection<String> interruptsAfter);

    /**
     * Enables/disables thread release after execution
     * @param releaseThread Whether to release threads
     * @return Builder for method chaining
     */
    Builder releaseThread(boolean releaseThread);

    /**
     * Configures interruption before evaluating conditional edges
     * @param interruptBeforeEdge Whether to interrupt before edges
     * @return Builder for method chaining
     */
    Builder interruptBeforeEdge(boolean interruptBeforeEdge);

    /**
     * Builds the configuration
     * @return Configured CompileConfig instance
     */
    CompileConfig build();
}

Usage Examples:

// Step-by-step configuration
CompileConfig.Builder builder = CompileConfig.builder();

builder.checkpointSaver(new MemorySaver());
builder.interruptBefore("review_step", "approval_gate");
builder.interruptAfter("data_processing");
builder.releaseThread(true);

CompileConfig config = builder.build();

// Fluent configuration
CompileConfig fluentConfig = CompileConfig.builder()
    .checkpointSaver(new FileSystemSaver(Paths.get("/tmp/checkpoints")))
    .interruptBefore("human_input")
    .interruptAfter("critical_step")
    .interruptBeforeEdge(false)
    .releaseThread(false)
    .build();

// Configuration with collections
Set<String> beforeNodes = Set.of("node1", "node2", "node3");
Set<String> afterNodes = Set.of("nodeA", "nodeB");

CompileConfig collectionConfig = CompileConfig.builder()
    .interruptsBefore(beforeNodes)
    .interruptsAfter(afterNodes)
    .build();

Runtime Configuration

Configure individual graph execution instances with thread management and metadata.

/**
 * Configuration for individual graph execution runs
 */
final class RunnableConfig implements HasMetadata {
    /**
     * Reserved metadata key for studio environment detection
     */
    static final String STUDIO_METADATA_KEY = "__STUDIO_MDK__";

    /**
     * Creates new configuration builder
     * @return Builder instance
     */
    static Builder builder();

    /**
     * Creates builder from existing configuration
     * @param config Base configuration to copy
     * @return Builder with copied configuration
     */
    static Builder builder(RunnableConfig config);

    /**
     * Get thread identifier for this execution
     * @return Optional containing thread ID if set
     */
    Optional<String> threadId();

    /**
     * Get checkpoint identifier for resumption
     * @return Optional containing checkpoint ID if set
     */
    Optional<String> checkPointId();

    /**
     * Get next node identifier for directed execution
     * @return Optional containing next node ID if set
     */
    Optional<String> nextNode();

    /**
     * Get stream mode for execution output
     * @return Stream mode (VALUES or SNAPSHOTS)
     */
    CompiledGraph.StreamMode streamMode();

    /**
     * Get metadata value by key
     * @param key Metadata key
     * @return Optional containing metadata value
     */
    Optional<Object> metadata(String key);

    /**
     * Check if execution is running in studio environment
     * @return true if studio environment detected
     */
    boolean isRunningInStudio();

    /**
     * Create new configuration with different stream mode
     * @param streamMode New stream mode
     * @return New configuration instance
     */
    RunnableConfig withStreamMode(CompiledGraph.StreamMode streamMode);

    /**
     * Create new configuration with different checkpoint ID
     * @param checkPointId New checkpoint ID
     * @return New configuration instance
     */
    RunnableConfig withCheckPointId(String checkPointId);
}

Usage Examples:

// Basic runtime configuration
RunnableConfig basicRunConfig = RunnableConfig.builder()
    .threadId("user-session-123")
    .build();

// Advanced configuration with metadata
RunnableConfig advancedRunConfig = RunnableConfig.builder()
    .threadId("advanced-session")
    .checkPointId("checkpoint-abc123")
    .streamMode(CompiledGraph.StreamMode.SNAPSHOTS)
    .addMetadata("user_id", "user123")
    .addMetadata("session_type", "interactive")
    .build();

// Use in graph execution
Optional<MyState> result = app.invoke(Map.of("input", "data"), basicRunConfig);

// Check metadata
String userId = advancedRunConfig.metadata("user_id")
    .map(Object::toString)
    .orElse("anonymous");

// Modify configuration
RunnableConfig snapshotConfig = basicRunConfig.withStreamMode(
    CompiledGraph.StreamMode.SNAPSHOTS
);

Runtime Configuration Builder

Fluent builder for runtime configurations with metadata support.

/**
 * Builder for RunnableConfig instances with metadata support
 */
class RunnableConfig.Builder extends HasMetadata.Builder<RunnableConfig.Builder> {
    /**
     * Sets thread identifier
     * @param threadId Thread ID for execution
     * @return Builder for method chaining
     */
    Builder threadId(String threadId);

    /**
     * Sets checkpoint identifier for resumption
     * @param checkPointId Checkpoint ID
     * @return Builder for method chaining
     */
    Builder checkPointId(String checkPointId);

    /**
     * Sets next node for directed execution
     * @param nextNode Next node ID
     * @return Builder for method chaining
     */
    Builder nextNode(String nextNode);

    /**
     * Sets stream mode for output
     * @param streamMode Stream mode (VALUES or SNAPSHOTS)
     * @return Builder for method chaining
     */
    Builder streamMode(CompiledGraph.StreamMode streamMode);

    /**
     * Adds custom executor for parallel node
     * @param nodeId Parallel node ID
     * @param executor Executor for parallel execution
     * @return Builder for method chaining
     */
    Builder addParallelNodeExecutor(String nodeId, Executor executor);

    /**
     * Builds the configuration
     * @return Configured RunnableConfig instance
     */
    RunnableConfig build();
}

Usage Examples:

import java.util.concurrent.Executors;

// Step-by-step configuration
RunnableConfig.Builder builder = RunnableConfig.builder();
builder.threadId("session-456");
builder.streamMode(CompiledGraph.StreamMode.VALUES);
builder.addMetadata("priority", "high");
builder.addMetadata("timeout", 30000);

RunnableConfig config = builder.build();

// Parallel execution configuration
RunnableConfig parallelConfig = RunnableConfig.builder()
    .threadId("parallel-session")
    .addParallelNodeExecutor("data_processor", Executors.newFixedThreadPool(4))
    .addParallelNodeExecutor("file_handler", Executors.newCachedThreadPool())
    .build();

// Resumption configuration
RunnableConfig resumeConfig = RunnableConfig.builder()
    .threadId("interrupted-session")
    .checkPointId("checkpoint-xyz789")
    .nextNode("resume_point")
    .build();

Metadata Management

Handle custom metadata for execution context and configuration.

/**
 * Interface for objects that can hold metadata
 */
interface HasMetadata {
    /**
     * Get metadata value by key
     * @param key Metadata key
     * @return Optional containing metadata value
     */
    Optional<Object> metadata(String key);

    /**
     * Get typed metadata value by key
     * @param key Metadata key
     * @param typeRef Type reference for casting
     * @return Optional containing typed metadata value
     */
    default <T> Optional<T> metadata(String key, TypeRef<T> typeRef) {
        return metadata(key).flatMap(typeRef::cast);
    }

    /**
     * Base builder class for metadata-aware objects
     */
    abstract class Builder<T extends Builder<T>> {
        /**
         * Add metadata key-value pair
         * @param key Metadata key
         * @param value Metadata value
         * @return Builder for method chaining
         */
        T addMetadata(String key, Object value);

        /**
         * Get current metadata map
         * @return Current metadata
         */
        Map<String, Object> metadata();
    }
}

Usage Examples:

// Add various metadata types
RunnableConfig configWithMetadata = RunnableConfig.builder()
    .threadId("metadata-session")
    .addMetadata("user_id", "user123")
    .addMetadata("priority", 5)
    .addMetadata("timeout", Duration.ofMinutes(10))
    .addMetadata("features", List.of("feature1", "feature2"))
    .addMetadata("config", Map.of("debug", true, "verbose", false))
    .build();

// Access metadata in actions
AsyncNodeActionWithConfig<MyState> metadataAwareAction = (state, config) -> {
    // Get user ID
    String userId = config.metadata("user_id")
        .map(Object::toString)
        .orElse("anonymous");

    // Get priority with type safety
    Optional<Integer> priority = config.metadata("priority", new TypeRef<Integer>() {});

    // Get features list
    Optional<List<String>> features = config.metadata("features", new TypeRef<List<String>>() {});

    Map<String, Object> updates = new HashMap<>();
    updates.put("user_id", userId);
    priority.ifPresent(p -> updates.put("priority_level", p));
    features.ifPresent(f -> updates.put("enabled_features", f));

    return CompletableFuture.completedFuture(updates);
};

Stream Mode Configuration

Control how execution outputs are delivered.

/**
 * Stream modes for execution output
 */
enum CompiledGraph.StreamMode {
    /**
     * Stream node execution outputs with state
     */
    VALUES,

    /**
     * Stream state snapshots with checkpoint information
     */
    SNAPSHOTS
}

Usage Examples:

// Configuration for different stream modes
RunnableConfig valuesConfig = RunnableConfig.builder()
    .threadId("values-session")
    .streamMode(CompiledGraph.StreamMode.VALUES)
    .build();

RunnableConfig snapshotsConfig = RunnableConfig.builder()
    .threadId("snapshots-session")
    .streamMode(CompiledGraph.StreamMode.SNAPSHOTS)
    .build();

// Stream with VALUES mode
AsyncGenerator<NodeOutput<MyState>> valuesStream = app.stream(
    Map.of("input", "data"),
    valuesConfig
);

valuesStream.forEachAsync(output -> {
    System.out.println("Node: " + output.node());
    System.out.println("State: " + output.state().data());
    return CompletableFuture.completedFuture(null);
});

// Stream with SNAPSHOTS mode
AsyncGenerator<NodeOutput<MyState>> snapshotsStream = app.stream(
    Map.of("input", "data"),
    snapshotsConfig
);

snapshotsStream.forEachAsync(output -> {
    if (output instanceof StateSnapshot) {
        StateSnapshot<MyState> snapshot = (StateSnapshot<MyState>) output;
        System.out.println("Checkpoint: " + snapshot.getCheckpointId());
        System.out.println("Node: " + snapshot.getNodeId());
        System.out.println("Next: " + snapshot.getNextNodeId());
    }
    return CompletableFuture.completedFuture(null);
});

Configuration Patterns

Development vs Production Configuration

Different configurations for different environments.

// Development configuration with debugging
CompileConfig developmentConfig = CompileConfig.builder()
    .checkpointSaver(new MemorySaver())
    .interruptBefore("debug_point")
    .releaseThread(false) // Keep threads for debugging
    .build();

// Production configuration with persistence
CompileConfig productionConfig = CompileConfig.builder()
    .checkpointSaver(new FileSystemSaver(Paths.get("/var/app/checkpoints")))
    .releaseThread(true) // Release threads to save memory
    .interruptBeforeEdge(false) // No debugging interrupts
    .build();

// Environment-based configuration
boolean isProduction = "production".equals(System.getenv("ENVIRONMENT"));
CompileConfig config = isProduction ? productionConfig : developmentConfig;

User Session Management

Configure execution for different user contexts.

// User-specific configuration factory
public class UserConfigFactory {
    public static RunnableConfig createUserConfig(String userId, UserRole role) {
        RunnableConfig.Builder builder = RunnableConfig.builder()
            .threadId("user-" + userId)
            .addMetadata("user_id", userId)
            .addMetadata("role", role.name())
            .addMetadata("session_start", System.currentTimeMillis());

        // Add role-specific configuration
        switch (role) {
            case ADMIN:
                builder.addMetadata("permissions", Set.of("read", "write", "delete"));
                builder.streamMode(CompiledGraph.StreamMode.SNAPSHOTS); // Debug info
                break;
            case USER:
                builder.addMetadata("permissions", Set.of("read"));
                builder.streamMode(CompiledGraph.StreamMode.VALUES);
                break;
        }

        return builder.build();
    }
}

// Usage
RunnableConfig adminConfig = UserConfigFactory.createUserConfig("admin123", UserRole.ADMIN);
RunnableConfig userConfig = UserConfigFactory.createUserConfig("user456", UserRole.USER);

Conditional Interruption Configuration

Configure interruptions based on runtime conditions.

// Conditional interruption helper
public class ConditionalInterrupts {
    public static CompileConfig createConditionalConfig(boolean debugMode, boolean requireApproval) {
        CompileConfig.Builder builder = CompileConfig.builder()
            .checkpointSaver(new MemorySaver());

        if (debugMode) {
            builder.interruptBefore("validation", "processing", "output");
            builder.interruptBeforeEdge(true);
        }

        if (requireApproval) {
            builder.interruptAfter("user_input", "data_modification");
        }

        return builder.build();
    }
}

// Usage based on user preferences
boolean debugEnabled = user.getPreferences().isDebugEnabled();
boolean approvalRequired = user.hasRole("REQUIRES_APPROVAL");

CompileConfig config = ConditionalInterrupts.createConditionalConfig(debugEnabled, approvalRequired);
CompiledGraph<MyState> app = workflow.compile(config);

Install with Tessl CLI

npx tessl i tessl/maven-org-bsc-langgraph4j--langgraph4j-core

docs

actions.md

checkpoints.md

configuration.md

graph-construction.md

graph-execution.md

index.md

prebuilt.md

state-management.md

tile.json