yaml-flow 3.0.0 → 3.1.1

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 (59) hide show
  1. package/README.md +44 -23
  2. package/dist/{constants-B_ftYTTE.d.ts → constants-B2zqu10b.d.ts} +7 -57
  3. package/dist/{constants-CiyHX8L-.d.cts → constants-DJZU1pwJ.d.cts} +7 -57
  4. package/dist/continuous-event-graph/index.cjs +1161 -182
  5. package/dist/continuous-event-graph/index.cjs.map +1 -1
  6. package/dist/continuous-event-graph/index.d.cts +567 -48
  7. package/dist/continuous-event-graph/index.d.ts +567 -48
  8. package/dist/continuous-event-graph/index.js +1151 -183
  9. package/dist/continuous-event-graph/index.js.map +1 -1
  10. package/dist/event-graph/index.cjs +35 -11
  11. package/dist/event-graph/index.cjs.map +1 -1
  12. package/dist/event-graph/index.d.cts +14 -5
  13. package/dist/event-graph/index.d.ts +14 -5
  14. package/dist/event-graph/index.js +34 -11
  15. package/dist/event-graph/index.js.map +1 -1
  16. package/dist/index.cjs +945 -414
  17. package/dist/index.cjs.map +1 -1
  18. package/dist/index.d.cts +5 -4
  19. package/dist/index.d.ts +5 -4
  20. package/dist/index.js +936 -415
  21. package/dist/index.js.map +1 -1
  22. package/dist/inference/index.cjs +31 -7
  23. package/dist/inference/index.cjs.map +1 -1
  24. package/dist/inference/index.d.cts +2 -2
  25. package/dist/inference/index.d.ts +2 -2
  26. package/dist/inference/index.js +31 -7
  27. package/dist/inference/index.js.map +1 -1
  28. package/dist/{types-CxJg9Jrt.d.cts → types-BwvgvlOO.d.cts} +2 -2
  29. package/dist/{types-BuEo3wVG.d.ts → types-ClRA8hzC.d.ts} +2 -2
  30. package/dist/{types-BpWrH1sf.d.cts → types-DEj7OakX.d.cts} +14 -4
  31. package/dist/{types-BpWrH1sf.d.ts → types-DEj7OakX.d.ts} +14 -4
  32. package/dist/validate-DEZ2Ymdb.d.ts +53 -0
  33. package/dist/validate-DqKTZg_o.d.cts +53 -0
  34. package/examples/batch/batch-step-machine.ts +121 -0
  35. package/examples/browser/index.html +367 -0
  36. package/examples/continuous-event-graph/live-cards-board.ts +215 -0
  37. package/examples/continuous-event-graph/live-portfolio-dashboard.ts +555 -0
  38. package/examples/continuous-event-graph/portfolio-tracker.ts +287 -0
  39. package/examples/continuous-event-graph/reactive-monitoring.ts +265 -0
  40. package/examples/continuous-event-graph/reactive-pipeline.ts +168 -0
  41. package/examples/continuous-event-graph/soc-incident-board.ts +287 -0
  42. package/examples/continuous-event-graph/stock-dashboard.ts +229 -0
  43. package/examples/event-graph/ci-cd-pipeline.ts +243 -0
  44. package/examples/event-graph/executor-diamond.ts +165 -0
  45. package/examples/event-graph/executor-pipeline.ts +161 -0
  46. package/examples/event-graph/research-pipeline.ts +137 -0
  47. package/examples/flows/ai-conversation.yaml +116 -0
  48. package/examples/flows/order-processing.yaml +143 -0
  49. package/examples/flows/simple-greeting.yaml +54 -0
  50. package/examples/graph-of-graphs/multi-stage-etl.ts +307 -0
  51. package/examples/graph-of-graphs/url-processing-pipeline.ts +254 -0
  52. package/examples/inference/azure-deployment.ts +149 -0
  53. package/examples/inference/copilot-cli.ts +138 -0
  54. package/examples/inference/data-pipeline.ts +145 -0
  55. package/examples/inference/pluggable-adapters.ts +254 -0
  56. package/examples/ingest.js +733 -0
  57. package/examples/node/ai-conversation.ts +195 -0
  58. package/examples/node/simple-greeting.ts +101 -0
  59. package/package.json +3 -2
