@hexabot-ai/agentic 3.1.2-alpha.15 → 3.1.2-alpha.17
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/dist/cjs/step-executors/task-executor.js +23 -8
- package/dist/cjs/workflow-runner.js +7 -1
- package/dist/esm/step-executors/task-executor.js +23 -8
- package/dist/esm/workflow-runner.js +7 -1
- package/dist/types/step-executors/task-executor.d.ts.map +1 -1
- package/dist/types/step-executors/types.d.ts +1 -1
- package/dist/types/step-executors/types.d.ts.map +1 -1
- package/dist/types/workflow-event-emitter.d.ts +10 -14
- package/dist/types/workflow-event-emitter.d.ts.map +1 -1
- package/dist/types/workflow-runner.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/step-executors/task-executor.test.ts +79 -21
- package/src/step-executors/task-executor.ts +23 -8
- package/src/step-executors/types.ts +1 -1
- package/src/workflow-event-emitter.ts +12 -6
- package/src/workflow-runner.ts +10 -3
|
@@ -31,7 +31,7 @@ async function executeTaskStep(env, step, state, _path) {
|
|
|
31
31
|
accumulator: state.accumulator,
|
|
32
32
|
};
|
|
33
33
|
const inputs = await (0, workflow_values_1.evaluateMapping)(task.inputs, scope);
|
|
34
|
-
env.recordStepExecution(stepInfo, {
|
|
34
|
+
const stepExecution = env.recordStepExecution(stepInfo, {
|
|
35
35
|
action: task.actionName,
|
|
36
36
|
status: 'running',
|
|
37
37
|
startedAt: Date.now(),
|
|
@@ -41,7 +41,11 @@ async function executeTaskStep(env, step, state, _path) {
|
|
|
41
41
|
env.beginStepExecution?.(stepInfo.id);
|
|
42
42
|
env.setCurrentStep(stepInfo);
|
|
43
43
|
env.markSnapshot(stepInfo, 'running');
|
|
44
|
-
env.emit('hook:step:start', {
|
|
44
|
+
env.emit('hook:step:start', {
|
|
45
|
+
runId: env.runId,
|
|
46
|
+
step: stepInfo,
|
|
47
|
+
stepExecution,
|
|
48
|
+
});
|
|
45
49
|
try {
|
|
46
50
|
const actionPromise = Promise.resolve().then(() => task.action.run(inputs, env.context, task.settings, task.bindings));
|
|
47
51
|
const outcome = await waitForTaskProgress(env, stepInfo.id, actionPromise);
|
|
@@ -69,18 +73,22 @@ const waitForTaskProgress = async (env, stepId, actionPromise) => {
|
|
|
69
73
|
};
|
|
70
74
|
const completeTask = async (env, stepId, stepInfo, task, state, result) => {
|
|
71
75
|
await env.captureTaskOutput(task, state, result);
|
|
72
|
-
env.recordStepExecution(stepInfo, {
|
|
76
|
+
const stepExecution = env.recordStepExecution(stepInfo, {
|
|
73
77
|
status: 'completed',
|
|
74
78
|
endedAt: Date.now(),
|
|
75
79
|
output: result,
|
|
76
80
|
context: { after: env.context.snapshot() },
|
|
77
81
|
});
|
|
78
82
|
env.markSnapshot(stepInfo, 'completed');
|
|
79
|
-
env.emit('hook:step:success', {
|
|
83
|
+
env.emit('hook:step:success', {
|
|
84
|
+
runId: env.runId,
|
|
85
|
+
step: stepInfo,
|
|
86
|
+
stepExecution,
|
|
87
|
+
});
|
|
80
88
|
env.clearStepSuspensions(stepId);
|
|
81
89
|
};
|
|
82
90
|
const recordSuspension = (env, stepInfo, reason, data) => {
|
|
83
|
-
env.recordStepExecution(stepInfo, {
|
|
91
|
+
const stepExecution = env.recordStepExecution(stepInfo, {
|
|
84
92
|
status: 'suspended',
|
|
85
93
|
endedAt: Date.now(),
|
|
86
94
|
reason,
|
|
@@ -90,6 +98,7 @@ const recordSuspension = (env, stepInfo, reason, data) => {
|
|
|
90
98
|
env.emit('hook:step:suspended', {
|
|
91
99
|
runId: env.runId,
|
|
92
100
|
step: stepInfo,
|
|
101
|
+
stepExecution,
|
|
93
102
|
reason,
|
|
94
103
|
data,
|
|
95
104
|
});
|
|
@@ -140,14 +149,20 @@ const buildSuspensionContinuation = (env, stepId, stepInfo, task, state, actionP
|
|
|
140
149
|
};
|
|
141
150
|
};
|
|
142
151
|
const recordTaskFailure = (env, stepInfo, error) => {
|
|
143
|
-
|
|
152
|
+
const normalizedError = normalizeError(error);
|
|
153
|
+
const stepExecution = env.recordStepExecution(stepInfo, {
|
|
144
154
|
status: 'failed',
|
|
145
155
|
endedAt: Date.now(),
|
|
146
|
-
error:
|
|
156
|
+
error: normalizedError,
|
|
147
157
|
context: { after: env.context.snapshot() },
|
|
148
158
|
});
|
|
149
159
|
env.markSnapshot(stepInfo, 'failed', normalizeErrorMessage(error));
|
|
150
|
-
env.emit('hook:step:error', {
|
|
160
|
+
env.emit('hook:step:error', {
|
|
161
|
+
runId: env.runId,
|
|
162
|
+
step: stepInfo,
|
|
163
|
+
stepExecution,
|
|
164
|
+
error,
|
|
165
|
+
});
|
|
151
166
|
};
|
|
152
167
|
const normalizeError = (error) => error instanceof Error
|
|
153
168
|
? { message: error.message, stack: error.stack }
|
|
@@ -316,7 +316,7 @@ class WorkflowRunner {
|
|
|
316
316
|
const mergedContext = existing?.context || update.context
|
|
317
317
|
? { ...existing?.context, ...update.context }
|
|
318
318
|
: undefined;
|
|
319
|
-
|
|
319
|
+
const nextRecord = {
|
|
320
320
|
...base,
|
|
321
321
|
...update,
|
|
322
322
|
id: step.id,
|
|
@@ -324,6 +324,12 @@ class WorkflowRunner {
|
|
|
324
324
|
status: update.status ?? base.status,
|
|
325
325
|
context: mergedContext,
|
|
326
326
|
};
|
|
327
|
+
this.stepLog[step.id] = nextRecord;
|
|
328
|
+
return {
|
|
329
|
+
...nextRecord,
|
|
330
|
+
context: nextRecord.context ? { ...nextRecord.context } : undefined,
|
|
331
|
+
error: nextRecord.error ? { ...nextRecord.error } : undefined,
|
|
332
|
+
};
|
|
327
333
|
}
|
|
328
334
|
/**
|
|
329
335
|
* Construct the environment object passed to step executors.
|
|
@@ -28,7 +28,7 @@ export async function executeTaskStep(env, step, state, _path) {
|
|
|
28
28
|
accumulator: state.accumulator,
|
|
29
29
|
};
|
|
30
30
|
const inputs = await evaluateMapping(task.inputs, scope);
|
|
31
|
-
env.recordStepExecution(stepInfo, {
|
|
31
|
+
const stepExecution = env.recordStepExecution(stepInfo, {
|
|
32
32
|
action: task.actionName,
|
|
33
33
|
status: 'running',
|
|
34
34
|
startedAt: Date.now(),
|
|
@@ -38,7 +38,11 @@ export async function executeTaskStep(env, step, state, _path) {
|
|
|
38
38
|
env.beginStepExecution?.(stepInfo.id);
|
|
39
39
|
env.setCurrentStep(stepInfo);
|
|
40
40
|
env.markSnapshot(stepInfo, 'running');
|
|
41
|
-
env.emit('hook:step:start', {
|
|
41
|
+
env.emit('hook:step:start', {
|
|
42
|
+
runId: env.runId,
|
|
43
|
+
step: stepInfo,
|
|
44
|
+
stepExecution,
|
|
45
|
+
});
|
|
42
46
|
try {
|
|
43
47
|
const actionPromise = Promise.resolve().then(() => task.action.run(inputs, env.context, task.settings, task.bindings));
|
|
44
48
|
const outcome = await waitForTaskProgress(env, stepInfo.id, actionPromise);
|
|
@@ -66,18 +70,22 @@ const waitForTaskProgress = async (env, stepId, actionPromise) => {
|
|
|
66
70
|
};
|
|
67
71
|
const completeTask = async (env, stepId, stepInfo, task, state, result) => {
|
|
68
72
|
await env.captureTaskOutput(task, state, result);
|
|
69
|
-
env.recordStepExecution(stepInfo, {
|
|
73
|
+
const stepExecution = env.recordStepExecution(stepInfo, {
|
|
70
74
|
status: 'completed',
|
|
71
75
|
endedAt: Date.now(),
|
|
72
76
|
output: result,
|
|
73
77
|
context: { after: env.context.snapshot() },
|
|
74
78
|
});
|
|
75
79
|
env.markSnapshot(stepInfo, 'completed');
|
|
76
|
-
env.emit('hook:step:success', {
|
|
80
|
+
env.emit('hook:step:success', {
|
|
81
|
+
runId: env.runId,
|
|
82
|
+
step: stepInfo,
|
|
83
|
+
stepExecution,
|
|
84
|
+
});
|
|
77
85
|
env.clearStepSuspensions(stepId);
|
|
78
86
|
};
|
|
79
87
|
const recordSuspension = (env, stepInfo, reason, data) => {
|
|
80
|
-
env.recordStepExecution(stepInfo, {
|
|
88
|
+
const stepExecution = env.recordStepExecution(stepInfo, {
|
|
81
89
|
status: 'suspended',
|
|
82
90
|
endedAt: Date.now(),
|
|
83
91
|
reason,
|
|
@@ -87,6 +95,7 @@ const recordSuspension = (env, stepInfo, reason, data) => {
|
|
|
87
95
|
env.emit('hook:step:suspended', {
|
|
88
96
|
runId: env.runId,
|
|
89
97
|
step: stepInfo,
|
|
98
|
+
stepExecution,
|
|
90
99
|
reason,
|
|
91
100
|
data,
|
|
92
101
|
});
|
|
@@ -137,14 +146,20 @@ const buildSuspensionContinuation = (env, stepId, stepInfo, task, state, actionP
|
|
|
137
146
|
};
|
|
138
147
|
};
|
|
139
148
|
const recordTaskFailure = (env, stepInfo, error) => {
|
|
140
|
-
|
|
149
|
+
const normalizedError = normalizeError(error);
|
|
150
|
+
const stepExecution = env.recordStepExecution(stepInfo, {
|
|
141
151
|
status: 'failed',
|
|
142
152
|
endedAt: Date.now(),
|
|
143
|
-
error:
|
|
153
|
+
error: normalizedError,
|
|
144
154
|
context: { after: env.context.snapshot() },
|
|
145
155
|
});
|
|
146
156
|
env.markSnapshot(stepInfo, 'failed', normalizeErrorMessage(error));
|
|
147
|
-
env.emit('hook:step:error', {
|
|
157
|
+
env.emit('hook:step:error', {
|
|
158
|
+
runId: env.runId,
|
|
159
|
+
step: stepInfo,
|
|
160
|
+
stepExecution,
|
|
161
|
+
error,
|
|
162
|
+
});
|
|
148
163
|
};
|
|
149
164
|
const normalizeError = (error) => error instanceof Error
|
|
150
165
|
? { message: error.message, stack: error.stack }
|
|
@@ -313,7 +313,7 @@ export class WorkflowRunner {
|
|
|
313
313
|
const mergedContext = existing?.context || update.context
|
|
314
314
|
? { ...existing?.context, ...update.context }
|
|
315
315
|
: undefined;
|
|
316
|
-
|
|
316
|
+
const nextRecord = {
|
|
317
317
|
...base,
|
|
318
318
|
...update,
|
|
319
319
|
id: step.id,
|
|
@@ -321,6 +321,12 @@ export class WorkflowRunner {
|
|
|
321
321
|
status: update.status ?? base.status,
|
|
322
322
|
context: mergedContext,
|
|
323
323
|
};
|
|
324
|
+
this.stepLog[step.id] = nextRecord;
|
|
325
|
+
return {
|
|
326
|
+
...nextRecord,
|
|
327
|
+
context: nextRecord.context ? { ...nextRecord.context } : undefined,
|
|
328
|
+
error: nextRecord.error ? { ...nextRecord.error } : undefined,
|
|
329
|
+
};
|
|
324
330
|
}
|
|
325
331
|
/**
|
|
326
332
|
* Construct the environment object passed to step executors.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task-executor.d.ts","sourceRoot":"","sources":["../../../src/step-executors/task-executor.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAGV,cAAc,EACd,UAAU,EACV,QAAQ,EACT,MAAM,mBAAmB,CAAC;AAG3B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAO/C;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CACnC,GAAG,EAAE,eAAe,EACpB,IAAI,EAAE,QAAQ,EACd,KAAK,EAAE,cAAc,EACrB,KAAK,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,GAC5B,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"task-executor.d.ts","sourceRoot":"","sources":["../../../src/step-executors/task-executor.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAGV,cAAc,EACd,UAAU,EACV,QAAQ,EACT,MAAM,mBAAmB,CAAC;AAG3B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAO/C;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CACnC,GAAG,EAAE,eAAe,EACpB,IAAI,EAAE,QAAQ,EACd,KAAK,EAAE,cAAc,EACrB,KAAK,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,GAC5B,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAqE5B"}
|
|
@@ -8,7 +8,7 @@ export type StepExecutorEnv = {
|
|
|
8
8
|
runId?: string;
|
|
9
9
|
buildInstanceStepInfo: (step: CompiledStep, iterationStack: number[]) => StepInfo;
|
|
10
10
|
markSnapshot: (step: StepInfo, status: ActionSnapshot['status'], reason?: string) => void;
|
|
11
|
-
recordStepExecution: (step: StepInfo, update: Partial<StepExecutionRecord>) =>
|
|
11
|
+
recordStepExecution: (step: StepInfo, update: Partial<StepExecutionRecord>) => StepExecutionRecord;
|
|
12
12
|
emit: <K extends keyof WorkflowEventMap>(event: K, payload: WorkflowEventMap[K]) => void;
|
|
13
13
|
setCurrentStep: (step?: StepInfo) => void;
|
|
14
14
|
beginStepExecution?: (stepId: string) => string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/step-executors/types.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,cAAc,EACd,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EACV,yBAAyB,EACzB,qBAAqB,EACrB,wBAAwB,EACzB,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC5E,OAAO,KAAK,EACV,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAChB,cAAc,EACd,UAAU,EACX,MAAM,mBAAmB,CAAC;AAE3B,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,OAAO,EAAE,mBAAmB,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qBAAqB,EAAE,CACrB,IAAI,EAAE,YAAY,EAClB,cAAc,EAAE,MAAM,EAAE,KACrB,QAAQ,CAAC;IACd,YAAY,EAAE,CACZ,IAAI,EAAE,QAAQ,EACd,MAAM,EAAE,cAAc,CAAC,QAAQ,CAAC,EAChC,MAAM,CAAC,EAAE,MAAM,KACZ,IAAI,CAAC;IACV,mBAAmB,EAAE,CACnB,IAAI,EAAE,QAAQ,EACd,MAAM,EAAE,OAAO,CAAC,mBAAmB,CAAC,KACjC,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/step-executors/types.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,cAAc,EACd,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EACV,yBAAyB,EACzB,qBAAqB,EACrB,wBAAwB,EACzB,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC5E,OAAO,KAAK,EACV,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAChB,cAAc,EACd,UAAU,EACX,MAAM,mBAAmB,CAAC;AAE3B,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,OAAO,EAAE,mBAAmB,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qBAAqB,EAAE,CACrB,IAAI,EAAE,YAAY,EAClB,cAAc,EAAE,MAAM,EAAE,KACrB,QAAQ,CAAC;IACd,YAAY,EAAE,CACZ,IAAI,EAAE,QAAQ,EACd,MAAM,EAAE,cAAc,CAAC,QAAQ,CAAC,EAChC,MAAM,CAAC,EAAE,MAAM,KACZ,IAAI,CAAC;IACV,mBAAmB,EAAE,CACnB,IAAI,EAAE,QAAQ,EACd,MAAM,EAAE,OAAO,CAAC,mBAAmB,CAAC,KACjC,mBAAmB,CAAC;IACzB,IAAI,EAAE,CAAC,CAAC,SAAS,MAAM,gBAAgB,EACrC,KAAK,EAAE,CAAC,EACR,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAC,KACzB,IAAI,CAAC;IACV,cAAc,EAAE,CAAC,IAAI,CAAC,EAAE,QAAQ,KAAK,IAAI,CAAC;IAC1C,kBAAkB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC;IAChD,qBAAqB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,wBAAwB,CAAC,CAAC;IAC7E,oBAAoB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IAChE,mBAAmB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,KAAK,IAAI,CAAC;IACnE,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,qBAAqB,KAAK,IAAI,CAAC;IAC1D,uBAAuB,CAAC,EAAE,CAAC,MAAM,EAAE,yBAAyB,KAAK,IAAI,CAAC;IACtE,iBAAiB,EAAE,CACjB,IAAI,EAAE,YAAY,EAClB,KAAK,EAAE,cAAc,EACrB,MAAM,EAAE,OAAO,KACZ,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,WAAW,EAAE,CACX,KAAK,EAAE,YAAY,EAAE,EACrB,KAAK,EAAE,cAAc,EACrB,IAAI,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,EAC5B,UAAU,CAAC,EAAE,MAAM,KAChB,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IAChC,WAAW,EAAE,CACX,IAAI,EAAE,YAAY,EAClB,KAAK,EAAE,cAAc,EACrB,IAAI,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,KACzB,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;CACjC,CAAC"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { StepExecutionRecord } from './context';
|
|
1
2
|
export declare enum StepType {
|
|
2
3
|
Task = "task",
|
|
3
4
|
Parallel = "parallel",
|
|
@@ -9,6 +10,11 @@ export type StepInfo = {
|
|
|
9
10
|
name: string;
|
|
10
11
|
type: StepType;
|
|
11
12
|
};
|
|
13
|
+
export type StepWorkflowEventPayload = {
|
|
14
|
+
runId?: string;
|
|
15
|
+
step: StepInfo;
|
|
16
|
+
stepExecution?: StepExecutionRecord;
|
|
17
|
+
};
|
|
12
18
|
export type WorkflowEventMap = {
|
|
13
19
|
'hook:workflow:start': {
|
|
14
20
|
runId?: string;
|
|
@@ -27,22 +33,12 @@ export type WorkflowEventMap = {
|
|
|
27
33
|
reason?: string;
|
|
28
34
|
data?: unknown;
|
|
29
35
|
};
|
|
30
|
-
'hook:step:start':
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
};
|
|
34
|
-
'hook:step:success': {
|
|
35
|
-
runId?: string;
|
|
36
|
-
step: StepInfo;
|
|
37
|
-
};
|
|
38
|
-
'hook:step:error': {
|
|
39
|
-
runId?: string;
|
|
40
|
-
step: StepInfo;
|
|
36
|
+
'hook:step:start': StepWorkflowEventPayload;
|
|
37
|
+
'hook:step:success': StepWorkflowEventPayload;
|
|
38
|
+
'hook:step:error': StepWorkflowEventPayload & {
|
|
41
39
|
error: unknown;
|
|
42
40
|
};
|
|
43
|
-
'hook:step:suspended': {
|
|
44
|
-
runId?: string;
|
|
45
|
-
step: StepInfo;
|
|
41
|
+
'hook:step:suspended': StepWorkflowEventPayload & {
|
|
46
42
|
reason?: string;
|
|
47
43
|
data?: unknown;
|
|
48
44
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workflow-event-emitter.d.ts","sourceRoot":"","sources":["../../src/workflow-event-emitter.ts"],"names":[],"mappings":"AAMA,oBAAY,QAAQ;IAClB,IAAI,SAAS;IACb,QAAQ,aAAa;IACrB,WAAW,gBAAgB;IAC3B,IAAI,SAAS;CACd;AAED,MAAM,MAAM,QAAQ,GAAG;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,qBAAqB,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1C,sBAAsB,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC;IAC5E,uBAAuB,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC;IAC5D,yBAAyB,EAAE;QACzB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,IAAI,EAAE,QAAQ,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,OAAO,CAAC;KAChB,CAAC;IACF,iBAAiB,EAAE
|
|
1
|
+
{"version":3,"file":"workflow-event-emitter.d.ts","sourceRoot":"","sources":["../../src/workflow-event-emitter.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAErD,oBAAY,QAAQ;IAClB,IAAI,SAAS;IACb,QAAQ,aAAa;IACrB,WAAW,gBAAgB;IAC3B,IAAI,SAAS;CACd;AAED,MAAM,MAAM,QAAQ,GAAG;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,QAAQ,CAAC;IACf,aAAa,CAAC,EAAE,mBAAmB,CAAC;CACrC,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,qBAAqB,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1C,sBAAsB,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC;IAC5E,uBAAuB,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC;IAC5D,yBAAyB,EAAE;QACzB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,IAAI,EAAE,QAAQ,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,OAAO,CAAC;KAChB,CAAC;IACF,iBAAiB,EAAE,wBAAwB,CAAC;IAC5C,mBAAmB,EAAE,wBAAwB,CAAC;IAC9C,iBAAiB,EAAE,wBAAwB,GAAG;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC;IACjE,qBAAqB,EAAE,wBAAwB,GAAG;QAChD,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,OAAO,CAAC;KAChB,CAAC;IACF,mBAAmB,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,QAAQ,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC1E,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC;IACtD,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,GAAG,OAAO,CAAC;CACzE,CAAC;AAEF,MAAM,MAAM,wBAAwB,CAAC,CAAC,GAAG,OAAO,IAAI,CAAC,GAAG,gBAAgB,CAAC;AAKzE;;;;GAIG;AACH,qBAAa,oBACX,YAAW,wBAAwB,CAAC,oBAAoB,CAAC;IAEzD,OAAO,CAAC,SAAS,CAAyC;IAE1D,IAAI,CAAC,CAAC,SAAS,MAAM,gBAAgB,EACnC,KAAK,EAAE,CAAC,EACR,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAC3B,OAAO;IAWV,EAAE,CAAC,CAAC,SAAS,MAAM,gBAAgB,EACjC,KAAK,EAAE,CAAC,EACR,QAAQ,EAAE,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAC,KAAK,IAAI,GAC/C,IAAI;CAOR"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workflow-runner.d.ts","sourceRoot":"","sources":["../../src/workflow-runner.ts"],"names":[],"mappings":"AAMA,OAAO,EAIL,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACtB,MAAM,WAAW,CAAC;AAYnB,OAAO,EAEL,KAAK,QAAQ,EAEd,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAGV,gBAAgB,EAChB,cAAc,EACd,mBAAmB,EACnB,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,WAAW,EAEX,kBAAkB,EACnB,MAAM,kBAAkB,CAAC;AAG1B;;;GAGG;AACH,qBAAa,cAAc;IAEzB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAmB;IAG5C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAS;IAGhC,OAAO,CAAC,MAAM,CAA8C;IAG5D,OAAO,CAAC,SAAS,CAAsC;IAGvD,OAAO,CAAC,OAAO,CAA2C;IAG1D,OAAO,CAAC,UAAU,CAAC,CAAa;IAGhC,OAAO,CAAC,cAAc,CAAC,CAAuB;IAG9C,OAAO,CAAC,WAAW,CAAC,CAAW;IAG/B,OAAO,CAAC,cAAc,CAAC,CAAU;IAGjC,OAAO,CAAC,KAAK,CAAC,CAAiB;IAG/B,OAAO,CAAC,OAAO,CAAC,CAAsB;IAEtC;;;;;OAKG;gBACS,QAAQ,EAAE,gBAAgB,EAAE,OAAO,CAAC,EAAE,kBAAkB;IAKpE;;;;OAIG;IACH,QAAQ,IAAI,cAAc,GAAG,SAAS;IAItC;;;;OAIG;IACH,SAAS,IAAI,iBAAiB;IAI9B;;;;OAIG;IACH,WAAW,IAAI,gBAAgB;IAO/B;;;;OAIG;IACH,UAAU,IAAI,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC;IAajD;;;;OAIG;IACH,cAAc,IAAI,QAAQ,GAAG,SAAS;IAItC;;;;OAIG;IACH,iBAAiB,IAAI,OAAO;IAI5B;;;;;;OAMG;IACG,KAAK,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,WAAW,CAAC;IA6BxD;;;;;OAKG;IACG,MAAM,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC;IAiB3D;;;;;OAKG;YACW,YAAY;IA0D1B;;;;;;OAMG;WACU,kBAAkB,CAC7B,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,EAAE;QACP,KAAK,EAAE,cAAc,CAAC;QACtB,OAAO,EAAE,mBAAmB,CAAC;QAC7B,QAAQ,EAAE,gBAAgB,CAAC;QAC3B,UAAU,CAAC,EAAE,mBAAmB,CAAC;QACjC,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,cAAc,CAAC,EAAE,OAAO,CAAC;KAC1B,GACA,OAAO,CAAC,cAAc,CAAC;IAgD1B;;;;;OAKG;IACH,OAAO,CAAC,IAAI;IAOZ;;;;;;OAMG;YACW,uBAAuB;IAYrC;;;;;;OAMG;IACH,OAAO,CAAC,qBAAqB;IAc7B;;;;;;OAMG;IACH,OAAO,CAAC,YAAY;IASpB;;;;;OAKG;IACH,OAAO,CAAC,mBAAmB;
|
|
1
|
+
{"version":3,"file":"workflow-runner.d.ts","sourceRoot":"","sources":["../../src/workflow-runner.ts"],"names":[],"mappings":"AAMA,OAAO,EAIL,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACtB,MAAM,WAAW,CAAC;AAYnB,OAAO,EAEL,KAAK,QAAQ,EAEd,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAGV,gBAAgB,EAChB,cAAc,EACd,mBAAmB,EACnB,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,WAAW,EAEX,kBAAkB,EACnB,MAAM,kBAAkB,CAAC;AAG1B;;;GAGG;AACH,qBAAa,cAAc;IAEzB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAmB;IAG5C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAS;IAGhC,OAAO,CAAC,MAAM,CAA8C;IAG5D,OAAO,CAAC,SAAS,CAAsC;IAGvD,OAAO,CAAC,OAAO,CAA2C;IAG1D,OAAO,CAAC,UAAU,CAAC,CAAa;IAGhC,OAAO,CAAC,cAAc,CAAC,CAAuB;IAG9C,OAAO,CAAC,WAAW,CAAC,CAAW;IAG/B,OAAO,CAAC,cAAc,CAAC,CAAU;IAGjC,OAAO,CAAC,KAAK,CAAC,CAAiB;IAG/B,OAAO,CAAC,OAAO,CAAC,CAAsB;IAEtC;;;;;OAKG;gBACS,QAAQ,EAAE,gBAAgB,EAAE,OAAO,CAAC,EAAE,kBAAkB;IAKpE;;;;OAIG;IACH,QAAQ,IAAI,cAAc,GAAG,SAAS;IAItC;;;;OAIG;IACH,SAAS,IAAI,iBAAiB;IAI9B;;;;OAIG;IACH,WAAW,IAAI,gBAAgB;IAO/B;;;;OAIG;IACH,UAAU,IAAI,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC;IAajD;;;;OAIG;IACH,cAAc,IAAI,QAAQ,GAAG,SAAS;IAItC;;;;OAIG;IACH,iBAAiB,IAAI,OAAO;IAI5B;;;;;;OAMG;IACG,KAAK,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,WAAW,CAAC;IA6BxD;;;;;OAKG;IACG,MAAM,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC;IAiB3D;;;;;OAKG;YACW,YAAY;IA0D1B;;;;;;OAMG;WACU,kBAAkB,CAC7B,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,EAAE;QACP,KAAK,EAAE,cAAc,CAAC;QACtB,OAAO,EAAE,mBAAmB,CAAC;QAC7B,QAAQ,EAAE,gBAAgB,CAAC;QAC3B,UAAU,CAAC,EAAE,mBAAmB,CAAC;QACjC,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,cAAc,CAAC,EAAE,OAAO,CAAC;KAC1B,GACA,OAAO,CAAC,cAAc,CAAC;IAgD1B;;;;;OAKG;IACH,OAAO,CAAC,IAAI;IAOZ;;;;;;OAMG;YACW,uBAAuB;IAYrC;;;;;;OAMG;IACH,OAAO,CAAC,qBAAqB;IAc7B;;;;;;OAMG;IACH,OAAO,CAAC,YAAY;IASpB;;;;;OAKG;IACH,OAAO,CAAC,mBAAmB;IAkC3B;;;;;OAKG;IACH,OAAO,CAAC,iBAAiB;IAqDzB;;;;OAIG;IACH,OAAO,CAAC,6BAA6B;IAkBrC;;;;;;;;OAQG;YACW,WAAW;IAsBzB;;;;;;;OAOG;YACW,WAAW;IAkBzB;;;;;;OAMG;YACW,iBAAiB;CAOhC"}
|
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import type { Action } from '../action/action.types';
|
|
8
|
-
import { BaseWorkflowContext } from '../context';
|
|
8
|
+
import { BaseWorkflowContext, type StepExecutionRecord } from '../context';
|
|
9
9
|
import type { RuntimeSuspensionRequest } from '../runner-runtime-control';
|
|
10
10
|
import { createDeferred } from '../utils/deferred';
|
|
11
11
|
import {
|
|
@@ -72,26 +72,54 @@ const createCompiled = (task: CompiledTask): CompiledWorkflow =>
|
|
|
72
72
|
const createEnv = (
|
|
73
73
|
compiled: CompiledWorkflow,
|
|
74
74
|
stepInfo: StepInfo,
|
|
75
|
-
): StepExecutorEnv =>
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
}
|
|
75
|
+
): StepExecutorEnv => {
|
|
76
|
+
const stepRecords: Record<string, StepExecutionRecord> = {};
|
|
77
|
+
|
|
78
|
+
return {
|
|
79
|
+
compiled,
|
|
80
|
+
context: new TestContext(),
|
|
81
|
+
runId: 'run-123',
|
|
82
|
+
buildInstanceStepInfo: jest.fn().mockReturnValue(stepInfo),
|
|
83
|
+
markSnapshot: jest.fn(),
|
|
84
|
+
recordStepExecution: jest.fn((step, update) => {
|
|
85
|
+
const existing =
|
|
86
|
+
stepRecords[step.id] ??
|
|
87
|
+
({
|
|
88
|
+
id: step.id,
|
|
89
|
+
name: step.name,
|
|
90
|
+
status: 'pending',
|
|
91
|
+
} satisfies StepExecutionRecord);
|
|
92
|
+
const context =
|
|
93
|
+
existing.context || update.context
|
|
94
|
+
? { ...existing.context, ...update.context }
|
|
95
|
+
: undefined;
|
|
96
|
+
const nextRecord = {
|
|
97
|
+
...existing,
|
|
98
|
+
...update,
|
|
99
|
+
id: step.id,
|
|
100
|
+
name: step.name,
|
|
101
|
+
status: update.status ?? existing.status,
|
|
102
|
+
context,
|
|
103
|
+
} satisfies StepExecutionRecord;
|
|
104
|
+
|
|
105
|
+
stepRecords[step.id] = nextRecord;
|
|
106
|
+
|
|
107
|
+
return nextRecord;
|
|
108
|
+
}),
|
|
109
|
+
emit: jest.fn(),
|
|
110
|
+
setCurrentStep: jest.fn(),
|
|
111
|
+
waitForStepSuspension: jest
|
|
112
|
+
.fn()
|
|
113
|
+
.mockImplementation(
|
|
114
|
+
() => new Promise<RuntimeSuspensionRequest>(() => undefined),
|
|
115
|
+
),
|
|
116
|
+
clearStepSuspensions: jest.fn(),
|
|
117
|
+
primeStepResumeData: jest.fn(),
|
|
118
|
+
captureTaskOutput: jest.fn().mockResolvedValue(undefined),
|
|
119
|
+
executeFlow: jest.fn(),
|
|
120
|
+
executeStep: jest.fn(),
|
|
121
|
+
};
|
|
122
|
+
};
|
|
95
123
|
const step: TaskStep = {
|
|
96
124
|
id: '0:test_task',
|
|
97
125
|
type: StepType.Task,
|
|
@@ -153,10 +181,18 @@ describe('executeTaskStep', () => {
|
|
|
153
181
|
expect(env.emit).toHaveBeenCalledWith('hook:step:start', {
|
|
154
182
|
runId: 'run-123',
|
|
155
183
|
step: stepInfo,
|
|
184
|
+
stepExecution: expect.objectContaining({
|
|
185
|
+
id: stepInfo.id,
|
|
186
|
+
status: 'running',
|
|
187
|
+
}),
|
|
156
188
|
});
|
|
157
189
|
expect(env.emit).toHaveBeenCalledWith('hook:step:success', {
|
|
158
190
|
runId: 'run-123',
|
|
159
191
|
step: stepInfo,
|
|
192
|
+
stepExecution: expect.objectContaining({
|
|
193
|
+
id: stepInfo.id,
|
|
194
|
+
status: 'completed',
|
|
195
|
+
}),
|
|
160
196
|
});
|
|
161
197
|
expect(env.setCurrentStep).toHaveBeenLastCalledWith(undefined);
|
|
162
198
|
});
|
|
@@ -215,6 +251,16 @@ describe('executeTaskStep', () => {
|
|
|
215
251
|
'suspended',
|
|
216
252
|
'awaiting_user',
|
|
217
253
|
);
|
|
254
|
+
expect(env.emit).toHaveBeenCalledWith('hook:step:suspended', {
|
|
255
|
+
runId: 'run-123',
|
|
256
|
+
step: stepInfo,
|
|
257
|
+
stepExecution: expect.objectContaining({
|
|
258
|
+
id: stepInfo.id,
|
|
259
|
+
status: 'suspended',
|
|
260
|
+
}),
|
|
261
|
+
reason: 'awaiting_user',
|
|
262
|
+
data: { channel: 'sms' },
|
|
263
|
+
});
|
|
218
264
|
|
|
219
265
|
await suspension?.continue({ reply: 'Sure' });
|
|
220
266
|
|
|
@@ -228,6 +274,14 @@ describe('executeTaskStep', () => {
|
|
|
228
274
|
output: { reply: 'SURE' },
|
|
229
275
|
}),
|
|
230
276
|
);
|
|
277
|
+
expect(env.emit).toHaveBeenCalledWith('hook:step:success', {
|
|
278
|
+
runId: 'run-123',
|
|
279
|
+
step: stepInfo,
|
|
280
|
+
stepExecution: expect.objectContaining({
|
|
281
|
+
id: stepInfo.id,
|
|
282
|
+
status: 'completed',
|
|
283
|
+
}),
|
|
284
|
+
});
|
|
231
285
|
});
|
|
232
286
|
|
|
233
287
|
it('marks failure and rethrows errors from the task', async () => {
|
|
@@ -250,6 +304,10 @@ describe('executeTaskStep', () => {
|
|
|
250
304
|
expect(env.emit).toHaveBeenCalledWith('hook:step:error', {
|
|
251
305
|
runId: 'run-123',
|
|
252
306
|
step: stepInfo,
|
|
307
|
+
stepExecution: expect.objectContaining({
|
|
308
|
+
id: stepInfo.id,
|
|
309
|
+
status: 'failed',
|
|
310
|
+
}),
|
|
253
311
|
error: expect.any(Error),
|
|
254
312
|
});
|
|
255
313
|
expect(env.setCurrentStep).toHaveBeenLastCalledWith(undefined);
|
|
@@ -51,7 +51,7 @@ export async function executeTaskStep(
|
|
|
51
51
|
accumulator: state.accumulator,
|
|
52
52
|
};
|
|
53
53
|
const inputs = await evaluateMapping(task.inputs, scope);
|
|
54
|
-
env.recordStepExecution(stepInfo, {
|
|
54
|
+
const stepExecution = env.recordStepExecution(stepInfo, {
|
|
55
55
|
action: task.actionName,
|
|
56
56
|
status: 'running',
|
|
57
57
|
startedAt: Date.now(),
|
|
@@ -61,7 +61,11 @@ export async function executeTaskStep(
|
|
|
61
61
|
env.beginStepExecution?.(stepInfo.id);
|
|
62
62
|
env.setCurrentStep(stepInfo);
|
|
63
63
|
env.markSnapshot(stepInfo, 'running');
|
|
64
|
-
env.emit('hook:step:start', {
|
|
64
|
+
env.emit('hook:step:start', {
|
|
65
|
+
runId: env.runId,
|
|
66
|
+
step: stepInfo,
|
|
67
|
+
stepExecution,
|
|
68
|
+
});
|
|
65
69
|
|
|
66
70
|
try {
|
|
67
71
|
const actionPromise = Promise.resolve().then(() =>
|
|
@@ -126,14 +130,18 @@ const completeTask = async (
|
|
|
126
130
|
result: unknown,
|
|
127
131
|
) => {
|
|
128
132
|
await env.captureTaskOutput(task, state, result);
|
|
129
|
-
env.recordStepExecution(stepInfo, {
|
|
133
|
+
const stepExecution = env.recordStepExecution(stepInfo, {
|
|
130
134
|
status: 'completed',
|
|
131
135
|
endedAt: Date.now(),
|
|
132
136
|
output: result,
|
|
133
137
|
context: { after: env.context.snapshot() },
|
|
134
138
|
});
|
|
135
139
|
env.markSnapshot(stepInfo, 'completed');
|
|
136
|
-
env.emit('hook:step:success', {
|
|
140
|
+
env.emit('hook:step:success', {
|
|
141
|
+
runId: env.runId,
|
|
142
|
+
step: stepInfo,
|
|
143
|
+
stepExecution,
|
|
144
|
+
});
|
|
137
145
|
env.clearStepSuspensions(stepId);
|
|
138
146
|
};
|
|
139
147
|
const recordSuspension = (
|
|
@@ -142,7 +150,7 @@ const recordSuspension = (
|
|
|
142
150
|
reason?: string,
|
|
143
151
|
data?: unknown,
|
|
144
152
|
) => {
|
|
145
|
-
env.recordStepExecution(stepInfo, {
|
|
153
|
+
const stepExecution = env.recordStepExecution(stepInfo, {
|
|
146
154
|
status: 'suspended',
|
|
147
155
|
endedAt: Date.now(),
|
|
148
156
|
reason,
|
|
@@ -152,6 +160,7 @@ const recordSuspension = (
|
|
|
152
160
|
env.emit('hook:step:suspended', {
|
|
153
161
|
runId: env.runId,
|
|
154
162
|
step: stepInfo,
|
|
163
|
+
stepExecution,
|
|
155
164
|
reason,
|
|
156
165
|
data,
|
|
157
166
|
});
|
|
@@ -231,14 +240,20 @@ const recordTaskFailure = (
|
|
|
231
240
|
stepInfo: Suspension['step'],
|
|
232
241
|
error: unknown,
|
|
233
242
|
) => {
|
|
234
|
-
|
|
243
|
+
const normalizedError = normalizeError(error);
|
|
244
|
+
const stepExecution = env.recordStepExecution(stepInfo, {
|
|
235
245
|
status: 'failed',
|
|
236
246
|
endedAt: Date.now(),
|
|
237
|
-
error:
|
|
247
|
+
error: normalizedError,
|
|
238
248
|
context: { after: env.context.snapshot() },
|
|
239
249
|
});
|
|
240
250
|
env.markSnapshot(stepInfo, 'failed', normalizeErrorMessage(error));
|
|
241
|
-
env.emit('hook:step:error', {
|
|
251
|
+
env.emit('hook:step:error', {
|
|
252
|
+
runId: env.runId,
|
|
253
|
+
step: stepInfo,
|
|
254
|
+
stepExecution,
|
|
255
|
+
error,
|
|
256
|
+
});
|
|
242
257
|
};
|
|
243
258
|
const normalizeError = (error: unknown): { message: string; stack?: string } =>
|
|
244
259
|
error instanceof Error
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
* Full terms: see LICENSE.md.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
import type { StepExecutionRecord } from './context';
|
|
8
|
+
|
|
7
9
|
export enum StepType {
|
|
8
10
|
Task = 'task',
|
|
9
11
|
Parallel = 'parallel',
|
|
@@ -17,6 +19,12 @@ export type StepInfo = {
|
|
|
17
19
|
type: StepType;
|
|
18
20
|
};
|
|
19
21
|
|
|
22
|
+
export type StepWorkflowEventPayload = {
|
|
23
|
+
runId?: string;
|
|
24
|
+
step: StepInfo;
|
|
25
|
+
stepExecution?: StepExecutionRecord;
|
|
26
|
+
};
|
|
27
|
+
|
|
20
28
|
export type WorkflowEventMap = {
|
|
21
29
|
'hook:workflow:start': { runId?: string };
|
|
22
30
|
'hook:workflow:finish': { runId?: string; output: Record<string, unknown> };
|
|
@@ -27,12 +35,10 @@ export type WorkflowEventMap = {
|
|
|
27
35
|
reason?: string;
|
|
28
36
|
data?: unknown;
|
|
29
37
|
};
|
|
30
|
-
'hook:step:start':
|
|
31
|
-
'hook:step:success':
|
|
32
|
-
'hook:step:error':
|
|
33
|
-
'hook:step:suspended': {
|
|
34
|
-
runId?: string;
|
|
35
|
-
step: StepInfo;
|
|
38
|
+
'hook:step:start': StepWorkflowEventPayload;
|
|
39
|
+
'hook:step:success': StepWorkflowEventPayload;
|
|
40
|
+
'hook:step:error': StepWorkflowEventPayload & { error: unknown };
|
|
41
|
+
'hook:step:suspended': StepWorkflowEventPayload & {
|
|
36
42
|
reason?: string;
|
|
37
43
|
data?: unknown;
|
|
38
44
|
};
|
package/src/workflow-runner.ts
CHANGED
|
@@ -425,7 +425,7 @@ export class WorkflowRunner {
|
|
|
425
425
|
private recordStepExecution(
|
|
426
426
|
step: StepInfo,
|
|
427
427
|
update: Partial<StepExecutionRecord>,
|
|
428
|
-
) {
|
|
428
|
+
): StepExecutionRecord {
|
|
429
429
|
const existing = this.stepLog[step.id];
|
|
430
430
|
const base: StepExecutionRecord =
|
|
431
431
|
existing ??
|
|
@@ -438,8 +438,7 @@ export class WorkflowRunner {
|
|
|
438
438
|
existing?.context || update.context
|
|
439
439
|
? { ...existing?.context, ...update.context }
|
|
440
440
|
: undefined;
|
|
441
|
-
|
|
442
|
-
this.stepLog[step.id] = {
|
|
441
|
+
const nextRecord: StepExecutionRecord = {
|
|
443
442
|
...base,
|
|
444
443
|
...update,
|
|
445
444
|
id: step.id,
|
|
@@ -447,6 +446,14 @@ export class WorkflowRunner {
|
|
|
447
446
|
status: update.status ?? base.status,
|
|
448
447
|
context: mergedContext,
|
|
449
448
|
};
|
|
449
|
+
|
|
450
|
+
this.stepLog[step.id] = nextRecord;
|
|
451
|
+
|
|
452
|
+
return {
|
|
453
|
+
...nextRecord,
|
|
454
|
+
context: nextRecord.context ? { ...nextRecord.context } : undefined,
|
|
455
|
+
error: nextRecord.error ? { ...nextRecord.error } : undefined,
|
|
456
|
+
};
|
|
450
457
|
}
|
|
451
458
|
|
|
452
459
|
/**
|