@gobing-ai/ts-dual-workflow-engine 0.2.8 → 0.2.9

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.
@@ -54,6 +54,7 @@ export class StateMachineDriver {
54
54
  vars,
55
55
  env,
56
56
  options,
57
+ transitionsTaken,
57
58
  );
58
59
  if (lastActionResult?.ok === false)
59
60
  return await this.fail(
@@ -103,6 +104,7 @@ export class StateMachineDriver {
103
104
  vars,
104
105
  env,
105
106
  options,
107
+ transitionsTaken,
106
108
  );
107
109
  if (exitResult?.ok === false)
108
110
  return await this.fail(runId, workflow.name, mode, current.id, transitionsTaken, exitResult.error);
@@ -139,13 +141,14 @@ export class StateMachineDriver {
139
141
  vars: Record<string, string>,
140
142
  env: Record<string, string>,
141
143
  options: WorkflowRunOptions,
144
+ transitionsTaken: number,
142
145
  ): Promise<ActionResult | undefined> {
143
146
  let last: ActionResult | undefined;
144
147
  for (const action of actions) {
145
148
  const resolved = resolveTemplates(action.options ?? {}, {
146
149
  vars,
147
150
  env,
148
- builtins: { workflow: workflowName, state: stateId, runId },
151
+ builtins: runtimeBuiltins(workflowName, stateId, runId, transitionsTaken),
149
152
  });
150
153
  last = await this.options.host.runAction(action.kind, resolved, {
151
154
  runId,
@@ -186,6 +189,25 @@ export class StateMachineDriver {
186
189
  }
187
190
  }
188
191
 
192
+ /** Built-in bare template values available to state-machine action options. */
193
+ function runtimeBuiltins(
194
+ workflowName: string,
195
+ stateId: string,
196
+ runId: string,
197
+ transitionsTaken: number,
198
+ ): Record<string, string | number> {
199
+ return {
200
+ workflow: workflowName,
201
+ runId,
202
+ task: workflowName,
203
+ state: stateId,
204
+ node: stateId,
205
+ iteration: transitionsTaken,
206
+ run: runId,
207
+ runtime: 'state-machine',
208
+ };
209
+ }
210
+
189
211
  async function firstPassingTransition(
190
212
  transitions: StateMachineWorkflowDef['transitions'],
191
213
  host: WorkflowEngineHost,
@@ -1,4 +1,5 @@
1
1
  import { getProcessEnv } from '@gobing-ai/ts-runtime';
2
+ import { FSMError } from './errors';
2
3
  import type { WorkflowEngineHost } from './host';
3
4
  import type {
4
5
  ActionResult,
@@ -37,7 +38,7 @@ export class TransitionFlowDriver {
37
38
  const iterationBound = workflow.iterationBound ?? 50;
38
39
 
39
40
  if (current === undefined) {
40
- throw new Error(`Initial node "${workflow.initialNode}" is not declared`);
41
+ throw new FSMError(`Initial node "${workflow.initialNode}" is not declared`);
41
42
  }
42
43
 
43
44
  while (true) {
@@ -50,7 +51,7 @@ export class TransitionFlowDriver {
50
51
  const resolved = resolveTemplates(current.action.options ?? {}, {
51
52
  vars,
52
53
  env,
53
- builtins: { workflow: workflow.name, node: current.id, runId },
54
+ builtins: runtimeBuiltins(workflow.name, current.id, runId, transitionsTaken),
54
55
  });
55
56
  lastActionResult = await this.options.host.runAction(current.action.kind, resolved, {
56
57
  runId,
@@ -110,7 +111,7 @@ export class TransitionFlowDriver {
110
111
 
111
112
  // 7. Move to the target node and repeat.
112
113
  const nextNode = nodes.get(edge.to);
113
- if (nextNode === undefined) throw new Error(`Edge target "${edge.to}" is not declared`);
114
+ if (nextNode === undefined) throw new FSMError(`Edge target "${edge.to}" is not declared`);
114
115
  current = nextNode;
115
116
  }
116
117
  }
@@ -141,6 +142,25 @@ export class TransitionFlowDriver {
141
142
  }
142
143
  }
143
144
 
145
+ /** Built-in bare template values available to transition-flow action options. */
146
+ function runtimeBuiltins(
147
+ workflowName: string,
148
+ nodeId: string,
149
+ runId: string,
150
+ transitionsTaken: number,
151
+ ): Record<string, string | number> {
152
+ return {
153
+ workflow: workflowName,
154
+ runId,
155
+ task: workflowName,
156
+ state: nodeId,
157
+ node: nodeId,
158
+ iteration: transitionsTaken,
159
+ run: runId,
160
+ runtime: 'transition-flow',
161
+ };
162
+ }
163
+
144
164
  async function firstPassingEdge(
145
165
  edges: TransitionFlowWorkflowDef['edges'],
146
166
  host: WorkflowEngineHost,
package/src/types.ts CHANGED
@@ -24,6 +24,8 @@ export interface GuardDef {
24
24
  /** One state in a state-machine workflow. */
25
25
  export interface StateDef {
26
26
  readonly id: string;
27
+ /** Optional human description of what this state does. */
28
+ readonly description?: string;
27
29
  readonly onEnter?: readonly ActionDef[];
28
30
  readonly onExit?: readonly ActionDef[];
29
31
  }
@@ -32,6 +34,8 @@ export interface StateDef {
32
34
  export interface TransitionDef {
33
35
  readonly from: string;
34
36
  readonly to: string;
37
+ /** Optional human description of when/why this transition is taken. */
38
+ readonly description?: string;
35
39
  readonly trigger?: string;
36
40
  readonly guard?: GuardDef;
37
41
  }
@@ -40,6 +44,10 @@ export interface TransitionDef {
40
44
  export interface StateMachineWorkflowDef {
41
45
  readonly kind?: 'state-machine';
42
46
  readonly name: string;
47
+ /** Optional behavior-free document version tag. */
48
+ readonly version?: string;
49
+ /** Optional human description of the workflow's purpose. */
50
+ readonly description?: string;
43
51
  readonly initialState: string;
44
52
  readonly terminalStates?: readonly string[];
45
53
  readonly iterationBound?: number;
@@ -52,6 +60,8 @@ export interface StateMachineWorkflowDef {
52
60
  /** Transition-flow node definition. */
53
61
  export interface FlowNodeDef {
54
62
  readonly id: string;
63
+ /** Optional human description of what this node does. */
64
+ readonly description?: string;
55
65
  readonly type?: 'action' | 'gate' | 'parallel' | 'decision';
56
66
  readonly action?: ActionDef;
57
67
  }
@@ -60,6 +70,8 @@ export interface FlowNodeDef {
60
70
  export interface FlowEdgeDef {
61
71
  readonly from: string;
62
72
  readonly to: string;
73
+ /** Optional human description of when/why this edge is taken. */
74
+ readonly description?: string;
63
75
  readonly condition?: GuardDef;
64
76
  }
65
77
 
@@ -67,6 +79,10 @@ export interface FlowEdgeDef {
67
79
  export interface TransitionFlowWorkflowDef {
68
80
  readonly kind: 'transition-flow';
69
81
  readonly name: string;
82
+ /** Optional behavior-free document version tag. */
83
+ readonly version?: string;
84
+ /** Optional human description of the workflow's purpose. */
85
+ readonly description?: string;
70
86
  readonly initialNode: string;
71
87
  readonly terminalNodes?: readonly string[];
72
88
  readonly iterationBound?: number;