@doclo/flows 0.1.2 → 0.1.4
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 +23 -2
- package/dist/index.js +88 -18
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
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.
|
|
@@ -537,6 +554,7 @@ type ParseConfig = {
|
|
|
537
554
|
strategy?: 'majority' | 'unanimous';
|
|
538
555
|
onTie?: 'random' | 'fail' | 'retry';
|
|
539
556
|
};
|
|
557
|
+
maxTokens?: number;
|
|
540
558
|
};
|
|
541
559
|
type ExtractConfig = {
|
|
542
560
|
type: 'extract';
|
|
@@ -552,6 +570,7 @@ type ExtractConfig = {
|
|
|
552
570
|
effort?: 'low' | 'medium' | 'high';
|
|
553
571
|
max_tokens?: number;
|
|
554
572
|
};
|
|
573
|
+
maxTokens?: number;
|
|
555
574
|
};
|
|
556
575
|
type SplitConfig = {
|
|
557
576
|
type: 'split';
|
|
@@ -564,6 +583,7 @@ type SplitConfig = {
|
|
|
564
583
|
onTie?: 'random' | 'fail' | 'retry';
|
|
565
584
|
};
|
|
566
585
|
schemaRef?: string;
|
|
586
|
+
maxTokens?: number;
|
|
567
587
|
};
|
|
568
588
|
type CategorizeConfig = {
|
|
569
589
|
type: 'categorize';
|
|
@@ -575,6 +595,7 @@ type CategorizeConfig = {
|
|
|
575
595
|
onTie?: 'random' | 'fail' | 'retry';
|
|
576
596
|
};
|
|
577
597
|
promptRef?: string;
|
|
598
|
+
maxTokens?: number;
|
|
578
599
|
};
|
|
579
600
|
type TriggerConfig = {
|
|
580
601
|
type: 'trigger';
|
|
@@ -929,4 +950,4 @@ declare function buildTwoProviderFlow(opts: {
|
|
|
929
950
|
}>;
|
|
930
951
|
};
|
|
931
952
|
|
|
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 };
|
|
953
|
+
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
|
}
|
|
@@ -1743,7 +1807,8 @@ function createNodeFromConfig(nodeType, config, providers, flows) {
|
|
|
1743
1807
|
const cfg = config;
|
|
1744
1808
|
return parse({
|
|
1745
1809
|
provider,
|
|
1746
|
-
consensus: cfg.consensus
|
|
1810
|
+
consensus: cfg.consensus,
|
|
1811
|
+
maxTokens: cfg.maxTokens
|
|
1747
1812
|
});
|
|
1748
1813
|
}
|
|
1749
1814
|
case "extract": {
|
|
@@ -1752,7 +1817,8 @@ function createNodeFromConfig(nodeType, config, providers, flows) {
|
|
|
1752
1817
|
provider,
|
|
1753
1818
|
schema: cfg.schema,
|
|
1754
1819
|
consensus: cfg.consensus,
|
|
1755
|
-
reasoning: cfg.reasoning
|
|
1820
|
+
reasoning: cfg.reasoning,
|
|
1821
|
+
maxTokens: cfg.maxTokens
|
|
1756
1822
|
});
|
|
1757
1823
|
}
|
|
1758
1824
|
case "split": {
|
|
@@ -1761,7 +1827,8 @@ function createNodeFromConfig(nodeType, config, providers, flows) {
|
|
|
1761
1827
|
provider,
|
|
1762
1828
|
schemas: cfg.schemas,
|
|
1763
1829
|
includeOther: cfg.includeOther,
|
|
1764
|
-
consensus: cfg.consensus
|
|
1830
|
+
consensus: cfg.consensus,
|
|
1831
|
+
maxTokens: cfg.maxTokens
|
|
1765
1832
|
});
|
|
1766
1833
|
}
|
|
1767
1834
|
case "categorize": {
|
|
@@ -1769,7 +1836,8 @@ function createNodeFromConfig(nodeType, config, providers, flows) {
|
|
|
1769
1836
|
return categorize2({
|
|
1770
1837
|
provider,
|
|
1771
1838
|
categories: cfg.categories,
|
|
1772
|
-
consensus: cfg.consensus
|
|
1839
|
+
consensus: cfg.consensus,
|
|
1840
|
+
maxTokens: cfg.maxTokens
|
|
1773
1841
|
});
|
|
1774
1842
|
}
|
|
1775
1843
|
default:
|
|
@@ -2519,7 +2587,9 @@ export {
|
|
|
2519
2587
|
getFlow,
|
|
2520
2588
|
getFlowCount,
|
|
2521
2589
|
hasFlow,
|
|
2590
|
+
isBatchFlowResult,
|
|
2522
2591
|
isFlowReference,
|
|
2592
|
+
isSingleFlowResult,
|
|
2523
2593
|
listFlows,
|
|
2524
2594
|
parse2 as parse,
|
|
2525
2595
|
registerFlow,
|