Skip to content

Commit fd4ba7d

Browse files
committed
Introduce Agentic DSL
Signed-off-by: Ricardo Zanini <[email protected]>
1 parent 81073cc commit fd4ba7d

File tree

26 files changed

+891
-172
lines changed

26 files changed

+891
-172
lines changed

experimental/lambda/src/test/java/io/serverless/workflow/impl/FluentDSLCallTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ void testJavaFunction() throws InterruptedException, ExecutionException {
3434
try (WorkflowApplication app = WorkflowApplication.builder().build()) {
3535
final Workflow workflow =
3636
FuncWorkflowBuilder.workflow("testJavaCall")
37-
.tasks(tasks -> tasks.callFn(f -> f.fn(JavaFunctions::getName)))
37+
.tasks(tasks -> tasks.callFn(f -> f.function(JavaFunctions::getName)))
3838
.build();
3939
assertThat(
4040
app.workflowDefinition(workflow)
@@ -85,7 +85,7 @@ void testSwitch() throws InterruptedException, ExecutionException {
8585
switchOdd.items(
8686
item ->
8787
item.when(CallTest::isOdd).then(FlowDirectiveEnum.END)))
88-
.callFn(callJava -> callJava.fn(CallTest::zero)))
88+
.callFn(callJava -> callJava.function(CallTest::zero)))
8989
.build();
9090

9191
WorkflowDefinition definition = app.workflowDefinition(workflow);

fluent/agentic/pom.xml

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
<parent>
7+
<groupId>io.serverlessworkflow</groupId>
8+
<artifactId>serverlessworkflow-fluent</artifactId>
9+
<version>8.0.0-SNAPSHOT</version>
10+
</parent>
11+
12+
<name>Serverless Workflow :: Fluent :: Agentic</name>
13+
<artifactId>serverlessworkflow-fluent-agentic</artifactId>
14+
15+
<properties>
16+
<maven.compiler.source>17</maven.compiler.source>
17+
<maven.compiler.target>17</maven.compiler.target>
18+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
19+
20+
<version.dev.langchain4j>1.2.0-beta8-SNAPSHOT</version.dev.langchain4j>
21+
</properties>
22+
23+
<dependencies>
24+
<dependency>
25+
<groupId>io.serverlessworkflow</groupId>
26+
<artifactId>serverlessworkflow-experimental-types</artifactId>
27+
</dependency>
28+
<dependency>
29+
<groupId>io.serverlessworkflow</groupId>
30+
<artifactId>serverlessworkflow-types</artifactId>
31+
</dependency>
32+
<dependency>
33+
<groupId>io.serverlessworkflow</groupId>
34+
<artifactId>serverlessworkflow-fluent-spec</artifactId>
35+
</dependency>
36+
<dependency>
37+
<groupId>io.serverlessworkflow</groupId>
38+
<artifactId>serverlessworkflow-fluent-func</artifactId>
39+
</dependency>
40+
<dependency>
41+
<groupId>dev.langchain4j</groupId>
42+
<artifactId>langchain4j-agentic</artifactId>
43+
<version>${version.dev.langchain4j}</version>
44+
</dependency>
45+
<dependency>
46+
<groupId>org.slf4j</groupId>
47+
<artifactId>slf4j-simple</artifactId>
48+
<scope>test</scope>
49+
</dependency>
50+
51+
<dependency>
52+
<groupId>org.junit.jupiter</groupId>
53+
<artifactId>junit-jupiter-api</artifactId>
54+
<scope>test</scope>
55+
</dependency>
56+
<dependency>
57+
<groupId>org.mockito</groupId>
58+
<artifactId>mockito-core</artifactId>
59+
<scope>test</scope>
60+
</dependency>
61+
<dependency>
62+
<groupId>dev.langchain4j</groupId>
63+
<artifactId>langchain4j-ollama</artifactId>
64+
<scope>test</scope>
65+
<version>1.2.0-SNAPSHOT</version>
66+
</dependency>
67+
</dependencies>
68+
69+
</project>
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright 2020-Present The Serverless Workflow Specification Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.serverlessworkflow.fluent.agentic;
17+
18+
import static dev.langchain4j.agentic.internal.AgentExecutor.agentsToExecutors;
19+
20+
import dev.langchain4j.agentic.Cognisphere;
21+
import dev.langchain4j.agentic.internal.AgentExecutor;
22+
import dev.langchain4j.agentic.internal.AgentInstance;
23+
import java.util.List;
24+
import java.util.function.Function;
25+
import java.util.stream.Stream;
26+
27+
public final class AgentAdapters {
28+
private AgentAdapters() {}
29+
30+
public static List<AgentExecutor> toExecutors(Object... agents) {
31+
return agentsToExecutors(Stream.of(agents).map(AgentInstance.class::cast).toList());
32+
}
33+
34+
public static Function<Cognisphere, Object> toFn(AgentExecutor exec) {
35+
return exec::invoke;
36+
}
37+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Copyright 2020-Present The Serverless Workflow Specification Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.serverlessworkflow.fluent.agentic;
17+
18+
import io.serverlessworkflow.fluent.func.FuncDoTaskBuilder;
19+
import io.serverlessworkflow.fluent.func.FuncTaskItemListBuilder;
20+
21+
public class AgentDoTaskBuilder extends FuncDoTaskBuilder
22+
implements DelegatingAgentDoTaskFluent<AgentDoTaskBuilder> {
23+
24+
private AgentDoTaskBuilder(AgentTaskItemListBuilder agentTaskItemListBuilder) {
25+
super(agentTaskItemListBuilder);
26+
}
27+
28+
static AgentDoTaskBuilder wrap(FuncDoTaskBuilder base) {
29+
FuncTaskItemListBuilder funcList = base.internalDelegate();
30+
AgentTaskItemListBuilder agentList =
31+
(funcList instanceof AgentTaskItemListBuilder al)
32+
? al
33+
: new AgentTaskItemListBuilder(funcList.getInternalList());
34+
return new AgentDoTaskBuilder(agentList);
35+
}
36+
37+
@Override
38+
public AgentDoTaskFluent<?> agentInternalDelegate() {
39+
return (AgentDoTaskFluent<?>) super.internalDelegate();
40+
}
41+
42+
@Override
43+
public AgentDoTaskBuilder self() {
44+
return this;
45+
}
46+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*
2+
* Copyright 2020-Present The Serverless Workflow Specification Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.serverlessworkflow.fluent.agentic;
17+
18+
public interface AgentDoTaskFluent<SELF extends AgentDoTaskFluent<SELF>> {
19+
20+
SELF agent(String name, Object agent);
21+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright 2020-Present The Serverless Workflow Specification Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.serverlessworkflow.fluent.agentic;
17+
18+
import dev.langchain4j.agentic.internal.AgentExecutor;
19+
import io.serverlessworkflow.api.types.TaskItem;
20+
import io.serverlessworkflow.fluent.func.FuncTaskItemListBuilder;
21+
import java.util.List;
22+
23+
public class AgentTaskItemListBuilder extends FuncTaskItemListBuilder
24+
implements AgentDoTaskFluent<AgentTaskItemListBuilder> {
25+
26+
AgentTaskItemListBuilder(final List<TaskItem> list) {
27+
super(list);
28+
}
29+
30+
@Override
31+
public AgentTaskItemListBuilder agent(String name, Object agent) {
32+
AgentExecutor exec = AgentAdapters.toExecutors(agent).get(0);
33+
this.callFn(name, fn -> fn.function(AgentAdapters.toFn(exec)));
34+
return this;
35+
}
36+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
* Copyright 2020-Present The Serverless Workflow Specification Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.serverlessworkflow.fluent.agentic;
17+
18+
import io.serverlessworkflow.api.types.Workflow;
19+
import io.serverlessworkflow.fluent.func.FuncWorkflowBuilder;
20+
import io.serverlessworkflow.fluent.spec.DocumentBuilder;
21+
import io.serverlessworkflow.fluent.spec.InputBuilder;
22+
import io.serverlessworkflow.fluent.spec.OutputBuilder;
23+
import io.serverlessworkflow.fluent.spec.UseBuilder;
24+
import java.util.function.Consumer;
25+
26+
public final class AgenticWorkflowBuilder {
27+
28+
private final FuncWorkflowBuilder delegate;
29+
30+
AgenticWorkflowBuilder(final FuncWorkflowBuilder delegate) {
31+
this.delegate = delegate;
32+
}
33+
34+
public static AgenticWorkflowBuilder workflow() {
35+
return new AgenticWorkflowBuilder(FuncWorkflowBuilder.workflow());
36+
}
37+
38+
public static AgenticWorkflowBuilder workflow(String name) {
39+
return new AgenticWorkflowBuilder(FuncWorkflowBuilder.workflow(name));
40+
}
41+
42+
public static AgenticWorkflowBuilder workflow(String name, String ns) {
43+
return new AgenticWorkflowBuilder(FuncWorkflowBuilder.workflow(name, ns));
44+
}
45+
46+
public AgenticWorkflowBuilder document(Consumer<DocumentBuilder> c) {
47+
delegate.document(c);
48+
return this;
49+
}
50+
51+
public AgenticWorkflowBuilder input(Consumer<InputBuilder> c) {
52+
delegate.input(c);
53+
return this;
54+
}
55+
56+
public AgenticWorkflowBuilder output(Consumer<OutputBuilder> c) {
57+
delegate.output(c);
58+
return this;
59+
}
60+
61+
public AgenticWorkflowBuilder use(Consumer<UseBuilder> c) {
62+
delegate.use(c);
63+
return this;
64+
}
65+
66+
public AgenticWorkflowBuilder tasks(Consumer<AgentDoTaskBuilder> c) {
67+
delegate.tasks(
68+
funcDo -> {
69+
AgentDoTaskBuilder agentDoTaskBuilder = AgentDoTaskBuilder.wrap(funcDo);
70+
c.accept(agentDoTaskBuilder);
71+
});
72+
return this;
73+
}
74+
75+
public Workflow build() {
76+
return delegate.build();
77+
}
78+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Copyright 2020-Present The Serverless Workflow Specification Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.serverlessworkflow.fluent.agentic;
17+
18+
public interface DelegatingAgentDoTaskFluent<SELF extends DelegatingAgentDoTaskFluent<SELF>>
19+
extends AgentDoTaskFluent<SELF> {
20+
21+
/** Return the underlying functional ops delegate. */
22+
AgentDoTaskFluent<?> agentInternalDelegate();
23+
24+
@SuppressWarnings("unchecked")
25+
default SELF self() {
26+
return (SELF) this;
27+
}
28+
29+
default SELF agent(String name, Object agent) {
30+
agentInternalDelegate().agent(name, agent);
31+
return (SELF) this;
32+
}
33+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Copyright 2020-Present The Serverless Workflow Specification Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.serverlessworkflow.fluent.agentic;
17+
18+
import static io.serverlessworkflow.fluent.agentic.Models.BASE_MODEL;
19+
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
20+
import static org.junit.jupiter.api.Assertions.assertNotNull;
21+
import static org.mockito.Mockito.spy;
22+
23+
import dev.langchain4j.agentic.AgentServices;
24+
import io.serverlessworkflow.api.types.Workflow;
25+
import io.serverlessworkflow.api.types.func.CallJava;
26+
import org.junit.jupiter.api.Test;
27+
28+
public class AgenticWorkflowBuilderTest {
29+
30+
@Test
31+
public void verifyAgentCall() {
32+
Agents.MovieExpert movieExpert =
33+
spy(
34+
AgentServices.agentBuilder(Agents.MovieExpert.class)
35+
.outputName("movies")
36+
.chatModel(BASE_MODEL)
37+
.build());
38+
39+
Workflow workflow =
40+
AgenticWorkflowBuilder.workflow()
41+
.tasks(tasks -> tasks.agent("myAgent", movieExpert))
42+
.build();
43+
44+
assertNotNull(workflow);
45+
assertInstanceOf(CallJava.class, workflow.getDo().get(0).getTask().getCallTask().get());
46+
}
47+
}

0 commit comments

Comments
 (0)