@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.
@@ -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', { runId: env.runId, step: stepInfo });
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', { runId: env.runId, step: stepInfo });
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
- env.recordStepExecution(stepInfo, {
152
+ const normalizedError = normalizeError(error);
153
+ const stepExecution = env.recordStepExecution(stepInfo, {
144
154
  status: 'failed',
145
155
  endedAt: Date.now(),
146
- error: normalizeError(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', { runId: env.runId, step: stepInfo, 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
- this.stepLog[step.id] = {
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', { runId: env.runId, step: stepInfo });
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', { runId: env.runId, step: stepInfo });
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
- env.recordStepExecution(stepInfo, {
149
+ const normalizedError = normalizeError(error);
150
+ const stepExecution = env.recordStepExecution(stepInfo, {
141
151
  status: 'failed',
142
152
  endedAt: Date.now(),
143
- error: normalizeError(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', { runId: env.runId, step: stepInfo, 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
- this.stepLog[step.id] = {
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,CAiE5B"}
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>) => void;
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,IAAI,CAAC;IACV,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
+ {"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
- runId?: string;
32
- step: StepInfo;
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;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,QAAQ,CAAA;KAAE,CAAC;IACtD,mBAAmB,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,QAAQ,CAAA;KAAE,CAAC;IACxD,iBAAiB,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,QAAQ,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC;IACtE,qBAAqB,EAAE;QACrB,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,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
+ {"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;IA2B3B;;;;;OAKG;IACH,OAAO,CAAC,iBAAiB;IAqDzB;;;;OAIG;IACH,OAAO,CAAC,6BAA6B;IAkBrC;;;;;;;;OAQG;YACW,WAAW;IAsBzB;;;;;;;OAOG;YACW,WAAW;IAkBzB;;;;;;OAMG;YACW,iBAAiB;CAOhC"}
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hexabot-ai/agentic",
3
- "version": "3.1.2-alpha.15",
3
+ "version": "3.1.2-alpha.17",
4
4
  "description": "Schemas and utilities for the Hexabot agentic workflow DSL.",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",
@@ -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
- compiled,
77
- context: new TestContext(),
78
- runId: 'run-123',
79
- buildInstanceStepInfo: jest.fn().mockReturnValue(stepInfo),
80
- markSnapshot: jest.fn(),
81
- recordStepExecution: jest.fn(),
82
- emit: jest.fn(),
83
- setCurrentStep: jest.fn(),
84
- waitForStepSuspension: jest
85
- .fn()
86
- .mockImplementation(
87
- () => new Promise<RuntimeSuspensionRequest>(() => undefined),
88
- ),
89
- clearStepSuspensions: jest.fn(),
90
- primeStepResumeData: jest.fn(),
91
- captureTaskOutput: jest.fn().mockResolvedValue(undefined),
92
- executeFlow: jest.fn(),
93
- executeStep: jest.fn(),
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', { runId: env.runId, step: stepInfo });
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', { runId: env.runId, step: stepInfo });
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
- env.recordStepExecution(stepInfo, {
243
+ const normalizedError = normalizeError(error);
244
+ const stepExecution = env.recordStepExecution(stepInfo, {
235
245
  status: 'failed',
236
246
  endedAt: Date.now(),
237
- error: normalizeError(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', { runId: env.runId, step: stepInfo, 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
@@ -39,7 +39,7 @@ export type StepExecutorEnv = {
39
39
  recordStepExecution: (
40
40
  step: StepInfo,
41
41
  update: Partial<StepExecutionRecord>,
42
- ) => void;
42
+ ) => StepExecutionRecord;
43
43
  emit: <K extends keyof WorkflowEventMap>(
44
44
  event: K,
45
45
  payload: WorkflowEventMap[K],
@@ -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': { runId?: string; step: StepInfo };
31
- 'hook:step:success': { runId?: string; step: StepInfo };
32
- 'hook:step:error': { runId?: string; step: StepInfo; error: unknown };
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
  };
@@ -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
  /**