0
# Configuration
1
2
Configure graph compilation and execution behavior with interrupts, thread management, metadata handling, and runtime control options.
3
4
## Capabilities
5
6
### Compile Configuration
7
8
Configure how graphs are compiled and prepared for execution.
9
10
```java { .api }
11
/**
12
* Configuration for graph compilation behavior
13
*/
14
class CompileConfig {
15
/**
16
* Creates new configuration builder
17
* @return Builder instance for configuration
18
*/
19
static Builder builder();
20
21
/**
22
* Creates builder from existing configuration
23
* @param config Base configuration to copy
24
* @return Builder with copied configuration
25
*/
26
static Builder builder(CompileConfig config);
27
28
/**
29
* Get configured checkpoint saver
30
* @return Optional containing checkpoint saver if configured
31
*/
32
Optional<BaseCheckpointSaver> checkpointSaver();
33
34
/**
35
* Get nodes where execution should interrupt before execution
36
* @return Unmodifiable set of node IDs for before-interruption
37
*/
38
Set<String> interruptsBefore();
39
40
/**
41
* Get nodes where execution should interrupt after execution
42
* @return Unmodifiable set of node IDs for after-interruption
43
*/
44
Set<String> interruptsAfter();
45
46
/**
47
* Check if threads should be released after execution
48
* @return true if thread release is enabled
49
*/
50
boolean releaseThread();
51
52
/**
53
* Check if interruption should occur before evaluating conditional edges
54
* @return true if edge interruption is enabled
55
*/
56
boolean interruptBeforeEdge();
57
}
58
```
59
60
**Usage Examples:**
61
62
```java
63
// Basic compilation configuration
64
CompileConfig basicConfig = CompileConfig.builder()
65
.checkpointSaver(new MemorySaver())
66
.build();
67
68
// Advanced configuration with interruptions
69
CompileConfig advancedConfig = CompileConfig.builder()
70
.checkpointSaver(new FileSystemSaver(Paths.get("/app/checkpoints")))
71
.interruptBefore("human_review", "approval_step")
72
.interruptAfter("critical_operation", "data_validation")
73
.releaseThread(true)
74
.interruptBeforeEdge(true)
75
.build();
76
77
// Copy and modify existing configuration
78
CompileConfig modifiedConfig = CompileConfig.builder(advancedConfig)
79
.interruptBefore("additional_node")
80
.build();
81
82
// Compile graph with configuration
83
CompiledGraph<MyState> app = workflow.compile(advancedConfig);
84
```
85
86
### Compile Configuration Builder
87
88
Fluent builder for constructing compile configurations.
89
90
```java { .api }
91
/**
92
* Builder for CompileConfig instances
93
*/
94
class CompileConfig.Builder {
95
/**
96
* Sets checkpoint saver for persistent state
97
* @param checkpointSaver Checkpoint saver implementation
98
* @return Builder for method chaining
99
*/
100
Builder checkpointSaver(BaseCheckpointSaver checkpointSaver);
101
102
/**
103
* Sets nodes to interrupt before execution
104
* @param interruptBefore Node IDs to interrupt before
105
* @return Builder for method chaining
106
*/
107
Builder interruptBefore(String... interruptBefore);
108
109
/**
110
* Sets nodes to interrupt after execution
111
* @param interruptAfter Node IDs to interrupt after
112
* @return Builder for method chaining
113
*/
114
Builder interruptAfter(String... interruptAfter);
115
116
/**
117
* Sets collection of nodes to interrupt before execution
118
* @param interruptsBefore Collection of node IDs
119
* @return Builder for method chaining
120
*/
121
Builder interruptsBefore(Collection<String> interruptsBefore);
122
123
/**
124
* Sets collection of nodes to interrupt after execution
125
* @param interruptsAfter Collection of node IDs
126
* @return Builder for method chaining
127
*/
128
Builder interruptsAfter(Collection<String> interruptsAfter);
129
130
/**
131
* Enables/disables thread release after execution
132
* @param releaseThread Whether to release threads
133
* @return Builder for method chaining
134
*/
135
Builder releaseThread(boolean releaseThread);
136
137
/**
138
* Configures interruption before evaluating conditional edges
139
* @param interruptBeforeEdge Whether to interrupt before edges
140
* @return Builder for method chaining
141
*/
142
Builder interruptBeforeEdge(boolean interruptBeforeEdge);
143
144
/**
145
* Builds the configuration
146
* @return Configured CompileConfig instance
147
*/
148
CompileConfig build();
149
}
150
```
151
152
**Usage Examples:**
153
154
```java
155
// Step-by-step configuration
156
CompileConfig.Builder builder = CompileConfig.builder();
157
158
builder.checkpointSaver(new MemorySaver());
159
builder.interruptBefore("review_step", "approval_gate");
160
builder.interruptAfter("data_processing");
161
builder.releaseThread(true);
162
163
CompileConfig config = builder.build();
164
165
// Fluent configuration
166
CompileConfig fluentConfig = CompileConfig.builder()
167
.checkpointSaver(new FileSystemSaver(Paths.get("/tmp/checkpoints")))
168
.interruptBefore("human_input")
169
.interruptAfter("critical_step")
170
.interruptBeforeEdge(false)
171
.releaseThread(false)
172
.build();
173
174
// Configuration with collections
175
Set<String> beforeNodes = Set.of("node1", "node2", "node3");
176
Set<String> afterNodes = Set.of("nodeA", "nodeB");
177
178
CompileConfig collectionConfig = CompileConfig.builder()
179
.interruptsBefore(beforeNodes)
180
.interruptsAfter(afterNodes)
181
.build();
182
```
183
184
### Runtime Configuration
185
186
Configure individual graph execution instances with thread management and metadata.
187
188
```java { .api }
189
/**
190
* Configuration for individual graph execution runs
191
*/
192
final class RunnableConfig implements HasMetadata {
193
/**
194
* Reserved metadata key for studio environment detection
195
*/
196
static final String STUDIO_METADATA_KEY = "__STUDIO_MDK__";
197
198
/**
199
* Creates new configuration builder
200
* @return Builder instance
201
*/
202
static Builder builder();
203
204
/**
205
* Creates builder from existing configuration
206
* @param config Base configuration to copy
207
* @return Builder with copied configuration
208
*/
209
static Builder builder(RunnableConfig config);
210
211
/**
212
* Get thread identifier for this execution
213
* @return Optional containing thread ID if set
214
*/
215
Optional<String> threadId();
216
217
/**
218
* Get checkpoint identifier for resumption
219
* @return Optional containing checkpoint ID if set
220
*/
221
Optional<String> checkPointId();
222
223
/**
224
* Get next node identifier for directed execution
225
* @return Optional containing next node ID if set
226
*/
227
Optional<String> nextNode();
228
229
/**
230
* Get stream mode for execution output
231
* @return Stream mode (VALUES or SNAPSHOTS)
232
*/
233
CompiledGraph.StreamMode streamMode();
234
235
/**
236
* Get metadata value by key
237
* @param key Metadata key
238
* @return Optional containing metadata value
239
*/
240
Optional<Object> metadata(String key);
241
242
/**
243
* Check if execution is running in studio environment
244
* @return true if studio environment detected
245
*/
246
boolean isRunningInStudio();
247
248
/**
249
* Create new configuration with different stream mode
250
* @param streamMode New stream mode
251
* @return New configuration instance
252
*/
253
RunnableConfig withStreamMode(CompiledGraph.StreamMode streamMode);
254
255
/**
256
* Create new configuration with different checkpoint ID
257
* @param checkPointId New checkpoint ID
258
* @return New configuration instance
259
*/
260
RunnableConfig withCheckPointId(String checkPointId);
261
}
262
```
263
264
**Usage Examples:**
265
266
```java
267
// Basic runtime configuration
268
RunnableConfig basicRunConfig = RunnableConfig.builder()
269
.threadId("user-session-123")
270
.build();
271
272
// Advanced configuration with metadata
273
RunnableConfig advancedRunConfig = RunnableConfig.builder()
274
.threadId("advanced-session")
275
.checkPointId("checkpoint-abc123")
276
.streamMode(CompiledGraph.StreamMode.SNAPSHOTS)
277
.addMetadata("user_id", "user123")
278
.addMetadata("session_type", "interactive")
279
.build();
280
281
// Use in graph execution
282
Optional<MyState> result = app.invoke(Map.of("input", "data"), basicRunConfig);
283
284
// Check metadata
285
String userId = advancedRunConfig.metadata("user_id")
286
.map(Object::toString)
287
.orElse("anonymous");
288
289
// Modify configuration
290
RunnableConfig snapshotConfig = basicRunConfig.withStreamMode(
291
CompiledGraph.StreamMode.SNAPSHOTS
292
);
293
```
294
295
### Runtime Configuration Builder
296
297
Fluent builder for runtime configurations with metadata support.
298
299
```java { .api }
300
/**
301
* Builder for RunnableConfig instances with metadata support
302
*/
303
class RunnableConfig.Builder extends HasMetadata.Builder<RunnableConfig.Builder> {
304
/**
305
* Sets thread identifier
306
* @param threadId Thread ID for execution
307
* @return Builder for method chaining
308
*/
309
Builder threadId(String threadId);
310
311
/**
312
* Sets checkpoint identifier for resumption
313
* @param checkPointId Checkpoint ID
314
* @return Builder for method chaining
315
*/
316
Builder checkPointId(String checkPointId);
317
318
/**
319
* Sets next node for directed execution
320
* @param nextNode Next node ID
321
* @return Builder for method chaining
322
*/
323
Builder nextNode(String nextNode);
324
325
/**
326
* Sets stream mode for output
327
* @param streamMode Stream mode (VALUES or SNAPSHOTS)
328
* @return Builder for method chaining
329
*/
330
Builder streamMode(CompiledGraph.StreamMode streamMode);
331
332
/**
333
* Adds custom executor for parallel node
334
* @param nodeId Parallel node ID
335
* @param executor Executor for parallel execution
336
* @return Builder for method chaining
337
*/
338
Builder addParallelNodeExecutor(String nodeId, Executor executor);
339
340
/**
341
* Builds the configuration
342
* @return Configured RunnableConfig instance
343
*/
344
RunnableConfig build();
345
}
346
```
347
348
**Usage Examples:**
349
350
```java
351
import java.util.concurrent.Executors;
352
353
// Step-by-step configuration
354
RunnableConfig.Builder builder = RunnableConfig.builder();
355
builder.threadId("session-456");
356
builder.streamMode(CompiledGraph.StreamMode.VALUES);
357
builder.addMetadata("priority", "high");
358
builder.addMetadata("timeout", 30000);
359
360
RunnableConfig config = builder.build();
361
362
// Parallel execution configuration
363
RunnableConfig parallelConfig = RunnableConfig.builder()
364
.threadId("parallel-session")
365
.addParallelNodeExecutor("data_processor", Executors.newFixedThreadPool(4))
366
.addParallelNodeExecutor("file_handler", Executors.newCachedThreadPool())
367
.build();
368
369
// Resumption configuration
370
RunnableConfig resumeConfig = RunnableConfig.builder()
371
.threadId("interrupted-session")
372
.checkPointId("checkpoint-xyz789")
373
.nextNode("resume_point")
374
.build();
375
```
376
377
### Metadata Management
378
379
Handle custom metadata for execution context and configuration.
380
381
```java { .api }
382
/**
383
* Interface for objects that can hold metadata
384
*/
385
interface HasMetadata {
386
/**
387
* Get metadata value by key
388
* @param key Metadata key
389
* @return Optional containing metadata value
390
*/
391
Optional<Object> metadata(String key);
392
393
/**
394
* Get typed metadata value by key
395
* @param key Metadata key
396
* @param typeRef Type reference for casting
397
* @return Optional containing typed metadata value
398
*/
399
default <T> Optional<T> metadata(String key, TypeRef<T> typeRef) {
400
return metadata(key).flatMap(typeRef::cast);
401
}
402
403
/**
404
* Base builder class for metadata-aware objects
405
*/
406
abstract class Builder<T extends Builder<T>> {
407
/**
408
* Add metadata key-value pair
409
* @param key Metadata key
410
* @param value Metadata value
411
* @return Builder for method chaining
412
*/
413
T addMetadata(String key, Object value);
414
415
/**
416
* Get current metadata map
417
* @return Current metadata
418
*/
419
Map<String, Object> metadata();
420
}
421
}
422
```
423
424
**Usage Examples:**
425
426
```java
427
// Add various metadata types
428
RunnableConfig configWithMetadata = RunnableConfig.builder()
429
.threadId("metadata-session")
430
.addMetadata("user_id", "user123")
431
.addMetadata("priority", 5)
432
.addMetadata("timeout", Duration.ofMinutes(10))
433
.addMetadata("features", List.of("feature1", "feature2"))
434
.addMetadata("config", Map.of("debug", true, "verbose", false))
435
.build();
436
437
// Access metadata in actions
438
AsyncNodeActionWithConfig<MyState> metadataAwareAction = (state, config) -> {
439
// Get user ID
440
String userId = config.metadata("user_id")
441
.map(Object::toString)
442
.orElse("anonymous");
443
444
// Get priority with type safety
445
Optional<Integer> priority = config.metadata("priority", new TypeRef<Integer>() {});
446
447
// Get features list
448
Optional<List<String>> features = config.metadata("features", new TypeRef<List<String>>() {});
449
450
Map<String, Object> updates = new HashMap<>();
451
updates.put("user_id", userId);
452
priority.ifPresent(p -> updates.put("priority_level", p));
453
features.ifPresent(f -> updates.put("enabled_features", f));
454
455
return CompletableFuture.completedFuture(updates);
456
};
457
```
458
459
### Stream Mode Configuration
460
461
Control how execution outputs are delivered.
462
463
```java { .api }
464
/**
465
* Stream modes for execution output
466
*/
467
enum CompiledGraph.StreamMode {
468
/**
469
* Stream node execution outputs with state
470
*/
471
VALUES,
472
473
/**
474
* Stream state snapshots with checkpoint information
475
*/
476
SNAPSHOTS
477
}
478
```
479
480
**Usage Examples:**
481
482
```java
483
// Configuration for different stream modes
484
RunnableConfig valuesConfig = RunnableConfig.builder()
485
.threadId("values-session")
486
.streamMode(CompiledGraph.StreamMode.VALUES)
487
.build();
488
489
RunnableConfig snapshotsConfig = RunnableConfig.builder()
490
.threadId("snapshots-session")
491
.streamMode(CompiledGraph.StreamMode.SNAPSHOTS)
492
.build();
493
494
// Stream with VALUES mode
495
AsyncGenerator<NodeOutput<MyState>> valuesStream = app.stream(
496
Map.of("input", "data"),
497
valuesConfig
498
);
499
500
valuesStream.forEachAsync(output -> {
501
System.out.println("Node: " + output.node());
502
System.out.println("State: " + output.state().data());
503
return CompletableFuture.completedFuture(null);
504
});
505
506
// Stream with SNAPSHOTS mode
507
AsyncGenerator<NodeOutput<MyState>> snapshotsStream = app.stream(
508
Map.of("input", "data"),
509
snapshotsConfig
510
);
511
512
snapshotsStream.forEachAsync(output -> {
513
if (output instanceof StateSnapshot) {
514
StateSnapshot<MyState> snapshot = (StateSnapshot<MyState>) output;
515
System.out.println("Checkpoint: " + snapshot.getCheckpointId());
516
System.out.println("Node: " + snapshot.getNodeId());
517
System.out.println("Next: " + snapshot.getNextNodeId());
518
}
519
return CompletableFuture.completedFuture(null);
520
});
521
```
522
523
## Configuration Patterns
524
525
### Development vs Production Configuration
526
527
Different configurations for different environments.
528
529
```java { .api }
530
// Development configuration with debugging
531
CompileConfig developmentConfig = CompileConfig.builder()
532
.checkpointSaver(new MemorySaver())
533
.interruptBefore("debug_point")
534
.releaseThread(false) // Keep threads for debugging
535
.build();
536
537
// Production configuration with persistence
538
CompileConfig productionConfig = CompileConfig.builder()
539
.checkpointSaver(new FileSystemSaver(Paths.get("/var/app/checkpoints")))
540
.releaseThread(true) // Release threads to save memory
541
.interruptBeforeEdge(false) // No debugging interrupts
542
.build();
543
544
// Environment-based configuration
545
boolean isProduction = "production".equals(System.getenv("ENVIRONMENT"));
546
CompileConfig config = isProduction ? productionConfig : developmentConfig;
547
```
548
549
### User Session Management
550
551
Configure execution for different user contexts.
552
553
```java { .api }
554
// User-specific configuration factory
555
public class UserConfigFactory {
556
public static RunnableConfig createUserConfig(String userId, UserRole role) {
557
RunnableConfig.Builder builder = RunnableConfig.builder()
558
.threadId("user-" + userId)
559
.addMetadata("user_id", userId)
560
.addMetadata("role", role.name())
561
.addMetadata("session_start", System.currentTimeMillis());
562
563
// Add role-specific configuration
564
switch (role) {
565
case ADMIN:
566
builder.addMetadata("permissions", Set.of("read", "write", "delete"));
567
builder.streamMode(CompiledGraph.StreamMode.SNAPSHOTS); // Debug info
568
break;
569
case USER:
570
builder.addMetadata("permissions", Set.of("read"));
571
builder.streamMode(CompiledGraph.StreamMode.VALUES);
572
break;
573
}
574
575
return builder.build();
576
}
577
}
578
579
// Usage
580
RunnableConfig adminConfig = UserConfigFactory.createUserConfig("admin123", UserRole.ADMIN);
581
RunnableConfig userConfig = UserConfigFactory.createUserConfig("user456", UserRole.USER);
582
```
583
584
### Conditional Interruption Configuration
585
586
Configure interruptions based on runtime conditions.
587
588
```java { .api }
589
// Conditional interruption helper
590
public class ConditionalInterrupts {
591
public static CompileConfig createConditionalConfig(boolean debugMode, boolean requireApproval) {
592
CompileConfig.Builder builder = CompileConfig.builder()
593
.checkpointSaver(new MemorySaver());
594
595
if (debugMode) {
596
builder.interruptBefore("validation", "processing", "output");
597
builder.interruptBeforeEdge(true);
598
}
599
600
if (requireApproval) {
601
builder.interruptAfter("user_input", "data_modification");
602
}
603
604
return builder.build();
605
}
606
}
607
608
// Usage based on user preferences
609
boolean debugEnabled = user.getPreferences().isDebugEnabled();
610
boolean approvalRequired = user.hasRole("REQUIRES_APPROVAL");
611
612
CompileConfig config = ConditionalInterrupts.createConditionalConfig(debugEnabled, approvalRequired);
613
CompiledGraph<MyState> app = workflow.compile(config);
614
```