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.
Files changed (211) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +17 -1
  3. package/README.md +305 -184
  4. package/dist/barrier.d.ts +159 -0
  5. package/dist/barrier.d.ts.map +1 -0
  6. package/dist/barrier.js +377 -0
  7. package/dist/barrier.js.map +1 -0
  8. package/dist/cascade-context.d.ts +149 -0
  9. package/dist/cascade-context.d.ts.map +1 -0
  10. package/dist/cascade-context.js +324 -0
  11. package/dist/cascade-context.js.map +1 -0
  12. package/dist/cascade-executor.d.ts +196 -0
  13. package/dist/cascade-executor.d.ts.map +1 -0
  14. package/dist/cascade-executor.js +384 -0
  15. package/dist/cascade-executor.js.map +1 -0
  16. package/dist/context.d.ts.map +1 -1
  17. package/dist/context.js +27 -8
  18. package/dist/context.js.map +1 -1
  19. package/dist/cron-parser.d.ts +65 -0
  20. package/dist/cron-parser.d.ts.map +1 -0
  21. package/dist/cron-parser.js +294 -0
  22. package/dist/cron-parser.js.map +1 -0
  23. package/dist/cron-scheduler.d.ts +117 -0
  24. package/dist/cron-scheduler.d.ts.map +1 -0
  25. package/dist/cron-scheduler.js +176 -0
  26. package/dist/cron-scheduler.js.map +1 -0
  27. package/dist/database-context.d.ts +184 -0
  28. package/dist/database-context.d.ts.map +1 -0
  29. package/dist/database-context.js +428 -0
  30. package/dist/database-context.js.map +1 -0
  31. package/dist/dependency-graph.d.ts +157 -0
  32. package/dist/dependency-graph.d.ts.map +1 -0
  33. package/dist/dependency-graph.js +382 -0
  34. package/dist/dependency-graph.js.map +1 -0
  35. package/dist/digital-objects-adapter.d.ts +159 -0
  36. package/dist/digital-objects-adapter.d.ts.map +1 -0
  37. package/dist/digital-objects-adapter.js +229 -0
  38. package/dist/digital-objects-adapter.js.map +1 -0
  39. package/dist/durable-execution-cloudflare.d.ts +427 -0
  40. package/dist/durable-execution-cloudflare.d.ts.map +1 -0
  41. package/dist/durable-execution-cloudflare.js +510 -0
  42. package/dist/durable-execution-cloudflare.js.map +1 -0
  43. package/dist/durable-execution.d.ts +482 -0
  44. package/dist/durable-execution.d.ts.map +1 -0
  45. package/dist/durable-execution.js +594 -0
  46. package/dist/durable-execution.js.map +1 -0
  47. package/dist/durable-workflow.d.ts +176 -0
  48. package/dist/durable-workflow.d.ts.map +1 -0
  49. package/dist/durable-workflow.js +552 -0
  50. package/dist/durable-workflow.js.map +1 -0
  51. package/dist/every.d.ts +31 -2
  52. package/dist/every.d.ts.map +1 -1
  53. package/dist/every.js +63 -32
  54. package/dist/every.js.map +1 -1
  55. package/dist/graph/index.d.ts +8 -0
  56. package/dist/graph/index.d.ts.map +1 -0
  57. package/dist/graph/index.js +8 -0
  58. package/dist/graph/index.js.map +1 -0
  59. package/dist/graph/topological-sort.d.ts +121 -0
  60. package/dist/graph/topological-sort.d.ts.map +1 -0
  61. package/dist/graph/topological-sort.js +292 -0
  62. package/dist/graph/topological-sort.js.map +1 -0
  63. package/dist/index.d.ts +10 -1
  64. package/dist/index.d.ts.map +1 -1
  65. package/dist/index.js +25 -0
  66. package/dist/index.js.map +1 -1
  67. package/dist/logger.d.ts +101 -0
  68. package/dist/logger.d.ts.map +1 -0
  69. package/dist/logger.js +115 -0
  70. package/dist/logger.js.map +1 -0
  71. package/dist/on.d.ts +35 -10
  72. package/dist/on.d.ts.map +1 -1
  73. package/dist/on.js +53 -19
  74. package/dist/on.js.map +1 -1
  75. package/dist/runtime.d.ts +169 -0
  76. package/dist/runtime.d.ts.map +1 -0
  77. package/dist/runtime.js +275 -0
  78. package/dist/runtime.js.map +1 -0
  79. package/dist/send.d.ts.map +1 -1
  80. package/dist/send.js +4 -3
  81. package/dist/send.js.map +1 -1
  82. package/dist/telemetry.d.ts +150 -0
  83. package/dist/telemetry.d.ts.map +1 -0
  84. package/dist/telemetry.js +388 -0
  85. package/dist/telemetry.js.map +1 -0
  86. package/dist/timer-registry.d.ts +77 -0
  87. package/dist/timer-registry.d.ts.map +1 -0
  88. package/dist/timer-registry.js +154 -0
  89. package/dist/timer-registry.js.map +1 -0
  90. package/dist/types.d.ts +105 -6
  91. package/dist/types.d.ts.map +1 -1
  92. package/dist/types.js +17 -1
  93. package/dist/types.js.map +1 -1
  94. package/dist/worker/durable-step.d.ts +481 -0
  95. package/dist/worker/durable-step.d.ts.map +1 -0
  96. package/dist/worker/durable-step.js +606 -0
  97. package/dist/worker/durable-step.js.map +1 -0
  98. package/dist/worker/index.d.ts +106 -0
  99. package/dist/worker/index.d.ts.map +1 -0
  100. package/dist/worker/index.js +124 -0
  101. package/dist/worker/index.js.map +1 -0
  102. package/dist/worker/state-adapter.d.ts +230 -0
  103. package/dist/worker/state-adapter.d.ts.map +1 -0
  104. package/dist/worker/state-adapter.js +409 -0
  105. package/dist/worker/state-adapter.js.map +1 -0
  106. package/dist/worker/topological-executor.d.ts +282 -0
  107. package/dist/worker/topological-executor.d.ts.map +1 -0
  108. package/dist/worker/topological-executor.js +396 -0
  109. package/dist/worker/topological-executor.js.map +1 -0
  110. package/dist/worker/workflow-builder.d.ts +286 -0
  111. package/dist/worker/workflow-builder.d.ts.map +1 -0
  112. package/dist/worker/workflow-builder.js +565 -0
  113. package/dist/worker/workflow-builder.js.map +1 -0
  114. package/dist/worker.d.ts +800 -0
  115. package/dist/worker.d.ts.map +1 -0
  116. package/dist/worker.js +2428 -0
  117. package/dist/worker.js.map +1 -0
  118. package/dist/workflow-builder.d.ts +287 -0
  119. package/dist/workflow-builder.d.ts.map +1 -0
  120. package/dist/workflow-builder.js +762 -0
  121. package/dist/workflow-builder.js.map +1 -0
  122. package/dist/workflow.d.ts +14 -30
  123. package/dist/workflow.d.ts.map +1 -1
  124. package/dist/workflow.js +136 -292
  125. package/dist/workflow.js.map +1 -1
  126. package/examples/01-ecommerce-order-pipeline.ts +358 -0
  127. package/examples/02-content-moderation-cascade.ts +454 -0
  128. package/examples/03-scheduled-reporting-dependencies.ts +479 -0
  129. package/examples/04-database-persistence.ts +518 -0
  130. package/examples/README.md +173 -0
  131. package/package.json +21 -4
  132. package/src/__tests__/digital-objects-adapter.test.ts +274 -0
  133. package/src/__tests__/durable-workflow.test.ts +297 -0
  134. package/src/barrier.ts +507 -0
  135. package/src/cascade-context.ts +495 -0
  136. package/src/cascade-executor.ts +588 -0
  137. package/src/context.ts +51 -17
  138. package/src/cron-parser.ts +347 -0
  139. package/src/cron-scheduler.ts +239 -0
  140. package/src/database-context.ts +658 -0
  141. package/src/dependency-graph.ts +518 -0
  142. package/src/digital-objects-adapter.ts +351 -0
  143. package/src/durable-execution-cloudflare.ts +855 -0
  144. package/src/durable-execution.ts +1042 -0
  145. package/src/durable-workflow.ts +717 -0
  146. package/src/every.ts +104 -35
  147. package/src/graph/index.ts +19 -0
  148. package/src/graph/topological-sort.ts +412 -0
  149. package/src/index.ts +147 -0
  150. package/src/logger.ts +148 -0
  151. package/src/on.ts +81 -26
  152. package/src/runtime.ts +436 -0
  153. package/src/send.ts +4 -5
  154. package/src/telemetry.ts +577 -0
  155. package/src/timer-registry.ts +179 -0
  156. package/src/types.ts +146 -10
  157. package/src/worker/durable-step.ts +976 -0
  158. package/src/worker/index.ts +216 -0
  159. package/src/worker/state-adapter.ts +589 -0
  160. package/src/worker/topological-executor.ts +625 -0
  161. package/src/worker/workflow-builder.ts +871 -0
  162. package/src/worker.ts +2906 -0
  163. package/src/workflow-builder.ts +1068 -0
  164. package/src/workflow.ts +199 -355
  165. package/test/barrier-join.test.ts +442 -0
  166. package/test/barrier-unhandled-rejections.test.ts +359 -0
  167. package/test/cascade-context.test.ts +390 -0
  168. package/test/cascade-executor.test.ts +852 -0
  169. package/test/cron-parser.test.ts +314 -0
  170. package/test/cron-scheduler.test.ts +291 -0
  171. package/test/database-context.test.ts +770 -0
  172. package/test/db-provider-adapter.test.ts +862 -0
  173. package/test/dependency-graph.test.ts +512 -0
  174. package/test/durable-execution-cloudflare.test.ts +606 -0
  175. package/test/durable-execution-in-process.test.ts +286 -0
  176. package/test/durable-execution.test.ts +247 -0
  177. package/test/e2e/workflow-scenarios.e2e.test.ts +1039 -0
  178. package/test/graph/topological-sort.test.ts +586 -0
  179. package/test/integration.test.ts +442 -0
  180. package/test/rpc-surface.test.ts +946 -0
  181. package/test/runtime.test.ts +262 -0
  182. package/test/schedule-timer-cleanup.test.ts +353 -0
  183. package/test/send-race-conditions.test.ts +400 -0
  184. package/test/type-safety-every.test.ts +303 -0
  185. package/test/worker/durable-cascade.test.ts +1117 -0
  186. package/test/worker/durable-step.test.ts +723 -0
  187. package/test/worker/topological-executor.test.ts +1240 -0
  188. package/test/worker/workflow-builder.test.ts +1067 -0
  189. package/test/worker.test.ts +608 -0
  190. package/test/workflow-builder.test.ts +1670 -0
  191. package/test/workflow-cron.test.ts +256 -0
  192. package/test/workflow-state-adapter.test.ts +923 -0
  193. package/test/workflow.test.ts +25 -22
  194. package/tsconfig.json +3 -1
  195. package/vitest.config.ts +38 -1
  196. package/vitest.workers.config.ts +44 -0
  197. package/wrangler.jsonc +22 -0
  198. package/.turbo/turbo-test.log +0 -7
  199. package/src/context.js +0 -83
  200. package/src/every.js +0 -267
  201. package/src/index.js +0 -71
  202. package/src/on.js +0 -79
  203. package/src/send.js +0 -111
  204. package/src/types.js +0 -4
  205. package/src/workflow.js +0 -455
  206. package/test/context.test.js +0 -116
  207. package/test/every.test.js +0 -282
  208. package/test/on.test.js +0 -80
  209. package/test/send.test.js +0 -89
  210. package/test/workflow.test.js +0 -224
  211. 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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"}
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,eAAe,EAA4D,MAAM,YAAY,CAAA;AAE3G;;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,CAwE7E;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,IAAI,eAAe,GAAG;IAAE,gBAAgB,EAAE,MAAM,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,CAAA;KAAE,CAAC,CAAA;CAAE,CAa7H"}
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
- const noOpEveryProxy = new Proxy(function () { }, {
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
- async send(event, data) {
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 eventBus.emit(event, data);
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
- console.log(`[workflow] ${message}`, data ?? '');
83
+ getLogger().log(`[workflow] ${message}`, data ?? '');
65
84
  },
66
85
  };
67
86
  }