15
15
*/
16
16
package io .serverlessworkflow .fluent .agentic .langchain4j ;
17
17
18
+ import dev .langchain4j .agentic .UntypedAgent ;
18
19
import dev .langchain4j .agentic .cognisphere .Cognisphere ;
19
20
import dev .langchain4j .agentic .cognisphere .CognisphereAccess ;
20
21
import dev .langchain4j .agentic .cognisphere .CognisphereKey ;
21
22
import dev .langchain4j .agentic .cognisphere .CognisphereRegistry ;
23
+ import dev .langchain4j .agentic .cognisphere .ResultWithCognisphere ;
22
24
import dev .langchain4j .agentic .internal .AgentInstance ;
25
+ import dev .langchain4j .agentic .internal .AgentSpecification ;
23
26
import dev .langchain4j .agentic .internal .CognisphereOwner ;
27
+ import dev .langchain4j .service .MemoryId ;
24
28
import io .serverlessworkflow .api .types .Workflow ;
25
29
import io .serverlessworkflow .impl .WorkflowApplication ;
30
+ import io .serverlessworkflow .impl .WorkflowModel ;
31
+
26
32
import java .lang .reflect .Method ;
33
+ import java .lang .reflect .Parameter ;
34
+ import java .util .HashMap ;
35
+ import java .util .Map ;
36
+ import java .util .concurrent .CompletableFuture ;
37
+ import java .util .concurrent .ExecutionException ;
27
38
28
39
public class WorkflowInvocationHandler implements CognisphereOwner {
29
40
@@ -37,6 +48,38 @@ public class WorkflowInvocationHandler implements CognisphereOwner {
37
48
this .workflowApplicationBuilder = workflowApplicationBuilder ;
38
49
}
39
50
51
+ @ SuppressWarnings ("unchecked" )
52
+ private static void writeCognisphereState (Cognisphere cognisphere , Method method , Object [] args ) {
53
+ if (method .getDeclaringClass () == UntypedAgent .class ) {
54
+ cognisphere .writeStates ((Map <String , Object >) args [0 ]);
55
+ } else {
56
+ Parameter [] parameters = method .getParameters ();
57
+ for (int i = 0 ; i < parameters .length ; i ++) {
58
+ int index = i ;
59
+ AgentSpecification .optionalParameterName (parameters [i ])
60
+ .ifPresent (argName -> cognisphere .writeState (argName , args [index ]));
61
+ }
62
+ }
63
+ }
64
+
65
+ @ SuppressWarnings ("unchecked" )
66
+ private static void writeWorkflowInputState (final Map <String , Object > input , Method method , Object [] args ) {
67
+ if (method .getDeclaringClass () == UntypedAgent .class ) {
68
+ input .putAll (((Map <String , Object >) args [0 ]));
69
+ } else {
70
+ Parameter [] parameters = method .getParameters ();
71
+ for (int i = 0 ; i < parameters .length ; i ++) {
72
+ int index = i ;
73
+ AgentSpecification .optionalParameterName (parameters [i ])
74
+ .ifPresent (argName -> input .put (argName , args [index ]));
75
+ }
76
+ }
77
+ }
78
+
79
+ private String agentId () {
80
+ return workflow .getDocument ().getName ();
81
+ }
82
+
40
83
@ Override
41
84
public Object invoke (Object proxy , Method method , Object [] args ) throws Throwable {
42
85
// outputName
@@ -69,24 +112,73 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl
69
112
if (method .getDeclaringClass () == CognisphereAccess .class ) {
70
113
return switch (method .getName ()) {
71
114
case "getCognisphere" ->
72
- CognisphereRegistry .get (
73
- new CognisphereKey (this .workflow .getDocument ().getName (), args [0 ]));
115
+ CognisphereRegistry .get (new CognisphereKey (this .agentId (), args [0 ]));
74
116
case "evictCognisphere" ->
75
- CognisphereRegistry .evict (
76
- new CognisphereKey (this .workflow .getDocument ().getName (), args [0 ]));
117
+ CognisphereRegistry .evict (new CognisphereKey (this .agentId (), args [0 ]));
77
118
default ->
78
119
throw new UnsupportedOperationException (
79
120
"Unknown method on CognisphereAccess class : " + method .getName ());
80
121
};
81
122
}
82
123
83
124
// invoke
84
- return null ;
125
+ return executeWorkflow (method , args );
126
+ }
127
+
128
+ private Object executeWorkflow (Method method , Object [] args ) {
129
+ // TODO: actually, we must own the Cognisphere object creation upon calling the workflow
130
+
131
+ //writeCognisphereState(cognisphere, method, args);
132
+
133
+ Object input ;
134
+ if (args == null || args .length == 0 ) {
135
+ input = new HashMap <>();
136
+ } else if (args .length == 1 ) {
137
+ input = args [0 ];
138
+ } else {
139
+ Map <String , Object > inputMap = new HashMap <>();
140
+ writeWorkflowInputState (inputMap , method , args );
141
+ input = inputMap ;
142
+ }
143
+
144
+ try (WorkflowApplication app = workflowApplicationBuilder .build ()) {
145
+ CompletableFuture <WorkflowModel > workflowInstance = app .workflowDefinition (workflow ).instance (input ).start ();
146
+
147
+ if (method .getReturnType ().equals (ResultWithCognisphere .class )) {
148
+ return workflowInstance .get ().as (ResultWithCognisphere .class );
149
+ } else {
150
+ return workflowInstance .get ().asJavaObject ();
151
+ }
152
+ } catch (ExecutionException | InterruptedException e ) {
153
+ throw new RuntimeException (
154
+ "Failed to execute workflow: " + agentId () + " - Cognisphere: " + cognisphere , e );
155
+ }
85
156
}
86
157
87
158
@ Override
88
159
public CognisphereOwner withCognisphere (Cognisphere cognisphere ) {
89
160
this .cognisphere = cognisphere ;
90
161
return this ;
91
162
}
163
+
164
+ private Cognisphere currentCognisphere (Method method , Object [] args ) {
165
+ if (cognisphere != null ) {
166
+ return cognisphere ;
167
+ }
168
+
169
+ Object memoryId = memoryId (method , args );
170
+ return memoryId != null
171
+ ? CognisphereRegistry .getOrCreate (new CognisphereKey (this .agentId (), memoryId ))
172
+ : CognisphereRegistry .createEphemeralCognisphere ();
173
+ }
174
+
175
+ private Object memoryId (Method method , Object [] args ) {
176
+ Parameter [] parameters = method .getParameters ();
177
+ for (int i = 0 ; i < parameters .length ; i ++) {
178
+ if (parameters [i ].getAnnotation (MemoryId .class ) != null ) {
179
+ return args [i ];
180
+ }
181
+ }
182
+ return null ;
183
+ }
92
184
}
0 commit comments