Skip to content

Commit 3756926

Browse files
Fix #866 - Refactor FuncDSL and expose export/input/output to Functions (#871)
* Fix #866 - Refactor FuncDSL and expose export/input/output to Functions Signed-off-by: Ricardo Zanini <ricardozanini@gmail.com> * Review FuncDSL Signed-off-by: Ricardo Zanini <ricardozanini@gmail.com> * Add consumer and JavaContextFunction shortcuts Signed-off-by: Ricardo Zanini <ricardozanini@gmail.com> * Add Class<T> args to switch predicates Signed-off-by: Ricardo Zanini <ricardozanini@gmail.com> * Incorporating Javi's review Signed-off-by: Ricardo Zanini <ricardozanini@gmail.com> --------- Signed-off-by: Ricardo Zanini <ricardozanini@gmail.com>
1 parent b043e89 commit 3756926

File tree

71 files changed

+2789
-544
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

71 files changed

+2789
-544
lines changed
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16-
package io.serverlessworkflow.fluent.agentic.configurer;
16+
package io.serverlessworkflow.fluent.agentic.configurers;
1717

1818
import io.serverlessworkflow.fluent.agentic.AgentListenTaskBuilder;
1919
import java.util.function.Consumer;
2020

2121
@FunctionalInterface
22-
public interface ListenConfigurer extends Consumer<AgentListenTaskBuilder> {}
22+
public interface AgentListenConfigurer extends Consumer<AgentListenTaskBuilder> {}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16-
package io.serverlessworkflow.fluent.agentic.configurer;
16+
package io.serverlessworkflow.fluent.agentic.configurers;
1717

1818
import io.serverlessworkflow.fluent.agentic.AgentDoTaskBuilder;
1919
import java.util.function.Consumer;
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
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.dsl;
17+
18+
import io.serverlessworkflow.fluent.agentic.AgentListenTaskBuilder;
19+
import io.serverlessworkflow.fluent.agentic.configurers.AgentListenConfigurer;
20+
import io.serverlessworkflow.fluent.func.dsl.BaseFuncListenSpec;
21+
import io.serverlessworkflow.fluent.spec.AbstractListenTaskBuilder;
22+
23+
public final class AgentListenSpec
24+
extends BaseFuncListenSpec<AgentListenSpec, AgentListenTaskBuilder>
25+
implements AgentListenConfigurer {
26+
27+
public AgentListenSpec() {
28+
super(AbstractListenTaskBuilder::to);
29+
}
30+
31+
@Override
32+
protected AgentListenSpec self() {
33+
return this;
34+
}
35+
36+
@Override
37+
public void accept(AgentListenTaskBuilder agentListenTaskBuilder) {
38+
acceptInto(agentListenTaskBuilder);
39+
}
40+
}

experimental/fluent/agentic/src/main/java/io/serverlessworkflow/fluent/agentic/dsl/AgenticDSL.java

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,15 @@
1919
import io.cloudevents.CloudEventData;
2020
import io.serverlessworkflow.api.types.FlowDirectiveEnum;
2121
import io.serverlessworkflow.fluent.agentic.AgentDoTaskBuilder;
22-
import io.serverlessworkflow.fluent.agentic.configurer.AgentTaskConfigurer;
23-
import io.serverlessworkflow.fluent.agentic.configurer.FuncPredicateEventConfigurer;
24-
import io.serverlessworkflow.fluent.agentic.configurer.SwitchCaseConfigurer;
22+
import io.serverlessworkflow.fluent.agentic.configurers.AgentTaskConfigurer;
2523
import io.serverlessworkflow.fluent.func.FuncCallTaskBuilder;
2624
import io.serverlessworkflow.fluent.func.FuncEmitTaskBuilder;
2725
import io.serverlessworkflow.fluent.func.FuncSwitchTaskBuilder;
26+
import io.serverlessworkflow.fluent.func.configurers.FuncPredicateEventConfigurer;
27+
import io.serverlessworkflow.fluent.func.configurers.SwitchCaseConfigurer;
28+
import io.serverlessworkflow.fluent.func.dsl.ReflectionUtils;
29+
import io.serverlessworkflow.fluent.func.dsl.SwitchCaseSpec;
30+
import io.serverlessworkflow.fluent.func.dsl.internal.CommonFuncOps;
2831
import java.util.List;
2932
import java.util.Objects;
3033
import java.util.function.Consumer;
@@ -33,79 +36,75 @@
3336

