Skip to content

Commit 124b421

Browse files
committed
bump langchain4g to 1.9.0-beta16
Signed-off-by: Dmitrii Tikhomirov <chani.liet@gmail.com>
1 parent 5e40aef commit 124b421

File tree

8 files changed

+157
-33
lines changed

8 files changed

+157
-33
lines changed

experimental/fluent/agentic-langchain4j/src/main/java/io/serverlessworkflow/fluent/agentic/langchain4j/ConditionalAgentServiceImpl.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import dev.langchain4j.agentic.agent.AgentRequest;
1919
import dev.langchain4j.agentic.agent.AgentResponse;
20+
import dev.langchain4j.agentic.declarative.TypedKey;
2021
import dev.langchain4j.agentic.internal.AgentExecutor;
2122
import dev.langchain4j.agentic.scope.AgenticScope;
2223
import dev.langchain4j.agentic.workflow.ConditionalAgentService;
@@ -48,6 +49,11 @@ public ConditionalAgentService<T> subAgents(List<AgentExecutor> agentExecutors)
4849
return this.subAgents(agentExecutors.toArray());
4950
}
5051

52+
@Override
53+
public ConditionalAgentService<T> outputKey(Class<? extends TypedKey<?>> outputKey) {
54+
throw new UnsupportedOperationException("Feature not implemented yet");
55+
}
56+
5157
@Override
5258
public ConditionalAgentService<T> beforeAgentInvocation(Consumer<AgentRequest> consumer) {
5359
throw new UnsupportedOperationException(

experimental/fluent/agentic-langchain4j/src/main/java/io/serverlessworkflow/fluent/agentic/langchain4j/LoopAgentServiceImpl.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import dev.langchain4j.agentic.agent.AgentRequest;
1919
import dev.langchain4j.agentic.agent.AgentResponse;
20+
import dev.langchain4j.agentic.declarative.TypedKey;
2021
import dev.langchain4j.agentic.internal.AgentExecutor;
2122
import dev.langchain4j.agentic.scope.AgenticScope;
2223
import dev.langchain4j.agentic.workflow.LoopAgentService;
@@ -77,6 +78,11 @@ public LoopAgentService<T> subAgents(List<AgentExecutor> agentExecutors) {
7778
return this;
7879
}
7980

81+
@Override
82+
public LoopAgentService<T> outputKey(Class<? extends TypedKey<?>> outputKey) {
83+
throw new UnsupportedOperationException("Feature not implemented yet");
84+
}
85+
8086
@Override
8187
public LoopAgentService<T> beforeAgentInvocation(Consumer<AgentRequest> consumer) {
8288
throw new UnsupportedOperationException(

experimental/fluent/agentic-langchain4j/src/main/java/io/serverlessworkflow/fluent/agentic/langchain4j/ParallelAgentServiceImpl.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import dev.langchain4j.agentic.agent.AgentRequest;
1919
import dev.langchain4j.agentic.agent.AgentResponse;
20+
import dev.langchain4j.agentic.declarative.TypedKey;
2021
import dev.langchain4j.agentic.internal.AgentExecutor;
2122
import dev.langchain4j.agentic.workflow.ParallelAgentService;
2223
import io.serverlessworkflow.impl.ExecutorServiceHolder;
@@ -47,6 +48,11 @@ public ParallelAgentService<T> subAgents(List<AgentExecutor> agentExecutors) {
4748
return this.subAgents(agentExecutors.toArray());
4849
}
4950

51+
@Override
52+
public ParallelAgentService<T> outputKey(Class<? extends TypedKey<?>> outputKey) {
53+
throw new UnsupportedOperationException("Feature not implemented yet");
54+
}
55+
5056
@Override
5157
public ParallelAgentService<T> beforeAgentInvocation(Consumer<AgentRequest> consumer) {
5258
throw new UnsupportedOperationException(

experimental/fluent/agentic-langchain4j/src/main/java/io/serverlessworkflow/fluent/agentic/langchain4j/SequentialAgentServiceImpl.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import dev.langchain4j.agentic.agent.AgentRequest;
1919
import dev.langchain4j.agentic.agent.AgentResponse;
20+
import dev.langchain4j.agentic.declarative.TypedKey;
2021
import dev.langchain4j.agentic.internal.AgentExecutor;
2122
import dev.langchain4j.agentic.workflow.SequentialAgentService;
2223
import java.util.List;
@@ -46,6 +47,11 @@ public SequentialAgentService<T> subAgents(List<AgentExecutor> agentExecutors) {
4647
return this;
4748
}
4849

50+
@Override
51+
public SequentialAgentService<T> outputKey(Class<? extends TypedKey<?>> outputKey) {
52+
throw new UnsupportedOperationException("Feature not implemented yet");
53+
}
54+
4955
@Override
5056
public SequentialAgentService<T> beforeAgentInvocation(Consumer<AgentRequest> consumer) {
5157
throw new UnsupportedOperationException(

experimental/fluent/agentic/src/main/java/io/serverlessworkflow/fluent/agentic/AgentAdapters.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import static dev.langchain4j.agentic.internal.AgentUtil.agentsToExecutors;
1919

2020
import dev.langchain4j.agentic.internal.AgentExecutor;
21+
import dev.langchain4j.agentic.scope.AgentInvocationListener;
2122
import dev.langchain4j.agentic.scope.AgenticScope;
2223
import dev.langchain4j.agentic.scope.DefaultAgenticScope;
2324
import io.serverlessworkflow.api.types.func.LoopPredicateIndex;
@@ -35,7 +36,7 @@ public static List<AgentExecutor> toExecutors(Object... agents) {
3536
}
3637

3738
public static Function<DefaultAgenticScope, Object> toFunction(AgentExecutor exec) {
38-
return exec::execute;
39+
return agenticScope -> exec.execute(agenticScope, AgentInvocationListener.NO_OP);
3940
}
4041

4142
public static LoopPredicateIndex<AgenticScope, Object> toWhile(Predicate<AgenticScope> exit) {

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

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,4 +137,76 @@ public interface NovelCreator {
137137
String createNovel(
138138
@V("topic") String topic, @V("audience") String audience, @V("style") String style);
139139
}
140+
141+
public static Agents.StorySeedAgent newStorySeedAgent() {
142+
return spy(
143+
AgenticServices.agentBuilder(Agents.StorySeedAgent.class)
144+
.chatModel(BASE_MODEL)
145+
.outputKey("response")
146+
.build());
147+
}
148+
149+
public static Agents.PlotAgent newPlotAgent() {
150+
return spy(
151+
AgenticServices.agentBuilder(Agents.PlotAgent.class)
152+
.chatModel(BASE_MODEL)
153+
.outputKey("response")
154+
.build());
155+
}
156+
157+
public static Agents.SceneAgent newSceneAgent() {
158+
return spy(
159+
AgenticServices.agentBuilder(Agents.SceneAgent.class)
160+
.chatModel(BASE_MODEL)
161+
.outputKey("response")
162+
.build());
163+
}
164+
165+
public static Agents.SettingAgent newSettingAgent() {
166+
return spy(
167+
AgenticServices.agentBuilder(Agents.SettingAgent.class)
168+
.chatModel(BASE_MODEL)
169+
.outputKey("response")
170+
.build());
171+
}
172+
173+
public static Agents.HeroAgent newHeroAgent() {
174+
return spy(
175+
AgenticServices.agentBuilder(Agents.HeroAgent.class)
176+
.chatModel(BASE_MODEL)
177+
.outputKey("response")
178+
.build());
179+
}
180+
181+
public static Agents.ConflictAgent newConflictAgent() {
182+
return spy(
183+
AgenticServices.agentBuilder(Agents.ConflictAgent.class)
184+
.chatModel(BASE_MODEL)
185+
.outputKey("response")
186+
.build());
187+
}
188+
189+
public static Agents.FactAgent newFactAgent() {
190+
return spy(
191+
AgenticServices.agentBuilder(Agents.FactAgent.class)
192+
.chatModel(BASE_MODEL)
193+
.outputKey("response")
194+
.build());
195+
}
196+
197+
public static Agents.CultureAgent newCultureAgent() {
198+
return spy(
199+
AgenticServices.agentBuilder(Agents.CultureAgent.class)
200+
.chatModel(BASE_MODEL)
201+
.outputKey("response")
202+
.build());
203+
}
204+
205+
public static Agents.TechnologyAgent newTechnologyAgent() {
206+
return spy(
207+
AgenticServices.agentBuilder(Agents.TechnologyAgent.class)
208+
.chatModel(BASE_MODEL)
209+
.outputKey("response")
210+
.build());
211+
}
140212
}

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

Lines changed: 58 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,18 @@
1616
package io.serverlessworkflow.fluent.agentic;
1717

1818
import static io.serverlessworkflow.fluent.agentic.Agents.*;
19+
import static io.serverlessworkflow.fluent.agentic.AgentsUtils.newConflictAgent;
20+
import static io.serverlessworkflow.fluent.agentic.AgentsUtils.newCultureAgent;
21+
import static io.serverlessworkflow.fluent.agentic.AgentsUtils.newFactAgent;
22+
import static io.serverlessworkflow.fluent.agentic.AgentsUtils.newHeroAgent;
23+
import static io.serverlessworkflow.fluent.agentic.AgentsUtils.newPlotAgent;
24+
import static io.serverlessworkflow.fluent.agentic.AgentsUtils.newSceneAgent;
25+
import static io.serverlessworkflow.fluent.agentic.AgentsUtils.newSettingAgent;
26+
import static io.serverlessworkflow.fluent.agentic.AgentsUtils.newStorySeedAgent;
27+
import static io.serverlessworkflow.fluent.agentic.AgentsUtils.newTechnologyAgent;
1928
import static org.junit.jupiter.api.Assertions.assertEquals;
2029
import static org.mockito.ArgumentMatchers.eq;
30+
import static org.mockito.Mockito.doReturn;
2131
import static org.mockito.Mockito.mock;
2232
import static org.mockito.Mockito.when;
2333

@@ -38,9 +48,12 @@ class WorkflowTests {
3848

3949
@Test
4050
public void testAgent() throws ExecutionException, InterruptedException {
41-
final StorySeedAgent storySeedAgent = mock(StorySeedAgent.class);
51+
final StorySeedAgent storySeedAgent = newStorySeedAgent();
52+
53+
doReturn("storySeedAgent")
54+
.when(storySeedAgent)
55+
.invoke(org.mockito.ArgumentMatchers.anyString());
4256

43-
when(storySeedAgent.invoke(eq("A Great Story"))).thenReturn("storySeedAgent");
4457
when(storySeedAgent.outputKey()).thenReturn("premise");
4558
when(storySeedAgent.name()).thenReturn("storySeedAgent");
4659

@@ -67,21 +80,23 @@ public void testAgent() throws ExecutionException, InterruptedException {
6780

6881
@Test
6982
public void testAgents() throws ExecutionException, InterruptedException {
70-
final StorySeedAgent storySeedAgent = mock(StorySeedAgent.class);
71-
final PlotAgent plotAgent = mock(PlotAgent.class);
72-
final SceneAgent sceneAgent = mock(SceneAgent.class);
83+
final StorySeedAgent storySeedAgent = newStorySeedAgent();
84+
final PlotAgent plotAgent = newPlotAgent();
85+
final SceneAgent sceneAgent = newSceneAgent();
7386

74-
when(storySeedAgent.invoke(eq("A Great Story"))).thenReturn("storySeedAgent");
7587
when(storySeedAgent.outputKey()).thenReturn("premise");
7688
when(storySeedAgent.name()).thenReturn("storySeedAgent");
89+
doReturn("storySeedAgent")
90+
.when(storySeedAgent)
91+
.invoke(org.mockito.ArgumentMatchers.anyString());
7792

78-
when(plotAgent.invoke(eq("storySeedAgent"))).thenReturn("plotAgent");
7993
when(plotAgent.outputKey()).thenReturn("plot");
8094
when(plotAgent.name()).thenReturn("plotAgent");
95+
doReturn("plotAgent").when(plotAgent).invoke(org.mockito.ArgumentMatchers.anyString());
8196

82-
when(sceneAgent.invoke(eq("plotAgent"))).thenReturn("sceneAgent");
8397
when(sceneAgent.outputKey()).thenReturn("story");
8498
when(sceneAgent.name()).thenReturn("sceneAgent");
99+
doReturn("sceneAgent").when(sceneAgent).invoke(org.mockito.ArgumentMatchers.anyString());
85100

86101
Workflow workflow =
87102
AgentWorkflowBuilder.workflow("storyFlow")
@@ -110,21 +125,25 @@ public void testAgents() throws ExecutionException, InterruptedException {
110125

111126
@Test
112127
public void testSequence() throws ExecutionException, InterruptedException {
113-
final StorySeedAgent storySeedAgent = mock(StorySeedAgent.class);
114-
final PlotAgent plotAgent = mock(PlotAgent.class);
115-
final SceneAgent sceneAgent = mock(SceneAgent.class);
128+
final StorySeedAgent storySeedAgent = newStorySeedAgent();
129+
final PlotAgent plotAgent = newPlotAgent();
130+
final SceneAgent sceneAgent = newSceneAgent();
116131

117-
when(storySeedAgent.invoke(eq("A Great Story"))).thenReturn("storySeedAgent");
118132
when(storySeedAgent.outputKey()).thenReturn("premise");
119133
when(storySeedAgent.name()).thenReturn("storySeedAgent");
120134

121-
when(plotAgent.invoke(eq("storySeedAgent"))).thenReturn("plotAgent");
135+
doReturn("storySeedAgent")
136+
.when(storySeedAgent)
137+
.invoke(org.mockito.ArgumentMatchers.anyString());
138+
122139
when(plotAgent.outputKey()).thenReturn("plot");
123140
when(plotAgent.name()).thenReturn("plotAgent");
124141

125-
when(sceneAgent.invoke(eq("plotAgent"))).thenReturn("sceneAgent");
142+
doReturn("plotAgent").when(plotAgent).invoke(org.mockito.ArgumentMatchers.anyString());
143+
126144
when(sceneAgent.outputKey()).thenReturn("story");
127145
when(sceneAgent.name()).thenReturn("sceneAgent");
146+
doReturn("sceneAgent").when(sceneAgent).invoke(org.mockito.ArgumentMatchers.anyString());
128147

129148
Workflow workflow =
130149
AgentWorkflowBuilder.workflow("storyFlow")
@@ -149,22 +168,25 @@ public void testSequence() throws ExecutionException, InterruptedException {
149168

150169
@Test
151170
public void testParallel() throws ExecutionException, InterruptedException {
171+
final SettingAgent setting = newSettingAgent();
172+
final HeroAgent hero = newHeroAgent();
173+
final ConflictAgent conflict = newConflictAgent();
152174

153-
final SettingAgent setting = mock(SettingAgent.class);
154-
final HeroAgent hero = mock(HeroAgent.class);
155-
final ConflictAgent conflict = mock(ConflictAgent.class);
156-
157-
when(setting.invoke(eq("sci-fi"))).thenReturn("Fake conflict response");
158175
when(setting.outputKey()).thenReturn("setting");
159176
when(setting.name()).thenReturn("setting");
177+
doReturn("Fake setting response")
178+
.when(setting)
179+
.invoke(org.mockito.ArgumentMatchers.anyString());
160180

161-
when(hero.invoke(eq("sci-fi"))).thenReturn("Fake hero response");
162181
when(hero.outputKey()).thenReturn("hero");
163182
when(hero.name()).thenReturn("hero");
183+
doReturn("Fake hero response").when(hero).invoke(org.mockito.ArgumentMatchers.anyString());
164184

165-
when(conflict.invoke(eq("sci-fi"))).thenReturn("Fake setting response");
166185
when(conflict.outputKey()).thenReturn("conflict");
167186
when(conflict.name()).thenReturn("conflict");
187+
doReturn("Fake conflict response")
188+
.when(conflict)
189+
.invoke(org.mockito.ArgumentMatchers.anyString());
168190

169191
Workflow workflow =
170192
AgentWorkflowBuilder.workflow("parallelFlow")
@@ -178,9 +200,9 @@ public void testParallel() throws ExecutionException, InterruptedException {
178200
Map<String, Object> result =
179201
app.workflowDefinition(workflow).instance(topic).start().get().asMap().orElseThrow();
180202

181-
assertEquals("Fake conflict response", result.get("setting").toString());
203+
assertEquals("Fake setting response", result.get("setting").toString());
182204
assertEquals("Fake hero response", result.get("hero").toString());
183-
assertEquals("Fake setting response", result.get("conflict").toString());
205+
assertEquals("Fake conflict response", result.get("conflict").toString());
184206
}
185207

186208
try (WorkflowApplication app = WorkflowApplication.builder().build()) {
@@ -192,35 +214,40 @@ public void testParallel() throws ExecutionException, InterruptedException {
192214
.as(AgenticScope.class)
193215
.orElseThrow();
194216

195-
assertEquals("Fake conflict response", result.readState("setting").toString());
217+
assertEquals("Fake setting response", result.readState("setting").toString());
196218
assertEquals("Fake hero response", result.readState("hero").toString());
197-
assertEquals("Fake setting response", result.readState("conflict").toString());
219+
assertEquals("Fake conflict response", result.readState("conflict").toString());
198220
}
199221
}
200222

201223
@Test
202224
public void testSeqAndThenParallel() throws ExecutionException, InterruptedException {
203-
final FactAgent factAgent = mock(FactAgent.class);
204-
final CultureAgent cultureAgent = mock(CultureAgent.class);
205-
final TechnologyAgent technologyAgent = mock(TechnologyAgent.class);
225+
final FactAgent factAgent = newFactAgent();
226+
final CultureAgent cultureAgent = newCultureAgent();
227+
final TechnologyAgent technologyAgent = newTechnologyAgent();
206228

207229
List<String> cultureTraits =
208230
List.of("Alien Culture Trait 1", "Alien Culture Trait 2", "Alien Culture Trait 3");
209231

210232
List<String> technologyTraits =
211233
List.of("Alien Technology Trait 1", "Alien Technology Trait 2", "Alien Technology Trait 3");
212234

213-
when(factAgent.invoke(eq("alien"))).thenReturn("Some Fact about aliens");
214235
when(factAgent.outputKey()).thenReturn("fact");
215236
when(factAgent.name()).thenReturn("fact");
237+
doReturn("Some Fact about aliens")
238+
.when(factAgent)
239+
.invoke(org.mockito.ArgumentMatchers.anyString());
216240

217-
when(cultureAgent.invoke(eq("Some Fact about aliens"))).thenReturn(cultureTraits);
218241
when(cultureAgent.outputKey()).thenReturn("culture");
219242
when(cultureAgent.name()).thenReturn("culture");
243+
doReturn(cultureTraits).when(cultureAgent).invoke(org.mockito.ArgumentMatchers.anyString());
220244

221-
when(technologyAgent.invoke(eq("Some Fact about aliens"))).thenReturn(technologyTraits);
222245
when(technologyAgent.outputKey()).thenReturn("technology");
223246
when(technologyAgent.name()).thenReturn("technology");
247+
doReturn(technologyTraits)
248+
.when(technologyAgent)
249+
.invoke(org.mockito.ArgumentMatchers.anyString());
250+
224251
Workflow workflow =
225252
AgentWorkflowBuilder.workflow("alienCultureFlow")
226253
.tasks(

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@
9393
<version.org.hibernate.validator>9.1.0.Final</version.org.hibernate.validator>
9494
<version.org.glassfish.expressly>6.0.0</version.org.glassfish.expressly>
9595
<!-- Experimental modules from langchain4j -->
96-
<version.dev.langchain4j.beta>1.8.0-beta15</version.dev.langchain4j.beta>
96+
<version.dev.langchain4j.beta>1.9.0-beta16</version.dev.langchain4j.beta>
9797
<!-- Base langchain4j version -->
9898
<version.dev.langchain4j>1.8.0</version.dev.langchain4j>
9999
<!-- Swagger Parser -->

0 commit comments

Comments
 (0)