@multiplier-labs/stepflow 0.3.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.
- package/.github/workflows/publish.yml +30 -0
- package/README.md +408 -0
- package/dist/chunk-FQCT3I2A.js +1512 -0
- package/dist/chunk-FQCT3I2A.js.map +1 -0
- package/dist/chunk-GXY66V7Q.js +111 -0
- package/dist/chunk-GXY66V7Q.js.map +1 -0
- package/dist/chunk-U5QGN3RT.js +715 -0
- package/dist/chunk-U5QGN3RT.js.map +1 -0
- package/dist/chunk-XCF4PLN7.js +575 -0
- package/dist/chunk-XCF4PLN7.js.map +1 -0
- package/dist/events/index.d.ts +346 -0
- package/dist/events/index.js +11 -0
- package/dist/events/index.js.map +1 -0
- package/dist/index-CPfGsmrp.d.ts +567 -0
- package/dist/index.d.ts +748 -0
- package/dist/index.js +1707 -0
- package/dist/index.js.map +1 -0
- package/dist/scheduler/index.d.ts +6 -0
- package/dist/scheduler/index.js +12 -0
- package/dist/scheduler/index.js.map +1 -0
- package/dist/storage/index.d.ts +402 -0
- package/dist/storage/index.js +13 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/types-BVShq7zT.d.ts +150 -0
- package/dist/types-BlwFEGzj.d.ts +276 -0
- package/dist/types-DzkEqnQJ.d.ts +75 -0
- package/docs/github-packages-setup.md +97 -0
- package/docs/stepflow-api-reference.md +1662 -0
- package/package.json +85 -0
- package/src/core/engine.test.ts +1421 -0
- package/src/core/engine.ts +717 -0
- package/src/core/index.ts +7 -0
- package/src/core/orchestrator.ts +590 -0
- package/src/core/types.ts +242 -0
- package/src/events/index.ts +8 -0
- package/src/events/memory.test.ts +109 -0
- package/src/events/memory.ts +95 -0
- package/src/events/socketio.test.ts +428 -0
- package/src/events/socketio.ts +269 -0
- package/src/events/types.ts +121 -0
- package/src/events/webhook.test.ts +695 -0
- package/src/events/webhook.ts +591 -0
- package/src/index.ts +270 -0
- package/src/planning/index.ts +52 -0
- package/src/planning/planner.ts +601 -0
- package/src/planning/planning.test.ts +790 -0
- package/src/planning/registry.test.ts +445 -0
- package/src/planning/registry.ts +369 -0
- package/src/planning/types.ts +570 -0
- package/src/scheduler/cron.test.ts +480 -0
- package/src/scheduler/cron.ts +449 -0
- package/src/scheduler/index.ts +18 -0
- package/src/scheduler/postgres-persistence.test.ts +906 -0
- package/src/scheduler/postgres-persistence.ts +546 -0
- package/src/scheduler/sqlite-persistence.test.ts +235 -0
- package/src/scheduler/sqlite-persistence.ts +268 -0
- package/src/scheduler/types.ts +78 -0
- package/src/storage/index.ts +27 -0
- package/src/storage/memory.test.ts +399 -0
- package/src/storage/memory.ts +248 -0
- package/src/storage/postgres.ts +1550 -0
- package/src/storage/sqlite.test.ts +593 -0
- package/src/storage/sqlite.ts +662 -0
- package/src/storage/types.ts +368 -0
- package/src/utils/errors.test.ts +152 -0
- package/src/utils/errors.ts +191 -0
- package/src/utils/id.ts +21 -0
- package/src/utils/index.ts +8 -0
- package/src/utils/logger.test.ts +127 -0
- package/src/utils/logger.ts +96 -0
- package/src/utils/postgres-deps.ts +63 -0
- package/src/utils/retry.test.ts +197 -0
- package/src/utils/retry.ts +121 -0
- package/tsconfig.json +21 -0
- package/tsup.config.ts +14 -0
- package/vitest.config.ts +9 -0
|
@@ -0,0 +1,570 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Planning types for the workflow engine.
|
|
3
|
+
* Enables dynamic workflow orchestration through recipes and plans.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type {
|
|
7
|
+
WorkflowKind,
|
|
8
|
+
StepErrorStrategy,
|
|
9
|
+
WorkflowStep,
|
|
10
|
+
} from "../core/types";
|
|
11
|
+
|
|
12
|
+
// Re-export core types used in planning
|
|
13
|
+
export type { WorkflowKind, StepErrorStrategy } from "../core/types";
|
|
14
|
+
|
|
15
|
+
// ============================================================================
|
|
16
|
+
// Recipe Types
|
|
17
|
+
// ============================================================================
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Comparison operators for recipe conditions.
|
|
21
|
+
*/
|
|
22
|
+
export type ConditionOperator =
|
|
23
|
+
| "eq" // equals
|
|
24
|
+
| "neq" // not equals
|
|
25
|
+
| "gt" // greater than
|
|
26
|
+
| "gte" // greater than or equal
|
|
27
|
+
| "lt" // less than
|
|
28
|
+
| "lte" // less than or equal
|
|
29
|
+
| "contains" // string/array contains
|
|
30
|
+
| "matches" // regex match
|
|
31
|
+
| "exists" // field exists and is truthy
|
|
32
|
+
| "notExists"; // field does not exist or is falsy
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* A condition that determines when a recipe should be selected.
|
|
36
|
+
* Conditions are evaluated against the workflow input.
|
|
37
|
+
*/
|
|
38
|
+
export interface RecipeCondition {
|
|
39
|
+
/** Input field to check (supports dot notation for nested fields) */
|
|
40
|
+
field: string;
|
|
41
|
+
|
|
42
|
+
/** Comparison operator */
|
|
43
|
+
operator: ConditionOperator;
|
|
44
|
+
|
|
45
|
+
/** Value to compare against (not required for exists/notExists) */
|
|
46
|
+
value?: unknown;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Default parameters for a recipe.
|
|
51
|
+
*/
|
|
52
|
+
export interface RecipeDefaults {
|
|
53
|
+
/** Workflow-level timeout in ms */
|
|
54
|
+
timeout?: number;
|
|
55
|
+
|
|
56
|
+
/** Default max retries for steps */
|
|
57
|
+
maxRetries?: number;
|
|
58
|
+
|
|
59
|
+
/** Base retry delay in ms */
|
|
60
|
+
retryDelay?: number;
|
|
61
|
+
|
|
62
|
+
/** Retry backoff multiplier */
|
|
63
|
+
retryBackoff?: number;
|
|
64
|
+
|
|
65
|
+
/** Default error strategy for steps */
|
|
66
|
+
onError?: StepErrorStrategy;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Reference to a step handler function.
|
|
71
|
+
* The actual handler is resolved at plan execution time.
|
|
72
|
+
*/
|
|
73
|
+
export interface StepHandlerRef {
|
|
74
|
+
/** Unique handler identifier (e.g., 'handlers.loadDocument') */
|
|
75
|
+
id: string;
|
|
76
|
+
|
|
77
|
+
/** Human-readable description */
|
|
78
|
+
description?: string;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* A step definition within a recipe.
|
|
83
|
+
* Similar to WorkflowStep but uses handler references instead of functions.
|
|
84
|
+
*/
|
|
85
|
+
export interface RecipeStep {
|
|
86
|
+
/** Unique step identifier within the recipe */
|
|
87
|
+
key: string;
|
|
88
|
+
|
|
89
|
+
/** Human-readable step name */
|
|
90
|
+
name: string;
|
|
91
|
+
|
|
92
|
+
/** Reference to the step handler function */
|
|
93
|
+
handlerRef: string;
|
|
94
|
+
|
|
95
|
+
/** Step-specific configuration passed to the handler */
|
|
96
|
+
config?: Record<string, unknown>;
|
|
97
|
+
|
|
98
|
+
/** Error handling strategy */
|
|
99
|
+
onError?: StepErrorStrategy;
|
|
100
|
+
|
|
101
|
+
/** Maximum retry attempts */
|
|
102
|
+
maxRetries?: number;
|
|
103
|
+
|
|
104
|
+
/** Retry delay in ms */
|
|
105
|
+
retryDelay?: number;
|
|
106
|
+
|
|
107
|
+
/** Retry backoff multiplier */
|
|
108
|
+
retryBackoff?: number;
|
|
109
|
+
|
|
110
|
+
/** Step timeout in ms */
|
|
111
|
+
timeout?: number;
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Expression to evaluate for skipping (simple field reference).
|
|
115
|
+
* If the referenced field is truthy, the step is skipped.
|
|
116
|
+
* Example: 'input.skipValidation' or 'results.load.alreadyExists'
|
|
117
|
+
*/
|
|
118
|
+
skipCondition?: string;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* A recipe is a reusable workflow configuration template.
|
|
123
|
+
* Recipes define the steps to execute and conditions for selection.
|
|
124
|
+
*/
|
|
125
|
+
export interface Recipe {
|
|
126
|
+
/** Unique recipe identifier (e.g., 'summarize.comprehensive') */
|
|
127
|
+
id: string;
|
|
128
|
+
|
|
129
|
+
/** Human-readable name */
|
|
130
|
+
name: string;
|
|
131
|
+
|
|
132
|
+
/** Description of what this recipe does */
|
|
133
|
+
description?: string;
|
|
134
|
+
|
|
135
|
+
/** Target workflow type */
|
|
136
|
+
workflowKind: WorkflowKind;
|
|
137
|
+
|
|
138
|
+
/** Variant name (e.g., 'default', 'fast', 'thorough') */
|
|
139
|
+
variant: string;
|
|
140
|
+
|
|
141
|
+
/** Ordered list of steps to execute */
|
|
142
|
+
steps: RecipeStep[];
|
|
143
|
+
|
|
144
|
+
/** Default parameters for this recipe */
|
|
145
|
+
defaults?: RecipeDefaults;
|
|
146
|
+
|
|
147
|
+
/** Conditions for auto-selecting this recipe */
|
|
148
|
+
conditions?: RecipeCondition[];
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Selection priority. Semantics differ by context:
|
|
152
|
+
* - {@link MemoryRecipeRegistry.getDefault}: lower number = higher precedence
|
|
153
|
+
* (used as fallback when no 'default' variant exists).
|
|
154
|
+
* - {@link RuleBasedPlanner.selectRecipe}: condition-based scoring (0-100) is
|
|
155
|
+
* the primary selection axis; this value is only a tiebreaker where higher
|
|
156
|
+
* numeric value wins.
|
|
157
|
+
*/
|
|
158
|
+
priority?: number;
|
|
159
|
+
|
|
160
|
+
/** Tags for categorization and filtering */
|
|
161
|
+
tags?: string[];
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// ============================================================================
|
|
165
|
+
// Plan Types
|
|
166
|
+
// ============================================================================
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Types of modifications that can be made to a plan.
|
|
170
|
+
*/
|
|
171
|
+
export type PlanModificationType =
|
|
172
|
+
| "add_step" // Add a new step
|
|
173
|
+
| "remove_step" // Remove an existing step
|
|
174
|
+
| "modify_step" // Modify step configuration
|
|
175
|
+
| "reorder_steps" // Change step order
|
|
176
|
+
| "set_default"; // Override a default parameter
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* A modification to apply to a recipe when generating a plan.
|
|
180
|
+
*/
|
|
181
|
+
export interface PlanModification {
|
|
182
|
+
/** Type of modification */
|
|
183
|
+
type: PlanModificationType;
|
|
184
|
+
|
|
185
|
+
/** Target step key (for step modifications) */
|
|
186
|
+
stepKey?: string;
|
|
187
|
+
|
|
188
|
+
/** New value or configuration */
|
|
189
|
+
value: unknown;
|
|
190
|
+
|
|
191
|
+
/** Human-readable reason for this modification */
|
|
192
|
+
reason: string;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* A resolved step in a plan, ready for execution.
|
|
197
|
+
*/
|
|
198
|
+
export interface PlannedStep {
|
|
199
|
+
/** Unique step identifier */
|
|
200
|
+
key: string;
|
|
201
|
+
|
|
202
|
+
/** Human-readable step name */
|
|
203
|
+
name: string;
|
|
204
|
+
|
|
205
|
+
/** Reference to the step handler */
|
|
206
|
+
handlerRef: string;
|
|
207
|
+
|
|
208
|
+
/** Resolved configuration for this step */
|
|
209
|
+
config: Record<string, unknown>;
|
|
210
|
+
|
|
211
|
+
/** Error handling strategy */
|
|
212
|
+
onError?: StepErrorStrategy;
|
|
213
|
+
|
|
214
|
+
/** Maximum retry attempts */
|
|
215
|
+
maxRetries?: number;
|
|
216
|
+
|
|
217
|
+
/** Retry delay in ms */
|
|
218
|
+
retryDelay?: number;
|
|
219
|
+
|
|
220
|
+
/** Retry backoff multiplier */
|
|
221
|
+
retryBackoff?: number;
|
|
222
|
+
|
|
223
|
+
/** Step timeout in ms */
|
|
224
|
+
timeout?: number;
|
|
225
|
+
|
|
226
|
+
/** Skip condition expression */
|
|
227
|
+
skipCondition?: string;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* A planned child workflow to spawn during execution.
|
|
232
|
+
*/
|
|
233
|
+
export interface ChildWorkflowPlan {
|
|
234
|
+
/** Workflow type to spawn */
|
|
235
|
+
kind: WorkflowKind;
|
|
236
|
+
|
|
237
|
+
/** Input for the child workflow */
|
|
238
|
+
input: Record<string, unknown>;
|
|
239
|
+
|
|
240
|
+
/** Whether to wait for the child to complete */
|
|
241
|
+
waitFor?: boolean;
|
|
242
|
+
|
|
243
|
+
/** Step key after which to spawn this workflow */
|
|
244
|
+
afterStep?: string;
|
|
245
|
+
|
|
246
|
+
/** Optional metadata for the child workflow */
|
|
247
|
+
metadata?: Record<string, unknown>;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Resource requirements estimated for a plan.
|
|
252
|
+
*/
|
|
253
|
+
export interface ResourceEstimate {
|
|
254
|
+
/** Estimated API calls */
|
|
255
|
+
apiCalls?: number;
|
|
256
|
+
|
|
257
|
+
/** Estimated LLM tokens */
|
|
258
|
+
tokens?: number;
|
|
259
|
+
|
|
260
|
+
/** Estimated duration in ms */
|
|
261
|
+
duration?: number;
|
|
262
|
+
|
|
263
|
+
/** Estimated memory usage in bytes */
|
|
264
|
+
memory?: number;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* A plan is the output of planning - a concrete execution strategy.
|
|
269
|
+
*/
|
|
270
|
+
export interface Plan {
|
|
271
|
+
/** Unique plan identifier */
|
|
272
|
+
id: string;
|
|
273
|
+
|
|
274
|
+
/** Recipe this plan is based on */
|
|
275
|
+
recipeId: string;
|
|
276
|
+
|
|
277
|
+
/** Recipe variant used */
|
|
278
|
+
variant: string;
|
|
279
|
+
|
|
280
|
+
/** Modifications applied to the base recipe */
|
|
281
|
+
modifications: PlanModification[];
|
|
282
|
+
|
|
283
|
+
/** Final step sequence after modifications */
|
|
284
|
+
steps: PlannedStep[];
|
|
285
|
+
|
|
286
|
+
/** Child workflows to spawn */
|
|
287
|
+
childWorkflows?: ChildWorkflowPlan[];
|
|
288
|
+
|
|
289
|
+
/** Resolved default parameters */
|
|
290
|
+
defaults: RecipeDefaults;
|
|
291
|
+
|
|
292
|
+
/** Human-readable reasoning for plan decisions */
|
|
293
|
+
reasoning?: string;
|
|
294
|
+
|
|
295
|
+
/** Estimated resource requirements */
|
|
296
|
+
resourceEstimate?: ResourceEstimate;
|
|
297
|
+
|
|
298
|
+
/** When this plan was generated */
|
|
299
|
+
createdAt: Date;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// ============================================================================
|
|
303
|
+
// Planning Context Types
|
|
304
|
+
// ============================================================================
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Priority modes for planning.
|
|
308
|
+
*/
|
|
309
|
+
export type PlanningPriority = "speed" | "quality" | "cost" | "balanced";
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* Constraints that limit planning and execution.
|
|
313
|
+
*/
|
|
314
|
+
export interface PlanningConstraints {
|
|
315
|
+
/** Maximum allowed duration in ms */
|
|
316
|
+
maxDuration?: number;
|
|
317
|
+
|
|
318
|
+
/** Maximum API calls allowed */
|
|
319
|
+
maxApiCalls?: number;
|
|
320
|
+
|
|
321
|
+
/** Maximum LLM tokens allowed */
|
|
322
|
+
maxTokens?: number;
|
|
323
|
+
|
|
324
|
+
/** Optimization priority */
|
|
325
|
+
priority?: PlanningPriority;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* User-provided hints to guide planning.
|
|
330
|
+
*/
|
|
331
|
+
export interface PlanningHints {
|
|
332
|
+
/** Preferred recipe variant */
|
|
333
|
+
preferredVariant?: string;
|
|
334
|
+
|
|
335
|
+
/** Specific recipe to use (bypasses selection) */
|
|
336
|
+
forceRecipeId?: string;
|
|
337
|
+
|
|
338
|
+
/** Steps to skip */
|
|
339
|
+
skipSteps?: string[];
|
|
340
|
+
|
|
341
|
+
/** Steps to include (even if normally skipped) */
|
|
342
|
+
includeSteps?: string[];
|
|
343
|
+
|
|
344
|
+
/** Focus areas (domain-specific) */
|
|
345
|
+
focusAreas?: string[];
|
|
346
|
+
|
|
347
|
+
/** Additional configuration to merge */
|
|
348
|
+
additionalConfig?: Record<string, unknown>;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* Context provided to the planner for decision-making.
|
|
353
|
+
*/
|
|
354
|
+
export interface PlanningContext {
|
|
355
|
+
/** Parent workflow run ID (if spawned as child) */
|
|
356
|
+
parentRunId?: string;
|
|
357
|
+
|
|
358
|
+
/** Domain-specific metadata */
|
|
359
|
+
metadata?: Record<string, unknown>;
|
|
360
|
+
|
|
361
|
+
/** Resource constraints */
|
|
362
|
+
constraints?: PlanningConstraints;
|
|
363
|
+
|
|
364
|
+
/** User-provided hints */
|
|
365
|
+
hints?: PlanningHints;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// ============================================================================
|
|
369
|
+
// Planner Interface
|
|
370
|
+
// ============================================================================
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Result of recipe selection.
|
|
374
|
+
*/
|
|
375
|
+
export interface RecipeSelectionResult {
|
|
376
|
+
/** Selected recipe */
|
|
377
|
+
recipe: Recipe;
|
|
378
|
+
|
|
379
|
+
/** Score indicating confidence (0-100) */
|
|
380
|
+
score: number;
|
|
381
|
+
|
|
382
|
+
/** Why this recipe was selected */
|
|
383
|
+
reason: string;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
/**
|
|
387
|
+
* Validation result for a plan.
|
|
388
|
+
*/
|
|
389
|
+
export interface PlanValidationResult {
|
|
390
|
+
/** Whether the plan is valid */
|
|
391
|
+
valid: boolean;
|
|
392
|
+
|
|
393
|
+
/** Validation errors (if any) */
|
|
394
|
+
errors: string[];
|
|
395
|
+
|
|
396
|
+
/** Validation warnings */
|
|
397
|
+
warnings: string[];
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
/**
|
|
401
|
+
* Planner interface for generating execution plans.
|
|
402
|
+
*/
|
|
403
|
+
export interface Planner {
|
|
404
|
+
/**
|
|
405
|
+
* Select the best recipe for a workflow and input.
|
|
406
|
+
*/
|
|
407
|
+
selectRecipe(
|
|
408
|
+
workflowKind: WorkflowKind,
|
|
409
|
+
input: Record<string, unknown>,
|
|
410
|
+
context?: PlanningContext,
|
|
411
|
+
): Promise<RecipeSelectionResult>;
|
|
412
|
+
|
|
413
|
+
/**
|
|
414
|
+
* Generate a plan from a recipe and input.
|
|
415
|
+
*/
|
|
416
|
+
generatePlan(
|
|
417
|
+
recipe: Recipe,
|
|
418
|
+
input: Record<string, unknown>,
|
|
419
|
+
context?: PlanningContext,
|
|
420
|
+
): Promise<Plan>;
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* Combined operation: select recipe and generate plan.
|
|
424
|
+
*/
|
|
425
|
+
plan(
|
|
426
|
+
workflowKind: WorkflowKind,
|
|
427
|
+
input: Record<string, unknown>,
|
|
428
|
+
context?: PlanningContext,
|
|
429
|
+
): Promise<Plan>;
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* Validate a plan before execution.
|
|
433
|
+
*/
|
|
434
|
+
validatePlan(plan: Plan): PlanValidationResult;
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* Estimate resources required for a plan.
|
|
438
|
+
*/
|
|
439
|
+
estimateResources(plan: Plan): ResourceEstimate;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
// ============================================================================
|
|
443
|
+
// Step Handler Registry Types
|
|
444
|
+
// ============================================================================
|
|
445
|
+
|
|
446
|
+
/**
|
|
447
|
+
* A registered step handler function.
|
|
448
|
+
*/
|
|
449
|
+
export interface RegisteredStepHandler<TInput = Record<string, unknown>> {
|
|
450
|
+
/** Unique handler identifier */
|
|
451
|
+
id: string;
|
|
452
|
+
|
|
453
|
+
/** Human-readable description */
|
|
454
|
+
description?: string;
|
|
455
|
+
|
|
456
|
+
/** The handler function */
|
|
457
|
+
handler: WorkflowStep<TInput>["handler"];
|
|
458
|
+
|
|
459
|
+
/** Tags for categorization */
|
|
460
|
+
tags?: string[];
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
/**
|
|
464
|
+
* Registry for step handlers.
|
|
465
|
+
* Allows recipes to reference handlers by ID.
|
|
466
|
+
*/
|
|
467
|
+
export interface StepHandlerRegistry {
|
|
468
|
+
/**
|
|
469
|
+
* Register a step handler.
|
|
470
|
+
*/
|
|
471
|
+
register<TInput = Record<string, unknown>>(
|
|
472
|
+
handler: RegisteredStepHandler<TInput>,
|
|
473
|
+
): void;
|
|
474
|
+
|
|
475
|
+
/**
|
|
476
|
+
* Get a handler by ID.
|
|
477
|
+
*/
|
|
478
|
+
get(id: string): RegisteredStepHandler | undefined;
|
|
479
|
+
|
|
480
|
+
/**
|
|
481
|
+
* Check if a handler exists.
|
|
482
|
+
*/
|
|
483
|
+
has(id: string): boolean;
|
|
484
|
+
|
|
485
|
+
/**
|
|
486
|
+
* List all registered handlers.
|
|
487
|
+
*/
|
|
488
|
+
list(): RegisteredStepHandler[];
|
|
489
|
+
|
|
490
|
+
/**
|
|
491
|
+
* List handlers by tag.
|
|
492
|
+
*/
|
|
493
|
+
listByTag(tag: string): RegisteredStepHandler[];
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
// ============================================================================
|
|
497
|
+
// Recipe Registry Types
|
|
498
|
+
// ============================================================================
|
|
499
|
+
|
|
500
|
+
/**
|
|
501
|
+
* Options for querying recipes.
|
|
502
|
+
*/
|
|
503
|
+
export interface RecipeQueryOptions {
|
|
504
|
+
/** Filter by workflow kind */
|
|
505
|
+
workflowKind?: WorkflowKind;
|
|
506
|
+
|
|
507
|
+
/** Filter by variant */
|
|
508
|
+
variant?: string;
|
|
509
|
+
|
|
510
|
+
/** Filter by tags (any match) */
|
|
511
|
+
tags?: string[];
|
|
512
|
+
|
|
513
|
+
/** Only include recipes matching conditions */
|
|
514
|
+
matchConditions?: Record<string, unknown>;
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
/**
|
|
518
|
+
* Registry for recipes.
|
|
519
|
+
*/
|
|
520
|
+
export interface RecipeRegistry {
|
|
521
|
+
/**
|
|
522
|
+
* Register a recipe.
|
|
523
|
+
*/
|
|
524
|
+
register(recipe: Recipe): void;
|
|
525
|
+
|
|
526
|
+
/**
|
|
527
|
+
* Register multiple recipes.
|
|
528
|
+
*/
|
|
529
|
+
registerAll(recipes: Recipe[]): void;
|
|
530
|
+
|
|
531
|
+
/**
|
|
532
|
+
* Get a recipe by ID.
|
|
533
|
+
*/
|
|
534
|
+
get(recipeId: string): Recipe | undefined;
|
|
535
|
+
|
|
536
|
+
/**
|
|
537
|
+
* Check if a recipe exists.
|
|
538
|
+
*/
|
|
539
|
+
has(recipeId: string): boolean;
|
|
540
|
+
|
|
541
|
+
/**
|
|
542
|
+
* Get all recipes for a workflow kind.
|
|
543
|
+
*/
|
|
544
|
+
getByKind(workflowKind: WorkflowKind): Recipe[];
|
|
545
|
+
|
|
546
|
+
/**
|
|
547
|
+
* Get a specific variant for a workflow kind.
|
|
548
|
+
*/
|
|
549
|
+
getVariant(workflowKind: WorkflowKind, variant: string): Recipe | undefined;
|
|
550
|
+
|
|
551
|
+
/**
|
|
552
|
+
* Get the default recipe for a workflow kind.
|
|
553
|
+
*/
|
|
554
|
+
getDefault(workflowKind: WorkflowKind): Recipe | undefined;
|
|
555
|
+
|
|
556
|
+
/**
|
|
557
|
+
* List all available variants for a workflow kind.
|
|
558
|
+
*/
|
|
559
|
+
listVariants(workflowKind: WorkflowKind): string[];
|
|
560
|
+
|
|
561
|
+
/**
|
|
562
|
+
* Query recipes with filters.
|
|
563
|
+
*/
|
|
564
|
+
query(options: RecipeQueryOptions): Recipe[];
|
|
565
|
+
|
|
566
|
+
/**
|
|
567
|
+
* List all registered recipes.
|
|
568
|
+
*/
|
|
569
|
+
list(): Recipe[];
|
|
570
|
+
}
|