yaml-flow 2.2.0 → 2.4.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/README.md +196 -0
- package/dist/{constants-Bwvkbr5s.d.cts → constants-Dbk6ArN5.d.cts} +52 -187
- package/dist/{constants-Ewufm5cK.d.ts → constants-DcCDDQON.d.ts} +52 -187
- package/dist/continuous-event-graph/index.cjs +939 -0
- package/dist/continuous-event-graph/index.cjs.map +1 -0
- package/dist/continuous-event-graph/index.d.cts +309 -0
- package/dist/continuous-event-graph/index.d.ts +309 -0
- package/dist/continuous-event-graph/index.js +916 -0
- package/dist/continuous-event-graph/index.js.map +1 -0
- package/dist/event-graph/index.cjs +208 -0
- package/dist/event-graph/index.cjs.map +1 -1
- package/dist/event-graph/index.d.cts +3 -2
- package/dist/event-graph/index.d.ts +3 -2
- package/dist/event-graph/index.js +208 -1
- package/dist/event-graph/index.js.map +1 -1
- package/dist/index.cjs +957 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +935 -1
- package/dist/index.js.map +1 -1
- package/dist/types-CTu8RqY0.d.cts +187 -0
- package/dist/types-CTu8RqY0.d.ts +187 -0
- package/package.json +6 -1
package/README.md
CHANGED
|
@@ -801,6 +801,188 @@ Entry points (no requires) get rounded shapes, leaf tasks get double-bracketed s
|
|
|
801
801
|
|
|
802
802
|
---
|
|
803
803
|
|
|
804
|
+
## Graph Validation (Semantic)
|
|
805
|
+
|
|
806
|
+
Validate the logical correctness of a graph — catches issues that structural validation (`validateGraphConfig`) can't.
|
|
807
|
+
|
|
808
|
+
```typescript
|
|
809
|
+
import { validateGraph } from 'yaml-flow/event-graph';
|
|
810
|
+
|
|
811
|
+
const result = validateGraph(graph);
|
|
812
|
+
|
|
813
|
+
result.valid; // true if no errors (warnings/info allowed)
|
|
814
|
+
result.errors; // issues that will break execution
|
|
815
|
+
result.warnings; // issues that may cause unexpected behavior
|
|
816
|
+
result.issues; // all issues (errors + warnings + info)
|
|
817
|
+
|
|
818
|
+
// Each issue
|
|
819
|
+
result.issues[0].severity; // 'error' | 'warning' | 'info'
|
|
820
|
+
result.issues[0].code; // e.g. 'CIRCULAR_DEPENDENCY'
|
|
821
|
+
result.issues[0].message; // human-readable description
|
|
822
|
+
result.issues[0].tasks; // affected task names
|
|
823
|
+
result.issues[0].tokens; // affected tokens
|
|
824
|
+
```
|
|
825
|
+
|
|
826
|
+
| Issue Code | Severity | Description |
|
|
827
|
+
|---|---|---|
|
|
828
|
+
| `EMPTY_GRAPH` | error | Graph has no tasks |
|
|
829
|
+
| `DANGLING_REQUIRES` | error | Task requires a token that no task produces |
|
|
830
|
+
| `CIRCULAR_DEPENDENCY` | error | Cycle detected in task dependencies |
|
|
831
|
+
| `SELF_DEPENDENCY` | error | Task requires a token it provides itself |
|
|
832
|
+
| `UNREACHABLE_GOAL` | error | Goal token cannot be produced by any task |
|
|
833
|
+
| `MISSING_GOAL` | error | `goal-reached` strategy without goal array |
|
|
834
|
+
| `PROVIDE_CONFLICT` | warning | Multiple tasks produce the same token |
|
|
835
|
+
| `DEAD_END_TASK` | warning | Task has no provides — can't unblock downstream |
|
|
836
|
+
| `ISOLATED_TASK` | info | Disconnected task with no requires or dependents |
|
|
837
|
+
|
|
838
|
+
Use `validateGraphConfig()` for structural checks (JSON shape) and `validateGraph()` for semantic checks (logical correctness). Both are pure functions.
|
|
839
|
+
|
|
840
|
+
---
|
|
841
|
+
|
|
842
|
+
## Continuous Event Graph
|
|
843
|
+
|
|
844
|
+
A **long-lived, evolving** event-graph where both the graph config and execution state mutate over time. Ideal for dashboards, monitoring systems, and any scenario where the workflow has no fixed endpoint.
|
|
845
|
+
|
|
846
|
+
The core type is `LiveGraph` — it bundles `config` + `state` so they can't get out of sync. Every function is pure: `f(LiveGraph, input) → LiveGraph`.
|
|
847
|
+
|
|
848
|
+
```typescript
|
|
849
|
+
import {
|
|
850
|
+
createLiveGraph, applyEvent,
|
|
851
|
+
addNode, removeNode,
|
|
852
|
+
addRequires, removeRequires, addProvides, removeProvides,
|
|
853
|
+
injectTokens, drainTokens,
|
|
854
|
+
schedule, inspect,
|
|
855
|
+
resetNode, disableNode, enableNode, getNode,
|
|
856
|
+
snapshot, restore,
|
|
857
|
+
getUnreachableTokens, getUnreachableNodes,
|
|
858
|
+
getUpstream, getDownstream,
|
|
859
|
+
} from 'yaml-flow/continuous-event-graph';
|
|
860
|
+
```
|
|
861
|
+
|
|
862
|
+
### Quick Start
|
|
863
|
+
|
|
864
|
+
```typescript
|
|
865
|
+
import { createLiveGraph, applyEvent, addNode, schedule, inspect } from 'yaml-flow/continuous-event-graph';
|
|
866
|
+
|
|
867
|
+
// 1. Bootstrap
|
|
868
|
+
let live = createLiveGraph({
|
|
869
|
+
settings: { completion: 'manual' },
|
|
870
|
+
tasks: {
|
|
871
|
+
fetch_prices: { provides: ['price-data'] },
|
|
872
|
+
compute: { requires: ['price-data'], provides: ['indicators'] },
|
|
873
|
+
},
|
|
874
|
+
});
|
|
875
|
+
|
|
876
|
+
// 2. Schedule — what's ready?
|
|
877
|
+
schedule(live).eligible; // ['fetch_prices']
|
|
878
|
+
|
|
879
|
+
// 3. Apply events — immutable state transitions
|
|
880
|
+
live = applyEvent(live, { type: 'task-started', taskName: 'fetch_prices', timestamp: new Date().toISOString() });
|
|
881
|
+
live = applyEvent(live, { type: 'task-completed', taskName: 'fetch_prices', timestamp: new Date().toISOString() });
|
|
882
|
+
schedule(live).eligible; // ['compute']
|
|
883
|
+
|
|
884
|
+
// 4. Evolve — add a node at runtime
|
|
885
|
+
live = addNode(live, 'alert', { requires: ['indicators'], provides: ['alert-sent'] });
|
|
886
|
+
|
|
887
|
+
// 5. Health check
|
|
888
|
+
inspect(live); // { totalNodes: 3, running: 0, completed: 1, ... }
|
|
889
|
+
```
|
|
890
|
+
|
|
891
|
+
### Graph Mutations
|
|
892
|
+
|
|
893
|
+
| Function | Description |
|
|
894
|
+
|---|---|
|
|
895
|
+
| `addNode(live, name, config)` | Add a task to the graph (config + state) |
|
|
896
|
+
| `removeNode(live, name)` | Remove a task from the graph |
|
|
897
|
+
| `addRequires(live, node, tokens)` | Add requires tokens to a node |
|
|
898
|
+
| `removeRequires(live, node, tokens)` | Remove requires tokens from a node |
|
|
899
|
+
| `addProvides(live, node, tokens)` | Add provides tokens to a node |
|
|
900
|
+
| `removeProvides(live, node, tokens)` | Remove provides tokens from a node |
|
|
901
|
+
|
|
902
|
+
### Token Management
|
|
903
|
+
|
|
904
|
+
```typescript
|
|
905
|
+
// Inject external data/signals
|
|
906
|
+
live = injectTokens(live, ['market-open', 'price-data']);
|
|
907
|
+
|
|
908
|
+
// Drain stale/expired tokens
|
|
909
|
+
live = drainTokens(live, ['price-data']); // forces re-fetch before downstream can run
|
|
910
|
+
```
|
|
911
|
+
|
|
912
|
+
### Node Lifecycle
|
|
913
|
+
|
|
914
|
+
| Function | Description |
|
|
915
|
+
|---|---|
|
|
916
|
+
| `resetNode(live, name)` | Reset a node to `not-started` (for retry) |
|
|
917
|
+
| `disableNode(live, name)` | Set a node to `inactivated` (scheduler skips it) |
|
|
918
|
+
| `enableNode(live, name)` | Re-enable a disabled node |
|
|
919
|
+
| `getNode(live, name)` | Get config + state for a single node |
|
|
920
|
+
|
|
921
|
+
### Graph Traversal
|
|
922
|
+
|
|
923
|
+
```typescript
|
|
924
|
+
// "What feeds into generate_signals?"
|
|
925
|
+
const upstream = getUpstream(live, 'generate_signals');
|
|
926
|
+
upstream.nodes; // [{ nodeName: 'fetch_prices', providesTokens: ['price-data'] }, ...]
|
|
927
|
+
upstream.tokens; // ['price-data', 'indicators', ...]
|
|
928
|
+
|
|
929
|
+
// "What breaks if fetch_prices goes down?"
|
|
930
|
+
const downstream = getDownstream(live, 'fetch_prices');
|
|
931
|
+
downstream.nodes; // [{ nodeName: 'compute', requiresTokens: ['price-data'] }, ...]
|
|
932
|
+
downstream.tokens; // ['price-data', 'indicators', ...]
|
|
933
|
+
```
|
|
934
|
+
|
|
935
|
+
### Reachability Analysis
|
|
936
|
+
|
|
937
|
+
```typescript
|
|
938
|
+
// Tokens that can never be produced given the current state
|
|
939
|
+
const unreachableTokens = getUnreachableTokens(live);
|
|
940
|
+
unreachableTokens.tokens; // [{ token: 'ghost', reason: 'no-producer', producers: [] }]
|
|
941
|
+
|
|
942
|
+
// Nodes that can never become eligible
|
|
943
|
+
const unreachableNodes = getUnreachableNodes(live);
|
|
944
|
+
unreachableNodes.nodes; // [{ nodeName: 'orphan', missingTokens: ['ghost'] }]
|
|
945
|
+
```
|
|
946
|
+
|
|
947
|
+
### Persistence
|
|
948
|
+
|
|
949
|
+
```typescript
|
|
950
|
+
// Save
|
|
951
|
+
const snap = snapshot(live); // JSON-safe object
|
|
952
|
+
localStorage.setItem('graph', JSON.stringify(snap));
|
|
953
|
+
|
|
954
|
+
// Restore
|
|
955
|
+
const data = JSON.parse(localStorage.getItem('graph')!);
|
|
956
|
+
const restored = restore(data); // → LiveGraph (validates shape)
|
|
957
|
+
```
|
|
958
|
+
|
|
959
|
+
### Continuous Event Graph API Reference
|
|
960
|
+
|
|
961
|
+
| Function | Description |
|
|
962
|
+
|---|---|
|
|
963
|
+
| `createLiveGraph(config, id?)` | Bootstrap a LiveGraph from a GraphConfig |
|
|
964
|
+
| `applyEvent(live, event)` | Apply an execution event (task-started, task-completed, etc.) |
|
|
965
|
+
| `addNode(live, name, config)` | Add a node (both config + state) |
|
|
966
|
+
| `removeNode(live, name)` | Remove a node |
|
|
967
|
+
| `addRequires / removeRequires` | Wire/unwire requires tokens |
|
|
968
|
+
| `addProvides / removeProvides` | Wire/unwire provides tokens |
|
|
969
|
+
| `injectTokens(live, tokens)` | Add tokens to available outputs |
|
|
970
|
+
| `drainTokens(live, tokens)` | Remove tokens from available outputs |
|
|
971
|
+
| `schedule(live)` | Classify tasks: eligible / pending / unresolved / blocked / conflicts |
|
|
972
|
+
| `inspect(live)` | Health report: statuses, cycles, open deps, conflicts |
|
|
973
|
+
| `resetNode(live, name)` | Reset node to not-started |
|
|
974
|
+
| `disableNode(live, name)` | Disable a node (inactivated) |
|
|
975
|
+
| `enableNode(live, name)` | Re-enable a disabled node |
|
|
976
|
+
| `getNode(live, name)` | Get a node's config + state |
|
|
977
|
+
| `getUpstream(live, name)` | Transitive upstream: what feeds into this node? |
|
|
978
|
+
| `getDownstream(live, name)` | Transitive downstream: what depends on this node? |
|
|
979
|
+
| `getUnreachableTokens(live)` | Tokens that can never be produced |
|
|
980
|
+
| `getUnreachableNodes(live)` | Nodes that can never become eligible |
|
|
981
|
+
| `snapshot(live)` | Serialize to a JSON-safe snapshot |
|
|
982
|
+
| `restore(data)` | Restore a LiveGraph from a snapshot |
|
|
983
|
+
|
|
984
|
+
---
|
|
985
|
+
|
|
804
986
|
## Loading & Exporting Graph Configs
|
|
805
987
|
|
|
806
988
|
```typescript
|
|
@@ -835,6 +1017,7 @@ import { next, apply, applyAll, getCandidateTasks } from 'yaml-flow/event-graph'
|
|
|
835
1017
|
import { createInitialExecutionState, isExecutionComplete, detectStuckState } from 'yaml-flow/event-graph';
|
|
836
1018
|
import { planExecution, graphToMermaid, flowToMermaid } from 'yaml-flow/event-graph';
|
|
837
1019
|
import { loadGraphConfig, validateGraphConfig, exportGraphConfig } from 'yaml-flow/event-graph';
|
|
1020
|
+
import { validateGraph } from 'yaml-flow/event-graph';
|
|
838
1021
|
import { TASK_STATUS, COMPLETION_STRATEGIES, CONFLICT_STRATEGIES } from 'yaml-flow/event-graph';
|
|
839
1022
|
|
|
840
1023
|
// Stores
|
|
@@ -847,6 +1030,17 @@ import type { BatchOptions, BatchResult, BatchItemResult, BatchProgress } from '
|
|
|
847
1030
|
// Config utilities
|
|
848
1031
|
import { resolveVariables, resolveConfigTemplates } from 'yaml-flow/config';
|
|
849
1032
|
|
|
1033
|
+
// Continuous Event Graph (long-lived evolving workflows)
|
|
1034
|
+
import {
|
|
1035
|
+
createLiveGraph, applyEvent, addNode, removeNode,
|
|
1036
|
+
addRequires, removeRequires, addProvides, removeProvides,
|
|
1037
|
+
injectTokens, drainTokens, schedule, inspect,
|
|
1038
|
+
resetNode, disableNode, enableNode, getNode,
|
|
1039
|
+
snapshot, restore,
|
|
1040
|
+
getUnreachableTokens, getUnreachableNodes,
|
|
1041
|
+
getUpstream, getDownstream,
|
|
1042
|
+
} from 'yaml-flow/continuous-event-graph';
|
|
1043
|
+
|
|
850
1044
|
// Backward compatibility (v1 names → v2)
|
|
851
1045
|
import { FlowEngine, createEngine } from 'yaml-flow'; // aliases for StepMachine, createStepMachine
|
|
852
1046
|
```
|
|
@@ -889,6 +1083,7 @@ import { FlowEngine, createEngine } from 'yaml-flow'; // aliases for StepMachin
|
|
|
889
1083
|
| `validateGraphConfig(config)` | Validate a GraphConfig, returns error strings |
|
|
890
1084
|
| `exportGraphConfig(config, options?)` | Export a GraphConfig to JSON or YAML string |
|
|
891
1085
|
| `exportGraphConfigToFile(config, path)` | Export a GraphConfig to a file |
|
|
1086
|
+
| `validateGraph(graph)` | Semantic validation: cycles, dangling requires, unreachable goals, conflicts |
|
|
892
1087
|
|
|
893
1088
|
### Event Types (for `apply()`)
|
|
894
1089
|
|
|
@@ -917,6 +1112,7 @@ See the [examples/](./examples) directory:
|
|
|
917
1112
|
| [Batch Tickets](./examples/batch/batch-step-machine.ts) | Batch | Concurrent processing, progress tracking |
|
|
918
1113
|
| [URL Pipeline](./examples/graph-of-graphs/url-processing-pipeline.ts) | Graph-of-Graphs | Outer event-graph → batch × inner event-graph per item |
|
|
919
1114
|
| [Multi-Stage ETL](./examples/graph-of-graphs/multi-stage-etl.ts) | Graph-of-Graphs | Mixed modes: event-graph outer → step-machine + event-graph subs |
|
|
1115
|
+
| [Stock Dashboard](./examples/continuous-event-graph/stock-dashboard.ts) | Continuous Event Graph | Runtime mutations, token drain, upstream/downstream, snapshot |
|
|
920
1116
|
| [Order Processing](./examples/flows/order-processing.yaml) | Step Machine | YAML flow definition |
|
|
921
1117
|
| [Browser Demo](./examples/browser/index.html) | Step Machine | In-browser usage |
|
|
922
1118
|
|
|
@@ -1,191 +1,6 @@
|
|
|
1
|
+
import { G as GraphConfig, c as ExecutionState, S as SchedulerResult, e as GraphEvent, T as TaskConfig, l as TaskState, g as StuckDetection, C as CompletionStrategy, a as ConflictStrategy, b as ExecutionMode, d as ExecutionStatus, m as TaskStatus } from './types-CTu8RqY0.cjs';
|
|
1
2
|
import { e as StepFlowConfig } from './types-FZ_eyErS.cjs';
|
|
2
3
|
|
|
3
|
-
/**
|
|
4
|
-
* Event Graph — Core Types
|
|
5
|
-
*
|
|
6
|
-
* Type definitions for the stateless event-graph engine.
|
|
7
|
-
* Pure: f(state, event) → newState
|
|
8
|
-
*/
|
|
9
|
-
interface GraphConfig {
|
|
10
|
-
id?: string;
|
|
11
|
-
settings: GraphSettings;
|
|
12
|
-
tasks: Record<string, TaskConfig>;
|
|
13
|
-
}
|
|
14
|
-
interface GraphSettings {
|
|
15
|
-
/** Completion strategy */
|
|
16
|
-
completion: CompletionStrategy;
|
|
17
|
-
/** Conflict resolution strategy */
|
|
18
|
-
conflict_strategy?: ConflictStrategy;
|
|
19
|
-
/** Execution mode */
|
|
20
|
-
execution_mode?: ExecutionMode;
|
|
21
|
-
/** Goal outputs — used with 'goal-reached' completion */
|
|
22
|
-
goal?: string[];
|
|
23
|
-
/** Max total scheduler iterations (safety limit, default: 1000) */
|
|
24
|
-
max_iterations?: number;
|
|
25
|
-
/** Timeout in ms (declared for drivers, not enforced by pure engine) */
|
|
26
|
-
timeout_ms?: number;
|
|
27
|
-
}
|
|
28
|
-
interface TaskConfig {
|
|
29
|
-
/** What this task needs to become eligible */
|
|
30
|
-
requires?: string[];
|
|
31
|
-
/** What this task produces on successful completion */
|
|
32
|
-
provides: string[];
|
|
33
|
-
/** Conditional provides based on handler result */
|
|
34
|
-
on?: Record<string, string[]>;
|
|
35
|
-
/** Tokens to inject into available outputs on failure */
|
|
36
|
-
on_failure?: string[];
|
|
37
|
-
/** Task execution method (informational — driver concern) */
|
|
38
|
-
method?: string;
|
|
39
|
-
/** Arbitrary task configuration (driver concern) */
|
|
40
|
-
config?: Record<string, unknown>;
|
|
41
|
-
/** Task priority (higher = preferred in conflict resolution) */
|
|
42
|
-
priority?: number;
|
|
43
|
-
/** Estimated duration in ms (used by duration-first strategy) */
|
|
44
|
-
estimatedDuration?: number;
|
|
45
|
-
/** Estimated cost (used by cost-optimized strategy) */
|
|
46
|
-
estimatedCost?: number;
|
|
47
|
-
/** Resource requirements (used by resource-aware strategy) */
|
|
48
|
-
estimatedResources?: Record<string, number>;
|
|
49
|
-
/** Retry configuration */
|
|
50
|
-
retry?: TaskRetryConfig;
|
|
51
|
-
/** Repeatable task configuration */
|
|
52
|
-
repeatable?: boolean | RepeatableConfig;
|
|
53
|
-
/** Circuit breaker: max executions before breaking */
|
|
54
|
-
circuit_breaker?: TaskCircuitBreakerConfig;
|
|
55
|
-
/** Description */
|
|
56
|
-
description?: string;
|
|
57
|
-
}
|
|
58
|
-
interface TaskRetryConfig {
|
|
59
|
-
max_attempts: number;
|
|
60
|
-
delay_ms?: number;
|
|
61
|
-
backoff_multiplier?: number;
|
|
62
|
-
}
|
|
63
|
-
interface RepeatableConfig {
|
|
64
|
-
/** Max times this task can repeat (undefined = unlimited) */
|
|
65
|
-
max?: number;
|
|
66
|
-
}
|
|
67
|
-
interface TaskCircuitBreakerConfig {
|
|
68
|
-
/** Max executions before injecting break tokens */
|
|
69
|
-
max_executions: number;
|
|
70
|
-
/** Tokens to inject when breaker trips */
|
|
71
|
-
on_break: string[];
|
|
72
|
-
}
|
|
73
|
-
interface ExecutionState {
|
|
74
|
-
/** Current status of the execution */
|
|
75
|
-
status: ExecutionStatus;
|
|
76
|
-
/** Task states keyed by task name */
|
|
77
|
-
tasks: Record<string, TaskState>;
|
|
78
|
-
/** Tokens currently available in the system */
|
|
79
|
-
availableOutputs: string[];
|
|
80
|
-
/** Stuck detection result */
|
|
81
|
-
stuckDetection: StuckDetection;
|
|
82
|
-
/** Last update timestamp */
|
|
83
|
-
lastUpdated: string;
|
|
84
|
-
/** Execution ID for this run */
|
|
85
|
-
executionId: string | null;
|
|
86
|
-
/** Execution configuration */
|
|
87
|
-
executionConfig: ExecutionConfig;
|
|
88
|
-
}
|
|
89
|
-
interface ExecutionConfig {
|
|
90
|
-
executionMode: ExecutionMode;
|
|
91
|
-
conflictStrategy: ConflictStrategy;
|
|
92
|
-
completionStrategy: CompletionStrategy;
|
|
93
|
-
}
|
|
94
|
-
interface TaskState {
|
|
95
|
-
status: TaskStatus;
|
|
96
|
-
executionCount: number;
|
|
97
|
-
retryCount: number;
|
|
98
|
-
lastEpoch: number;
|
|
99
|
-
startedAt?: string;
|
|
100
|
-
completedAt?: string;
|
|
101
|
-
failedAt?: string;
|
|
102
|
-
lastUpdated?: string;
|
|
103
|
-
error?: string;
|
|
104
|
-
messages?: TaskMessage[];
|
|
105
|
-
progress?: number | null;
|
|
106
|
-
}
|
|
107
|
-
interface TaskMessage {
|
|
108
|
-
message: string;
|
|
109
|
-
timestamp: string;
|
|
110
|
-
status: string;
|
|
111
|
-
}
|
|
112
|
-
interface StuckDetection {
|
|
113
|
-
is_stuck: boolean;
|
|
114
|
-
stuck_description: string | null;
|
|
115
|
-
outputs_unresolvable: string[];
|
|
116
|
-
tasks_blocked: string[];
|
|
117
|
-
}
|
|
118
|
-
type GraphEvent = TaskStartedEvent | TaskCompletedEvent | TaskFailedEvent | TaskProgressEvent | InjectTokensEvent | AgentActionEvent | TaskCreationEvent;
|
|
119
|
-
interface TaskStartedEvent {
|
|
120
|
-
type: 'task-started';
|
|
121
|
-
taskName: string;
|
|
122
|
-
timestamp: string;
|
|
123
|
-
executionId?: string;
|
|
124
|
-
}
|
|
125
|
-
interface TaskCompletedEvent {
|
|
126
|
-
type: 'task-completed';
|
|
127
|
-
taskName: string;
|
|
128
|
-
/** Handler result key — used for conditional routing via `on` */
|
|
129
|
-
result?: string;
|
|
130
|
-
/** Data payload from task execution */
|
|
131
|
-
data?: Record<string, unknown>;
|
|
132
|
-
timestamp: string;
|
|
133
|
-
executionId?: string;
|
|
134
|
-
}
|
|
135
|
-
interface TaskFailedEvent {
|
|
136
|
-
type: 'task-failed';
|
|
137
|
-
taskName: string;
|
|
138
|
-
error: string;
|
|
139
|
-
timestamp: string;
|
|
140
|
-
executionId?: string;
|
|
141
|
-
}
|
|
142
|
-
interface TaskProgressEvent {
|
|
143
|
-
type: 'task-progress';
|
|
144
|
-
taskName: string;
|
|
145
|
-
message?: string;
|
|
146
|
-
progress?: number;
|
|
147
|
-
timestamp: string;
|
|
148
|
-
executionId?: string;
|
|
149
|
-
}
|
|
150
|
-
interface InjectTokensEvent {
|
|
151
|
-
type: 'inject-tokens';
|
|
152
|
-
tokens: string[];
|
|
153
|
-
timestamp: string;
|
|
154
|
-
}
|
|
155
|
-
interface AgentActionEvent {
|
|
156
|
-
type: 'agent-action';
|
|
157
|
-
action: 'start' | 'stop' | 'pause' | 'resume';
|
|
158
|
-
timestamp: string;
|
|
159
|
-
config?: Partial<ExecutionConfig>;
|
|
160
|
-
}
|
|
161
|
-
interface TaskCreationEvent {
|
|
162
|
-
type: 'task-creation';
|
|
163
|
-
taskName: string;
|
|
164
|
-
taskConfig: TaskConfig;
|
|
165
|
-
timestamp: string;
|
|
166
|
-
}
|
|
167
|
-
interface SchedulerResult {
|
|
168
|
-
/** Tasks eligible for execution */
|
|
169
|
-
eligibleTasks: string[];
|
|
170
|
-
/** Whether the graph execution is complete */
|
|
171
|
-
isComplete: boolean;
|
|
172
|
-
/** Stuck detection result */
|
|
173
|
-
stuckDetection: StuckDetection;
|
|
174
|
-
/** Whether conflicts were detected */
|
|
175
|
-
hasConflicts: boolean;
|
|
176
|
-
/** Conflict groups: output → competing task names */
|
|
177
|
-
conflicts: Record<string, string[]>;
|
|
178
|
-
/** Strategy used for conflict resolution */
|
|
179
|
-
strategy: ConflictStrategy;
|
|
180
|
-
/** Processing log for diagnostics */
|
|
181
|
-
processingLog: string[];
|
|
182
|
-
}
|
|
183
|
-
type TaskStatus = 'not-started' | 'running' | 'completed' | 'failed' | 'inactivated';
|
|
184
|
-
type ExecutionStatus = 'created' | 'running' | 'paused' | 'stopped' | 'completed' | 'failed';
|
|
185
|
-
type CompletionStrategy = 'all-tasks-done' | 'all-outputs-done' | 'only-resolved' | 'goal-reached' | 'manual';
|
|
186
|
-
type ExecutionMode = 'dependency-mode' | 'eligibility-mode';
|
|
187
|
-
type ConflictStrategy = 'alphabetical' | 'priority-first' | 'duration-first' | 'cost-optimized' | 'resource-aware' | 'random-select' | 'user-choice' | 'parallel-all' | 'skip-conflicts' | 'round-robin';
|
|
188
|
-
|
|
189
4
|
/**
|
|
190
5
|
* Event Graph — Scheduler
|
|
191
6
|
*
|
|
@@ -438,6 +253,56 @@ declare function exportGraphConfig(config: GraphConfig, options?: ExportOptions)
|
|
|
438
253
|
*/
|
|
439
254
|
declare function exportGraphConfigToFile(config: GraphConfig, filePath: string, options?: ExportOptions): Promise<void>;
|
|
440
255
|
|
|
256
|
+
/**
|
|
257
|
+
* Event Graph — Semantic Graph Validation
|
|
258
|
+
*
|
|
259
|
+
* Validates the logical correctness of a static graph configuration.
|
|
260
|
+
* Unlike validateGraphConfig() which checks JSON structure, this checks:
|
|
261
|
+
* - Dangling requires (tokens no task produces)
|
|
262
|
+
* - Circular dependencies
|
|
263
|
+
* - Provide conflicts (multiple tasks producing same token)
|
|
264
|
+
* - Unreachable goal tokens
|
|
265
|
+
* - Dead-end tasks (no provides)
|
|
266
|
+
* - Self-dependencies
|
|
267
|
+
* - Orphaned tasks (disconnected from the graph)
|
|
268
|
+
*
|
|
269
|
+
* Pure function — config in, diagnostics out.
|
|
270
|
+
*/
|
|
271
|
+
|
|
272
|
+
type IssueSeverity = 'error' | 'warning' | 'info';
|
|
273
|
+
interface GraphIssue {
|
|
274
|
+
/** Severity: error = will break execution, warning = may cause problems, info = notable */
|
|
275
|
+
severity: IssueSeverity;
|
|
276
|
+
/** Machine-readable issue code */
|
|
277
|
+
code: string;
|
|
278
|
+
/** Human-readable description */
|
|
279
|
+
message: string;
|
|
280
|
+
/** Affected task names (if applicable) */
|
|
281
|
+
tasks?: string[];
|
|
282
|
+
/** Affected tokens (if applicable) */
|
|
283
|
+
tokens?: string[];
|
|
284
|
+
}
|
|
285
|
+
interface GraphValidationResult {
|
|
286
|
+
/** true if no errors (warnings/info are allowed) */
|
|
287
|
+
valid: boolean;
|
|
288
|
+
/** All issues found */
|
|
289
|
+
issues: GraphIssue[];
|
|
290
|
+
/** Just the errors */
|
|
291
|
+
errors: GraphIssue[];
|
|
292
|
+
/** Just the warnings */
|
|
293
|
+
warnings: GraphIssue[];
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Validate the semantic correctness of a static event-graph configuration.
|
|
297
|
+
*
|
|
298
|
+
* Checks for logical issues that would cause execution failures, stuck states,
|
|
299
|
+
* or unexpected behavior. Does NOT check JSON structure (use validateGraphConfig for that).
|
|
300
|
+
*
|
|
301
|
+
* @param graph - The event-graph configuration to validate
|
|
302
|
+
* @returns Validation result with categorized issues
|
|
303
|
+
*/
|
|
304
|
+
declare function validateGraph(graph: GraphConfig): GraphValidationResult;
|
|
305
|
+
|
|
441
306
|
/**
|
|
442
307
|
* Event Graph — Constants
|
|
443
308
|
*/
|
|
@@ -454,4 +319,4 @@ declare const DEFAULTS: {
|
|
|
454
319
|
readonly MAX_ITERATIONS: 1000;
|
|
455
320
|
};
|
|
456
321
|
|
|
457
|
-
export {
|
|
322
|
+
export { isTaskCompleted as A, isTaskRunning as B, COMPLETION_STRATEGIES as C, DEFAULTS as D, EXECUTION_MODES as E, loadGraphConfig as F, type GraphIssue as G, next as H, type IssueSeverity as I, planExecution as J, validateGraph as K, validateGraphConfig as L, type MermaidOptions as M, addKeyToProvides as N, addKeyToRequires as O, getRepeatableMax as P, groupTasksByProvides as Q, hasOutputConflict as R, removeKeyFromProvides as S, TASK_STATUS as T, removeKeyFromRequires as U, CONFLICT_STRATEGIES as a, type CompletionResult as b, EXECUTION_STATUS as c, type ExecutionPlan as d, type ExportOptions as e, type GraphValidationResult as f, addDynamicTask as g, apply as h, applyAll as i, computeAvailableOutputs as j, createDefaultTaskState as k, createInitialExecutionState as l, detectStuckState as m, exportGraphConfig as n, exportGraphConfigToFile as o, flowToMermaid as p, getAllTasks as q, getCandidateTasks as r, getProvides as s, getRequires as t, getTask as u, graphToMermaid as v, hasTask as w, isExecutionComplete as x, isNonActiveTask as y, isRepeatableTask as z };
|