1818import static io .serverlessworkflow .fluent .agentic .AgentWorkflowBuilder .workflow ;
1919import static io .serverlessworkflow .fluent .agentic .dsl .AgenticDSL .conditional ;
2020import static io .serverlessworkflow .fluent .agentic .dsl .AgenticDSL .doTasks ;
21+ import static io .serverlessworkflow .fluent .agentic .dsl .AgenticDSL .loop ;
2122import static io .serverlessworkflow .fluent .spec .dsl .DSL .tasks ;
2223import static org .assertj .core .api .Assertions .assertThat ;
2324import static org .junit .jupiter .api .Assertions .assertEquals ;
2425
2526import dev .langchain4j .agentic .AgenticServices ;
27+ import dev .langchain4j .agentic .scope .AgenticScope ;
2628import dev .langchain4j .agentic .workflow .HumanInTheLoop ;
2729import io .serverlessworkflow .api .types .FlowDirectiveEnum ;
2830import io .serverlessworkflow .api .types .TaskItem ;
2931import io .serverlessworkflow .api .types .Workflow ;
3032import io .serverlessworkflow .api .types .func .CallTaskJava ;
3133import io .serverlessworkflow .api .types .func .ForTaskFunction ;
34+ import io .serverlessworkflow .fluent .agentic .dsl .AgenticDSL ;
35+ import io .serverlessworkflow .fluent .spec .dsl .DSL ;
3236import io .serverlessworkflow .impl .WorkflowApplication ;
37+
3338import java .util .List ;
3439import java .util .Map ;
3540import java .util .concurrent .atomic .AtomicReference ;
41+ import java .util .function .Predicate ;
42+
3643import org .junit .jupiter .api .DisplayName ;
3744import org .junit .jupiter .api .Test ;
3845
@@ -41,11 +48,11 @@ public class LC4JEquivalenceIT {
4148 @ Test
4249 @ DisplayName ("Sequential agents via DSL.sequence(...)" )
4350 public void sequentialWorkflow () {
44- var a1 = AgentsUtils .newCreativeWriter ();
45- var a2 = AgentsUtils .newAudienceEditor ();
46- var a3 = AgentsUtils .newStyleEditor ();
51+ var creativeWriter = AgentsUtils .newCreativeWriter ();
52+ var audienceEditor = AgentsUtils .newAudienceEditor ();
53+ var styleEditor = AgentsUtils .newStyleEditor ();
4754
48- Workflow wf = workflow ("seqFlow" ).tasks (tasks -> tasks .sequence ("process" , a1 , a2 , a3 )).build ();
55+ Workflow wf = workflow ("seqFlow" ).tasks (tasks -> tasks .sequence ("process" , creativeWriter , audienceEditor , styleEditor )).build ();
4956
5057 List <TaskItem > items = wf .getDo ();
5158 assertThat (items ).hasSize (3 );
@@ -56,10 +63,10 @@ public void sequentialWorkflow() {
5663 items .forEach (it -> assertThat (it .getTask ().getCallTask ()).isInstanceOf (CallTaskJava .class ));
5764
5865 Map <String , Object > input =
59- Map .of (
60- "topic" , "dragons and wizards" ,
61- "style" , "fantasy" ,
62- "audience" , "young adults" );
66+ Map .of (
67+ "topic" , "dragons and wizards" ,
68+ "style" , "fantasy" ,
69+ "audience" , "young adults" );
6370
6471 Map <String , Object > result ;
6572 try (WorkflowApplication app = WorkflowApplication .builder ().build ()) {
@@ -79,9 +86,9 @@ public void loopWorkflow() {
7986 var editor = AgentsUtils .newStyleEditor ();
8087
8188 Workflow wf =
82- AgentWorkflowBuilder .workflow ("retryFlow" )
83- .loop ("reviewLoop" , c -> c .readState ("score" , 0 ).doubleValue () >= 0.8 , scorer , editor )
84- .build ();
89+ AgentWorkflowBuilder .workflow ("retryFlow" )
90+ .loop ("reviewLoop" , c -> c .readState ("score" , 0 ).doubleValue () >= 0.8 , scorer , editor )
91+ .build ();
8592
8693 List <TaskItem > items = wf .getDo ();
8794 assertThat (items ).hasSize (1 );
@@ -90,12 +97,12 @@ public void loopWorkflow() {
9097 assertThat (fn .getDo ()).isNotNull ();
9198 assertThat (fn .getDo ()).hasSize (2 );
9299 fn .getDo ()
93- .forEach (si -> assertThat (si .getTask ().getCallTask ()).isInstanceOf (CallTaskJava .class ));
100+ .forEach (si -> assertThat (si .getTask ().getCallTask ()).isInstanceOf (CallTaskJava .class ));
94101
95102 Map <String , Object > input =
96- Map .of (
97- "story" , "dragons and wizards" ,
98- "style" , "comedy" );
103+ Map .of (
104+ "story" , "dragons and wizards" ,
105+ "style" , "comedy" );
99106
100107 Map <String , Object > result ;
101108 try (WorkflowApplication app = WorkflowApplication .builder ().build ()) {
@@ -113,17 +120,13 @@ public void loopWorkflowWithMaxIterations() {
113120 var scorer = AgentsUtils .newStyleScorer ();
114121 var editor = AgentsUtils .newStyleEditor ();
115122
123+
124+ Predicate <AgenticScope > until = s -> s .readState ("score" , 0 ).doubleValue () >= 0.8 ;
125+
116126 Workflow wf =
117- AgentWorkflowBuilder .workflow ("maxFlow" )
118- .tasks (
119- d ->
120- d .loop (
121- "limit" ,
122- l ->
123- l .maxIterations (5 )
124- .exitCondition (c -> c .readState ("score" , 0 ).doubleValue () >= 0.8 )
125- .subAgents ("sub" , scorer , editor )))
126- .build ();
127+ AgentWorkflowBuilder .workflow ("retryFlow" )
128+ .tasks (loop (until , scorer , 5 , editor ))
129+ .build ();
127130
128131 List <TaskItem > items = wf .getDo ();
129132 assertThat (items ).hasSize (1 );
@@ -132,12 +135,12 @@ public void loopWorkflowWithMaxIterations() {
132135 assertThat (fn .getDo ()).isNotNull ();
133136 assertThat (fn .getDo ()).hasSize (2 );
134137 fn .getDo ()
135- .forEach (si -> assertThat (si .getTask ().getCallTask ()).isInstanceOf (CallTaskJava .class ));
138+ .forEach (si -> assertThat (si .getTask ().getCallTask ()).isInstanceOf (CallTaskJava .class ));
136139
137140 Map <String , Object > input =
138- Map .of (
139- "story" , "dragons and wizards" ,
140- "style" , "comedy" );
141+ Map .of (
142+ "story" , "dragons and wizards" ,
143+ "style" , "comedy" );
141144
142145 Map <String , Object > result ;
143146 try (WorkflowApplication app = WorkflowApplication .builder ().build ()) {
@@ -152,10 +155,10 @@ public void loopWorkflowWithMaxIterations() {
152155 @ Test
153156 @ DisplayName ("Parallel agents via DSL.parallel(...)" )
154157 public void parallelWorkflow () {
155- var a1 = AgentsUtils .newFoodExpert ();
156- var a2 = AgentsUtils .newMovieExpert ();
158+ var foodExpert = AgentsUtils .newFoodExpert ();
159+ var movieExpert = AgentsUtils .newMovieExpert ();
157160
158- Workflow wf = workflow ("forkFlow" ).parallel ("fanout" , a1 , a2 ).build ();
161+ Workflow wf = workflow ("forkFlow" ).parallel ("fanout" , foodExpert , movieExpert ).build ();
159162
160163 List <TaskItem > items = wf .getDo ();
161164 assertThat (items ).hasSize (1 );
@@ -183,11 +186,11 @@ public void parallelWorkflow() {
183186 @ Test
184187 @ DisplayName ("Error handling with agents" )
185188 public void errorHandling () {
186- var a1 = AgentsUtils .newCreativeWriter ();
187- var a2 = AgentsUtils .newAudienceEditor ();
188- var a3 = AgentsUtils .newStyleEditor ();
189+ var creativeWriter = AgentsUtils .newCreativeWriter ();
190+ var audienceEditor = AgentsUtils .newAudienceEditor ();
191+ var styleEditor = AgentsUtils .newStyleEditor ();
189192
190- Workflow wf = workflow ("seqFlow" ).tasks (tasks -> tasks .sequence ("process" , a1 , a2 , a3 )).build ();
193+ Workflow wf = workflow ("seqFlow" ).tasks (tasks -> tasks .sequence ("process" , creativeWriter , audienceEditor , styleEditor )).build ();
191194
192195 List <TaskItem > items = wf .getDo ();
193196 assertThat (items ).hasSize (3 );
@@ -198,9 +201,9 @@ public void errorHandling() {
198201 items .forEach (it -> assertThat (it .getTask ().getCallTask ()).isInstanceOf (CallTaskJava .class ));
199202
200203 Map <String , Object > input =
201- Map .of (
202- "style" , "fantasy" ,
203- "audience" , "young adults" );
204+ Map .of (
205+ "style" , "fantasy" ,
206+ "audience" , "young adults" );
204207
205208 Map <String , Object > result ;
206209 try (WorkflowApplication app = WorkflowApplication .builder ().build ()) {
@@ -218,27 +221,19 @@ public void errorHandling() {
218221 public void conditionalWorkflow () {
219222
220223 var category = AgentsUtils .newCategoryRouter ();
221- var a1 = AgentsUtils .newMedicalExpert ();
222- var a2 = AgentsUtils .newTechnicalExpert ();
223- var a3 = AgentsUtils .newLegalExpert ();
224+ var medicalExpert = AgentsUtils .newMedicalExpert ();
225+ var technicalExpert = AgentsUtils .newTechnicalExpert ();
226+ var legalExpert = AgentsUtils .newLegalExpert ();
224227
225228 Workflow wf =
226- workflow ("conditional" )
227- .sequence ("process" , category )
228- .tasks (
229- t ->
230- t .switchCase (
231- p ->
232- p .onPredicate (
233- item ->
234- item .when (Agents .RequestCategory .UNKNOWN ::equals )
235- .then (FlowDirectiveEnum .END ))))
236- .tasks (
237- doTasks (
238- conditional (Agents .RequestCategory .MEDICAL ::equals , a1 ),
239- conditional (Agents .RequestCategory .TECHNICAL ::equals , a2 ),
240- conditional (Agents .RequestCategory .LEGAL ::equals , a3 )))
241- .build ();
229+ workflow ("conditional" )
230+ .sequence ("process" , category )
231+ .tasks (
232+ doTasks (
233+ conditional (Agents .RequestCategory .MEDICAL ::equals , medicalExpert ),
234+ conditional (Agents .RequestCategory .TECHNICAL ::equals , technicalExpert ),
235+ conditional (Agents .RequestCategory .LEGAL ::equals , legalExpert )))
236+ .build ();
242237
243238 Map <String , Object > input = Map .of ("question" , "What is the best treatment for a common cold?" );
244239
@@ -259,17 +254,17 @@ public void humanInTheLoop() {
259254 AtomicReference <String > request = new AtomicReference <>();
260255
261256 HumanInTheLoop humanInTheLoop =
262- AgenticServices .humanInTheLoopBuilder ()
263- .description ("Please provide the horoscope request" )
264- .inputName ("request" )
265- .outputName ("sign" )
266- .requestWriter (q -> request .set ("My name is Mario. What is my horoscope?" ))
267- .responseReader (() -> "piscis" )
268- .build ();
257+ AgenticServices .humanInTheLoopBuilder ()
258+ .description ("Please provide the horoscope request" )
259+ .inputName ("request" )
260+ .outputName ("sign" )
261+ .requestWriter (q -> request .set ("My name is Mario. What is my horoscope?" ))
262+ .responseReader (() -> "piscis" )
263+ .build ();
269264
270- var a1 = AgentsUtils .newAstrologyAgent ();
265+ var astrologyAgent = AgentsUtils .newAstrologyAgent ();
271266
272- Workflow wf = workflow ("seqFlow" ).sequence ("process" , a1 , humanInTheLoop ).build ();
267+ Workflow wf = workflow ("seqFlow" ).sequence ("process" , astrologyAgent , humanInTheLoop ).build ();
273268
274269 assertThat (wf .getDo ()).hasSize (2 );
275270
0 commit comments