3437
public final class AgenticDSL {
3538

39+
private static final CommonFuncOps OPS = new CommonFuncOps() {};
40+
3641
private AgenticDSL() {}
3742

3843
public static <T, V> Consumer<FuncCallTaskBuilder> fn(
3944
Function<T, V> function, Class<T> argClass) {
40-
return f -> f.function(function, argClass);
45+
return OPS.fn(function, argClass);
4146
}
4247

4348
public static <T, V> Consumer<FuncCallTaskBuilder> fn(Function<T, V> function) {
44-
return f -> f.function(function);
49+
return OPS.fn(function);
4550
}
4651

4752
public static Consumer<FuncSwitchTaskBuilder> cases(SwitchCaseConfigurer... cases) {
48-
return s -> {
49-
for (SwitchCaseConfigurer c : cases) {
50-
s.onPredicate(c);
51-
}
52-
};
53+
return OPS.cases(cases);
5354
}
5455

55-
public static <T> SwitchCaseSpec<T> on(Predicate<T> when, Class<T> whenClass) {
56-
return new SwitchCaseSpec<T>().when(when, whenClass);
56+
public static <T> SwitchCaseSpec<T> caseOf(Predicate<T> when, Class<T> whenClass) {
57+
return OPS.caseOf(when, whenClass);
5758
}
5859

59-
public static <T> SwitchCaseSpec<T> on(Predicate<T> when) {
60-
return new SwitchCaseSpec<T>().when(when);
60+
public static <T> SwitchCaseSpec<T> caseOf(Predicate<T> when) {
61+
return OPS.caseOf(when);
6162
}
6263

63-
public static SwitchCaseConfigurer onDefault(String task) {
64-
return s -> s.then(task);
64+
public static SwitchCaseConfigurer caseDefault(String task) {
65+
return OPS.caseDefault(task);
6566
}
6667

67-
public static SwitchCaseConfigurer onDefault(FlowDirectiveEnum directive) {
68-
return s -> s.then(directive);
68+
public static SwitchCaseConfigurer caseDefault(FlowDirectiveEnum directive) {
69+
return OPS.caseDefault(directive);
6970
}
7071

71-
public static ListenSpec to() {
72-
return new ListenSpec();
72+
public static AgentListenSpec to() {
73+
return new AgentListenSpec();
7374
}
7475

75-
public static ListenSpec toOne(String type) {
76-
return new ListenSpec().one(e -> e.type(type));
76+
public static AgentListenSpec toOne(String type) {
77+
return new AgentListenSpec().one(e -> e.type(type));
7778
}
7879

79-
public static ListenSpec toAll(String... types) {
80+
public static AgentListenSpec toAll(String... types) {
8081
FuncPredicateEventConfigurer[] events = new FuncPredicateEventConfigurer[types.length];
8182
for (int i = 0; i < types.length; i++) {
8283
events[i] = event(types[i]);
8384
}
84-
return new ListenSpec().all(events);
85+
return new AgentListenSpec().all(events);
8586
}
8687

87-
public static ListenSpec toAny(String... types) {
88+
public static AgentListenSpec toAny(String... types) {
8889
FuncPredicateEventConfigurer[] events = new FuncPredicateEventConfigurer[types.length];
8990
for (int i = 0; i < types.length; i++) {
9091
events[i] = event(types[i]);
9192
}
92-
return new ListenSpec().any(events);
93+
return new AgentListenSpec().any(events);
9394
}
9495

9596
public static FuncPredicateEventConfigurer event(String type) {
96-
return e -> e.type(type);
97+
return OPS.event(type);
9798
}
9899

99-
// TODO: expand the `event` static ref with more attributes based on community feedback
100-
101100
public static <T> Consumer<FuncEmitTaskBuilder> event(
102101
String type, Function<T, CloudEventData> function) {
103-
return event -> event.event(e -> e.type(type).data(function));
102+
return OPS.event(type, function);
104103
}
105104

106105
public static <T> Consumer<FuncEmitTaskBuilder> event(
107106
String type, Function<T, CloudEventData> function, Class<T> clazz) {
108-
return event -> event.event(e -> e.type(type).data(function, clazz));
107+
return OPS.event(type, function, clazz);
109108
}
110109

111110
// -------- Agentic Workflow Patterns -------- //
@@ -148,7 +147,8 @@ public static <T, V> AgentTaskConfigurer function(Function<T, V> function, Class
148147
}
149148

150149
public static <T, V> AgentTaskConfigurer function(Function<T, V> function) {
151-
return list -> list.callFn(fn(function));
150+
Class<T> clazz = ReflectionUtils.inferInputType(function);
151+
return list -> list.callFn(fn(function, clazz));
152152
}
153153

154154
public static AgentTaskConfigurer agent(Object agent) {

experimental/fluent/agentic/src/main/java/io/serverlessworkflow/fluent/agentic/dsl/ListenSpec.java

Lines changed: 0 additions & 72 deletions
This file was deleted.

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@
1818
import static io.serverlessworkflow.fluent.agentic.dsl.AgenticDSL.cases;
1919
import static io.serverlessworkflow.fluent.agentic.dsl.AgenticDSL.event;
2020
import static io.serverlessworkflow.fluent.agentic.dsl.AgenticDSL.fn;
21-
import static io.serverlessworkflow.fluent.agentic.dsl.AgenticDSL.on;
22-
import static io.serverlessworkflow.fluent.agentic.dsl.AgenticDSL.onDefault;
2321
import static io.serverlessworkflow.fluent.agentic.dsl.AgenticDSL.toAny;
2422
import static org.assertj.core.api.Assertions.assertThat;
2523
import static org.junit.jupiter.api.Assertions.fail;
@@ -30,6 +28,7 @@
3028
import io.serverlessworkflow.api.types.EventFilter;
3129
import io.serverlessworkflow.api.types.EventProperties;
3230
import io.serverlessworkflow.api.types.Workflow;
31+
import io.serverlessworkflow.fluent.agentic.dsl.AgenticDSL;
3332
import io.serverlessworkflow.impl.WorkflowApplication;
3433
import io.serverlessworkflow.impl.WorkflowStatus;
3534
import io.serverlessworkflow.impl.jackson.JsonUtils;
@@ -68,11 +67,11 @@ void email_drafter_agent() {
6867
.switchCase(
6968
"needsHumanReview?",
7069
cases(
71-
on(
70+
AgenticDSL.caseOf(
7271
d -> !EmailPolicies.Decision.AUTO_SEND.equals(d.decision()),
7372
PolicyDecision.class)
7473
.then("requestReview"),
75-
onDefault("emailFinished")))
74+
AgenticDSL.caseDefault("emailFinished")))
7675
.emit(
7776
"requestReview",
7877
event(

experimental/fluent/func/pom.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@
2121
<groupId>io.serverlessworkflow</groupId>
2222
<artifactId>serverlessworkflow-experimental-types</artifactId>
2323
</dependency>
24+
<dependency>
25+
<groupId>io.serverlessworkflow</groupId>
26+
<artifactId>serverlessworkflow-impl-json</artifactId>
27+
</dependency>
2428
<dependency>
2529
<groupId>io.serverlessworkflow</groupId>
2630
<artifactId>serverlessworkflow-fluent-spec</artifactId>

experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncCallTaskBuilder.java

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,15 @@
1717

1818
import io.serverlessworkflow.api.types.func.CallJava;
1919
import io.serverlessworkflow.api.types.func.CallTaskJava;
20+
import io.serverlessworkflow.api.types.func.JavaContextFunction;
2021
import io.serverlessworkflow.fluent.func.spi.ConditionalTaskBuilder;
21-
import io.serverlessworkflow.fluent.func.spi.FuncTransformations;
22+
import io.serverlessworkflow.fluent.func.spi.FuncTaskTransformations;
2223
import io.serverlessworkflow.fluent.spec.TaskBaseBuilder;
24+
import java.util.function.Consumer;
2325
import java.util.function.Function;
2426

2527
public class FuncCallTaskBuilder extends TaskBaseBuilder<FuncCallTaskBuilder>
26-
implements FuncTransformations<FuncCallTaskBuilder>,
28+
implements FuncTaskTransformations<FuncCallTaskBuilder>,
2729
ConditionalTaskBuilder<FuncCallTaskBuilder> {
2830

2931
private CallTaskJava callTaskJava;
@@ -48,6 +50,31 @@ public <T, V> FuncCallTaskBuilder function(Function<T, V> function, Class<T> arg
4850
return this;
4951
}
5052

53+
public <T, V> FuncCallTaskBuilder function(JavaContextFunction<T, V> function) {
54+
return function(function, null);
55+
}
56+
57+
public <T, V> FuncCallTaskBuilder function(
58+
JavaContextFunction<T, V> function, Class<T> argClass) {
59+
this.callTaskJava = new CallTaskJava(CallJava.function(function, argClass));
60+
super.setTask(this.callTaskJava.getCallJava());
61+
return this;
62+
}
63+
64+
/** Accept a side-effect Consumer; engine should pass input through unchanged. */
65+
public <T> FuncCallTaskBuilder consumer(Consumer<T> consumer) {
66+
this.callTaskJava = new CallTaskJava(CallJava.consumer(consumer));
67+
super.setTask(this.callTaskJava.getCallJava());
68+
return this;
69+
}
70+
71+
/** Accept a Consumer with explicit input type hint. */
72+
public <T> FuncCallTaskBuilder consumer(Consumer<T> consumer, Class<T> argClass) {
73+
this.callTaskJava = new CallTaskJava(CallJava.consumer(consumer, argClass));
74+
super.setTask(this.callTaskJava.getCallJava());
75+
return this;
76+
}
77+
5178
public CallTaskJava build() {
5279
return this.callTaskJava;
5380
}

experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncDoTaskBuilder.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@
1717

1818
import io.serverlessworkflow.fluent.func.spi.ConditionalTaskBuilder;
1919
import io.serverlessworkflow.fluent.func.spi.FuncDoFluent;
20-
import io.serverlessworkflow.fluent.func.spi.FuncTransformations;
20+
import io.serverlessworkflow.fluent.func.spi.FuncTaskTransformations;
2121
import io.serverlessworkflow.fluent.spec.BaseDoTaskBuilder;
2222
import java.util.function.Consumer;
2323

2424
public class FuncDoTaskBuilder extends BaseDoTaskBuilder<FuncDoTaskBuilder, FuncTaskItemListBuilder>
25-
implements FuncTransformations<FuncDoTaskBuilder>,
25+
implements FuncTaskTransformations<FuncDoTaskBuilder>,
2626
ConditionalTaskBuilder<FuncDoTaskBuilder>,
2727
FuncDoFluent<FuncDoTaskBuilder> {
2828

experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncEmitTaskBuilder.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@
1616
package io.serverlessworkflow.fluent.func;
1717

1818
import io.serverlessworkflow.fluent.func.spi.ConditionalTaskBuilder;
19-
import io.serverlessworkflow.fluent.func.spi.FuncTransformations;
19+
import io.serverlessworkflow.fluent.func.spi.FuncTaskTransformations;
2020
import io.serverlessworkflow.fluent.spec.AbstractEmitTaskBuilder;
2121

2222
public class FuncEmitTaskBuilder
2323
extends AbstractEmitTaskBuilder<FuncEmitTaskBuilder, FuncEventPropertiesBuilder>
2424
implements ConditionalTaskBuilder<FuncEmitTaskBuilder>,
25-
FuncTransformations<FuncEmitTaskBuilder> {
25+
FuncTaskTransformations<FuncEmitTaskBuilder> {
2626
FuncEmitTaskBuilder() {
2727
super();
2828
}

0 commit comments

Comments
 (0)