@kb-labs/workflow-engine 1.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.
- package/README.md +408 -0
- package/dist/index.d.ts +1057 -0
- package/dist/index.js +3077 -0
- package/dist/index.js.map +1 -0
- package/package.json +67 -0
package/README.md
ADDED
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
# @kb-labs/workflow-engine
|
|
2
|
+
|
|
3
|
+
Workflow orchestration engine for KB Labs. Provides job scheduling, state management, Redis coordination, and workflow execution.
|
|
4
|
+
|
|
5
|
+
## Vision & Purpose
|
|
6
|
+
|
|
7
|
+
**@kb-labs/workflow-engine** provides workflow orchestration engine for KB Labs. It includes job scheduling, state management, Redis coordination, event bus, retry logic, concurrency control, and timeout handling.
|
|
8
|
+
|
|
9
|
+
### Core Goals
|
|
10
|
+
|
|
11
|
+
- **Job Scheduling**: Intelligent job scheduling with dependency resolution
|
|
12
|
+
- **Redis Coordination**: Distributed state management and coordination through Redis
|
|
13
|
+
- **Event Bus**: Event streaming for workflow observability
|
|
14
|
+
- **Retry Logic**: Configurable retry policies for jobs and steps
|
|
15
|
+
- **Concurrency Control**: Idempotency and concurrency group management
|
|
16
|
+
- **Timeout Handling**: Configurable timeouts for jobs and steps
|
|
17
|
+
|
|
18
|
+
## Package Status
|
|
19
|
+
|
|
20
|
+
- **Version**: 0.1.0
|
|
21
|
+
- **Stage**: Stable
|
|
22
|
+
- **Status**: Production Ready ✅
|
|
23
|
+
|
|
24
|
+
## Architecture
|
|
25
|
+
|
|
26
|
+
### High-Level Overview
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
Workflow Engine
|
|
30
|
+
│
|
|
31
|
+
├──► WorkflowEngine (main orchestrator)
|
|
32
|
+
├──► Job Scheduling
|
|
33
|
+
├──► State Management
|
|
34
|
+
├──► Redis Coordination
|
|
35
|
+
├──► Event Bus
|
|
36
|
+
├──► Retry Logic
|
|
37
|
+
├──► Concurrency Control
|
|
38
|
+
└──► Worker System
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Key Components
|
|
42
|
+
|
|
43
|
+
1. **Engine** (`engine.ts`): Main orchestration engine
|
|
44
|
+
2. **Scheduler** (`scheduler.ts`): Job scheduling with dependency resolution
|
|
45
|
+
3. **StateStore** (`state-store.ts`): State management
|
|
46
|
+
4. **RunCoordinator** (`run-coordinator.ts`): Run coordination
|
|
47
|
+
5. **ConcurrencyManager** (`concurrency-manager.ts`): Concurrency control
|
|
48
|
+
6. **JobRunner** (`job-runner.ts`): Job execution
|
|
49
|
+
7. **JobHandler** (`job-handler.ts`): Job handling
|
|
50
|
+
8. **Worker** (`worker.ts`): Worker system
|
|
51
|
+
9. **EventBus** (`event-bus.ts`): Event streaming
|
|
52
|
+
10. **Redis** (`redis.ts`): Redis client management
|
|
53
|
+
11. **ApprovalStepHandler** (`approval-step-handler.ts`): Approval step handling
|
|
54
|
+
12. **ArtifactMerger** (`artifact-merger.ts`): Cross-run artifact merging
|
|
55
|
+
13. **RunSnapshotStorage** (`run-snapshot.ts`): Snapshot storage for replay
|
|
56
|
+
14. **BudgetTracker** (`budget-tracker.ts`): Budget tracking and control
|
|
57
|
+
|
|
58
|
+
## ✨ Features
|
|
59
|
+
|
|
60
|
+
- **Job scheduling** with dependency resolution
|
|
61
|
+
- **Redis coordination** for distributed state
|
|
62
|
+
- **Event bus** for workflow observability
|
|
63
|
+
- **Retry logic** with configurable policies
|
|
64
|
+
- **Concurrency control** with idempotency
|
|
65
|
+
- **Timeout handling** for jobs and steps
|
|
66
|
+
- **Worker system** for background processing
|
|
67
|
+
- **State management** with Redis persistence
|
|
68
|
+
- **Nested workflows** - call workflows from within workflows
|
|
69
|
+
- **Conditional execution** - `if` expressions for steps and jobs
|
|
70
|
+
- **Step outputs** - capture and use outputs between steps
|
|
71
|
+
- **Job hooks** - pre/post/onSuccess/onFailure lifecycle hooks
|
|
72
|
+
- **Approval steps** - manual approval gates with Redis storage
|
|
73
|
+
- **Artifact merge** - merge artifacts from multiple runs with configurable strategies
|
|
74
|
+
- **Local replay** - replay workflows from snapshots with context restoration
|
|
75
|
+
- **Budget control** - track and limit workflow execution costs with extension points
|
|
76
|
+
|
|
77
|
+
## 📦 API Reference
|
|
78
|
+
|
|
79
|
+
### Main Exports
|
|
80
|
+
|
|
81
|
+
#### Engine Classes
|
|
82
|
+
|
|
83
|
+
- `WorkflowEngine`: Main orchestration engine
|
|
84
|
+
- `WorkflowWorker`: Worker for background processing
|
|
85
|
+
- `JobRunner`: Job execution runner
|
|
86
|
+
- `WorkflowJobHandler`: Job handler implementation
|
|
87
|
+
|
|
88
|
+
#### Factory Functions
|
|
89
|
+
|
|
90
|
+
- `createWorkflowWorker(options)`: Create workflow worker
|
|
91
|
+
- `createRedisClient(options)`: Create Redis client
|
|
92
|
+
|
|
93
|
+
#### Types & Interfaces
|
|
94
|
+
|
|
95
|
+
- `WorkflowEngineOptions`: Engine configuration
|
|
96
|
+
- `WorkflowWorkerOptions`: Worker configuration
|
|
97
|
+
- `CreateRunInput`: Run creation input
|
|
98
|
+
- `RunContext`: Run execution context
|
|
99
|
+
|
|
100
|
+
### Types & Interfaces
|
|
101
|
+
|
|
102
|
+
#### `WorkflowEngineOptions`
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
interface WorkflowEngineOptions {
|
|
106
|
+
redis?: CreateRedisClientOptions;
|
|
107
|
+
scheduler?: SchedulerOptions;
|
|
108
|
+
concurrency?: AcquireOptions;
|
|
109
|
+
runCoordinator?: RunCoordinatorOptions;
|
|
110
|
+
logger?: EngineLogger;
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
#### `WorkflowWorkerOptions`
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
interface WorkflowWorkerOptions {
|
|
118
|
+
engine: WorkflowEngine;
|
|
119
|
+
maxConcurrentJobs?: number;
|
|
120
|
+
capabilities?: string[];
|
|
121
|
+
permissions?: PermissionSpec;
|
|
122
|
+
logger?: {
|
|
123
|
+
level: 'silent' | 'error' | 'warn' | 'info' | 'debug';
|
|
124
|
+
};
|
|
125
|
+
reconnect?: CreateRedisClientOptions['reconnectStrategy'];
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## 🔧 Configuration
|
|
130
|
+
|
|
131
|
+
### Configuration Options
|
|
132
|
+
|
|
133
|
+
All configuration via `WorkflowEngineOptions`:
|
|
134
|
+
|
|
135
|
+
- **redis**: Redis client configuration
|
|
136
|
+
- **scheduler**: Scheduler configuration
|
|
137
|
+
- **concurrency**: Concurrency control options
|
|
138
|
+
- **runCoordinator**: Run coordinator options
|
|
139
|
+
- **logger**: Logger configuration
|
|
140
|
+
|
|
141
|
+
### Environment Variables
|
|
142
|
+
|
|
143
|
+
- `KB_REDIS_URL`: Redis connection URL
|
|
144
|
+
- `LOG_LEVEL`: Logging level
|
|
145
|
+
|
|
146
|
+
## 🔗 Dependencies
|
|
147
|
+
|
|
148
|
+
### Runtime Dependencies
|
|
149
|
+
|
|
150
|
+
- `@kb-labs/core-sys` (`link:../../../kb-labs-core/packages/sys`): Core sys
|
|
151
|
+
- `@kb-labs/cli-core` (`link:../../../kb-labs-cli/packages/core`): CLI core
|
|
152
|
+
- `@kb-labs/plugin-manifest` (`link:../../../kb-labs-plugin/packages/manifest`): Plugin manifest
|
|
153
|
+
- `@kb-labs/plugin-runtime` (`link:../../../kb-labs-plugin/packages/runtime`): Plugin runtime
|
|
154
|
+
- `@kb-labs/workflow-artifacts` (`workspace:*`): Workflow artifacts
|
|
155
|
+
- `@kb-labs/workflow-constants` (`workspace:*`): Workflow constants
|
|
156
|
+
- `@kb-labs/workflow-contracts` (`workspace:*`): Workflow contracts
|
|
157
|
+
- `@kb-labs/workflow-runtime` (`workspace:*`): Workflow runtime
|
|
158
|
+
- `ioredis` (`^5.4.1`): Redis client
|
|
159
|
+
- `pino` (`^9.4.0`): Logger
|
|
160
|
+
- `yaml` (`^2.8.0`): YAML parsing
|
|
161
|
+
- `zod` (`^4.1.5`): Schema validation
|
|
162
|
+
|
|
163
|
+
### Development Dependencies
|
|
164
|
+
|
|
165
|
+
- `@kb-labs/devkit` (`link:../../../kb-labs-devkit`): DevKit presets
|
|
166
|
+
- `@types/node` (`^24.3.3`): Node.js types
|
|
167
|
+
- `tsup` (`^8.5.0`): TypeScript bundler
|
|
168
|
+
- `typescript` (`^5.6.3`): TypeScript compiler
|
|
169
|
+
- `vitest` (`^3.2.4`): Test runner
|
|
170
|
+
|
|
171
|
+
## 🧪 Testing
|
|
172
|
+
|
|
173
|
+
### Test Structure
|
|
174
|
+
|
|
175
|
+
```
|
|
176
|
+
src/__tests__/
|
|
177
|
+
├── job-runner.timeout.spec.ts
|
|
178
|
+
├── plugin-command-resolver.spec.ts
|
|
179
|
+
└── scheduler.priority.spec.ts
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Test Coverage
|
|
183
|
+
|
|
184
|
+
- **Current Coverage**: ~70%
|
|
185
|
+
- **Target Coverage**: 90%
|
|
186
|
+
|
|
187
|
+
## 📈 Performance
|
|
188
|
+
|
|
189
|
+
### Performance Characteristics
|
|
190
|
+
|
|
191
|
+
- **Time Complexity**: O(n) for scheduling, O(1) for state operations
|
|
192
|
+
- **Space Complexity**: O(n) where n = number of jobs
|
|
193
|
+
- **Bottlenecks**: Redis operations, job scheduling
|
|
194
|
+
|
|
195
|
+
## 🔒 Security
|
|
196
|
+
|
|
197
|
+
### Security Considerations
|
|
198
|
+
|
|
199
|
+
- **Redis Security**: Redis connection security
|
|
200
|
+
- **Permission Checking**: Capability checks before execution
|
|
201
|
+
- **Secrets Management**: Secrets management for workflows
|
|
202
|
+
- **Concurrency Control**: Idempotency and concurrency limits
|
|
203
|
+
|
|
204
|
+
### Known Vulnerabilities
|
|
205
|
+
|
|
206
|
+
- None
|
|
207
|
+
|
|
208
|
+
## 🐛 Known Issues & Limitations
|
|
209
|
+
|
|
210
|
+
### Known Issues
|
|
211
|
+
|
|
212
|
+
- None currently
|
|
213
|
+
|
|
214
|
+
### Limitations
|
|
215
|
+
|
|
216
|
+
- **Redis Dependency**: Requires Redis for distributed coordination
|
|
217
|
+
- **State Persistence**: State stored in Redis only
|
|
218
|
+
|
|
219
|
+
### Future Improvements
|
|
220
|
+
|
|
221
|
+
- **Alternative State Stores**: Support for other state stores
|
|
222
|
+
- **Enhanced Retry Policies**: More retry policy options
|
|
223
|
+
|
|
224
|
+
## 🔄 Migration & Breaking Changes
|
|
225
|
+
|
|
226
|
+
### Migration from Previous Versions
|
|
227
|
+
|
|
228
|
+
No breaking changes in current version (0.1.0).
|
|
229
|
+
|
|
230
|
+
### Breaking Changes in Future Versions
|
|
231
|
+
|
|
232
|
+
- None planned
|
|
233
|
+
|
|
234
|
+
## 📚 Examples
|
|
235
|
+
|
|
236
|
+
### Example 1: Create Engine and Run Workflow
|
|
237
|
+
|
|
238
|
+
```typescript
|
|
239
|
+
import { WorkflowEngine, createRedisClient } from '@kb-labs/workflow-engine';
|
|
240
|
+
import type { WorkflowSpec } from '@kb-labs/workflow-contracts';
|
|
241
|
+
|
|
242
|
+
const redis = await createRedisClient({
|
|
243
|
+
url: process.env.KB_REDIS_URL || 'redis://localhost:6379',
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
const engine = new WorkflowEngine({
|
|
247
|
+
redis,
|
|
248
|
+
logger: getLogger('workflow'),
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
const run = await engine.run(spec, {
|
|
252
|
+
idempotency: 'unique-key',
|
|
253
|
+
concurrency: { group: 'my-group' },
|
|
254
|
+
});
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### Example 2: Create Worker
|
|
258
|
+
|
|
259
|
+
```typescript
|
|
260
|
+
import { createWorkflowWorker } from '@kb-labs/workflow-engine';
|
|
261
|
+
|
|
262
|
+
const worker = createWorkflowWorker({
|
|
263
|
+
engine,
|
|
264
|
+
maxConcurrentJobs: 2,
|
|
265
|
+
capabilities: ['fs.read'],
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
await worker.start();
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
### Example 3: Handle Events
|
|
272
|
+
|
|
273
|
+
```typescript
|
|
274
|
+
import { WorkflowEngine } from '@kb-labs/workflow-engine';
|
|
275
|
+
|
|
276
|
+
const engine = new WorkflowEngine({ redis });
|
|
277
|
+
|
|
278
|
+
engine.on('run.started', (event) => {
|
|
279
|
+
console.log('Run started:', event.runId);
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
engine.on('run.completed', (event) => {
|
|
283
|
+
console.log('Run completed:', event.runId);
|
|
284
|
+
});
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
## 🔧 Advanced Features
|
|
288
|
+
|
|
289
|
+
### Nested Workflows
|
|
290
|
+
|
|
291
|
+
The workflow engine supports calling workflows from within other workflows using the `workflow:` prefix:
|
|
292
|
+
|
|
293
|
+
```yaml
|
|
294
|
+
steps:
|
|
295
|
+
- name: Call Child Workflow
|
|
296
|
+
uses: workflow:workspace:child-workflow
|
|
297
|
+
with:
|
|
298
|
+
input: value
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
**Key Features:**
|
|
302
|
+
- **Workflow Registry**: Discovers workflows from workspace and plugins
|
|
303
|
+
- **Depth Guard**: Prevents infinite recursion with `maxDepth` configuration
|
|
304
|
+
- **Parent/Child Linkage**: Child runs include parent metadata for analytics
|
|
305
|
+
- **Cancellation Propagation**: Parent cancellation automatically cancels child runs
|
|
306
|
+
- **Mode Support**: Currently supports `mode: 'wait'` (MVP), `fire-and-forget` throws error
|
|
307
|
+
|
|
308
|
+
**Configuration:**
|
|
309
|
+
```json
|
|
310
|
+
{
|
|
311
|
+
"workflow": {
|
|
312
|
+
"maxDepth": 2,
|
|
313
|
+
"workspaces": [".kb/workflows/**/*.yml"],
|
|
314
|
+
"plugins": true
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
### Conditional Execution
|
|
320
|
+
|
|
321
|
+
Steps and jobs can be conditionally executed using `if` expressions:
|
|
322
|
+
|
|
323
|
+
```yaml
|
|
324
|
+
jobs:
|
|
325
|
+
deploy:
|
|
326
|
+
if: ${{ trigger.type == 'push' && trigger.payload.ref == 'refs/heads/main' }}
|
|
327
|
+
steps:
|
|
328
|
+
- name: Deploy
|
|
329
|
+
if: ${{ steps.tests.outputs.exitCode == 0 }}
|
|
330
|
+
uses: builtin:shell
|
|
331
|
+
with:
|
|
332
|
+
command: npm run deploy
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
**Expression Context:**
|
|
336
|
+
- `env.*`: Environment variables
|
|
337
|
+
- `trigger.*`: Run trigger information
|
|
338
|
+
- `steps.<id>.outputs.*`: Step outputs
|
|
339
|
+
- Boolean literals and comparison operators
|
|
340
|
+
|
|
341
|
+
### Step Outputs
|
|
342
|
+
|
|
343
|
+
Steps can produce outputs accessible in subsequent steps:
|
|
344
|
+
|
|
345
|
+
```yaml
|
|
346
|
+
steps:
|
|
347
|
+
- name: Generate Version
|
|
348
|
+
id: version
|
|
349
|
+
uses: builtin:shell
|
|
350
|
+
with:
|
|
351
|
+
command: echo "1.0.0"
|
|
352
|
+
|
|
353
|
+
- name: Use Output
|
|
354
|
+
uses: builtin:shell
|
|
355
|
+
with:
|
|
356
|
+
command: echo "Version: ${{ steps.version.outputs.result }}"
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
Outputs are automatically captured from step execution results and available in expressions.
|
|
360
|
+
|
|
361
|
+
### Job Hooks
|
|
362
|
+
|
|
363
|
+
Jobs can define hooks that run at different lifecycle stages:
|
|
364
|
+
|
|
365
|
+
```yaml
|
|
366
|
+
jobs:
|
|
367
|
+
main:
|
|
368
|
+
hooks:
|
|
369
|
+
pre:
|
|
370
|
+
- name: Setup
|
|
371
|
+
uses: builtin:shell
|
|
372
|
+
with:
|
|
373
|
+
command: echo "Setting up..."
|
|
374
|
+
post:
|
|
375
|
+
- name: Cleanup
|
|
376
|
+
uses: builtin:shell
|
|
377
|
+
with:
|
|
378
|
+
command: echo "Cleaning up..."
|
|
379
|
+
onSuccess:
|
|
380
|
+
- name: Notify Success
|
|
381
|
+
uses: builtin:shell
|
|
382
|
+
with:
|
|
383
|
+
command: echo "✓ Success"
|
|
384
|
+
onFailure:
|
|
385
|
+
- name: Notify Failure
|
|
386
|
+
uses: builtin:shell
|
|
387
|
+
with:
|
|
388
|
+
command: echo "✗ Failed"
|
|
389
|
+
steps:
|
|
390
|
+
- name: Main Task
|
|
391
|
+
uses: builtin:shell
|
|
392
|
+
with:
|
|
393
|
+
command: echo "Running main task..."
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
**Hook Execution Order:**
|
|
397
|
+
1. `pre` hooks (before main steps)
|
|
398
|
+
2. Main steps
|
|
399
|
+
3. `post` hooks (always, after main steps)
|
|
400
|
+
4. `onSuccess` or `onFailure` hooks (based on job result)
|
|
401
|
+
|
|
402
|
+
## 🤝 Contributing
|
|
403
|
+
|
|
404
|
+
See [CONTRIBUTING.md](../../CONTRIBUTING.md) for development guidelines.
|
|
405
|
+
|
|
406
|
+
## 📄 License
|
|
407
|
+
|
|
408
|
+
MIT © KB Labs
|