@flowgram.ai/runtime-js 0.2.21 → 0.2.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/esm/index.js CHANGED
@@ -200,8 +200,27 @@ var FlowGramNode = /* @__PURE__ */ ((FlowGramNode22) => {
200
200
  FlowGramNode22["Loop"] = "loop";
201
201
  FlowGramNode22["Comment"] = "comment";
202
202
  FlowGramNode22["Group"] = "group";
203
+ FlowGramNode22["BlockStart"] = "block-start";
204
+ FlowGramNode22["BlockEnd"] = "block-end";
203
205
  return FlowGramNode22;
204
206
  })(FlowGramNode || {});
207
+ var ConditionOperation = /* @__PURE__ */ ((ConditionOperation2) => {
208
+ ConditionOperation2["EQ"] = "eq";
209
+ ConditionOperation2["NEQ"] = "neq";
210
+ ConditionOperation2["GT"] = "gt";
211
+ ConditionOperation2["GTE"] = "gte";
212
+ ConditionOperation2["LT"] = "lt";
213
+ ConditionOperation2["LTE"] = "lte";
214
+ ConditionOperation2["IN"] = "in";
215
+ ConditionOperation2["NIN"] = "nin";
216
+ ConditionOperation2["CONTAINS"] = "contains";
217
+ ConditionOperation2["NOT_CONTAINS"] = "not_contains";
218
+ ConditionOperation2["IS_EMPTY"] = "is_empty";
219
+ ConditionOperation2["IS_NOT_EMPTY"] = "is_not_empty";
220
+ ConditionOperation2["IS_TRUE"] = "is_true";
221
+ ConditionOperation2["IS_FALSE"] = "is_false";
222
+ return ConditionOperation2;
223
+ })(ConditionOperation || {});
205
224
  var IEngine = Symbol.for("Engine");
206
225
  var IExecutor = Symbol.for("Executor");
