@flowgram.ai/runtime-js 0.1.0-alpha.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/index.js +1855 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/index.d.mts +86 -0
- package/dist/index.d.ts +86 -0
- package/dist/index.js +1896 -0
- package/dist/index.js.map +1 -0
- package/package.json +53 -0
|
@@ -0,0 +1,1855 @@
|
|
|
1
|
+
// ../interface/dist/esm/index.js
|
|
2
|
+
import z from "zod";
|
|
3
|
+
import z3 from "zod";
|
|
4
|
+
import z2 from "zod";
|
|
5
|
+
import z4 from "zod";
|
|
6
|
+
import z5 from "zod";
|
|
7
|
+
import z6 from "zod";
|
|
8
|
+
import z7 from "zod";
|
|
9
|
+
var FlowGramAPIName = /* @__PURE__ */ ((FlowGramAPIName2) => {
|
|
10
|
+
FlowGramAPIName2["ServerInfo"] = "ServerInfo";
|
|
11
|
+
FlowGramAPIName2["TaskRun"] = "TaskRun";
|
|
12
|
+
FlowGramAPIName2["TaskReport"] = "TaskReport";
|
|
13
|
+
FlowGramAPIName2["TaskResult"] = "TaskResult";
|
|
14
|
+
FlowGramAPIName2["TaskCancel"] = "TaskCancel";
|
|
15
|
+
FlowGramAPIName2["Validation"] = "Validation";
|
|
16
|
+
return FlowGramAPIName2;
|
|
17
|
+
})(FlowGramAPIName || {});
|
|
18
|
+
var ValidationDefine = {
|
|
19
|
+
name: "Validation",
|
|
20
|
+
method: "POST",
|
|
21
|
+
path: "/validation",
|
|
22
|
+
module: "Validation",
|
|
23
|
+
schema: {
|
|
24
|
+
input: z.object({
|
|
25
|
+
schema: z.string()
|
|
26
|
+
}),
|
|
27
|
+
output: z.object({
|
|
28
|
+
valid: z.boolean(),
|
|
29
|
+
nodeErrors: z.array(
|
|
30
|
+
z.object({
|
|
31
|
+
message: z.string(),
|
|
32
|
+
nodeID: z.string()
|
|
33
|
+
})
|
|
34
|
+
),
|
|
35
|
+
edgeErrors: z.array(
|
|
36
|
+
z.object({
|
|
37
|
+
message: z.string(),
|
|
38
|
+
edge: z.object({
|
|
39
|
+
sourceNodeID: z.string(),
|
|
40
|
+
targetNodeID: z.string(),
|
|
41
|
+
sourcePortID: z.string().optional(),
|
|
42
|
+
targetPortID: z.string().optional()
|
|
43
|
+
})
|
|
44
|
+
})
|
|
45
|
+
)
|
|
46
|
+
})
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
var WorkflowIOZodSchema = z2.record(z2.string(), z2.any());
|
|
50
|
+
var WorkflowSnapshotZodSchema = z2.object({
|
|
51
|
+
id: z2.string(),
|
|
52
|
+
nodeID: z2.string(),
|
|
53
|
+
inputs: WorkflowIOZodSchema,
|
|
54
|
+
outputs: WorkflowIOZodSchema.optional(),
|
|
55
|
+
data: WorkflowIOZodSchema,
|
|
56
|
+
branch: z2.string().optional()
|
|
57
|
+
});
|
|
58
|
+
var WorkflowStatusZodShape = {
|
|
59
|
+
status: z2.string(),
|
|
60
|
+
terminated: z2.boolean(),
|
|
61
|
+
startTime: z2.number(),
|
|
62
|
+
endTime: z2.number().optional(),
|
|
63
|
+
timeCost: z2.number()
|
|
64
|
+
};
|
|
65
|
+
var WorkflowStatusZodSchema = z2.object(WorkflowStatusZodShape);
|
|
66
|
+
var WorkflowZodSchema = {
|
|
67
|
+
Inputs: WorkflowIOZodSchema,
|
|
68
|
+
Outputs: WorkflowIOZodSchema,
|
|
69
|
+
Status: WorkflowStatusZodSchema,
|
|
70
|
+
Snapshot: WorkflowSnapshotZodSchema,
|
|
71
|
+
NodeReport: z2.object({
|
|
72
|
+
id: z2.string(),
|
|
73
|
+
...WorkflowStatusZodShape,
|
|
74
|
+
snapshots: z2.array(WorkflowSnapshotZodSchema)
|
|
75
|
+
})
|
|
76
|
+
};
|
|
77
|
+
var TaskRunDefine = {
|
|
78
|
+
name: "TaskRun",
|
|
79
|
+
method: "POST",
|
|
80
|
+
path: "/task/run",
|
|
81
|
+
module: "Task",
|
|
82
|
+
schema: {
|
|
83
|
+
input: z3.object({
|
|
84
|
+
schema: z3.string(),
|
|
85
|
+
inputs: WorkflowZodSchema.Inputs
|
|
86
|
+
}),
|
|
87
|
+
output: z3.object({
|
|
88
|
+
taskID: z3.string()
|
|
89
|
+
})
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
var TaskResultDefine = {
|
|
93
|
+
name: "TaskResult",
|
|
94
|
+
method: "GET",
|
|
95
|
+
path: "/task/result",
|
|
96
|
+
module: "Task",
|
|
97
|
+
schema: {
|
|
98
|
+
input: z4.object({
|
|
99
|
+
taskID: z4.string()
|
|
100
|
+
}),
|
|
101
|
+
output: WorkflowZodSchema.Outputs
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
var TaskReportDefine = {
|
|
105
|
+
name: "TaskReport",
|
|
106
|
+
method: "GET",
|
|
107
|
+
path: "/task/report",
|
|
108
|
+
module: "Task",
|
|
109
|
+
schema: {
|
|
110
|
+
input: z5.object({
|
|
111
|
+
taskID: z5.string()
|
|
112
|
+
}),
|
|
113
|
+
output: z5.object({
|
|
114
|
+
id: z5.string(),
|
|
115
|
+
inputs: WorkflowZodSchema.Inputs,
|
|
116
|
+
outputs: WorkflowZodSchema.Outputs,
|
|
117
|
+
workflowStatus: WorkflowZodSchema.Status,
|
|
118
|
+
reports: z5.record(z5.string(), WorkflowZodSchema.NodeReport)
|
|
119
|
+
})
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
var TaskCancelDefine = {
|
|
123
|
+
name: "TaskCancel",
|
|
124
|
+
method: "PUT",
|
|
125
|
+
path: "/task/cancel",
|
|
126
|
+
module: "Task",
|
|
127
|
+
schema: {
|
|
128
|
+
input: z6.object({
|
|
129
|
+
taskID: z6.string()
|
|
130
|
+
}),
|
|
131
|
+
output: z6.object({
|
|
132
|
+
success: z6.boolean()
|
|
133
|
+
})
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
var ServerInfoDefine = {
|
|
137
|
+
name: "ServerInfo",
|
|
138
|
+
method: "GET",
|
|
139
|
+
path: "/info",
|
|
140
|
+
module: "Info",
|
|
141
|
+
schema: {
|
|
142
|
+
input: z7.undefined(),
|
|
143
|
+
output: z7.object({
|
|
144
|
+
name: z7.string(),
|
|
145
|
+
runtime: z7.string(),
|
|
146
|
+
version: z7.string(),
|
|
147
|
+
time: z7.string()
|
|
148
|
+
})
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
var FlowGramAPIs = {
|
|
152
|
+
[
|
|
153
|
+
"ServerInfo"
|
|
154
|
+
/* ServerInfo */
|
|
155
|
+
]: ServerInfoDefine,
|
|
156
|
+
[
|
|
157
|
+
"TaskRun"
|
|
158
|
+
/* TaskRun */
|
|
159
|
+
]: TaskRunDefine,
|
|
160
|
+
[
|
|
161
|
+
"TaskReport"
|
|
162
|
+
/* TaskReport */
|
|
163
|
+
]: TaskReportDefine,
|
|
164
|
+
[
|
|
165
|
+
"TaskResult"
|
|
166
|
+
/* TaskResult */
|
|
167
|
+
]: TaskResultDefine,
|
|
168
|
+
[
|
|
169
|
+
"TaskCancel"
|
|
170
|
+
/* TaskCancel */
|
|
171
|
+
]: TaskCancelDefine,
|
|
172
|
+
[
|
|
173
|
+
"Validation"
|
|
174
|
+
/* Validation */
|
|
175
|
+
]: ValidationDefine
|
|
176
|
+
};
|
|
177
|
+
var FlowGramAPINames = Object.keys(FlowGramAPIs);
|
|
178
|
+
var WorkflowPortType = /* @__PURE__ */ ((WorkflowPortType2) => {
|
|
179
|
+
WorkflowPortType2["Input"] = "input";
|
|
180
|
+
WorkflowPortType2["Output"] = "output";
|
|
181
|
+
return WorkflowPortType2;
|
|
182
|
+
})(WorkflowPortType || {});
|
|
183
|
+
var WorkflowVariableType = /* @__PURE__ */ ((WorkflowVariableType2) => {
|
|
184
|
+
WorkflowVariableType2["String"] = "string";
|
|
185
|
+
WorkflowVariableType2["Integer"] = "integer";
|
|
186
|
+
WorkflowVariableType2["Number"] = "number";
|
|
187
|
+
WorkflowVariableType2["Boolean"] = "boolean";
|
|
188
|
+
WorkflowVariableType2["Object"] = "object";
|
|
189
|
+
WorkflowVariableType2["Array"] = "array";
|
|
190
|
+
WorkflowVariableType2["Null"] = "null";
|
|
191
|
+
return WorkflowVariableType2;
|
|
192
|
+
})(WorkflowVariableType || {});
|
|
193
|
+
var FlowGramNode = /* @__PURE__ */ ((FlowGramNode22) => {
|
|
194
|
+
FlowGramNode22["Root"] = "root";
|
|
195
|
+
FlowGramNode22["Start"] = "start";
|
|
196
|
+
FlowGramNode22["End"] = "end";
|
|
197
|
+
FlowGramNode22["LLM"] = "llm";
|
|
198
|
+
FlowGramNode22["code"] = "code";
|
|
199
|
+
FlowGramNode22["Condition"] = "condition";
|
|
200
|
+
FlowGramNode22["Loop"] = "loop";
|
|
201
|
+
FlowGramNode22["Comment"] = "comment";
|
|
202
|
+
FlowGramNode22["Group"] = "group";
|
|
203
|
+
return FlowGramNode22;
|
|
204
|
+
})(FlowGramNode || {});
|
|
205
|
+
var IEngine = Symbol.for("Engine");
|
|
206
|
+
var IExecutor = Symbol.for("Executor");
|
|
207
|
+
var WorkflowStatus = /* @__PURE__ */ ((WorkflowStatus2) => {
|
|
208
|
+
WorkflowStatus2["Pending"] = "pending";
|
|
209
|
+
WorkflowStatus2["Processing"] = "processing";
|
|
210
|
+
WorkflowStatus2["Succeeded"] = "succeeded";
|
|
211
|
+
WorkflowStatus2["Failed"] = "failed";
|
|
212
|
+
WorkflowStatus2["Canceled"] = "canceled";
|
|
213
|
+
return WorkflowStatus2;
|
|
214
|
+
})(WorkflowStatus || {});
|
|
215
|
+
var IValidation = Symbol.for("Validation");
|
|
216
|
+
|
|
217
|
+
// src/nodes/start/index.ts
|
|
218
|
+
var StartExecutor = class {
|
|
219
|
+
constructor() {
|
|
220
|
+
this.type = FlowGramNode.Start;
|
|
221
|
+
}
|
|
222
|
+
async execute(context) {
|
|
223
|
+
return {
|
|
224
|
+
outputs: context.runtime.ioCenter.inputs
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
// src/nodes/loop/index.ts
|
|
230
|
+
import { isNil } from "lodash-es";
|
|
231
|
+
var LoopExecutor = class {
|
|
232
|
+
constructor() {
|
|
233
|
+
this.type = FlowGramNode.Loop;
|
|
234
|
+
}
|
|
235
|
+
async execute(context) {
|
|
236
|
+
const loopNodeID = context.node.id;
|
|
237
|
+
const loopArrayResult = context.runtime.state.parseRef(context.node.data.batchFor);
|
|
238
|
+
this.checkLoopArray(loopArrayResult);
|
|
239
|
+
const loopArray = loopArrayResult.value;
|
|
240
|
+
const itemsType = loopArrayResult.itemsType;
|
|
241
|
+
const engine = context.container.get(IEngine);
|
|
242
|
+
const subNodes = context.node.children;
|
|
243
|
+
const startSubNodes = subNodes.filter((node) => node.prev.length === 0);
|
|
244
|
+
if (loopArray.length === 0 || startSubNodes.length === 0) {
|
|
245
|
+
return {
|
|
246
|
+
outputs: {}
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
for (let i = 0; i < loopArray.length; i++) {
|
|
250
|
+
const loopItem = loopArray[i];
|
|
251
|
+
const subContext = context.runtime.sub();
|
|
252
|
+
subContext.variableStore.setVariable({
|
|
253
|
+
nodeID: `${loopNodeID}_locals`,
|
|
254
|
+
key: "item",
|
|
255
|
+
type: itemsType,
|
|
256
|
+
value: loopItem
|
|
257
|
+
});
|
|
258
|
+
await Promise.all(
|
|
259
|
+
startSubNodes.map(
|
|
260
|
+
(node) => engine.executeNode({
|
|
261
|
+
context: subContext,
|
|
262
|
+
node
|
|
263
|
+
})
|
|
264
|
+
)
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
return {
|
|
268
|
+
outputs: {}
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
checkLoopArray(loopArrayResult) {
|
|
272
|
+
const loopArray = loopArrayResult?.value;
|
|
273
|
+
if (!loopArray || isNil(loopArray) || !Array.isArray(loopArray)) {
|
|
274
|
+
throw new Error("batchFor is required");
|
|
275
|
+
}
|
|
276
|
+
const loopArrayType = loopArrayResult.type;
|
|
277
|
+
if (loopArrayType !== WorkflowVariableType.Array) {
|
|
278
|
+
throw new Error("batchFor must be an array");
|
|
279
|
+
}
|
|
280
|
+
const loopArrayItemType = loopArrayResult.itemsType;
|
|
281
|
+
if (isNil(loopArrayItemType)) {
|
|
282
|
+
throw new Error("batchFor items must be array items");
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
// src/nodes/llm/index.ts
|
|
288
|
+
import { isNil as isNil2 } from "lodash-es";
|
|
289
|
+
import { ChatOpenAI } from "@langchain/openai";
|
|
290
|
+
import { SystemMessage, HumanMessage } from "@langchain/core/messages";
|
|
291
|
+
var LLMExecutor = class {
|
|
292
|
+
constructor() {
|
|
293
|
+
this.type = FlowGramNode.LLM;
|
|
294
|
+
}
|
|
295
|
+
async execute(context) {
|
|
296
|
+
const inputs = context.inputs;
|
|
297
|
+
this.checkInputs(inputs);
|
|
298
|
+
const { modelName, temperature, apiKey, apiHost, systemPrompt, prompt } = inputs;
|
|
299
|
+
const model = new ChatOpenAI({
|
|
300
|
+
modelName,
|
|
301
|
+
temperature,
|
|
302
|
+
apiKey,
|
|
303
|
+
configuration: {
|
|
304
|
+
baseURL: apiHost
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
const messages = [];
|
|
308
|
+
if (systemPrompt) {
|
|
309
|
+
messages.push(new SystemMessage(systemPrompt));
|
|
310
|
+
}
|
|
311
|
+
messages.push(new HumanMessage(prompt));
|
|
312
|
+
const apiMessage = await model.invoke(messages);
|
|
313
|
+
const result = apiMessage.content;
|
|
314
|
+
return {
|
|
315
|
+
outputs: {
|
|
316
|
+
result
|
|
317
|
+
}
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
checkInputs(inputs) {
|
|
321
|
+
const { modelName, temperature, apiKey, apiHost, prompt } = inputs;
|
|
322
|
+
const missingInputs = [];
|
|
323
|
+
if (isNil2(modelName)) missingInputs.push("modelName");
|
|
324
|
+
if (isNil2(temperature)) missingInputs.push("temperature");
|
|
325
|
+
if (isNil2(apiKey)) missingInputs.push("apiKey");
|
|
326
|
+
if (isNil2(apiHost)) missingInputs.push("apiHost");
|
|
327
|
+
if (isNil2(prompt)) missingInputs.push("prompt");
|
|
328
|
+
if (missingInputs.length > 0) {
|
|
329
|
+
throw new Error(`LLM node missing required inputs: ${missingInputs.join(", ")}`);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
};
|
|
333
|
+
|
|
334
|
+
// src/nodes/end/index.ts
|
|
335
|
+
var EndExecutor = class {
|
|
336
|
+
constructor() {
|
|
337
|
+
this.type = FlowGramNode.End;
|
|
338
|
+
}
|
|
339
|
+
async execute(context) {
|
|
340
|
+
context.runtime.ioCenter.setOutputs(context.inputs);
|
|
341
|
+
return {
|
|
342
|
+
outputs: context.inputs
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
};
|
|
346
|
+
|
|
347
|
+
// src/nodes/condition/index.ts
|
|
348
|
+
import { isNil as isNil9 } from "lodash-es";
|
|
349
|
+
|
|
350
|
+
// src/nodes/condition/rules.ts
|
|
351
|
+
var conditionRules = {
|
|
352
|
+
[WorkflowVariableType.String]: {
|
|
353
|
+
["eq" /* EQ */]: WorkflowVariableType.String,
|
|
354
|
+
["neq" /* NEQ */]: WorkflowVariableType.String,
|
|
355
|
+
["contains" /* CONTAINS */]: WorkflowVariableType.String,
|
|
356
|
+
["not_contains" /* NOT_CONTAINS */]: WorkflowVariableType.String,
|
|
357
|
+
["in" /* IN */]: WorkflowVariableType.Array,
|
|
358
|
+
["nin" /* NIN */]: WorkflowVariableType.Array,
|
|
359
|
+
["is_empty" /* IS_EMPTY */]: WorkflowVariableType.String,
|
|
360
|
+
["is_not_empty" /* IS_NOT_EMPTY */]: WorkflowVariableType.String
|
|
361
|
+
},
|
|
362
|
+
[WorkflowVariableType.Number]: {
|
|
363
|
+
["eq" /* EQ */]: WorkflowVariableType.Number,
|
|
364
|
+
["neq" /* NEQ */]: WorkflowVariableType.Number,
|
|
365
|
+
["gt" /* GT */]: WorkflowVariableType.Number,
|
|
366
|
+
["gte" /* GTE */]: WorkflowVariableType.Number,
|
|
367
|
+
["lt" /* LT */]: WorkflowVariableType.Number,
|
|
368
|
+
["lte" /* LTE */]: WorkflowVariableType.Number,
|
|
369
|
+
["in" /* IN */]: WorkflowVariableType.Array,
|
|
370
|
+
["nin" /* NIN */]: WorkflowVariableType.Array,
|
|
371
|
+
["is_empty" /* IS_EMPTY */]: WorkflowVariableType.Null,
|
|
372
|
+
["is_not_empty" /* IS_NOT_EMPTY */]: WorkflowVariableType.Null
|
|
373
|
+
},
|
|
374
|
+
[WorkflowVariableType.Integer]: {
|
|
375
|
+
["eq" /* EQ */]: WorkflowVariableType.Integer,
|
|
376
|
+
["neq" /* NEQ */]: WorkflowVariableType.Integer,
|
|
377
|
+
["gt" /* GT */]: WorkflowVariableType.Integer,
|
|
378
|
+
["gte" /* GTE */]: WorkflowVariableType.Integer,
|
|
379
|
+
["lt" /* LT */]: WorkflowVariableType.Integer,
|
|
380
|
+
["lte" /* LTE */]: WorkflowVariableType.Integer,
|
|
381
|
+
["in" /* IN */]: WorkflowVariableType.Array,
|
|
382
|
+
["nin" /* NIN */]: WorkflowVariableType.Array,
|
|
383
|
+
["is_empty" /* IS_EMPTY */]: WorkflowVariableType.Null,
|
|
384
|
+
["is_not_empty" /* IS_NOT_EMPTY */]: WorkflowVariableType.Null
|
|
385
|
+
},
|
|
386
|
+
[WorkflowVariableType.Boolean]: {
|
|
387
|
+
["eq" /* EQ */]: WorkflowVariableType.Boolean,
|
|
388
|
+
["neq" /* NEQ */]: WorkflowVariableType.Boolean,
|
|
389
|
+
["is_true" /* IS_TRUE */]: WorkflowVariableType.Null,
|
|
390
|
+
["is_false" /* IS_FALSE */]: WorkflowVariableType.Null,
|
|
391
|
+
["in" /* IN */]: WorkflowVariableType.Array,
|
|
392
|
+
["nin" /* NIN */]: WorkflowVariableType.Array,
|
|
393
|
+
["is_empty" /* IS_EMPTY */]: WorkflowVariableType.Null,
|
|
394
|
+
["is_not_empty" /* IS_NOT_EMPTY */]: WorkflowVariableType.Null
|
|
395
|
+
},
|
|
396
|
+
[WorkflowVariableType.Object]: {
|
|
397
|
+
["is_empty" /* IS_EMPTY */]: WorkflowVariableType.Null,
|
|
398
|
+
["is_not_empty" /* IS_NOT_EMPTY */]: WorkflowVariableType.Null
|
|
399
|
+
},
|
|
400
|
+
[WorkflowVariableType.Array]: {
|
|
401
|
+
["is_empty" /* IS_EMPTY */]: WorkflowVariableType.Null,
|
|
402
|
+
["is_not_empty" /* IS_NOT_EMPTY */]: WorkflowVariableType.Null
|
|
403
|
+
},
|
|
404
|
+
[WorkflowVariableType.Null]: {
|
|
405
|
+
["eq" /* EQ */]: WorkflowVariableType.Null,
|
|
406
|
+
["is_empty" /* IS_EMPTY */]: WorkflowVariableType.Null,
|
|
407
|
+
["is_not_empty" /* IS_NOT_EMPTY */]: WorkflowVariableType.Null
|
|
408
|
+
}
|
|
409
|
+
};
|
|
410
|
+
|
|
411
|
+
// src/nodes/condition/handlers/string.ts
|
|
412
|
+
import { isNil as isNil3 } from "lodash-es";
|
|
413
|
+
var conditionStringHandler = (condition) => {
|
|
414
|
+
const { operator } = condition;
|
|
415
|
+
const leftValue = condition.leftValue;
|
|
416
|
+
if (operator === "eq" /* EQ */) {
|
|
417
|
+
const rightValue = condition.rightValue;
|
|
418
|
+
return leftValue === rightValue;
|
|
419
|
+
}
|
|
420
|
+
if (operator === "neq" /* NEQ */) {
|
|
421
|
+
const rightValue = condition.rightValue;
|
|
422
|
+
return leftValue !== rightValue;
|
|
423
|
+
}
|
|
424
|
+
if (operator === "contains" /* CONTAINS */) {
|
|
425
|
+
const rightValue = condition.rightValue;
|
|
426
|
+
return leftValue.includes(rightValue);
|
|
427
|
+
}
|
|
428
|
+
if (operator === "not_contains" /* NOT_CONTAINS */) {
|
|
429
|
+
const rightValue = condition.rightValue;
|
|
430
|
+
return !leftValue.includes(rightValue);
|
|
431
|
+
}
|
|
432
|
+
if (operator === "in" /* IN */) {
|
|
433
|
+
const rightValue = condition.rightValue;
|
|
434
|
+
return rightValue.includes(leftValue);
|
|
435
|
+
}
|
|
436
|
+
if (operator === "nin" /* NIN */) {
|
|
437
|
+
const rightValue = condition.rightValue;
|
|
438
|
+
return !rightValue.includes(leftValue);
|
|
439
|
+
}
|
|
440
|
+
if (operator === "is_empty" /* IS_EMPTY */) {
|
|
441
|
+
return isNil3(leftValue);
|
|
442
|
+
}
|
|
443
|
+
if (operator === "is_not_empty" /* IS_NOT_EMPTY */) {
|
|
444
|
+
return !isNil3(leftValue);
|
|
445
|
+
}
|
|
446
|
+
return false;
|
|
447
|
+
};
|
|
448
|
+
|
|
449
|
+
// src/nodes/condition/handlers/object.ts
|
|
450
|
+
import { isNil as isNil4 } from "lodash-es";
|
|
451
|
+
var conditionObjectHandler = (condition) => {
|
|
452
|
+
const { operator } = condition;
|
|
453
|
+
const leftValue = condition.leftValue;
|
|
454
|
+
if (operator === "is_empty" /* IS_EMPTY */) {
|
|
455
|
+
return isNil4(leftValue);
|
|
456
|
+
}
|
|
457
|
+
if (operator === "is_not_empty" /* IS_NOT_EMPTY */) {
|
|
458
|
+
return !isNil4(leftValue);
|
|
459
|
+
}
|
|
460
|
+
return false;
|
|
461
|
+
};
|
|
462
|
+
|
|
463
|
+
// src/nodes/condition/handlers/number.ts
|
|
464
|
+
import { isNil as isNil5 } from "lodash-es";
|
|
465
|
+
var conditionNumberHandler = (condition) => {
|
|
466
|
+
const { operator } = condition;
|
|
467
|
+
const leftValue = condition.leftValue;
|
|
468
|
+
if (operator === "eq" /* EQ */) {
|
|
469
|
+
const rightValue = condition.rightValue;
|
|
470
|
+
return leftValue === rightValue;
|
|
471
|
+
}
|
|
472
|
+
if (operator === "neq" /* NEQ */) {
|
|
473
|
+
const rightValue = condition.rightValue;
|
|
474
|
+
return leftValue !== rightValue;
|
|
475
|
+
}
|
|
476
|
+
if (operator === "gt" /* GT */) {
|
|
477
|
+
const rightValue = condition.rightValue;
|
|
478
|
+
return leftValue > rightValue;
|
|
479
|
+
}
|
|
480
|
+
if (operator === "gte" /* GTE */) {
|
|
481
|
+
const rightValue = condition.rightValue;
|
|
482
|
+
return leftValue >= rightValue;
|
|
483
|
+
}
|
|
484
|
+
if (operator === "lt" /* LT */) {
|
|
485
|
+
const rightValue = condition.rightValue;
|
|
486
|
+
return leftValue < rightValue;
|
|
487
|
+
}
|
|
488
|
+
if (operator === "lte" /* LTE */) {
|
|
489
|
+
const rightValue = condition.rightValue;
|
|
490
|
+
return leftValue <= rightValue;
|
|
491
|
+
}
|
|
492
|
+
if (operator === "in" /* IN */) {
|
|
493
|
+
const rightValue = condition.rightValue;
|
|
494
|
+
return rightValue.includes(leftValue);
|
|
495
|
+
}
|
|
496
|
+
if (operator === "nin" /* NIN */) {
|
|
497
|
+
const rightValue = condition.rightValue;
|
|
498
|
+
return !rightValue.includes(leftValue);
|
|
499
|
+
}
|
|
500
|
+
if (operator === "is_empty" /* IS_EMPTY */) {
|
|
501
|
+
return isNil5(leftValue);
|
|
502
|
+
}
|
|
503
|
+
if (operator === "is_not_empty" /* IS_NOT_EMPTY */) {
|
|
504
|
+
return !isNil5(leftValue);
|
|
505
|
+
}
|
|
506
|
+
return false;
|
|
507
|
+
};
|
|
508
|
+
|
|
509
|
+
// src/nodes/condition/handlers/null.ts
|
|
510
|
+
import { isNil as isNil6 } from "lodash-es";
|
|
511
|
+
var conditionNullHandler = (condition) => {
|
|
512
|
+
const { operator } = condition;
|
|
513
|
+
const leftValue = condition.leftValue;
|
|
514
|
+
if (operator === "eq" /* EQ */) {
|
|
515
|
+
return isNil6(leftValue) && isNil6(condition.rightValue);
|
|
516
|
+
}
|
|
517
|
+
if (operator === "is_empty" /* IS_EMPTY */) {
|
|
518
|
+
return isNil6(leftValue);
|
|
519
|
+
}
|
|
520
|
+
if (operator === "is_not_empty" /* IS_NOT_EMPTY */) {
|
|
521
|
+
return !isNil6(leftValue);
|
|
522
|
+
}
|
|
523
|
+
return false;
|
|
524
|
+
};
|
|
525
|
+
|
|
526
|
+
// src/nodes/condition/handlers/boolean.ts
|
|
527
|
+
import { isNil as isNil7 } from "lodash-es";
|
|
528
|
+
var conditionBooleanHandler = (condition) => {
|
|
529
|
+
const { operator } = condition;
|
|
530
|
+
const leftValue = condition.leftValue;
|
|
531
|
+
if (operator === "eq" /* EQ */) {
|
|
532
|
+
const rightValue = condition.rightValue;
|
|
533
|
+
return leftValue === rightValue;
|
|
534
|
+
}
|
|
535
|
+
if (operator === "neq" /* NEQ */) {
|
|
536
|
+
const rightValue = condition.rightValue;
|
|
537
|
+
return leftValue !== rightValue;
|
|
538
|
+
}
|
|
539
|
+
if (operator === "is_true" /* IS_TRUE */) {
|
|
540
|
+
return leftValue === true;
|
|
541
|
+
}
|
|
542
|
+
if (operator === "is_false" /* IS_FALSE */) {
|
|
543
|
+
return leftValue === false;
|
|
544
|
+
}
|
|
545
|
+
if (operator === "in" /* IN */) {
|
|
546
|
+
const rightValue = condition.rightValue;
|
|
547
|
+
return rightValue.includes(leftValue);
|
|
548
|
+
}
|
|
549
|
+
if (operator === "nin" /* NIN */) {
|
|
550
|
+
const rightValue = condition.rightValue;
|
|
551
|
+
return !rightValue.includes(leftValue);
|
|
552
|
+
}
|
|
553
|
+
if (operator === "is_empty" /* IS_EMPTY */) {
|
|
554
|
+
return isNil7(leftValue);
|
|
555
|
+
}
|
|
556
|
+
if (operator === "is_not_empty" /* IS_NOT_EMPTY */) {
|
|
557
|
+
return !isNil7(leftValue);
|
|
558
|
+
}
|
|
559
|
+
return false;
|
|
560
|
+
};
|
|
561
|
+
|
|
562
|
+
// src/nodes/condition/handlers/array.ts
|
|
563
|
+
import { isNil as isNil8 } from "lodash-es";
|
|
564
|
+
var conditionArrayHandler = (condition) => {
|
|
565
|
+
const { operator } = condition;
|
|
566
|
+
const leftValue = condition.leftValue;
|
|
567
|
+
if (operator === "is_empty" /* IS_EMPTY */) {
|
|
568
|
+
return isNil8(leftValue);
|
|
569
|
+
}
|
|
570
|
+
if (operator === "is_not_empty" /* IS_NOT_EMPTY */) {
|
|
571
|
+
return !isNil8(leftValue);
|
|
572
|
+
}
|
|
573
|
+
return false;
|
|
574
|
+
};
|
|
575
|
+
|
|
576
|
+
// src/nodes/condition/handlers/index.ts
|
|
577
|
+
var conditionHandlers = {
|
|
578
|
+
[WorkflowVariableType.String]: conditionStringHandler,
|
|
579
|
+
[WorkflowVariableType.Number]: conditionNumberHandler,
|
|
580
|
+
[WorkflowVariableType.Integer]: conditionNumberHandler,
|
|
581
|
+
[WorkflowVariableType.Boolean]: conditionBooleanHandler,
|
|
582
|
+
[WorkflowVariableType.Object]: conditionObjectHandler,
|
|
583
|
+
[WorkflowVariableType.Array]: conditionArrayHandler,
|
|
584
|
+
[WorkflowVariableType.Null]: conditionNullHandler
|
|
585
|
+
};
|
|
586
|
+
|
|
587
|
+
// src/nodes/condition/index.ts
|
|
588
|
+
var ConditionExecutor = class {
|
|
589
|
+
constructor() {
|
|
590
|
+
this.type = FlowGramNode.Condition;
|
|
591
|
+
}
|
|
592
|
+
async execute(context) {
|
|
593
|
+
const conditions = context.node.data?.conditions;
|
|
594
|
+
if (!conditions) {
|
|
595
|
+
return {
|
|
596
|
+
outputs: {}
|
|
597
|
+
};
|
|
598
|
+
}
|
|
599
|
+
const parsedConditions = conditions.map((item) => this.parseCondition(item, context)).filter((item) => this.checkCondition(item));
|
|
600
|
+
const activatedCondition = parsedConditions.find((item) => this.handleCondition(item));
|
|
601
|
+
if (!activatedCondition) {
|
|
602
|
+
return {
|
|
603
|
+
outputs: {}
|
|
604
|
+
};
|
|
605
|
+
}
|
|
606
|
+
return {
|
|
607
|
+
outputs: {},
|
|
608
|
+
branch: activatedCondition.key
|
|
609
|
+
};
|
|
610
|
+
}
|
|
611
|
+
parseCondition(item, context) {
|
|
612
|
+
const { key, value } = item;
|
|
613
|
+
const { left, operator, right } = value;
|
|
614
|
+
const parsedLeft = context.runtime.state.parseRef(left);
|
|
615
|
+
const leftValue = parsedLeft?.value ?? null;
|
|
616
|
+
const leftType = parsedLeft?.type ?? WorkflowVariableType.Null;
|
|
617
|
+
const parsedRight = Boolean(right) ? context.runtime.state.parseValue(right) : null;
|
|
618
|
+
const rightValue = parsedRight?.value ?? null;
|
|
619
|
+
const rightType = parsedRight?.type ?? WorkflowVariableType.Null;
|
|
620
|
+
return {
|
|
621
|
+
key,
|
|
622
|
+
leftValue,
|
|
623
|
+
leftType,
|
|
624
|
+
rightValue,
|
|
625
|
+
rightType,
|
|
626
|
+
operator
|
|
627
|
+
};
|
|
628
|
+
}
|
|
629
|
+
checkCondition(condition) {
|
|
630
|
+
const rule = conditionRules[condition.leftType];
|
|
631
|
+
if (isNil9(rule)) {
|
|
632
|
+
throw new Error(`condition left type ${condition.leftType} is not supported`);
|
|
633
|
+
}
|
|
634
|
+
const ruleType = rule[condition.operator];
|
|
635
|
+
if (isNil9(ruleType)) {
|
|
636
|
+
throw new Error(`condition operator ${condition.operator} is not supported`);
|
|
637
|
+
}
|
|
638
|
+
if (ruleType !== condition.rightType) {
|
|
639
|
+
return false;
|
|
640
|
+
}
|
|
641
|
+
return true;
|
|
642
|
+
}
|
|
643
|
+
handleCondition(condition) {
|
|
644
|
+
const handler = conditionHandlers[condition.leftType];
|
|
645
|
+
if (!handler) {
|
|
646
|
+
throw new Error(`condition left type ${condition.leftType} is not supported`);
|
|
647
|
+
}
|
|
648
|
+
const isActive = handler(condition);
|
|
649
|
+
return isActive;
|
|
650
|
+
}
|
|
651
|
+
};
|
|
652
|
+
|
|
653
|
+
// src/nodes/index.ts
|
|
654
|
+
var WorkflowRuntimeNodeExecutors = [
|
|
655
|
+
StartExecutor,
|
|
656
|
+
EndExecutor,
|
|
657
|
+
LLMExecutor,
|
|
658
|
+
ConditionExecutor,
|
|
659
|
+
LoopExecutor
|
|
660
|
+
];
|
|
661
|
+
|
|
662
|
+
// src/domain/validation/index.ts
|
|
663
|
+
var WorkflowRuntimeValidation = class {
|
|
664
|
+
validate(schema) {
|
|
665
|
+
return {
|
|
666
|
+
valid: true
|
|
667
|
+
};
|
|
668
|
+
}
|
|
669
|
+
};
|
|
670
|
+
|
|
671
|
+
// src/domain/executor/index.ts
|
|
672
|
+
var WorkflowRuntimeExecutor = class {
|
|
673
|
+
constructor(nodeExecutors) {
|
|
674
|
+
this.nodeExecutors = /* @__PURE__ */ new Map();
|
|
675
|
+
nodeExecutors.forEach((executor) => {
|
|
676
|
+
this.register(new executor());
|
|
677
|
+
});
|
|
678
|
+
}
|
|
679
|
+
register(executor) {
|
|
680
|
+
this.nodeExecutors.set(executor.type, executor);
|
|
681
|
+
}
|
|
682
|
+
async execute(context) {
|
|
683
|
+
const nodeType = context.node.type;
|
|
684
|
+
const nodeExecutor = this.nodeExecutors.get(nodeType);
|
|
685
|
+
if (!nodeExecutor) {
|
|
686
|
+
throw new Error(`no executor found for node type ${nodeType}`);
|
|
687
|
+
}
|
|
688
|
+
const output = await nodeExecutor.execute(context);
|
|
689
|
+
return output;
|
|
690
|
+
}
|
|
691
|
+
};
|
|
692
|
+
|
|
693
|
+
// src/infrastructure/utils/uuid.ts
|
|
694
|
+
import { v4 } from "uuid";
|
|
695
|
+
var uuid = v4;
|
|
696
|
+
|
|
697
|
+
// src/infrastructure/utils/runtime-type.ts
|
|
698
|
+
var WorkflowRuntimeType;
|
|
699
|
+
((WorkflowRuntimeType2) => {
|
|
700
|
+
WorkflowRuntimeType2.getWorkflowType = (value) => {
|
|
701
|
+
if (value === null || value === void 0) {
|
|
702
|
+
return WorkflowVariableType.Null;
|
|
703
|
+
}
|
|
704
|
+
if (typeof value === "string") {
|
|
705
|
+
return WorkflowVariableType.String;
|
|
706
|
+
}
|
|
707
|
+
if (typeof value === "boolean") {
|
|
708
|
+
return WorkflowVariableType.Boolean;
|
|
709
|
+
}
|
|
710
|
+
if (typeof value === "number") {
|
|
711
|
+
if (Number.isInteger(value)) {
|
|
712
|
+
return WorkflowVariableType.Integer;
|
|
713
|
+
}
|
|
714
|
+
return WorkflowVariableType.Number;
|
|
715
|
+
}
|
|
716
|
+
if (Array.isArray(value)) {
|
|
717
|
+
return WorkflowVariableType.Array;
|
|
718
|
+
}
|
|
719
|
+
if (typeof value === "object") {
|
|
720
|
+
return WorkflowVariableType.Object;
|
|
721
|
+
}
|
|
722
|
+
return null;
|
|
723
|
+
};
|
|
724
|
+
WorkflowRuntimeType2.isMatchWorkflowType = (value, type) => {
|
|
725
|
+
const workflowType = (0, WorkflowRuntimeType2.getWorkflowType)(value);
|
|
726
|
+
if (!workflowType) {
|
|
727
|
+
return false;
|
|
728
|
+
}
|
|
729
|
+
return workflowType === type;
|
|
730
|
+
};
|
|
731
|
+
WorkflowRuntimeType2.isTypeEqual = (leftType, rightType) => {
|
|
732
|
+
if (leftType === WorkflowVariableType.Number && rightType === WorkflowVariableType.Integer || leftType === WorkflowVariableType.Integer && rightType === WorkflowVariableType.Number) {
|
|
733
|
+
return true;
|
|
734
|
+
}
|
|
735
|
+
return leftType === rightType;
|
|
736
|
+
};
|
|
737
|
+
})(WorkflowRuntimeType || (WorkflowRuntimeType = {}));
|
|
738
|
+
|
|
739
|
+
// src/domain/task/index.ts
|
|
740
|
+
var WorkflowRuntimeTask = class _WorkflowRuntimeTask {
|
|
741
|
+
constructor(params) {
|
|
742
|
+
this.id = uuid();
|
|
743
|
+
this.context = params.context;
|
|
744
|
+
this.processing = params.processing;
|
|
745
|
+
}
|
|
746
|
+
cancel() {
|
|
747
|
+
this.context.statusCenter.workflow.cancel();
|
|
748
|
+
const cancelNodeIDs = this.context.statusCenter.getStatusNodeIDs(WorkflowStatus.Processing);
|
|
749
|
+
cancelNodeIDs.forEach((nodeID) => {
|
|
750
|
+
this.context.statusCenter.nodeStatus(nodeID).cancel();
|
|
751
|
+
});
|
|
752
|
+
}
|
|
753
|
+
static create(params) {
|
|
754
|
+
return new _WorkflowRuntimeTask(params);
|
|
755
|
+
}
|
|
756
|
+
};
|
|
757
|
+
|
|
758
|
+
// src/domain/variable/variable-store/index.ts
|
|
759
|
+
import { get, set } from "lodash-es";
|
|
760
|
+
|
|
761
|
+
// src/domain/variable/variable-value-object/index.ts
|
|
762
|
+
var WorkflowRuntimeVariable;
|
|
763
|
+
((WorkflowRuntimeVariable2) => {
|
|
764
|
+
WorkflowRuntimeVariable2.create = (params) => ({
|
|
765
|
+
id: uuid(),
|
|
766
|
+
...params
|
|
767
|
+
});
|
|
768
|
+
})(WorkflowRuntimeVariable || (WorkflowRuntimeVariable = {}));
|
|
769
|
+
|
|
770
|
+
// src/domain/variable/variable-store/index.ts
|
|
771
|
+
var WorkflowRuntimeVariableStore = class {
|
|
772
|
+
constructor() {
|
|
773
|
+
this.id = uuid();
|
|
774
|
+
}
|
|
775
|
+
init() {
|
|
776
|
+
this.store = /* @__PURE__ */ new Map();
|
|
777
|
+
}
|
|
778
|
+
dispose() {
|
|
779
|
+
this.store.clear();
|
|
780
|
+
}
|
|
781
|
+
setParent(parent) {
|
|
782
|
+
this.parent = parent;
|
|
783
|
+
}
|
|
784
|
+
globalGet(nodeID) {
|
|
785
|
+
const store = this.store.get(nodeID);
|
|
786
|
+
if (!store && this.parent) {
|
|
787
|
+
return this.parent.globalGet(nodeID);
|
|
788
|
+
}
|
|
789
|
+
return store;
|
|
790
|
+
}
|
|
791
|
+
setVariable(params) {
|
|
792
|
+
const { nodeID, key, value, type, itemsType } = params;
|
|
793
|
+
if (!this.store.has(nodeID)) {
|
|
794
|
+
this.store.set(nodeID, /* @__PURE__ */ new Map());
|
|
795
|
+
}
|
|
796
|
+
const nodeStore = this.store.get(nodeID);
|
|
797
|
+
const variable = WorkflowRuntimeVariable.create({
|
|
798
|
+
nodeID,
|
|
799
|
+
key,
|
|
800
|
+
value,
|
|
801
|
+
type,
|
|
802
|
+
// TODO check type
|
|
803
|
+
itemsType
|
|
804
|
+
// TODO check is array
|
|
805
|
+
});
|
|
806
|
+
nodeStore.set(key, variable);
|
|
807
|
+
}
|
|
808
|
+
setValue(params) {
|
|
809
|
+
const { nodeID, variableKey, variablePath, value } = params;
|
|
810
|
+
if (!this.store.has(nodeID)) {
|
|
811
|
+
this.store.set(nodeID, /* @__PURE__ */ new Map());
|
|
812
|
+
}
|
|
813
|
+
const nodeStore = this.store.get(nodeID);
|
|
814
|
+
if (!nodeStore.has(variableKey)) {
|
|
815
|
+
const variable2 = WorkflowRuntimeVariable.create({
|
|
816
|
+
nodeID,
|
|
817
|
+
key: variableKey,
|
|
818
|
+
value: {},
|
|
819
|
+
type: WorkflowVariableType.Object
|
|
820
|
+
});
|
|
821
|
+
nodeStore.set(variableKey, variable2);
|
|
822
|
+
}
|
|
823
|
+
const variable = nodeStore.get(variableKey);
|
|
824
|
+
if (!variablePath) {
|
|
825
|
+
variable.value = value;
|
|
826
|
+
return;
|
|
827
|
+
}
|
|
828
|
+
set(variable.value, variablePath, value);
|
|
829
|
+
}
|
|
830
|
+
getValue(params) {
|
|
831
|
+
const { nodeID, variableKey, variablePath } = params;
|
|
832
|
+
const variable = this.globalGet(nodeID)?.get(variableKey);
|
|
833
|
+
if (!variable) {
|
|
834
|
+
return null;
|
|
835
|
+
}
|
|
836
|
+
if (!variablePath || variablePath.length === 0) {
|
|
837
|
+
return {
|
|
838
|
+
value: variable.value,
|
|
839
|
+
type: variable.type,
|
|
840
|
+
itemsType: variable.itemsType
|
|
841
|
+
};
|
|
842
|
+
}
|
|
843
|
+
const value = get(variable.value, variablePath);
|
|
844
|
+
const type = WorkflowRuntimeType.getWorkflowType(value);
|
|
845
|
+
if (!type) {
|
|
846
|
+
return null;
|
|
847
|
+
}
|
|
848
|
+
if (type === WorkflowVariableType.Array && Array.isArray(value)) {
|
|
849
|
+
const itemsType = WorkflowRuntimeType.getWorkflowType(value[0]);
|
|
850
|
+
if (!itemsType) {
|
|
851
|
+
return null;
|
|
852
|
+
}
|
|
853
|
+
return {
|
|
854
|
+
value,
|
|
855
|
+
type,
|
|
856
|
+
itemsType
|
|
857
|
+
};
|
|
858
|
+
}
|
|
859
|
+
return {
|
|
860
|
+
value,
|
|
861
|
+
type
|
|
862
|
+
};
|
|
863
|
+
}
|
|
864
|
+
};
|
|
865
|
+
|
|
866
|
+
// src/domain/status/status-entity/index.ts
|
|
867
|
+
var WorkflowRuntimeStatus = class _WorkflowRuntimeStatus {
|
|
868
|
+
constructor() {
|
|
869
|
+
this.id = uuid();
|
|
870
|
+
this._status = WorkflowStatus.Pending;
|
|
871
|
+
}
|
|
872
|
+
get status() {
|
|
873
|
+
return this._status;
|
|
874
|
+
}
|
|
875
|
+
get terminated() {
|
|
876
|
+
return [WorkflowStatus.Succeeded, WorkflowStatus.Failed, WorkflowStatus.Canceled].includes(
|
|
877
|
+
this.status
|
|
878
|
+
);
|
|
879
|
+
}
|
|
880
|
+
get startTime() {
|
|
881
|
+
return this._startTime;
|
|
882
|
+
}
|
|
883
|
+
get endTime() {
|
|
884
|
+
return this._endTime;
|
|
885
|
+
}
|
|
886
|
+
get timeCost() {
|
|
887
|
+
if (!this.startTime) {
|
|
888
|
+
return 0;
|
|
889
|
+
}
|
|
890
|
+
if (this.endTime) {
|
|
891
|
+
return this.endTime - this.startTime;
|
|
892
|
+
}
|
|
893
|
+
return Date.now() - this.startTime;
|
|
894
|
+
}
|
|
895
|
+
process() {
|
|
896
|
+
this._status = WorkflowStatus.Processing;
|
|
897
|
+
this._startTime = Date.now();
|
|
898
|
+
this._endTime = void 0;
|
|
899
|
+
}
|
|
900
|
+
success() {
|
|
901
|
+
if (this.terminated) {
|
|
902
|
+
return;
|
|
903
|
+
}
|
|
904
|
+
this._status = WorkflowStatus.Succeeded;
|
|
905
|
+
this._endTime = Date.now();
|
|
906
|
+
}
|
|
907
|
+
fail() {
|
|
908
|
+
if (this.terminated) {
|
|
909
|
+
return;
|
|
910
|
+
}
|
|
911
|
+
this._status = WorkflowStatus.Failed;
|
|
912
|
+
this._endTime = Date.now();
|
|
913
|
+
}
|
|
914
|
+
cancel() {
|
|
915
|
+
if (this.terminated) {
|
|
916
|
+
return;
|
|
917
|
+
}
|
|
918
|
+
this._status = WorkflowStatus.Canceled;
|
|
919
|
+
this._endTime = Date.now();
|
|
920
|
+
}
|
|
921
|
+
export() {
|
|
922
|
+
return {
|
|
923
|
+
status: this.status,
|
|
924
|
+
terminated: this.terminated,
|
|
925
|
+
startTime: this.startTime,
|
|
926
|
+
endTime: this.endTime,
|
|
927
|
+
timeCost: this.timeCost
|
|
928
|
+
};
|
|
929
|
+
}
|
|
930
|
+
static create() {
|
|
931
|
+
const status = new _WorkflowRuntimeStatus();
|
|
932
|
+
return status;
|
|
933
|
+
}
|
|
934
|
+
};
|
|
935
|
+
|
|
936
|
+
// src/domain/status/status-center/index.ts
|
|
937
|
+
var WorkflowRuntimeStatusCenter = class {
|
|
938
|
+
init() {
|
|
939
|
+
this._workflowStatus = WorkflowRuntimeStatus.create();
|
|
940
|
+
this._nodeStatus = /* @__PURE__ */ new Map();
|
|
941
|
+
}
|
|
942
|
+
dispose() {
|
|
943
|
+
}
|
|
944
|
+
get workflow() {
|
|
945
|
+
return this._workflowStatus;
|
|
946
|
+
}
|
|
947
|
+
get workflowStatus() {
|
|
948
|
+
return this._workflowStatus;
|
|
949
|
+
}
|
|
950
|
+
nodeStatus(nodeID) {
|
|
951
|
+
if (!this._nodeStatus.has(nodeID)) {
|
|
952
|
+
this._nodeStatus.set(nodeID, WorkflowRuntimeStatus.create());
|
|
953
|
+
}
|
|
954
|
+
const status = this._nodeStatus.get(nodeID);
|
|
955
|
+
return status;
|
|
956
|
+
}
|
|
957
|
+
getStatusNodeIDs(status) {
|
|
958
|
+
return Array.from(this._nodeStatus.entries()).filter(([, nodeStatus]) => nodeStatus.status === status).map(([nodeID]) => nodeID);
|
|
959
|
+
}
|
|
960
|
+
exportNodeStatus() {
|
|
961
|
+
return Object.fromEntries(
|
|
962
|
+
Array.from(this._nodeStatus.entries()).map(([nodeID, status]) => [nodeID, status.export()])
|
|
963
|
+
);
|
|
964
|
+
}
|
|
965
|
+
};
|
|
966
|
+
|
|
967
|
+
// src/domain/state/index.ts
|
|
968
|
+
import { isNil as isNil10 } from "lodash-es";
|
|
969
|
+
var WorkflowRuntimeState = class {
|
|
970
|
+
constructor(variableStore) {
|
|
971
|
+
this.variableStore = variableStore;
|
|
972
|
+
this.id = uuid();
|
|
973
|
+
}
|
|
974
|
+
init() {
|
|
975
|
+
this.executedNodes = /* @__PURE__ */ new Set();
|
|
976
|
+
}
|
|
977
|
+
dispose() {
|
|
978
|
+
this.executedNodes.clear();
|
|
979
|
+
}
|
|
980
|
+
getNodeInputs(node) {
|
|
981
|
+
const inputsDeclare = node.declare.inputs;
|
|
982
|
+
const inputsValues = node.declare.inputsValues;
|
|
983
|
+
if (!inputsDeclare || !inputsValues) {
|
|
984
|
+
return {};
|
|
985
|
+
}
|
|
986
|
+
return Object.entries(inputsValues).reduce((prev, [key, inputValue]) => {
|
|
987
|
+
const typeInfo = inputsDeclare.properties?.[key];
|
|
988
|
+
if (!typeInfo) {
|
|
989
|
+
return prev;
|
|
990
|
+
}
|
|
991
|
+
const expectType = typeInfo.type;
|
|
992
|
+
const result = this.parseValue(inputValue);
|
|
993
|
+
if (!result) {
|
|
994
|
+
return prev;
|
|
995
|
+
}
|
|
996
|
+
const { value, type } = result;
|
|
997
|
+
if (!WorkflowRuntimeType.isTypeEqual(type, expectType)) {
|
|
998
|
+
return prev;
|
|
999
|
+
}
|
|
1000
|
+
prev[key] = value;
|
|
1001
|
+
return prev;
|
|
1002
|
+
}, {});
|
|
1003
|
+
}
|
|
1004
|
+
setNodeOutputs(params) {
|
|
1005
|
+
const { node, outputs } = params;
|
|
1006
|
+
const outputsDeclare = node.declare.outputs;
|
|
1007
|
+
if (!outputsDeclare) {
|
|
1008
|
+
return;
|
|
1009
|
+
}
|
|
1010
|
+
Object.entries(outputs).forEach(([key, value]) => {
|
|
1011
|
+
const typeInfo = outputsDeclare.properties?.[key];
|
|
1012
|
+
if (!typeInfo) {
|
|
1013
|
+
return;
|
|
1014
|
+
}
|
|
1015
|
+
const type = typeInfo.type;
|
|
1016
|
+
const itemsType = typeInfo.items?.type;
|
|
1017
|
+
this.variableStore.setVariable({
|
|
1018
|
+
nodeID: node.id,
|
|
1019
|
+
key,
|
|
1020
|
+
value,
|
|
1021
|
+
type,
|
|
1022
|
+
itemsType
|
|
1023
|
+
});
|
|
1024
|
+
});
|
|
1025
|
+
}
|
|
1026
|
+
parseRef(ref) {
|
|
1027
|
+
if (ref?.type !== "ref") {
|
|
1028
|
+
throw new Error(`invalid ref value: ${ref}`);
|
|
1029
|
+
}
|
|
1030
|
+
if (!ref.content || ref.content.length < 2) {
|
|
1031
|
+
return null;
|
|
1032
|
+
}
|
|
1033
|
+
const [nodeID, variableKey, ...variablePath] = ref.content;
|
|
1034
|
+
const result = this.variableStore.getValue({
|
|
1035
|
+
nodeID,
|
|
1036
|
+
variableKey,
|
|
1037
|
+
variablePath
|
|
1038
|
+
});
|
|
1039
|
+
if (!result) {
|
|
1040
|
+
return null;
|
|
1041
|
+
}
|
|
1042
|
+
return result;
|
|
1043
|
+
}
|
|
1044
|
+
parseValue(flowValue) {
|
|
1045
|
+
if (!flowValue?.type) {
|
|
1046
|
+
throw new Error(`invalid flow value type: ${flowValue.type}`);
|
|
1047
|
+
}
|
|
1048
|
+
if (flowValue.type === "constant") {
|
|
1049
|
+
const value = flowValue.content;
|
|
1050
|
+
const type = WorkflowRuntimeType.getWorkflowType(value);
|
|
1051
|
+
if (isNil10(value) || !type) {
|
|
1052
|
+
return null;
|
|
1053
|
+
}
|
|
1054
|
+
return {
|
|
1055
|
+
value,
|
|
1056
|
+
type
|
|
1057
|
+
};
|
|
1058
|
+
}
|
|
1059
|
+
if (flowValue.type === "ref") {
|
|
1060
|
+
return this.parseRef(flowValue);
|
|
1061
|
+
}
|
|
1062
|
+
throw new Error(`unknown flow value type: ${flowValue.type}`);
|
|
1063
|
+
}
|
|
1064
|
+
isExecutedNode(node) {
|
|
1065
|
+
return this.executedNodes.has(node.id);
|
|
1066
|
+
}
|
|
1067
|
+
addExecutedNode(node) {
|
|
1068
|
+
this.executedNodes.add(node.id);
|
|
1069
|
+
}
|
|
1070
|
+
};
|
|
1071
|
+
|
|
1072
|
+
// src/domain/snapshot/snapshot-entity/index.ts
|
|
1073
|
+
var WorkflowRuntimeSnapshot = class _WorkflowRuntimeSnapshot {
|
|
1074
|
+
constructor(data) {
|
|
1075
|
+
this.id = uuid();
|
|
1076
|
+
this.data = data;
|
|
1077
|
+
}
|
|
1078
|
+
addData(data) {
|
|
1079
|
+
Object.assign(this.data, data);
|
|
1080
|
+
}
|
|
1081
|
+
validate() {
|
|
1082
|
+
const required = ["nodeID", "inputs", "outputs", "data"];
|
|
1083
|
+
return required.every((key) => this.data[key] !== void 0);
|
|
1084
|
+
}
|
|
1085
|
+
export() {
|
|
1086
|
+
const snapshot = {
|
|
1087
|
+
id: this.id,
|
|
1088
|
+
...this.data
|
|
1089
|
+
};
|
|
1090
|
+
return snapshot;
|
|
1091
|
+
}
|
|
1092
|
+
static create(params) {
|
|
1093
|
+
return new _WorkflowRuntimeSnapshot(params);
|
|
1094
|
+
}
|
|
1095
|
+
};
|
|
1096
|
+
|
|
1097
|
+
// src/domain/snapshot/snapshot-center/index.ts
|
|
1098
|
+
var WorkflowRuntimeSnapshotCenter = class {
|
|
1099
|
+
constructor() {
|
|
1100
|
+
this.id = uuid();
|
|
1101
|
+
}
|
|
1102
|
+
create(snapshotData) {
|
|
1103
|
+
const snapshot = WorkflowRuntimeSnapshot.create(snapshotData);
|
|
1104
|
+
this.snapshots.push(snapshot);
|
|
1105
|
+
return snapshot;
|
|
1106
|
+
}
|
|
1107
|
+
init() {
|
|
1108
|
+
this.snapshots = [];
|
|
1109
|
+
}
|
|
1110
|
+
dispose() {
|
|
1111
|
+
}
|
|
1112
|
+
exportAll() {
|
|
1113
|
+
return this.snapshots.slice().map((snapshot) => snapshot.export());
|
|
1114
|
+
}
|
|
1115
|
+
export() {
|
|
1116
|
+
const result = {};
|
|
1117
|
+
this.exportAll().forEach((snapshot) => {
|
|
1118
|
+
if (result[snapshot.nodeID]) {
|
|
1119
|
+
result[snapshot.nodeID].push(snapshot);
|
|
1120
|
+
} else {
|
|
1121
|
+
result[snapshot.nodeID] = [snapshot];
|
|
1122
|
+
}
|
|
1123
|
+
});
|
|
1124
|
+
return result;
|
|
1125
|
+
}
|
|
1126
|
+
};
|
|
1127
|
+
|
|
1128
|
+
// src/domain/report/report-value-object/index.ts
|
|
1129
|
+
var WorkflowRuntimeReport;
|
|
1130
|
+
((WorkflowRuntimeReport2) => {
|
|
1131
|
+
WorkflowRuntimeReport2.create = (params) => ({
|
|
1132
|
+
id: uuid(),
|
|
1133
|
+
...params
|
|
1134
|
+
});
|
|
1135
|
+
})(WorkflowRuntimeReport || (WorkflowRuntimeReport = {}));
|
|
1136
|
+
|
|
1137
|
+
// src/domain/report/reporter/index.ts
|
|
1138
|
+
var WorkflowRuntimeReporter = class {
|
|
1139
|
+
constructor(ioCenter, snapshotCenter, statusCenter) {
|
|
1140
|
+
this.ioCenter = ioCenter;
|
|
1141
|
+
this.snapshotCenter = snapshotCenter;
|
|
1142
|
+
this.statusCenter = statusCenter;
|
|
1143
|
+
}
|
|
1144
|
+
init() {
|
|
1145
|
+
}
|
|
1146
|
+
dispose() {
|
|
1147
|
+
}
|
|
1148
|
+
export() {
|
|
1149
|
+
const report = WorkflowRuntimeReport.create({
|
|
1150
|
+
inputs: this.ioCenter.inputs,
|
|
1151
|
+
outputs: this.ioCenter.outputs,
|
|
1152
|
+
workflowStatus: this.statusCenter.workflow.export(),
|
|
1153
|
+
reports: this.nodeReports()
|
|
1154
|
+
});
|
|
1155
|
+
return report;
|
|
1156
|
+
}
|
|
1157
|
+
nodeReports() {
|
|
1158
|
+
const reports = {};
|
|
1159
|
+
const statuses = this.statusCenter.exportNodeStatus();
|
|
1160
|
+
const snapshots = this.snapshotCenter.export();
|
|
1161
|
+
Object.keys(statuses).forEach((nodeID) => {
|
|
1162
|
+
const status = statuses[nodeID];
|
|
1163
|
+
const nodeSnapshots = snapshots[nodeID] || [];
|
|
1164
|
+
const nodeReport = {
|
|
1165
|
+
id: nodeID,
|
|
1166
|
+
...status,
|
|
1167
|
+
snapshots: nodeSnapshots
|
|
1168
|
+
};
|
|
1169
|
+
reports[nodeID] = nodeReport;
|
|
1170
|
+
});
|
|
1171
|
+
return reports;
|
|
1172
|
+
}
|
|
1173
|
+
};
|
|
1174
|
+
|
|
1175
|
+
// src/domain/io-center/index.ts
|
|
1176
|
+
var WorkflowRuntimeIOCenter = class {
|
|
1177
|
+
init(inputs) {
|
|
1178
|
+
this.setInputs(inputs);
|
|
1179
|
+
}
|
|
1180
|
+
dispose() {
|
|
1181
|
+
}
|
|
1182
|
+
get inputs() {
|
|
1183
|
+
return this._inputs ?? {};
|
|
1184
|
+
}
|
|
1185
|
+
get outputs() {
|
|
1186
|
+
return this._outputs ?? {};
|
|
1187
|
+
}
|
|
1188
|
+
setInputs(inputs) {
|
|
1189
|
+
this._inputs = inputs;
|
|
1190
|
+
}
|
|
1191
|
+
setOutputs(outputs) {
|
|
1192
|
+
this._outputs = outputs;
|
|
1193
|
+
}
|
|
1194
|
+
export() {
|
|
1195
|
+
return {
|
|
1196
|
+
inputs: this._inputs,
|
|
1197
|
+
outputs: this._outputs
|
|
1198
|
+
};
|
|
1199
|
+
}
|
|
1200
|
+
};
|
|
1201
|
+
|
|
1202
|
+
// src/domain/document/entity/edge/index.ts
|
|
1203
|
+
var WorkflowRuntimeEdge = class {
|
|
1204
|
+
constructor(params) {
|
|
1205
|
+
const { id, from, to } = params;
|
|
1206
|
+
this.id = id;
|
|
1207
|
+
this.from = from;
|
|
1208
|
+
this.to = to;
|
|
1209
|
+
}
|
|
1210
|
+
get fromPort() {
|
|
1211
|
+
return this._fromPort;
|
|
1212
|
+
}
|
|
1213
|
+
set fromPort(port) {
|
|
1214
|
+
this._fromPort = port;
|
|
1215
|
+
}
|
|
1216
|
+
get toPort() {
|
|
1217
|
+
return this._toPort;
|
|
1218
|
+
}
|
|
1219
|
+
set toPort(port) {
|
|
1220
|
+
this._toPort = port;
|
|
1221
|
+
}
|
|
1222
|
+
static createID(schema) {
|
|
1223
|
+
const { sourceNodeID, sourcePortID, targetNodeID, targetPortID } = schema;
|
|
1224
|
+
const sourcePart = sourcePortID ? `${sourceNodeID}:${sourcePortID}` : sourceNodeID;
|
|
1225
|
+
const targetPart = targetPortID ? `${targetNodeID}:${targetPortID}` : targetNodeID;
|
|
1226
|
+
return `${sourcePart}-${targetPart}`;
|
|
1227
|
+
}
|
|
1228
|
+
};
|
|
1229
|
+
|
|
1230
|
+
// src/domain/document/entity/node/index.ts
|
|
1231
|
+
var WorkflowRuntimeNode = class {
|
|
1232
|
+
constructor(params) {
|
|
1233
|
+
const { id, type, name, position, variable, data } = params;
|
|
1234
|
+
this.id = id;
|
|
1235
|
+
this.type = type;
|
|
1236
|
+
this.name = name;
|
|
1237
|
+
this.position = position;
|
|
1238
|
+
this.declare = variable ?? {};
|
|
1239
|
+
this.data = data ?? {};
|
|
1240
|
+
this._parent = null;
|
|
1241
|
+
this._children = [];
|
|
1242
|
+
this._ports = [];
|
|
1243
|
+
this._inputEdges = [];
|
|
1244
|
+
this._outputEdges = [];
|
|
1245
|
+
this._prev = [];
|
|
1246
|
+
this._next = [];
|
|
1247
|
+
}
|
|
1248
|
+
get ports() {
|
|
1249
|
+
const inputs = this._ports.filter((port) => port.type === WorkflowPortType.Input);
|
|
1250
|
+
const outputs = this._ports.filter((port) => port.type === WorkflowPortType.Output);
|
|
1251
|
+
return {
|
|
1252
|
+
inputs,
|
|
1253
|
+
outputs
|
|
1254
|
+
};
|
|
1255
|
+
}
|
|
1256
|
+
get edges() {
|
|
1257
|
+
return {
|
|
1258
|
+
inputs: this._inputEdges,
|
|
1259
|
+
outputs: this._outputEdges
|
|
1260
|
+
};
|
|
1261
|
+
}
|
|
1262
|
+
get parent() {
|
|
1263
|
+
return this._parent;
|
|
1264
|
+
}
|
|
1265
|
+
set parent(parent) {
|
|
1266
|
+
this._parent = parent;
|
|
1267
|
+
}
|
|
1268
|
+
get children() {
|
|
1269
|
+
return this._children;
|
|
1270
|
+
}
|
|
1271
|
+
addChild(child) {
|
|
1272
|
+
this._children.push(child);
|
|
1273
|
+
}
|
|
1274
|
+
addPort(port) {
|
|
1275
|
+
this._ports.push(port);
|
|
1276
|
+
}
|
|
1277
|
+
addInputEdge(edge) {
|
|
1278
|
+
this._inputEdges.push(edge);
|
|
1279
|
+
this._prev.push(edge.from);
|
|
1280
|
+
}
|
|
1281
|
+
addOutputEdge(edge) {
|
|
1282
|
+
this._outputEdges.push(edge);
|
|
1283
|
+
this._next.push(edge.to);
|
|
1284
|
+
}
|
|
1285
|
+
get prev() {
|
|
1286
|
+
return this._prev;
|
|
1287
|
+
}
|
|
1288
|
+
get next() {
|
|
1289
|
+
return this._next;
|
|
1290
|
+
}
|
|
1291
|
+
get isBranch() {
|
|
1292
|
+
return this.ports.outputs.length > 1;
|
|
1293
|
+
}
|
|
1294
|
+
};
|
|
1295
|
+
|
|
1296
|
+
// src/domain/document/entity/port/index.ts
|
|
1297
|
+
var WorkflowRuntimePort = class {
|
|
1298
|
+
constructor(params) {
|
|
1299
|
+
const { id, node } = params;
|
|
1300
|
+
this.id = id;
|
|
1301
|
+
this.node = node;
|
|
1302
|
+
this.type = params.type;
|
|
1303
|
+
this._edges = [];
|
|
1304
|
+
}
|
|
1305
|
+
get edges() {
|
|
1306
|
+
return this._edges;
|
|
1307
|
+
}
|
|
1308
|
+
addEdge(edge) {
|
|
1309
|
+
this._edges.push(edge);
|
|
1310
|
+
}
|
|
1311
|
+
};
|
|
1312
|
+
|
|
1313
|
+
// src/domain/document/document/flat-schema.ts
|
|
1314
|
+
var flatLayer = (data, nodeSchema) => {
|
|
1315
|
+
const { blocks, edges } = nodeSchema;
|
|
1316
|
+
if (blocks) {
|
|
1317
|
+
data.flattenSchema.nodes.push(...blocks);
|
|
1318
|
+
const blockIDs = [];
|
|
1319
|
+
blocks.forEach((block) => {
|
|
1320
|
+
blockIDs.push(block.id);
|
|
1321
|
+
if (block.blocks) {
|
|
1322
|
+
flatLayer(data, block);
|
|
1323
|
+
}
|
|
1324
|
+
});
|
|
1325
|
+
data.nodeBlocks.set(nodeSchema.id, blockIDs);
|
|
1326
|
+
delete nodeSchema.blocks;
|
|
1327
|
+
}
|
|
1328
|
+
if (edges) {
|
|
1329
|
+
data.flattenSchema.edges.push(...edges);
|
|
1330
|
+
const edgeIDs = [];
|
|
1331
|
+
edges.forEach((edge) => {
|
|
1332
|
+
const edgeID = WorkflowRuntimeEdge.createID(edge);
|
|
1333
|
+
edgeIDs.push(edgeID);
|
|
1334
|
+
});
|
|
1335
|
+
data.nodeEdges.set(nodeSchema.id, edgeIDs);
|
|
1336
|
+
delete nodeSchema.edges;
|
|
1337
|
+
}
|
|
1338
|
+
};
|
|
1339
|
+
var flatSchema = (schema = { nodes: [], edges: [] }) => {
|
|
1340
|
+
const rootNodes = schema.nodes ?? [];
|
|
1341
|
+
const rootEdges = schema.edges ?? [];
|
|
1342
|
+
const data = {
|
|
1343
|
+
flattenSchema: {
|
|
1344
|
+
nodes: [],
|
|
1345
|
+
edges: []
|
|
1346
|
+
},
|
|
1347
|
+
nodeBlocks: /* @__PURE__ */ new Map(),
|
|
1348
|
+
nodeEdges: /* @__PURE__ */ new Map()
|
|
1349
|
+
};
|
|
1350
|
+
const root = {
|
|
1351
|
+
id: FlowGramNode.Root,
|
|
1352
|
+
type: FlowGramNode.Root,
|
|
1353
|
+
blocks: rootNodes,
|
|
1354
|
+
edges: rootEdges,
|
|
1355
|
+
meta: {
|
|
1356
|
+
position: {
|
|
1357
|
+
x: 0,
|
|
1358
|
+
y: 0
|
|
1359
|
+
}
|
|
1360
|
+
},
|
|
1361
|
+
data: {}
|
|
1362
|
+
};
|
|
1363
|
+
flatLayer(data, root);
|
|
1364
|
+
return data;
|
|
1365
|
+
};
|
|
1366
|
+
|
|
1367
|
+
// src/domain/document/document/create-store.ts
|
|
1368
|
+
var createNode = (store, params) => {
|
|
1369
|
+
const node = new WorkflowRuntimeNode(params);
|
|
1370
|
+
store.nodes.set(node.id, node);
|
|
1371
|
+
return node;
|
|
1372
|
+
};
|
|
1373
|
+
var createEdge = (store, params) => {
|
|
1374
|
+
const edge = new WorkflowRuntimeEdge(params);
|
|
1375
|
+
store.edges.set(edge.id, edge);
|
|
1376
|
+
return edge;
|
|
1377
|
+
};
|
|
1378
|
+
var getOrCreatePort = (store, params) => {
|
|
1379
|
+
const createdPort = store.ports.get(params.id);
|
|
1380
|
+
if (createdPort) {
|
|
1381
|
+
return createdPort;
|
|
1382
|
+
}
|
|
1383
|
+
const port = new WorkflowRuntimePort(params);
|
|
1384
|
+
store.ports.set(port.id, port);
|
|
1385
|
+
return port;
|
|
1386
|
+
};
|
|
1387
|
+
var createStore = (params) => {
|
|
1388
|
+
const { flattenSchema, nodeBlocks } = params;
|
|
1389
|
+
const { nodes, edges } = flattenSchema;
|
|
1390
|
+
const store = {
|
|
1391
|
+
nodes: /* @__PURE__ */ new Map(),
|
|
1392
|
+
edges: /* @__PURE__ */ new Map(),
|
|
1393
|
+
ports: /* @__PURE__ */ new Map()
|
|
1394
|
+
};
|
|
1395
|
+
createNode(store, {
|
|
1396
|
+
id: FlowGramNode.Root,
|
|
1397
|
+
type: FlowGramNode.Root,
|
|
1398
|
+
name: FlowGramNode.Root,
|
|
1399
|
+
position: { x: 0, y: 0 }
|
|
1400
|
+
});
|
|
1401
|
+
nodes.forEach((nodeSchema) => {
|
|
1402
|
+
const id = nodeSchema.id;
|
|
1403
|
+
const type = nodeSchema.type;
|
|
1404
|
+
const {
|
|
1405
|
+
title = `${type}-${id}-untitled`,
|
|
1406
|
+
inputsValues,
|
|
1407
|
+
inputs,
|
|
1408
|
+
outputs,
|
|
1409
|
+
...data
|
|
1410
|
+
} = nodeSchema.data ?? {};
|
|
1411
|
+
createNode(store, {
|
|
1412
|
+
id,
|
|
1413
|
+
type,
|
|
1414
|
+
name: title,
|
|
1415
|
+
position: nodeSchema.meta.position,
|
|
1416
|
+
variable: { inputsValues, inputs, outputs },
|
|
1417
|
+
data
|
|
1418
|
+
});
|
|
1419
|
+
});
|
|
1420
|
+
nodeBlocks.forEach((blockIDs, parentID) => {
|
|
1421
|
+
const parent = store.nodes.get(parentID);
|
|
1422
|
+
const children = blockIDs.map((id) => store.nodes.get(id)).filter(Boolean);
|
|
1423
|
+
children.forEach((child) => {
|
|
1424
|
+
child.parent = parent;
|
|
1425
|
+
parent.addChild(child);
|
|
1426
|
+
});
|
|
1427
|
+
});
|
|
1428
|
+
edges.forEach((edgeSchema) => {
|
|
1429
|
+
const id = WorkflowRuntimeEdge.createID(edgeSchema);
|
|
1430
|
+
const {
|
|
1431
|
+
sourceNodeID,
|
|
1432
|
+
targetNodeID,
|
|
1433
|
+
sourcePortID = "defaultOutput",
|
|
1434
|
+
targetPortID = "defaultInput"
|
|
1435
|
+
} = edgeSchema;
|
|
1436
|
+
const from = store.nodes.get(sourceNodeID);
|
|
1437
|
+
const to = store.nodes.get(targetNodeID);
|
|
1438
|
+
if (!from || !to) {
|
|
1439
|
+
throw new Error(`invalid edge schema ID: ${id}, from: ${sourceNodeID}, to: ${targetNodeID}`);
|
|
1440
|
+
}
|
|
1441
|
+
const edge = createEdge(store, {
|
|
1442
|
+
id,
|
|
1443
|
+
from,
|
|
1444
|
+
to
|
|
1445
|
+
});
|
|
1446
|
+
const fromPort = getOrCreatePort(store, {
|
|
1447
|
+
node: from,
|
|
1448
|
+
id: sourcePortID,
|
|
1449
|
+
type: WorkflowPortType.Output
|
|
1450
|
+
});
|
|
1451
|
+
fromPort.addEdge(edge);
|
|
1452
|
+
edge.fromPort = fromPort;
|
|
1453
|
+
from.addPort(fromPort);
|
|
1454
|
+
from.addOutputEdge(edge);
|
|
1455
|
+
const toPort = getOrCreatePort(store, {
|
|
1456
|
+
node: to,
|
|
1457
|
+
id: targetPortID,
|
|
1458
|
+
type: WorkflowPortType.Input
|
|
1459
|
+
});
|
|
1460
|
+
toPort.addEdge(edge);
|
|
1461
|
+
edge.toPort = toPort;
|
|
1462
|
+
to.addPort(toPort);
|
|
1463
|
+
to.addInputEdge(edge);
|
|
1464
|
+
});
|
|
1465
|
+
return store;
|
|
1466
|
+
};
|
|
1467
|
+
|
|
1468
|
+
// src/domain/document/document/index.ts
|
|
1469
|
+
var WorkflowRuntimeDocument = class {
|
|
1470
|
+
constructor() {
|
|
1471
|
+
this.id = uuid();
|
|
1472
|
+
}
|
|
1473
|
+
get root() {
|
|
1474
|
+
const rootNode = this.getNode(FlowGramNode.Root);
|
|
1475
|
+
if (!rootNode) {
|
|
1476
|
+
throw new Error("Root node not found");
|
|
1477
|
+
}
|
|
1478
|
+
return rootNode;
|
|
1479
|
+
}
|
|
1480
|
+
get start() {
|
|
1481
|
+
const startNode = this.nodes.find((n) => n.type === FlowGramNode.Start);
|
|
1482
|
+
if (!startNode) {
|
|
1483
|
+
throw new Error("Start node not found");
|
|
1484
|
+
}
|
|
1485
|
+
return startNode;
|
|
1486
|
+
}
|
|
1487
|
+
get end() {
|
|
1488
|
+
const endNode = this.nodes.find((n) => n.type === FlowGramNode.End);
|
|
1489
|
+
if (!endNode) {
|
|
1490
|
+
throw new Error("End node not found");
|
|
1491
|
+
}
|
|
1492
|
+
return endNode;
|
|
1493
|
+
}
|
|
1494
|
+
getNode(id) {
|
|
1495
|
+
return this.store.nodes.get(id) ?? null;
|
|
1496
|
+
}
|
|
1497
|
+
getEdge(id) {
|
|
1498
|
+
return this.store.edges.get(id) ?? null;
|
|
1499
|
+
}
|
|
1500
|
+
get nodes() {
|
|
1501
|
+
return Array.from(this.store.nodes.values());
|
|
1502
|
+
}
|
|
1503
|
+
get edges() {
|
|
1504
|
+
return Array.from(this.store.edges.values());
|
|
1505
|
+
}
|
|
1506
|
+
init(schema) {
|
|
1507
|
+
const flattenSchema = flatSchema(schema);
|
|
1508
|
+
this.store = createStore(flattenSchema);
|
|
1509
|
+
}
|
|
1510
|
+
dispose() {
|
|
1511
|
+
this.store.edges.clear();
|
|
1512
|
+
this.store.nodes.clear();
|
|
1513
|
+
this.store.ports.clear();
|
|
1514
|
+
}
|
|
1515
|
+
};
|
|
1516
|
+
|
|
1517
|
+
// src/domain/context/index.ts
|
|
1518
|
+
var WorkflowRuntimeContext = class _WorkflowRuntimeContext {
|
|
1519
|
+
constructor(data) {
|
|
1520
|
+
this.subContexts = [];
|
|
1521
|
+
this.id = uuid();
|
|
1522
|
+
this.document = data.document;
|
|
1523
|
+
this.variableStore = data.variableStore;
|
|
1524
|
+
this.state = data.state;
|
|
1525
|
+
this.ioCenter = data.ioCenter;
|
|
1526
|
+
this.snapshotCenter = data.snapshotCenter;
|
|
1527
|
+
this.statusCenter = data.statusCenter;
|
|
1528
|
+
this.reporter = data.reporter;
|
|
1529
|
+
}
|
|
1530
|
+
init(params) {
|
|
1531
|
+
const { schema, inputs } = params;
|
|
1532
|
+
this.document.init(schema);
|
|
1533
|
+
this.variableStore.init();
|
|
1534
|
+
this.state.init();
|
|
1535
|
+
this.ioCenter.init(inputs);
|
|
1536
|
+
this.snapshotCenter.init();
|
|
1537
|
+
this.statusCenter.init();
|
|
1538
|
+
this.reporter.init();
|
|
1539
|
+
}
|
|
1540
|
+
dispose() {
|
|
1541
|
+
this.subContexts.forEach((subContext) => {
|
|
1542
|
+
subContext.dispose();
|
|
1543
|
+
});
|
|
1544
|
+
this.subContexts = [];
|
|
1545
|
+
this.document.dispose();
|
|
1546
|
+
this.variableStore.dispose();
|
|
1547
|
+
this.state.dispose();
|
|
1548
|
+
this.ioCenter.dispose();
|
|
1549
|
+
this.snapshotCenter.dispose();
|
|
1550
|
+
this.statusCenter.dispose();
|
|
1551
|
+
this.reporter.dispose();
|
|
1552
|
+
}
|
|
1553
|
+
sub() {
|
|
1554
|
+
const variableStore = new WorkflowRuntimeVariableStore();
|
|
1555
|
+
variableStore.setParent(this.variableStore);
|
|
1556
|
+
const state = new WorkflowRuntimeState(variableStore);
|
|
1557
|
+
const contextData = {
|
|
1558
|
+
document: this.document,
|
|
1559
|
+
ioCenter: this.ioCenter,
|
|
1560
|
+
snapshotCenter: this.snapshotCenter,
|
|
1561
|
+
statusCenter: this.statusCenter,
|
|
1562
|
+
reporter: this.reporter,
|
|
1563
|
+
variableStore,
|
|
1564
|
+
state
|
|
1565
|
+
};
|
|
1566
|
+
const subContext = new _WorkflowRuntimeContext(contextData);
|
|
1567
|
+
this.subContexts.push(subContext);
|
|
1568
|
+
subContext.variableStore.init();
|
|
1569
|
+
subContext.state.init();
|
|
1570
|
+
return subContext;
|
|
1571
|
+
}
|
|
1572
|
+
static create() {
|
|
1573
|
+
const document = new WorkflowRuntimeDocument();
|
|
1574
|
+
const variableStore = new WorkflowRuntimeVariableStore();
|
|
1575
|
+
const state = new WorkflowRuntimeState(variableStore);
|
|
1576
|
+
const ioCenter = new WorkflowRuntimeIOCenter();
|
|
1577
|
+
const snapshotCenter = new WorkflowRuntimeSnapshotCenter();
|
|
1578
|
+
const statusCenter = new WorkflowRuntimeStatusCenter();
|
|
1579
|
+
const reporter = new WorkflowRuntimeReporter(ioCenter, snapshotCenter, statusCenter);
|
|
1580
|
+
return new _WorkflowRuntimeContext({
|
|
1581
|
+
document,
|
|
1582
|
+
variableStore,
|
|
1583
|
+
state,
|
|
1584
|
+
ioCenter,
|
|
1585
|
+
snapshotCenter,
|
|
1586
|
+
statusCenter,
|
|
1587
|
+
reporter
|
|
1588
|
+
});
|
|
1589
|
+
}
|
|
1590
|
+
};
|
|
1591
|
+
|
|
1592
|
+
// src/domain/engine/index.ts
|
|
1593
|
+
var WorkflowRuntimeEngine = class {
|
|
1594
|
+
constructor(service) {
|
|
1595
|
+
this.executor = service.Executor;
|
|
1596
|
+
}
|
|
1597
|
+
invoke(params) {
|
|
1598
|
+
const context = WorkflowRuntimeContext.create();
|
|
1599
|
+
context.init(params);
|
|
1600
|
+
const processing = this.process(context);
|
|
1601
|
+
processing.then(() => {
|
|
1602
|
+
context.dispose();
|
|
1603
|
+
});
|
|
1604
|
+
return WorkflowRuntimeTask.create({
|
|
1605
|
+
processing,
|
|
1606
|
+
context
|
|
1607
|
+
});
|
|
1608
|
+
}
|
|
1609
|
+
async executeNode(params) {
|
|
1610
|
+
const { node, context } = params;
|
|
1611
|
+
if (!this.canExecuteNode({ node, context })) {
|
|
1612
|
+
return;
|
|
1613
|
+
}
|
|
1614
|
+
context.statusCenter.nodeStatus(node.id).process();
|
|
1615
|
+
try {
|
|
1616
|
+
const inputs = context.state.getNodeInputs(node);
|
|
1617
|
+
const snapshot = context.snapshotCenter.create({
|
|
1618
|
+
nodeID: node.id,
|
|
1619
|
+
data: node.data,
|
|
1620
|
+
inputs
|
|
1621
|
+
});
|
|
1622
|
+
const result = await this.executor.execute({
|
|
1623
|
+
node,
|
|
1624
|
+
inputs,
|
|
1625
|
+
runtime: context,
|
|
1626
|
+
container: WorkflowRuntimeContainer.instance
|
|
1627
|
+
});
|
|
1628
|
+
if (context.statusCenter.workflow.terminated) {
|
|
1629
|
+
return;
|
|
1630
|
+
}
|
|
1631
|
+
const { outputs, branch } = result;
|
|
1632
|
+
snapshot.addData({ outputs, branch });
|
|
1633
|
+
context.state.setNodeOutputs({ node, outputs });
|
|
1634
|
+
context.state.addExecutedNode(node);
|
|
1635
|
+
context.statusCenter.nodeStatus(node.id).success();
|
|
1636
|
+
const nextNodes = this.getNextNodes({ node, branch, context });
|
|
1637
|
+
await this.executeNext({ node, nextNodes, context });
|
|
1638
|
+
} catch (e) {
|
|
1639
|
+
context.statusCenter.nodeStatus(node.id).fail();
|
|
1640
|
+
console.error(e);
|
|
1641
|
+
return;
|
|
1642
|
+
}
|
|
1643
|
+
}
|
|
1644
|
+
async process(context) {
|
|
1645
|
+
const startNode = context.document.start;
|
|
1646
|
+
context.statusCenter.workflow.process();
|
|
1647
|
+
try {
|
|
1648
|
+
await this.executeNode({ node: startNode, context });
|
|
1649
|
+
const outputs = context.ioCenter.outputs;
|
|
1650
|
+
context.statusCenter.workflow.success();
|
|
1651
|
+
return outputs;
|
|
1652
|
+
} catch (e) {
|
|
1653
|
+
context.statusCenter.workflow.fail();
|
|
1654
|
+
throw e;
|
|
1655
|
+
}
|
|
1656
|
+
}
|
|
1657
|
+
canExecuteNode(params) {
|
|
1658
|
+
const { node, context } = params;
|
|
1659
|
+
const prevNodes = node.prev;
|
|
1660
|
+
if (prevNodes.length === 0) {
|
|
1661
|
+
return true;
|
|
1662
|
+
}
|
|
1663
|
+
return prevNodes.every((prevNode) => context.state.isExecutedNode(prevNode));
|
|
1664
|
+
}
|
|
1665
|
+
getNextNodes(params) {
|
|
1666
|
+
const { node, branch, context } = params;
|
|
1667
|
+
const allNextNodes = node.next;
|
|
1668
|
+
if (!branch) {
|
|
1669
|
+
return allNextNodes;
|
|
1670
|
+
}
|
|
1671
|
+
const targetPort = node.ports.outputs.find((port) => port.id === branch);
|
|
1672
|
+
if (!targetPort) {
|
|
1673
|
+
throw new Error(`branch ${branch} not found`);
|
|
1674
|
+
}
|
|
1675
|
+
const nextNodeIDs = new Set(targetPort.edges.map((edge) => edge.to.id));
|
|
1676
|
+
const nextNodes = allNextNodes.filter((nextNode) => nextNodeIDs.has(nextNode.id));
|
|
1677
|
+
const skipNodes = allNextNodes.filter((nextNode) => !nextNodeIDs.has(nextNode.id));
|
|
1678
|
+
skipNodes.forEach((skipNode) => {
|
|
1679
|
+
context.state.addExecutedNode(skipNode);
|
|
1680
|
+
});
|
|
1681
|
+
return nextNodes;
|
|
1682
|
+
}
|
|
1683
|
+
async executeNext(params) {
|
|
1684
|
+
const { context, node, nextNodes } = params;
|
|
1685
|
+
if (node.type === FlowGramNode.End) {
|
|
1686
|
+
return;
|
|
1687
|
+
}
|
|
1688
|
+
if (nextNodes.length === 0) {
|
|
1689
|
+
return;
|
|
1690
|
+
}
|
|
1691
|
+
await Promise.all(
|
|
1692
|
+
nextNodes.map(
|
|
1693
|
+
(nextNode) => this.executeNode({
|
|
1694
|
+
node: nextNode,
|
|
1695
|
+
context
|
|
1696
|
+
})
|
|
1697
|
+
)
|
|
1698
|
+
);
|
|
1699
|
+
}
|
|
1700
|
+
};
|
|
1701
|
+
|
|
1702
|
+
// src/domain/container/index.ts
|
|
1703
|
+
var WorkflowRuntimeContainer = class _WorkflowRuntimeContainer {
|
|
1704
|
+
constructor(services) {
|
|
1705
|
+
this.services = services;
|
|
1706
|
+
}
|
|
1707
|
+
get(key) {
|
|
1708
|
+
return this.services[key];
|
|
1709
|
+
}
|
|
1710
|
+
static get instance() {
|
|
1711
|
+
if (this._instance) {
|
|
1712
|
+
return this._instance;
|
|
1713
|
+
}
|
|
1714
|
+
const services = this.create();
|
|
1715
|
+
this._instance = new _WorkflowRuntimeContainer(services);
|
|
1716
|
+
return this._instance;
|
|
1717
|
+
}
|
|
1718
|
+
static create() {
|
|
1719
|
+
const Validation = new WorkflowRuntimeValidation();
|
|
1720
|
+
const Executor = new WorkflowRuntimeExecutor(WorkflowRuntimeNodeExecutors);
|
|
1721
|
+
const Engine = new WorkflowRuntimeEngine({
|
|
1722
|
+
Executor
|
|
1723
|
+
});
|
|
1724
|
+
return {
|
|
1725
|
+
[IValidation]: Validation,
|
|
1726
|
+
[IExecutor]: Executor,
|
|
1727
|
+
[IEngine]: Engine
|
|
1728
|
+
};
|
|
1729
|
+
}
|
|
1730
|
+
};
|
|
1731
|
+
|
|
1732
|
+
// src/application/workflow.ts
|
|
1733
|
+
var WorkflowApplication = class _WorkflowApplication {
|
|
1734
|
+
constructor() {
|
|
1735
|
+
this.container = WorkflowRuntimeContainer.instance;
|
|
1736
|
+
this.tasks = /* @__PURE__ */ new Map();
|
|
1737
|
+
}
|
|
1738
|
+
run(params) {
|
|
1739
|
+
const engine = this.container.get(IEngine);
|
|
1740
|
+
const task = engine.invoke(params);
|
|
1741
|
+
this.tasks.set(task.id, task);
|
|
1742
|
+
console.log("> POST TaskRun - taskID: ", task.id);
|
|
1743
|
+
console.log(params.inputs);
|
|
1744
|
+
task.processing.then((output) => {
|
|
1745
|
+
console.log("> LOG Task finished: ", task.id);
|
|
1746
|
+
console.log(output);
|
|
1747
|
+
});
|
|
1748
|
+
return task.id;
|
|
1749
|
+
}
|
|
1750
|
+
cancel(taskID) {
|
|
1751
|
+
console.log("> PUT TaskCancel - taskID: ", taskID);
|
|
1752
|
+
const task = this.tasks.get(taskID);
|
|
1753
|
+
if (!task) {
|
|
1754
|
+
return false;
|
|
1755
|
+
}
|
|
1756
|
+
task.cancel();
|
|
1757
|
+
return true;
|
|
1758
|
+
}
|
|
1759
|
+
report(taskID) {
|
|
1760
|
+
const task = this.tasks.get(taskID);
|
|
1761
|
+
console.log("> GET TaskReport - taskID: ", taskID);
|
|
1762
|
+
if (!task) {
|
|
1763
|
+
return;
|
|
1764
|
+
}
|
|
1765
|
+
return task.context.reporter.export();
|
|
1766
|
+
}
|
|
1767
|
+
result(taskID) {
|
|
1768
|
+
console.log("> GET TaskResult - taskID: ", taskID);
|
|
1769
|
+
const task = this.tasks.get(taskID);
|
|
1770
|
+
if (!task) {
|
|
1771
|
+
return;
|
|
1772
|
+
}
|
|
1773
|
+
if (!task.context.statusCenter.workflow.terminated) {
|
|
1774
|
+
return;
|
|
1775
|
+
}
|
|
1776
|
+
return task.context.ioCenter.outputs;
|
|
1777
|
+
}
|
|
1778
|
+
static get instance() {
|
|
1779
|
+
if (this._instance) {
|
|
1780
|
+
return this._instance;
|
|
1781
|
+
}
|
|
1782
|
+
this._instance = new _WorkflowApplication();
|
|
1783
|
+
return this._instance;
|
|
1784
|
+
}
|
|
1785
|
+
};
|
|
1786
|
+
|
|
1787
|
+
// src/api/task-run.ts
|
|
1788
|
+
var TaskRunAPI = async (input) => {
|
|
1789
|
+
const app = WorkflowApplication.instance;
|
|
1790
|
+
const { schema: stringSchema, inputs } = input;
|
|
1791
|
+
const schema = JSON.parse(stringSchema);
|
|
1792
|
+
const taskID = app.run({
|
|
1793
|
+
schema,
|
|
1794
|
+
inputs
|
|
1795
|
+
});
|
|
1796
|
+
const output = {
|
|
1797
|
+
taskID
|
|
1798
|
+
};
|
|
1799
|
+
return output;
|
|
1800
|
+
};
|
|
1801
|
+
|
|
1802
|
+
// src/api/task-result.ts
|
|
1803
|
+
var TaskResultAPI = async (input) => {
|
|
1804
|
+
const app = WorkflowApplication.instance;
|
|
1805
|
+
const { taskID } = input;
|
|
1806
|
+
const output = app.result(taskID);
|
|
1807
|
+
return output;
|
|
1808
|
+
};
|
|
1809
|
+
|
|
1810
|
+
// src/api/task-report.ts
|
|
1811
|
+
var TaskReportAPI = async (input) => {
|
|
1812
|
+
const app = WorkflowApplication.instance;
|
|
1813
|
+
const { taskID } = input;
|
|
1814
|
+
const output = app.report(taskID);
|
|
1815
|
+
try {
|
|
1816
|
+
TaskReportDefine.schema.output.parse(output);
|
|
1817
|
+
} catch (e) {
|
|
1818
|
+
console.log("> TaskReportAPI - output: ", JSON.stringify(output));
|
|
1819
|
+
console.error(e);
|
|
1820
|
+
}
|
|
1821
|
+
return output;
|
|
1822
|
+
};
|
|
1823
|
+
|
|
1824
|
+
// src/api/task-cancel.ts
|
|
1825
|
+
var TaskCancelAPI = async (input) => {
|
|
1826
|
+
const app = WorkflowApplication.instance;
|
|
1827
|
+
const { taskID } = input;
|
|
1828
|
+
const success = app.cancel(taskID);
|
|
1829
|
+
const output = {
|
|
1830
|
+
success
|
|
1831
|
+
};
|
|
1832
|
+
return output;
|
|
1833
|
+
};
|
|
1834
|
+
|
|
1835
|
+
// src/api/index.ts
|
|
1836
|
+
var WorkflowRuntimeAPIs = {
|
|
1837
|
+
[FlowGramAPIName.TaskRun]: TaskRunAPI,
|
|
1838
|
+
[FlowGramAPIName.TaskReport]: TaskReportAPI,
|
|
1839
|
+
[FlowGramAPIName.TaskResult]: TaskResultAPI,
|
|
1840
|
+
[FlowGramAPIName.TaskCancel]: TaskCancelAPI,
|
|
1841
|
+
[FlowGramAPIName.ServerInfo]: () => {
|
|
1842
|
+
},
|
|
1843
|
+
// TODO
|
|
1844
|
+
[FlowGramAPIName.Validation]: () => {
|
|
1845
|
+
}
|
|
1846
|
+
// TODO
|
|
1847
|
+
};
|
|
1848
|
+
export {
|
|
1849
|
+
TaskCancelAPI,
|
|
1850
|
+
TaskReportAPI,
|
|
1851
|
+
TaskResultAPI,
|
|
1852
|
+
TaskRunAPI,
|
|
1853
|
+
WorkflowRuntimeAPIs
|
|
1854
|
+
};
|
|
1855
|
+
//# sourceMappingURL=index.js.map
|