@flowgram.ai/runtime-js 0.2.25 → 0.2.27
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 +308 -32
- package/dist/esm/index.js.map +1 -1
- package/dist/index.js +308 -32
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -345,7 +345,7 @@ var WorkflowRuntimeType;
|
|
|
345
345
|
const expectedType = types[0];
|
|
346
346
|
types.forEach((type) => {
|
|
347
347
|
if (type !== expectedType) {
|
|
348
|
-
throw new Error(`
|
|
348
|
+
throw new Error(`Array items type must be same, expect ${expectedType}, but got ${type}`);
|
|
349
349
|
}
|
|
350
350
|
});
|
|
351
351
|
return expectedType;
|
|
@@ -503,8 +503,8 @@ var validateObject = (value, schema, path) => {
|
|
|
503
503
|
}
|
|
504
504
|
}
|
|
505
505
|
if (schema.properties) {
|
|
506
|
-
for (const [propertyName
|
|
507
|
-
const isRequired =
|
|
506
|
+
for (const [propertyName] of Object.entries(schema.properties)) {
|
|
507
|
+
const isRequired = schema.required?.includes(propertyName) ?? false;
|
|
508
508
|
if (isRequired && !(propertyName in objectValue)) {
|
|
509
509
|
return {
|
|
510
510
|
result: false,
|
|
@@ -614,7 +614,7 @@ var LoopExecutor = class {
|
|
|
614
614
|
const subNodes = context.node.children;
|
|
615
615
|
const blockStartNode = subNodes.find((node) => node.type === FlowGramNode.BlockStart);
|
|
616
616
|
if (!blockStartNode) {
|
|
617
|
-
throw new Error("block start node not found");
|
|
617
|
+
throw new Error("Loop block start node not found");
|
|
618
618
|
}
|
|
619
619
|
const blockOutputs = [];
|
|
620
620
|
for (let index = 0; index < loopArray.length; index++) {
|
|
@@ -632,10 +632,14 @@ var LoopExecutor = class {
|
|
|
632
632
|
type: WorkflowVariableType.Number,
|
|
633
633
|
value: index
|
|
634
634
|
});
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
635
|
+
try {
|
|
636
|
+
await engine.executeNode({
|
|
637
|
+
context: subContext,
|
|
638
|
+
node: blockStartNode
|
|
639
|
+
});
|
|
640
|
+
} catch (e) {
|
|
641
|
+
throw new Error(`Loop block execute error`);
|
|
642
|
+
}
|
|
639
643
|
const blockOutput = this.getBlockOutput(context, subContext);
|
|
640
644
|
blockOutputs.push(blockOutput);
|
|
641
645
|
}
|
|
@@ -656,15 +660,15 @@ var LoopExecutor = class {
|
|
|
656
660
|
checkLoopArray(LoopArrayVariable) {
|
|
657
661
|
const loopArray = LoopArrayVariable?.value;
|
|
658
662
|
if (!loopArray || (0, import_lodash_es.isNil)(loopArray) || !Array.isArray(loopArray)) {
|
|
659
|
-
throw new Error("loopFor is required
|
|
663
|
+
throw new Error('Loop "loopFor" is required');
|
|
660
664
|
}
|
|
661
665
|
const loopArrayType = LoopArrayVariable.type;
|
|
662
666
|
if (loopArrayType !== WorkflowVariableType.Array) {
|
|
663
|
-
throw new Error("loopFor must be an array
|
|
667
|
+
throw new Error('Loop "loopFor" must be an array');
|
|
664
668
|
}
|
|
665
669
|
const loopArrayItemType = LoopArrayVariable.itemsType;
|
|
666
670
|
if ((0, import_lodash_es.isNil)(loopArrayItemType)) {
|
|
667
|
-
throw new Error("loopFor
|
|
671
|
+
throw new Error('Loop "loopFor.items" must be array items');
|
|
668
672
|
}
|
|
669
673
|
}
|
|
670
674
|
getBlockOutput(executionContext, subContext) {
|
|
@@ -739,14 +743,24 @@ var LLMExecutor = class {
|
|
|
739
743
|
apiKey,
|
|
740
744
|
configuration: {
|
|
741
745
|
baseURL: apiHost
|
|
742
|
-
}
|
|
746
|
+
},
|
|
747
|
+
maxRetries: 3
|
|
743
748
|
});
|
|
744
749
|
const messages = [];
|
|
745
750
|
if (systemPrompt) {
|
|
746
751
|
messages.push(new import_messages.SystemMessage(systemPrompt));
|
|
747
752
|
}
|
|
748
753
|
messages.push(new import_messages.HumanMessage(prompt));
|
|
749
|
-
|
|
754
|
+
let apiMessage;
|
|
755
|
+
try {
|
|
756
|
+
apiMessage = await model.invoke(messages);
|
|
757
|
+
} catch (error) {
|
|
758
|
+
const errorMessage = error?.message;
|
|
759
|
+
if (errorMessage === "Connection error.") {
|
|
760
|
+
throw new Error(`Network error: unreachable api "${apiHost}"`);
|
|
761
|
+
}
|
|
762
|
+
throw error;
|
|
763
|
+
}
|
|
750
764
|
const result = apiMessage.content;
|
|
751
765
|
return {
|
|
752
766
|
outputs: {
|
|
@@ -757,13 +771,23 @@ var LLMExecutor = class {
|
|
|
757
771
|
checkInputs(inputs) {
|
|
758
772
|
const { modelName, temperature, apiKey, apiHost, prompt } = inputs;
|
|
759
773
|
const missingInputs = [];
|
|
760
|
-
if (
|
|
774
|
+
if (!modelName) missingInputs.push("modelName");
|
|
761
775
|
if ((0, import_lodash_es2.isNil)(temperature)) missingInputs.push("temperature");
|
|
762
|
-
if (
|
|
763
|
-
if (
|
|
764
|
-
if (
|
|
776
|
+
if (!apiKey) missingInputs.push("apiKey");
|
|
777
|
+
if (!apiHost) missingInputs.push("apiHost");
|
|
778
|
+
if (!prompt) missingInputs.push("prompt");
|
|
765
779
|
if (missingInputs.length > 0) {
|
|
766
|
-
throw new Error(`LLM node missing required inputs: ${missingInputs.join(", ")}`);
|
|
780
|
+
throw new Error(`LLM node missing required inputs: "${missingInputs.join('", "')}"`);
|
|
781
|
+
}
|
|
782
|
+
this.checkApiHost(apiHost);
|
|
783
|
+
}
|
|
784
|
+
checkApiHost(apiHost) {
|
|
785
|
+
if (!apiHost || typeof apiHost !== "string") {
|
|
786
|
+
throw new Error(`Invalid API host format - ${apiHost}`);
|
|
787
|
+
}
|
|
788
|
+
const url = new URL(apiHost);
|
|
789
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") {
|
|
790
|
+
throw new Error(`Invalid API host protocol - ${url.protocol}`);
|
|
767
791
|
}
|
|
768
792
|
}
|
|
769
793
|
};
|
|
@@ -1058,7 +1082,7 @@ var ConditionExecutor = class {
|
|
|
1058
1082
|
const parsedConditions = conditions.map((item) => this.parseCondition(item, context)).filter((item) => this.checkCondition(item));
|
|
1059
1083
|
const activatedCondition = parsedConditions.find((item) => this.handleCondition(item));
|
|
1060
1084
|
if (!activatedCondition) {
|
|
1061
|
-
throw new Error("
|
|
1085
|
+
throw new Error("No condition is activated");
|
|
1062
1086
|
}
|
|
1063
1087
|
return {
|
|
1064
1088
|
outputs: {},
|
|
@@ -1086,11 +1110,13 @@ var ConditionExecutor = class {
|
|
|
1086
1110
|
checkCondition(condition) {
|
|
1087
1111
|
const rule = conditionRules[condition.leftType];
|
|
1088
1112
|
if ((0, import_lodash_es9.isNil)(rule)) {
|
|
1089
|
-
throw new Error(`
|
|
1113
|
+
throw new Error(`Condition left type "${condition.leftType}" is not supported`);
|
|
1090
1114
|
}
|
|
1091
1115
|
const ruleType = rule[condition.operator];
|
|
1092
1116
|
if ((0, import_lodash_es9.isNil)(ruleType)) {
|
|
1093
|
-
throw new Error(
|
|
1117
|
+
throw new Error(
|
|
1118
|
+
`Condition left type "${condition.leftType}" has no operator "${condition.operator}"`
|
|
1119
|
+
);
|
|
1094
1120
|
}
|
|
1095
1121
|
if (ruleType !== condition.rightType) {
|
|
1096
1122
|
return false;
|
|
@@ -1100,7 +1126,7 @@ var ConditionExecutor = class {
|
|
|
1100
1126
|
handleCondition(condition) {
|
|
1101
1127
|
const handler = conditionHandlers[condition.leftType];
|
|
1102
1128
|
if (!handler) {
|
|
1103
|
-
throw new Error(`
|
|
1129
|
+
throw new Error(`Condition left type ${condition.leftType} is not supported`);
|
|
1104
1130
|
}
|
|
1105
1131
|
const isActive = handler(condition);
|
|
1106
1132
|
return isActive;
|
|
@@ -1118,6 +1144,241 @@ var WorkflowRuntimeNodeExecutors = [
|
|
|
1118
1144
|
BlockEndExecutor
|
|
1119
1145
|
];
|
|
1120
1146
|
|
|
1147
|
+
// src/domain/validation/validators/cycle-detection.ts
|
|
1148
|
+
var cycleDetection = (schema) => {
|
|
1149
|
+
const { nodes, edges } = schema;
|
|
1150
|
+
const adjacencyList = /* @__PURE__ */ new Map();
|
|
1151
|
+
const nodeIds = new Set(nodes.map((node) => node.id));
|
|
1152
|
+
nodeIds.forEach((nodeId) => {
|
|
1153
|
+
adjacencyList.set(nodeId, []);
|
|
1154
|
+
});
|
|
1155
|
+
edges.forEach((edge) => {
|
|
1156
|
+
const sourceList = adjacencyList.get(edge.sourceNodeID);
|
|
1157
|
+
if (sourceList) {
|
|
1158
|
+
sourceList.push(edge.targetNodeID);
|
|
1159
|
+
}
|
|
1160
|
+
});
|
|
1161
|
+
let NodeStatus;
|
|
1162
|
+
((NodeStatus2) => {
|
|
1163
|
+
NodeStatus2[NodeStatus2["Unvisited"] = 0] = "Unvisited";
|
|
1164
|
+
NodeStatus2[NodeStatus2["Visiting"] = 1] = "Visiting";
|
|
1165
|
+
NodeStatus2[NodeStatus2["Visited"] = 2] = "Visited";
|
|
1166
|
+
})(NodeStatus || (NodeStatus = {}));
|
|
1167
|
+
const nodeStatusMap = /* @__PURE__ */ new Map();
|
|
1168
|
+
nodeIds.forEach((nodeId) => {
|
|
1169
|
+
nodeStatusMap.set(nodeId, 0 /* Unvisited */);
|
|
1170
|
+
});
|
|
1171
|
+
const detectCycleFromNode = (nodeId) => {
|
|
1172
|
+
nodeStatusMap.set(nodeId, 1 /* Visiting */);
|
|
1173
|
+
const neighbors = adjacencyList.get(nodeId) || [];
|
|
1174
|
+
for (const neighbor of neighbors) {
|
|
1175
|
+
const neighborColor = nodeStatusMap.get(neighbor);
|
|
1176
|
+
if (neighborColor === 1 /* Visiting */) {
|
|
1177
|
+
return true;
|
|
1178
|
+
}
|
|
1179
|
+
if (neighborColor === 0 /* Unvisited */ && detectCycleFromNode(neighbor)) {
|
|
1180
|
+
return true;
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
nodeStatusMap.set(nodeId, 2 /* Visited */);
|
|
1184
|
+
return false;
|
|
1185
|
+
};
|
|
1186
|
+
for (const nodeId of nodeIds) {
|
|
1187
|
+
if (nodeStatusMap.get(nodeId) === 0 /* Unvisited */) {
|
|
1188
|
+
if (detectCycleFromNode(nodeId)) {
|
|
1189
|
+
throw new Error("Workflow schema contains a cycle, which is not allowed");
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1192
|
+
}
|
|
1193
|
+
nodes.forEach((node) => {
|
|
1194
|
+
if (node.blocks) {
|
|
1195
|
+
cycleDetection({
|
|
1196
|
+
nodes: node.blocks,
|
|
1197
|
+
edges: node.edges ?? []
|
|
1198
|
+
});
|
|
1199
|
+
}
|
|
1200
|
+
});
|
|
1201
|
+
};
|
|
1202
|
+
|
|
1203
|
+
// src/domain/validation/validators/start-end-node.ts
|
|
1204
|
+
var blockStartEndNode = (schema) => {
|
|
1205
|
+
const { blockStartNodes, blockEndNodes } = schema.nodes.reduce(
|
|
1206
|
+
(acc, node) => {
|
|
1207
|
+
if (node.type === FlowGramNode.BlockStart) {
|
|
1208
|
+
acc.blockStartNodes.push(node);
|
|
1209
|
+
} else if (node.type === FlowGramNode.BlockEnd) {
|
|
1210
|
+
acc.blockEndNodes.push(node);
|
|
1211
|
+
}
|
|
1212
|
+
return acc;
|
|
1213
|
+
},
|
|
1214
|
+
{ blockStartNodes: [], blockEndNodes: [] }
|
|
1215
|
+
);
|
|
1216
|
+
if (!blockStartNodes.length && !blockEndNodes.length) {
|
|
1217
|
+
throw new Error("Workflow block schema must have a block-start node and a block-end node");
|
|
1218
|
+
}
|
|
1219
|
+
if (!blockStartNodes.length) {
|
|
1220
|
+
throw new Error("Workflow block schema must have a block-start node");
|
|
1221
|
+
}
|
|
1222
|
+
if (!blockEndNodes.length) {
|
|
1223
|
+
throw new Error("Workflow block schema must have an block-end node");
|
|
1224
|
+
}
|
|
1225
|
+
if (blockStartNodes.length > 1) {
|
|
1226
|
+
throw new Error("Workflow block schema must have only one block-start node");
|
|
1227
|
+
}
|
|
1228
|
+
if (blockEndNodes.length > 1) {
|
|
1229
|
+
throw new Error("Workflow block schema must have only one block-end node");
|
|
1230
|
+
}
|
|
1231
|
+
schema.nodes.forEach((node) => {
|
|
1232
|
+
if (node.blocks) {
|
|
1233
|
+
blockStartEndNode({
|
|
1234
|
+
nodes: node.blocks,
|
|
1235
|
+
edges: node.edges ?? []
|
|
1236
|
+
});
|
|
1237
|
+
}
|
|
1238
|
+
});
|
|
1239
|
+
};
|
|
1240
|
+
var startEndNode = (schema) => {
|
|
1241
|
+
const { startNodes, endNodes } = schema.nodes.reduce(
|
|
1242
|
+
(acc, node) => {
|
|
1243
|
+
if (node.type === FlowGramNode.Start) {
|
|
1244
|
+
acc.startNodes.push(node);
|
|
1245
|
+
} else if (node.type === FlowGramNode.End) {
|
|
1246
|
+
acc.endNodes.push(node);
|
|
1247
|
+
}
|
|
1248
|
+
return acc;
|
|
1249
|
+
},
|
|
1250
|
+
{ startNodes: [], endNodes: [] }
|
|
1251
|
+
);
|
|
1252
|
+
if (!startNodes.length && !endNodes.length) {
|
|
1253
|
+
throw new Error("Workflow schema must have a start node and an end node");
|
|
1254
|
+
}
|
|
1255
|
+
if (!startNodes.length) {
|
|
1256
|
+
throw new Error("Workflow schema must have a start node");
|
|
1257
|
+
}
|
|
1258
|
+
if (!endNodes.length) {
|
|
1259
|
+
throw new Error("Workflow schema must have an end node");
|
|
1260
|
+
}
|
|
1261
|
+
if (startNodes.length > 1) {
|
|
1262
|
+
throw new Error("Workflow schema must have only one start node");
|
|
1263
|
+
}
|
|
1264
|
+
if (endNodes.length > 1) {
|
|
1265
|
+
throw new Error("Workflow schema must have only one end node");
|
|
1266
|
+
}
|
|
1267
|
+
schema.nodes.forEach((node) => {
|
|
1268
|
+
if (node.blocks) {
|
|
1269
|
+
blockStartEndNode({
|
|
1270
|
+
nodes: node.blocks,
|
|
1271
|
+
edges: node.edges ?? []
|
|
1272
|
+
});
|
|
1273
|
+
}
|
|
1274
|
+
});
|
|
1275
|
+
};
|
|
1276
|
+
|
|
1277
|
+
// src/domain/validation/validators/edge-source-target-exist.ts
|
|
1278
|
+
var edgeSourceTargetExist = (schema) => {
|
|
1279
|
+
const { nodes, edges } = schema;
|
|
1280
|
+
const nodeSet = new Set(nodes.map((node) => node.id));
|
|
1281
|
+
edges.forEach((edge) => {
|
|
1282
|
+
if (!nodeSet.has(edge.sourceNodeID)) {
|
|
1283
|
+
throw new Error(`Workflow schema edge source node "${edge.sourceNodeID}" not exist`);
|
|
1284
|
+
}
|
|
1285
|
+
if (!nodeSet.has(edge.targetNodeID)) {
|
|
1286
|
+
throw new Error(`Workflow schema edge target node "${edge.targetNodeID}" not exist`);
|
|
1287
|
+
}
|
|
1288
|
+
});
|
|
1289
|
+
nodes.forEach((node) => {
|
|
1290
|
+
if (node.blocks) {
|
|
1291
|
+
edgeSourceTargetExist({
|
|
1292
|
+
nodes: node.blocks,
|
|
1293
|
+
edges: node.edges ?? []
|
|
1294
|
+
});
|
|
1295
|
+
}
|
|
1296
|
+
});
|
|
1297
|
+
};
|
|
1298
|
+
|
|
1299
|
+
// src/domain/validation/validators/schema-format.ts
|
|
1300
|
+
var schemaFormat = (schema) => {
|
|
1301
|
+
if (!schema || typeof schema !== "object") {
|
|
1302
|
+
throw new Error("Workflow schema must be a valid object");
|
|
1303
|
+
}
|
|
1304
|
+
if (!Array.isArray(schema.nodes)) {
|
|
1305
|
+
throw new Error("Workflow schema must have a valid nodes array");
|
|
1306
|
+
}
|
|
1307
|
+
if (!Array.isArray(schema.edges)) {
|
|
1308
|
+
throw new Error("Workflow schema must have a valid edges array");
|
|
1309
|
+
}
|
|
1310
|
+
schema.nodes.forEach((node, index) => {
|
|
1311
|
+
validateNodeFormat(node, `nodes[${index}]`);
|
|
1312
|
+
});
|
|
1313
|
+
schema.edges.forEach((edge, index) => {
|
|
1314
|
+
validateEdgeFormat(edge, `edges[${index}]`);
|
|
1315
|
+
});
|
|
1316
|
+
schema.nodes.forEach((node, nodeIndex) => {
|
|
1317
|
+
if (node.blocks) {
|
|
1318
|
+
if (!Array.isArray(node.blocks)) {
|
|
1319
|
+
throw new Error(`Node nodes[${nodeIndex}].blocks must be an array`);
|
|
1320
|
+
}
|
|
1321
|
+
const nestedSchema = {
|
|
1322
|
+
nodes: node.blocks,
|
|
1323
|
+
edges: node.edges || []
|
|
1324
|
+
};
|
|
1325
|
+
schemaFormat(nestedSchema);
|
|
1326
|
+
}
|
|
1327
|
+
});
|
|
1328
|
+
};
|
|
1329
|
+
var validateNodeFormat = (node, path) => {
|
|
1330
|
+
if (!node || typeof node !== "object") {
|
|
1331
|
+
throw new Error(`${path} must be a valid object`);
|
|
1332
|
+
}
|
|
1333
|
+
if (typeof node.id !== "string" || !node.id.trim()) {
|
|
1334
|
+
throw new Error(`${path}.id must be a non-empty string`);
|
|
1335
|
+
}
|
|
1336
|
+
if (typeof node.type !== "string" || !node.type.trim()) {
|
|
1337
|
+
throw new Error(`${path}.type must be a non-empty string`);
|
|
1338
|
+
}
|
|
1339
|
+
if (!node.meta || typeof node.meta !== "object") {
|
|
1340
|
+
throw new Error(`${path}.meta must be a valid object`);
|
|
1341
|
+
}
|
|
1342
|
+
if (!node.data || typeof node.data !== "object") {
|
|
1343
|
+
throw new Error(`${path}.data must be a valid object`);
|
|
1344
|
+
}
|
|
1345
|
+
if (node.blocks !== void 0 && !Array.isArray(node.blocks)) {
|
|
1346
|
+
throw new Error(`${path}.blocks must be an array if present`);
|
|
1347
|
+
}
|
|
1348
|
+
if (node.edges !== void 0 && !Array.isArray(node.edges)) {
|
|
1349
|
+
throw new Error(`${path}.edges must be an array if present`);
|
|
1350
|
+
}
|
|
1351
|
+
if (node.data.inputs !== void 0 && (typeof node.data.inputs !== "object" || node.data.inputs === null)) {
|
|
1352
|
+
throw new Error(`${path}.data.inputs must be a valid object if present`);
|
|
1353
|
+
}
|
|
1354
|
+
if (node.data.outputs !== void 0 && (typeof node.data.outputs !== "object" || node.data.outputs === null)) {
|
|
1355
|
+
throw new Error(`${path}.data.outputs must be a valid object if present`);
|
|
1356
|
+
}
|
|
1357
|
+
if (node.data.inputsValues !== void 0 && (typeof node.data.inputsValues !== "object" || node.data.inputsValues === null)) {
|
|
1358
|
+
throw new Error(`${path}.data.inputsValues must be a valid object if present`);
|
|
1359
|
+
}
|
|
1360
|
+
if (node.data.title !== void 0 && typeof node.data.title !== "string") {
|
|
1361
|
+
throw new Error(`${path}.data.title must be a string if present`);
|
|
1362
|
+
}
|
|
1363
|
+
};
|
|
1364
|
+
var validateEdgeFormat = (edge, path) => {
|
|
1365
|
+
if (!edge || typeof edge !== "object") {
|
|
1366
|
+
throw new Error(`${path} must be a valid object`);
|
|
1367
|
+
}
|
|
1368
|
+
if (typeof edge.sourceNodeID !== "string" || !edge.sourceNodeID.trim()) {
|
|
1369
|
+
throw new Error(`${path}.sourceNodeID must be a non-empty string`);
|
|
1370
|
+
}
|
|
1371
|
+
if (typeof edge.targetNodeID !== "string" || !edge.targetNodeID.trim()) {
|
|
1372
|
+
throw new Error(`${path}.targetNodeID must be a non-empty string`);
|
|
1373
|
+
}
|
|
1374
|
+
if (edge.sourcePortID !== void 0 && typeof edge.sourcePortID !== "string") {
|
|
1375
|
+
throw new Error(`${path}.sourcePortID must be a string if present`);
|
|
1376
|
+
}
|
|
1377
|
+
if (edge.targetPortID !== void 0 && typeof edge.targetPortID !== "string") {
|
|
1378
|
+
throw new Error(`${path}.targetPortID must be a string if present`);
|
|
1379
|
+
}
|
|
1380
|
+
};
|
|
1381
|
+
|
|
1121
1382
|
// src/domain/validation/index.ts
|
|
1122
1383
|
var WorkflowRuntimeValidation = class {
|
|
1123
1384
|
invoke(params) {
|
|
@@ -1135,8 +1396,23 @@ var WorkflowRuntimeValidation = class {
|
|
|
1135
1396
|
};
|
|
1136
1397
|
}
|
|
1137
1398
|
schema(schema) {
|
|
1399
|
+
const errors = [];
|
|
1400
|
+
const validations = [
|
|
1401
|
+
() => schemaFormat(schema),
|
|
1402
|
+
() => cycleDetection(schema),
|
|
1403
|
+
() => edgeSourceTargetExist(schema),
|
|
1404
|
+
() => startEndNode(schema)
|
|
1405
|
+
];
|
|
1406
|
+
validations.forEach((validation) => {
|
|
1407
|
+
try {
|
|
1408
|
+
validation();
|
|
1409
|
+
} catch (error) {
|
|
1410
|
+
errors.push(error instanceof Error ? error.message : String(error));
|
|
1411
|
+
}
|
|
1412
|
+
});
|
|
1138
1413
|
return {
|
|
1139
|
-
valid:
|
|
1414
|
+
valid: errors.length === 0,
|
|
1415
|
+
errors: errors.length > 0 ? errors : void 0
|
|
1140
1416
|
};
|
|
1141
1417
|
}
|
|
1142
1418
|
inputs(inputsSchema, inputs) {
|
|
@@ -1179,7 +1455,7 @@ var WorkflowRuntimeExecutor = class {
|
|
|
1179
1455
|
const nodeType = context.node.type;
|
|
1180
1456
|
const nodeExecutor = this.nodeExecutors.get(nodeType);
|
|
1181
1457
|
if (!nodeExecutor) {
|
|
1182
|
-
throw new Error(`
|
|
1458
|
+
throw new Error(`No executor found for node type ${nodeType}`);
|
|
1183
1459
|
}
|
|
1184
1460
|
const output = await nodeExecutor.execute(context);
|
|
1185
1461
|
return output;
|
|
@@ -1554,7 +1830,7 @@ var WorkflowRuntimeState = class {
|
|
|
1554
1830
|
}
|
|
1555
1831
|
parseRef(ref) {
|
|
1556
1832
|
if (ref?.type !== "ref") {
|
|
1557
|
-
throw new Error(`
|
|
1833
|
+
throw new Error(`Invalid ref value: ${ref}`);
|
|
1558
1834
|
}
|
|
1559
1835
|
if (!ref.content || ref.content.length < 2) {
|
|
1560
1836
|
return null;
|
|
@@ -1572,7 +1848,7 @@ var WorkflowRuntimeState = class {
|
|
|
1572
1848
|
}
|
|
1573
1849
|
parseTemplate(template) {
|
|
1574
1850
|
if (template?.type !== "template") {
|
|
1575
|
-
throw new Error(`
|
|
1851
|
+
throw new Error(`Invalid template value: ${template}`);
|
|
1576
1852
|
}
|
|
1577
1853
|
if (!template.content) {
|
|
1578
1854
|
return null;
|
|
@@ -1598,7 +1874,7 @@ var WorkflowRuntimeState = class {
|
|
|
1598
1874
|
}
|
|
1599
1875
|
parseValue(flowValue) {
|
|
1600
1876
|
if (!flowValue?.type) {
|
|
1601
|
-
throw new Error(`
|
|
1877
|
+
throw new Error(`Invalid flow value type: ${flowValue.type}`);
|
|
1602
1878
|
}
|
|
1603
1879
|
if (flowValue.type === "constant") {
|
|
1604
1880
|
const value = flowValue.content;
|
|
@@ -1617,7 +1893,7 @@ var WorkflowRuntimeState = class {
|
|
|
1617
1893
|
if (flowValue.type === "template") {
|
|
1618
1894
|
return this.parseTemplate(flowValue);
|
|
1619
1895
|
}
|
|
1620
|
-
throw new Error(`
|
|
1896
|
+
throw new Error(`Unknown flow value type: ${flowValue.type}`);
|
|
1621
1897
|
}
|
|
1622
1898
|
isExecutedNode(node) {
|
|
1623
1899
|
return this.executedNodes.has(node.id);
|
|
@@ -2002,7 +2278,7 @@ var createStore = (params) => {
|
|
|
2002
2278
|
const from = store.nodes.get(sourceNodeID);
|
|
2003
2279
|
const to = store.nodes.get(targetNodeID);
|
|
2004
2280
|
if (!from || !to) {
|
|
2005
|
-
throw new Error(`
|
|
2281
|
+
throw new Error(`Invalid edge schema ID: ${id}, from: ${sourceNodeID}, to: ${targetNodeID}`);
|
|
2006
2282
|
}
|
|
2007
2283
|
const edge = createEdge(store, {
|
|
2008
2284
|
id,
|
|
@@ -2277,7 +2553,7 @@ var WorkflowRuntimeEngine = class {
|
|
|
2277
2553
|
}
|
|
2278
2554
|
const targetPort = node.ports.outputs.find((port) => port.id === branch);
|
|
2279
2555
|
if (!targetPort) {
|
|
2280
|
-
throw new Error(`branch ${branch} not found`);
|
|
2556
|
+
throw new Error(`Engine branch ${branch} not found`);
|
|
2281
2557
|
}
|
|
2282
2558
|
const nextNodeIDs = new Set(targetPort.edges.map((edge) => edge.to.id));
|
|
2283
2559
|
const nextNodes = allNextNodes.filter((nextNode) => nextNodeIDs.has(nextNode.id));
|
|
@@ -2292,11 +2568,11 @@ var WorkflowRuntimeEngine = class {
|
|
|
2292
2568
|
}
|
|
2293
2569
|
async executeNext(params) {
|
|
2294
2570
|
const { context, node, nextNodes } = params;
|
|
2295
|
-
if (node.type === FlowGramNode.End) {
|
|
2571
|
+
if (node.type === FlowGramNode.End || node.type === FlowGramNode.BlockEnd) {
|
|
2296
2572
|
return;
|
|
2297
2573
|
}
|
|
2298
2574
|
if (nextNodes.length === 0) {
|
|
2299
|
-
|
|
2575
|
+
throw new Error(`Node ${node.id} has no next nodes`);
|
|
2300
2576
|
}
|
|
2301
2577
|
await Promise.all(
|
|
2302
2578
|
nextNodes.map(
|