@gobing-ai/ts-dual-workflow-engine 0.3.1 → 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/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/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
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { Logger } from '@gobing-ai/ts-infra';
|
|
2
|
+
import type { WorkflowEngineHost } from './host';
|
|
3
|
+
/** Minimal warning sink accepted for non-fatal extension diagnostics; a full {@link Logger} satisfies it. */
|
|
4
|
+
export type WorkflowExtensionLogger = Pick<Logger, 'warn'>;
|
|
5
|
+
/**
|
|
6
|
+
* Capability kinds a workflow extension module can contribute.
|
|
7
|
+
*
|
|
8
|
+
* Only `actions` and `guards` are supported as extension surfaces. Driver,
|
|
9
|
+
* loader, validator, and formatter registries are explicitly deferred per
|
|
10
|
+
* ADR-010 and are not extension-loadable.
|
|
11
|
+
*/
|
|
12
|
+
export type WorkflowExtensionKind = 'actions' | 'guards';
|
|
13
|
+
/**
|
|
14
|
+
* A single workflow extension module reference.
|
|
15
|
+
*
|
|
16
|
+
* The caller provides a pre-resolved absolute path; the loader adapts it to the
|
|
17
|
+
* shared `ExtensionRef` format before delegating to the generic core so the
|
|
18
|
+
* trust guard always governs the module that gets imported.
|
|
19
|
+
*/
|
|
20
|
+
export interface WorkflowExtensionRef {
|
|
21
|
+
/** Target capability registry. */
|
|
22
|
+
readonly kind: WorkflowExtensionKind;
|
|
23
|
+
/** Absolute path to the module to import. */
|
|
24
|
+
readonly absPath: string;
|
|
25
|
+
/** Name of the config declaring this extension (for diagnostics). */
|
|
26
|
+
readonly sourceName: string;
|
|
27
|
+
}
|
|
28
|
+
/** Options controlling workflow extension loading. */
|
|
29
|
+
export interface LoadWorkflowExtensionsOptions {
|
|
30
|
+
/**
|
|
31
|
+
* Whether to actually import extension modules. Defaults to `false`:
|
|
32
|
+
* loading arbitrary code is a trust decision the caller must make
|
|
33
|
+
* explicitly. When refs exist and this is not `true`, loading throws
|
|
34
|
+
* **before any import**.
|
|
35
|
+
*/
|
|
36
|
+
readonly allowExtensions?: boolean;
|
|
37
|
+
/** Optional sink for non-fatal warnings (e.g. built-in overrides). */
|
|
38
|
+
readonly logger?: WorkflowExtensionLogger;
|
|
39
|
+
/**
|
|
40
|
+
* Required module loader seam for tests or embedders with custom import
|
|
41
|
+
* policy. The shared core has no ambient code-loading capability of its
|
|
42
|
+
* own; the embedder supplies the import policy.
|
|
43
|
+
*/
|
|
44
|
+
readonly moduleLoader: (absPath: string) => Promise<Record<string, unknown>>;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Import each extension module behind an explicit trust gate and register
|
|
48
|
+
* its actions and/or guards on the workflow host.
|
|
49
|
+
*
|
|
50
|
+
* Delegates generic loading (gate, path guard, module import, export
|
|
51
|
+
* validation) to the shared ``loadExtensionModules`` from ts-runtime/plugin,
|
|
52
|
+
* then routes each capability to ``host.registerAction`` or
|
|
53
|
+
* ``host.registerGuard`` based on ``ref.kind``.
|
|
54
|
+
*
|
|
55
|
+
* @throws When extensions are present but ``allowExtensions`` is not ``true``,
|
|
56
|
+
* when a module lacks a valid export shape, or when the module's export
|
|
57
|
+
* does not contain entries matching ``ref.kind``.
|
|
58
|
+
*/
|
|
59
|
+
export declare function loadWorkflowExtensionsIntoHost(host: WorkflowEngineHost, refs: readonly WorkflowExtensionRef[], options: LoadWorkflowExtensionsOptions): Promise<void>;
|
|
60
|
+
//# sourceMappingURL=extensions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extensions.d.ts","sourceRoot":"","sources":["../src/extensions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAKlD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AAGjD,6GAA6G;AAC7G,MAAM,MAAM,uBAAuB,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAE3D;;;;;;GAMG;AACH,MAAM,MAAM,qBAAqB,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEzD;;;;;;GAMG;AACH,MAAM,WAAW,oBAAoB;IACjC,kCAAkC;IAClC,QAAQ,CAAC,IAAI,EAAE,qBAAqB,CAAC;IACrC,6CAA6C;IAC7C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,qEAAqE;IACrE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC/B;AAED,sDAAsD;AACtD,MAAM,WAAW,6BAA6B;IAC1C;;;;;OAKG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;IACnC,sEAAsE;IACtE,QAAQ,CAAC,MAAM,CAAC,EAAE,uBAAuB,CAAC;IAC1C;;;;OAIG;IACH,QAAQ,CAAC,YAAY,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CAChF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,8BAA8B,CAChD,IAAI,EAAE,kBAAkB,EACxB,IAAI,EAAE,SAAS,oBAAoB,EAAE,EACrC,OAAO,EAAE,6BAA6B,GACvC,OAAO,CAAC,IAAI,CAAC,CAqCf"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { basenamePath, dirnamePath, SEP } from '@gobing-ai/ts-runtime';
|
|
2
|
+
import { loadExtensionModules } from '@gobing-ai/ts-runtime/plugin';
|
|
3
|
+
import { WorkflowValidationError } from './errors.js';
|
|
4
|
+
/**
|
|
5
|
+
* Import each extension module behind an explicit trust gate and register
|
|
6
|
+
* its actions and/or guards on the workflow host.
|
|
7
|
+
*
|
|
8
|
+
* Delegates generic loading (gate, path guard, module import, export
|
|
9
|
+
* validation) to the shared ``loadExtensionModules`` from ts-runtime/plugin,
|
|
10
|
+
* then routes each capability to ``host.registerAction`` or
|
|
11
|
+
* ``host.registerGuard`` based on ``ref.kind``.
|
|
12
|
+
*
|
|
13
|
+
* @throws When extensions are present but ``allowExtensions`` is not ``true``,
|
|
14
|
+
* when a module lacks a valid export shape, or when the module's export
|
|
15
|
+
* does not contain entries matching ``ref.kind``.
|
|
16
|
+
*/
|
|
17
|
+
export async function loadWorkflowExtensionsIntoHost(host, refs, options) {
|
|
18
|
+
if (refs.length === 0)
|
|
19
|
+
return;
|
|
20
|
+
// Enforce relative-path guard before adapting to the shared format.
|
|
21
|
+
// The shared loader's assertRelativeExtensionPath applies to the derived
|
|
22
|
+
// (basename) path, which is always clean — this pre-check catches `..`
|
|
23
|
+
// traversal in the caller-supplied absPath before basename strips it (R6).
|
|
24
|
+
for (const ref of refs) {
|
|
25
|
+
const segments = ref.absPath.split(SEP);
|
|
26
|
+
if (segments.includes('..')) {
|
|
27
|
+
throw new Error(`extension path "${ref.absPath}" declared by "${ref.sourceName}" must not contain ".." traversal`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
// Adapt WorkflowExtensionRef → shared ExtensionRef so the generic loader
|
|
31
|
+
// governs every import. The shared loader resolves (baseDir, path) ->
|
|
32
|
+
// absPath internally; we supply dirname/basename so the resolved path
|
|
33
|
+
// reconstructs the caller's original absPath. assertRelativeExtensionPath
|
|
34
|
+
// is satisfied because basenamePath() is always a simple filename.
|
|
35
|
+
const sharedRefs = refs.map((ref) => ({
|
|
36
|
+
kind: ref.kind,
|
|
37
|
+
path: `./${basenamePath(ref.absPath)}`,
|
|
38
|
+
baseDir: dirnamePath(ref.absPath),
|
|
39
|
+
sourceName: ref.sourceName,
|
|
40
|
+
}));
|
|
41
|
+
const sharedOptions = {
|
|
42
|
+
allowExtensions: options.allowExtensions,
|
|
43
|
+
logger: options.logger,
|
|
44
|
+
moduleLoader: options.moduleLoader,
|
|
45
|
+
};
|
|
46
|
+
await loadExtensionModules(sharedRefs, sharedOptions, async (sharedRef, extension) => {
|
|
47
|
+
await registerExtensionOnHost(host, sharedRef, extension, options.logger);
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Route extension-exported capabilities to the correct host registry.
|
|
52
|
+
*
|
|
53
|
+
* Validates that the module export contains entries matching `ref.kind`
|
|
54
|
+
* (wrong-kind-for-ref throws ``WorkflowValidationError``), registers each
|
|
55
|
+
* with origin ``'extension'``, and warns on built-in overrides.
|
|
56
|
+
*/
|
|
57
|
+
async function registerExtensionOnHost(host, ref, extension, logger) {
|
|
58
|
+
const name = extension.name;
|
|
59
|
+
if (ref.kind === 'actions') {
|
|
60
|
+
const actions = extension.actions;
|
|
61
|
+
if (!Array.isArray(actions)) {
|
|
62
|
+
throw new WorkflowValidationError(`"${ref.sourceName}" extension "${name}" is referenced as kind "actions" but does not export an actions[] array`);
|
|
63
|
+
}
|
|
64
|
+
for (const action of actions) {
|
|
65
|
+
warnIfOverride(host, action.kind, 'action', ref.sourceName, logger);
|
|
66
|
+
host.registerAction(action, 'extension');
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
const guards = extension.guards;
|
|
71
|
+
if (!Array.isArray(guards)) {
|
|
72
|
+
throw new WorkflowValidationError(`"${ref.sourceName}" extension "${name}" is referenced as kind "guards" but does not export a guards[] array`);
|
|
73
|
+
}
|
|
74
|
+
for (const guard of guards) {
|
|
75
|
+
warnIfOverride(host, guard.kind, 'guard', ref.sourceName, logger);
|
|
76
|
+
host.registerGuard(guard, 'extension');
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
function warnIfOverride(host, kind, capabilityType, sourceName, logger) {
|
|
81
|
+
const origin = capabilityType === 'action' ? host.actionOrigin(kind) : host.guardOrigin(kind);
|
|
82
|
+
if (logger && origin === 'builtin') {
|
|
83
|
+
logger.warn(`"${sourceName}" extension overrides built-in ${capabilityType} "${kind}"`);
|
|
84
|
+
}
|
|
85
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
export { loadWorkflowDef, loadWorkflowDefFromText, validateWorkflowDef } from './config';
|
|
2
2
|
export { FSMError, RunCollisionError, WorkflowValidationError } from './errors';
|
|
3
|
+
export type { WorkflowEngineEvents } from './events';
|
|
4
|
+
export { type LoadWorkflowExtensionsOptions, loadWorkflowExtensionsIntoHost, type WorkflowExtensionKind, type WorkflowExtensionLogger, type WorkflowExtensionRef, } from './extensions';
|
|
3
5
|
export { createDefaultWorkflowEngineHost, NoteActionRunner, ShellActionRunner, WorkflowEngineHost, } from './host';
|
|
4
6
|
export { applyWorkflowEngineSchema, DbWorkflowPersistenceAdapter, MemoryWorkflowPersistenceAdapter, } from './persistence';
|
|
7
|
+
export { allowedEnv, RUNTIME_BUILTIN_KEYS, RunLifecycle, type RunLifecycleDeps, runtimeBuiltins, type WorkflowMode, } from './run-lifecycle';
|
|
5
8
|
export { ActionDefSchema, GuardDefSchema, StateMachineWorkflowDefSchema, TransitionFlowWorkflowDefSchema, WorkflowDefSchema, } from './schema';
|
|
6
9
|
export { WORKFLOW_ENGINE_SCHEMA_SQL } from './schema-sql';
|
|
7
10
|
export { WorkflowService } from './service';
|
|
8
11
|
export { StateMachineDriver, type StateMachineDriverOptions } from './state-machine';
|
|
9
12
|
export { TransitionFlowDriver, type TransitionFlowDriverOptions } from './transition-flow';
|
|
10
|
-
export type { ActionDef, ActionResult, ActionRunContext, ActionRunner, Env, FlowEdgeDef, FlowNodeDef, GuardContext, GuardDef, GuardRunner, StateDef, StateMachineWorkflowDef, TransitionDef, TransitionFlowWorkflowDef, Vars, WorkflowDef, WorkflowPersistenceAdapter, WorkflowRunOptions, WorkflowRunRecord, WorkflowRunResult, WorkflowStatus, } from './types';
|
|
11
|
-
export { mergeVars, resolveTemplateString, resolveTemplates, type VariableContext } from './variables';
|
|
13
|
+
export type { ActionDef, ActionResult, ActionRunContext, ActionRunner, Env, FlowEdgeDef, FlowNodeDef, GuardContext, GuardDef, GuardRunner, OnErrorPolicy, StateDef, StateMachineWorkflowDef, TransitionDef, TransitionFlowWorkflowDef, Vars, WorkflowDef, WorkflowPersistenceAdapter, WorkflowRunOptions, WorkflowRunRecord, WorkflowRunResult, WorkflowStatus, } from './types';
|
|
14
|
+
export { mergeVars, resolveOnErrorPolicy, resolveTemplateString, resolveTemplates, type VariableContext, } from './variables';
|
|
12
15
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AACzF,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AAChF,OAAO,EACH,+BAA+B,EAC/B,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,GACrB,MAAM,QAAQ,CAAC;AAChB,OAAO,EACH,yBAAyB,EACzB,4BAA4B,EAC5B,gCAAgC,GACnC,MAAM,eAAe,CAAC;AACvB,OAAO,EACH,eAAe,EACf,cAAc,EACd,6BAA6B,EAC7B,+BAA+B,EAC/B,iBAAiB,GACpB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,kBAAkB,EAAE,KAAK,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AACrF,OAAO,EAAE,oBAAoB,EAAE,KAAK,2BAA2B,EAAE,MAAM,mBAAmB,CAAC;AAC3F,YAAY,EACR,SAAS,EACT,YAAY,EACZ,gBAAgB,EAChB,YAAY,EACZ,GAAG,EACH,WAAW,EACX,WAAW,EACX,YAAY,EACZ,QAAQ,EACR,WAAW,EACX,QAAQ,EACR,uBAAuB,EACvB,aAAa,EACb,yBAAyB,EACzB,IAAI,EACJ,WAAW,EACX,0BAA0B,EAC1B,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,GACjB,MAAM,SAAS,CAAC;AACjB,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AACzF,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AAChF,YAAY,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AACrD,OAAO,EACH,KAAK,6BAA6B,EAClC,8BAA8B,EAC9B,KAAK,qBAAqB,EAC1B,KAAK,uBAAuB,EAC5B,KAAK,oBAAoB,GAC5B,MAAM,cAAc,CAAC;AACtB,OAAO,EACH,+BAA+B,EAC/B,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,GACrB,MAAM,QAAQ,CAAC;AAChB,OAAO,EACH,yBAAyB,EACzB,4BAA4B,EAC5B,gCAAgC,GACnC,MAAM,eAAe,CAAC;AACvB,OAAO,EACH,UAAU,EACV,oBAAoB,EACpB,YAAY,EACZ,KAAK,gBAAgB,EACrB,eAAe,EACf,KAAK,YAAY,GACpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACH,eAAe,EACf,cAAc,EACd,6BAA6B,EAC7B,+BAA+B,EAC/B,iBAAiB,GACpB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,kBAAkB,EAAE,KAAK,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AACrF,OAAO,EAAE,oBAAoB,EAAE,KAAK,2BAA2B,EAAE,MAAM,mBAAmB,CAAC;AAC3F,YAAY,EACR,SAAS,EACT,YAAY,EACZ,gBAAgB,EAChB,YAAY,EACZ,GAAG,EACH,WAAW,EACX,WAAW,EACX,YAAY,EACZ,QAAQ,EACR,WAAW,EACX,aAAa,EACb,QAAQ,EACR,uBAAuB,EACvB,aAAa,EACb,yBAAyB,EACzB,IAAI,EACJ,WAAW,EACX,0BAA0B,EAC1B,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,GACjB,MAAM,SAAS,CAAC;AACjB,OAAO,EACH,SAAS,EACT,oBAAoB,EACpB,qBAAqB,EACrB,gBAAgB,EAChB,KAAK,eAAe,GACvB,MAAM,aAAa,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
export { loadWorkflowDef, loadWorkflowDefFromText, validateWorkflowDef } from './config.js';
|
|
2
2
|
export { FSMError, RunCollisionError, WorkflowValidationError } from './errors.js';
|
|
3
|
+
export { loadWorkflowExtensionsIntoHost, } from './extensions.js';
|
|
3
4
|
export { createDefaultWorkflowEngineHost, NoteActionRunner, ShellActionRunner, WorkflowEngineHost, } from './host.js';
|
|
4
5
|
export { applyWorkflowEngineSchema, DbWorkflowPersistenceAdapter, MemoryWorkflowPersistenceAdapter, } from './persistence.js';
|
|
6
|
+
export { allowedEnv, RUNTIME_BUILTIN_KEYS, RunLifecycle, runtimeBuiltins, } from './run-lifecycle.js';
|
|
5
7
|
export { ActionDefSchema, GuardDefSchema, StateMachineWorkflowDefSchema, TransitionFlowWorkflowDefSchema, WorkflowDefSchema, } from './schema.js';
|
|
6
8
|
export { WORKFLOW_ENGINE_SCHEMA_SQL } from './schema-sql.js';
|
|
7
9
|
export { WorkflowService } from './service.js';
|
|
8
10
|
export { StateMachineDriver } from './state-machine.js';
|
|
9
11
|
export { TransitionFlowDriver } from './transition-flow.js';
|
|
10
|
-
export { mergeVars, resolveTemplateString, resolveTemplates } from './variables.js';
|
|
12
|
+
export { mergeVars, resolveOnErrorPolicy, resolveTemplateString, resolveTemplates, } from './variables.js';
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { type EventBus, type Logger } from '@gobing-ai/ts-infra';
|
|
2
|
+
import type { WorkflowEngineEvents } from './events';
|
|
3
|
+
import type { WorkflowPersistenceAdapter, WorkflowRunOptions, WorkflowRunResult } from './types';
|
|
4
|
+
/** Workflow dialect carried on every run, span, and persisted record. */
|
|
5
|
+
export type WorkflowMode = WorkflowRunResult['mode'];
|
|
6
|
+
/** Keys of the runtime builtin namespace, single-sourced for resolver + validator. */
|
|
7
|
+
export declare const RUNTIME_BUILTIN_KEYS: readonly ["workflow", "runId", "task", "state", "node", "iteration", "run", "runtime"];
|
|
8
|
+
/** Built-in bare template values available to action options (state-machine + transition-flow). */
|
|
9
|
+
export declare function runtimeBuiltins(workflowName: string, stateOrNodeId: string, runId: string, transitionsTaken: number, mode: WorkflowMode): Record<(typeof RUNTIME_BUILTIN_KEYS)[number], string | number>;
|
|
10
|
+
/** Project the env allowlist over a source map, dropping unset names. */
|
|
11
|
+
export declare function allowedEnv(names: readonly string[], source?: Record<string, string | undefined>): Record<string, string>;
|
|
12
|
+
/** Dependencies a driver hands to {@link RunLifecycle}. */
|
|
13
|
+
export interface RunLifecycleDeps {
|
|
14
|
+
readonly persistence: WorkflowPersistenceAdapter;
|
|
15
|
+
/** Observability sink; defaults to the shared `workflow` category logger. */
|
|
16
|
+
readonly logger?: Logger;
|
|
17
|
+
/** Optional event bus for structured in-process run observability. */
|
|
18
|
+
readonly events?: EventBus<WorkflowEngineEvents>;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Owns the run-level bookkeeping shared by both drivers: run identity, the
|
|
22
|
+
* create→phase→finalize persistence sequence, and observability (one OTel span
|
|
23
|
+
* per run plus structured log lines). The two driver control loops stay
|
|
24
|
+
* dialect-specific (ADR-006 §7) and call into this for every persistence touch.
|
|
25
|
+
*/
|
|
26
|
+
export declare class RunLifecycle {
|
|
27
|
+
private readonly workflowName;
|
|
28
|
+
private readonly mode;
|
|
29
|
+
readonly runId: string;
|
|
30
|
+
private readonly persistence;
|
|
31
|
+
private readonly events;
|
|
32
|
+
private readonly logger;
|
|
33
|
+
private readonly startedAt;
|
|
34
|
+
private constructor();
|
|
35
|
+
/**
|
|
36
|
+
* Create the run record and execute `loop` inside the run's OTel span. The
|
|
37
|
+
* driver's control loop is the body; it receives this lifecycle to drive
|
|
38
|
+
* per-step persistence and terminal results.
|
|
39
|
+
*/
|
|
40
|
+
static run(workflowName: string, mode: WorkflowMode, deps: RunLifecycleDeps, options: WorkflowRunOptions, loop: (lifecycle: RunLifecycle) => Promise<WorkflowRunResult>): Promise<WorkflowRunResult>;
|
|
41
|
+
/** Persist the current state/node snapshot and mark its phase running. */
|
|
42
|
+
enter(stateOrNodeId: string, transitionsTaken: number): Promise<void>;
|
|
43
|
+
/** Persist a transition and emit its observability event. */
|
|
44
|
+
recordTransition(from: string, to: string, trigger: string | null): Promise<void>;
|
|
45
|
+
/** Finalize the run as succeeded and return its result. */
|
|
46
|
+
done(finalState: string, transitionsTaken: number): Promise<WorkflowRunResult>;
|
|
47
|
+
/** Finalize the run as failed and return its result. */
|
|
48
|
+
fail(finalState: string, transitionsTaken: number, reason?: string): Promise<WorkflowRunResult>;
|
|
49
|
+
/** Emit action-level observability before a host action is invoked. */
|
|
50
|
+
actionStart(stateOrNodeId: string, kind: string): void;
|
|
51
|
+
/** Emit action-level observability after a host action settles. */
|
|
52
|
+
actionDone(stateOrNodeId: string, kind: string, durationMs: number, ok: boolean): void;
|
|
53
|
+
/** Log and trace a non-fatal action failure for the 'continue' error policy (ADR-013 observability seam). */
|
|
54
|
+
warnActionFailed(stateOrNodeId: string, transitionsTaken: number, error?: string): void;
|
|
55
|
+
private result;
|
|
56
|
+
private runRecord;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=run-lifecycle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-lifecycle.d.ts","sourceRoot":"","sources":["../src/run-lifecycle.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { addSpanEvent, getLogger, traceAsync } from '@gobing-ai/ts-infra';
|
|
2
|
+
import { getProcessEnv } from '@gobing-ai/ts-runtime';
|
|
3
|
+
/** Keys of the runtime builtin namespace, single-sourced for resolver + validator. */
|
|
4
|
+
export const RUNTIME_BUILTIN_KEYS = [
|
|
5
|
+
'workflow',
|
|
6
|
+
'runId',
|
|
7
|
+
'task',
|
|
8
|
+
'state',
|
|
9
|
+
'node',
|
|
10
|
+
'iteration',
|
|
11
|
+
'run',
|
|
12
|
+
'runtime',
|
|
13
|
+
];
|
|
14
|
+
/** Built-in bare template values available to action options (state-machine + transition-flow). */
|
|
15
|
+
export function runtimeBuiltins(workflowName, stateOrNodeId, runId, transitionsTaken, mode) {
|
|
16
|
+
return {
|
|
17
|
+
workflow: workflowName,
|
|
18
|
+
runId,
|
|
19
|
+
task: workflowName,
|
|
20
|
+
state: stateOrNodeId,
|
|
21
|
+
node: stateOrNodeId,
|
|
22
|
+
iteration: transitionsTaken,
|
|
23
|
+
run: runId,
|
|
24
|
+
runtime: mode,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/** Project the env allowlist over a source map, dropping unset names. */
|
|
28
|
+
export function allowedEnv(names, source = getProcessEnv()) {
|
|
29
|
+
return Object.fromEntries(names.flatMap((name) => (source[name] === undefined ? [] : [[name, source[name]]])));
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Owns the run-level bookkeeping shared by both drivers: run identity, the
|
|
33
|
+
* create→phase→finalize persistence sequence, and observability (one OTel span
|
|
34
|
+
* per run plus structured log lines). The two driver control loops stay
|
|
35
|
+
* dialect-specific (ADR-006 §7) and call into this for every persistence touch.
|
|
36
|
+
*/
|
|
37
|
+
export class RunLifecycle {
|
|
38
|
+
workflowName;
|
|
39
|
+
mode;
|
|
40
|
+
runId;
|
|
41
|
+
persistence;
|
|
42
|
+
events;
|
|
43
|
+
logger;
|
|
44
|
+
startedAt;
|
|
45
|
+
constructor(runId, workflowName, mode, deps) {
|
|
46
|
+
this.workflowName = workflowName;
|
|
47
|
+
this.mode = mode;
|
|
48
|
+
this.runId = runId;
|
|
49
|
+
this.persistence = deps.persistence;
|
|
50
|
+
this.events = deps.events;
|
|
51
|
+
this.startedAt = new Date().toISOString();
|
|
52
|
+
this.logger = (deps.logger ?? getLogger('workflow')).child({ runId, workflow: workflowName, mode });
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Create the run record and execute `loop` inside the run's OTel span. The
|
|
56
|
+
* driver's control loop is the body; it receives this lifecycle to drive
|
|
57
|
+
* per-step persistence and terminal results.
|
|
58
|
+
*/
|
|
59
|
+
static async run(workflowName, mode, deps, options, loop) {
|
|
60
|
+
const runId = options.runId ?? crypto.randomUUID();
|
|
61
|
+
const lifecycle = new RunLifecycle(runId, workflowName, mode, deps);
|
|
62
|
+
return await traceAsync('workflow.run', async () => {
|
|
63
|
+
await lifecycle.persistence.createRun(lifecycle.runRecord(options.metadata));
|
|
64
|
+
lifecycle.logger.info('workflow run started');
|
|
65
|
+
addSpanEvent('workflow.run.started', { workflowName, mode, runId });
|
|
66
|
+
void lifecycle.events?.emit('workflow.run.started', { workflowName, mode, runId });
|
|
67
|
+
return await loop(lifecycle);
|
|
68
|
+
}, { attributes: { 'workflow.name': workflowName, 'workflow.mode': mode, 'workflow.run_id': runId } });
|
|
69
|
+
}
|
|
70
|
+
/** Persist the current state/node snapshot and mark its phase running. */
|
|
71
|
+
async enter(stateOrNodeId, transitionsTaken) {
|
|
72
|
+
await this.persistence.saveWorkflowState(this.runId, stateOrNodeId, { transitionsTaken });
|
|
73
|
+
await this.persistence.savePhase(this.runId, stateOrNodeId, 'running');
|
|
74
|
+
addSpanEvent('workflow.node.enter', { node: stateOrNodeId, transitionsTaken });
|
|
75
|
+
void this.events?.emit('workflow.node.enter', { node: stateOrNodeId, transitionsTaken });
|
|
76
|
+
this.logger.debug('entered', { node: stateOrNodeId, transitionsTaken });
|
|
77
|
+
}
|
|
78
|
+
/** Persist a transition and emit its observability event. */
|
|
79
|
+
async recordTransition(from, to, trigger) {
|
|
80
|
+
await this.persistence.saveTransition(this.runId, from, to, trigger);
|
|
81
|
+
addSpanEvent('workflow.node.transition', { from, to, ...(trigger === null ? {} : { trigger }) });
|
|
82
|
+
void this.events?.emit('workflow.node.transition', { from, to, trigger });
|
|
83
|
+
this.logger.debug('transition', { from, to, trigger });
|
|
84
|
+
}
|
|
85
|
+
/** Finalize the run as succeeded and return its result. */
|
|
86
|
+
async done(finalState, transitionsTaken) {
|
|
87
|
+
await this.persistence.savePhase(this.runId, finalState, 'done');
|
|
88
|
+
await this.persistence.finalizeRun(this.runId, 'done', new Date().toISOString());
|
|
89
|
+
this.logger.info('workflow run done', { finalState, transitionsTaken });
|
|
90
|
+
addSpanEvent('workflow.run.done', { finalState, transitionsTaken });
|
|
91
|
+
void this.events?.emit('workflow.run.done', { finalState, transitionsTaken });
|
|
92
|
+
return this.result('done', finalState, transitionsTaken);
|
|
93
|
+
}
|
|
94
|
+
/** Finalize the run as failed and return its result. */
|
|
95
|
+
async fail(finalState, transitionsTaken, reason = 'failed') {
|
|
96
|
+
await this.persistence.savePhase(this.runId, finalState, 'failed');
|
|
97
|
+
await this.persistence.finalizeRun(this.runId, 'failed', new Date().toISOString());
|
|
98
|
+
addSpanEvent('workflow.run.failed', { finalState, reason });
|
|
99
|
+
void this.events?.emit('workflow.run.failed', { finalState, reason });
|
|
100
|
+
this.logger.warn('workflow run failed', { finalState, transitionsTaken, reason });
|
|
101
|
+
return this.result('failed', finalState, transitionsTaken, reason);
|
|
102
|
+
}
|
|
103
|
+
/** Emit action-level observability before a host action is invoked. */
|
|
104
|
+
actionStart(stateOrNodeId, kind) {
|
|
105
|
+
addSpanEvent('workflow.action.start', { node: stateOrNodeId, kind });
|
|
106
|
+
void this.events?.emit('workflow.action.start', { node: stateOrNodeId, kind });
|
|
107
|
+
}
|
|
108
|
+
/** Emit action-level observability after a host action settles. */
|
|
109
|
+
actionDone(stateOrNodeId, kind, durationMs, ok) {
|
|
110
|
+
addSpanEvent('workflow.action.done', { node: stateOrNodeId, kind, durationMs, ok });
|
|
111
|
+
void this.events?.emit('workflow.action.done', { node: stateOrNodeId, kind, durationMs, ok });
|
|
112
|
+
}
|
|
113
|
+
/** Log and trace a non-fatal action failure for the 'continue' error policy (ADR-013 observability seam). */
|
|
114
|
+
warnActionFailed(stateOrNodeId, transitionsTaken, error) {
|
|
115
|
+
addSpanEvent('workflow.action.failed_continue', {
|
|
116
|
+
node: stateOrNodeId,
|
|
117
|
+
transitionsTaken,
|
|
118
|
+
...(error === undefined ? {} : { error }),
|
|
119
|
+
});
|
|
120
|
+
void this.events?.emit('workflow.action.failed_continue', {
|
|
121
|
+
node: stateOrNodeId,
|
|
122
|
+
transitionsTaken,
|
|
123
|
+
...(error === undefined ? {} : { error }),
|
|
124
|
+
});
|
|
125
|
+
this.logger.warn('action failed (continuing)', { node: stateOrNodeId, transitionsTaken, error });
|
|
126
|
+
}
|
|
127
|
+
result(status, finalState, transitionsTaken, reason) {
|
|
128
|
+
return {
|
|
129
|
+
runId: this.runId,
|
|
130
|
+
workflowName: this.workflowName,
|
|
131
|
+
mode: this.mode,
|
|
132
|
+
status,
|
|
133
|
+
finalState,
|
|
134
|
+
transitionsTaken,
|
|
135
|
+
...(reason === undefined ? {} : { reason }),
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
runRecord(metadata) {
|
|
139
|
+
return {
|
|
140
|
+
id: this.runId,
|
|
141
|
+
workflow_name: this.workflowName,
|
|
142
|
+
mode: this.mode,
|
|
143
|
+
status: 'running',
|
|
144
|
+
started_at: this.startedAt,
|
|
145
|
+
metadata_json: JSON.stringify(metadata ?? {}),
|
|
146
|
+
completed_at: null,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
}
|
package/dist/schema-sql.d.ts
CHANGED
package/dist/schema-sql.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema-sql.d.ts","sourceRoot":"","sources":["../src/schema-sql.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,0BAA0B,QA+C/B,CAAC"}
|
|
1
|
+
{"version":3,"file":"schema-sql.d.ts","sourceRoot":"","sources":["../src/schema-sql.ts"],"names":[],"mappings":"AAAA,gIAAgI;AAChI,eAAO,MAAM,0BAA0B,QA+C/B,CAAC"}
|
package/dist/schema-sql.js
CHANGED
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"}
|