@hexabot-ai/agentic 3.0.1-alpha.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/LICENSE.md +120 -0
- package/README.md +231 -0
- package/dist/cjs/action/abstract-action.js +141 -0
- package/dist/cjs/action/action.js +47 -0
- package/dist/cjs/action/action.types.js +7 -0
- package/dist/cjs/bindings/base-binding.js +278 -0
- package/dist/cjs/context.js +79 -0
- package/dist/cjs/dsl.types.js +318 -0
- package/dist/cjs/index.js +52 -0
- package/dist/cjs/runner-runtime-control.js +343 -0
- package/dist/cjs/step-executors/conditional-executor.js +63 -0
- package/dist/cjs/step-executors/loop-executor.js +187 -0
- package/dist/cjs/step-executors/parallel-executor.js +51 -0
- package/dist/cjs/step-executors/skip-helpers.js +29 -0
- package/dist/cjs/step-executors/task-executor.js +155 -0
- package/dist/cjs/step-executors/types.js +7 -0
- package/dist/cjs/suspension-rebuilder.js +301 -0
- package/dist/cjs/utils/deferred.js +17 -0
- package/dist/cjs/utils/naming.js +48 -0
- package/dist/cjs/utils/timeout.js +42 -0
- package/dist/cjs/utils/workflow-definition.js +102 -0
- package/dist/cjs/workflow-compiler.js +212 -0
- package/dist/cjs/workflow-event-emitter.js +40 -0
- package/dist/cjs/workflow-runner.js +448 -0
- package/dist/cjs/workflow-types.js +7 -0
- package/dist/cjs/workflow-values.js +99 -0
- package/dist/cjs/workflow.js +243 -0
- package/dist/esm/action/abstract-action.js +137 -0
- package/dist/esm/action/action.js +44 -0
- package/dist/esm/action/action.types.js +6 -0
- package/dist/esm/bindings/base-binding.js +273 -0
- package/dist/esm/context.js +75 -0
- package/dist/esm/dsl.types.js +309 -0
- package/dist/esm/index.js +16 -0
- package/dist/esm/runner-runtime-control.js +338 -0
- package/dist/esm/step-executors/conditional-executor.js +60 -0
- package/dist/esm/step-executors/loop-executor.js +182 -0
- package/dist/esm/step-executors/parallel-executor.js +48 -0
- package/dist/esm/step-executors/skip-helpers.js +25 -0
- package/dist/esm/step-executors/task-executor.js +152 -0
- package/dist/esm/step-executors/types.js +6 -0
- package/dist/esm/suspension-rebuilder.js +296 -0
- package/dist/esm/utils/deferred.js +14 -0
- package/dist/esm/utils/naming.js +42 -0
- package/dist/esm/utils/timeout.js +37 -0
- package/dist/esm/utils/workflow-definition.js +98 -0
- package/dist/esm/workflow-compiler.js +208 -0
- package/dist/esm/workflow-event-emitter.js +36 -0
- package/dist/esm/workflow-runner.js +444 -0
- package/dist/esm/workflow-types.js +6 -0
- package/dist/esm/workflow-values.js +89 -0
- package/dist/esm/workflow.js +236 -0
- package/dist/types/action/abstract-action.d.ts +54 -0
- package/dist/types/action/abstract-action.d.ts.map +1 -0
- package/dist/types/action/action.d.ts +23 -0
- package/dist/types/action/action.d.ts.map +1 -0
- package/dist/types/action/action.types.d.ts +55 -0
- package/dist/types/action/action.types.d.ts.map +1 -0
- package/dist/types/bindings/base-binding.d.ts +52 -0
- package/dist/types/bindings/base-binding.d.ts.map +1 -0
- package/dist/types/context.d.ts +105 -0
- package/dist/types/context.d.ts.map +1 -0
- package/dist/types/dsl.types.d.ts +220 -0
- package/dist/types/dsl.types.d.ts.map +1 -0
- package/dist/types/index.d.ts +18 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/runner-runtime-control.d.ts +64 -0
- package/dist/types/runner-runtime-control.d.ts.map +1 -0
- package/dist/types/step-executors/conditional-executor.d.ts +13 -0
- package/dist/types/step-executors/conditional-executor.d.ts.map +1 -0
- package/dist/types/step-executors/loop-executor.d.ts +33 -0
- package/dist/types/step-executors/loop-executor.d.ts.map +1 -0
- package/dist/types/step-executors/parallel-executor.d.ts +14 -0
- package/dist/types/step-executors/parallel-executor.d.ts.map +1 -0
- package/dist/types/step-executors/skip-helpers.d.ts +12 -0
- package/dist/types/step-executors/skip-helpers.d.ts.map +1 -0
- package/dist/types/step-executors/task-executor.d.ts +13 -0
- package/dist/types/step-executors/task-executor.d.ts.map +1 -0
- package/dist/types/step-executors/types.d.ts +24 -0
- package/dist/types/step-executors/types.d.ts.map +1 -0
- package/dist/types/suspension-rebuilder.d.ts +67 -0
- package/dist/types/suspension-rebuilder.d.ts.map +1 -0
- package/dist/types/utils/deferred.d.ts +7 -0
- package/dist/types/utils/deferred.d.ts.map +1 -0
- package/dist/types/utils/naming.d.ts +24 -0
- package/dist/types/utils/naming.d.ts.map +1 -0
- package/dist/types/utils/timeout.d.ts +17 -0
- package/dist/types/utils/timeout.d.ts.map +1 -0
- package/dist/types/utils/workflow-definition.d.ts +3 -0
- package/dist/types/utils/workflow-definition.d.ts.map +1 -0
- package/dist/types/workflow-compiler.d.ts +12 -0
- package/dist/types/workflow-compiler.d.ts.map +1 -0
- package/dist/types/workflow-event-emitter.d.ts +70 -0
- package/dist/types/workflow-event-emitter.d.ts.map +1 -0
- package/dist/types/workflow-runner.d.ts +179 -0
- package/dist/types/workflow-runner.d.ts.map +1 -0
- package/dist/types/workflow-types.d.ts +195 -0
- package/dist/types/workflow-types.d.ts.map +1 -0
- package/dist/types/workflow-values.d.ts +34 -0
- package/dist/types/workflow-values.d.ts.map +1 -0
- package/dist/types/workflow.d.ts +75 -0
- package/dist/types/workflow.d.ts.map +1 -0
- package/examples/defs-bindings-agent/actions/ai-agent.ts +110 -0
- package/examples/defs-bindings-agent/actions/caculate-score.ts +49 -0
- package/examples/defs-bindings-agent/actions/index.ts +15 -0
- package/examples/defs-bindings-agent/bindings.ts +20 -0
- package/examples/defs-bindings-agent/context.ts +32 -0
- package/examples/defs-bindings-agent/workflow.ts +67 -0
- package/examples/defs-bindings-agent/workflow.yml +28 -0
- package/examples/full/actions/await-user-input.ts +46 -0
- package/examples/full/actions/call-llm.ts +133 -0
- package/examples/full/actions/create-ticket.ts +46 -0
- package/examples/full/actions/decision-router.ts +83 -0
- package/examples/full/actions/get-calendar-events.ts +55 -0
- package/examples/full/actions/get-user-profile.ts +72 -0
- package/examples/full/actions/index.ts +33 -0
- package/examples/full/actions/query-memory.ts +45 -0
- package/examples/full/actions/search-web.ts +53 -0
- package/examples/full/actions/send-email.ts +50 -0
- package/examples/full/context.ts +41 -0
- package/examples/full/workflow.ts +75 -0
- package/examples/full/workflow.yml +359 -0
- package/examples/loop/actions/await-reply.ts +47 -0
- package/examples/loop/actions/index.ts +19 -0
- package/examples/loop/actions/send-text-message.ts +40 -0
- package/examples/loop/context.ts +32 -0
- package/examples/loop/workflow.ts +66 -0
- package/examples/loop/workflow.yml +66 -0
- package/examples/suspend-resume/actions/format-reply.ts +43 -0
- package/examples/suspend-resume/actions/index.ts +13 -0
- package/examples/suspend-resume/actions/wait-for-user.ts +51 -0
- package/examples/suspend-resume/context.ts +32 -0
- package/examples/suspend-resume/workflow.ts +79 -0
- package/examples/suspend-resume/workflow.yml +29 -0
- package/package.json +60 -0
- package/src/__tests__/parser.test.ts +95 -0
- package/src/__tests__/suspension-rebuilder.test.ts +361 -0
- package/src/__tests__/test-helpers.ts +36 -0
- package/src/__tests__/validation.test.ts +526 -0
- package/src/__tests__/workflow-compiler.test.ts +715 -0
- package/src/__tests__/workflow-definition-path.test.ts +381 -0
- package/src/__tests__/workflow-event-emitter.test.ts +50 -0
- package/src/__tests__/workflow-runner.test.ts +1397 -0
- package/src/__tests__/workflow-values.test.ts +132 -0
- package/src/__tests__/workflow.test.ts +320 -0
- package/src/action/__tests__/abstract-action-timing.test.ts +183 -0
- package/src/action/__tests__/action.test.ts +473 -0
- package/src/action/abstract-action.ts +215 -0
- package/src/action/action.ts +83 -0
- package/src/action/action.types.ts +93 -0
- package/src/bindings/base-binding.ts +508 -0
- package/src/context.ts +179 -0
- package/src/dsl.types.ts +473 -0
- package/src/index.ts +114 -0
- package/src/runner-runtime-control.ts +544 -0
- package/src/step-executors/conditional-executor.test.ts +192 -0
- package/src/step-executors/conditional-executor.ts +83 -0
- package/src/step-executors/loop-executor.test.ts +303 -0
- package/src/step-executors/loop-executor.ts +299 -0
- package/src/step-executors/parallel-executor.test.ts +182 -0
- package/src/step-executors/parallel-executor.ts +77 -0
- package/src/step-executors/skip-helpers.ts +68 -0
- package/src/step-executors/task-executor.test.ts +257 -0
- package/src/step-executors/task-executor.ts +248 -0
- package/src/step-executors/types.ts +70 -0
- package/src/suspension-rebuilder.ts +504 -0
- package/src/utils/deferred.ts +23 -0
- package/src/utils/naming.ts +55 -0
- package/src/utils/timeout.ts +48 -0
- package/src/utils/workflow-definition.ts +173 -0
- package/src/workflow-compiler.ts +317 -0
- package/src/workflow-event-emitter.ts +86 -0
- package/src/workflow-runner.ts +603 -0
- package/src/workflow-types.ts +207 -0
- package/src/workflow-values.ts +159 -0
- package/src/workflow.ts +387 -0
package/src/workflow.ts
ADDED
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Hexabot — Fair Core License (FCL-1.0-ALv2)
|
|
3
|
+
* Copyright (c) 2025 Hexastack.
|
|
4
|
+
* Full terms: see LICENSE.md.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { stringify as stringifyYaml } from 'yaml';
|
|
8
|
+
|
|
9
|
+
import type { BaseWorkflowContext, WorkflowSnapshot } from './context';
|
|
10
|
+
import {
|
|
11
|
+
TASK_KIND,
|
|
12
|
+
WorkflowDefinition,
|
|
13
|
+
WorkflowDefinitionSchema,
|
|
14
|
+
validateWorkflow,
|
|
15
|
+
type FlowStep,
|
|
16
|
+
} from './dsl.types';
|
|
17
|
+
import { safeRenameTaskInDefinition as safeRenameTaskInDefinitionHelper } from './utils/workflow-definition';
|
|
18
|
+
import {
|
|
19
|
+
compileWorkflow,
|
|
20
|
+
type WorkflowCompileOptions,
|
|
21
|
+
} from './workflow-compiler';
|
|
22
|
+
import { WorkflowRunner } from './workflow-runner';
|
|
23
|
+
import type {
|
|
24
|
+
CompiledWorkflow,
|
|
25
|
+
ExecutionState,
|
|
26
|
+
PersistedSuspension,
|
|
27
|
+
WorkflowRunOptions,
|
|
28
|
+
} from './workflow-types';
|
|
29
|
+
|
|
30
|
+
export { compileWorkflow } from './workflow-compiler';
|
|
31
|
+
|
|
32
|
+
export { WorkflowEventEmitter } from './workflow-event-emitter';
|
|
33
|
+
|
|
34
|
+
export { WorkflowRunner } from './workflow-runner';
|
|
35
|
+
|
|
36
|
+
export type {
|
|
37
|
+
WorkflowResumeResult,
|
|
38
|
+
WorkflowRunOptions,
|
|
39
|
+
WorkflowStartResult,
|
|
40
|
+
} from './workflow-types';
|
|
41
|
+
|
|
42
|
+
export type { WorkflowCompileOptions } from './workflow-compiler';
|
|
43
|
+
|
|
44
|
+
export type FlowStepPath = Array<string | number>;
|
|
45
|
+
|
|
46
|
+
class WorkflowRunSuspendedError extends Error {
|
|
47
|
+
public readonly stepId: string;
|
|
48
|
+
|
|
49
|
+
public readonly reason?: string;
|
|
50
|
+
|
|
51
|
+
public readonly data?: unknown;
|
|
52
|
+
|
|
53
|
+
constructor(stepId: string, options?: { reason?: string; data?: unknown }) {
|
|
54
|
+
super(
|
|
55
|
+
`Workflow run suspended at step ${stepId}${options?.reason ? `: ${options.reason}` : ''}`,
|
|
56
|
+
);
|
|
57
|
+
this.name = 'WorkflowRunSuspendedError';
|
|
58
|
+
this.stepId = stepId;
|
|
59
|
+
this.reason = options?.reason;
|
|
60
|
+
this.data = options?.data;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const getTaskNameFromStep = (step: unknown): string | null => {
|
|
65
|
+
if (!step || typeof step !== 'object') {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const taskName = (step as { do?: unknown }).do;
|
|
70
|
+
|
|
71
|
+
return typeof taskName === 'string' ? taskName : null;
|
|
72
|
+
};
|
|
73
|
+
const hasTaskReference = (steps: FlowStep[], taskName: string): boolean => {
|
|
74
|
+
return steps.some((step) => {
|
|
75
|
+
if ('do' in step) {
|
|
76
|
+
return step.do === taskName;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if ('parallel' in step) {
|
|
80
|
+
return hasTaskReference(step.parallel.steps, taskName);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if ('conditional' in step) {
|
|
84
|
+
return step.conditional.when.some((branch) =>
|
|
85
|
+
hasTaskReference(branch.steps, taskName),
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if ('loop' in step) {
|
|
90
|
+
return hasTaskReference(step.loop.steps, taskName);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return false;
|
|
94
|
+
});
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Entry point for preparing and executing workflows from YAML or object definitions.
|
|
99
|
+
* Instances are thin wrappers around a compiled workflow graph.
|
|
100
|
+
*/
|
|
101
|
+
export class Workflow {
|
|
102
|
+
private readonly compiled: CompiledWorkflow;
|
|
103
|
+
|
|
104
|
+
private constructor(compiled: CompiledWorkflow) {
|
|
105
|
+
this.compiled = compiled;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Create a workflow from an already parsed definition.
|
|
110
|
+
* The definition is validated before compilation to catch schema issues early.
|
|
111
|
+
*/
|
|
112
|
+
static fromDefinition(
|
|
113
|
+
definition: WorkflowDefinition,
|
|
114
|
+
options: WorkflowCompileOptions,
|
|
115
|
+
): Workflow {
|
|
116
|
+
const validation = validateWorkflow(definition, {
|
|
117
|
+
bindingKinds: options.bindingKinds,
|
|
118
|
+
actions: options.actions,
|
|
119
|
+
});
|
|
120
|
+
if (!validation.success) {
|
|
121
|
+
throw new Error(
|
|
122
|
+
`Workflow validation failed: ${validation.errors.join('; ')}`,
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const compiled = compileWorkflow(validation.data, options);
|
|
127
|
+
|
|
128
|
+
return new Workflow(compiled);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Create a workflow from YAML source.
|
|
133
|
+
* YAML is validated and compiled before being wrapped in a {@link Workflow} instance.
|
|
134
|
+
*/
|
|
135
|
+
static fromYaml(yaml: string, options: WorkflowCompileOptions): Workflow {
|
|
136
|
+
const validation = validateWorkflow(yaml, {
|
|
137
|
+
bindingKinds: options.bindingKinds,
|
|
138
|
+
actions: options.actions,
|
|
139
|
+
});
|
|
140
|
+
if (!validation.success) {
|
|
141
|
+
throw new Error(
|
|
142
|
+
`Workflow validation failed: ${validation.errors.join('; ')}`,
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const compiled = compileWorkflow(validation.data, options);
|
|
147
|
+
|
|
148
|
+
return new Workflow(compiled);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Convert a workflow definition to YAML.
|
|
153
|
+
* The definition is validated before serialization.
|
|
154
|
+
*/
|
|
155
|
+
static stringifyDefinition(definition: WorkflowDefinition): string {
|
|
156
|
+
const parsed = WorkflowDefinitionSchema.parse(definition);
|
|
157
|
+
|
|
158
|
+
return stringifyYaml(parsed);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Resolve a nested value from a workflow definition by path.
|
|
163
|
+
*/
|
|
164
|
+
static getValueAtPath(value: unknown, path: FlowStepPath): unknown {
|
|
165
|
+
return path.reduce<unknown>((acc, key) => {
|
|
166
|
+
if (acc === null || acc === undefined) {
|
|
167
|
+
return undefined;
|
|
168
|
+
}
|
|
169
|
+
if (Array.isArray(acc)) {
|
|
170
|
+
return typeof key === 'number' ? acc[key] : undefined;
|
|
171
|
+
}
|
|
172
|
+
if (typeof acc === 'object') {
|
|
173
|
+
return (acc as Record<string, unknown>)[String(key)];
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
return undefined;
|
|
177
|
+
}, value);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Create a new value with a nested path updated immutably.
|
|
182
|
+
*/
|
|
183
|
+
static setValueAtPath<T>(
|
|
184
|
+
value: T,
|
|
185
|
+
path: FlowStepPath,
|
|
186
|
+
nextValue: unknown,
|
|
187
|
+
): T {
|
|
188
|
+
if (path.length === 0) {
|
|
189
|
+
return nextValue as T;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const [key, ...rest] = path;
|
|
193
|
+
|
|
194
|
+
if (Array.isArray(value)) {
|
|
195
|
+
if (typeof key !== 'number') {
|
|
196
|
+
return value;
|
|
197
|
+
}
|
|
198
|
+
const nextArray = [...value];
|
|
199
|
+
|
|
200
|
+
nextArray[key] = Workflow.setValueAtPath(value[key], rest, nextValue);
|
|
201
|
+
|
|
202
|
+
return nextArray as unknown as T;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
if (value && typeof value === 'object') {
|
|
206
|
+
return {
|
|
207
|
+
...(value as Record<string, unknown>),
|
|
208
|
+
[String(key)]: Workflow.setValueAtPath(
|
|
209
|
+
(value as Record<string, unknown>)[String(key)],
|
|
210
|
+
rest,
|
|
211
|
+
nextValue,
|
|
212
|
+
),
|
|
213
|
+
} as T;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
return value;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Remove a flow step from the definition at the given path, if valid.
|
|
221
|
+
*/
|
|
222
|
+
static removeStepAtPath(
|
|
223
|
+
definition: WorkflowDefinition,
|
|
224
|
+
stepPath: FlowStepPath,
|
|
225
|
+
): WorkflowDefinition | null {
|
|
226
|
+
if (!stepPath.length) {
|
|
227
|
+
return null;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
const removeIndex = stepPath[stepPath.length - 1];
|
|
231
|
+
|
|
232
|
+
if (typeof removeIndex !== 'number') {
|
|
233
|
+
return null;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
const stepsPath = stepPath.slice(0, -1);
|
|
237
|
+
const steps = Workflow.getValueAtPath(definition, stepsPath);
|
|
238
|
+
|
|
239
|
+
if (!Array.isArray(steps)) {
|
|
240
|
+
return null;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
if (removeIndex < 0 || removeIndex >= steps.length) {
|
|
244
|
+
return null;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
const removedTaskName = getTaskNameFromStep(steps[removeIndex]);
|
|
248
|
+
const nextSteps = [...steps];
|
|
249
|
+
|
|
250
|
+
nextSteps.splice(removeIndex, 1);
|
|
251
|
+
|
|
252
|
+
const nextDefinition = Workflow.setValueAtPath(
|
|
253
|
+
definition,
|
|
254
|
+
stepsPath,
|
|
255
|
+
nextSteps,
|
|
256
|
+
);
|
|
257
|
+
|
|
258
|
+
if (
|
|
259
|
+
!removedTaskName ||
|
|
260
|
+
!Object.prototype.hasOwnProperty.call(
|
|
261
|
+
nextDefinition.defs,
|
|
262
|
+
removedTaskName,
|
|
263
|
+
)
|
|
264
|
+
) {
|
|
265
|
+
return nextDefinition;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
if (nextDefinition.defs[removedTaskName]?.kind !== TASK_KIND) {
|
|
269
|
+
return nextDefinition;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
if (hasTaskReference(nextDefinition.flow, removedTaskName)) {
|
|
273
|
+
return nextDefinition;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
const { [removedTaskName]: _removedTask, ...remainingDefs } =
|
|
277
|
+
nextDefinition.defs;
|
|
278
|
+
|
|
279
|
+
return {
|
|
280
|
+
...nextDefinition,
|
|
281
|
+
defs: remainingDefs,
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Insert a flow step into the definition at the given path, if valid.
|
|
287
|
+
*/
|
|
288
|
+
static insertStepAtPath(
|
|
289
|
+
definition: WorkflowDefinition,
|
|
290
|
+
insertPath: FlowStepPath,
|
|
291
|
+
step: FlowStep,
|
|
292
|
+
): WorkflowDefinition | null {
|
|
293
|
+
if (!insertPath.length) {
|
|
294
|
+
return null;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
const insertIndex = insertPath[insertPath.length - 1];
|
|
298
|
+
|
|
299
|
+
if (typeof insertIndex !== 'number') {
|
|
300
|
+
return null;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
const stepsPath = insertPath.slice(0, -1);
|
|
304
|
+
const steps = Workflow.getValueAtPath(definition, stepsPath);
|
|
305
|
+
|
|
306
|
+
if (!Array.isArray(steps)) {
|
|
307
|
+
return null;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
const nextSteps = [...steps];
|
|
311
|
+
const safeIndex = Math.min(Math.max(insertIndex, 0), nextSteps.length);
|
|
312
|
+
|
|
313
|
+
nextSteps.splice(safeIndex, 0, step);
|
|
314
|
+
|
|
315
|
+
return Workflow.setValueAtPath(definition, stepsPath, nextSteps);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Rename a task key and update references in flow steps and output expressions.
|
|
320
|
+
*/
|
|
321
|
+
static safeRenameTaskInDefinition(
|
|
322
|
+
definition: WorkflowDefinition,
|
|
323
|
+
currentTaskName: string,
|
|
324
|
+
nextTaskName: string,
|
|
325
|
+
): WorkflowDefinition {
|
|
326
|
+
return safeRenameTaskInDefinitionHelper(
|
|
327
|
+
definition,
|
|
328
|
+
currentTaskName,
|
|
329
|
+
nextTaskName,
|
|
330
|
+
);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* Run the workflow until completion or suspension.
|
|
335
|
+
* Throws when a task suspends so callers can capture the state.
|
|
336
|
+
*/
|
|
337
|
+
async run(
|
|
338
|
+
inputData: unknown,
|
|
339
|
+
context: BaseWorkflowContext,
|
|
340
|
+
options?: WorkflowRunOptions,
|
|
341
|
+
): Promise<Record<string, unknown>> {
|
|
342
|
+
const runner = new WorkflowRunner(this.compiled, options);
|
|
343
|
+
const result = await runner.start({
|
|
344
|
+
inputData,
|
|
345
|
+
context,
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
if (result.status === 'finished') {
|
|
349
|
+
return result.output;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
if (result.status === 'failed') {
|
|
353
|
+
throw result.error instanceof Error
|
|
354
|
+
? result.error
|
|
355
|
+
: new Error(String(result.error));
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
context.attachWorkflowRuntime(undefined);
|
|
359
|
+
throw new WorkflowRunSuspendedError(result.step.id, {
|
|
360
|
+
reason: result.reason,
|
|
361
|
+
data: result.data,
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* Construct a runner without executing, allowing hosts to manage start/resume manually.
|
|
367
|
+
*/
|
|
368
|
+
async buildAsyncRunner(
|
|
369
|
+
options?: WorkflowRunOptions,
|
|
370
|
+
): Promise<WorkflowRunner> {
|
|
371
|
+
return new WorkflowRunner(this.compiled, options);
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* Rebuild a runner from persisted state and snapshot, useful after restarts.
|
|
376
|
+
*/
|
|
377
|
+
async buildRunnerFromState(options: {
|
|
378
|
+
state: ExecutionState;
|
|
379
|
+
context: BaseWorkflowContext;
|
|
380
|
+
snapshot: WorkflowSnapshot;
|
|
381
|
+
suspension?: PersistedSuspension;
|
|
382
|
+
runId?: string;
|
|
383
|
+
lastResumeData?: unknown;
|
|
384
|
+
}): Promise<WorkflowRunner> {
|
|
385
|
+
return WorkflowRunner.fromPersistedState(this.compiled, options);
|
|
386
|
+
}
|
|
387
|
+
}
|