207
226
  var WorkflowStatus = /* @__PURE__ */ ((WorkflowStatus2) => {
@@ -213,6 +232,14 @@ var WorkflowStatus = /* @__PURE__ */ ((WorkflowStatus2) => {
213
232
  return WorkflowStatus2;
214
233
  })(WorkflowStatus || {});
215
234
  var IValidation = Symbol.for("Validation");
235
+ var WorkflowMessageType = /* @__PURE__ */ ((WorkflowMessageType2) => {
236
+ WorkflowMessageType2["Log"] = "log";
237
+ WorkflowMessageType2["Info"] = "info";
238
+ WorkflowMessageType2["Debug"] = "debug";
239
+ WorkflowMessageType2["Error"] = "error";
240
+ WorkflowMessageType2["Warn"] = "warning";
241
+ return WorkflowMessageType2;
242
+ })(WorkflowMessageType || {});
216
243
 
217
244
  // src/nodes/start/index.ts
218
245
  var StartExecutor = class {
@@ -228,26 +255,130 @@ var StartExecutor = class {
228
255
 
229
256
  // src/nodes/loop/index.ts
230
257
  import { isNil } from "lodash-es";
258
+
259
+ // src/infrastructure/utils/uuid.ts
260
+ import { v4 } from "uuid";
261
+ var uuid = v4;
262
+
263
+ // src/infrastructure/utils/runtime-type.ts
264
+ var WorkflowRuntimeType;
265
+ ((WorkflowRuntimeType2) => {
266
+ WorkflowRuntimeType2.getWorkflowType = (value) => {
267
+ if (value === null || value === void 0) {
268
+ return WorkflowVariableType.Null;
269
+ }
270
+ if (typeof value === "string") {
271
+ return WorkflowVariableType.String;
272
+ }
273
+ if (typeof value === "boolean") {
274
+ return WorkflowVariableType.Boolean;
275
+ }
276
+ if (typeof value === "number") {
277
+ if (Number.isInteger(value)) {
278
+ return WorkflowVariableType.Integer;
279
+ }
280
+ return WorkflowVariableType.Number;
281
+ }
282
+ if (Array.isArray(value)) {
283
+ return WorkflowVariableType.Array;
284
+ }
285
+ if (typeof value === "object") {
286
+ return WorkflowVariableType.Object;
287
+ }
288
+ return null;
289
+ };
290
+ WorkflowRuntimeType2.isMatchWorkflowType = (value, type) => {
291
+ const workflowType = (0, WorkflowRuntimeType2.getWorkflowType)(value);
292
+ if (!workflowType) {
293
+ return false;
294
+ }
295
+ return workflowType === type;
296
+ };
297
+ WorkflowRuntimeType2.isTypeEqual = (leftType, rightType) => {
298
+ if (leftType === WorkflowVariableType.Number && rightType === WorkflowVariableType.Integer || leftType === WorkflowVariableType.Integer && rightType === WorkflowVariableType.Number) {
299
+ return true;
300
+ }
301
+ return leftType === rightType;
302
+ };
303
+ WorkflowRuntimeType2.getArrayItemsType = (types) => {
304
+ const expectedType = types[0];
305
+ types.forEach((type) => {
306
+ if (type !== expectedType) {
307
+ throw new Error(`array items type must be same, expect ${expectedType}, but got ${type}`);
308
+ }
309
+ });
310
+ return expectedType;
311
+ };
312
+ })(WorkflowRuntimeType || (WorkflowRuntimeType = {}));
313
+
314
+ // src/infrastructure/utils/traverse-nodes.ts
315
+ function traverseNodes(startNode, getConnectedNodes) {
316
+ const visited = /* @__PURE__ */ new Set();
317
+ const result = [];
318
+ const traverse = (node) => {
319
+ for (const connectedNode of getConnectedNodes(node)) {
320
+ if (!visited.has(connectedNode.id)) {
321
+ visited.add(connectedNode.id);
322
+ result.push(connectedNode);
323
+ traverse(connectedNode);
324
+ }
325
+ }
326
+ };
327
+ traverse(startNode);
328
+ return result;
329
+ }
330
+
331
+ // src/infrastructure/utils/compare-node-groups.ts
332
+ function compareNodeGroups(groupA, groupB) {
333
+ const flatA = groupA.flat();
334
+ const setA = /* @__PURE__ */ new Map();
335
+ flatA.forEach((node) => {
336
+ setA.set(node.id, node);
337
+ });
338
+ const flatB = groupB.flat();
339
+ const setB = /* @__PURE__ */ new Map();
340
+ flatB.forEach((node) => {
341
+ setB.set(node.id, node);
342
+ });
343
+ const common = [];
344
+ const uniqueToA = [];
345
+ const uniqueToB = [];
346
+ setA.forEach((node, id) => {
347
+ if (setB.has(id)) {
348
+ common.push(node);
349
+ } else {
350
+ uniqueToA.push(node);
351
+ }
352
+ });
353
+ setB.forEach((node, id) => {
354
+ if (!setA.has(id)) {
355
+ uniqueToB.push(node);
356
+ }
357
+ });
358
+ return {
359
+ common,
360
+ uniqueToA,
361
+ uniqueToB
362
+ };
363
+ }
364
+
365
+ // src/nodes/loop/index.ts
231
366
  var LoopExecutor = class {
232
367
  constructor() {
233
368
  this.type = FlowGramNode.Loop;
234
369
  }
235
370
  async execute(context) {
236
371
  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
372
  const engine = context.container.get(IEngine);
373
+ const { value: loopArray, itemsType } = this.getLoopArrayVariable(context);
242
374
  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
- };
375
+ const blockStartNode = subNodes.find((node) => node.type === FlowGramNode.BlockStart);
376
+ if (!blockStartNode) {
377
+ throw new Error("block start node not found");
248
378
  }
249
- for (let i = 0; i < loopArray.length; i++) {
250
- const loopItem = loopArray[i];
379
+ const blockOutputs = [];
380
+ for (let index = 0; index < loopArray.length; index++) {
381
+ const loopItem = loopArray[index];
251
382
  const subContext = context.runtime.sub();
252
383
  subContext.variableStore.setVariable({
253
384
  nodeID: `${loopNodeID}_locals`,
@@ -255,33 +386,99 @@ var LoopExecutor = class {
255
386
  type: itemsType,
256
387
  value: loopItem
257
388
  });
258
- await Promise.all(
259
- startSubNodes.map(
260
- (node) => engine.executeNode({
261
- context: subContext,
262
- node
263
- })
264
- )
265
- );
389
+ subContext.variableStore.setVariable({
390
+ nodeID: `${loopNodeID}_locals`,
391
+ key: "index",
392
+ type: WorkflowVariableType.Number,
393
+ value: index
394
+ });
395
+ await engine.executeNode({
396
+ context: subContext,
397
+ node: blockStartNode
398
+ });
399
+ const blockOutput = this.getBlockOutput(context, subContext);
400
+ blockOutputs.push(blockOutput);
266
401
  }
402
+ this.setLoopNodeOutputs(context, blockOutputs);
403
+ const outputs = this.combineBlockOutputs(context, blockOutputs);
267
404
  return {
268
- outputs: {}
405
+ outputs
269
406
  };
270
407
  }
271
- checkLoopArray(loopArrayResult) {
272
- const loopArray = loopArrayResult?.value;
408
+ getLoopArrayVariable(executionContext) {
409
+ const loopNodeData = executionContext.node.data;
410
+ const LoopArrayVariable = executionContext.runtime.state.parseRef(
411
+ loopNodeData.loopFor
412
+ );
413
+ this.checkLoopArray(LoopArrayVariable);
414
+ return LoopArrayVariable;
415
+ }
416
+ checkLoopArray(LoopArrayVariable) {
417
+ const loopArray = LoopArrayVariable?.value;
273
418
  if (!loopArray || isNil(loopArray) || !Array.isArray(loopArray)) {
274
- throw new Error("batchFor is required");
419
+ throw new Error("loopFor is required");
275
420
  }
276
- const loopArrayType = loopArrayResult.type;
421
+ const loopArrayType = LoopArrayVariable.type;
277
422
  if (loopArrayType !== WorkflowVariableType.Array) {
278
- throw new Error("batchFor must be an array");
423
+ throw new Error("loopFor must be an array");
279
424
  }
280
- const loopArrayItemType = loopArrayResult.itemsType;
425
+ const loopArrayItemType = LoopArrayVariable.itemsType;
281
426
  if (isNil(loopArrayItemType)) {
282
- throw new Error("batchFor items must be array items");
427
+ throw new Error("loopFor items must be array items");
283
428
  }
284
429
  }
430
+ getBlockOutput(executionContext, subContext) {
431
+ const loopOutputsDeclare = this.getLoopOutputsDeclare(executionContext);
432
+ const blockOutput = Object.entries(loopOutputsDeclare).reduce(
433
+ (acc, [outputName, outputRef]) => {
434
+ const outputVariable = subContext.state.parseRef(outputRef);
435
+ if (!outputVariable) {
436
+ return acc;
437
+ }
438
+ return {
439
+ ...acc,
440
+ [outputName]: outputVariable
441
+ };
442
+ },
443
+ {}
444
+ );
445
+ return blockOutput;
446
+ }
447
+ setLoopNodeOutputs(executionContext, blockOutputs) {
448
+ const loopNode = executionContext.node;
449
+ const loopOutputsDeclare = this.getLoopOutputsDeclare(executionContext);
450
+ const loopOutputNames = Object.keys(loopOutputsDeclare);
451
+ loopOutputNames.forEach((outputName) => {
452
+ const outputVariables = blockOutputs.map((blockOutput) => blockOutput[outputName]);
453
+ const outputTypes = outputVariables.map((fieldVariable) => fieldVariable.type);
454
+ const itemsType = WorkflowRuntimeType.getArrayItemsType(outputTypes);
455
+ const value = outputVariables.map((fieldVariable) => fieldVariable.value);
456
+ executionContext.runtime.variableStore.setVariable({
457
+ nodeID: loopNode.id,
458
+ key: outputName,
459
+ type: WorkflowVariableType.Array,
460
+ itemsType,
461
+ value
462
+ });
463
+ });
464
+ }
465
+ combineBlockOutputs(executionContext, blockOutputs) {
466
+ const loopOutputsDeclare = this.getLoopOutputsDeclare(executionContext);
467
+ const loopOutputNames = Object.keys(loopOutputsDeclare);
468
+ const loopOutput = loopOutputNames.reduce(
469
+ (outputs, outputName) => ({
470
+ ...outputs,
471
+ [outputName]: blockOutputs.map((blockOutput) => blockOutput[outputName].value)
472
+ }),
473
+ {}
474
+ );
475
+ return loopOutput;
476
+ }
477
+ getLoopOutputsDeclare(executionContext) {
478
+ const loopNodeData = executionContext.node.data;
479
+ const loopOutputsDeclare = loopNodeData.loopOutputs ?? {};
480
+ return loopOutputsDeclare;
481
+ }
285
482
  };
286
483
 
287
484
  // src/nodes/llm/index.ts
@@ -344,67 +541,89 @@ var EndExecutor = class {
344
541
  }
345
542
  };
346
543
 
544
+ // src/nodes/empty/index.ts
545
+ var BlockStartExecutor = class {
546
+ constructor() {
547
+ this.type = FlowGramNode.BlockStart;
548
+ }
549
+ async execute(context) {
550
+ return {
551
+ outputs: {}
552
+ };
553
+ }
554
+ };
555
+ var BlockEndExecutor = class {
556
+ constructor() {
557
+ this.type = FlowGramNode.BlockEnd;
558
+ }
559
+ async execute(context) {
560
+ return {
561
+ outputs: {}
562
+ };
563
+ }
564
+ };
565
+
347
566
  // src/nodes/condition/index.ts
348
567
  import { isNil as isNil9 } from "lodash-es";
349
568
 
350
569
  // src/nodes/condition/rules.ts
351
570
  var conditionRules = {
352
571
  [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
572
+ [ConditionOperation.EQ]: WorkflowVariableType.String,
573
+ [ConditionOperation.NEQ]: WorkflowVariableType.String,
574
+ [ConditionOperation.CONTAINS]: WorkflowVariableType.String,
575
+ [ConditionOperation.NOT_CONTAINS]: WorkflowVariableType.String,
576
+ [ConditionOperation.IN]: WorkflowVariableType.Array,
577
+ [ConditionOperation.NIN]: WorkflowVariableType.Array,
578
+ [ConditionOperation.IS_EMPTY]: WorkflowVariableType.String,
579
+ [ConditionOperation.IS_NOT_EMPTY]: WorkflowVariableType.String
361
580
  },
362
581
  [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
582
+ [ConditionOperation.EQ]: WorkflowVariableType.Number,
583
+ [ConditionOperation.NEQ]: WorkflowVariableType.Number,
584
+ [ConditionOperation.GT]: WorkflowVariableType.Number,
585
+ [ConditionOperation.GTE]: WorkflowVariableType.Number,
586
+ [ConditionOperation.LT]: WorkflowVariableType.Number,
587
+ [ConditionOperation.LTE]: WorkflowVariableType.Number,
588
+ [ConditionOperation.IN]: WorkflowVariableType.Array,
589
+ [ConditionOperation.NIN]: WorkflowVariableType.Array,
590
+ [ConditionOperation.IS_EMPTY]: WorkflowVariableType.Null,
591
+ [ConditionOperation.IS_NOT_EMPTY]: WorkflowVariableType.Null
373
592
  },
374
593
  [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
594
+ [ConditionOperation.EQ]: WorkflowVariableType.Integer,
595
+ [ConditionOperation.NEQ]: WorkflowVariableType.Integer,
596
+ [ConditionOperation.GT]: WorkflowVariableType.Integer,
597
+ [ConditionOperation.GTE]: WorkflowVariableType.Integer,
598
+ [ConditionOperation.LT]: WorkflowVariableType.Integer,
599
+ [ConditionOperation.LTE]: WorkflowVariableType.Integer,
600
+ [ConditionOperation.IN]: WorkflowVariableType.Array,
601
+ [ConditionOperation.NIN]: WorkflowVariableType.Array,
602
+ [ConditionOperation.IS_EMPTY]: WorkflowVariableType.Null,
603
+ [ConditionOperation.IS_NOT_EMPTY]: WorkflowVariableType.Null
385
604
  },
386
605
  [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
606
+ [ConditionOperation.EQ]: WorkflowVariableType.Boolean,
607
+ [ConditionOperation.NEQ]: WorkflowVariableType.Boolean,
608
+ [ConditionOperation.IS_TRUE]: WorkflowVariableType.Null,
609
+ [ConditionOperation.IS_FALSE]: WorkflowVariableType.Null,
610
+ [ConditionOperation.IN]: WorkflowVariableType.Array,
611
+ [ConditionOperation.NIN]: WorkflowVariableType.Array,
612
+ [ConditionOperation.IS_EMPTY]: WorkflowVariableType.Null,
613
+ [ConditionOperation.IS_NOT_EMPTY]: WorkflowVariableType.Null
395
614
  },
396
615
  [WorkflowVariableType.Object]: {
397
- ["is_empty" /* IS_EMPTY */]: WorkflowVariableType.Null,
398
- ["is_not_empty" /* IS_NOT_EMPTY */]: WorkflowVariableType.Null
616
+ [ConditionOperation.IS_EMPTY]: WorkflowVariableType.Null,
617
+ [ConditionOperation.IS_NOT_EMPTY]: WorkflowVariableType.Null
399
618
  },
400
619
  [WorkflowVariableType.Array]: {
401
- ["is_empty" /* IS_EMPTY */]: WorkflowVariableType.Null,
402
- ["is_not_empty" /* IS_NOT_EMPTY */]: WorkflowVariableType.Null
620
+ [ConditionOperation.IS_EMPTY]: WorkflowVariableType.Null,
621
+ [ConditionOperation.IS_NOT_EMPTY]: WorkflowVariableType.Null
403
622
  },
404
623
  [WorkflowVariableType.Null]: {
405
- ["eq" /* EQ */]: WorkflowVariableType.Null,
406
- ["is_empty" /* IS_EMPTY */]: WorkflowVariableType.Null,
407
- ["is_not_empty" /* IS_NOT_EMPTY */]: WorkflowVariableType.Null
624
+ [ConditionOperation.EQ]: WorkflowVariableType.Null,
625
+ [ConditionOperation.IS_EMPTY]: WorkflowVariableType.Null,
626
+ [ConditionOperation.IS_NOT_EMPTY]: WorkflowVariableType.Null
408
627
  }
409
628
  };
410
629
 
@@ -413,34 +632,34 @@ import { isNil as isNil3 } from "lodash-es";
413
632
  var conditionStringHandler = (condition) => {
414
633
  const { operator } = condition;
415
634
  const leftValue = condition.leftValue;
416
- if (operator === "eq" /* EQ */) {
635
+ if (operator === ConditionOperation.EQ) {
417
636
  const rightValue = condition.rightValue;
418
637
  return leftValue === rightValue;
419
638
  }
420
- if (operator === "neq" /* NEQ */) {
639
+ if (operator === ConditionOperation.NEQ) {
421
640
  const rightValue = condition.rightValue;
422
641
  return leftValue !== rightValue;
423
642
  }
424
- if (operator === "contains" /* CONTAINS */) {
643
+ if (operator === ConditionOperation.CONTAINS) {
425
644
  const rightValue = condition.rightValue;
426
645
  return leftValue.includes(rightValue);
427
646
  }
428
- if (operator === "not_contains" /* NOT_CONTAINS */) {
647
+ if (operator === ConditionOperation.NOT_CONTAINS) {
429
648
  const rightValue = condition.rightValue;
430
649
  return !leftValue.includes(rightValue);
431
650
  }
432
- if (operator === "in" /* IN */) {
651
+ if (operator === ConditionOperation.IN) {
433
652
  const rightValue = condition.rightValue;
434
653
  return rightValue.includes(leftValue);
435
654
  }
436
- if (operator === "nin" /* NIN */) {
655
+ if (operator === ConditionOperation.NIN) {
437
656
  const rightValue = condition.rightValue;
438
657
  return !rightValue.includes(leftValue);
439
658
  }
440
- if (operator === "is_empty" /* IS_EMPTY */) {
659
+ if (operator === ConditionOperation.IS_EMPTY) {
441
660
  return isNil3(leftValue);
442
661
  }
443
- if (operator === "is_not_empty" /* IS_NOT_EMPTY */) {
662
+ if (operator === ConditionOperation.IS_NOT_EMPTY) {
444
663
  return !isNil3(leftValue);
445
664
  }
446
665
  return false;
@@ -451,10 +670,10 @@ import { isNil as isNil4 } from "lodash-es";
451
670
  var conditionObjectHandler = (condition) => {
452
671
  const { operator } = condition;
453
672
  const leftValue = condition.leftValue;
454
- if (operator === "is_empty" /* IS_EMPTY */) {
673
+ if (operator === ConditionOperation.IS_EMPTY) {
455
674
  return isNil4(leftValue);
456
675
  }
457
- if (operator === "is_not_empty" /* IS_NOT_EMPTY */) {
676
+ if (operator === ConditionOperation.IS_NOT_EMPTY) {
458
677
  return !isNil4(leftValue);
459
678
  }
460
679
  return false;
@@ -465,42 +684,42 @@ import { isNil as isNil5 } from "lodash-es";
465
684
  var conditionNumberHandler = (condition) => {
466
685
  const { operator } = condition;
467
686
  const leftValue = condition.leftValue;
468
- if (operator === "eq" /* EQ */) {
687
+ if (operator === ConditionOperation.EQ) {
469
688
  const rightValue = condition.rightValue;
470
689
  return leftValue === rightValue;
471
690
  }
472
- if (operator === "neq" /* NEQ */) {
691
+ if (operator === ConditionOperation.NEQ) {
473
692
  const rightValue = condition.rightValue;
474
693
  return leftValue !== rightValue;
475
694
  }
476
- if (operator === "gt" /* GT */) {
695
+ if (operator === ConditionOperation.GT) {
477
696
  const rightValue = condition.rightValue;
478
697
  return leftValue > rightValue;
479
698
  }
480
- if (operator === "gte" /* GTE */) {
699
+ if (operator === ConditionOperation.GTE) {
481
700
  const rightValue = condition.rightValue;
482
701
  return leftValue >= rightValue;
483
702
  }
484
- if (operator === "lt" /* LT */) {
703
+ if (operator === ConditionOperation.LT) {
485
704
  const rightValue = condition.rightValue;
486
705
  return leftValue < rightValue;
487
706
  }
488
- if (operator === "lte" /* LTE */) {
707
+ if (operator === ConditionOperation.LTE) {
489
708
  const rightValue = condition.rightValue;
490
709
  return leftValue <= rightValue;
491
710
  }
492
- if (operator === "in" /* IN */) {
711
+ if (operator === ConditionOperation.IN) {
493
712
  const rightValue = condition.rightValue;
494
713
  return rightValue.includes(leftValue);
495
714
  }
496
- if (operator === "nin" /* NIN */) {
715
+ if (operator === ConditionOperation.NIN) {
497
716
  const rightValue = condition.rightValue;
498
717
  return !rightValue.includes(leftValue);
499
718
  }
500
- if (operator === "is_empty" /* IS_EMPTY */) {
719
+ if (operator === ConditionOperation.IS_EMPTY) {
501
720
  return isNil5(leftValue);
502
721
  }
503
- if (operator === "is_not_empty" /* IS_NOT_EMPTY */) {
722
+ if (operator === ConditionOperation.IS_NOT_EMPTY) {
504
723
  return !isNil5(leftValue);
505
724
  }
506
725
  return false;
@@ -511,13 +730,13 @@ import { isNil as isNil6 } from "lodash-es";
511
730
  var conditionNullHandler = (condition) => {
512
731
  const { operator } = condition;
513
732
  const leftValue = condition.leftValue;
514
- if (operator === "eq" /* EQ */) {
733
+ if (operator === ConditionOperation.EQ) {
515
734
  return isNil6(leftValue) && isNil6(condition.rightValue);
516
735
  }
517
- if (operator === "is_empty" /* IS_EMPTY */) {
736
+ if (operator === ConditionOperation.IS_EMPTY) {
518
737
  return isNil6(leftValue);
519
738
  }
520
- if (operator === "is_not_empty" /* IS_NOT_EMPTY */) {
739
+ if (operator === ConditionOperation.IS_NOT_EMPTY) {
521
740
  return !isNil6(leftValue);
522
741
  }
523
742
  return false;
@@ -528,32 +747,32 @@ import { isNil as isNil7 } from "lodash-es";
528
747
  var conditionBooleanHandler = (condition) => {
529
748
  const { operator } = condition;
530
749
  const leftValue = condition.leftValue;
531
- if (operator === "eq" /* EQ */) {
750
+ if (operator === ConditionOperation.EQ) {
532
751
  const rightValue = condition.rightValue;
533
752
  return leftValue === rightValue;
534
753
  }
535
- if (operator === "neq" /* NEQ */) {
754
+ if (operator === ConditionOperation.NEQ) {
536
755
  const rightValue = condition.rightValue;
537
756
  return leftValue !== rightValue;
538
757
  }
539
- if (operator === "is_true" /* IS_TRUE */) {
758
+ if (operator === ConditionOperation.IS_TRUE) {
540
759
  return leftValue === true;
541
760
  }
542
- if (operator === "is_false" /* IS_FALSE */) {
761
+ if (operator === ConditionOperation.IS_FALSE) {
543
762
  return leftValue === false;
544
763
  }
545
- if (operator === "in" /* IN */) {
764
+ if (operator === ConditionOperation.IN) {
546
765
  const rightValue = condition.rightValue;
547
766
  return rightValue.includes(leftValue);
548
767
  }
549
- if (operator === "nin" /* NIN */) {
768
+ if (operator === ConditionOperation.NIN) {
550
769
  const rightValue = condition.rightValue;
551
770
  return !rightValue.includes(leftValue);
552
771
  }
553
- if (operator === "is_empty" /* IS_EMPTY */) {
772
+ if (operator === ConditionOperation.IS_EMPTY) {
554
773
  return isNil7(leftValue);
555
774
  }
556
- if (operator === "is_not_empty" /* IS_NOT_EMPTY */) {
775
+ if (operator === ConditionOperation.IS_NOT_EMPTY) {
557
776
  return !isNil7(leftValue);
558
777
  }
559
778
  return false;
@@ -564,10 +783,10 @@ import { isNil as isNil8 } from "lodash-es";
564
783
  var conditionArrayHandler = (condition) => {
565
784
  const { operator } = condition;
566
785
  const leftValue = condition.leftValue;
567
- if (operator === "is_empty" /* IS_EMPTY */) {
786
+ if (operator === ConditionOperation.IS_EMPTY) {
568
787
  return isNil8(leftValue);
569
788
  }
570
- if (operator === "is_not_empty" /* IS_NOT_EMPTY */) {
789
+ if (operator === ConditionOperation.IS_NOT_EMPTY) {
571
790
  return !isNil8(leftValue);
572
791
  }
573
792
  return false;
@@ -599,9 +818,7 @@ var ConditionExecutor = class {
599
818
  const parsedConditions = conditions.map((item) => this.parseCondition(item, context)).filter((item) => this.checkCondition(item));
600
819
  const activatedCondition = parsedConditions.find((item) => this.handleCondition(item));
601
820
  if (!activatedCondition) {
602
- return {
603
- outputs: {}
604
- };
821
+ throw new Error("no condition is activated");
605
822
  }
606
823
  return {
607
824
  outputs: {},
@@ -656,7 +873,9 @@ var WorkflowRuntimeNodeExecutors = [
656
873
  EndExecutor,
657
874
  LLMExecutor,
658
875
  ConditionExecutor,
659
- LoopExecutor
876
+ LoopExecutor,
877
+ BlockStartExecutor,
878
+ BlockEndExecutor
660
879
  ];
661
880
 
662
881
  // src/domain/validation/index.ts
@@ -690,52 +909,6 @@ var WorkflowRuntimeExecutor = class {
690
909
  }
691
910
  };
692
911
 
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
912
  // src/domain/task/index.ts
740
913
  var WorkflowRuntimeTask = class _WorkflowRuntimeTask {
741
914
  constructor(params) {
@@ -755,6 +928,85 @@ var WorkflowRuntimeTask = class _WorkflowRuntimeTask {
755
928
  }
756
929
  };
757
930
 
931
+ // src/domain/message/message-value-object/index.ts
932
+ var WorkflowRuntimeMessage;
933
+ ((WorkflowRuntimeMessage2) => {
934
+ WorkflowRuntimeMessage2.create = (params) => {
935
+ const message = {
936
+ id: uuid(),
937
+ ...params
938
+ };
939
+ if (!params.timestamp) {
940
+ message.timestamp = Date.now();
941
+ }
942
+ return message;
943
+ };
944
+ })(WorkflowRuntimeMessage || (WorkflowRuntimeMessage = {}));
945
+
946
+ // src/domain/message/message-center/index.ts
947
+ var WorkflowRuntimeMessageCenter = class {
948
+ init() {
949
+ this.messages = {
950
+ [WorkflowMessageType.Log]: [],
951
+ [WorkflowMessageType.Info]: [],
952
+ [WorkflowMessageType.Debug]: [],
953
+ [WorkflowMessageType.Error]: [],
954
+ [WorkflowMessageType.Warn]: []
955
+ };
956
+ }
957
+ dispose() {
958
+ }
959
+ log(data) {
960
+ const message = WorkflowRuntimeMessage.create({
961
+ type: WorkflowMessageType.Log,
962
+ ...data
963
+ });
964
+ this.messages[WorkflowMessageType.Log].push(message);
965
+ return message;
966
+ }
967
+ info(data) {
968
+ const message = WorkflowRuntimeMessage.create({
969
+ type: WorkflowMessageType.Info,
970
+ ...data
971
+ });
972
+ this.messages[WorkflowMessageType.Info].push(message);
973
+ return message;
974
+ }
975
+ debug(data) {
976
+ const message = WorkflowRuntimeMessage.create({
977
+ type: WorkflowMessageType.Debug,
978
+ ...data
979
+ });
980
+ this.messages[WorkflowMessageType.Debug].push(message);
981
+ return message;
982
+ }
983
+ error(data) {
984
+ const message = WorkflowRuntimeMessage.create({
985
+ type: WorkflowMessageType.Error,
986
+ ...data
987
+ });
988
+ this.messages[WorkflowMessageType.Error].push(message);
989
+ return message;
990
+ }
991
+ warn(data) {
992
+ const message = WorkflowRuntimeMessage.create({
993
+ type: WorkflowMessageType.Warn,
994
+ ...data
995
+ });
996
+ this.messages[WorkflowMessageType.Warn].push(message);
997
+ return message;
998
+ }
999
+ export() {
1000
+ return {
1001
+ [WorkflowMessageType.Log]: this.messages[WorkflowMessageType.Log].slice(),
1002
+ [WorkflowMessageType.Info]: this.messages[WorkflowMessageType.Info].slice(),
1003
+ [WorkflowMessageType.Debug]: this.messages[WorkflowMessageType.Debug].slice(),
1004
+ [WorkflowMessageType.Error]: this.messages[WorkflowMessageType.Error].slice(),
1005
+ [WorkflowMessageType.Warn]: this.messages[WorkflowMessageType.Warn].slice()
1006
+ };
1007
+ }
1008
+ };
1009
+
758
1010
  // src/domain/variable/variable-store/index.ts
759
1011
  import { get, set } from "lodash-es";
760
1012
 
@@ -1104,7 +1356,7 @@ var WorkflowRuntimeSnapshot = class _WorkflowRuntimeSnapshot {
1104
1356
  this.id = uuid();
1105
1357
  this.data = data;
1106
1358
  }
1107
- addData(data) {
1359
+ update(data) {
1108
1360
  Object.assign(this.data, data);
1109
1361
  }
1110
1362
  validate() {
@@ -1165,10 +1417,11 @@ var WorkflowRuntimeReport;
1165
1417
 
1166
1418
  // src/domain/report/reporter/index.ts
1167
1419
  var WorkflowRuntimeReporter = class {
1168
- constructor(ioCenter, snapshotCenter, statusCenter) {
1420
+ constructor(ioCenter, snapshotCenter, statusCenter, messageCenter) {
1169
1421
  this.ioCenter = ioCenter;
1170
1422
  this.snapshotCenter = snapshotCenter;
1171
1423
  this.statusCenter = statusCenter;
1424
+ this.messageCenter = messageCenter;
1172
1425
  }
1173
1426
  init() {
1174
1427
  }
@@ -1179,7 +1432,8 @@ var WorkflowRuntimeReporter = class {
1179
1432
  inputs: this.ioCenter.inputs,
1180
1433
  outputs: this.ioCenter.outputs,
1181
1434
  workflowStatus: this.statusCenter.workflow.export(),
1182
- reports: this.nodeReports()
1435
+ reports: this.nodeReports(),
1436
+ messages: this.messageCenter.export()
1183
1437
  });
1184
1438
  return report;
1185
1439
  }
@@ -1317,6 +1571,12 @@ var WorkflowRuntimeNode = class {
1317
1571
  get next() {
1318
1572
  return this._next;
1319
1573
  }
1574
+ get successors() {
1575
+ return traverseNodes(this, (node) => node.next);
1576
+ }
1577
+ get predecessors() {
1578
+ return traverseNodes(this, (node) => node.prev);
1579
+ }
1320
1580
  get isBranch() {
1321
1581
  return this.ports.outputs.length > 1;
1322
1582
  }
@@ -1554,6 +1814,7 @@ var WorkflowRuntimeContext = class _WorkflowRuntimeContext {
1554
1814
  this.ioCenter = data.ioCenter;
1555
1815
  this.snapshotCenter = data.snapshotCenter;
1556
1816
  this.statusCenter = data.statusCenter;
1817
+ this.messageCenter = data.messageCenter;
1557
1818
  this.reporter = data.reporter;
1558
1819
  }
1559
1820
  init(params) {
@@ -1564,6 +1825,7 @@ var WorkflowRuntimeContext = class _WorkflowRuntimeContext {
1564
1825
  this.ioCenter.init(inputs);
1565
1826
  this.snapshotCenter.init();
1566
1827
  this.statusCenter.init();
1828
+ this.messageCenter.init();
1567
1829
  this.reporter.init();
1568
1830
  }
1569
1831
  dispose() {
@@ -1577,6 +1839,7 @@ var WorkflowRuntimeContext = class _WorkflowRuntimeContext {
1577
1839
  this.ioCenter.dispose();
1578
1840
  this.snapshotCenter.dispose();
1579
1841
  this.statusCenter.dispose();
1842
+ this.messageCenter.dispose();
1580
1843
  this.reporter.dispose();
1581
1844
  }
1582
1845
  sub() {
@@ -1588,6 +1851,7 @@ var WorkflowRuntimeContext = class _WorkflowRuntimeContext {
1588
1851
  ioCenter: this.ioCenter,
1589
1852
  snapshotCenter: this.snapshotCenter,
1590
1853
  statusCenter: this.statusCenter,
1854
+ messageCenter: this.messageCenter,
1591
1855
  reporter: this.reporter,
1592
1856
  variableStore,
1593
1857
  state
@@ -1605,7 +1869,13 @@ var WorkflowRuntimeContext = class _WorkflowRuntimeContext {
1605
1869
  const ioCenter = new WorkflowRuntimeIOCenter();
1606
1870
  const snapshotCenter = new WorkflowRuntimeSnapshotCenter();
1607
1871
  const statusCenter = new WorkflowRuntimeStatusCenter();
1608
- const reporter = new WorkflowRuntimeReporter(ioCenter, snapshotCenter, statusCenter);
1872
+ const messageCenter = new WorkflowRuntimeMessageCenter();
1873
+ const reporter = new WorkflowRuntimeReporter(
1874
+ ioCenter,
1875
+ snapshotCenter,
1876
+ statusCenter,
1877
+ messageCenter
1878
+ );
1609
1879
  return new _WorkflowRuntimeContext({
1610
1880
  document,
1611
1881
  variableStore,
@@ -1613,6 +1883,7 @@ var WorkflowRuntimeContext = class _WorkflowRuntimeContext {
1613
1883
  ioCenter,
1614
1884
  snapshotCenter,
1615
1885
  statusCenter,
1886
+ messageCenter,
1616
1887
  reporter
1617
1888
  });
1618
1889
  }
@@ -1641,11 +1912,14 @@ var WorkflowRuntimeEngine = class {
1641
1912
  return;
1642
1913
  }
1643
1914
  context.statusCenter.nodeStatus(node.id).process();
1915
+ const snapshot = context.snapshotCenter.create({
1916
+ nodeID: node.id,
1917
+ data: node.data
1918
+ });
1919
+ let nextNodes = [];
1644
1920
  try {
1645
1921
  const inputs = context.state.getNodeInputs(node);
1646
- const snapshot = context.snapshotCenter.create({
1647
- nodeID: node.id,
1648
- data: node.data,
1922
+ snapshot.update({
1649
1923
  inputs
1650
1924
  });
1651
1925
  const result = await this.executor.execute({
@@ -1658,17 +1932,23 @@ var WorkflowRuntimeEngine = class {
1658
1932
  return;
1659
1933
  }
1660
1934
  const { outputs, branch } = result;
1661
- snapshot.addData({ outputs, branch });
1935
+ snapshot.update({ outputs, branch });
1662
1936
  context.state.setNodeOutputs({ node, outputs });
1663
1937
  context.state.addExecutedNode(node);
1664
1938
  context.statusCenter.nodeStatus(node.id).success();
1665
- const nextNodes = this.getNextNodes({ node, branch, context });
1666
- await this.executeNext({ node, nextNodes, context });
1939
+ nextNodes = this.getNextNodes({ node, branch, context });
1667
1940
  } catch (e) {
1941
+ const errorMessage = e instanceof Error ? e.message : "An unknown error occurred";
1942
+ snapshot.update({ error: errorMessage });
1943
+ context.messageCenter.error({
1944
+ nodeID: node.id,
1945
+ message: errorMessage
1946
+ });
1668
1947
  context.statusCenter.nodeStatus(node.id).fail();
1669
1948
  console.error(e);
1670
- return;
1949
+ throw e;
1671
1950
  }
1951
+ await this.executeNext({ node, nextNodes, context });
1672
1952
  }
1673
1953
  async process(context) {
1674
1954
  const startNode = context.document.start;
@@ -1680,7 +1960,7 @@ var WorkflowRuntimeEngine = class {
1680
1960
  return outputs;
1681
1961
  } catch (e) {
1682
1962
  context.statusCenter.workflow.fail();
1683
- throw e;
1963
+ return {};
1684
1964
  }
1685
1965
  }
1686
1966
  canExecuteNode(params) {
@@ -1704,8 +1984,11 @@ var WorkflowRuntimeEngine = class {
1704
1984
  const nextNodeIDs = new Set(targetPort.edges.map((edge) => edge.to.id));
1705
1985
  const nextNodes = allNextNodes.filter((nextNode) => nextNodeIDs.has(nextNode.id));
1706
1986
  const skipNodes = allNextNodes.filter((nextNode) => !nextNodeIDs.has(nextNode.id));
1707
- skipNodes.forEach((skipNode) => {
1708
- context.state.addExecutedNode(skipNode);
1987
+ const nextGroups = nextNodes.map((nextNode) => [nextNode, ...nextNode.successors]);
1988
+ const skipGroups = skipNodes.map((skipNode) => [skipNode, ...skipNode.successors]);
1989
+ const { uniqueToB: skippedNodes } = compareNodeGroups(nextGroups, skipGroups);
1990
+ skippedNodes.forEach((node2) => {
1991
+ context.state.addExecutedNode(node2);
1709
1992
  });
1710
1993
  return nextNodes;
1711
1994
  }