From 601fa634f47164d02fedb872582b9583d6b01eff Mon Sep 17 00:00:00 2001 From: Dmitrii Tikhomirov Date: Thu, 25 Sep 2025 14:24:15 -0700 Subject: [PATCH 1/6] add better docs about Langchain4g/ServerlessWorkflow Signed-off-by: Dmitrii Tikhomirov --- .../fluent/agentic/dsl/AgenticDSL.java | 2 +- .../fluent/agentic/LC4JEquivalenceIT.java | 8 +- .../fluent/agentic/README.md | 254 ++++++++++++------ 3 files changed, 169 insertions(+), 95 deletions(-) diff --git a/experimental/fluent/agentic/src/main/java/io/serverlessworkflow/fluent/agentic/dsl/AgenticDSL.java b/experimental/fluent/agentic/src/main/java/io/serverlessworkflow/fluent/agentic/dsl/AgenticDSL.java index ccf77f37..d91fb86c 100644 --- a/experimental/fluent/agentic/src/main/java/io/serverlessworkflow/fluent/agentic/dsl/AgenticDSL.java +++ b/experimental/fluent/agentic/src/main/java/io/serverlessworkflow/fluent/agentic/dsl/AgenticDSL.java @@ -122,7 +122,7 @@ public static AgentTaskConfigurer loop(Predicate exitCondition, Ob } public static AgentTaskConfigurer loop( - Predicate exitCondition, int maxIterations, Object... agents) { + int maxIterations, Predicate exitCondition, Object... agents) { return list -> list.loop( l -> l.subAgents(agents).exitCondition(exitCondition).maxIterations(maxIterations)); diff --git a/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/LC4JEquivalenceIT.java b/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/LC4JEquivalenceIT.java index 492b373c..aa059a57 100644 --- a/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/LC4JEquivalenceIT.java +++ b/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/LC4JEquivalenceIT.java @@ -18,6 +18,7 @@ import static io.serverlessworkflow.fluent.agentic.AgentWorkflowBuilder.workflow; import static io.serverlessworkflow.fluent.agentic.dsl.AgenticDSL.conditional; import static io.serverlessworkflow.fluent.agentic.dsl.AgenticDSL.doTasks; +import static io.serverlessworkflow.fluent.agentic.dsl.AgenticDSL.loop; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -45,10 +46,7 @@ public void sequentialWorkflow() { var audienceEditor = AgentsUtils.newAudienceEditor(); var styleEditor = AgentsUtils.newStyleEditor(); - Workflow wf = - workflow("seqFlow") - .sequence("process", creativeWriter, audienceEditor, styleEditor) - .build(); + Workflow wf = workflow("seqFlow").sequence(creativeWriter, audienceEditor, styleEditor).build(); List items = wf.getDo(); assertThat(items).hasSize(3); @@ -118,7 +116,7 @@ public void loopWorkflowWithMaxIterations() { Predicate until = s -> s.readState("score", 0).doubleValue() >= 0.8; - Workflow wf = workflow("retryFlow").loop(until, scorer, 5, editor).build(); + Workflow wf = workflow("retryFlow").tasks(loop(5, until, scorer, editor)).build(); List items = wf.getDo(); assertThat(items).hasSize(1); diff --git a/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/README.md b/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/README.md index a9c2e469..3a635829 100644 --- a/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/README.md +++ b/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/README.md @@ -2,6 +2,8 @@ # Sequential workflow ### Common part: +
Click to expand + ```java public interface AudienceEditor { @@ -65,33 +67,53 @@ Map input = Map.of( "audience", "young adults" ); ``` - -### LangChain4j -```java -UntypedAgent novelCreator = AgenticServices - .sequenceBuilder() - .subAgents(creativeWriter, audienceEditor, styleEditor) - .outputName("story") - .build(); +
+ + + + + + + + -```java -Workflow wf = workflow("seqFlow").sequence("process", creativeWriter, audienceEditor, styleEditor).build(); + + +
LangChain4jServerless Workflow
+
+UntypedAgent novelCreator = AgenticServices
+    .sequenceBuilder()
+    .subAgents(creativeWriter, audienceEditor, styleEditor)
+    .outputName("story")
+    .build();
 
 String story = (String) novelCreator.invoke(input);
-```
 
-### Serverless Workflow
+
+
+
+
+Workflow wf = workflow("seqFlow")
+    .sequence(creativeWriter, audienceEditor, styleEditor)
+    .build();
+ 
+ 
 
 try (WorkflowApplication app = WorkflowApplication.builder().build()) {
     String result = app.workflowDefinition(wf).instance(input).start().get().asText().orElseThrow();
 } catch (Exception e) {
     throw new RuntimeException("Workflow execution failed", e);
 }
-```
+
+
+
+
### Loop workflow ### Common part: +
Click to expand + ```java interface StyleEditor { @@ -136,38 +158,58 @@ StyleScorer styleScorer = AgenticServices ``` -### LangChain4j -```java +
+ + + + + + + + + + +
LangChain4jServerless Workflow
+
+
+ 
+ 
 StyledWriter styledWriter = AgenticServices
-        .sequenceBuilder(StyledWriter.class)
-        .subAgents(creativeWriter, styleReviewLoop)
-        .outputName("story")
-        .build();
+    .sequenceBuilder(StyledWriter.class)
+    .subAgents(creativeWriter, styleReviewLoop)
+    .outputName("story")
+    .build();
 
 String story = styledWriter.writeStoryWithStyle("dragons and wizards", "comedy");
-```
-
-### Serverless Workflow
-```java
-Predicate until = s -> s.readState("score", 0).doubleValue() >= 0.8;
 
-Workflow wf = workflow("retryFlow").loop(until, scorer, 5, editor).build();
+
+
+
+
+Map<String, Object> input =  Map.of("story", "dragons and wizards","style", "comedy");
+Predicate until = s -> s.readState("score", 0).doubleValue() >= 0.8;
 
-Map input =
-        Map.of(
-                "story", "dragons and wizards",
-                "style", "comedy");
-
+Workflow wf = workflow("retryFlow")
+    .loop(until, scorer, editor)
+    .build();
+ 
+ 
+ 
 try (WorkflowApplication app = WorkflowApplication.builder().build()) {
-  String result = app.workflowDefinition(wf).instance(input).start().get().asText().orElseThrow();
+    String result = app.workflowDefinition(wf).instance(input).start().get().asText().orElseThrow();
 } catch (Exception e) {
-  throw new RuntimeException("Workflow execution failed", e);
+    throw new RuntimeException("Workflow execution failed", e);
 }
-```
+
+
+
+
### Parallel workflow ### Common part: +
Click to expand + ```java public interface FoodExpert { @@ -206,65 +248,81 @@ MovieExpert movieExpert = AgenticServices .outputName("movies") .build(); ``` - -### LangChain4j -```java +
+ + + + + + + + + + + + +
LangChain4jServerless Workflow
+
+
 EveningPlannerAgent eveningPlannerAgent = AgenticServices
-        .parallelBuilder(EveningPlannerAgent.class)
-        .subAgents(foodExpert, movieExpert)
-        .executor(Executors.newFixedThreadPool(2))
-        .outputName("plans")
-        .output(agenticScope -> {
-            List movies = agenticScope.readState("movies", List.of());
-            List meals = agenticScope.readState("meals", List.of());
-
-            List moviesAndMeals = new ArrayList<>();
-            for (int i = 0; i < movies.size(); i++) {
-                if (i >= meals.size()) {
-                    break;
-                }
-                moviesAndMeals.add(new EveningPlan(movies.get(i), meals.get(i)));
-            }
-            return moviesAndMeals;
-        })
-        .build();
+    .parallelBuilder(EveningPlannerAgent.class)
+    .subAgents(foodExpert, movieExpert)
+    .executor(Executors.newFixedThreadPool(2))
+    .outputName("plans")
+    .output(agenticScope -> {
+        List movies = agenticScope.readState("movies", List.of());
+        List meals = agenticScope.readState("meals", List.of());
+        List moviesAndMeals = new ArrayList<>();
+        for (int i = 0; i < movies.size(); i++) {
+        if (i >= meals.size()) {
+            break;
+        }
+        moviesAndMeals.add(new EveningPlan(movies.get(i), meals.get(i)));
+        }
+        return moviesAndMeals;
+    })
+    .build();
 
 List plans = eveningPlannerAgent.plan("romantic");
-```
 
-### Serverless Workflow
-```java
-Workflow wf = workflow("forkFlow").parallel("fanout", foodExpert, movieExpert).build();
+
+
+
+
+
+Workflow wf = workflow("forkFlow")
+    .parallel(foodExpert, movieExpert)
+    .build();
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+Map<String, Object> input = Map.of("mood", "I am hungry and bored");
 
-Map input = Map.of("mood", "I am hungry and bored");
-
-Map result;
 try (WorkflowApplication app = WorkflowApplication.builder().build()) {
-    result = app.workflowDefinition(wf).instance(input).start().get().asMap().orElseThrow();
+    Map result = app.workflowDefinition(wf).instance(input).start().get().asMap().orElseThrow();
 } catch (Exception e) {
-   throw new RuntimeException("Workflow execution failed", e);
+    throw new RuntimeException("Workflow execution failed", e);
 }
-```
-
-### Error handling
-### Common part:
-```java
-
-```
-
-### LangChain4j
-```java
-
-```
 
-### Serverless Workflow
+
+
+
-```java - -``` ### Human-in-the-loop ### Common part: +
Click to expand + ```java public record HumanInTheLoop(Consumer requestWriter, Supplier responseReader) { @@ -302,9 +360,17 @@ HumanInTheLoop humanInTheLoop = AgenticServices .responseReader(() -> System.console().readLine()) .build(); ``` - -### LangChain4j -```java +
+ + + + + + + + -```java -Workflow wf = workflow("seqFlow").sequence("process", astrologyAgent, humanInTheLoop).build(); + + +
LangChain4jServerless Workflow
+
+
 SupervisorAgent horoscopeAgent = AgenticServices
         .supervisorBuilder()
         .chatModel(PLANNER_MODEL)
@@ -312,18 +378,28 @@ SupervisorAgent horoscopeAgent = AgenticServices
         .build();
 
 horoscopeAgent.invoke("My name is Mario. What is my horoscope?")
-```
 
-### Serverless Workflow
+
+
+
+
+
+Workflow wf = workflow("seqFlow")
+    .sequence(astrologyAgent, humanInTheLoop)
+    .build();
 
 Map input = Map.of("request", "My name is Mario. What is my horoscope?");
 
 try (WorkflowApplication app = WorkflowApplication.builder().build()) {
-  String result = app.workflowDefinition(wf).instance(input).start().get().asMap().orElseThrow();
+    String result = app.workflowDefinition(wf).instance(input).start().get().asMap().orElseThrow();
 } catch (Exception e) {
-  throw new RuntimeException("Workflow execution failed", e);
+    throw new RuntimeException("Workflow execution failed", e);
 }
-```
\ No newline at end of file
+
+
+
+
\ No newline at end of file From 562e9d88054ea68da302c2d99bad802077887afa Mon Sep 17 00:00:00 2001 From: Dmitrii Tikhomirov Date: Thu, 25 Sep 2025 14:50:05 -0700 Subject: [PATCH 2/6] no try-catch-blocks Signed-off-by: Dmitrii Tikhomirov --- .../fluent/agentic/README.md | 29 +++++-------------- 1 file changed, 7 insertions(+), 22 deletions(-) diff --git a/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/README.md b/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/README.md index 3a635829..ea4d8fe1 100644 --- a/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/README.md +++ b/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/README.md @@ -97,11 +97,7 @@ String story = (String) novelCreator.invoke(input);     -try (WorkflowApplication app = WorkflowApplication.builder().build()) { - String result = app.workflowDefinition(wf).instance(input).start().get().asText().orElseThrow(); -} catch (Exception e) { - throw new RuntimeException("Workflow execution failed", e); -} +String result = app.workflowDefinition(wf).instance(input).start().get().asText().orElseThrow(); @@ -194,11 +190,7 @@ Workflow wf = workflow("retryFlow")       -try (WorkflowApplication app = WorkflowApplication.builder().build()) { - String result = app.workflowDefinition(wf).instance(input).start().get().asText().orElseThrow(); -} catch (Exception e) { - throw new RuntimeException("Workflow execution failed", e); -} +String result = app.workflowDefinition(wf).instance(input).start().get().asText().orElseThrow(); @@ -304,13 +296,10 @@ Workflow wf = workflow("forkFlow")       +  Map<String, Object> input = Map.of("mood", "I am hungry and bored"); -try (WorkflowApplication app = WorkflowApplication.builder().build()) { - Map result = app.workflowDefinition(wf).instance(input).start().get().asMap().orElseThrow(); -} catch (Exception e) { - throw new RuntimeException("Workflow execution failed", e); -} +Map result = app.workflowDefinition(wf).instance(input).start().get().asMap().orElseThrow(); @@ -390,13 +379,9 @@ Workflow wf = workflow("seqFlow") .sequence(astrologyAgent, humanInTheLoop) .build(); -Map input = Map.of("request", "My name is Mario. What is my horoscope?"); - -try (WorkflowApplication app = WorkflowApplication.builder().build()) { - String result = app.workflowDefinition(wf).instance(input).start().get().asMap().orElseThrow(); -} catch (Exception e) { - throw new RuntimeException("Workflow execution failed", e); -} +  +  +String result = app.workflowDefinition(wf).instance("My name is Mario. What is my horoscope?").start().get().asMap().orElseThrow(); From db5218ca03c5ab3876af170bd8d3d22335ac04df Mon Sep 17 00:00:00 2001 From: Dmitrii Tikhomirov Date: Thu, 25 Sep 2025 16:42:20 -0700 Subject: [PATCH 3/6] next step Signed-off-by: Dmitrii Tikhomirov --- .../fluent/agentic/LC4JEquivalenceIT.java | 13 +++++--- .../fluent/agentic/README.md | 30 ++++++++++++------- 2 files changed, 28 insertions(+), 15 deletions(-) diff --git a/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/LC4JEquivalenceIT.java b/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/LC4JEquivalenceIT.java index aa059a57..452e2218 100644 --- a/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/LC4JEquivalenceIT.java +++ b/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/LC4JEquivalenceIT.java @@ -75,13 +75,18 @@ public void sequentialWorkflow() { @Test @DisplayName("Looping agents via DSL.loop(...)") public void loopWorkflow() { - - var scorer = AgentsUtils.newStyleScorer(); - var editor = AgentsUtils.newStyleEditor(); + var creativeWriter = AgentsUtils.newCreativeWriter(); + var styleScorer = AgentsUtils.newStyleScorer(); + var styleEditor = AgentsUtils.newStyleEditor(); Workflow wf = AgentWorkflowBuilder.workflow("retryFlow") - .loop("reviewLoop", c -> c.readState("score", 0).doubleValue() >= 0.8, scorer, editor) + .agent(creativeWriter) + .loop( + "reviewLoop", + c -> c.readState("score", 0).doubleValue() >= 0.8, + styleScorer, + styleEditor) .build(); List items = wf.getDo(); diff --git a/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/README.md b/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/README.md index ea4d8fe1..824e3b49 100644 --- a/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/README.md +++ b/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/README.md @@ -164,14 +164,18 @@ StyleScorer styleScorer = AgenticServices
-
- 
- 
+UntypedAgent styleReviewLoop = AgenticServices
+        .loopBuilder()
+        .subAgents(styleScorer, styleEditor)
+        .maxIterations(5)
+        .exitCondition(agenticScope -> agenticScope.readState("score", 0.0) >= 0.8)
+        .build();
+
 StyledWriter styledWriter = AgenticServices
-    .sequenceBuilder(StyledWriter.class)
-    .subAgents(creativeWriter, styleReviewLoop)
-    .outputName("story")
-    .build();
+        .sequenceBuilder(StyledWriter.class)
+        .subAgents(creativeWriter, styleReviewLoop)
+        .outputName("story")
+        .build();
 
 String story = styledWriter.writeStoryWithStyle("dragons and wizards", "comedy");
 
@@ -183,13 +187,17 @@ String story = styledWriter.writeStoryWithStyle("dragons and wizards", "comedy")
 
 Map<String, Object> input =  Map.of("story", "dragons and wizards","style", "comedy");
 Predicate until = s -> s.readState("score", 0).doubleValue() >= 0.8;
-
-Workflow wf = workflow("retryFlow")
-    .loop(until, scorer, editor)
-    .build();
  
  
  
+ 
+ 
+ 
+Workflow wf = workflow("retryFlow")
+    .agent(creativeWriter)
+    .loop(until, styleScorer, styleEditor)
+    .build();
+ 
 String result = app.workflowDefinition(wf).instance(input).start().get().asText().orElseThrow();
 
 

From 40fbfcbcdae916809fd244da9232549de4363001 Mon Sep 17 00:00:00 2001
From: Dmitrii Tikhomirov 
Date: Thu, 25 Sep 2025 18:26:38 -0700
Subject: [PATCH 4/6] we can do better

Signed-off-by: Dmitrii Tikhomirov 
---
 .../fluent/agentic/LC4JEquivalenceIT.java     | 40 ++++++++++++++++++-
 .../fluent/agentic/README.md                  | 24 +++++------
 2 files changed, 51 insertions(+), 13 deletions(-)

diff --git a/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/LC4JEquivalenceIT.java b/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/LC4JEquivalenceIT.java
index 452e2218..56fe2529 100644
--- a/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/LC4JEquivalenceIT.java
+++ b/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/LC4JEquivalenceIT.java
@@ -18,6 +18,7 @@
 import static io.serverlessworkflow.fluent.agentic.AgentWorkflowBuilder.workflow;
 import static io.serverlessworkflow.fluent.agentic.dsl.AgenticDSL.conditional;
 import static io.serverlessworkflow.fluent.agentic.dsl.AgenticDSL.doTasks;
+import static io.serverlessworkflow.fluent.agentic.dsl.AgenticDSL.fn;
 import static io.serverlessworkflow.fluent.agentic.dsl.AgenticDSL.loop;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -30,6 +31,7 @@
 import io.serverlessworkflow.api.types.func.CallTaskJava;
 import io.serverlessworkflow.api.types.func.ForTaskFunction;
 import io.serverlessworkflow.impl.WorkflowApplication;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.atomic.AtomicReference;
@@ -147,13 +149,49 @@ public void loopWorkflowWithMaxIterations() {
     assertThat(result).containsKey("story");
   }
 
+  public record EveningPlan(String movie, String meal) {}
+
   @Test
   @DisplayName("Parallel agents via DSL.parallel(...)")
   public void parallelWorkflow() {
     var foodExpert = AgentsUtils.newFoodExpert();
     var movieExpert = AgentsUtils.newMovieExpert();
 
-    Workflow wf = workflow("forkFlow").parallel("fanout", foodExpert, movieExpert).build();
+    workflow("forkFlow")
+        .tasks(
+            d ->
+                d.parallel(foodExpert, movieExpert)
+                    .callFn(
+                        fn(
+                            f -> {
+                              Map> asMap = (Map>) f;
+                              List result = new ArrayList<>();
+                              int max =
+                                  asMap.values().stream()
+                                      .map(List::size)
+                                      .min(Integer::compareTo)
+                                      .orElse(0);
+                              for (int i = 0; i < max; i++) {
+                                result.add(
+                                    new EveningPlan(
+                                        asMap.get("movies").get(i), asMap.get("meals").get(i)));
+                              }
+                              return result;
+                            })))
+        .build();
+
+    Workflow wf = workflow("forkFlow")
+            .tasks(d -> d
+                    .parallel("fanout", foodExpert, movieExpert)
+                    .callFn(fn((Map> m) -> {
+                      var movies = m.getOrDefault("movies", List.of());
+                      var meals  = m.getOrDefault("meals",  List.of());
+                      return java.util.stream.IntStream
+                              .range(0, Math.min(movies.size(), meals.size()))
+                              .mapToObj(i -> new EveningPlan(movies.get(i), meals.get(i)))
+                              .toList();
+                    }))
+            ).build();
 
     List items = wf.getDo();
     assertThat(items).hasSize(1);
diff --git a/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/README.md b/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/README.md
index 824e3b49..d8ca91bd 100644
--- a/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/README.md
+++ b/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/README.md
@@ -288,17 +288,17 @@ List plans = eveningPlannerAgent.plan("romantic");
 
 
 
-Workflow wf = workflow("forkFlow")
-    .parallel(foodExpert, movieExpert)
-    .build();
- 
- 
- 
- 
- 
- 
- 
- 
+    Workflow wf = workflow("forkFlow")
+            .tasks(d -> d.parallel(foodExpert, movieExpert)
+                    .callFn(fn((Map<String, List> m) -> {
+                      var movies = m.getOrDefault("movies", List.of());
+                      var meals  = m.getOrDefault("meals",  List.of());
+                      return java.util.stream.IntStream
+                              .range(0, Math.min(movies.size(), meals.size()))
+                              .mapToObj(i -> new EveningPlan(movies.get(i), meals.get(i)))
+                              .toList();
+                    }))
+            ).build();
  
  
  
@@ -307,7 +307,7 @@ Workflow wf = workflow("forkFlow")
  
 Map<String, Object> input = Map.of("mood", "I am hungry and bored");
 
-Map result = app.workflowDefinition(wf).instance(input).start().get().asMap().orElseThrow();
+List result = app.workflowDefinition(wf).instance(input).start().get().asMap().orElseThrow();
 
 
 
From 57604939f7b4b937512847ba9743e6c7274ec7cf Mon Sep 17 00:00:00 2001 From: Dmitrii Tikhomirov Date: Thu, 25 Sep 2025 18:29:52 -0700 Subject: [PATCH 5/6] fix style Signed-off-by: Dmitrii Tikhomirov --- .../fluent/agentic/LC4JEquivalenceIT.java | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/LC4JEquivalenceIT.java b/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/LC4JEquivalenceIT.java index 56fe2529..90ee0f6a 100644 --- a/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/LC4JEquivalenceIT.java +++ b/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/LC4JEquivalenceIT.java @@ -180,18 +180,22 @@ public void parallelWorkflow() { }))) .build(); - Workflow wf = workflow("forkFlow") - .tasks(d -> d - .parallel("fanout", foodExpert, movieExpert) - .callFn(fn((Map> m) -> { - var movies = m.getOrDefault("movies", List.of()); - var meals = m.getOrDefault("meals", List.of()); - return java.util.stream.IntStream - .range(0, Math.min(movies.size(), meals.size())) - .mapToObj(i -> new EveningPlan(movies.get(i), meals.get(i))) - .toList(); - })) - ).build(); + Workflow wf = + workflow("forkFlow") + .tasks( + d -> + d.parallel("fanout", foodExpert, movieExpert) + .callFn( + fn( + (Map> m) -> { + var movies = m.getOrDefault("movies", List.of()); + var meals = m.getOrDefault("meals", List.of()); + return java.util.stream.IntStream.range( + 0, Math.min(movies.size(), meals.size())) + .mapToObj(i -> new EveningPlan(movies.get(i), meals.get(i))) + .toList(); + }))) + .build(); List items = wf.getDo(); assertThat(items).hasSize(1); From dd8b0f28d3e03b7b3e447b3fa1f232e074a6844d Mon Sep 17 00:00:00 2001 From: Dmitrii Tikhomirov Date: Thu, 25 Sep 2025 18:45:37 -0700 Subject: [PATCH 6/6] missed maxIterations Signed-off-by: Dmitrii Tikhomirov --- .../java/io/serverlessworkflow/fluent/agentic/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/README.md b/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/README.md index d8ca91bd..2d1d0319 100644 --- a/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/README.md +++ b/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/README.md @@ -194,9 +194,9 @@ Predicate until = s -> s.readState("score", 0).doubleValue() >= 0.     Workflow wf = workflow("retryFlow") - .agent(creativeWriter) - .loop(until, styleScorer, styleEditor) - .build(); + .agent(creativeWriter) + .tasks(loop(5, c -> c.readState("score", 0).doubleValue() >= 0.8, styleScorer, styleEditor)) + .build();   String result = app.workflowDefinition(wf).instance(input).start().get().asText().orElseThrow();