@@ -0,0 +1,195 @@
1
+ /**
2
+ * Node.js Example: AI Conversation with External API
3
+ *
4
+ * Demonstrates a more complex flow with:
5
+ * - Component injection (AI client)
6
+ * - Retry logic
7
+ * - Circuit breakers
8
+ * - Event handling
9
+ *
10
+ * Run with: npx ts-node examples/node/ai-conversation.ts
11
+ */
12
+
13
+ import { createEngine, loadFlow, MemoryStore } from '../../src/index.js';
14
+ import type { StepInput, StepContext, StepResult } from '../../src/index.js';
15
+ import { fileURLToPath } from 'url';
16
+ import { dirname, join } from 'path';
17
+
18
+ const __filename = fileURLToPath(import.meta.url);
19
+ const __dirname = dirname(__filename);
20
+
21
+ // Simulated AI client (replace with actual OpenAI/Anthropic client)
22
+ const mockAIClient = {
23
+ async generateResponse(prompt: string, history: string[]): Promise<{ text: string; confidence: number }> {
24
+ // Simulate API latency
25
+ await new Promise(resolve => setTimeout(resolve, 100));
26
+
27
+ // Simulate occasional low confidence
28
+ const confidence = Math.random() > 0.3 ? 0.85 : 0.4;
29
+
30
+ return {
31
+ text: `AI Response to: "${prompt}" (simulated)`,
32
+ confidence,
33
+ };
34
+ },
35
+ };
36
+
37
+ // Define step handlers
38
+ const handlers = {
39
+ async generate_response(input: StepInput, ctx: StepContext): Promise<StepResult> {
40
+ const userMessage = input.user_message as string;
41
+ const history = (input.conversation_history as string[]) || [];
42
+
43
+ // Access injected AI client from components
44
+ const ai = ctx.components.aiClient as typeof mockAIClient;
45
+
46
+ console.log(`[generate] Processing: "${userMessage}"`);
47
+
48
+ try {
49
+ const response = await ai.generateResponse(userMessage, history);
50
+
51
+ return {
52
+ result: 'success',
53
+ data: {
54
+ ai_response: response.text,
55
+ confidence_score: response.confidence,
56
+ },
57
+ };
58
+ } catch (error) {
59
+ console.log('[generate] API call failed, will retry...');
60
+ return { result: 'failure' };
61
+ }
62
+ },
63
+
64
+ async validate_response(input: StepInput, ctx: StepContext): Promise<StepResult> {
65
+ const response = input.ai_response as string;
66
+ const confidence = input.confidence_score as number;
67
+
68
+ console.log(`[validate] Confidence: ${(confidence * 100).toFixed(1)}%`);
69
+
70
+ // Check quality criteria
71
+ if (confidence >= 0.7 && response.length > 10) {
72
+ return {
73
+ result: 'valid',
74
+ data: {
75
+ validation_result: 'passed',
76
+ validation_feedback: null,
77
+ },
78
+ };
79
+ }
80
+
81
+ return {
82
+ result: 'needs_refinement',
83
+ data: {
84
+ validation_result: 'needs_improvement',
85
+ validation_feedback: confidence < 0.7
86
+ ? 'Low confidence - regenerate with more context'
87
+ : 'Response too short',
88
+ },
89
+ };
90
+ },
91
+
92
+ async refine_response(input: StepInput, ctx: StepContext): Promise<StepResult> {
93
+ const feedback = input.validation_feedback as string;
94
+ const userMessage = input.user_message as string;
95
+
96
+ console.log(`[refine] Refining based on: ${feedback}`);
97
+
98
+ const ai = ctx.components.aiClient as typeof mockAIClient;
99
+
100
+ // Enhanced prompt with feedback
101
+ const enhancedPrompt = `${userMessage} (Note: ${feedback})`;
102
+ const response = await ai.generateResponse(enhancedPrompt, []);
103
+
104
+ return {
105
+ result: 'success',
106
+ data: {
107
+ ai_response: response.text + ' [refined]',
108
+ confidence_score: Math.min(response.confidence + 0.2, 0.95), // Boost confidence
109
+ },
110
+ };
111
+ },
112
+
113
+ async check_approval(input: StepInput, ctx: StepContext): Promise<StepResult> {
114
+ const response = input.ai_response as string;
115
+
116
+ console.log(`[approval] Response ready: "${response}"`);
117
+
118
+ // Simulate user approval (in real app, this would wait for user input)
119
+ const userApproves = Math.random() > 0.3;
120
+
121
+ if (userApproves) {
122
+ console.log('[approval] User approved!');
123
+ return {
124
+ result: 'approved',
125
+ data: {
126
+ user_approved: true,
127
+ user_feedback: null,
128
+ },
129
+ };
130
+ }
131
+
132
+ console.log('[approval] User rejected, requesting changes');
133
+ return {
134
+ result: 'rejected',
135
+ data: {
136
+ user_approved: false,
137
+ user_feedback: 'Please make it more concise',
138
+ },
139
+ };
140
+ },
141
+
142
+ async incorporate_feedback(input: StepInput, ctx: StepContext): Promise<StepResult> {
143
+ const response = input.ai_response as string;
144
+ const feedback = input.user_feedback as string;
145
+
146
+ console.log(`[feedback] Incorporating: "${feedback}"`);
147
+
148
+ return {
149
+ result: 'success',
150
+ data: {
151
+ ai_response: response.replace(' [refined]', '') + ' [user-adjusted]',
152
+ confidence_score: 0.9,
153
+ },
154
+ };
155
+ },
156
+ };
157
+
158
+ async function main() {
159
+ // Load the AI conversation flow
160
+ const flowPath = join(__dirname, '../flows/ai-conversation.yaml');
161
+ const flow = await loadFlow(flowPath);
162
+
163
+ console.log('=== AI Conversation Flow Demo ===\n');
164
+
165
+ // Create engine with AI client component
166
+ const engine = createEngine(flow, handlers, {
167
+ store: new MemoryStore(),
168
+ components: {
169
+ aiClient: mockAIClient,
170
+ },
171
+ onTransition: (from, to) => {
172
+ console.log(` >> ${from} -> ${to}`);
173
+ },
174
+ });
175
+
176
+ // Subscribe to events
177
+ engine.on('step:error', (event) => {
178
+ console.log(` !! Error in step: ${event.data.step}`);
179
+ });
180
+
181
+ // Run the flow
182
+ const result = await engine.run({
183
+ user_message: 'Explain quantum computing in simple terms',
184
+ conversation_history: [],
185
+ });
186
+
187
+ console.log('\n=== Flow Complete ===');
188
+ console.log('Status:', result.status);
189
+ console.log('Intent:', result.intent);
190
+ console.log('Final Response:', result.data.ai_response);
191
+ console.log('Steps taken:', result.stepHistory.length);
192
+ console.log('Duration:', result.durationMs, 'ms');
193
+ }
194
+
195
+ main().catch(console.error);
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Node.js Example: Simple Greeting Flow
3
+ *
4
+ * Demonstrates basic usage with file-based persistence.
5
+ *
6
+ * Run with: npx ts-node examples/node/simple-greeting.ts
7
+ * Or after build: node examples/node/simple-greeting.js
8
+ */
9
+
10
+ import { createEngine, loadFlow, FileStore } from '../../src/index.js';
11
+ import type { StepInput, StepContext, StepResult } from '../../src/index.js';
12
+ import { fileURLToPath } from 'url';
13
+ import { dirname, join } from 'path';
14
+
15
+ const __filename = fileURLToPath(import.meta.url);
16
+ const __dirname = dirname(__filename);
17
+
18
+ // Define step handlers as pure functions
19
+ const handlers = {
20
+ async greet(input: StepInput, ctx: StepContext): Promise<StepResult> {
21
+ const userName = (input.initial_name as string) || 'World';
22
+
23
+ console.log(`[${ctx.stepName}] Generating greeting for: ${userName}`);
24
+
25
+ return {
26
+ result: 'success',
27
+ data: {
28
+ greeting: 'Hello',
29
+ user_name: userName,
30
+ },
31
+ };
32
+ },
33
+
34
+ async validate(input: StepInput, ctx: StepContext): Promise<StepResult> {
35
+ const { greeting, user_name } = input;
36
+
37
+ console.log(`[${ctx.stepName}] Validating: ${greeting} ${user_name}`);
38
+
39
+ const isValid = typeof greeting === 'string' &&
40
+ greeting.length > 0 &&
41
+ typeof user_name === 'string';
42
+
43
+ if (!isValid) {
44
+ return { result: 'invalid', data: { is_valid: false } };
45
+ }
46
+
47
+ return {
48
+ result: 'success',
49
+ data: { is_valid: true },
50
+ };
51
+ },
52
+
53
+ async personalize(input: StepInput, ctx: StepContext): Promise<StepResult> {
54
+ const { greeting, user_name } = input;
55
+
56
+ const finalMessage = `${greeting}, ${user_name}! Welcome to yaml-flow.`;
57
+
58
+ console.log(`[${ctx.stepName}] Created message: ${finalMessage}`);
59
+
60
+ return {
61
+ result: 'success',
62
+ data: { final_message: finalMessage },
63
+ };
64
+ },
65
+ };
66
+
67
+ async function main() {
68
+ // Load flow from YAML file
69
+ const flowPath = join(__dirname, '../flows/simple-greeting.yaml');
70
+ const flow = await loadFlow(flowPath);
71
+
72
+ console.log('Loaded flow:', flow.id ?? 'simple-greeting');
73
+ console.log('Steps:', Object.keys(flow.steps).join(', '));
74
+ console.log('---');
75
+
76
+ // Create engine with file-based persistence
77
+ const engine = createEngine(flow, handlers, {
78
+ store: new FileStore({ directory: './flow-data' }),
79
+ onStep: (step, result) => {
80
+ console.log(`Step completed: ${step} -> ${result.result}`);
81
+ },
82
+ onTransition: (from, to) => {
83
+ console.log(`Transition: ${from} -> ${to}`);
84
+ },
85
+ });
86
+
87
+ // Run the flow
88
+ const result = await engine.run({
89
+ initial_name: 'Developer',
90
+ });
91
+
92
+ console.log('---');
93
+ console.log('Flow Result:');
94
+ console.log(' Status:', result.status);
95
+ console.log(' Intent:', result.intent);
96
+ console.log(' Data:', result.data);
97
+ console.log(' Steps:', result.stepHistory.join(' -> '));
98
+ console.log(' Duration:', result.durationMs, 'ms');
99
+ }
100
+
101
+ main().catch(console.error);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yaml-flow",
3
- "version": "3.0.0",
3
+ "version": "3.1.1",
4
4
  "description": "Unified workflow engine: step-machine (sequential) + event-graph (stateless DAG) with pluggable storage",
5
5
  "author": "",
6
6
  "license": "MIT",
@@ -76,7 +76,8 @@
76
76
  "files": [
77
77
  "dist",
78
78
  "schema",
79
- "browser"
79
+ "browser",
80
+ "examples"
80
81
  ],
81
82
  "scripts": {
82
83
  "build": "tsup",