2828import io .serverlessworkflow .fluent .func .configurers .FuncPredicateEventConfigurer ;
2929import io .serverlessworkflow .fluent .func .configurers .FuncTaskConfigurer ;
3030import io .serverlessworkflow .fluent .func .configurers .SwitchCaseConfigurer ;
31- import io .serverlessworkflow .fluent .func .dsl .internal .CommonFuncOps ;
3231import io .serverlessworkflow .fluent .spec .configurers .AuthenticationConfigurer ;
3332import io .serverlessworkflow .impl .TaskContextData ;
3433import io .serverlessworkflow .impl .WorkflowContextData ;
@@ -97,15 +96,15 @@ public static <T, V> Consumer<FuncCallTaskBuilder> fn(
9796 * @param <V> output type
9897 * @return a consumer that configures a {@code FuncCallTaskBuilder}
9998 */
100- public static <T , V > Consumer <FuncCallTaskBuilder > fn (Function <T , V > function ) {
101- return f -> f .function (function );
99+ public static <T , V > Consumer <FuncCallTaskBuilder > fn (SerializableFunction <T , V > function ) {
100+ return f -> f .function (function , ReflectionUtils . inferInputType ( function ) );
102101 }
103102
104103 /**
105104 * Compose multiple switch cases into a single configurer for {@link FuncSwitchTaskBuilder}.
106105 *
107- * @param cases one or more {@link SwitchCaseConfigurer} built via {@link #caseOf(Predicate)} or
108- * {@link #caseDefault(String)}
106+ * @param cases one or more {@link SwitchCaseConfigurer} built via {@link
107+ * #caseOf(SerializablePredicate)} or {@link #caseDefault(String)}
109108 * @return a consumer to apply on a switch task builder
110109 */
111110 public static Consumer <FuncSwitchTaskBuilder > cases (SwitchCaseConfigurer ... cases ) {
@@ -131,7 +130,7 @@ public static <T> SwitchCaseSpec<T> caseOf(Predicate<T> when, Class<T> whenClass
131130 * @param <T> predicate input type
132131 * @return a fluent builder to set the consequent action (e.g., {@code then("taskName")})
133132 */
134- public static <T > SwitchCaseSpec <T > caseOf (Predicate <T > when ) {
133+ public static <T > SwitchCaseSpec <T > caseOf (SerializablePredicate <T > when ) {
135134 return OPS .caseOf (when );
136135 }
137136
@@ -213,12 +212,13 @@ public static FuncListenSpec toAny(String... types) {
213212 * @return a consumer to configure {@link FuncEmitTaskBuilder}
214213 */
215214 public static <T > Consumer <FuncEmitTaskBuilder > event (
216- String type , Function <T , CloudEventData > function ) {
217- return OPS .event (type , function );
215+ String type , SerializableFunction <T , CloudEventData > function ) {
216+ return OPS .event (type , function , ReflectionUtils . inferInputType ( function ) );
218217 }
219218
220219 /**
221- * Same as {@link #event(String, Function)} but with an explicit input class to guide conversion.
220+ * Same as {@link #event(String, SerializableFunction)} but with an explicit input class to guide
221+ * conversion.
222222 *
223223 * @param type CloudEvent type
224224 * @param function function that maps workflow input to {@link CloudEventData}
@@ -279,20 +279,6 @@ public static FuncPredicateEventConfigurer event(String type) {
279279 return OPS .event (type );
280280 }
281281
282- /**
283- * Create a {@link FuncCallStep} that calls a simple Java {@link Function} with explicit input
284- * type.
285- *
286- * @param fn the function to execute at runtime
287- * @param inputClass expected input class for model conversion
288- * @param <T> input type
289- * @param <R> result type
290- * @return a call step which supports chaining (e.g., {@code .exportAs(...).when(...)})
291- */
292- public static <T , R > FuncCallStep <T , R > function (Function <T , R > fn , Class <T > inputClass ) {
293- return new FuncCallStep <>(fn , inputClass );
294- }
295-
296282 /**
297283 * Build a call step for functions that need {@link WorkflowContextData} as the first parameter.
298284 * The DSL wraps it as a {@link JavaContextFunction} and injects the runtime context.
@@ -309,21 +295,8 @@ public static <T, R> FuncCallStep<T, R> withContext(JavaContextFunction<T, R> fn
309295 return withContext (null , fn , in );
310296 }
311297
312- /**
313- * Build a call step for functions that expect the workflow instance ID as the first parameter.
314- * The instance ID is extracted from the runtime context.
315- *
316- * <p>Signature expected: {@code (instanceId, payload) -> result}
317- *
318- * @param fn instance-id-aware function
319- * @param in payload input class
320- * @param <T> input type
321- * @param <R> result type
322- * @return a call step
323- */
324- public static <T , R > FuncCallStep <T , R > withInstanceId (
325- InstanceIdBiFunction <T , R > fn , Class <T > in ) {
326- return withInstanceId (null , fn , in );
298+ public static <T , R > FuncCallStep <T , R > withContext (JavaContextFunction <T , R > fn ) {
299+ return withContext (null , fn , ReflectionUtils .inferInputType (fn ));
327300 }
328301
329302 /**
@@ -341,6 +314,10 @@ public static <T, R> FuncCallStep<T, R> withContext(
341314 return new FuncCallStep <>(name , fn , in );
342315 }
343316
317+ public static <T , R > FuncCallStep <T , R > withContext (String name , JavaContextFunction <T , R > fn ) {
318+ return new FuncCallStep <>(name , fn , ReflectionUtils .inferInputType (fn ));
319+ }
320+
344321 /**
345322 * Build a call step for functions that need {@link WorkflowContextData} and {@link
346323 * TaskContextData} as the first and second parameter. The DSL wraps it as a {@link
@@ -373,8 +350,16 @@ public static <T, R> FuncCallStep<T, R> withFilter(
373350 return new FuncCallStep <>(name , fn , in );
374351 }
375352
353+ public static <T , R > FuncCallStep <T , R > withFilter (JavaFilterFunction <T , R > fn ) {
354+ return withFilter (null , fn , ReflectionUtils .inferInputType (fn ));
355+ }
356+
357+ public static <T , R > FuncCallStep <T , R > withFilter (String name , JavaFilterFunction <T , R > fn ) {
358+ return withFilter (name , fn , ReflectionUtils .inferInputType (fn ));
359+ }
360+
376361 /**
377- * Named variant of {@link #withInstanceId(InstanceIdBiFunction , Class)}.
362+ * Named variant of {@link #withInstanceId(InstanceIdFunction , Class)}.
378363 *
379364 * @param name task name
380365 * @param fn instance-id-aware function
@@ -384,11 +369,35 @@ public static <T, R> FuncCallStep<T, R> withFilter(
384369 * @return a named call step
385370 */
386371 public static <T , R > FuncCallStep <T , R > withInstanceId (
387- String name , InstanceIdBiFunction <T , R > fn , Class <T > in ) {
372+ String name , InstanceIdFunction <T , R > fn , Class <T > in ) {
388373 JavaContextFunction <T , R > jcf = (payload , wctx ) -> fn .apply (wctx .instanceData ().id (), payload );
389374 return new FuncCallStep <>(name , jcf , in );
390375 }
391376
377+ /**
378+ * Build a call step for functions that expect the workflow instance ID as the first parameter.
379+ * The instance ID is extracted from the runtime context.
380+ *
381+ * <p>Signature expected: {@code (instanceId, payload) -> result}
382+ *
383+ * @param fn instance-id-aware function
384+ * @param in payload input class
385+ * @param <T> input type
386+ * @param <R> result type
387+ * @return a call step
388+ */
389+ public static <T , R > FuncCallStep <T , R > withInstanceId (InstanceIdFunction <T , R > fn , Class <T > in ) {
390+ return withInstanceId (null , fn , in );
391+ }
392+
393+ public static <T , R > FuncCallStep <T , R > withInstanceId (String name , InstanceIdFunction <T , R > fn ) {
394+ return withInstanceId (name , fn , ReflectionUtils .inferInputType (fn ));
395+ }
396+
397+ public static <T , R > FuncCallStep <T , R > withInstanceId (InstanceIdFunction <T , R > fn ) {
398+ return withInstanceId (null , fn , ReflectionUtils .inferInputType (fn ));
399+ }
400+
392401 /**
393402 * Builds a composition of the current workflow instance id and the definition of the task
394403 * position as a JSON pointer, used as a stable "unique id" for the task.
@@ -422,6 +431,10 @@ public static <T, R> FuncCallStep<T, R> withUniqueId(
422431 return new FuncCallStep <>(name , jff , in );
423432 }
424433
434+ public static <T , R > FuncCallStep <T , R > withUniqueId (String name , UniqueIdBiFunction <T , R > fn ) {
435+ return withUniqueId (name , fn , ReflectionUtils .inferInputType (fn ));
436+ }
437+
425438 /**
426439 * Variant of {@link #withUniqueId(String, UniqueIdBiFunction, Class)} without an explicit task
427440 * name.
@@ -436,6 +449,10 @@ public static <T, R> FuncCallStep<T, R> withUniqueId(UniqueIdBiFunction<T, R> fn
436449 return withUniqueId (null , fn , in );
437450 }
438451
452+ public static <T , R > FuncCallStep <T , R > withUniqueId (UniqueIdBiFunction <T , R > fn ) {
453+ return withUniqueId (null , fn , ReflectionUtils .inferInputType (fn ));
454+ }
455+
439456 /**
440457 * Create a fire-and-forget side-effect step (unnamed). The consumer receives the typed input.
441458 *
@@ -449,6 +466,10 @@ public static <T> ConsumeStep<T> consume(Consumer<T> consumer, Class<T> inputCla
449466 return new ConsumeStep <>(consumer , inputClass );
450467 }
451468
469+ public static <T > ConsumeStep <T > consume (SerializableConsumer <T > consumer ) {
470+ return consume (consumer , ReflectionUtils .inferInputType (consumer ));
471+ }
472+
452473 /**
453474 * Named variant of {@link #consume(Consumer, Class)}.
454475 *
@@ -462,6 +483,10 @@ public static <T> ConsumeStep<T> consume(String name, Consumer<T> consumer, Clas
462483 return new ConsumeStep <>(name , consumer , inputClass );
463484 }
464485
486+ public static <T > ConsumeStep <T > consume (String name , SerializableConsumer <T > consumer ) {
487+ return consume (name , consumer , ReflectionUtils .inferInputType (consumer ));
488+ }
489+
465490 /**
466491 * Agent-style sugar for methods that receive a "memory id" as first parameter. The DSL uses a
467492 * derived unique id composed of the workflow instance id and the task position (JSON pointer),
@@ -479,6 +504,10 @@ public static <T, R> FuncCallStep<T, R> agent(UniqueIdBiFunction<T, R> fn, Class
479504 return withUniqueId (fn , in );
480505 }
481506
507+ public static <T , R > FuncCallStep <T , R > agent (UniqueIdBiFunction <T , R > fn ) {
508+ return withUniqueId (fn , ReflectionUtils .inferInputType (fn ));
509+ }
510+
482511 /**
483512 * Named agent-style sugar. See {@link #agent(UniqueIdBiFunction, Class)}.
484513 *
@@ -496,6 +525,24 @@ public static <T, R> FuncCallStep<T, R> agent(
496525 return withUniqueId (name , fn , in );
497526 }
498527
528+ public static <T , R > FuncCallStep <T , R > agent (String name , UniqueIdBiFunction <T , R > fn ) {
529+ return withUniqueId (name , fn , ReflectionUtils .inferInputType (fn ));
530+ }
531+
532+ /**
533+ * Create a {@link FuncCallStep} that calls a simple Java {@link Function} with explicit input
534+ * type.
535+ *
536+ * @param fn the function to execute at runtime
537+ * @param inputClass expected input class for model conversion
538+ * @param <T> input type
539+ * @param <R> result type
540+ * @return a call step which supports chaining (e.g., {@code .exportAs(...).when(...)})
541+ */
542+ public static <T , R > FuncCallStep <T , R > function (Function <T , R > fn , Class <T > inputClass ) {
543+ return new FuncCallStep <>(fn , inputClass );
544+ }
545+
499546 /**
500547 * Create a {@link FuncCallStep} that invokes a plain Java {@link Function} with inferred input
501548 * type.
@@ -505,21 +552,21 @@ public static <T, R> FuncCallStep<T, R> agent(
505552 * @param <R> output type
506553 * @return a call step
507554 */
508- public static <T , R > FuncCallStep <T , R > function (Function <T , R > fn ) {
555+ public static <T , R > FuncCallStep <T , R > function (SerializableFunction <T , R > fn ) {
509556 Class <T > inputClass = ReflectionUtils .inferInputType (fn );
510557 return new FuncCallStep <>(fn , inputClass );
511558 }
512559
513560 /**
514- * Named variant of {@link #function(Function )} with inferred input type.
561+ * Named variant of {@link #function(SerializableFunction )} with inferred input type.
515562 *
516563 * @param name task name
517564 * @param fn the function to execute
518565 * @param <T> input type
519566 * @param <R> output type
520567 * @return a named call step
521568 */
522- public static <T , R > FuncCallStep <T , R > function (String name , Function <T , R > fn ) {
569+ public static <T , R > FuncCallStep <T , R > function (String name , SerializableFunction <T , R > fn ) {
523570 Class <T > inputClass = ReflectionUtils .inferInputType (fn );
524571 return new FuncCallStep <>(name , fn , inputClass );
525572 }
@@ -584,20 +631,21 @@ public static EmitStep emit(String name, Consumer<FuncEmitTaskBuilder> cfg) {
584631 * @param <T> input type
585632 * @return an {@link EmitStep}
586633 */
587- public static <T > EmitStep emit (String type , Function <T , CloudEventData > fn ) {
634+ public static <T > EmitStep emit (String type , SerializableFunction <T , CloudEventData > fn ) {
588635 return new EmitStep (null , event (type , fn ));
589636 }
590637
591638 /**
592- * Named variant of {@link #emit(String, Function )}.
639+ * Named variant of {@link #emit(String, SerializableFunction )}.
593640 *
594641 * @param name task name
595642 * @param type CloudEvent type
596643 * @param fn function producing {@link CloudEventData}
597644 * @param <T> input type
598645 * @return a named {@link EmitStep}
599646 */
600- public static <T > EmitStep emit (String name , String type , Function <T , CloudEventData > fn ) {
647+ public static <T > EmitStep emit (
648+ String name , String type , SerializableFunction <T , CloudEventData > fn ) {
601649 return new EmitStep (name , event (type , fn ));
602650 }
603651
@@ -678,7 +726,7 @@ public static ListenStep listen(String name, FuncListenSpec spec) {
678726
679727 /**
680728 * Low-level switch case configurer using a custom builder consumer. Prefer the {@link
681- * #caseOf(Predicate )} helpers when possible.
729+ * #caseOf(SerializablePredicate )} helpers when possible.
682730 *
683731 * @param taskName optional task name
684732 * @param switchCase consumer to configure the {@link FuncSwitchTaskBuilder}
@@ -701,7 +749,7 @@ public static FuncTaskConfigurer switchCase(Consumer<FuncSwitchTaskBuilder> swit
701749
702750 /**
703751 * Convenience to apply multiple {@link SwitchCaseConfigurer} built via {@link
704- * #caseOf(Predicate )}.
752+ * #caseOf(SerializablePredicate )}.
705753 *
706754 * @param cases case configurers
707755 * @return list configurer
@@ -773,6 +821,11 @@ public static <T> FuncTaskConfigurer switchWhenOrElse(
773821 FuncDSL .cases (caseOf (pred , predClass ).then (thenTask ), caseDefault (otherwise )));
774822 }
775823
824+ public static <T > FuncTaskConfigurer switchWhenOrElse (
825+ SerializablePredicate <T > pred , String thenTask , FlowDirectiveEnum otherwise ) {
826+ return switchWhenOrElse (pred , thenTask , otherwise , ReflectionUtils .inferInputType (pred ));
827+ }
828+
776829 /**
777830 * Sugar for a single-case switch with a default task fallback.
778831 *
@@ -789,6 +842,11 @@ public static <T> FuncTaskConfigurer switchWhenOrElse(
789842 list .switchCase (cases (caseOf (pred , predClass ).then (thenTask ), caseDefault (otherwiseTask )));
790843 }
791844
845+ public static <T > FuncTaskConfigurer switchWhenOrElse (
846+ SerializablePredicate <T > pred , String thenTask , String otherwiseTask ) {
847+ return switchWhenOrElse (pred , thenTask , otherwiseTask , ReflectionUtils .inferInputType (pred ));
848+ }
849+
792850 /**
793851 * JQ-based condition: if the JQ expression evaluates truthy → jump to {@code thenTask}, otherwise
794852 * follow the {@link FlowDirectiveEnum} given in {@code otherwise}.
0 commit comments