flowscale 1.3.0 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -0
- package/dist/index.js +132 -45
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -75,6 +75,7 @@ export declare class FlowscaleAPI {
|
|
|
75
75
|
private emitExecuteWorkflowAsyncIntermediateResponse;
|
|
76
76
|
private formatUnknownError;
|
|
77
77
|
private sleep;
|
|
78
|
+
private normalizeGetOutputResponse;
|
|
78
79
|
private resolveGlobalFetch;
|
|
79
80
|
private consumeRunEventsStream;
|
|
80
81
|
private safeReadResponseText;
|
package/dist/index.js
CHANGED
|
@@ -236,13 +236,13 @@ var FlowscaleAPI = /** @class */ (function () {
|
|
|
236
236
|
*/
|
|
237
237
|
FlowscaleAPI.prototype.executeWorkflowAsync = function (workflowId_1, data_1, groupId_1) {
|
|
238
238
|
return __awaiter(this, arguments, void 0, function (workflowId, data, groupId, pollIntervalMs, timeoutMs, returnAllOutputsOrOptions) {
|
|
239
|
-
var _a, returnAllOutputs, onIntermediateResponse, startTime, executeResponse, runId, resolvedWorkflowId, run_status, output_names, runResponse, attempts, outputPromises, outputResults, successfulOutputs, pendingOutputs, hasErrors, _i, outputResults_1, result, deprecationWarning, legacyResponse, allOutputsResponse, error_1;
|
|
239
|
+
var _a, returnAllOutputs, onIntermediateResponse, startTime, executeResponse, runId, resolvedWorkflowId, run_status, output_names, runResponse, attempts, runResponse, latestOutputNames, outputPromises, outputResults, successfulOutputs, pendingOutputs, hasErrors, _i, outputResults_1, result, deprecationWarning, legacyResponse, allOutputsResponse, error_1;
|
|
240
240
|
var _this = this;
|
|
241
|
-
var _b, _c, _d, _e, _f;
|
|
241
|
+
var _b, _c, _d, _e, _f, _g, _h, _j;
|
|
242
242
|
if (pollIntervalMs === void 0) { pollIntervalMs = 2000; }
|
|
243
243
|
if (timeoutMs === void 0) { timeoutMs = 600000; }
|
|
244
|
-
return __generator(this, function (
|
|
245
|
-
switch (
|
|
244
|
+
return __generator(this, function (_k) {
|
|
245
|
+
switch (_k.label) {
|
|
246
246
|
case 0:
|
|
247
247
|
// Validate inputs
|
|
248
248
|
if (!workflowId || typeof workflowId !== 'string' || workflowId.trim() === '') {
|
|
@@ -261,7 +261,7 @@ var FlowscaleAPI = /** @class */ (function () {
|
|
|
261
261
|
startTime = Date.now();
|
|
262
262
|
return [4 /*yield*/, this.executeWorkflow(workflowId, data, groupId)];
|
|
263
263
|
case 1:
|
|
264
|
-
executeResponse =
|
|
264
|
+
executeResponse = _k.sent();
|
|
265
265
|
if (!((_b = executeResponse === null || executeResponse === void 0 ? void 0 : executeResponse.data) === null || _b === void 0 ? void 0 : _b.run_id)) {
|
|
266
266
|
throw new Error('No run ID returned from workflow execution');
|
|
267
267
|
}
|
|
@@ -278,10 +278,10 @@ var FlowscaleAPI = /** @class */ (function () {
|
|
|
278
278
|
response: executeResponse,
|
|
279
279
|
})];
|
|
280
280
|
case 2:
|
|
281
|
-
|
|
281
|
+
_k.sent();
|
|
282
282
|
run_status = "queued";
|
|
283
283
|
output_names = [];
|
|
284
|
-
|
|
284
|
+
_k.label = 3;
|
|
285
285
|
case 3:
|
|
286
286
|
if (!(output_names.length === 0)) return [3 /*break*/, 8];
|
|
287
287
|
if (Date.now() - startTime > timeoutMs) {
|
|
@@ -289,7 +289,7 @@ var FlowscaleAPI = /** @class */ (function () {
|
|
|
289
289
|
}
|
|
290
290
|
return [4 /*yield*/, this.getRun(runId)];
|
|
291
291
|
case 4:
|
|
292
|
-
runResponse =
|
|
292
|
+
runResponse = _k.sent();
|
|
293
293
|
run_status = ((_d = runResponse === null || runResponse === void 0 ? void 0 : runResponse.data) === null || _d === void 0 ? void 0 : _d.status) || "queued";
|
|
294
294
|
output_names = ((_e = runResponse === null || runResponse === void 0 ? void 0 : runResponse.data) === null || _e === void 0 ? void 0 : _e.output_names) || [];
|
|
295
295
|
return [4 /*yield*/, this.emitExecuteWorkflowAsyncIntermediateResponse(onIntermediateResponse, {
|
|
@@ -303,15 +303,15 @@ var FlowscaleAPI = /** @class */ (function () {
|
|
|
303
303
|
response: runResponse,
|
|
304
304
|
})];
|
|
305
305
|
case 5:
|
|
306
|
-
|
|
306
|
+
_k.sent();
|
|
307
307
|
if (run_status === 'failed' || run_status === 'cancelled') {
|
|
308
308
|
throw new Error("Run ".concat(runId, " failed with status: ").concat(run_status));
|
|
309
309
|
}
|
|
310
310
|
if (!(output_names.length === 0)) return [3 /*break*/, 7];
|
|
311
311
|
return [4 /*yield*/, this.sleep(pollIntervalMs)];
|
|
312
312
|
case 6:
|
|
313
|
-
|
|
314
|
-
|
|
313
|
+
_k.sent();
|
|
314
|
+
_k.label = 7;
|
|
315
315
|
case 7: return [3 /*break*/, 3];
|
|
316
316
|
case 8:
|
|
317
317
|
if (!output_names || output_names.length === 0) {
|
|
@@ -319,15 +319,39 @@ var FlowscaleAPI = /** @class */ (function () {
|
|
|
319
319
|
}
|
|
320
320
|
this.logInfo("Found ".concat(output_names.length, " outputs to wait for: ").concat(output_names.join(', ')));
|
|
321
321
|
attempts = 0;
|
|
322
|
-
|
|
322
|
+
_k.label = 9;
|
|
323
323
|
case 9:
|
|
324
|
-
if (!true) return [3 /*break*/,
|
|
324
|
+
if (!true) return [3 /*break*/, 23];
|
|
325
325
|
if (Date.now() - startTime > timeoutMs) {
|
|
326
326
|
throw new Error("Workflow execution timed out after ".concat(timeoutMs, "ms"));
|
|
327
327
|
}
|
|
328
|
-
|
|
328
|
+
_k.label = 10;
|
|
329
329
|
case 10:
|
|
330
|
-
|
|
330
|
+
_k.trys.push([10, 19, , 22]);
|
|
331
|
+
return [4 /*yield*/, this.getRun(runId)];
|
|
332
|
+
case 11:
|
|
333
|
+
runResponse = _k.sent();
|
|
334
|
+
run_status = ((_g = runResponse === null || runResponse === void 0 ? void 0 : runResponse.data) === null || _g === void 0 ? void 0 : _g.status) || run_status;
|
|
335
|
+
latestOutputNames = ((_h = runResponse === null || runResponse === void 0 ? void 0 : runResponse.data) === null || _h === void 0 ? void 0 : _h.output_names) || [];
|
|
336
|
+
if (latestOutputNames.length > 0) {
|
|
337
|
+
output_names = latestOutputNames;
|
|
338
|
+
}
|
|
339
|
+
return [4 /*yield*/, this.emitExecuteWorkflowAsyncIntermediateResponse(onIntermediateResponse, {
|
|
340
|
+
type: 'run_status',
|
|
341
|
+
timestamp: new Date().toISOString(),
|
|
342
|
+
run_id: runId,
|
|
343
|
+
workflow_id: resolvedWorkflowId,
|
|
344
|
+
attempt: attempts,
|
|
345
|
+
run_status: run_status,
|
|
346
|
+
output_names: output_names,
|
|
347
|
+
progress: ((_j = runResponse === null || runResponse === void 0 ? void 0 : runResponse.data) === null || _j === void 0 ? void 0 : _j.progress) || undefined,
|
|
348
|
+
response: runResponse,
|
|
349
|
+
})];
|
|
350
|
+
case 12:
|
|
351
|
+
_k.sent();
|
|
352
|
+
if (run_status === 'failed' || run_status === 'cancelled') {
|
|
353
|
+
throw new Error("Run ".concat(runId, " failed with status: ").concat(run_status));
|
|
354
|
+
}
|
|
331
355
|
outputPromises = output_names.map(function (outputName) { return __awaiter(_this, void 0, void 0, function () {
|
|
332
356
|
var output, error_2;
|
|
333
357
|
var _a;
|
|
@@ -372,8 +396,8 @@ var FlowscaleAPI = /** @class */ (function () {
|
|
|
372
396
|
});
|
|
373
397
|
}); });
|
|
374
398
|
return [4 /*yield*/, Promise.all(outputPromises)];
|
|
375
|
-
case
|
|
376
|
-
outputResults =
|
|
399
|
+
case 13:
|
|
400
|
+
outputResults = _k.sent();
|
|
377
401
|
successfulOutputs = [];
|
|
378
402
|
pendingOutputs = [];
|
|
379
403
|
hasErrors = false;
|
|
@@ -413,9 +437,9 @@ var FlowscaleAPI = /** @class */ (function () {
|
|
|
413
437
|
if (hasErrors) {
|
|
414
438
|
throw new Error('One or more workflow outputs failed');
|
|
415
439
|
}
|
|
416
|
-
if (!(pendingOutputs.length === 0)) return [3 /*break*/,
|
|
440
|
+
if (!(pendingOutputs.length === 0)) return [3 /*break*/, 17];
|
|
417
441
|
this.logInfo("All ".concat(successfulOutputs.length, " outputs completed successfully"));
|
|
418
|
-
if (!(returnAllOutputs === false || (returnAllOutputs === undefined && successfulOutputs.length === 1))) return [3 /*break*/,
|
|
442
|
+
if (!(returnAllOutputs === false || (returnAllOutputs === undefined && successfulOutputs.length === 1))) return [3 /*break*/, 15];
|
|
419
443
|
deprecationWarning = {
|
|
420
444
|
message: successfulOutputs.length > 1
|
|
421
445
|
? 'Single output format is deprecated. This workflow returned multiple outputs but only the first is shown.'
|
|
@@ -443,10 +467,10 @@ var FlowscaleAPI = /** @class */ (function () {
|
|
|
443
467
|
completed_outputs: successfulOutputs.map(function (output) { return output.filename; }),
|
|
444
468
|
response: legacyResponse,
|
|
445
469
|
})];
|
|
446
|
-
case
|
|
447
|
-
|
|
470
|
+
case 14:
|
|
471
|
+
_k.sent();
|
|
448
472
|
return [2 /*return*/, legacyResponse];
|
|
449
|
-
case
|
|
473
|
+
case 15:
|
|
450
474
|
allOutputsResponse = {
|
|
451
475
|
status: 'success',
|
|
452
476
|
data: successfulOutputs
|
|
@@ -460,18 +484,18 @@ var FlowscaleAPI = /** @class */ (function () {
|
|
|
460
484
|
completed_outputs: successfulOutputs.map(function (output) { return output.filename; }),
|
|
461
485
|
response: allOutputsResponse,
|
|
462
486
|
})];
|
|
463
|
-
case
|
|
464
|
-
|
|
487
|
+
case 16:
|
|
488
|
+
_k.sent();
|
|
465
489
|
return [2 /*return*/, allOutputsResponse];
|
|
466
|
-
case
|
|
490
|
+
case 17:
|
|
467
491
|
// If some outputs are still pending, continue polling
|
|
468
492
|
this.logDebug("".concat(pendingOutputs.length, " outputs still pending: ").concat(pendingOutputs.join(', ')));
|
|
469
493
|
return [4 /*yield*/, this.sleep(pollIntervalMs)];
|
|
470
|
-
case
|
|
471
|
-
|
|
472
|
-
return [3 /*break*/,
|
|
473
|
-
case
|
|
474
|
-
error_1 =
|
|
494
|
+
case 18:
|
|
495
|
+
_k.sent();
|
|
496
|
+
return [3 /*break*/, 22];
|
|
497
|
+
case 19:
|
|
498
|
+
error_1 = _k.sent();
|
|
475
499
|
// Log the error but continue polling
|
|
476
500
|
this.logWarn("Error polling for outputs (attempt ".concat(attempts, "):"), error_1);
|
|
477
501
|
return [4 /*yield*/, this.emitExecuteWorkflowAsyncIntermediateResponse(onIntermediateResponse, {
|
|
@@ -483,22 +507,22 @@ var FlowscaleAPI = /** @class */ (function () {
|
|
|
483
507
|
output_names: output_names,
|
|
484
508
|
error: this.formatUnknownError(error_1),
|
|
485
509
|
})];
|
|
486
|
-
case
|
|
487
|
-
|
|
510
|
+
case 20:
|
|
511
|
+
_k.sent();
|
|
488
512
|
// After several failures, increase polling interval to avoid excessive requests
|
|
489
513
|
if (attempts > 5) {
|
|
490
514
|
pollIntervalMs = Math.min(pollIntervalMs * 1.5, 10000); // Increase interval, max 10s
|
|
491
515
|
}
|
|
492
516
|
// Wait before retrying
|
|
493
517
|
return [4 /*yield*/, this.sleep(pollIntervalMs)];
|
|
494
|
-
case
|
|
518
|
+
case 21:
|
|
495
519
|
// Wait before retrying
|
|
496
|
-
|
|
497
|
-
return [3 /*break*/,
|
|
498
|
-
case
|
|
520
|
+
_k.sent();
|
|
521
|
+
return [3 /*break*/, 22];
|
|
522
|
+
case 22:
|
|
499
523
|
attempts++;
|
|
500
524
|
return [3 /*break*/, 9];
|
|
501
|
-
case
|
|
525
|
+
case 23: return [2 /*return*/];
|
|
502
526
|
}
|
|
503
527
|
});
|
|
504
528
|
});
|
|
@@ -509,7 +533,7 @@ var FlowscaleAPI = /** @class */ (function () {
|
|
|
509
533
|
*/
|
|
510
534
|
FlowscaleAPI.prototype.getOutput = function (filename) {
|
|
511
535
|
return __awaiter(this, void 0, void 0, function () {
|
|
512
|
-
var error_3, axiosError;
|
|
536
|
+
var response, error_3, axiosError;
|
|
513
537
|
return __generator(this, function (_a) {
|
|
514
538
|
switch (_a.label) {
|
|
515
539
|
case 0:
|
|
@@ -520,21 +544,35 @@ var FlowscaleAPI = /** @class */ (function () {
|
|
|
520
544
|
_a.label = 1;
|
|
521
545
|
case 1:
|
|
522
546
|
_a.trys.push([1, 3, , 4]);
|
|
523
|
-
return [4 /*yield*/, this.
|
|
547
|
+
return [4 /*yield*/, this.client.get('/api/v1/runs/output', {
|
|
524
548
|
params: { filename: filename },
|
|
549
|
+
// We need to inspect HTTP status directly (204 is a valid "not ready" response).
|
|
550
|
+
validateStatus: function () { return true; },
|
|
525
551
|
})];
|
|
526
|
-
case 2:
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
axiosError = error_3;
|
|
530
|
-
if (axiosError.response && axiosError.response.status === 204) {
|
|
552
|
+
case 2:
|
|
553
|
+
response = _a.sent();
|
|
554
|
+
if (response.status === 204) {
|
|
531
555
|
return [2 /*return*/, null]; // No output found
|
|
532
556
|
}
|
|
533
|
-
else if (
|
|
557
|
+
else if (response.status === 504) {
|
|
534
558
|
this.logWarn('Received 504 Gateway Timeout, retrying...');
|
|
535
559
|
// For 504 errors specifically, we'll return null to allow the polling to continue
|
|
536
560
|
return [2 /*return*/, null];
|
|
537
561
|
}
|
|
562
|
+
else if (response.status === 408) {
|
|
563
|
+
throw new Error('Run Timeout');
|
|
564
|
+
}
|
|
565
|
+
if (response.status < 200 || response.status >= 300) {
|
|
566
|
+
throw new Error("Error: ".concat(response.status, " ").concat(response.statusText, " - ").concat(JSON.stringify(response.data)));
|
|
567
|
+
}
|
|
568
|
+
return [2 /*return*/, this.normalizeGetOutputResponse(response.data)];
|
|
569
|
+
case 3:
|
|
570
|
+
error_3 = _a.sent();
|
|
571
|
+
axiosError = error_3;
|
|
572
|
+
if (axiosError.response && axiosError.response.status === 504) {
|
|
573
|
+
this.logWarn('Received 504 Gateway Timeout, retrying...');
|
|
574
|
+
return [2 /*return*/, null];
|
|
575
|
+
}
|
|
538
576
|
else if (axiosError.response && axiosError.response.status === 408) {
|
|
539
577
|
throw new Error('Run Timeout');
|
|
540
578
|
}
|
|
@@ -685,6 +723,55 @@ var FlowscaleAPI = /** @class */ (function () {
|
|
|
685
723
|
});
|
|
686
724
|
});
|
|
687
725
|
};
|
|
726
|
+
FlowscaleAPI.prototype.normalizeGetOutputResponse = function (payload) {
|
|
727
|
+
if (!payload || typeof payload !== 'object') {
|
|
728
|
+
return null;
|
|
729
|
+
}
|
|
730
|
+
if (typeof payload.status === 'string') {
|
|
731
|
+
return payload;
|
|
732
|
+
}
|
|
733
|
+
// Handle payloads that omit top-level status but still contain useful output data.
|
|
734
|
+
if (payload.data && typeof payload.data === 'object') {
|
|
735
|
+
if (payload.data.errors) {
|
|
736
|
+
return {
|
|
737
|
+
status: 'error',
|
|
738
|
+
data: {
|
|
739
|
+
errors: payload.data.errors,
|
|
740
|
+
},
|
|
741
|
+
};
|
|
742
|
+
}
|
|
743
|
+
if (payload.data.progress) {
|
|
744
|
+
return {
|
|
745
|
+
status: 'in_progress',
|
|
746
|
+
data: payload.data,
|
|
747
|
+
};
|
|
748
|
+
}
|
|
749
|
+
if (payload.data.download_url ||
|
|
750
|
+
payload.data.file_content ||
|
|
751
|
+
payload.data.generation_status) {
|
|
752
|
+
return {
|
|
753
|
+
status: 'success',
|
|
754
|
+
data: payload.data,
|
|
755
|
+
};
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
// Legacy shape fallback: response data returned directly without wrapping.
|
|
759
|
+
if (payload.download_url || payload.file_content || payload.generation_status) {
|
|
760
|
+
return {
|
|
761
|
+
status: 'success',
|
|
762
|
+
data: payload,
|
|
763
|
+
};
|
|
764
|
+
}
|
|
765
|
+
if (payload.errors) {
|
|
766
|
+
return {
|
|
767
|
+
status: 'error',
|
|
768
|
+
data: {
|
|
769
|
+
errors: payload.errors,
|
|
770
|
+
},
|
|
771
|
+
};
|
|
772
|
+
}
|
|
773
|
+
return null;
|
|
774
|
+
};
|
|
688
775
|
FlowscaleAPI.prototype.resolveGlobalFetch = function () {
|
|
689
776
|
var globalScope = typeof globalThis !== 'undefined'
|
|
690
777
|
? globalThis
|