@flowgram.ai/runtime-js 0.1.0-alpha.10

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