ai-workflows 2.1.1 → 2.3.0
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/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +17 -1
- package/README.md +305 -184
- package/dist/barrier.d.ts +159 -0
- package/dist/barrier.d.ts.map +1 -0
- package/dist/barrier.js +377 -0
- package/dist/barrier.js.map +1 -0
- package/dist/cascade-context.d.ts +149 -0
- package/dist/cascade-context.d.ts.map +1 -0
- package/dist/cascade-context.js +324 -0
- package/dist/cascade-context.js.map +1 -0
- package/dist/cascade-executor.d.ts +196 -0
- package/dist/cascade-executor.d.ts.map +1 -0
- package/dist/cascade-executor.js +384 -0
- package/dist/cascade-executor.js.map +1 -0
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +27 -8
- package/dist/context.js.map +1 -1
- package/dist/cron-parser.d.ts +65 -0
- package/dist/cron-parser.d.ts.map +1 -0
- package/dist/cron-parser.js +294 -0
- package/dist/cron-parser.js.map +1 -0
- package/dist/cron-scheduler.d.ts +117 -0
- package/dist/cron-scheduler.d.ts.map +1 -0
- package/dist/cron-scheduler.js +176 -0
- package/dist/cron-scheduler.js.map +1 -0
- package/dist/database-context.d.ts +184 -0
- package/dist/database-context.d.ts.map +1 -0
- package/dist/database-context.js +428 -0
- package/dist/database-context.js.map +1 -0
- package/dist/dependency-graph.d.ts +157 -0
- package/dist/dependency-graph.d.ts.map +1 -0
- package/dist/dependency-graph.js +382 -0
- package/dist/dependency-graph.js.map +1 -0
- package/dist/digital-objects-adapter.d.ts +159 -0
- package/dist/digital-objects-adapter.d.ts.map +1 -0
- package/dist/digital-objects-adapter.js +229 -0
- package/dist/digital-objects-adapter.js.map +1 -0
- package/dist/durable-execution-cloudflare.d.ts +427 -0
- package/dist/durable-execution-cloudflare.d.ts.map +1 -0
- package/dist/durable-execution-cloudflare.js +510 -0
- package/dist/durable-execution-cloudflare.js.map +1 -0
- package/dist/durable-execution.d.ts +482 -0
- package/dist/durable-execution.d.ts.map +1 -0
- package/dist/durable-execution.js +594 -0
- package/dist/durable-execution.js.map +1 -0
- package/dist/durable-workflow.d.ts +176 -0
- package/dist/durable-workflow.d.ts.map +1 -0
- package/dist/durable-workflow.js +552 -0
- package/dist/durable-workflow.js.map +1 -0
- package/dist/every.d.ts +31 -2
- package/dist/every.d.ts.map +1 -1
- package/dist/every.js +63 -32
- package/dist/every.js.map +1 -1
- package/dist/graph/index.d.ts +8 -0
- package/dist/graph/index.d.ts.map +1 -0
- package/dist/graph/index.js +8 -0
- package/dist/graph/index.js.map +1 -0
- package/dist/graph/topological-sort.d.ts +121 -0
- package/dist/graph/topological-sort.d.ts.map +1 -0
- package/dist/graph/topological-sort.js +292 -0
- package/dist/graph/topological-sort.js.map +1 -0
- package/dist/index.d.ts +10 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -1
- package/dist/logger.d.ts +101 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +115 -0
- package/dist/logger.js.map +1 -0
- package/dist/on.d.ts +35 -10
- package/dist/on.d.ts.map +1 -1
- package/dist/on.js +53 -19
- package/dist/on.js.map +1 -1
- package/dist/runtime.d.ts +169 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +275 -0
- package/dist/runtime.js.map +1 -0
- package/dist/send.d.ts.map +1 -1
- package/dist/send.js +4 -3
- package/dist/send.js.map +1 -1
- package/dist/telemetry.d.ts +150 -0
- package/dist/telemetry.d.ts.map +1 -0
- package/dist/telemetry.js +388 -0
- package/dist/telemetry.js.map +1 -0
- package/dist/timer-registry.d.ts +77 -0
- package/dist/timer-registry.d.ts.map +1 -0
- package/dist/timer-registry.js +154 -0
- package/dist/timer-registry.js.map +1 -0
- package/dist/types.d.ts +105 -6
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +17 -1
- package/dist/types.js.map +1 -1
- package/dist/worker/durable-step.d.ts +481 -0
- package/dist/worker/durable-step.d.ts.map +1 -0
- package/dist/worker/durable-step.js +606 -0
- package/dist/worker/durable-step.js.map +1 -0
- package/dist/worker/index.d.ts +106 -0
- package/dist/worker/index.d.ts.map +1 -0
- package/dist/worker/index.js +124 -0
- package/dist/worker/index.js.map +1 -0
- package/dist/worker/state-adapter.d.ts +230 -0
- package/dist/worker/state-adapter.d.ts.map +1 -0
- package/dist/worker/state-adapter.js +409 -0
- package/dist/worker/state-adapter.js.map +1 -0
- package/dist/worker/topological-executor.d.ts +282 -0
- package/dist/worker/topological-executor.d.ts.map +1 -0
- package/dist/worker/topological-executor.js +396 -0
- package/dist/worker/topological-executor.js.map +1 -0
- package/dist/worker/workflow-builder.d.ts +286 -0
- package/dist/worker/workflow-builder.d.ts.map +1 -0
- package/dist/worker/workflow-builder.js +565 -0
- package/dist/worker/workflow-builder.js.map +1 -0
- package/dist/worker.d.ts +800 -0
- package/dist/worker.d.ts.map +1 -0
- package/dist/worker.js +2428 -0
- package/dist/worker.js.map +1 -0
- package/dist/workflow-builder.d.ts +287 -0
- package/dist/workflow-builder.d.ts.map +1 -0
- package/dist/workflow-builder.js +762 -0
- package/dist/workflow-builder.js.map +1 -0
- package/dist/workflow.d.ts +14 -30
- package/dist/workflow.d.ts.map +1 -1
- package/dist/workflow.js +136 -292
- package/dist/workflow.js.map +1 -1
- package/examples/01-ecommerce-order-pipeline.ts +358 -0
- package/examples/02-content-moderation-cascade.ts +454 -0
- package/examples/03-scheduled-reporting-dependencies.ts +479 -0
- package/examples/04-database-persistence.ts +518 -0
- package/examples/README.md +173 -0
- package/package.json +21 -4
- package/src/__tests__/digital-objects-adapter.test.ts +274 -0
- package/src/__tests__/durable-workflow.test.ts +297 -0
- package/src/barrier.ts +507 -0
- package/src/cascade-context.ts +495 -0
- package/src/cascade-executor.ts +588 -0
- package/src/context.ts +51 -17
- package/src/cron-parser.ts +347 -0
- package/src/cron-scheduler.ts +239 -0
- package/src/database-context.ts +658 -0
- package/src/dependency-graph.ts +518 -0
- package/src/digital-objects-adapter.ts +351 -0
- package/src/durable-execution-cloudflare.ts +855 -0
- package/src/durable-execution.ts +1042 -0
- package/src/durable-workflow.ts +717 -0
- package/src/every.ts +104 -35
- package/src/graph/index.ts +19 -0
- package/src/graph/topological-sort.ts +412 -0
- package/src/index.ts +147 -0
- package/src/logger.ts +148 -0
- package/src/on.ts +81 -26
- package/src/runtime.ts +436 -0
- package/src/send.ts +4 -5
- package/src/telemetry.ts +577 -0
- package/src/timer-registry.ts +179 -0
- package/src/types.ts +146 -10
- package/src/worker/durable-step.ts +976 -0
- package/src/worker/index.ts +216 -0
- package/src/worker/state-adapter.ts +589 -0
- package/src/worker/topological-executor.ts +625 -0
- package/src/worker/workflow-builder.ts +871 -0
- package/src/worker.ts +2906 -0
- package/src/workflow-builder.ts +1068 -0
- package/src/workflow.ts +199 -355
- package/test/barrier-join.test.ts +442 -0
- package/test/barrier-unhandled-rejections.test.ts +359 -0
- package/test/cascade-context.test.ts +390 -0
- package/test/cascade-executor.test.ts +852 -0
- package/test/cron-parser.test.ts +314 -0
- package/test/cron-scheduler.test.ts +291 -0
- package/test/database-context.test.ts +770 -0
- package/test/db-provider-adapter.test.ts +862 -0
- package/test/dependency-graph.test.ts +512 -0
- package/test/durable-execution-cloudflare.test.ts +606 -0
- package/test/durable-execution-in-process.test.ts +286 -0
- package/test/durable-execution.test.ts +247 -0
- package/test/e2e/workflow-scenarios.e2e.test.ts +1039 -0
- package/test/graph/topological-sort.test.ts +586 -0
- package/test/integration.test.ts +442 -0
- package/test/rpc-surface.test.ts +946 -0
- package/test/runtime.test.ts +262 -0
- package/test/schedule-timer-cleanup.test.ts +353 -0
- package/test/send-race-conditions.test.ts +400 -0
- package/test/type-safety-every.test.ts +303 -0
- package/test/worker/durable-cascade.test.ts +1117 -0
- package/test/worker/durable-step.test.ts +723 -0
- package/test/worker/topological-executor.test.ts +1240 -0
- package/test/worker/workflow-builder.test.ts +1067 -0
- package/test/worker.test.ts +608 -0
- package/test/workflow-builder.test.ts +1670 -0
- package/test/workflow-cron.test.ts +256 -0
- package/test/workflow-state-adapter.test.ts +923 -0
- package/test/workflow.test.ts +25 -22
- package/tsconfig.json +3 -1
- package/vitest.config.ts +38 -1
- package/vitest.workers.config.ts +44 -0
- package/wrangler.jsonc +22 -0
- package/.turbo/turbo-test.log +0 -7
- package/src/context.js +0 -83
- package/src/every.js +0 -267
- package/src/index.js +0 -71
- package/src/on.js +0 -79
- package/src/send.js +0 -111
- package/src/types.js +0 -4
- package/src/workflow.js +0 -455
- package/test/context.test.js +0 -116
- package/test/every.test.js +0 -282
- package/test/on.test.js +0 -80
- package/test/send.test.js +0 -89
- package/test/workflow.test.js +0 -224
- package/vitest.config.js +0 -7
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CascadeExecutor - Code -> Generative -> Agentic -> Human escalation pattern
|
|
3
|
+
*
|
|
4
|
+
* Implements a tiered execution strategy that tries deterministic code first,
|
|
5
|
+
* then escalates to AI-powered solutions, and finally to human-in-the-loop
|
|
6
|
+
* if all automated approaches fail.
|
|
7
|
+
*
|
|
8
|
+
* Features:
|
|
9
|
+
* - Tier escalation on failure
|
|
10
|
+
* - Per-tier and total cascade timeouts
|
|
11
|
+
* - 5W+H event emission for audit trails
|
|
12
|
+
* - Context propagation through tiers
|
|
13
|
+
* - Retry support per tier
|
|
14
|
+
* - Custom skip conditions
|
|
15
|
+
*
|
|
16
|
+
* @packageDocumentation
|
|
17
|
+
*/
|
|
18
|
+
import { type CascadeContext, type FiveWHEvent } from './cascade-context.js';
|
|
19
|
+
/**
|
|
20
|
+
* Ordered list of capability tiers
|
|
21
|
+
*/
|
|
22
|
+
export declare const TIER_ORDER: readonly ["code", "generative", "agentic", "human"];
|
|
23
|
+
/**
|
|
24
|
+
* Default timeouts per tier (from capability-tiers)
|
|
25
|
+
*/
|
|
26
|
+
export declare const DEFAULT_TIER_TIMEOUTS: Record<CapabilityTier, number>;
|
|
27
|
+
/**
|
|
28
|
+
* Capability tier levels
|
|
29
|
+
*/
|
|
30
|
+
export type CapabilityTier = 'code' | 'generative' | 'agentic' | 'human';
|
|
31
|
+
/**
|
|
32
|
+
* Context passed to tier handlers
|
|
33
|
+
*/
|
|
34
|
+
export interface TierContext {
|
|
35
|
+
/** Correlation ID for tracing */
|
|
36
|
+
correlationId: string;
|
|
37
|
+
/** Current tier being executed */
|
|
38
|
+
tier: CapabilityTier;
|
|
39
|
+
/** Input data */
|
|
40
|
+
input: unknown;
|
|
41
|
+
/** Cascade context */
|
|
42
|
+
cascadeContext: CascadeContext;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Handler for a specific tier
|
|
46
|
+
*/
|
|
47
|
+
export interface TierHandler<T = unknown> {
|
|
48
|
+
/** Handler name for debugging */
|
|
49
|
+
name: string;
|
|
50
|
+
/** Execute the tier logic */
|
|
51
|
+
execute: (input: unknown, context: TierContext) => Promise<T>;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Retry configuration per tier
|
|
55
|
+
*/
|
|
56
|
+
export interface TierRetryConfig {
|
|
57
|
+
/** Maximum number of retries */
|
|
58
|
+
maxRetries: number;
|
|
59
|
+
/** Base delay in milliseconds */
|
|
60
|
+
baseDelay: number;
|
|
61
|
+
/** Multiplier for exponential backoff */
|
|
62
|
+
multiplier?: number;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Result from a single tier execution
|
|
66
|
+
*/
|
|
67
|
+
export interface TierResult {
|
|
68
|
+
/** Tier that was executed */
|
|
69
|
+
tier: CapabilityTier;
|
|
70
|
+
/** Whether the tier succeeded */
|
|
71
|
+
success: boolean;
|
|
72
|
+
/** Result value (if success) */
|
|
73
|
+
value?: unknown;
|
|
74
|
+
/** Error (if failure) */
|
|
75
|
+
error?: Error;
|
|
76
|
+
/** Whether the tier timed out */
|
|
77
|
+
timedOut?: boolean;
|
|
78
|
+
/** Duration in milliseconds */
|
|
79
|
+
duration: number;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Metrics from cascade execution
|
|
83
|
+
*/
|
|
84
|
+
export interface CascadeMetrics {
|
|
85
|
+
/** Total execution duration */
|
|
86
|
+
totalDuration: number;
|
|
87
|
+
/** Duration per tier */
|
|
88
|
+
tierDurations: Partial<Record<CapabilityTier, number>>;
|
|
89
|
+
/** Number of retries per tier */
|
|
90
|
+
tierRetries?: Partial<Record<CapabilityTier, number>>;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Result from cascade execution
|
|
94
|
+
*/
|
|
95
|
+
export interface CascadeResult<T = unknown> {
|
|
96
|
+
/** Final result value */
|
|
97
|
+
value: T;
|
|
98
|
+
/** Tier that produced the result */
|
|
99
|
+
tier: CapabilityTier;
|
|
100
|
+
/** History of all tier executions */
|
|
101
|
+
history: TierResult[];
|
|
102
|
+
/** Tiers that were skipped */
|
|
103
|
+
skippedTiers: CapabilityTier[];
|
|
104
|
+
/** Cascade context with tracing info */
|
|
105
|
+
context: CascadeContext;
|
|
106
|
+
/** Execution metrics */
|
|
107
|
+
metrics: CascadeMetrics;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Skip condition function
|
|
111
|
+
*/
|
|
112
|
+
export type SkipCondition = (input: unknown) => boolean;
|
|
113
|
+
/**
|
|
114
|
+
* Configuration for CascadeExecutor
|
|
115
|
+
*/
|
|
116
|
+
export interface CascadeConfig<T = unknown> {
|
|
117
|
+
/** Tier handlers */
|
|
118
|
+
tiers: Partial<Record<CapabilityTier, TierHandler<T>>>;
|
|
119
|
+
/** Per-tier timeouts in milliseconds */
|
|
120
|
+
timeouts?: Partial<Record<CapabilityTier, number>>;
|
|
121
|
+
/** Total cascade timeout in milliseconds */
|
|
122
|
+
totalTimeout?: number;
|
|
123
|
+
/** Use default timeouts from capability-tiers */
|
|
124
|
+
useDefaultTimeouts?: boolean;
|
|
125
|
+
/** Actor identifier for 5W+H events */
|
|
126
|
+
actor?: string;
|
|
127
|
+
/** Cascade name for 5W+H events */
|
|
128
|
+
cascadeName?: string;
|
|
129
|
+
/** Event callback for 5W+H events */
|
|
130
|
+
onEvent?: (event: FiveWHEvent) => void;
|
|
131
|
+
/** Skip conditions per tier */
|
|
132
|
+
skipConditions?: Partial<Record<CapabilityTier, SkipCondition>>;
|
|
133
|
+
/** Retry configuration per tier */
|
|
134
|
+
retryConfig?: Partial<Record<CapabilityTier, TierRetryConfig>>;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Error thrown when cascade times out
|
|
138
|
+
*/
|
|
139
|
+
export declare class CascadeTimeoutError extends Error {
|
|
140
|
+
readonly timeout: number;
|
|
141
|
+
readonly elapsed: number;
|
|
142
|
+
constructor(timeout: number, elapsed: number);
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Error thrown when a tier is skipped
|
|
146
|
+
*/
|
|
147
|
+
export declare class TierSkippedError extends Error {
|
|
148
|
+
readonly tier: CapabilityTier;
|
|
149
|
+
readonly reason: string;
|
|
150
|
+
constructor(tier: CapabilityTier, reason: string);
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Error thrown when all tiers fail
|
|
154
|
+
*/
|
|
155
|
+
export declare class AllTiersFailedError extends Error {
|
|
156
|
+
readonly history: TierResult[];
|
|
157
|
+
constructor(history: TierResult[]);
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* CascadeExecutor implements the code -> generative -> agentic -> human pattern
|
|
161
|
+
*/
|
|
162
|
+
export declare class CascadeExecutor<T = unknown> {
|
|
163
|
+
private readonly config;
|
|
164
|
+
private readonly actor;
|
|
165
|
+
private readonly cascadeName;
|
|
166
|
+
constructor(config: CascadeConfig<T>);
|
|
167
|
+
/**
|
|
168
|
+
* Execute the cascade
|
|
169
|
+
*/
|
|
170
|
+
execute(input: unknown): Promise<CascadeResult<T>>;
|
|
171
|
+
/**
|
|
172
|
+
* Execute a single tier with timeout and retry support
|
|
173
|
+
*/
|
|
174
|
+
private executeTier;
|
|
175
|
+
/**
|
|
176
|
+
* Execute a function with a timeout
|
|
177
|
+
*/
|
|
178
|
+
private executeWithTimeout;
|
|
179
|
+
/**
|
|
180
|
+
* Get timeout for a tier
|
|
181
|
+
*/
|
|
182
|
+
private getTierTimeout;
|
|
183
|
+
/**
|
|
184
|
+
* Get the next configured tier after the given tier
|
|
185
|
+
*/
|
|
186
|
+
private getNextConfiguredTier;
|
|
187
|
+
/**
|
|
188
|
+
* Emit a 5W+H event
|
|
189
|
+
*/
|
|
190
|
+
private emitEvent;
|
|
191
|
+
/**
|
|
192
|
+
* Sleep for a given duration
|
|
193
|
+
*/
|
|
194
|
+
private sleep;
|
|
195
|
+
}
|
|
196
|
+
//# sourceMappingURL=cascade-executor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cascade-executor.d.ts","sourceRoot":"","sources":["../src/cascade-executor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,384 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CascadeExecutor - Code -> Generative -> Agentic -> Human escalation pattern
|
|
3
|
+
*
|
|
4
|
+
* Implements a tiered execution strategy that tries deterministic code first,
|
|
5
|
+
* then escalates to AI-powered solutions, and finally to human-in-the-loop
|
|
6
|
+
* if all automated approaches fail.
|
|
7
|
+
*
|
|
8
|
+
* Features:
|
|
9
|
+
* - Tier escalation on failure
|
|
10
|
+
* - Per-tier and total cascade timeouts
|
|
11
|
+
* - 5W+H event emission for audit trails
|
|
12
|
+
* - Context propagation through tiers
|
|
13
|
+
* - Retry support per tier
|
|
14
|
+
* - Custom skip conditions
|
|
15
|
+
*
|
|
16
|
+
* @packageDocumentation
|
|
17
|
+
*/
|
|
18
|
+
import { createCascadeContext, recordStep, } from './cascade-context.js';
|
|
19
|
+
// ============================================================================
|
|
20
|
+
// Constants
|
|
21
|
+
// ============================================================================
|
|
22
|
+
/**
|
|
23
|
+
* Ordered list of capability tiers
|
|
24
|
+
*/
|
|
25
|
+
export const TIER_ORDER = ['code', 'generative', 'agentic', 'human'];
|
|
26
|
+
/**
|
|
27
|
+
* Default timeouts per tier (from capability-tiers)
|
|
28
|
+
*/
|
|
29
|
+
export const DEFAULT_TIER_TIMEOUTS = {
|
|
30
|
+
code: 5000, // 5 seconds
|
|
31
|
+
generative: 30000, // 30 seconds
|
|
32
|
+
agentic: 300000, // 5 minutes
|
|
33
|
+
human: 86400000, // 24 hours
|
|
34
|
+
};
|
|
35
|
+
// ============================================================================
|
|
36
|
+
// Errors
|
|
37
|
+
// ============================================================================
|
|
38
|
+
/**
|
|
39
|
+
* Error thrown when cascade times out
|
|
40
|
+
*/
|
|
41
|
+
export class CascadeTimeoutError extends Error {
|
|
42
|
+
timeout;
|
|
43
|
+
elapsed;
|
|
44
|
+
constructor(timeout, elapsed) {
|
|
45
|
+
super(`Cascade timed out after ${elapsed}ms (limit: ${timeout}ms)`);
|
|
46
|
+
this.name = 'CascadeTimeoutError';
|
|
47
|
+
this.timeout = timeout;
|
|
48
|
+
this.elapsed = elapsed;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Error thrown when a tier is skipped
|
|
53
|
+
*/
|
|
54
|
+
export class TierSkippedError extends Error {
|
|
55
|
+
tier;
|
|
56
|
+
reason;
|
|
57
|
+
constructor(tier, reason) {
|
|
58
|
+
super(`Tier '${tier}' was skipped: ${reason}`);
|
|
59
|
+
this.name = 'TierSkippedError';
|
|
60
|
+
this.tier = tier;
|
|
61
|
+
this.reason = reason;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Error thrown when all tiers fail
|
|
66
|
+
*/
|
|
67
|
+
export class AllTiersFailedError extends Error {
|
|
68
|
+
history;
|
|
69
|
+
constructor(history) {
|
|
70
|
+
super('All cascade tiers failed');
|
|
71
|
+
this.name = 'AllTiersFailedError';
|
|
72
|
+
this.history = history;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// ============================================================================
|
|
76
|
+
// CascadeExecutor
|
|
77
|
+
// ============================================================================
|
|
78
|
+
/**
|
|
79
|
+
* CascadeExecutor implements the code -> generative -> agentic -> human pattern
|
|
80
|
+
*/
|
|
81
|
+
export class CascadeExecutor {
|
|
82
|
+
config;
|
|
83
|
+
actor;
|
|
84
|
+
cascadeName;
|
|
85
|
+
constructor(config) {
|
|
86
|
+
this.config = config;
|
|
87
|
+
this.actor = config.actor || 'system';
|
|
88
|
+
this.cascadeName = config.cascadeName || 'cascade';
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Execute the cascade
|
|
92
|
+
*/
|
|
93
|
+
async execute(input) {
|
|
94
|
+
const startTime = Date.now();
|
|
95
|
+
const context = createCascadeContext({ name: this.cascadeName });
|
|
96
|
+
const history = [];
|
|
97
|
+
const skippedTiers = [];
|
|
98
|
+
const tierDurations = {};
|
|
99
|
+
// Emit cascade start event
|
|
100
|
+
this.emitEvent({
|
|
101
|
+
who: this.actor,
|
|
102
|
+
what: 'cascade-start',
|
|
103
|
+
when: startTime,
|
|
104
|
+
where: this.cascadeName,
|
|
105
|
+
how: {
|
|
106
|
+
status: 'running',
|
|
107
|
+
metadata: { input },
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
// Set up total timeout if configured
|
|
111
|
+
let totalTimeoutId;
|
|
112
|
+
let totalTimedOut = false;
|
|
113
|
+
const totalTimeoutPromise = new Promise((_, reject) => {
|
|
114
|
+
if (this.config.totalTimeout) {
|
|
115
|
+
totalTimeoutId = setTimeout(() => {
|
|
116
|
+
totalTimedOut = true;
|
|
117
|
+
reject(new CascadeTimeoutError(this.config.totalTimeout, Date.now() - startTime));
|
|
118
|
+
}, this.config.totalTimeout);
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
try {
|
|
122
|
+
// Execute tiers in order
|
|
123
|
+
for (const tier of TIER_ORDER) {
|
|
124
|
+
if (totalTimedOut)
|
|
125
|
+
break;
|
|
126
|
+
const handler = this.config.tiers[tier];
|
|
127
|
+
// Check if tier should be skipped
|
|
128
|
+
if (!handler) {
|
|
129
|
+
skippedTiers.push(tier);
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
// Check skip condition
|
|
133
|
+
const skipCondition = this.config.skipConditions?.[tier];
|
|
134
|
+
if (skipCondition && skipCondition(input)) {
|
|
135
|
+
skippedTiers.push(tier);
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
// Execute tier
|
|
139
|
+
const tierResult = await this.executeTier(tier, handler, input, context, startTime, totalTimeoutPromise);
|
|
140
|
+
history.push(tierResult);
|
|
141
|
+
tierDurations[tier] = tierResult.duration;
|
|
142
|
+
// If tier succeeded, we're done
|
|
143
|
+
if (tierResult.success && tierResult.value !== undefined) {
|
|
144
|
+
if (totalTimeoutId)
|
|
145
|
+
clearTimeout(totalTimeoutId);
|
|
146
|
+
const endTime = Date.now();
|
|
147
|
+
this.emitEvent({
|
|
148
|
+
who: this.actor,
|
|
149
|
+
what: 'cascade-complete',
|
|
150
|
+
when: endTime,
|
|
151
|
+
where: this.cascadeName,
|
|
152
|
+
how: {
|
|
153
|
+
status: 'completed',
|
|
154
|
+
duration: endTime - startTime,
|
|
155
|
+
metadata: { tier, value: tierResult.value },
|
|
156
|
+
},
|
|
157
|
+
});
|
|
158
|
+
return {
|
|
159
|
+
value: tierResult.value,
|
|
160
|
+
tier,
|
|
161
|
+
history,
|
|
162
|
+
skippedTiers,
|
|
163
|
+
context,
|
|
164
|
+
metrics: {
|
|
165
|
+
totalDuration: endTime - startTime,
|
|
166
|
+
tierDurations,
|
|
167
|
+
},
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
// Check if we timed out
|
|
172
|
+
if (totalTimedOut) {
|
|
173
|
+
if (totalTimeoutId)
|
|
174
|
+
clearTimeout(totalTimeoutId);
|
|
175
|
+
throw new CascadeTimeoutError(this.config.totalTimeout, Date.now() - startTime);
|
|
176
|
+
}
|
|
177
|
+
// All tiers failed
|
|
178
|
+
if (totalTimeoutId)
|
|
179
|
+
clearTimeout(totalTimeoutId);
|
|
180
|
+
throw new AllTiersFailedError(history);
|
|
181
|
+
}
|
|
182
|
+
catch (error) {
|
|
183
|
+
if (totalTimeoutId)
|
|
184
|
+
clearTimeout(totalTimeoutId);
|
|
185
|
+
const endTime = Date.now();
|
|
186
|
+
this.emitEvent({
|
|
187
|
+
who: this.actor,
|
|
188
|
+
what: 'cascade-failed',
|
|
189
|
+
when: endTime,
|
|
190
|
+
where: this.cascadeName,
|
|
191
|
+
why: error instanceof Error ? error.message : String(error),
|
|
192
|
+
how: {
|
|
193
|
+
status: 'failed',
|
|
194
|
+
duration: endTime - startTime,
|
|
195
|
+
},
|
|
196
|
+
});
|
|
197
|
+
throw error;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Execute a single tier with timeout and retry support
|
|
202
|
+
*/
|
|
203
|
+
async executeTier(tier, handler, input, cascadeContext, cascadeStartTime, totalTimeoutPromise) {
|
|
204
|
+
const tierStartTime = Date.now();
|
|
205
|
+
// Record step start
|
|
206
|
+
const step = recordStep(cascadeContext, tier, {
|
|
207
|
+
actor: this.actor,
|
|
208
|
+
action: `execute-${tier}`,
|
|
209
|
+
});
|
|
210
|
+
// Emit tier start event
|
|
211
|
+
this.emitEvent({
|
|
212
|
+
who: this.actor,
|
|
213
|
+
what: `tier-${tier}-execute`,
|
|
214
|
+
when: tierStartTime,
|
|
215
|
+
where: this.cascadeName,
|
|
216
|
+
how: {
|
|
217
|
+
status: 'running',
|
|
218
|
+
metadata: { tier },
|
|
219
|
+
},
|
|
220
|
+
});
|
|
221
|
+
// Determine timeout
|
|
222
|
+
const timeout = this.getTierTimeout(tier);
|
|
223
|
+
// Create tier context
|
|
224
|
+
const tierContext = {
|
|
225
|
+
correlationId: cascadeContext.correlationId,
|
|
226
|
+
tier,
|
|
227
|
+
input,
|
|
228
|
+
cascadeContext,
|
|
229
|
+
};
|
|
230
|
+
// Get retry config
|
|
231
|
+
const retryConfig = this.config.retryConfig?.[tier];
|
|
232
|
+
const maxRetries = retryConfig?.maxRetries ?? 0;
|
|
233
|
+
let lastError;
|
|
234
|
+
let attempts = 0;
|
|
235
|
+
while (attempts <= maxRetries) {
|
|
236
|
+
try {
|
|
237
|
+
// Execute with timeout
|
|
238
|
+
const result = await this.executeWithTimeout(() => handler.execute(input, tierContext), timeout, totalTimeoutPromise);
|
|
239
|
+
const duration = Date.now() - tierStartTime;
|
|
240
|
+
// Mark step complete
|
|
241
|
+
step.complete();
|
|
242
|
+
// Emit tier success event
|
|
243
|
+
this.emitEvent({
|
|
244
|
+
who: this.actor,
|
|
245
|
+
what: `tier-${tier}-execute`,
|
|
246
|
+
when: Date.now(),
|
|
247
|
+
where: this.cascadeName,
|
|
248
|
+
how: {
|
|
249
|
+
status: 'completed',
|
|
250
|
+
duration,
|
|
251
|
+
metadata: { tier, result },
|
|
252
|
+
},
|
|
253
|
+
});
|
|
254
|
+
return {
|
|
255
|
+
tier,
|
|
256
|
+
success: true,
|
|
257
|
+
value: result,
|
|
258
|
+
duration,
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
catch (error) {
|
|
262
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
263
|
+
attempts++;
|
|
264
|
+
// Check if it's a timeout error
|
|
265
|
+
const isTimeout = lastError.message.includes('timed out') || lastError.name === 'TimeoutError';
|
|
266
|
+
// If we've exhausted retries or it's a total timeout, stop
|
|
267
|
+
if (attempts > maxRetries || lastError instanceof CascadeTimeoutError) {
|
|
268
|
+
const duration = Date.now() - tierStartTime;
|
|
269
|
+
// Mark step failed
|
|
270
|
+
step.fail(lastError);
|
|
271
|
+
// Emit tier failure event
|
|
272
|
+
this.emitEvent({
|
|
273
|
+
who: this.actor,
|
|
274
|
+
what: `tier-${tier}-execute`,
|
|
275
|
+
when: Date.now(),
|
|
276
|
+
where: this.cascadeName,
|
|
277
|
+
why: lastError.message,
|
|
278
|
+
how: {
|
|
279
|
+
status: 'failed',
|
|
280
|
+
duration,
|
|
281
|
+
metadata: { tier, error: lastError.message },
|
|
282
|
+
},
|
|
283
|
+
});
|
|
284
|
+
// Emit escalation event if not last tier
|
|
285
|
+
const nextTier = this.getNextConfiguredTier(tier);
|
|
286
|
+
if (nextTier) {
|
|
287
|
+
this.emitEvent({
|
|
288
|
+
who: this.actor,
|
|
289
|
+
what: `escalate-to-${nextTier}`,
|
|
290
|
+
when: Date.now(),
|
|
291
|
+
where: this.cascadeName,
|
|
292
|
+
why: lastError.message,
|
|
293
|
+
how: {
|
|
294
|
+
status: 'running',
|
|
295
|
+
metadata: { fromTier: tier, toTier: nextTier },
|
|
296
|
+
},
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
return {
|
|
300
|
+
tier,
|
|
301
|
+
success: false,
|
|
302
|
+
error: lastError,
|
|
303
|
+
timedOut: isTimeout,
|
|
304
|
+
duration,
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
// Wait before retry with exponential backoff
|
|
308
|
+
if (retryConfig) {
|
|
309
|
+
const delay = retryConfig.baseDelay * Math.pow(retryConfig.multiplier ?? 2, attempts - 1);
|
|
310
|
+
await this.sleep(delay);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
// Should not reach here, but handle edge case
|
|
315
|
+
const duration = Date.now() - tierStartTime;
|
|
316
|
+
return {
|
|
317
|
+
tier,
|
|
318
|
+
success: false,
|
|
319
|
+
...(lastError !== undefined && { error: lastError }),
|
|
320
|
+
duration,
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Execute a function with a timeout
|
|
325
|
+
*/
|
|
326
|
+
async executeWithTimeout(fn, timeout, totalTimeoutPromise) {
|
|
327
|
+
const promises = [fn()];
|
|
328
|
+
// Add total timeout race
|
|
329
|
+
if (this.config.totalTimeout) {
|
|
330
|
+
promises.push(totalTimeoutPromise);
|
|
331
|
+
}
|
|
332
|
+
// Add tier timeout
|
|
333
|
+
if (timeout) {
|
|
334
|
+
promises.push(new Promise((_, reject) => {
|
|
335
|
+
setTimeout(() => {
|
|
336
|
+
const error = new Error(`Tier timed out after ${timeout}ms`);
|
|
337
|
+
error.name = 'TimeoutError';
|
|
338
|
+
reject(error);
|
|
339
|
+
}, timeout);
|
|
340
|
+
}));
|
|
341
|
+
}
|
|
342
|
+
return Promise.race(promises);
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Get timeout for a tier
|
|
346
|
+
*/
|
|
347
|
+
getTierTimeout(tier) {
|
|
348
|
+
if (this.config.timeouts?.[tier]) {
|
|
349
|
+
return this.config.timeouts[tier];
|
|
350
|
+
}
|
|
351
|
+
if (this.config.useDefaultTimeouts) {
|
|
352
|
+
return DEFAULT_TIER_TIMEOUTS[tier];
|
|
353
|
+
}
|
|
354
|
+
return undefined;
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* Get the next configured tier after the given tier
|
|
358
|
+
*/
|
|
359
|
+
getNextConfiguredTier(currentTier) {
|
|
360
|
+
const currentIndex = TIER_ORDER.indexOf(currentTier);
|
|
361
|
+
for (let i = currentIndex + 1; i < TIER_ORDER.length; i++) {
|
|
362
|
+
const tier = TIER_ORDER[i];
|
|
363
|
+
if (tier && this.config.tiers[tier]) {
|
|
364
|
+
return tier;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
return undefined;
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* Emit a 5W+H event
|
|
371
|
+
*/
|
|
372
|
+
emitEvent(event) {
|
|
373
|
+
if (this.config.onEvent) {
|
|
374
|
+
this.config.onEvent(event);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* Sleep for a given duration
|
|
379
|
+
*/
|
|
380
|
+
sleep(ms) {
|
|
381
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
//# sourceMappingURL=cascade-executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cascade-executor.js","sourceRoot":"","sources":["../src/cascade-executor.ts"],"names":[],"mappings":"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"}
|
package/dist/context.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,eAAe,EAOhB,MAAM,YAAY,CAAA;AAGnB;;GAEG;AACH,UAAU,YAAY;IACpB,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAClD;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,YAAY,GAAG,eAAe,CA+F7E;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,IAAI,eAAe,GAAG;IACzD,gBAAgB,EAAE,MAAM,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,CAAA;KAAE,CAAC,CAAA;CAChE,CAaA"}
|
package/dist/context.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Workflow context implementation
|
|
3
3
|
*/
|
|
4
|
+
import { getLogger } from './logger.js';
|
|
4
5
|
/**
|
|
5
6
|
* Create a workflow context
|
|
6
7
|
*/
|
|
@@ -21,20 +22,38 @@ export function createWorkflowContext(eventBus) {
|
|
|
21
22
|
return new Proxy({}, {
|
|
22
23
|
get() {
|
|
23
24
|
return () => { };
|
|
24
|
-
}
|
|
25
|
+
},
|
|
25
26
|
});
|
|
26
|
-
}
|
|
27
|
+
},
|
|
27
28
|
});
|
|
28
|
-
|
|
29
|
+
// Cast to EveryProxy is safe: Proxy handler implements all EveryProxy behaviors dynamically
|
|
30
|
+
const noOpEveryProxy = new Proxy(
|
|
31
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
32
|
+
((_description, _handler) => { }), {
|
|
29
33
|
get() {
|
|
30
34
|
return () => () => { };
|
|
31
35
|
},
|
|
32
|
-
apply() { }
|
|
36
|
+
apply() { },
|
|
33
37
|
});
|
|
34
38
|
return {
|
|
35
|
-
|
|
39
|
+
track(event, data) {
|
|
40
|
+
// Fire and forget - swallow errors
|
|
41
|
+
try {
|
|
42
|
+
addHistory({ type: 'event', name: `track:${event}`, data });
|
|
43
|
+
eventBus.emit(event, data).catch(() => { });
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
// Silently swallow errors
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
send(event, data) {
|
|
50
|
+
const eventId = crypto.randomUUID();
|
|
36
51
|
addHistory({ type: 'event', name: event, data });
|
|
37
|
-
await
|
|
52
|
+
// Fire async but don't await - guaranteed delivery via event bus
|
|
53
|
+
eventBus.emit(event, { ...data, _eventId: eventId }).catch((err) => {
|
|
54
|
+
getLogger().error(`[workflow] Failed to send event ${event}:`, err);
|
|
55
|
+
});
|
|
56
|
+
return eventId;
|
|
38
57
|
},
|
|
39
58
|
async do(_event, _data) {
|
|
40
59
|
throw new Error('$.do not available in this context');
|
|
@@ -48,7 +67,7 @@ export function createWorkflowContext(eventBus) {
|
|
|
48
67
|
getState() {
|
|
49
68
|
// Return a deep copy to prevent mutation
|
|
50
69
|
return {
|
|
51
|
-
current: workflowState.current,
|
|
70
|
+
...(workflowState.current !== undefined && { current: workflowState.current }),
|
|
52
71
|
context: { ...workflowState.context },
|
|
53
72
|
history: [...workflowState.history],
|
|
54
73
|
};
|
|
@@ -61,7 +80,7 @@ export function createWorkflowContext(eventBus) {
|
|
|
61
80
|
},
|
|
62
81
|
log(message, data) {
|
|
63
82
|
addHistory({ type: 'action', name: 'log', data: { message, data } });
|
|
64
|
-
|
|
83
|
+
getLogger().log(`[workflow] ${message}`, data ?? '');
|
|
65
84
|
},
|
|
66
85
|
};
|
|
67
86
|
}
|