@gobing-ai/ts-dual-workflow-engine 0.3.0 → 0.3.2
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/README.md +506 -5
- package/dist/config.d.ts +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +7 -11
- package/dist/events.d.ts +49 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +0 -0
- package/dist/extensions.d.ts +60 -0
- package/dist/extensions.d.ts.map +1 -0
- package/dist/extensions.js +85 -0
- package/dist/host.d.ts +15 -2
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +42 -17
- package/dist/index.d.ts +5 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/run-lifecycle.d.ts +58 -0
- package/dist/run-lifecycle.d.ts.map +1 -0
- package/dist/run-lifecycle.js +149 -0
- package/dist/schema-sql.d.ts +1 -0
- package/dist/schema-sql.d.ts.map +1 -1
- package/dist/schema-sql.js +1 -0
- package/dist/schema.d.ts +44 -0
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +3 -0
- package/dist/state-machine.d.ts +7 -2
- package/dist/state-machine.d.ts.map +1 -1
- package/dist/state-machine.js +63 -72
- package/dist/transition-flow.d.ts +1 -2
- package/dist/transition-flow.d.ts.map +1 -1
- package/dist/transition-flow.js +35 -61
- package/dist/types.d.ts +14 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/variables.d.ts +6 -1
- package/dist/variables.d.ts.map +1 -1
- package/dist/variables.js +7 -0
- package/package.json +4 -4
- package/src/config.ts +8 -11
- package/src/events.ts +19 -0
- package/src/extensions.ts +163 -0
- package/src/host.ts +54 -20
- package/src/index.ts +24 -1
- package/src/run-lifecycle.ts +211 -0
- package/src/schema-sql.ts +1 -0
- package/src/schema.ts +3 -0
- package/src/state-machine.ts +78 -128
- package/src/transition-flow.ts +47 -105
- package/src/types.ts +16 -0
- package/src/variables.ts +13 -1
package/dist/schema.d.ts
CHANGED
|
@@ -3,6 +3,10 @@ import { z } from 'zod';
|
|
|
3
3
|
export declare const ActionDefSchema: z.ZodObject<{
|
|
4
4
|
kind: z.ZodString;
|
|
5
5
|
options: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
6
|
+
onError: z.ZodOptional<z.ZodEnum<{
|
|
7
|
+
fail: "fail";
|
|
8
|
+
continue: "continue";
|
|
9
|
+
}>>;
|
|
6
10
|
}, z.core.$strip>;
|
|
7
11
|
/** Zod schema for workflow guard definitions. */
|
|
8
12
|
export declare const GuardDefSchema: z.ZodObject<{
|
|
@@ -19,6 +23,10 @@ export declare const StateMachineWorkflowDefSchema: z.ZodObject<{
|
|
|
19
23
|
initialState: z.ZodString;
|
|
20
24
|
terminalStates: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
21
25
|
iterationBound: z.ZodOptional<z.ZodNumber>;
|
|
26
|
+
defaultOnError: z.ZodOptional<z.ZodEnum<{
|
|
27
|
+
fail: "fail";
|
|
28
|
+
continue: "continue";
|
|
29
|
+
}>>;
|
|
22
30
|
vars: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
23
31
|
env: z.ZodOptional<z.ZodObject<{
|
|
24
32
|
allow: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -29,10 +37,18 @@ export declare const StateMachineWorkflowDefSchema: z.ZodObject<{
|
|
|
29
37
|
onEnter: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
30
38
|
kind: z.ZodString;
|
|
31
39
|
options: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
40
|
+
onError: z.ZodOptional<z.ZodEnum<{
|
|
41
|
+
fail: "fail";
|
|
42
|
+
continue: "continue";
|
|
43
|
+
}>>;
|
|
32
44
|
}, z.core.$strip>>>;
|
|
33
45
|
onExit: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
34
46
|
kind: z.ZodString;
|
|
35
47
|
options: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
48
|
+
onError: z.ZodOptional<z.ZodEnum<{
|
|
49
|
+
fail: "fail";
|
|
50
|
+
continue: "continue";
|
|
51
|
+
}>>;
|
|
36
52
|
}, z.core.$strip>>>;
|
|
37
53
|
}, z.core.$strict>>;
|
|
38
54
|
transitions: z.ZodArray<z.ZodObject<{
|
|
@@ -56,6 +72,10 @@ export declare const TransitionFlowWorkflowDefSchema: z.ZodObject<{
|
|
|
56
72
|
initialNode: z.ZodString;
|
|
57
73
|
terminalNodes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
58
74
|
iterationBound: z.ZodOptional<z.ZodNumber>;
|
|
75
|
+
defaultOnError: z.ZodOptional<z.ZodEnum<{
|
|
76
|
+
fail: "fail";
|
|
77
|
+
continue: "continue";
|
|
78
|
+
}>>;
|
|
59
79
|
vars: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
60
80
|
env: z.ZodOptional<z.ZodObject<{
|
|
61
81
|
allow: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -72,6 +92,10 @@ export declare const TransitionFlowWorkflowDefSchema: z.ZodObject<{
|
|
|
72
92
|
action: z.ZodOptional<z.ZodObject<{
|
|
73
93
|
kind: z.ZodString;
|
|
74
94
|
options: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
95
|
+
onError: z.ZodOptional<z.ZodEnum<{
|
|
96
|
+
fail: "fail";
|
|
97
|
+
continue: "continue";
|
|
98
|
+
}>>;
|
|
75
99
|
}, z.core.$strip>>;
|
|
76
100
|
}, z.core.$strict>>;
|
|
77
101
|
edges: z.ZodArray<z.ZodObject<{
|
|
@@ -94,6 +118,10 @@ export declare const WorkflowDefSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
94
118
|
initialState: z.ZodString;
|
|
95
119
|
terminalStates: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
96
120
|
iterationBound: z.ZodOptional<z.ZodNumber>;
|
|
121
|
+
defaultOnError: z.ZodOptional<z.ZodEnum<{
|
|
122
|
+
fail: "fail";
|
|
123
|
+
continue: "continue";
|
|
124
|
+
}>>;
|
|
97
125
|
vars: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
98
126
|
env: z.ZodOptional<z.ZodObject<{
|
|
99
127
|
allow: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -104,10 +132,18 @@ export declare const WorkflowDefSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
104
132
|
onEnter: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
105
133
|
kind: z.ZodString;
|
|
106
134
|
options: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
135
|
+
onError: z.ZodOptional<z.ZodEnum<{
|
|
136
|
+
fail: "fail";
|
|
137
|
+
continue: "continue";
|
|
138
|
+
}>>;
|
|
107
139
|
}, z.core.$strip>>>;
|
|
108
140
|
onExit: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
109
141
|
kind: z.ZodString;
|
|
110
142
|
options: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
143
|
+
onError: z.ZodOptional<z.ZodEnum<{
|
|
144
|
+
fail: "fail";
|
|
145
|
+
continue: "continue";
|
|
146
|
+
}>>;
|
|
111
147
|
}, z.core.$strip>>>;
|
|
112
148
|
}, z.core.$strict>>;
|
|
113
149
|
transitions: z.ZodArray<z.ZodObject<{
|
|
@@ -129,6 +165,10 @@ export declare const WorkflowDefSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
129
165
|
initialNode: z.ZodString;
|
|
130
166
|
terminalNodes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
131
167
|
iterationBound: z.ZodOptional<z.ZodNumber>;
|
|
168
|
+
defaultOnError: z.ZodOptional<z.ZodEnum<{
|
|
169
|
+
fail: "fail";
|
|
170
|
+
continue: "continue";
|
|
171
|
+
}>>;
|
|
132
172
|
vars: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
133
173
|
env: z.ZodOptional<z.ZodObject<{
|
|
134
174
|
allow: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -145,6 +185,10 @@ export declare const WorkflowDefSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
145
185
|
action: z.ZodOptional<z.ZodObject<{
|
|
146
186
|
kind: z.ZodString;
|
|
147
187
|
options: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
188
|
+
onError: z.ZodOptional<z.ZodEnum<{
|
|
189
|
+
fail: "fail";
|
|
190
|
+
continue: "continue";
|
|
191
|
+
}>>;
|
|
148
192
|
}, z.core.$strip>>;
|
|
149
193
|
}, z.core.$strict>>;
|
|
150
194
|
edges: z.ZodArray<z.ZodObject<{
|
package/dist/schema.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAyBxB,kDAAkD;AAClD,eAAO,MAAM,eAAe
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAyBxB,kDAAkD;AAClD,eAAO,MAAM,eAAe;;;;;;;iBAI1B,CAAC;AAEH,iDAAiD;AACjD,eAAO,MAAM,cAAc;;;iBAGzB,CAAC;AAEH,yDAAyD;AACzD,eAAO,MAAM,6BAA6B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAoC7B,CAAC;AAEd,2DAA2D;AAC3D,eAAO,MAAM,+BAA+B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAmC/B,CAAC;AAEd,iEAAiE;AACjE,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oBAA4E,CAAC"}
|
package/dist/schema.js
CHANGED
|
@@ -22,6 +22,7 @@ const EnvSchema = z.object({
|
|
|
22
22
|
export const ActionDefSchema = z.object({
|
|
23
23
|
kind: z.string().min(1),
|
|
24
24
|
options: z.record(z.string(), z.unknown()).optional(),
|
|
25
|
+
onError: z.enum(['fail', 'continue']).optional(),
|
|
25
26
|
});
|
|
26
27
|
/** Zod schema for workflow guard definitions. */
|
|
27
28
|
export const GuardDefSchema = z.object({
|
|
@@ -40,6 +41,7 @@ export const StateMachineWorkflowDefSchema = z
|
|
|
40
41
|
initialState: z.string().min(1),
|
|
41
42
|
terminalStates: z.array(z.string().min(1)).optional(),
|
|
42
43
|
iterationBound: z.number().int().positive().optional(),
|
|
44
|
+
defaultOnError: z.enum(['fail', 'continue']).optional(),
|
|
43
45
|
vars: VarsSchema.optional(),
|
|
44
46
|
env: EnvSchema.optional(),
|
|
45
47
|
states: z.array(z
|
|
@@ -73,6 +75,7 @@ export const TransitionFlowWorkflowDefSchema = z
|
|
|
73
75
|
initialNode: z.string().min(1),
|
|
74
76
|
terminalNodes: z.array(z.string().min(1)).optional(),
|
|
75
77
|
iterationBound: z.number().int().positive().optional(),
|
|
78
|
+
defaultOnError: z.enum(['fail', 'continue']).optional(),
|
|
76
79
|
vars: VarsSchema.optional(),
|
|
77
80
|
env: EnvSchema.optional(),
|
|
78
81
|
nodes: z.array(z
|
package/dist/state-machine.d.ts
CHANGED
|
@@ -11,8 +11,13 @@ export declare class StateMachineDriver {
|
|
|
11
11
|
constructor(options: StateMachineDriverOptions);
|
|
12
12
|
/** Run a state-machine workflow to completion or failure. */
|
|
13
13
|
run(workflow: StateMachineWorkflowDef, options?: WorkflowRunOptions): Promise<WorkflowRunResult>;
|
|
14
|
+
private loop;
|
|
15
|
+
/**
|
|
16
|
+
* Run a state's actions in order. Returns the last action result (retained even
|
|
17
|
+
* when a failure was continued past, so downstream guards can inspect it) plus an
|
|
18
|
+
* `outcome` discriminator: `terminal` (an action declared terminal success),
|
|
19
|
+
* `fail` (a failure under a 'fail' policy — caller must halt), or `completed`.
|
|
20
|
+
*/
|
|
14
21
|
private runActions;
|
|
15
|
-
private done;
|
|
16
|
-
private fail;
|
|
17
22
|
}
|
|
18
23
|
//# sourceMappingURL=state-machine.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state-machine.d.ts","sourceRoot":"","sources":["../src/state-machine.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"state-machine.d.ts","sourceRoot":"","sources":["../src/state-machine.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AAEjD,OAAO,KAAK,EAIR,uBAAuB,EACvB,0BAA0B,EAC1B,kBAAkB,EAClB,iBAAiB,EACpB,MAAM,SAAS,CAAC;AAGjB,yDAAyD;AACzD,MAAM,WAAW,yBAAyB;IACtC,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAC;IAClC,QAAQ,CAAC,WAAW,EAAE,0BAA0B,CAAC;CACpD;AAED,wEAAwE;AACxE,qBAAa,kBAAkB;IACf,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,yBAAyB;IAE/D,6DAA6D;IACvD,GAAG,CAAC,QAAQ,EAAE,uBAAuB,EAAE,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,iBAAiB,CAAC;YAU5F,IAAI;IA6FlB;;;;;OAKG;YACW,UAAU;CA0C3B"}
|
package/dist/state-machine.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { getProcessEnv } from '@gobing-ai/ts-runtime';
|
|
2
1
|
import { FSMError } from './errors.js';
|
|
3
|
-
import {
|
|
2
|
+
import { allowedEnv, RunLifecycle, runtimeBuiltins } from './run-lifecycle.js';
|
|
3
|
+
import { mergeVars, resolveOnErrorPolicy, resolveTemplates } from './variables.js';
|
|
4
4
|
/** State-machine workflow driver with an R7 single control function. */
|
|
5
5
|
export class StateMachineDriver {
|
|
6
6
|
options;
|
|
@@ -9,36 +9,43 @@ export class StateMachineDriver {
|
|
|
9
9
|
}
|
|
10
10
|
/** Run a state-machine workflow to completion or failure. */
|
|
11
11
|
async run(workflow, options = {}) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
return await RunLifecycle.run(workflow.name, 'state-machine', { persistence: this.options.persistence, events: options.events }, options, (lifecycle) => this.loop(workflow, options, lifecycle));
|
|
13
|
+
}
|
|
14
|
+
async loop(workflow, options, lifecycle) {
|
|
15
|
+
const runId = lifecycle.runId;
|
|
16
16
|
const states = new Map(workflow.states.map((state) => [state.id, state]));
|
|
17
17
|
const terminal = new Set(workflow.terminalStates ?? []);
|
|
18
18
|
const vars = mergeVars(workflow.vars, options.vars);
|
|
19
|
-
const env = allowedEnv(workflow.env?.allow ?? [], options.env
|
|
19
|
+
const env = allowedEnv(workflow.env?.allow ?? [], options.env);
|
|
20
20
|
let current = states.get(workflow.initialState);
|
|
21
21
|
let transitionsTaken = 0;
|
|
22
22
|
let lastActionResult;
|
|
23
23
|
const iterationBound = workflow.iterationBound ?? 50;
|
|
24
|
+
const defaultOnError = workflow.defaultOnError;
|
|
24
25
|
if (current === undefined)
|
|
25
26
|
throw new FSMError(`Initial state "${workflow.initialState}" is not declared`);
|
|
26
27
|
while (true) {
|
|
27
28
|
// 1. Persist current state snapshot before work starts.
|
|
28
|
-
await
|
|
29
|
-
await this.options.persistence.savePhase(runId, current.id, 'running');
|
|
29
|
+
await lifecycle.enter(current.id, transitionsTaken);
|
|
30
30
|
// 2. Execute this state's on-enter actions in declaration order.
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
const enter = await this.runActions(current.onEnter ?? [], workflow.name, current.id, runId, vars, env, options, transitionsTaken, lifecycle, defaultOnError);
|
|
32
|
+
// Retain the last action result (including failures the policy continued
|
|
33
|
+
// past) so downstream guards can inspect it — matching the transition-flow
|
|
34
|
+
// driver's `continue` semantics. A state with no enter actions must not
|
|
35
|
+
// erase the previous result.
|
|
36
|
+
if (enter.result !== undefined)
|
|
37
|
+
lastActionResult = enter.result;
|
|
34
38
|
// 3. Stop immediately when an action explicitly declares terminal success.
|
|
35
|
-
if (
|
|
36
|
-
return await
|
|
39
|
+
if (enter.outcome === 'terminal') {
|
|
40
|
+
return await lifecycle.done(current.id, transitionsTaken);
|
|
41
|
+
}
|
|
42
|
+
// 4. Halt only when an action failed under a 'fail' policy.
|
|
43
|
+
if (enter.outcome === 'fail') {
|
|
44
|
+
return await lifecycle.fail(current.id, transitionsTaken, lastActionResult?.error);
|
|
37
45
|
}
|
|
38
|
-
// 4. Stop when the current state is terminal or has no outbound transitions.
|
|
39
46
|
const outbound = workflow.transitions.filter((transition) => transition.from === current?.id);
|
|
40
47
|
if (terminal.has(current.id) || outbound.length === 0) {
|
|
41
|
-
return await
|
|
48
|
+
return await lifecycle.done(current.id, transitionsTaken);
|
|
42
49
|
}
|
|
43
50
|
// 5. Evaluate transition guards in declaration order and pick the first passing transition.
|
|
44
51
|
const nextTransition = await firstPassingTransition(outbound, this.options.host, {
|
|
@@ -48,17 +55,19 @@ export class StateMachineDriver {
|
|
|
48
55
|
lastActionResult,
|
|
49
56
|
});
|
|
50
57
|
if (nextTransition === undefined) {
|
|
51
|
-
return await
|
|
58
|
+
return await lifecycle.fail(current.id, transitionsTaken, 'no-passing-transition');
|
|
52
59
|
}
|
|
53
60
|
// 6. Execute this state's on-exit actions before changing state.
|
|
54
|
-
const
|
|
55
|
-
if (
|
|
56
|
-
|
|
61
|
+
const exit = await this.runActions(current.onExit ?? [], workflow.name, current.id, runId, vars, env, options, transitionsTaken, lifecycle, defaultOnError);
|
|
62
|
+
if (exit.result !== undefined)
|
|
63
|
+
lastActionResult = exit.result;
|
|
64
|
+
if (exit.outcome === 'fail')
|
|
65
|
+
return await lifecycle.fail(current.id, transitionsTaken, exit.result?.error);
|
|
57
66
|
// 7. Persist transition and move to the target state.
|
|
58
67
|
transitionsTaken += 1;
|
|
59
|
-
await
|
|
68
|
+
await lifecycle.recordTransition(current.id, nextTransition.to, nextTransition.trigger ?? null);
|
|
60
69
|
if (transitionsTaken > iterationBound) {
|
|
61
|
-
return await
|
|
70
|
+
return await lifecycle.fail(current.id, transitionsTaken, 'iteration-bound-exceeded');
|
|
62
71
|
}
|
|
63
72
|
const nextState = states.get(nextTransition.to);
|
|
64
73
|
if (nextState === undefined)
|
|
@@ -66,51 +75,47 @@ export class StateMachineDriver {
|
|
|
66
75
|
current = nextState;
|
|
67
76
|
}
|
|
68
77
|
}
|
|
69
|
-
|
|
78
|
+
/**
|
|
79
|
+
* Run a state's actions in order. Returns the last action result (retained even
|
|
80
|
+
* when a failure was continued past, so downstream guards can inspect it) plus an
|
|
81
|
+
* `outcome` discriminator: `terminal` (an action declared terminal success),
|
|
82
|
+
* `fail` (a failure under a 'fail' policy — caller must halt), or `completed`.
|
|
83
|
+
*/
|
|
84
|
+
async runActions(actions, workflowName, stateId, runId, vars, env, options, transitionsTaken, lifecycle, defaultOnError) {
|
|
70
85
|
let last;
|
|
71
86
|
for (const action of actions) {
|
|
72
87
|
const resolved = resolveTemplates(action.options ?? {}, {
|
|
73
88
|
vars,
|
|
74
89
|
env,
|
|
75
|
-
builtins: runtimeBuiltins(workflowName, stateId, runId, transitionsTaken),
|
|
90
|
+
builtins: runtimeBuiltins(workflowName, stateId, runId, transitionsTaken, 'state-machine'),
|
|
76
91
|
});
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
92
|
+
const actionStartMs = Date.now();
|
|
93
|
+
lifecycle.actionStart(stateId, action.kind);
|
|
94
|
+
try {
|
|
95
|
+
last = await this.options.host.runAction(action.kind, resolved, {
|
|
96
|
+
runId,
|
|
97
|
+
workdir: options.workdir,
|
|
98
|
+
stateOrNodeId: stateId,
|
|
99
|
+
vars,
|
|
100
|
+
env,
|
|
101
|
+
metadata: options.metadata,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
finally {
|
|
105
|
+
lifecycle.actionDone(stateId, action.kind, Date.now() - actionStartMs, last?.ok ?? false);
|
|
106
|
+
}
|
|
107
|
+
if (last.terminal === true)
|
|
108
|
+
return { outcome: 'terminal', result: last };
|
|
109
|
+
if (!last.ok) {
|
|
110
|
+
const policy = resolveOnErrorPolicy(action.onError, defaultOnError, options.onError);
|
|
111
|
+
if (policy === 'fail')
|
|
112
|
+
return { outcome: 'fail', result: last };
|
|
113
|
+
lifecycle.warnActionFailed(stateId, transitionsTaken, last.error);
|
|
114
|
+
}
|
|
87
115
|
}
|
|
88
|
-
return last;
|
|
89
|
-
}
|
|
90
|
-
async done(runId, workflowName, mode, finalState, transitionsTaken) {
|
|
91
|
-
await this.options.persistence.savePhase(runId, finalState, 'done');
|
|
92
|
-
await this.options.persistence.finalizeRun(runId, 'done', new Date().toISOString());
|
|
93
|
-
return { runId, workflowName, mode, status: 'done', finalState, transitionsTaken };
|
|
94
|
-
}
|
|
95
|
-
async fail(runId, workflowName, mode, finalState, transitionsTaken, reason = 'failed') {
|
|
96
|
-
await this.options.persistence.savePhase(runId, finalState, 'failed');
|
|
97
|
-
await this.options.persistence.finalizeRun(runId, 'failed', new Date().toISOString());
|
|
98
|
-
return { runId, workflowName, mode, status: 'failed', finalState, transitionsTaken, reason };
|
|
116
|
+
return { outcome: 'completed', result: last };
|
|
99
117
|
}
|
|
100
118
|
}
|
|
101
|
-
/** Built-in bare template values available to state-machine action options. */
|
|
102
|
-
function runtimeBuiltins(workflowName, stateId, runId, transitionsTaken) {
|
|
103
|
-
return {
|
|
104
|
-
workflow: workflowName,
|
|
105
|
-
runId,
|
|
106
|
-
task: workflowName,
|
|
107
|
-
state: stateId,
|
|
108
|
-
node: stateId,
|
|
109
|
-
iteration: transitionsTaken,
|
|
110
|
-
run: runId,
|
|
111
|
-
runtime: 'state-machine',
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
119
|
async function firstPassingTransition(transitions, host, context) {
|
|
115
120
|
for (const transition of transitions) {
|
|
116
121
|
if (transition.guard === undefined)
|
|
@@ -120,17 +125,3 @@ async function firstPassingTransition(transitions, host, context) {
|
|
|
120
125
|
}
|
|
121
126
|
return undefined;
|
|
122
127
|
}
|
|
123
|
-
function allowedEnv(names, source) {
|
|
124
|
-
return Object.fromEntries(names.flatMap((name) => (source[name] === undefined ? [] : [[name, source[name]]])));
|
|
125
|
-
}
|
|
126
|
-
function runRecord(runId, workflowName, mode, startedAt, metadata) {
|
|
127
|
-
return {
|
|
128
|
-
id: runId,
|
|
129
|
-
workflow_name: workflowName,
|
|
130
|
-
mode,
|
|
131
|
-
status: 'running',
|
|
132
|
-
started_at: startedAt,
|
|
133
|
-
completed_at: null,
|
|
134
|
-
metadata_json: JSON.stringify(metadata ?? {}),
|
|
135
|
-
};
|
|
136
|
-
}
|
|
@@ -11,7 +11,6 @@ export declare class TransitionFlowDriver {
|
|
|
11
11
|
constructor(options: TransitionFlowDriverOptions);
|
|
12
12
|
/** Run a transition-flow workflow to completion or failure. */
|
|
13
13
|
run(workflow: TransitionFlowWorkflowDef, options?: WorkflowRunOptions): Promise<WorkflowRunResult>;
|
|
14
|
-
private
|
|
15
|
-
private fail;
|
|
14
|
+
private loop;
|
|
16
15
|
}
|
|
17
16
|
//# sourceMappingURL=transition-flow.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transition-flow.d.ts","sourceRoot":"","sources":["../src/transition-flow.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"transition-flow.d.ts","sourceRoot":"","sources":["../src/transition-flow.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AAEjD,OAAO,KAAK,EAER,yBAAyB,EACzB,0BAA0B,EAC1B,kBAAkB,EAClB,iBAAiB,EACpB,MAAM,SAAS,CAAC;AAGjB,2DAA2D;AAC3D,MAAM,WAAW,2BAA2B;IACxC,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAC;IAClC,QAAQ,CAAC,WAAW,EAAE,0BAA0B,CAAC;CACpD;AAED,0EAA0E;AAC1E,qBAAa,oBAAoB;IACjB,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,2BAA2B;IAEjE,+DAA+D;IACzD,GAAG,CAAC,QAAQ,EAAE,yBAAyB,EAAE,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,iBAAiB,CAAC;YAU9F,IAAI;CA8FrB"}
|
package/dist/transition-flow.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { getProcessEnv } from '@gobing-ai/ts-runtime';
|
|
2
1
|
import { FSMError } from './errors.js';
|
|
3
|
-
import {
|
|
2
|
+
import { allowedEnv, RunLifecycle, runtimeBuiltins } from './run-lifecycle.js';
|
|
3
|
+
import { mergeVars, resolveOnErrorPolicy, resolveTemplates } from './variables.js';
|
|
4
4
|
/** Transition-flow workflow driver with an R7 single control function. */
|
|
5
5
|
export class TransitionFlowDriver {
|
|
6
6
|
options;
|
|
@@ -9,51 +9,62 @@ export class TransitionFlowDriver {
|
|
|
9
9
|
}
|
|
10
10
|
/** Run a transition-flow workflow to completion or failure. */
|
|
11
11
|
async run(workflow, options = {}) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
return await RunLifecycle.run(workflow.name, 'transition-flow', { persistence: this.options.persistence, events: options.events }, options, (lifecycle) => this.loop(workflow, options, lifecycle));
|
|
13
|
+
}
|
|
14
|
+
async loop(workflow, options, lifecycle) {
|
|
15
|
+
const runId = lifecycle.runId;
|
|
16
16
|
const nodes = new Map(workflow.nodes.map((node) => [node.id, node]));
|
|
17
17
|
const terminal = new Set(workflow.terminalNodes ?? []);
|
|
18
18
|
const vars = mergeVars(workflow.vars, options.vars);
|
|
19
|
-
const env = allowedEnv(workflow.env?.allow ?? [], options.env
|
|
19
|
+
const env = allowedEnv(workflow.env?.allow ?? [], options.env);
|
|
20
20
|
let current = nodes.get(workflow.initialNode);
|
|
21
21
|
let transitionsTaken = 0;
|
|
22
22
|
let lastActionResult;
|
|
23
23
|
const iterationBound = workflow.iterationBound ?? 50;
|
|
24
|
+
const defaultOnError = workflow.defaultOnError;
|
|
24
25
|
if (current === undefined) {
|
|
25
26
|
throw new FSMError(`Initial node "${workflow.initialNode}" is not declared`);
|
|
26
27
|
}
|
|
27
28
|
while (true) {
|
|
28
29
|
// 1. Persist current node snapshot before action execution.
|
|
29
|
-
await
|
|
30
|
-
await this.options.persistence.savePhase(runId, current.id, 'running');
|
|
30
|
+
await lifecycle.enter(current.id, transitionsTaken);
|
|
31
31
|
// 2. Execute the node action when one is configured.
|
|
32
32
|
if (current.action !== undefined) {
|
|
33
33
|
const resolved = resolveTemplates(current.action.options ?? {}, {
|
|
34
34
|
vars,
|
|
35
35
|
env,
|
|
36
|
-
builtins: runtimeBuiltins(workflow.name, current.id, runId, transitionsTaken),
|
|
37
|
-
});
|
|
38
|
-
lastActionResult = await this.options.host.runAction(current.action.kind, resolved, {
|
|
39
|
-
runId,
|
|
40
|
-
workdir: options.workdir,
|
|
41
|
-
stateOrNodeId: current.id,
|
|
42
|
-
vars,
|
|
43
|
-
env,
|
|
44
|
-
metadata: options.metadata,
|
|
36
|
+
builtins: runtimeBuiltins(workflow.name, current.id, runId, transitionsTaken, 'transition-flow'),
|
|
45
37
|
});
|
|
38
|
+
const actionStartMs = Date.now();
|
|
39
|
+
lifecycle.actionStart(current.id, current.action.kind);
|
|
40
|
+
try {
|
|
41
|
+
lastActionResult = await this.options.host.runAction(current.action.kind, resolved, {
|
|
42
|
+
runId,
|
|
43
|
+
workdir: options.workdir,
|
|
44
|
+
stateOrNodeId: current.id,
|
|
45
|
+
vars,
|
|
46
|
+
env,
|
|
47
|
+
metadata: options.metadata,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
finally {
|
|
51
|
+
lifecycle.actionDone(current.id, current.action.kind, Date.now() - actionStartMs, lastActionResult?.ok ?? false);
|
|
52
|
+
}
|
|
46
53
|
if (!lastActionResult.ok) {
|
|
47
|
-
|
|
54
|
+
const policy = resolveOnErrorPolicy(current.action.onError, defaultOnError, options.onError);
|
|
55
|
+
if (policy === 'fail') {
|
|
56
|
+
return await lifecycle.fail(current.id, transitionsTaken, lastActionResult.error);
|
|
57
|
+
}
|
|
58
|
+
lifecycle.warnActionFailed(current.id, transitionsTaken, lastActionResult.error);
|
|
48
59
|
}
|
|
49
60
|
if (lastActionResult.terminal === true) {
|
|
50
|
-
return await
|
|
61
|
+
return await lifecycle.done(current.id, transitionsTaken);
|
|
51
62
|
}
|
|
52
63
|
}
|
|
53
64
|
// 3. Stop when the node is terminal or no outgoing edge exists.
|
|
54
65
|
const outbound = workflow.edges.filter((edge) => edge.from === current?.id);
|
|
55
66
|
if (terminal.has(current.id) || outbound.length === 0) {
|
|
56
|
-
return await
|
|
67
|
+
return await lifecycle.done(current.id, transitionsTaken);
|
|
57
68
|
}
|
|
58
69
|
// 4. Evaluate edge conditions in declaration order and pick the first passing edge.
|
|
59
70
|
const edge = await firstPassingEdge(outbound, this.options.host, {
|
|
@@ -63,14 +74,14 @@ export class TransitionFlowDriver {
|
|
|
63
74
|
lastActionResult,
|
|
64
75
|
});
|
|
65
76
|
if (edge === undefined) {
|
|
66
|
-
return await
|
|
77
|
+
return await lifecycle.fail(current.id, transitionsTaken, 'no-passing-edge');
|
|
67
78
|
}
|
|
68
79
|
// 5. Persist the edge transition.
|
|
69
80
|
transitionsTaken += 1;
|
|
70
|
-
await
|
|
81
|
+
await lifecycle.recordTransition(current.id, edge.to, edge.condition?.kind ?? null);
|
|
71
82
|
// 6. Enforce the iteration bound after taking the transition.
|
|
72
83
|
if (transitionsTaken > iterationBound) {
|
|
73
|
-
return await
|
|
84
|
+
return await lifecycle.fail(current.id, transitionsTaken, 'iteration-bound-exceeded');
|
|
74
85
|
}
|
|
75
86
|
// 7. Move to the target node and repeat.
|
|
76
87
|
const nextNode = nodes.get(edge.to);
|
|
@@ -79,29 +90,6 @@ export class TransitionFlowDriver {
|
|
|
79
90
|
current = nextNode;
|
|
80
91
|
}
|
|
81
92
|
}
|
|
82
|
-
async done(runId, workflowName, mode, finalState, transitionsTaken) {
|
|
83
|
-
await this.options.persistence.savePhase(runId, finalState, 'done');
|
|
84
|
-
await this.options.persistence.finalizeRun(runId, 'done', new Date().toISOString());
|
|
85
|
-
return { runId, workflowName, mode, status: 'done', finalState, transitionsTaken };
|
|
86
|
-
}
|
|
87
|
-
async fail(runId, workflowName, mode, finalState, transitionsTaken, reason = 'failed') {
|
|
88
|
-
await this.options.persistence.savePhase(runId, finalState, 'failed');
|
|
89
|
-
await this.options.persistence.finalizeRun(runId, 'failed', new Date().toISOString());
|
|
90
|
-
return { runId, workflowName, mode, status: 'failed', finalState, transitionsTaken, reason };
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
/** Built-in bare template values available to transition-flow action options. */
|
|
94
|
-
function runtimeBuiltins(workflowName, nodeId, runId, transitionsTaken) {
|
|
95
|
-
return {
|
|
96
|
-
workflow: workflowName,
|
|
97
|
-
runId,
|
|
98
|
-
task: workflowName,
|
|
99
|
-
state: nodeId,
|
|
100
|
-
node: nodeId,
|
|
101
|
-
iteration: transitionsTaken,
|
|
102
|
-
run: runId,
|
|
103
|
-
runtime: 'transition-flow',
|
|
104
|
-
};
|
|
105
93
|
}
|
|
106
94
|
async function firstPassingEdge(edges, host, context) {
|
|
107
95
|
for (const edge of edges) {
|
|
@@ -112,17 +100,3 @@ async function firstPassingEdge(edges, host, context) {
|
|
|
112
100
|
}
|
|
113
101
|
return undefined;
|
|
114
102
|
}
|
|
115
|
-
function allowedEnv(names, source) {
|
|
116
|
-
return Object.fromEntries(names.flatMap((name) => (source[name] === undefined ? [] : [[name, source[name]]])));
|
|
117
|
-
}
|
|
118
|
-
function runRecord(runId, workflowName, mode, startedAt, metadata) {
|
|
119
|
-
return {
|
|
120
|
-
id: runId,
|
|
121
|
-
workflow_name: workflowName,
|
|
122
|
-
mode,
|
|
123
|
-
status: 'running',
|
|
124
|
-
started_at: startedAt,
|
|
125
|
-
completed_at: null,
|
|
126
|
-
metadata_json: JSON.stringify(metadata ?? {}),
|
|
127
|
-
};
|
|
128
|
-
}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
/** Action error handling policy: fail-fast or log-and-continue. */
|
|
2
|
+
export type OnErrorPolicy = 'fail' | 'continue';
|
|
3
|
+
import type { EventBus } from '@gobing-ai/ts-infra';
|
|
4
|
+
import type { WorkflowEngineEvents } from './events';
|
|
1
5
|
/** Workflow execution status persisted for runs and phases. */
|
|
2
6
|
export type WorkflowStatus = 'running' | 'done' | 'failed';
|
|
3
7
|
/** Runtime variables and user variables available to workflow definitions. */
|
|
@@ -10,6 +14,8 @@ export interface Env {
|
|
|
10
14
|
export interface ActionDef {
|
|
11
15
|
readonly kind: string;
|
|
12
16
|
readonly options?: Record<string, unknown>;
|
|
17
|
+
/** Per-action error policy override. Falls back to workflow default then run-option then 'fail'. */
|
|
18
|
+
readonly onError?: OnErrorPolicy;
|
|
13
19
|
}
|
|
14
20
|
/** Guard predicate definition used by state-machine transitions and transition-flow edges. */
|
|
15
21
|
export interface GuardDef {
|
|
@@ -44,6 +50,8 @@ export interface StateMachineWorkflowDef {
|
|
|
44
50
|
readonly initialState: string;
|
|
45
51
|
readonly terminalStates?: readonly string[];
|
|
46
52
|
readonly iterationBound?: number;
|
|
53
|
+
/** Default error policy applied to actions that don't specify their own. Defaults to 'fail'. */
|
|
54
|
+
readonly defaultOnError?: OnErrorPolicy;
|
|
47
55
|
readonly vars?: Vars;
|
|
48
56
|
readonly env?: Env;
|
|
49
57
|
readonly states: readonly StateDef[];
|
|
@@ -76,6 +84,8 @@ export interface TransitionFlowWorkflowDef {
|
|
|
76
84
|
readonly initialNode: string;
|
|
77
85
|
readonly terminalNodes?: readonly string[];
|
|
78
86
|
readonly iterationBound?: number;
|
|
87
|
+
/** Default error policy applied to actions that don't specify their own. Defaults to 'fail'. */
|
|
88
|
+
readonly defaultOnError?: OnErrorPolicy;
|
|
79
89
|
readonly vars?: Vars;
|
|
80
90
|
readonly env?: Env;
|
|
81
91
|
readonly nodes: readonly FlowNodeDef[];
|
|
@@ -123,6 +133,10 @@ export interface WorkflowRunOptions {
|
|
|
123
133
|
readonly vars?: Vars;
|
|
124
134
|
readonly env?: Record<string, string | undefined>;
|
|
125
135
|
readonly metadata?: Record<string, unknown>;
|
|
136
|
+
/** Optional event bus for structured run observability. */
|
|
137
|
+
readonly events?: EventBus<WorkflowEngineEvents>;
|
|
138
|
+
/** Run-level error policy override. Lowest precedence; action-level wins. */
|
|
139
|
+
readonly onError?: OnErrorPolicy;
|
|
126
140
|
}
|
|
127
141
|
/** Result returned by both driver loops. */
|
|
128
142
|
export interface WorkflowRunResult {
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE3D,8EAA8E;AAC9E,MAAM,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAE1C,8DAA8D;AAC9D,MAAM,WAAW,GAAG;IAChB,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACtC;AAED,mEAAmE;AACnE,MAAM,WAAW,SAAS;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/variables.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Vars } from './types';
|
|
1
|
+
import type { OnErrorPolicy, Vars } from './types';
|
|
2
2
|
/** Runtime context used for workflow variable interpolation. */
|
|
3
3
|
export interface VariableContext {
|
|
4
4
|
readonly vars: Vars;
|
|
@@ -11,4 +11,9 @@ export declare function mergeVars(workflowVars?: Vars, overrideVars?: Vars): Var
|
|
|
11
11
|
export declare function resolveTemplates<T>(value: T, context: VariableContext): T;
|
|
12
12
|
/** Resolve a single template string. */
|
|
13
13
|
export declare function resolveTemplateString(value: string, context: VariableContext): string;
|
|
14
|
+
/**
|
|
15
|
+
* Resolve the effective error policy via fixed precedence:
|
|
16
|
+
* `action.onError ?? workflow.defaultOnError ?? runOptions.onError ?? 'fail'`.
|
|
17
|
+
*/
|
|
18
|
+
export declare function resolveOnErrorPolicy(actionOnError: OnErrorPolicy | undefined, workflowDefault: OnErrorPolicy | undefined, runOptionOverride: OnErrorPolicy | undefined): OnErrorPolicy;
|
|
14
19
|
//# sourceMappingURL=variables.d.ts.map
|
package/dist/variables.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"variables.d.ts","sourceRoot":"","sources":["../src/variables.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"variables.d.ts","sourceRoot":"","sources":["../src/variables.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAInD,gEAAgE;AAChE,MAAM,WAAW,eAAe;IAC5B,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACjD,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC,CAAC;CACnE;AAED,oEAAoE;AACpE,wBAAgB,SAAS,CAAC,YAAY,GAAE,IAAS,EAAE,YAAY,GAAE,IAAS,GAAG,IAAI,CAEhF;AAED,yDAAyD;AACzD,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,eAAe,GAAG,CAAC,CAgBzE;AAED,wCAAwC;AACxC,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,MAAM,CAmBrF;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAChC,aAAa,EAAE,aAAa,GAAG,SAAS,EACxC,eAAe,EAAE,aAAa,GAAG,SAAS,EAC1C,iBAAiB,EAAE,aAAa,GAAG,SAAS,GAC7C,aAAa,CAEf"}
|
package/dist/variables.js
CHANGED
|
@@ -43,3 +43,10 @@ export function resolveTemplateString(value, context) {
|
|
|
43
43
|
return String(resolved);
|
|
44
44
|
});
|
|
45
45
|
}
|
|
46
|
+
/**
|
|
47
|
+
* Resolve the effective error policy via fixed precedence:
|
|
48
|
+
* `action.onError ?? workflow.defaultOnError ?? runOptions.onError ?? 'fail'`.
|
|
49
|
+
*/
|
|
50
|
+
export function resolveOnErrorPolicy(actionOnError, workflowDefault, runOptionOverride) {
|
|
51
|
+
return actionOnError ?? workflowDefault ?? runOptionOverride ?? 'fail';
|
|
52
|
+
}
|