@doclo/flows 0.1.2 → 0.1.3
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 +19 -2
- package/dist/index.js +80 -14
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -45,10 +45,27 @@ type BatchFlowResult = {
|
|
|
45
45
|
/**
|
|
46
46
|
* Type representing the built flow object returned by Flow.build()
|
|
47
47
|
*/
|
|
48
|
+
/**
|
|
49
|
+
* Options for running a built flow
|
|
50
|
+
*/
|
|
51
|
+
interface FlowRunOptions {
|
|
52
|
+
/** Progress callbacks for step execution */
|
|
53
|
+
callbacks?: FlowProgressCallbacks;
|
|
54
|
+
/** Initial artifacts to merge into the flow context (for forEach child flows) */
|
|
55
|
+
initialArtifacts?: Record<string, any>;
|
|
56
|
+
}
|
|
48
57
|
type BuiltFlow<TInput = any, TOutput = any> = {
|
|
49
|
-
run: (input: TInput,
|
|
58
|
+
run: (input: TInput, callbacksOrOptions?: FlowProgressCallbacks | FlowRunOptions) => Promise<FlowResult<TOutput> | BatchFlowResult>;
|
|
50
59
|
validate: () => FlowValidationResult;
|
|
51
60
|
};
|
|
61
|
+
/**
|
|
62
|
+
* Type guard to check if a flow result is a single result (not batch)
|
|
63
|
+
*/
|
|
64
|
+
declare function isSingleFlowResult<T>(result: FlowResult<T> | BatchFlowResult): result is FlowResult<T>;
|
|
65
|
+
/**
|
|
66
|
+
* Type guard to check if a flow result is a batch result
|
|
67
|
+
*/
|
|
68
|
+
declare function isBatchFlowResult(result: FlowResult<unknown> | BatchFlowResult): result is BatchFlowResult;
|
|
52
69
|
/**
|
|
53
70
|
* Type helper to extract the unwrapped input type from a wrapped type.
|
|
54
71
|
* If T has an 'input' property, returns the type of that property.
|
|
@@ -929,4 +946,4 @@ declare function buildTwoProviderFlow(opts: {
|
|
|
929
946
|
}>;
|
|
930
947
|
};
|
|
931
948
|
|
|
932
|
-
export { type BuiltFlow, type CategorizeConfig, type ConditionalCompositeConfig, type ExtractConfig, FLOW_REGISTRY, type FieldMapping, type FlowBuilder, type FlowOptions, type FlowProgressCallbacks, type FlowReference, type FlowRegistry$1 as FlowRegistry, FlowSerializationError, type FlowValidationResult, type ForEachCompositeConfig, type InputMappingConfig, type NodeConfig, type OutputConfig, type ParseConfig, type ProviderRegistry, type SerializableConditionalStep, type SerializableFlow, type SerializableForEachStep, type SerializableInputValidation, type SerializableStandardStep, type SerializableStep, type SplitConfig, type TriggerConfig, type ValidationError, type ValidationOptions, type ValidationResult, type ValidationWarning, buildFlowFromConfig, buildMultiProviderFlow, buildTwoProviderFlow, buildVLMDirectFlow, clearRegistry, createConditionalCompositeNode, createFlow, createForEachCompositeNode, defineFlowConfig, extractNodeMetadata, getFlow, getFlowCount, hasFlow, isFlowReference, listFlows, registerFlow, resolveFlowReference, unregisterFlow, validateFlow, validateFlowOrThrow };
|
|
949
|
+
export { type BatchFlowResult, type BuiltFlow, type CategorizeConfig, type ConditionalCompositeConfig, type ExtractConfig, FLOW_REGISTRY, type FieldMapping, type FlowBuilder, type FlowOptions, type FlowProgressCallbacks, type FlowReference, type FlowRegistry$1 as FlowRegistry, type FlowRunOptions, FlowSerializationError, type FlowValidationResult, type ForEachCompositeConfig, type InputMappingConfig, type NodeConfig, type OutputConfig, type ParseConfig, type ProviderRegistry, type SerializableConditionalStep, type SerializableFlow, type SerializableForEachStep, type SerializableInputValidation, type SerializableStandardStep, type SerializableStep, type SplitConfig, type TriggerConfig, type ValidationError, type ValidationOptions, type ValidationResult, type ValidationWarning, buildFlowFromConfig, buildMultiProviderFlow, buildTwoProviderFlow, buildVLMDirectFlow, clearRegistry, createConditionalCompositeNode, createFlow, createForEachCompositeNode, defineFlowConfig, extractNodeMetadata, getFlow, getFlowCount, hasFlow, isBatchFlowResult, isFlowReference, isSingleFlowResult, listFlows, registerFlow, resolveFlowReference, unregisterFlow, validateFlow, validateFlowOrThrow };
|
package/dist/index.js
CHANGED
|
@@ -32,6 +32,9 @@ import {
|
|
|
32
32
|
function isSingleFlowResult(result) {
|
|
33
33
|
return "output" in result && "artifacts" in result;
|
|
34
34
|
}
|
|
35
|
+
function isBatchFlowResult(result) {
|
|
36
|
+
return "results" in result && Array.isArray(result.results);
|
|
37
|
+
}
|
|
35
38
|
function normalizeFlowInput(input) {
|
|
36
39
|
if (input == null) {
|
|
37
40
|
return input;
|
|
@@ -257,8 +260,18 @@ var Flow = class {
|
|
|
257
260
|
*/
|
|
258
261
|
build() {
|
|
259
262
|
return {
|
|
260
|
-
run: async (input,
|
|
261
|
-
|
|
263
|
+
run: async (input, callbacksOrOptions) => {
|
|
264
|
+
let callbacks;
|
|
265
|
+
let initialArtifacts;
|
|
266
|
+
if (callbacksOrOptions) {
|
|
267
|
+
if ("callbacks" in callbacksOrOptions || "initialArtifacts" in callbacksOrOptions) {
|
|
268
|
+
callbacks = callbacksOrOptions.callbacks;
|
|
269
|
+
initialArtifacts = callbacksOrOptions.initialArtifacts;
|
|
270
|
+
} else {
|
|
271
|
+
callbacks = callbacksOrOptions;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
return this.execute(input, callbacks, initialArtifacts);
|
|
262
275
|
},
|
|
263
276
|
validate: () => {
|
|
264
277
|
return this.validate();
|
|
@@ -483,9 +496,9 @@ var Flow = class {
|
|
|
483
496
|
/**
|
|
484
497
|
* Execute the flow with optional progress callbacks
|
|
485
498
|
*/
|
|
486
|
-
async execute(input, callbacks) {
|
|
499
|
+
async execute(input, callbacks, initialArtifacts) {
|
|
487
500
|
const flowStartTime = Date.now();
|
|
488
|
-
const artifacts = {};
|
|
501
|
+
const artifacts = initialArtifacts ? { ...initialArtifacts } : {};
|
|
489
502
|
const metrics = [];
|
|
490
503
|
const completedSteps = [];
|
|
491
504
|
const outputs = {};
|
|
@@ -532,6 +545,7 @@ var Flow = class {
|
|
|
532
545
|
}
|
|
533
546
|
}
|
|
534
547
|
let currentData = normalizeFlowInput(input);
|
|
548
|
+
artifacts.__flowInput = currentData;
|
|
535
549
|
if (this.inputValidation?.acceptedFormats?.length) {
|
|
536
550
|
const dataUrl = currentData?.base64 || currentData?.url;
|
|
537
551
|
if (dataUrl) {
|
|
@@ -641,7 +655,7 @@ var Flow = class {
|
|
|
641
655
|
} : {
|
|
642
656
|
// Always pass stepId for metrics tracking, even without observability
|
|
643
657
|
stepId: step.id
|
|
644
|
-
});
|
|
658
|
+
}, artifacts);
|
|
645
659
|
artifacts[step.id] = result2.output;
|
|
646
660
|
metrics.push(...result2.metrics);
|
|
647
661
|
completedSteps.push(step.id);
|
|
@@ -913,7 +927,11 @@ Correct: .conditional('step', () => parse({ provider }))`
|
|
|
913
927
|
const childFlow = step.childFlow(item);
|
|
914
928
|
const builtFlow = childFlow.build();
|
|
915
929
|
const flowInput = item && typeof item === "object" && "input" in item ? item.input : item;
|
|
916
|
-
const
|
|
930
|
+
const childInitialArtifacts = {
|
|
931
|
+
__originalFlowInput: artifacts.__flowInput
|
|
932
|
+
// Original source before split
|
|
933
|
+
};
|
|
934
|
+
const result2 = await builtFlow.run(flowInput, { initialArtifacts: childInitialArtifacts });
|
|
917
935
|
let itemResult;
|
|
918
936
|
if ("results" in result2 && Array.isArray(result2.results)) {
|
|
919
937
|
const aggregatedMetrics = (result2.results || []).flatMap((r) => r && r.metrics || []);
|
|
@@ -1063,20 +1081,26 @@ Correct: .conditional('step', () => parse({ provider }))`
|
|
|
1063
1081
|
context: stepErrorContext
|
|
1064
1082
|
});
|
|
1065
1083
|
}
|
|
1066
|
-
const
|
|
1084
|
+
const isNestedFlowError = err instanceof FlowExecutionError;
|
|
1085
|
+
const completedStepsStr = isNestedFlowError ? "" : completedSteps.length > 0 ? `
|
|
1067
1086
|
Completed steps: ${completedSteps.join(" \u2192 ")}` : "\n No steps completed before failure";
|
|
1068
1087
|
const artifactsStr = Object.keys(artifacts).length > 0 ? `
|
|
1069
1088
|
Partial results available in: ${Object.keys(artifacts).join(", ")}` : "";
|
|
1089
|
+
const allCompleted = isNestedFlowError ? [...err.allCompletedSteps || err.completedSteps, ...completedSteps] : completedSteps;
|
|
1090
|
+
const flowPath = isNestedFlowError && err.flowPath ? [...err.flowPath, { stepId: step.id, stepIndex, stepType: step.type }] : [{ stepId: step.id, stepIndex, stepType: step.type }];
|
|
1091
|
+
const errorMessage = isNestedFlowError ? err.getRootCause().message : err.message;
|
|
1070
1092
|
throw new FlowExecutionError(
|
|
1071
1093
|
`Flow execution failed at step "${step.id}" (index ${stepIndex}, type: ${step.type})
|
|
1072
|
-
Error: ${
|
|
1094
|
+
Error: ${errorMessage}` + completedStepsStr + artifactsStr,
|
|
1073
1095
|
step.id,
|
|
1074
1096
|
stepIndex,
|
|
1075
1097
|
step.type,
|
|
1076
1098
|
completedSteps,
|
|
1077
|
-
err,
|
|
1078
|
-
artifacts
|
|
1099
|
+
isNestedFlowError ? err.originalError : err,
|
|
1100
|
+
artifacts,
|
|
1079
1101
|
// Include partial artifacts for debugging
|
|
1102
|
+
flowPath,
|
|
1103
|
+
allCompleted
|
|
1080
1104
|
);
|
|
1081
1105
|
}
|
|
1082
1106
|
}
|
|
@@ -1218,6 +1242,7 @@ function getFlowCount() {
|
|
|
1218
1242
|
import { parse, extract, split as split2, categorize as categorize2, trigger, output } from "@doclo/nodes";
|
|
1219
1243
|
|
|
1220
1244
|
// src/composite-nodes.ts
|
|
1245
|
+
import { FlowExecutionError as FlowExecutionError2 } from "@doclo/core";
|
|
1221
1246
|
import { categorize, split } from "@doclo/nodes";
|
|
1222
1247
|
function parseProviderName(name) {
|
|
1223
1248
|
const colonIndex = name.indexOf(":");
|
|
@@ -1363,6 +1388,7 @@ function createConditionalCompositeNode(config) {
|
|
|
1363
1388
|
return branchResult.output;
|
|
1364
1389
|
} catch (error) {
|
|
1365
1390
|
const err = error instanceof Error ? error : new Error(String(error));
|
|
1391
|
+
const isNestedFlowError = err instanceof FlowExecutionError2;
|
|
1366
1392
|
if (ctx?.metrics) {
|
|
1367
1393
|
ctx.metrics.push({
|
|
1368
1394
|
step: stepId,
|
|
@@ -1382,8 +1408,27 @@ function createConditionalCompositeNode(config) {
|
|
|
1382
1408
|
}
|
|
1383
1409
|
});
|
|
1384
1410
|
}
|
|
1385
|
-
|
|
1386
|
-
|
|
1411
|
+
const flowPath = [{
|
|
1412
|
+
stepId,
|
|
1413
|
+
stepIndex: 0,
|
|
1414
|
+
stepType: "conditional",
|
|
1415
|
+
branch: selectedCategory || void 0
|
|
1416
|
+
}];
|
|
1417
|
+
if (isNestedFlowError && err.flowPath) {
|
|
1418
|
+
flowPath.push(...err.flowPath);
|
|
1419
|
+
}
|
|
1420
|
+
const rootCauseMessage = isNestedFlowError ? err.getRootCause().message : err.message;
|
|
1421
|
+
throw new FlowExecutionError2(
|
|
1422
|
+
`Conditional step "${stepId}" failed${selectedCategory ? ` (category: ${selectedCategory})` : ""} in phase: ${phase}
|
|
1423
|
+
Error: ${rootCauseMessage}`,
|
|
1424
|
+
stepId,
|
|
1425
|
+
0,
|
|
1426
|
+
"conditional",
|
|
1427
|
+
[],
|
|
1428
|
+
isNestedFlowError ? err.originalError : err,
|
|
1429
|
+
void 0,
|
|
1430
|
+
flowPath,
|
|
1431
|
+
isNestedFlowError ? err.allCompletedSteps : void 0
|
|
1387
1432
|
);
|
|
1388
1433
|
}
|
|
1389
1434
|
}
|
|
@@ -1520,6 +1565,7 @@ function createForEachCompositeNode(config) {
|
|
|
1520
1565
|
return results;
|
|
1521
1566
|
} catch (error) {
|
|
1522
1567
|
const err = error instanceof Error ? error : new Error(String(error));
|
|
1568
|
+
const isNestedFlowError = err instanceof FlowExecutionError2;
|
|
1523
1569
|
if (ctx?.metrics) {
|
|
1524
1570
|
ctx.metrics.push({
|
|
1525
1571
|
step: stepId,
|
|
@@ -1539,8 +1585,26 @@ function createForEachCompositeNode(config) {
|
|
|
1539
1585
|
}
|
|
1540
1586
|
});
|
|
1541
1587
|
}
|
|
1542
|
-
|
|
1543
|
-
|
|
1588
|
+
const flowPath = [{
|
|
1589
|
+
stepId,
|
|
1590
|
+
stepIndex: 0,
|
|
1591
|
+
stepType: "forEach"
|
|
1592
|
+
}];
|
|
1593
|
+
if (isNestedFlowError && err.flowPath) {
|
|
1594
|
+
flowPath.push(...err.flowPath);
|
|
1595
|
+
}
|
|
1596
|
+
const rootCauseMessage = isNestedFlowError ? err.getRootCause().message : err.message;
|
|
1597
|
+
throw new FlowExecutionError2(
|
|
1598
|
+
`ForEach step "${stepId}" failed${items ? ` (itemCount: ${items.length})` : ""} in phase: ${phase}
|
|
1599
|
+
Error: ${rootCauseMessage}`,
|
|
1600
|
+
stepId,
|
|
1601
|
+
0,
|
|
1602
|
+
"forEach",
|
|
1603
|
+
[],
|
|
1604
|
+
isNestedFlowError ? err.originalError : err,
|
|
1605
|
+
void 0,
|
|
1606
|
+
flowPath,
|
|
1607
|
+
isNestedFlowError ? err.allCompletedSteps : void 0
|
|
1544
1608
|
);
|
|
1545
1609
|
}
|
|
1546
1610
|
}
|
|
@@ -2519,7 +2583,9 @@ export {
|
|
|
2519
2583
|
getFlow,
|
|
2520
2584
|
getFlowCount,
|
|
2521
2585
|
hasFlow,
|
|
2586
|
+
isBatchFlowResult,
|
|
2522
2587
|
isFlowReference,
|
|
2588
|
+
isSingleFlowResult,
|
|
2523
2589
|
listFlows,
|
|
2524
2590
|
parse2 as parse,
|
|
2525
2591
|
registerFlow,
|