@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/esm/index.js
CHANGED
|
@@ -304,7 +304,7 @@ var WorkflowRuntimeType;
|
|
|
304
304
|
const expectedType = types[0];
|
|
305
305
|
types.forEach((type) => {
|
|
306
306
|
if (type !== expectedType) {
|
|
307
|
-
throw new Error(`
|
|
307
|
+
throw new Error(`Array items type must be same, expect ${expectedType}, but got ${type}`);
|
|
308
308
|
}
|
|
309
309
|
});
|
|
310
310
|
return expectedType;
|
|
@@ -462,8 +462,8 @@ var validateObject = (value, schema, path) => {
|
|
|
462
462
|
}
|
|
463
463
|
}
|
|
464
464
|
if (schema.properties) {
|
|
465
|
-
for (const [propertyName
|
|
466
|
-
const isRequired =
|
|
465
|
+
for (const [propertyName] of Object.entries(schema.properties)) {
|
|
466
|
+
const isRequired = schema.required?.includes(propertyName) ?? false;
|
|
467
467
|
if (isRequired && !(propertyName in objectValue)) {
|
|
468
468
|
return {
|
|
469
469
|
result: false,
|
|
@@ -573,7 +573,7 @@ var LoopExecutor = class {
|
|
|
573
573
|
const subNodes = context.node.children;
|
|
574
574
|
const blockStartNode = subNodes.find((node) => node.type === FlowGramNode.BlockStart);
|
|
575
575
|
if (!blockStartNode) {
|
|
576
|
-
throw new Error("block start node not found");
|
|
576
|
+
throw new Error("Loop block start node not found");
|
|
577
577
|
}
|
|
578
578
|
const blockOutputs = [];
|
|
579
579
|
for (let index = 0; index < loopArray.length; index++) {
|
|
@@ -591,10 +591,14 @@ var LoopExecutor = class {
|
|
|
591
591
|
type: WorkflowVariableType.Number,
|
|
592
592
|
value: index
|
|
593
593
|
});
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
594
|
+
try {
|
|
595
|
+
await engine.executeNode({
|
|
596
|
+
context: subContext,
|
|
597
|
+
node: blockStartNode
|
|
598
|
+
});
|
|
599
|
+
} catch (e) {
|
|
600
|
+
throw new Error(`Loop block execute error`);
|
|
601
|
+
}
|
|
598
602
|
const blockOutput = this.getBlockOutput(context, subContext);
|
|
599
603
|
blockOutputs.push(blockOutput);
|
|
600
604
|
}
|
|
@@ -615,15 +619,15 @@ var LoopExecutor = class {
|
|
|
615
619
|
checkLoopArray(LoopArrayVariable) {
|
|
616
620
|
const loopArray = LoopArrayVariable?.value;
|
|
617
621
|
if (!loopArray || isNil(loopArray) || !Array.isArray(loopArray)) {
|
|
618
|
-
throw new Error("loopFor is required
|
|
622
|
+
throw new Error('Loop "loopFor" is required');
|
|
619
623
|
}
|
|
620
624
|
const loopArrayType = LoopArrayVariable.type;
|
|
621
625
|
if (loopArrayType !== WorkflowVariableType.Array) {
|
|
622
|
-
throw new Error("loopFor must be an array
|
|
626
|
+
throw new Error('Loop "loopFor" must be an array');
|
|
623
627
|
}
|
|
624
628
|
const loopArrayItemType = LoopArrayVariable.itemsType;
|
|
625
629
|
if (isNil(loopArrayItemType)) {
|
|
626
|
-
throw new Error("loopFor
|
|
630
|
+
throw new Error('Loop "loopFor.items" must be array items');
|
|
627
631
|
}
|
|
628
632
|
}
|
|
629
633
|
getBlockOutput(executionContext, subContext) {
|
|
@@ -698,14 +702,24 @@ var LLMExecutor = class {
|
|
|
698
702
|
apiKey,
|
|
699
703
|
configuration: {
|
|
700
704
|
baseURL: apiHost
|
|
701
|
-
}
|
|
705
|
+
},
|
|
706
|
+
maxRetries: 3
|
|
702
707
|
});
|
|
703
708
|
const messages = [];
|
|
704
709
|
if (systemPrompt) {
|
|
705
710
|
messages.push(new SystemMessage(systemPrompt));
|
|
706
711
|
}
|
|
707
712
|
messages.push(new HumanMessage(prompt));
|
|
708
|
-
|
|
713
|
+
let apiMessage;
|
|
714
|
+
try {
|
|
715
|
+
apiMessage = await model.invoke(messages);
|
|
716
|
+
} catch (error) {
|
|
717
|
+
const errorMessage = error?.message;
|
|
718
|
+
if (errorMessage === "Connection error.") {
|
|
719
|
+
throw new Error(`Network error: unreachable api "${apiHost}"`);
|
|
720
|
+
}
|
|
721
|
+
throw error;
|
|
722
|
+
}
|
|
709
723
|
const result = apiMessage.content;
|
|
710
724
|
return {
|
|
711
725
|
outputs: {
|
|
@@ -716,13 +730,23 @@ var LLMExecutor = class {
|
|
|
716
730
|
checkInputs(inputs) {
|
|
717
731
|
const { modelName, temperature, apiKey, apiHost, prompt } = inputs;
|
|
718
732
|
const missingInputs = [];
|
|
719
|
-
if (
|
|
733
|
+
if (!modelName) missingInputs.push("modelName");
|
|
720
734
|
if (isNil2(temperature)) missingInputs.push("temperature");
|
|
721
|
-
if (
|
|
722
|
-
if (
|
|
723
|
-
if (
|
|
735
|
+
if (!apiKey) missingInputs.push("apiKey");
|
|
736
|
+
if (!apiHost) missingInputs.push("apiHost");
|
|
737
|
+
if (!prompt) missingInputs.push("prompt");
|
|
724
738
|
if (missingInputs.length > 0) {
|
|
725
|
-
throw new Error(`LLM node missing required inputs: ${missingInputs.join(", ")}`);
|
|
739
|
+
throw new Error(`LLM node missing required inputs: "${missingInputs.join('", "')}"`);
|
|
740
|
+
}
|
|
741
|
+
this.checkApiHost(apiHost);
|
|
742
|
+
}
|
|
743
|
+
checkApiHost(apiHost) {
|
|
744
|
+
if (!apiHost || typeof apiHost !== "string") {
|
|
745
|
+
throw new Error(`Invalid API host format - ${apiHost}`);
|
|
746
|
+
}
|
|
747
|
+
const url = new URL(apiHost);
|
|
748
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") {
|
|
749
|
+
throw new Error(`Invalid API host protocol - ${url.protocol}`);
|
|
726
750
|
}
|
|
727
751
|
}
|
|
728
752
|
};
|
|
@@ -1017,7 +1041,7 @@ var ConditionExecutor = class {
|
|
|
1017
1041
|
const parsedConditions = conditions.map((item) => this.parseCondition(item, context)).filter((item) => this.checkCondition(item));
|
|
1018
1042
|
const activatedCondition = parsedConditions.find((item) => this.handleCondition(item));
|
|
1019
1043
|
if (!activatedCondition) {
|
|
1020
|
-
throw new Error("
|
|
1044
|
+
throw new Error("No condition is activated");
|
|
1021
1045
|
}
|
|
1022
1046
|
return {
|
|
1023
1047
|
outputs: {},
|
|
@@ -1045,11 +1069,13 @@ var ConditionExecutor = class {
|
|
|
1045
1069
|
checkCondition(condition) {
|
|
1046
1070
|
const rule = conditionRules[condition.leftType];
|
|
1047
1071
|
if (isNil9(rule)) {
|
|
1048
|
-
throw new Error(`
|
|
1072
|
+
throw new Error(`Condition left type "${condition.leftType}" is not supported`);
|
|
1049
1073
|
}
|
|
1050
1074
|
const ruleType = rule[condition.operator];
|
|
1051
1075
|
if (isNil9(ruleType)) {
|
|
1052
|
-
throw new Error(
|
|
1076
|
+
throw new Error(
|
|
1077
|
+
`Condition left type "${condition.leftType}" has no operator "${condition.operator}"`
|
|
1078
|
+
);
|
|
1053
1079
|
}
|
|
1054
1080
|
if (ruleType !== condition.rightType) {
|
|
1055
1081
|
return false;
|
|
@@ -1059,7 +1085,7 @@ var ConditionExecutor = class {
|
|
|
1059
1085
|
handleCondition(condition) {
|
|
1060
1086
|
const handler = conditionHandlers[condition.leftType];
|
|
1061
1087
|
if (!handler) {
|
|
1062
|
-
throw new Error(`
|
|
1088
|
+
throw new Error(`Condition left type ${condition.leftType} is not supported`);
|
|
1063
1089
|
}
|
|
1064
1090
|
const isActive = handler(condition);
|
|
1065
1091
|
return isActive;
|
|
@@ -1077,6 +1103,241 @@ var WorkflowRuntimeNodeExecutors = [
|
|
|
1077
1103
|
BlockEndExecutor
|
|
1078
1104
|
];
|
|
1079
1105
|
|
|
1106
|
+
// src/domain/validation/validators/cycle-detection.ts
|
|
1107
|
+
var cycleDetection = (schema) => {
|
|
1108
|
+
const { nodes, edges } = schema;
|
|
1109
|
+
const adjacencyList = /* @__PURE__ */ new Map();
|
|
1110
|
+
const nodeIds = new Set(nodes.map((node) => node.id));
|
|
1111
|
+
nodeIds.forEach((nodeId) => {
|
|
1112
|
+
adjacencyList.set(nodeId, []);
|
|
1113
|
+
});
|
|
1114
|
+
edges.forEach((edge) => {
|
|
1115
|
+
const sourceList = adjacencyList.get(edge.sourceNodeID);
|
|
1116
|
+
if (sourceList) {
|
|
1117
|
+
sourceList.push(edge.targetNodeID);
|
|
1118
|
+
}
|
|
1119
|
+
});
|
|
1120
|
+
let NodeStatus;
|
|
1121
|
+
((NodeStatus2) => {
|
|
1122
|
+
NodeStatus2[NodeStatus2["Unvisited"] = 0] = "Unvisited";
|
|
1123
|
+
NodeStatus2[NodeStatus2["Visiting"] = 1] = "Visiting";
|
|
1124
|
+
NodeStatus2[NodeStatus2["Visited"] = 2] = "Visited";
|
|
1125
|
+
})(NodeStatus || (NodeStatus = {}));
|
|
1126
|
+
const nodeStatusMap = /* @__PURE__ */ new Map();
|
|
1127
|
+
nodeIds.forEach((nodeId) => {
|
|
1128
|
+
nodeStatusMap.set(nodeId, 0 /* Unvisited */);
|
|
1129
|
+
});
|
|
1130
|
+
const detectCycleFromNode = (nodeId) => {
|
|
1131
|
+
nodeStatusMap.set(nodeId, 1 /* Visiting */);
|
|
1132
|
+
const neighbors = adjacencyList.get(nodeId) || [];
|
|
1133
|
+
for (const neighbor of neighbors) {
|
|
1134
|
+
const neighborColor = nodeStatusMap.get(neighbor);
|
|
1135
|
+
if (neighborColor === 1 /* Visiting */) {
|
|
1136
|
+
return true;
|
|
1137
|
+
}
|
|
1138
|
+
if (neighborColor === 0 /* Unvisited */ && detectCycleFromNode(neighbor)) {
|
|
1139
|
+
return true;
|
|
1140
|
+
}
|
|
1141
|
+
}
|
|
1142
|
+
nodeStatusMap.set(nodeId, 2 /* Visited */);
|
|
1143
|
+
return false;
|
|
1144
|
+
};
|
|
1145
|
+
for (const nodeId of nodeIds) {
|
|
1146
|
+
if (nodeStatusMap.get(nodeId) === 0 /* Unvisited */) {
|
|
1147
|
+
if (detectCycleFromNode(nodeId)) {
|
|
1148
|
+
throw new Error("Workflow schema contains a cycle, which is not allowed");
|
|
1149
|
+
}
|
|
1150
|
+
}
|
|
1151
|
+
}
|
|
1152
|
+
nodes.forEach((node) => {
|
|
1153
|
+
if (node.blocks) {
|
|
1154
|
+
cycleDetection({
|
|
1155
|
+
nodes: node.blocks,
|
|
1156
|
+
edges: node.edges ?? []
|
|
1157
|
+
});
|
|
1158
|
+
}
|
|
1159
|
+
});
|
|
1160
|
+
};
|
|
1161
|
+
|
|
1162
|
+
// src/domain/validation/validators/start-end-node.ts
|
|
1163
|
+
var blockStartEndNode = (schema) => {
|
|
1164
|
+
const { blockStartNodes, blockEndNodes } = schema.nodes.reduce(
|
|
1165
|
+
(acc, node) => {
|
|
1166
|
+
if (node.type === FlowGramNode.BlockStart) {
|
|
1167
|
+
acc.blockStartNodes.push(node);
|
|
1168
|
+
} else if (node.type === FlowGramNode.BlockEnd) {
|
|
1169
|
+
acc.blockEndNodes.push(node);
|
|
1170
|
+
}
|
|
1171
|
+
return acc;
|
|
1172
|
+
},
|
|
1173
|
+
{ blockStartNodes: [], blockEndNodes: [] }
|
|
1174
|
+
);
|
|
1175
|
+
if (!blockStartNodes.length && !blockEndNodes.length) {
|
|
1176
|
+
throw new Error("Workflow block schema must have a block-start node and a block-end node");
|
|
1177
|
+
}
|
|
1178
|
+
if (!blockStartNodes.length) {
|
|
1179
|
+
throw new Error("Workflow block schema must have a block-start node");
|
|
1180
|
+
}
|
|
1181
|
+
if (!blockEndNodes.length) {
|
|
1182
|
+
throw new Error("Workflow block schema must have an block-end node");
|
|
1183
|
+
}
|
|
1184
|
+
if (blockStartNodes.length > 1) {
|
|
1185
|
+
throw new Error("Workflow block schema must have only one block-start node");
|
|
1186
|
+
}
|
|
1187
|
+
if (blockEndNodes.length > 1) {
|
|
1188
|
+
throw new Error("Workflow block schema must have only one block-end node");
|
|
1189
|
+
}
|
|
1190
|
+
schema.nodes.forEach((node) => {
|
|
1191
|
+
if (node.blocks) {
|
|
1192
|
+
blockStartEndNode({
|
|
1193
|
+
nodes: node.blocks,
|
|
1194
|
+
edges: node.edges ?? []
|
|
1195
|
+
});
|
|
1196
|
+
}
|
|
1197
|
+
});
|
|
1198
|
+
};
|
|
1199
|
+
var startEndNode = (schema) => {
|
|
1200
|
+
const { startNodes, endNodes } = schema.nodes.reduce(
|
|
1201
|
+
(acc, node) => {
|
|
1202
|
+
if (node.type === FlowGramNode.Start) {
|
|
1203
|
+
acc.startNodes.push(node);
|
|
1204
|
+
} else if (node.type === FlowGramNode.End) {
|
|
1205
|
+
acc.endNodes.push(node);
|
|
1206
|
+
}
|
|
1207
|
+
return acc;
|
|
1208
|
+
},
|
|
1209
|
+
{ startNodes: [], endNodes: [] }
|
|
1210
|
+
);
|
|
1211
|
+
if (!startNodes.length && !endNodes.length) {
|
|
1212
|
+
throw new Error("Workflow schema must have a start node and an end node");
|
|
1213
|
+
}
|
|
1214
|
+
if (!startNodes.length) {
|
|
1215
|
+
throw new Error("Workflow schema must have a start node");
|
|
1216
|
+
}
|
|
1217
|
+
if (!endNodes.length) {
|
|
1218
|
+
throw new Error("Workflow schema must have an end node");
|
|
1219
|
+
}
|
|
1220
|
+
if (startNodes.length > 1) {
|
|
1221
|
+
throw new Error("Workflow schema must have only one start node");
|
|
1222
|
+
}
|
|
1223
|
+
if (endNodes.length > 1) {
|
|
1224
|
+
throw new Error("Workflow schema must have only one end node");
|
|
1225
|
+
}
|
|
1226
|
+
schema.nodes.forEach((node) => {
|
|
1227
|
+
if (node.blocks) {
|
|
1228
|
+
blockStartEndNode({
|
|
1229
|
+
nodes: node.blocks,
|
|
1230
|
+
edges: node.edges ?? []
|
|
1231
|
+
});
|
|
1232
|
+
}
|
|
1233
|
+
});
|
|
1234
|
+
};
|
|
1235
|
+
|
|
1236
|
+
// src/domain/validation/validators/edge-source-target-exist.ts
|
|
1237
|
+
var edgeSourceTargetExist = (schema) => {
|
|
1238
|
+
const { nodes, edges } = schema;
|
|
1239
|
+
const nodeSet = new Set(nodes.map((node) => node.id));
|
|
1240
|
+
edges.forEach((edge) => {
|
|
1241
|
+
if (!nodeSet.has(edge.sourceNodeID)) {
|
|
1242
|
+
throw new Error(`Workflow schema edge source node "${edge.sourceNodeID}" not exist`);
|
|
1243
|
+
}
|
|
1244
|
+
if (!nodeSet.has(edge.targetNodeID)) {
|
|
1245
|
+
throw new Error(`Workflow schema edge target node "${edge.targetNodeID}" not exist`);
|
|
1246
|
+
}
|
|
1247
|
+
});
|
|
1248
|
+
nodes.forEach((node) => {
|
|
1249
|
+
if (node.blocks) {
|
|
1250
|
+
edgeSourceTargetExist({
|
|
1251
|
+
nodes: node.blocks,
|
|
1252
|
+
edges: node.edges ?? []
|
|
1253
|
+
});
|
|
1254
|
+
}
|
|
1255
|
+
});
|
|
1256
|
+
};
|
|
1257
|
+
|
|
1258
|
+
// src/domain/validation/validators/schema-format.ts
|
|
1259
|
+
var schemaFormat = (schema) => {
|
|
1260
|
+
if (!schema || typeof schema !== "object") {
|
|
1261
|
+
throw new Error("Workflow schema must be a valid object");
|
|
1262
|
+
}
|
|
1263
|
+
if (!Array.isArray(schema.nodes)) {
|
|
1264
|
+
throw new Error("Workflow schema must have a valid nodes array");
|
|
1265
|
+
}
|
|
1266
|
+
if (!Array.isArray(schema.edges)) {
|
|
1267
|
+
throw new Error("Workflow schema must have a valid edges array");
|
|
1268
|
+
}
|
|
1269
|
+
schema.nodes.forEach((node, index) => {
|
|
1270
|
+
validateNodeFormat(node, `nodes[${index}]`);
|
|
1271
|
+
});
|
|
1272
|
+
schema.edges.forEach((edge, index) => {
|
|
1273
|
+
validateEdgeFormat(edge, `edges[${index}]`);
|
|
1274
|
+
});
|
|
1275
|
+
schema.nodes.forEach((node, nodeIndex) => {
|
|
1276
|
+
if (node.blocks) {
|
|
1277
|
+
if (!Array.isArray(node.blocks)) {
|
|
1278
|
+
throw new Error(`Node nodes[${nodeIndex}].blocks must be an array`);
|
|
1279
|
+
}
|
|
1280
|
+
const nestedSchema = {
|
|
1281
|
+
nodes: node.blocks,
|
|
1282
|
+
edges: node.edges || []
|
|
1283
|
+
};
|
|
1284
|
+
schemaFormat(nestedSchema);
|
|
1285
|
+
}
|
|
1286
|
+
});
|
|
1287
|
+
};
|
|
1288
|
+
var validateNodeFormat = (node, path) => {
|
|
1289
|
+
if (!node || typeof node !== "object") {
|
|
1290
|
+
throw new Error(`${path} must be a valid object`);
|
|
1291
|
+
}
|
|
1292
|
+
if (typeof node.id !== "string" || !node.id.trim()) {
|
|
1293
|
+
throw new Error(`${path}.id must be a non-empty string`);
|
|
1294
|
+
}
|
|
1295
|
+
if (typeof node.type !== "string" || !node.type.trim()) {
|
|
1296
|
+
throw new Error(`${path}.type must be a non-empty string`);
|
|
1297
|
+
}
|
|
1298
|
+
if (!node.meta || typeof node.meta !== "object") {
|
|
1299
|
+
throw new Error(`${path}.meta must be a valid object`);
|
|
1300
|
+
}
|
|
1301
|
+
if (!node.data || typeof node.data !== "object") {
|
|
1302
|
+
throw new Error(`${path}.data must be a valid object`);
|
|
1303
|
+
}
|
|
1304
|
+
if (node.blocks !== void 0 && !Array.isArray(node.blocks)) {
|
|
1305
|
+
throw new Error(`${path}.blocks must be an array if present`);
|
|
1306
|
+
}
|
|
1307
|
+
if (node.edges !== void 0 && !Array.isArray(node.edges)) {
|
|
1308
|
+
throw new Error(`${path}.edges must be an array if present`);
|
|
1309
|
+
}
|
|
1310
|
+
if (node.data.inputs !== void 0 && (typeof node.data.inputs !== "object" || node.data.inputs === null)) {
|
|
1311
|
+
throw new Error(`${path}.data.inputs must be a valid object if present`);
|
|
1312
|
+
}
|
|
1313
|
+
if (node.data.outputs !== void 0 && (typeof node.data.outputs !== "object" || node.data.outputs === null)) {
|
|
1314
|
+
throw new Error(`${path}.data.outputs must be a valid object if present`);
|
|
1315
|
+
}
|
|
1316
|
+
if (node.data.inputsValues !== void 0 && (typeof node.data.inputsValues !== "object" || node.data.inputsValues === null)) {
|
|
1317
|
+
throw new Error(`${path}.data.inputsValues must be a valid object if present`);
|
|
1318
|
+
}
|
|
1319
|
+
if (node.data.title !== void 0 && typeof node.data.title !== "string") {
|
|
1320
|
+
throw new Error(`${path}.data.title must be a string if present`);
|
|
1321
|
+
}
|
|
1322
|
+
};
|
|
1323
|
+
var validateEdgeFormat = (edge, path) => {
|
|
1324
|
+
if (!edge || typeof edge !== "object") {
|
|
1325
|
+
throw new Error(`${path} must be a valid object`);
|
|
1326
|
+
}
|
|
1327
|
+
if (typeof edge.sourceNodeID !== "string" || !edge.sourceNodeID.trim()) {
|
|
1328
|
+
throw new Error(`${path}.sourceNodeID must be a non-empty string`);
|
|
1329
|
+
}
|
|
1330
|
+
if (typeof edge.targetNodeID !== "string" || !edge.targetNodeID.trim()) {
|
|
1331
|
+
throw new Error(`${path}.targetNodeID must be a non-empty string`);
|
|
1332
|
+
}
|
|
1333
|
+
if (edge.sourcePortID !== void 0 && typeof edge.sourcePortID !== "string") {
|
|
1334
|
+
throw new Error(`${path}.sourcePortID must be a string if present`);
|
|
1335
|
+
}
|
|
1336
|
+
if (edge.targetPortID !== void 0 && typeof edge.targetPortID !== "string") {
|
|
1337
|
+
throw new Error(`${path}.targetPortID must be a string if present`);
|
|
1338
|
+
}
|
|
1339
|
+
};
|
|
1340
|
+
|
|
1080
1341
|
// src/domain/validation/index.ts
|
|
1081
1342
|
var WorkflowRuntimeValidation = class {
|
|
1082
1343
|
invoke(params) {
|
|
@@ -1094,8 +1355,23 @@ var WorkflowRuntimeValidation = class {
|
|
|
1094
1355
|
};
|
|
1095
1356
|
}
|
|
1096
1357
|
schema(schema) {
|
|
1358
|
+
const errors = [];
|
|
1359
|
+
const validations = [
|
|
1360
|
+
() => schemaFormat(schema),
|
|
1361
|
+
() => cycleDetection(schema),
|
|
1362
|
+
() => edgeSourceTargetExist(schema),
|
|
1363
|
+
() => startEndNode(schema)
|
|
1364
|
+
];
|
|
1365
|
+
validations.forEach((validation) => {
|
|
1366
|
+
try {
|
|
1367
|
+
validation();
|
|
1368
|
+
} catch (error) {
|
|
1369
|
+
errors.push(error instanceof Error ? error.message : String(error));
|
|
1370
|
+
}
|
|
1371
|
+
});
|
|
1097
1372
|
return {
|
|
1098
|
-
valid:
|
|
1373
|
+
valid: errors.length === 0,
|
|
1374
|
+
errors: errors.length > 0 ? errors : void 0
|
|
1099
1375
|
};
|
|
1100
1376
|
}
|
|
1101
1377
|
inputs(inputsSchema, inputs) {
|
|
@@ -1138,7 +1414,7 @@ var WorkflowRuntimeExecutor = class {
|
|
|
1138
1414
|
const nodeType = context.node.type;
|
|
1139
1415
|
const nodeExecutor = this.nodeExecutors.get(nodeType);
|
|
1140
1416
|
if (!nodeExecutor) {
|
|
1141
|
-
throw new Error(`
|
|
1417
|
+
throw new Error(`No executor found for node type ${nodeType}`);
|
|
1142
1418
|
}
|
|
1143
1419
|
const output = await nodeExecutor.execute(context);
|
|
1144
1420
|
return output;
|
|
@@ -1513,7 +1789,7 @@ var WorkflowRuntimeState = class {
|
|
|
1513
1789
|
}
|
|
1514
1790
|
parseRef(ref) {
|
|
1515
1791
|
if (ref?.type !== "ref") {
|
|
1516
|
-
throw new Error(`
|
|
1792
|
+
throw new Error(`Invalid ref value: ${ref}`);
|
|
1517
1793
|
}
|
|
1518
1794
|
if (!ref.content || ref.content.length < 2) {
|
|
1519
1795
|
return null;
|
|
@@ -1531,7 +1807,7 @@ var WorkflowRuntimeState = class {
|
|
|
1531
1807
|
}
|
|
1532
1808
|
parseTemplate(template) {
|
|
1533
1809
|
if (template?.type !== "template") {
|
|
1534
|
-
throw new Error(`
|
|
1810
|
+
throw new Error(`Invalid template value: ${template}`);
|
|
1535
1811
|
}
|
|
1536
1812
|
if (!template.content) {
|
|
1537
1813
|
return null;
|
|
@@ -1557,7 +1833,7 @@ var WorkflowRuntimeState = class {
|
|
|
1557
1833
|
}
|
|
1558
1834
|
parseValue(flowValue) {
|
|
1559
1835
|
if (!flowValue?.type) {
|
|
1560
|
-
throw new Error(`
|
|
1836
|
+
throw new Error(`Invalid flow value type: ${flowValue.type}`);
|
|
1561
1837
|
}
|
|
1562
1838
|
if (flowValue.type === "constant") {
|
|
1563
1839
|
const value = flowValue.content;
|
|
@@ -1576,7 +1852,7 @@ var WorkflowRuntimeState = class {
|
|
|
1576
1852
|
if (flowValue.type === "template") {
|
|
1577
1853
|
return this.parseTemplate(flowValue);
|
|
1578
1854
|
}
|
|
1579
|
-
throw new Error(`
|
|
1855
|
+
throw new Error(`Unknown flow value type: ${flowValue.type}`);
|
|
1580
1856
|
}
|
|
1581
1857
|
isExecutedNode(node) {
|
|
1582
1858
|
return this.executedNodes.has(node.id);
|
|
@@ -1961,7 +2237,7 @@ var createStore = (params) => {
|
|
|
1961
2237
|
const from = store.nodes.get(sourceNodeID);
|
|
1962
2238
|
const to = store.nodes.get(targetNodeID);
|
|
1963
2239
|
if (!from || !to) {
|
|
1964
|
-
throw new Error(`
|
|
2240
|
+
throw new Error(`Invalid edge schema ID: ${id}, from: ${sourceNodeID}, to: ${targetNodeID}`);
|
|
1965
2241
|
}
|
|
1966
2242
|
const edge = createEdge(store, {
|
|
1967
2243
|
id,
|
|
@@ -2236,7 +2512,7 @@ var WorkflowRuntimeEngine = class {
|
|
|
2236
2512
|
}
|
|
2237
2513
|
const targetPort = node.ports.outputs.find((port) => port.id === branch);
|
|
2238
2514
|
if (!targetPort) {
|
|
2239
|
-
throw new Error(`branch ${branch} not found`);
|
|
2515
|
+
throw new Error(`Engine branch ${branch} not found`);
|
|
2240
2516
|
}
|
|
2241
2517
|
const nextNodeIDs = new Set(targetPort.edges.map((edge) => edge.to.id));
|
|
2242
2518
|
const nextNodes = allNextNodes.filter((nextNode) => nextNodeIDs.has(nextNode.id));
|
|
@@ -2251,11 +2527,11 @@ var WorkflowRuntimeEngine = class {
|
|
|
2251
2527
|
}
|
|
2252
2528
|
async executeNext(params) {
|
|
2253
2529
|
const { context, node, nextNodes } = params;
|
|
2254
|
-
if (node.type === FlowGramNode.End) {
|
|
2530
|
+
if (node.type === FlowGramNode.End || node.type === FlowGramNode.BlockEnd) {
|
|
2255
2531
|
return;
|
|
2256
2532
|
}
|
|
2257
2533
|
if (nextNodes.length === 0) {
|
|
2258
|
-
|
|
2534
|
+
throw new Error(`Node ${node.id} has no next nodes`);
|
|
2259
2535
|
}
|
|
2260
2536
|
await Promise.all(
|
|
2261
2537
|
nextNodes.map(
|