yaml-flow 1.0.0 → 2.1.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 (62) hide show
  1. package/README.md +705 -225
  2. package/dist/batch/index.cjs +109 -0
  3. package/dist/batch/index.cjs.map +1 -0
  4. package/dist/batch/index.d.cts +126 -0
  5. package/dist/batch/index.d.ts +126 -0
  6. package/dist/batch/index.js +107 -0
  7. package/dist/batch/index.js.map +1 -0
  8. package/dist/config/index.cjs +80 -0
  9. package/dist/config/index.cjs.map +1 -0
  10. package/dist/config/index.d.cts +71 -0
  11. package/dist/config/index.d.ts +71 -0
  12. package/dist/config/index.js +77 -0
  13. package/dist/config/index.js.map +1 -0
  14. package/dist/constants-D1fTEbbM.d.cts +330 -0
  15. package/dist/constants-D1fTEbbM.d.ts +330 -0
  16. package/dist/event-graph/index.cjs +895 -0
  17. package/dist/event-graph/index.cjs.map +1 -0
  18. package/dist/event-graph/index.d.cts +53 -0
  19. package/dist/event-graph/index.d.ts +53 -0
  20. package/dist/event-graph/index.js +855 -0
  21. package/dist/event-graph/index.js.map +1 -0
  22. package/dist/index.cjs +1309 -312
  23. package/dist/index.cjs.map +1 -1
  24. package/dist/index.d.cts +5 -2
  25. package/dist/index.d.ts +5 -2
  26. package/dist/index.js +1271 -306
  27. package/dist/index.js.map +1 -1
  28. package/dist/step-machine/index.cjs +513 -0
  29. package/dist/step-machine/index.cjs.map +1 -0
  30. package/dist/step-machine/index.d.cts +77 -0
  31. package/dist/step-machine/index.d.ts +77 -0
  32. package/dist/step-machine/index.js +502 -0
  33. package/dist/step-machine/index.js.map +1 -0
  34. package/dist/stores/file.cjs.map +1 -1
  35. package/dist/stores/file.d.cts +4 -4
  36. package/dist/stores/file.d.ts +4 -4
  37. package/dist/stores/file.js.map +1 -1
  38. package/dist/stores/index.cjs +232 -0
  39. package/dist/stores/index.cjs.map +1 -0
  40. package/dist/stores/index.d.cts +4 -0
  41. package/dist/stores/index.d.ts +4 -0
  42. package/dist/stores/index.js +228 -0
  43. package/dist/stores/index.js.map +1 -0
  44. package/dist/stores/localStorage.cjs.map +1 -1
  45. package/dist/stores/localStorage.d.cts +4 -4
  46. package/dist/stores/localStorage.d.ts +4 -4
  47. package/dist/stores/localStorage.js.map +1 -1
  48. package/dist/stores/memory.cjs.map +1 -1
  49. package/dist/stores/memory.d.cts +4 -4
  50. package/dist/stores/memory.d.ts +4 -4
  51. package/dist/stores/memory.js.map +1 -1
  52. package/dist/types-FZ_eyErS.d.cts +115 -0
  53. package/dist/types-FZ_eyErS.d.ts +115 -0
  54. package/package.json +26 -6
  55. package/dist/core/index.cjs +0 -557
  56. package/dist/core/index.cjs.map +0 -1
  57. package/dist/core/index.d.cts +0 -102
  58. package/dist/core/index.d.ts +0 -102
  59. package/dist/core/index.js +0 -549
  60. package/dist/core/index.js.map +0 -1
  61. package/dist/types-BoWndaAJ.d.cts +0 -237
  62. package/dist/types-BoWndaAJ.d.ts +0 -237
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Variable interpolation for workflow configs.
3
+ *
4
+ * Walks any object/array and replaces `${KEY}` patterns with values from
5
+ * a variables map. Pure function — returns a new object, never mutates.
6
+ *
7
+ * Works on both GraphConfig and StepFlowConfig (or any plain object).
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * const resolved = resolveVariables(config, {
12
+ * ENTITY_ID: 'ticket-42',
13
+ * TOOLS_DIR: '/opt/tools',
14
+ * });
15
+ * ```
16
+ */
17
+ type Variables = Record<string, string | number | boolean>;
18
+ /**
19
+ * Resolve `${KEY}` variable references in a workflow config object.
20
+ *
21
+ * Pure function: config in → new config out. Works on any shape
22
+ * (GraphConfig, StepFlowConfig, or arbitrary objects).
23
+ *
24
+ * @param config - The config object to interpolate
25
+ * @param variables - Key-value pairs to substitute
26
+ * @returns A new config with all `${KEY}` patterns replaced
27
+ */
28
+ declare function resolveVariables<T extends Record<string, unknown>>(config: T, variables: Variables): T;
29
+
30
+ /**
31
+ * Config template resolution for workflow configs.
32
+ *
33
+ * In large graphs, many tasks share the same base config (cmd, timeout, cwd, headers, etc.).
34
+ * Instead of duplicating, tasks reference a named template via `config-template`.
35
+ * This function deep-merges the template into each task's config, then removes the reference.
36
+ *
37
+ * Pure function — returns a new config, never mutates.
38
+ *
39
+ * @example
40
+ * ```ts
41
+ * const config = {
42
+ * configTemplates: {
43
+ * PYTHON_TOOL: { cmd: 'python', timeout: 30000, cwd: '/workdata' }
44
+ * },
45
+ * tasks: {
46
+ * analyze: {
47
+ * provides: ['analysis'],
48
+ * config: { 'config-template': 'PYTHON_TOOL', 'cmd-args': 'analyze.py' }
49
+ * }
50
+ * }
51
+ * };
52
+ * const resolved = resolveConfigTemplates(config);
53
+ * // analyze.config → { cmd: 'python', timeout: 30000, cwd: '/workdata', 'cmd-args': 'analyze.py' }
54
+ * ```
55
+ */
56
+ /** Shape of a config-templates block */
57
+ type ConfigTemplates = Record<string, Record<string, unknown>>;
58
+ /**
59
+ * Resolve `config-template` references in task configs against a `configTemplates` map.
60
+ *
61
+ * Accepts any config object that may contain:
62
+ * - `configTemplates` (camelCase) or `config-templates` (kebab-case) at the top level
63
+ * - `tasks` (event-graph) or `steps` (step-machine) containing task/step objects
64
+ * - Each task/step may have a `config` sub-object with a `config-template` key
65
+ *
66
+ * Returns a new config with templates merged and references removed.
67
+ * The `configTemplates` / `config-templates` key is also removed from the output.
68
+ */
69
+ declare function resolveConfigTemplates<T extends Record<string, unknown>>(config: T): T;
70
+
71
+ export { type ConfigTemplates, type Variables, resolveConfigTemplates, resolveVariables };
@@ -0,0 +1,77 @@
1
+ // src/config/resolve-variables.ts
2
+ function interpolateString(template, vars) {
3
+ return template.replace(/\$\{([^}]+)\}/g, (match, key) => {
4
+ const value = vars[key.trim()];
5
+ return value !== void 0 ? String(value) : match;
6
+ });
7
+ }
8
+ function walkAndInterpolate(value, vars) {
9
+ if (typeof value === "string") {
10
+ return interpolateString(value, vars);
11
+ }
12
+ if (Array.isArray(value)) {
13
+ return value.map((item) => walkAndInterpolate(item, vars));
14
+ }
15
+ if (value !== null && typeof value === "object") {
16
+ const result = {};
17
+ for (const [k, v] of Object.entries(value)) {
18
+ result[k] = walkAndInterpolate(v, vars);
19
+ }
20
+ return result;
21
+ }
22
+ return value;
23
+ }
24
+ function resolveVariables(config, variables) {
25
+ return walkAndInterpolate(config, variables);
26
+ }
27
+
28
+ // src/config/resolve-config-templates.ts
29
+ function mergeConfigs(template, taskConfig) {
30
+ const merged = { ...template };
31
+ for (const [key, value] of Object.entries(taskConfig)) {
32
+ if (key === "config-template") continue;
33
+ if (value !== null && typeof value === "object" && !Array.isArray(value) && merged[key] !== null && typeof merged[key] === "object" && !Array.isArray(merged[key])) {
34
+ merged[key] = {
35
+ ...merged[key],
36
+ ...value
37
+ };
38
+ } else {
39
+ merged[key] = value;
40
+ }
41
+ }
42
+ return merged;
43
+ }
44
+ function resolveConfigTemplates(config) {
45
+ const templates = config["configTemplates"] ?? config["config-templates"] ?? {};
46
+ const tasksKey = "tasks" in config ? "tasks" : "steps" in config ? "steps" : null;
47
+ if (!tasksKey) return config;
48
+ const tasks = config[tasksKey];
49
+ if (!tasks || typeof tasks !== "object") return config;
50
+ const resolvedTasks = {};
51
+ for (const [name, task] of Object.entries(tasks)) {
52
+ const taskConfig = task["config"];
53
+ const templateName = taskConfig?.["config-template"];
54
+ if (!templateName || !taskConfig) {
55
+ resolvedTasks[name] = task;
56
+ continue;
57
+ }
58
+ const template = templates[templateName];
59
+ if (!template) {
60
+ const { "config-template": _, ...rest } = taskConfig;
61
+ resolvedTasks[name] = { ...task, config: rest };
62
+ continue;
63
+ }
64
+ resolvedTasks[name] = {
65
+ ...task,
66
+ config: mergeConfigs(template, taskConfig)
67
+ };
68
+ }
69
+ const result = { ...config, [tasksKey]: resolvedTasks };
70
+ delete result["configTemplates"];
71
+ delete result["config-templates"];
72
+ return result;
73
+ }
74
+
75
+ export { resolveConfigTemplates, resolveVariables };
76
+ //# sourceMappingURL=index.js.map
77
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/config/resolve-variables.ts","../../src/config/resolve-config-templates.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Variable interpolation for workflow configs.\n *\n * Walks any object/array and replaces `${KEY}` patterns with values from\n * a variables map. Pure function — returns a new object, never mutates.\n *\n * Works on both GraphConfig and StepFlowConfig (or any plain object).\n *\n * @example\n * ```ts\n * const resolved = resolveVariables(config, {\n * ENTITY_ID: 'ticket-42',\n * TOOLS_DIR: '/opt/tools',\n * });\n * ```\n */\n\nexport type Variables = Record<string, string | number | boolean>;\n\n/**\n * Replace `${KEY}` patterns in a string with values from the variables map.\n * Unmatched variables are left as-is.\n */\nfunction interpolateString(template: string, vars: Variables): string {\n return template.replace(/\\$\\{([^}]+)\\}/g, (match, key: string) => {\n const value = vars[key.trim()];\n return value !== undefined ? String(value) : match;\n });\n}\n\n/**\n * Recursively walk a value and interpolate any `${KEY}` patterns found in strings.\n * Returns a new object/array — never mutates the input.\n */\nfunction walkAndInterpolate<T>(value: T, vars: Variables): T {\n if (typeof value === 'string') {\n return interpolateString(value, vars) as unknown as T;\n }\n if (Array.isArray(value)) {\n return value.map((item) => walkAndInterpolate(item, vars)) as unknown as T;\n }\n if (value !== null && typeof value === 'object') {\n const result: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value)) {\n result[k] = walkAndInterpolate(v, vars);\n }\n return result as T;\n }\n // numbers, booleans, null, undefined — pass through\n return value;\n}\n\n/**\n * Resolve `${KEY}` variable references in a workflow config object.\n *\n * Pure function: config in → new config out. Works on any shape\n * (GraphConfig, StepFlowConfig, or arbitrary objects).\n *\n * @param config - The config object to interpolate\n * @param variables - Key-value pairs to substitute\n * @returns A new config with all `${KEY}` patterns replaced\n */\nexport function resolveVariables<T extends Record<string, unknown>>(\n config: T,\n variables: Variables,\n): T {\n return walkAndInterpolate(config, variables);\n}\n","/**\n * Config template resolution for workflow configs.\n *\n * In large graphs, many tasks share the same base config (cmd, timeout, cwd, headers, etc.).\n * Instead of duplicating, tasks reference a named template via `config-template`.\n * This function deep-merges the template into each task's config, then removes the reference.\n *\n * Pure function — returns a new config, never mutates.\n *\n * @example\n * ```ts\n * const config = {\n * configTemplates: {\n * PYTHON_TOOL: { cmd: 'python', timeout: 30000, cwd: '/workdata' }\n * },\n * tasks: {\n * analyze: {\n * provides: ['analysis'],\n * config: { 'config-template': 'PYTHON_TOOL', 'cmd-args': 'analyze.py' }\n * }\n * }\n * };\n * const resolved = resolveConfigTemplates(config);\n * // analyze.config → { cmd: 'python', timeout: 30000, cwd: '/workdata', 'cmd-args': 'analyze.py' }\n * ```\n */\n\n/** Shape of a config-templates block */\nexport type ConfigTemplates = Record<string, Record<string, unknown>>;\n\n/**\n * Deep-merge template into task config.\n * Task-level values override template values.\n * Nested objects are merged one level deep (like SwarmX's pattern).\n */\nfunction mergeConfigs(\n template: Record<string, unknown>,\n taskConfig: Record<string, unknown>,\n): Record<string, unknown> {\n const merged: Record<string, unknown> = { ...template };\n\n for (const [key, value] of Object.entries(taskConfig)) {\n if (key === 'config-template') continue; // strip the reference\n\n // One-level deep merge for nested objects (both sides must be plain objects)\n if (\n value !== null &&\n typeof value === 'object' &&\n !Array.isArray(value) &&\n merged[key] !== null &&\n typeof merged[key] === 'object' &&\n !Array.isArray(merged[key])\n ) {\n merged[key] = {\n ...(merged[key] as Record<string, unknown>),\n ...(value as Record<string, unknown>),\n };\n } else {\n merged[key] = value;\n }\n }\n\n return merged;\n}\n\n/**\n * Resolve `config-template` references in task configs against a `configTemplates` map.\n *\n * Accepts any config object that may contain:\n * - `configTemplates` (camelCase) or `config-templates` (kebab-case) at the top level\n * - `tasks` (event-graph) or `steps` (step-machine) containing task/step objects\n * - Each task/step may have a `config` sub-object with a `config-template` key\n *\n * Returns a new config with templates merged and references removed.\n * The `configTemplates` / `config-templates` key is also removed from the output.\n */\nexport function resolveConfigTemplates<T extends Record<string, unknown>>(config: T): T {\n // Find templates — support both naming conventions\n const templates: ConfigTemplates =\n (config['configTemplates'] as ConfigTemplates) ??\n (config['config-templates'] as ConfigTemplates) ??\n {};\n\n // Find the tasks/steps container\n const tasksKey = 'tasks' in config ? 'tasks' : 'steps' in config ? 'steps' : null;\n if (!tasksKey) return config; // nothing to resolve\n\n const tasks = config[tasksKey] as Record<string, Record<string, unknown>> | undefined;\n if (!tasks || typeof tasks !== 'object') return config;\n\n const resolvedTasks: Record<string, Record<string, unknown>> = {};\n\n for (const [name, task] of Object.entries(tasks)) {\n const taskConfig = task['config'] as Record<string, unknown> | undefined;\n const templateName = taskConfig?.['config-template'] as string | undefined;\n\n if (!templateName || !taskConfig) {\n resolvedTasks[name] = task;\n continue;\n }\n\n const template = templates[templateName];\n if (!template) {\n // Template not found — leave as-is but strip the reference\n const { 'config-template': _, ...rest } = taskConfig;\n resolvedTasks[name] = { ...task, config: rest };\n continue;\n }\n\n resolvedTasks[name] = {\n ...task,\n config: mergeConfigs(template, taskConfig),\n };\n }\n\n // Build result — remove the templates key from output\n const result = { ...config, [tasksKey]: resolvedTasks };\n delete result['configTemplates'];\n delete result['config-templates'];\n return result as T;\n}\n"]}
@@ -0,0 +1,330 @@
1
+ /**
2
+ * Event Graph — Core Types
3
+ *
4
+ * Type definitions for the stateless event-graph engine.
5
+ * Pure: f(state, event) → newState
6
+ */
7
+ interface GraphConfig {
8
+ id?: string;
9
+ settings: GraphSettings;
10
+ tasks: Record<string, TaskConfig>;
11
+ }
12
+ interface GraphSettings {
13
+ /** Completion strategy */
14
+ completion: CompletionStrategy;
15
+ /** Conflict resolution strategy */
16
+ conflict_strategy?: ConflictStrategy;
17
+ /** Execution mode */
18
+ execution_mode?: ExecutionMode;
19
+ /** Goal outputs — used with 'goal-reached' completion */
20
+ goal?: string[];
21
+ /** Max total scheduler iterations (safety limit, default: 1000) */
22
+ max_iterations?: number;
23
+ /** Timeout in ms (declared for drivers, not enforced by pure engine) */
24
+ timeout_ms?: number;
25
+ }
26
+ interface TaskConfig {
27
+ /** What this task needs to become eligible */
28
+ requires?: string[];
29
+ /** What this task produces on successful completion */
30
+ provides: string[];
31
+ /** Conditional provides based on handler result */
32
+ on?: Record<string, string[]>;
33
+ /** Tokens to inject into available outputs on failure */
34
+ on_failure?: string[];
35
+ /** Task execution method (informational — driver concern) */
36
+ method?: string;
37
+ /** Arbitrary task configuration (driver concern) */
38
+ config?: Record<string, unknown>;
39
+ /** Task priority (higher = preferred in conflict resolution) */
40
+ priority?: number;
41
+ /** Estimated duration in ms (used by duration-first strategy) */
42
+ estimatedDuration?: number;
43
+ /** Estimated cost (used by cost-optimized strategy) */
44
+ estimatedCost?: number;
45
+ /** Resource requirements (used by resource-aware strategy) */
46
+ estimatedResources?: Record<string, number>;
47
+ /** Retry configuration */
48
+ retry?: TaskRetryConfig;
49
+ /** Repeatable task configuration */
50
+ repeatable?: boolean | RepeatableConfig;
51
+ /** Circuit breaker: max executions before breaking */
52
+ circuit_breaker?: TaskCircuitBreakerConfig;
53
+ /** Description */
54
+ description?: string;
55
+ }
56
+ interface TaskRetryConfig {
57
+ max_attempts: number;
58
+ delay_ms?: number;
59
+ backoff_multiplier?: number;
60
+ }
61
+ interface RepeatableConfig {
62
+ /** Max times this task can repeat (undefined = unlimited) */
63
+ max?: number;
64
+ }
65
+ interface TaskCircuitBreakerConfig {
66
+ /** Max executions before injecting break tokens */
67
+ max_executions: number;
68
+ /** Tokens to inject when breaker trips */
69
+ on_break: string[];
70
+ }
71
+ interface ExecutionState {
72
+ /** Current status of the execution */
73
+ status: ExecutionStatus;
74
+ /** Task states keyed by task name */
75
+ tasks: Record<string, TaskState>;
76
+ /** Tokens currently available in the system */
77
+ availableOutputs: string[];
78
+ /** Stuck detection result */
79
+ stuckDetection: StuckDetection;
80
+ /** Last update timestamp */
81
+ lastUpdated: string;
82
+ /** Execution ID for this run */
83
+ executionId: string | null;
84
+ /** Execution configuration */
85
+ executionConfig: ExecutionConfig;
86
+ }
87
+ interface ExecutionConfig {
88
+ executionMode: ExecutionMode;
89
+ conflictStrategy: ConflictStrategy;
90
+ completionStrategy: CompletionStrategy;
91
+ }
92
+ interface TaskState {
93
+ status: TaskStatus;
94
+ executionCount: number;
95
+ retryCount: number;
96
+ lastEpoch: number;
97
+ startedAt?: string;
98
+ completedAt?: string;
99
+ failedAt?: string;
100
+ lastUpdated?: string;
101
+ error?: string;
102
+ messages?: TaskMessage[];
103
+ progress?: number | null;
104
+ }
105
+ interface TaskMessage {
106
+ message: string;
107
+ timestamp: string;
108
+ status: string;
109
+ }
110
+ interface StuckDetection {
111
+ is_stuck: boolean;
112
+ stuck_description: string | null;
113
+ outputs_unresolvable: string[];
114
+ tasks_blocked: string[];
115
+ }
116
+ type GraphEvent = TaskStartedEvent | TaskCompletedEvent | TaskFailedEvent | TaskProgressEvent | InjectTokensEvent | AgentActionEvent | TaskCreationEvent;
117
+ interface TaskStartedEvent {
118
+ type: 'task-started';
119
+ taskName: string;
120
+ timestamp: string;
121
+ executionId?: string;
122
+ }
123
+ interface TaskCompletedEvent {
124
+ type: 'task-completed';
125
+ taskName: string;
126
+ /** Handler result key — used for conditional routing via `on` */
127
+ result?: string;
128
+ /** Data payload from task execution */
129
+ data?: Record<string, unknown>;
130
+ timestamp: string;
131
+ executionId?: string;
132
+ }
133
+ interface TaskFailedEvent {
134
+ type: 'task-failed';
135
+ taskName: string;
136
+ error: string;
137
+ timestamp: string;
138
+ executionId?: string;
139
+ }
140
+ interface TaskProgressEvent {
141
+ type: 'task-progress';
142
+ taskName: string;
143
+ message?: string;
144
+ progress?: number;
145
+ timestamp: string;
146
+ executionId?: string;
147
+ }
148
+ interface InjectTokensEvent {
149
+ type: 'inject-tokens';
150
+ tokens: string[];
151
+ timestamp: string;
152
+ }
153
+ interface AgentActionEvent {
154
+ type: 'agent-action';
155
+ action: 'start' | 'stop' | 'pause' | 'resume';
156
+ timestamp: string;
157
+ config?: Partial<ExecutionConfig>;
158
+ }
159
+ interface TaskCreationEvent {
160
+ type: 'task-creation';
161
+ taskName: string;
162
+ taskConfig: TaskConfig;
163
+ timestamp: string;
164
+ }
165
+ interface SchedulerResult {
166
+ /** Tasks eligible for execution */
167
+ eligibleTasks: string[];
168
+ /** Whether the graph execution is complete */
169
+ isComplete: boolean;
170
+ /** Stuck detection result */
171
+ stuckDetection: StuckDetection;
172
+ /** Whether conflicts were detected */
173
+ hasConflicts: boolean;
174
+ /** Conflict groups: output → competing task names */
175
+ conflicts: Record<string, string[]>;
176
+ /** Strategy used for conflict resolution */
177
+ strategy: ConflictStrategy;
178
+ /** Processing log for diagnostics */
179
+ processingLog: string[];
180
+ }
181
+ type TaskStatus = 'not-started' | 'running' | 'completed' | 'failed' | 'inactivated';
182
+ type ExecutionStatus = 'created' | 'running' | 'paused' | 'stopped' | 'completed' | 'failed';
183
+ type CompletionStrategy = 'all-tasks-done' | 'all-outputs-done' | 'only-resolved' | 'goal-reached' | 'manual';
184
+ type ExecutionMode = 'dependency-mode' | 'eligibility-mode';
185
+ type ConflictStrategy = 'alphabetical' | 'priority-first' | 'duration-first' | 'cost-optimized' | 'resource-aware' | 'random-select' | 'user-choice' | 'parallel-all' | 'skip-conflicts' | 'round-robin';
186
+
187
+ /**
188
+ * Event Graph — Scheduler
189
+ *
190
+ * The core pure function: f(graph, state) → { eligibleTasks, isComplete, isStuck }
191
+ * No I/O, no side effects, deterministic.
192
+ */
193
+
194
+ /**
195
+ * Determine what tasks should be executed next.
196
+ * Pure function — the heart of the event-graph engine.
197
+ */
198
+ declare function next(graph: GraphConfig, state: ExecutionState): SchedulerResult;
199
+ /**
200
+ * Get candidate tasks whose dependencies are all met.
201
+ * Handles repeatable tasks and circuit breakers.
202
+ * Pure function.
203
+ */
204
+ declare function getCandidateTasks(graph: GraphConfig, state: ExecutionState): string[];
205
+
206
+ /**
207
+ * Event Graph — Reducer
208
+ *
209
+ * The core state transition function: f(state, event, graph) → newState
210
+ * No I/O, no side effects, deterministic.
211
+ */
212
+
213
+ /**
214
+ * Apply an event to the current execution state, producing a new state.
215
+ * Pure function — the heart of the event-graph reducer.
216
+ *
217
+ * @param state - Current execution state
218
+ * @param event - Event to apply
219
+ * @param graph - Graph configuration (needed for task definitions)
220
+ * @returns New execution state
221
+ */
222
+ declare function apply(state: ExecutionState, event: GraphEvent, graph: GraphConfig): ExecutionState;
223
+ /**
224
+ * Apply multiple events sequentially. Pure function.
225
+ */
226
+ declare function applyAll(state: ExecutionState, events: GraphEvent[], graph: GraphConfig): ExecutionState;
227
+
228
+ /**
229
+ * Event Graph — Graph Helpers
230
+ *
231
+ * Pure functions for manipulating the requires/provides task dependency graph.
232
+ * No I/O, no side effects.
233
+ */
234
+
235
+ declare function getProvides(task: TaskConfig | undefined): string[];
236
+ declare function getRequires(task: TaskConfig | undefined): string[];
237
+ declare function getAllTasks(graph: GraphConfig): Record<string, TaskConfig>;
238
+ declare function getTask(graph: GraphConfig, taskName: string): TaskConfig | undefined;
239
+ declare function hasTask(graph: GraphConfig, taskName: string): boolean;
240
+ declare function isNonActiveTask(taskState: TaskState | undefined): boolean;
241
+ declare function isTaskCompleted(taskState: TaskState | undefined): boolean;
242
+ declare function isTaskRunning(taskState: TaskState | undefined): boolean;
243
+ declare function isRepeatableTask(taskConfig: TaskConfig): boolean;
244
+ declare function getRepeatableMax(taskConfig: TaskConfig): number | undefined;
245
+ /**
246
+ * Dynamically compute available outputs from all completed tasks.
247
+ * For repeatable tasks, outputs are versioned by epoch.
248
+ * Pure function.
249
+ */
250
+ declare function computeAvailableOutputs(graph: GraphConfig, taskStates: Record<string, TaskState>): string[];
251
+ /**
252
+ * Group candidate tasks by the outputs they provide.
253
+ * Used to detect conflicts (multiple tasks providing the same output).
254
+ */
255
+ declare function groupTasksByProvides(candidateTaskNames: string[], tasks: Record<string, TaskConfig>): Record<string, string[]>;
256
+ /**
257
+ * Check if a task's outputs conflict with other candidates.
258
+ */
259
+ declare function hasOutputConflict(taskName: string, taskProvides: string[], candidates: string[], tasks: Record<string, TaskConfig>): boolean;
260
+ declare function addKeyToProvides(task: TaskConfig, key: string): TaskConfig;
261
+ declare function removeKeyFromProvides(task: TaskConfig, key: string): TaskConfig;
262
+ declare function addKeyToRequires(task: TaskConfig, key: string): TaskConfig;
263
+ declare function removeKeyFromRequires(task: TaskConfig, key: string): TaskConfig;
264
+ /**
265
+ * Add a new task to a graph config. Returns a new GraphConfig (immutable).
266
+ */
267
+ declare function addDynamicTask(graph: GraphConfig, taskName: string, taskConfig: TaskConfig): GraphConfig;
268
+ /**
269
+ * Create default task state for a new task.
270
+ */
271
+ declare function createDefaultTaskState(): TaskState;
272
+ /**
273
+ * Create the initial execution state for a graph.
274
+ */
275
+ declare function createInitialExecutionState(graph: GraphConfig, executionId: string): ExecutionState;
276
+
277
+ /**
278
+ * Event Graph — Completion Detection
279
+ *
280
+ * Pure functions to determine if a graph execution is complete.
281
+ */
282
+
283
+ interface CompletionResult {
284
+ isComplete: boolean;
285
+ expectedCompletion: {
286
+ taskNames: string[];
287
+ outputs: string[];
288
+ };
289
+ }
290
+ /**
291
+ * Check if graph execution is complete based on the configured strategy.
292
+ * Pure function.
293
+ */
294
+ declare function isExecutionComplete(graph: GraphConfig, state: ExecutionState): CompletionResult;
295
+
296
+ /**
297
+ * Event Graph — Stuck Detection
298
+ *
299
+ * Pure function to detect when a graph execution cannot make progress.
300
+ */
301
+
302
+ /**
303
+ * Detect if the graph execution is stuck.
304
+ * Stuck = no eligible tasks AND execution is not complete.
305
+ * Pure function.
306
+ */
307
+ declare function detectStuckState(params: {
308
+ graph: GraphConfig;
309
+ state: ExecutionState;
310
+ eligibleTasks: string[];
311
+ completionResult?: CompletionResult;
312
+ }): StuckDetection;
313
+
314
+ /**
315
+ * Event Graph — Constants
316
+ */
317
+
318
+ declare const TASK_STATUS: Record<string, TaskStatus>;
319
+ declare const EXECUTION_STATUS: Record<string, ExecutionStatus>;
320
+ declare const COMPLETION_STRATEGIES: Record<string, CompletionStrategy>;
321
+ declare const EXECUTION_MODES: Record<string, ExecutionMode>;
322
+ declare const CONFLICT_STRATEGIES: Record<string, ConflictStrategy>;
323
+ declare const DEFAULTS: {
324
+ readonly EXECUTION_MODE: ExecutionMode;
325
+ readonly CONFLICT_STRATEGY: ConflictStrategy;
326
+ readonly COMPLETION_STRATEGY: CompletionStrategy;
327
+ readonly MAX_ITERATIONS: 1000;
328
+ };
329
+
330
+ export { getRepeatableMax as $, type AgentActionEvent as A, getAllTasks as B, COMPLETION_STRATEGIES as C, DEFAULTS as D, EXECUTION_MODES as E, getCandidateTasks as F, type GraphConfig as G, getProvides as H, type InjectTokensEvent as I, getRequires as J, getTask as K, hasTask as L, isExecutionComplete as M, isNonActiveTask as N, isRepeatableTask as O, isTaskCompleted as P, isTaskRunning as Q, next as R, type SchedulerResult as S, type TaskConfig as T, type RepeatableConfig as U, type TaskCircuitBreakerConfig as V, type TaskMessage as W, type TaskProgressEvent as X, type TaskRetryConfig as Y, addKeyToProvides as Z, addKeyToRequires as _, CONFLICT_STRATEGIES as a, groupTasksByProvides as a0, hasOutputConflict as a1, removeKeyFromProvides as a2, removeKeyFromRequires as a3, type CompletionResult as b, type CompletionStrategy as c, type ConflictStrategy as d, EXECUTION_STATUS as e, type ExecutionConfig as f, type ExecutionMode as g, type ExecutionState as h, type ExecutionStatus as i, type GraphEvent as j, type GraphSettings as k, type StuckDetection as l, TASK_STATUS as m, type TaskCompletedEvent as n, type TaskCreationEvent as o, type TaskFailedEvent as p, type TaskStartedEvent as q, type TaskState as r, type TaskStatus as s, addDynamicTask as t, apply as u, applyAll as v, computeAvailableOutputs as w, createDefaultTaskState as x, createInitialExecutionState as y, detectStuckState as z };