@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.
@@ -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