Skip to content

Commit c6f878b

Browse files
committed
Added AgenticServices helper
Signed-off-by: Dmitrii Tikhomirov <[email protected]>
1 parent 37bd454 commit c6f878b

File tree

3 files changed

+104
-8
lines changed

3 files changed

+104
-8
lines changed

experimental/fluent/agentic-langchain4j/src/test/java/io/serverlessworkflow/fluent/agentic/langchain4j/Agents.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,8 +212,13 @@ public interface StyleReviewLoop {
212212
public interface StyledWriter extends AgenticScopeAccess {
213213

214214
@Agent
215-
ResultWithAgenticScope<String> writeStoryWithStyle(
216-
@V("topic") String topic, @V("style") String style);
215+
String writeStoryWithStyle(@V("topic") String topic, @V("style") String style);
216+
}
217+
218+
public interface NovelCreator {
219+
220+
@Agent
221+
String createNovel(@V("topic") String topic, @V("audience") String audience, @V("style") String style);
217222
}
218223

219224
public interface FoodExpert {
@@ -250,4 +255,11 @@ public interface EveningPlannerAgent {
250255
@Agent
251256
List<EveningPlan> plan(@V("mood") String mood);
252257
}
258+
259+
public interface HoroscopeAgent {
260+
261+
@Agent
262+
String invoke(@V("name") String name);
263+
}
264+
253265
}

experimental/fluent/agentic-langchain4j/src/test/java/io/serverlessworkflow/fluent/agentic/langchain4j/WorkflowAgentsIT.java

Lines changed: 88 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,31 @@
1515
*/
1616
package io.serverlessworkflow.fluent.agentic.langchain4j;
1717

18+
import static io.serverlessworkflow.fluent.agentic.AgentWorkflowBuilder.workflow;
19+
import static io.serverlessworkflow.fluent.agentic.dsl.AgenticDSL.fn;
20+
import static io.serverlessworkflow.fluent.agentic.langchain4j.Agents.*;
1821
import static io.serverlessworkflow.fluent.agentic.langchain4j.Agents.AudienceEditor;
1922
import static io.serverlessworkflow.fluent.agentic.langchain4j.Agents.CreativeWriter;
2023
import static io.serverlessworkflow.fluent.agentic.langchain4j.Agents.StyleEditor;
2124
import static io.serverlessworkflow.fluent.agentic.langchain4j.Models.BASE_MODEL;
25+
import static org.junit.jupiter.api.Assertions.assertNotNull;
26+
import static org.junit.jupiter.api.Assertions.assertTrue;
2227
import static org.mockito.ArgumentMatchers.any;
2328
import static org.mockito.ArgumentMatchers.eq;
2429
import static org.mockito.Mockito.spy;
2530
import static org.mockito.Mockito.verify;
2631

27-
import dev.langchain4j.agentic.AgenticServices;
2832
import dev.langchain4j.agentic.UntypedAgent;
33+
import dev.langchain4j.agentic.scope.AgenticScope;
2934
import dev.langchain4j.agentic.workflow.WorkflowAgentsBuilder;
35+
36+
import java.util.List;
3037
import java.util.Map;
38+
import java.util.function.Function;
39+
import java.util.function.Predicate;
40+
41+
import io.serverlessworkflow.fluent.agentic.AgenticServices;
42+
import io.serverlessworkflow.fluent.agentic.AgentsUtils;
3143
import org.junit.jupiter.api.Test;
3244

3345
public class WorkflowAgentsIT {
@@ -38,21 +50,21 @@ void sequential_agents_tests() {
3850

3951
CreativeWriter creativeWriter =
4052
spy(
41-
AgenticServices.agentBuilder(CreativeWriter.class)
53+
dev.langchain4j.agentic.AgenticServices.agentBuilder(CreativeWriter.class)
4254
.chatModel(BASE_MODEL)
4355
.outputName("story")
4456
.build());
4557

4658
AudienceEditor audienceEditor =
4759
spy(
48-
AgenticServices.agentBuilder(AudienceEditor.class)
60+
dev.langchain4j.agentic.AgenticServices.agentBuilder(AudienceEditor.class)
4961
.chatModel(BASE_MODEL)
5062
.outputName("story")
5163
.build());
5264

5365
StyleEditor styleEditor =
5466
spy(
55-
AgenticServices.agentBuilder(StyleEditor.class)
67+
dev.langchain4j.agentic.AgenticServices.agentBuilder(StyleEditor.class)
5668
.chatModel(BASE_MODEL)
5769
.outputName("story")
5870
.build());
@@ -77,4 +89,76 @@ void sequential_agents_tests() {
7789
verify(audienceEditor).editStory(any(), eq("young adults"));
7890
verify(styleEditor).editStory(any(), eq("fantasy"));
7991
}
92+
93+
@Test
94+
public void sequenceHelperTest() {
95+
var creativeWriter = AgentsUtils.newCreativeWriter();
96+
var audienceEditor = AgentsUtils.newAudienceEditor();
97+
var styleEditor = AgentsUtils.newStyleEditor();
98+
99+
NovelCreator novelCreator = AgenticServices.of(NovelCreator.class)
100+
.flow(workflow("seqFlow")
101+
.sequence(creativeWriter, audienceEditor, styleEditor)
102+
).build();
103+
104+
String story = novelCreator.createNovel("dragons and wizards", "young adults", "fantasy");
105+
assertNotNull(story);
106+
}
107+
108+
@Test
109+
public void parallelWorkflow() {
110+
var foodExpert = AgentsUtils.newFoodExpert();
111+
var movieExpert = AgentsUtils.newMovieExpert();
112+
113+
EveningPlannerAgent eveningPlannerAgent = AgenticServices.of(EveningPlannerAgent.class)
114+
.flow(workflow("parallelFlow")
115+
.parallel(foodExpert, movieExpert)
116+
).build();
117+
List<EveningPlan> result = eveningPlannerAgent.plan("romantic");
118+
assertTrue(result.size() > 0);
119+
}
120+
121+
@Test
122+
public void loopTest() {
123+
var creativeWriter = AgentsUtils.newCreativeWriter();
124+
var scorer = AgentsUtils.newStyleScorer();
125+
var editor = AgentsUtils.newStyleEditor();
126+
127+
Predicate<AgenticScope> until = s -> s.readState("score", 0).doubleValue() >= 0.8;
128+
129+
130+
StyledWriter styledWriter = AgenticServices.of(StyledWriter.class)
131+
.flow(workflow("loopFlow").agent(creativeWriter)
132+
.loop(until, scorer, editor)
133+
).build();
134+
135+
String story = styledWriter.writeStoryWithStyle("dragons and wizards", "fantasy");
136+
assertNotNull(story);
137+
}
138+
139+
@Test
140+
public void humanInTheLoop() {
141+
var astrologyAgent = AgentsUtils.newAstrologyAgent();
142+
143+
var askSign = new Function<Map<String, Object>, Map<String, Object>>() {
144+
@Override
145+
public Map<String, Object> apply(Map<String, Object> holder) {
146+
System.out.println("What's your star sign?");
147+
//var sign = System.console().readLine();
148+
holder.put("sign", "piscis");
149+
return holder;
150+
}
151+
};
152+
153+
String result = AgenticServices.of(HoroscopeAgent.class)
154+
.flow(workflow("humanInTheLoop")
155+
.tasks(tasks -> tasks.callFn(fn(askSign)))
156+
.agent(astrologyAgent))
157+
.build()
158+
.invoke("My name is Mario. What is my horoscope?");
159+
160+
assertNotNull(result);
161+
162+
}
163+
80164
}

experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/LC4JEquivalenceIT.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,12 @@ public void sequentialWorkflow() {
7777
@Test
7878
@DisplayName("Looping agents via DSL.loop(...)")
7979
public void loopWorkflow() {
80-
80+
var creativeWriter = AgentsUtils.newCreativeWriter();
8181
var scorer = AgentsUtils.newStyleScorer();
8282
var editor = AgentsUtils.newStyleEditor();
8383

8484
Workflow wf =
85-
AgentWorkflowBuilder.workflow("retryFlow")
85+
AgentWorkflowBuilder.workflow("retryFlow").agent(creativeWriter)
8686
.loop("reviewLoop", c -> c.readState("score", 0).doubleValue() >= 0.8, scorer, editor)
8787
.build();
8888

0 commit comments

Comments
 (0)