@exaudeus/workrail 2.1.0 → 3.0.0

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.
Files changed (58) hide show
  1. package/dist/application/services/compiler/template-registry.d.ts +4 -2
  2. package/dist/application/services/compiler/template-registry.js +97 -5
  3. package/dist/application/services/workflow-compiler.d.ts +5 -1
  4. package/dist/application/services/workflow-compiler.js +20 -7
  5. package/dist/di/container.js +10 -1
  6. package/dist/di/tokens.d.ts +1 -0
  7. package/dist/di/tokens.js +1 -0
  8. package/dist/engine/engine-factory.d.ts +3 -0
  9. package/dist/engine/engine-factory.js +295 -0
  10. package/dist/engine/index.d.ts +3 -0
  11. package/dist/engine/index.js +12 -0
  12. package/dist/engine/types.d.ts +130 -0
  13. package/dist/engine/types.js +18 -0
  14. package/dist/infrastructure/storage/file-workflow-storage.d.ts +1 -0
  15. package/dist/infrastructure/storage/file-workflow-storage.js +10 -0
  16. package/dist/manifest.json +140 -76
  17. package/dist/mcp/handlers/v2-checkpoint.d.ts +31 -1
  18. package/dist/mcp/handlers/v2-checkpoint.js +76 -64
  19. package/dist/mcp/handlers/v2-execution/continue-advance.d.ts +2 -0
  20. package/dist/mcp/handlers/v2-execution/continue-advance.js +5 -5
  21. package/dist/mcp/handlers/v2-execution/continue-rehydrate.d.ts +2 -0
  22. package/dist/mcp/handlers/v2-execution/continue-rehydrate.js +17 -22
  23. package/dist/mcp/handlers/v2-execution/index.d.ts +10 -17
  24. package/dist/mcp/handlers/v2-execution/index.js +44 -54
  25. package/dist/mcp/handlers/v2-execution/replay.d.ts +4 -15
  26. package/dist/mcp/handlers/v2-execution/replay.js +52 -128
  27. package/dist/mcp/handlers/v2-execution/start.d.ts +3 -2
  28. package/dist/mcp/handlers/v2-execution/start.js +18 -46
  29. package/dist/mcp/handlers/v2-token-ops.d.ts +45 -24
  30. package/dist/mcp/handlers/v2-token-ops.js +372 -32
  31. package/dist/mcp/output-schemas.d.ts +104 -283
  32. package/dist/mcp/output-schemas.js +24 -22
  33. package/dist/mcp/server.js +8 -0
  34. package/dist/mcp/types.d.ts +4 -0
  35. package/dist/mcp/v2/tools.d.ts +22 -52
  36. package/dist/mcp/v2/tools.js +18 -32
  37. package/dist/mcp/v2-response-formatter.js +12 -16
  38. package/dist/runtime/runtime-mode.d.ts +2 -0
  39. package/dist/v2/durable-core/domain/prompt-renderer.d.ts +1 -0
  40. package/dist/v2/durable-core/domain/prompt-renderer.js +5 -3
  41. package/dist/v2/durable-core/schemas/export-bundle/index.d.ts +14 -14
  42. package/dist/v2/durable-core/schemas/session/events.d.ts +4 -4
  43. package/dist/v2/durable-core/schemas/session/validation-event.d.ts +2 -2
  44. package/dist/v2/durable-core/tokens/payloads.d.ts +32 -32
  45. package/dist/v2/durable-core/tokens/short-token.d.ts +38 -0
  46. package/dist/v2/durable-core/tokens/short-token.js +126 -0
  47. package/dist/v2/durable-core/tokens/token-patterns.d.ts +4 -0
  48. package/dist/v2/durable-core/tokens/token-patterns.js +9 -0
  49. package/dist/v2/infra/in-memory/token-alias-store/index.d.ts +11 -0
  50. package/dist/v2/infra/in-memory/token-alias-store/index.js +38 -0
  51. package/dist/v2/infra/local/data-dir/index.d.ts +1 -0
  52. package/dist/v2/infra/local/data-dir/index.js +3 -0
  53. package/dist/v2/infra/local/token-alias-store/index.d.ts +16 -0
  54. package/dist/v2/infra/local/token-alias-store/index.js +117 -0
  55. package/dist/v2/ports/data-dir.port.d.ts +1 -0
  56. package/dist/v2/ports/token-alias-store.port.d.ts +33 -0
  57. package/dist/v2/ports/token-alias-store.port.js +2 -0
  58. package/package.json +8 -1
@@ -1,5 +1,5 @@
1
1
  import type { Result } from 'neverthrow';
2
- import type { WorkflowStepDefinition } from '../../../types/workflow-definition.js';
2
+ import type { WorkflowStepDefinition, WorkflowDefinition } from '../../../types/workflow-definition.js';
3
3
  export type TemplateExpander = (callerId: string, args: Readonly<Record<string, unknown>>) => Result<readonly WorkflowStepDefinition[], TemplateExpandError>;
4
4
  export type TemplateExpandError = {
5
5
  readonly code: 'TEMPLATE_EXPAND_FAILED';
@@ -16,4 +16,6 @@ export interface TemplateRegistry {
16
16
  readonly has: (templateId: string) => boolean;
17
17
  readonly knownIds: () => readonly string[];
18
18
  }
19
- export declare function createTemplateRegistry(): TemplateRegistry;
19
+ export declare function createRoutineExpander(routineId: string, definition: WorkflowDefinition): Result<TemplateExpander, TemplateExpandError>;
20
+ export declare function routineIdToTemplateId(routineId: string): string;
21
+ export declare function createTemplateRegistry(routineDefinitions?: ReadonlyMap<string, WorkflowDefinition>): TemplateRegistry;
@@ -1,13 +1,105 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createRoutineExpander = createRoutineExpander;
4
+ exports.routineIdToTemplateId = routineIdToTemplateId;
3
5
  exports.createTemplateRegistry = createTemplateRegistry;
4
6
  const neverthrow_1 = require("neverthrow");
5
- const TEMPLATE_DEFINITIONS = new Map();
6
- function createTemplateRegistry() {
7
- const knownIds = [...TEMPLATE_DEFINITIONS.keys()];
7
+ const SINGLE_BRACE_ARG = /(?<!\{)\{([^{}]+)\}(?!\})/g;
8
+ function substituteArgs(text, args, routineId, stepId) {
9
+ const missing = [];
10
+ const substituted = text.replace(SINGLE_BRACE_ARG, (match, argName) => {
11
+ if (argName in args) {
12
+ return String(args[argName]);
13
+ }
14
+ missing.push(argName);
15
+ return match;
16
+ });
17
+ if (missing.length > 0) {
18
+ return (0, neverthrow_1.err)({
19
+ code: 'TEMPLATE_EXPAND_FAILED',
20
+ templateId: `wr.templates.routine.${routineId}`,
21
+ message: `MISSING_TEMPLATE_ARG: routine '${routineId}' step '${stepId}' references arg(s) '${missing.join("', '")}' but they were not provided in templateCall.args`,
22
+ });
23
+ }
24
+ return (0, neverthrow_1.ok)(substituted);
25
+ }
26
+ function validateNoRecursiveTemplateCall(routineId, steps) {
27
+ for (const step of steps) {
28
+ if (step.templateCall) {
29
+ return (0, neverthrow_1.err)({
30
+ code: 'TEMPLATE_EXPAND_FAILED',
31
+ templateId: `wr.templates.routine.${routineId}`,
32
+ message: `Routine '${routineId}' step '${step.id}' contains a templateCall. Recursive routine injection is not supported.`,
33
+ });
34
+ }
35
+ }
36
+ return (0, neverthrow_1.ok)(undefined);
37
+ }
38
+ function createRoutineExpander(routineId, definition) {
39
+ const routineSteps = definition.steps;
40
+ const recursiveCheck = validateNoRecursiveTemplateCall(routineId, routineSteps);
41
+ if (recursiveCheck.isErr())
42
+ return (0, neverthrow_1.err)(recursiveCheck.error);
43
+ for (const step of routineSteps) {
44
+ if (!step.id || !step.title) {
45
+ return (0, neverthrow_1.err)({
46
+ code: 'TEMPLATE_EXPAND_FAILED',
47
+ templateId: `wr.templates.routine.${routineId}`,
48
+ message: `Routine '${routineId}' step '${step.id ?? '(missing id)'}' is missing required field '${!step.id ? 'id' : 'title'}'.`,
49
+ });
50
+ }
51
+ if (!step.prompt) {
52
+ return (0, neverthrow_1.err)({
53
+ code: 'TEMPLATE_EXPAND_FAILED',
54
+ templateId: `wr.templates.routine.${routineId}`,
55
+ message: `Routine '${routineId}' step '${step.id}' is missing required field 'prompt'.`,
56
+ });
57
+ }
58
+ }
59
+ const routineGuidance = definition.metaGuidance ?? [];
60
+ const expander = (callerId, args) => {
61
+ const expandedSteps = [];
62
+ for (const step of routineSteps) {
63
+ const promptResult = substituteArgs(step.prompt, args, routineId, step.id);
64
+ if (promptResult.isErr())
65
+ return (0, neverthrow_1.err)(promptResult.error);
66
+ const mergedGuidance = routineGuidance.length > 0
67
+ ? [...(step.guidance ?? []), ...routineGuidance]
68
+ : (step.guidance ?? []);
69
+ const expandedStep = {
70
+ id: `${callerId}.${step.id}`,
71
+ title: step.title,
72
+ prompt: promptResult.value,
73
+ ...(step.agentRole !== undefined && { agentRole: step.agentRole }),
74
+ ...(mergedGuidance.length > 0 && { guidance: mergedGuidance }),
75
+ ...(step.requireConfirmation !== undefined && { requireConfirmation: step.requireConfirmation }),
76
+ };
77
+ expandedSteps.push(expandedStep);
78
+ }
79
+ return (0, neverthrow_1.ok)(expandedSteps);
80
+ };
81
+ return (0, neverthrow_1.ok)(expander);
82
+ }
83
+ function routineIdToTemplateId(routineId) {
84
+ const name = routineId.startsWith('routine-') ? routineId.slice('routine-'.length) : routineId;
85
+ return `wr.templates.routine.${name}`;
86
+ }
87
+ const STATIC_TEMPLATE_DEFINITIONS = new Map();
88
+ function createTemplateRegistry(routineDefinitions) {
89
+ const allTemplates = new Map(STATIC_TEMPLATE_DEFINITIONS);
90
+ if (routineDefinitions) {
91
+ for (const [routineId, definition] of routineDefinitions) {
92
+ const templateId = routineIdToTemplateId(routineId);
93
+ const expanderResult = createRoutineExpander(routineId, definition);
94
+ if (expanderResult.isOk()) {
95
+ allTemplates.set(templateId, expanderResult.value);
96
+ }
97
+ }
98
+ }
99
+ const knownIds = [...allTemplates.keys()];
8
100
  return {
9
101
  resolve(templateId) {
10
- const expander = TEMPLATE_DEFINITIONS.get(templateId);
102
+ const expander = allTemplates.get(templateId);
11
103
  if (!expander) {
12
104
  return (0, neverthrow_1.err)({
13
105
  code: 'UNKNOWN_TEMPLATE',
@@ -18,7 +110,7 @@ function createTemplateRegistry() {
18
110
  return (0, neverthrow_1.ok)(expander);
19
111
  },
20
112
  has(templateId) {
21
- return TEMPLATE_DEFINITIONS.has(templateId);
113
+ return allTemplates.has(templateId);
22
114
  },
23
115
  knownIds() {
24
116
  return knownIds;
@@ -2,6 +2,7 @@ import { Workflow, WorkflowStepDefinition, LoopStepDefinition } from '../../type
2
2
  import type { LoopConditionSource } from '../../types/workflow-definition';
3
3
  import type { Result } from 'neverthrow';
4
4
  import { type DomainError } from '../../domain/execution/error';
5
+ import { type TemplateRegistry } from './compiler/template-registry';
5
6
  export interface CompiledLoop {
6
7
  readonly loop: LoopStepDefinition;
7
8
  readonly bodySteps: readonly WorkflowStepDefinition[];
@@ -14,8 +15,11 @@ export interface CompiledWorkflow {
14
15
  readonly compiledLoops: ReadonlyMap<string, CompiledLoop>;
15
16
  readonly loopBodyStepIds: ReadonlySet<string>;
16
17
  }
17
- export declare function resolveDefinitionSteps(steps: readonly (WorkflowStepDefinition | LoopStepDefinition)[], features: readonly string[]): Result<readonly (WorkflowStepDefinition | LoopStepDefinition)[], DomainError>;
18
+ export declare function resolveDefinitionSteps(steps: readonly (WorkflowStepDefinition | LoopStepDefinition)[], features: readonly string[], templateRegistry?: TemplateRegistry): Result<readonly (WorkflowStepDefinition | LoopStepDefinition)[], DomainError>;
18
19
  export declare class WorkflowCompiler {
20
+ private readonly templateRegistry;
21
+ constructor();
22
+ static withTemplateRegistry(registry: TemplateRegistry): WorkflowCompiler;
19
23
  compile(workflow: Workflow): Result<CompiledWorkflow, DomainError>;
20
24
  private deriveConditionSource;
21
25
  private resolveLoopBody;
@@ -5,6 +5,10 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
5
5
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
6
  return c > 3 && r && Object.defineProperty(target, key, r), r;
7
7
  };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var WorkflowCompiler_1;
8
12
  Object.defineProperty(exports, "__esModule", { value: true });
9
13
  exports.WorkflowCompiler = void 0;
10
14
  exports.resolveDefinitionSteps = resolveDefinitionSteps;
@@ -22,9 +26,9 @@ const resolve_templates_1 = require("./compiler/resolve-templates");
22
26
  const template_registry_1 = require("./compiler/template-registry");
23
27
  const _refRegistry = (0, ref_registry_1.createRefRegistry)();
24
28
  const _featureRegistry = (0, feature_registry_1.createFeatureRegistry)();
25
- const _templateRegistry = (0, template_registry_1.createTemplateRegistry)();
26
- function resolveDefinitionSteps(steps, features) {
27
- const templatesResult = (0, resolve_templates_1.resolveTemplatesPass)(steps, _templateRegistry);
29
+ const _defaultTemplateRegistry = (0, template_registry_1.createTemplateRegistry)();
30
+ function resolveDefinitionSteps(steps, features, templateRegistry = _defaultTemplateRegistry) {
31
+ const templatesResult = (0, resolve_templates_1.resolveTemplatesPass)(steps, templateRegistry);
28
32
  if (templatesResult.isErr()) {
29
33
  const e = templatesResult.error;
30
34
  const message = e.code === 'TEMPLATE_RESOLVE_ERROR'
@@ -55,9 +59,17 @@ function resolveDefinitionSteps(steps, features) {
55
59
  }
56
60
  return (0, neverthrow_1.ok)(blocksResult.value);
57
61
  }
58
- let WorkflowCompiler = class WorkflowCompiler {
62
+ let WorkflowCompiler = WorkflowCompiler_1 = class WorkflowCompiler {
63
+ constructor() {
64
+ this.templateRegistry = _defaultTemplateRegistry;
65
+ }
66
+ static withTemplateRegistry(registry) {
67
+ const compiler = new WorkflowCompiler_1();
68
+ compiler.templateRegistry = registry;
69
+ return compiler;
70
+ }
59
71
  compile(workflow) {
60
- const resolvedResult = resolveDefinitionSteps(workflow.definition.steps, workflow.definition.features ?? []);
72
+ const resolvedResult = resolveDefinitionSteps(workflow.definition.steps, workflow.definition.features ?? [], this.templateRegistry);
61
73
  if (resolvedResult.isErr())
62
74
  return (0, neverthrow_1.err)(resolvedResult.error);
63
75
  const steps = resolvedResult.value;
@@ -158,6 +170,7 @@ let WorkflowCompiler = class WorkflowCompiler {
158
170
  }
159
171
  };
160
172
  exports.WorkflowCompiler = WorkflowCompiler;
161
- exports.WorkflowCompiler = WorkflowCompiler = __decorate([
162
- (0, tsyringe_1.singleton)()
173
+ exports.WorkflowCompiler = WorkflowCompiler = WorkflowCompiler_1 = __decorate([
174
+ (0, tsyringe_1.singleton)(),
175
+ __metadata("design:paramtypes", [])
163
176
  ], WorkflowCompiler);
@@ -86,6 +86,7 @@ function detectRuntimeMode() {
86
86
  function toProcessLifecyclePolicy(mode) {
87
87
  switch (mode.kind) {
88
88
  case 'test':
89
+ case 'library':
89
90
  return { kind: 'no_signal_handlers' };
90
91
  case 'cli':
91
92
  case 'rpc':
@@ -103,7 +104,7 @@ function registerRuntime(options = {}) {
103
104
  const signals = policy.kind === 'no_signal_handlers' ? new noop_process_signals_js_1.NoopProcessSignals() : new node_process_signals_js_1.NodeProcessSignals();
104
105
  tsyringe_1.container.register(tokens_js_1.DI.Runtime.ProcessSignals, { useValue: signals });
105
106
  tsyringe_1.container.register(tokens_js_1.DI.Runtime.ShutdownEvents, { useValue: new in_memory_shutdown_events_js_1.InMemoryShutdownEvents() });
106
- const terminator = mode.kind === 'test' ? new throwing_process_terminator_js_1.ThrowingProcessTerminator() : new node_process_terminator_js_1.NodeProcessTerminator();
107
+ const terminator = (mode.kind === 'test' || mode.kind === 'library') ? new throwing_process_terminator_js_1.ThrowingProcessTerminator() : new node_process_terminator_js_1.NodeProcessTerminator();
107
108
  tsyringe_1.container.register(tokens_js_1.DI.Runtime.ProcessTerminator, { useValue: terminator });
108
109
  }
109
110
  async function registerStorageChain() {
@@ -221,6 +222,7 @@ async function registerV2Services() {
221
222
  }),
222
223
  });
223
224
  const { LocalKeyringV2 } = await Promise.resolve().then(() => __importStar(require('../v2/infra/local/keyring/index.js')));
225
+ const { LocalTokenAliasStoreV2 } = await Promise.resolve().then(() => __importStar(require('../v2/infra/local/token-alias-store/index.js')));
224
226
  const { LocalSessionEventLogStoreV2 } = await Promise.resolve().then(() => __importStar(require('../v2/infra/local/session-store/index.js')));
225
227
  const { LocalSnapshotStoreV2 } = await Promise.resolve().then(() => __importStar(require('../v2/infra/local/snapshot-store/index.js')));
226
228
  const { LocalPinnedWorkflowStoreV2 } = await Promise.resolve().then(() => __importStar(require('../v2/infra/local/pinned-workflow-store/index.js')));
@@ -234,6 +236,13 @@ async function registerV2Services() {
234
236
  return new LocalKeyringV2(dataDir, fs, base64url, entropy);
235
237
  }),
236
238
  });
239
+ tsyringe_1.container.register(tokens_js_1.DI.V2.TokenAliasStore, {
240
+ useFactory: (0, tsyringe_1.instanceCachingFactory)((c) => {
241
+ const dataDir = c.resolve(tokens_js_1.DI.V2.DataDir);
242
+ const fs = c.resolve(tokens_js_1.DI.V2.FileSystem);
243
+ return new LocalTokenAliasStoreV2(dataDir, fs);
244
+ }),
245
+ });
237
246
  tsyringe_1.container.register(tokens_js_1.DI.V2.SessionStore, {
238
247
  useFactory: (0, tsyringe_1.instanceCachingFactory)((c) => {
239
248
  const dataDir = c.resolve(tokens_js_1.DI.V2.DataDir);
@@ -38,6 +38,7 @@ export declare const DI: {
38
38
  readonly SnapshotStore: symbol;
39
39
  readonly PinnedWorkflowStore: symbol;
40
40
  readonly SessionLock: symbol;
41
+ readonly TokenAliasStore: symbol;
41
42
  readonly ExecutionGate: symbol;
42
43
  };
43
44
  readonly Runtime: {
package/dist/di/tokens.js CHANGED
@@ -41,6 +41,7 @@ exports.DI = {
41
41
  SnapshotStore: Symbol('V2.SnapshotStore'),
42
42
  PinnedWorkflowStore: Symbol('V2.PinnedWorkflowStore'),
43
43
  SessionLock: Symbol('V2.SessionLock'),
44
+ TokenAliasStore: Symbol('V2.TokenAliasStore'),
44
45
  ExecutionGate: Symbol('V2.ExecutionGate'),
45
46
  },
46
47
  Runtime: {
@@ -0,0 +1,3 @@
1
+ import 'reflect-metadata';
2
+ import type { EngineConfig, EngineResult, WorkRailEngine } from './types.js';
3
+ export declare function createWorkRailEngine(config?: EngineConfig): Promise<EngineResult<WorkRailEngine>>;
@@ -0,0 +1,295 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createWorkRailEngine = createWorkRailEngine;
4
+ require("reflect-metadata");
5
+ const container_js_1 = require("../di/container.js");
6
+ const tokens_js_1 = require("../di/tokens.js");
7
+ const token_codec_ports_js_1 = require("../v2/durable-core/tokens/token-codec-ports.js");
8
+ const validation_js_1 = require("../application/validation.js");
9
+ const v1_to_v2_shim_js_1 = require("../v2/read-only/v1-to-v2-shim.js");
10
+ const feature_flags_js_1 = require("../config/feature-flags.js");
11
+ const index_js_1 = require("../v2/infra/local/data-dir/index.js");
12
+ const start_js_1 = require("../mcp/handlers/v2-execution/start.js");
13
+ const index_js_2 = require("../mcp/handlers/v2-execution/index.js");
14
+ const v2_checkpoint_js_1 = require("../mcp/handlers/v2-checkpoint.js");
15
+ const types_js_1 = require("./types.js");
16
+ async function safeAsync(fn) {
17
+ try {
18
+ return (0, types_js_1.engineOk)(await fn());
19
+ }
20
+ catch (e) {
21
+ return (0, types_js_1.engineErr)({
22
+ kind: 'storage_error',
23
+ message: e instanceof Error ? e.message : String(e),
24
+ });
25
+ }
26
+ }
27
+ function mapStartError(e) {
28
+ switch (e.kind) {
29
+ case 'workflow_not_found':
30
+ return { kind: 'workflow_not_found', workflowId: e.workflowId };
31
+ case 'workflow_has_no_steps':
32
+ return { kind: 'workflow_has_no_steps', workflowId: e.workflowId };
33
+ case 'workflow_compile_failed':
34
+ return { kind: 'workflow_compile_failed', message: e.message };
35
+ case 'token_signing_failed':
36
+ return { kind: 'token_signing_failed', message: String(e.cause) };
37
+ case 'prompt_render_failed':
38
+ return { kind: 'prompt_render_failed', message: e.message };
39
+ case 'precondition_failed':
40
+ return { kind: 'precondition_failed', message: e.message };
41
+ case 'invariant_violation':
42
+ return { kind: 'internal_error', message: e.message };
43
+ case 'validation_failed':
44
+ return { kind: 'validation_failed', message: e.failure.message };
45
+ case 'keyring_load_failed':
46
+ return { kind: 'internal_error', message: e.cause.message, code: e.cause.code };
47
+ case 'hash_computation_failed':
48
+ return { kind: 'internal_error', message: e.message };
49
+ case 'pinned_workflow_store_failed':
50
+ return { kind: 'storage_error', message: e.cause.message, code: e.cause.code };
51
+ case 'snapshot_creation_failed':
52
+ return { kind: 'storage_error', message: e.cause.message, code: e.cause.code };
53
+ case 'session_append_failed':
54
+ return { kind: 'session_error', message: e.cause.message, code: e.cause.code };
55
+ }
56
+ }
57
+ function mapContinueError(e) {
58
+ switch (e.kind) {
59
+ case 'precondition_failed':
60
+ return { kind: 'precondition_failed', message: e.message };
61
+ case 'token_unknown_node':
62
+ return { kind: 'token_invalid', message: e.message };
63
+ case 'invariant_violation':
64
+ return { kind: 'internal_error', message: e.message };
65
+ case 'validation_failed':
66
+ return { kind: 'validation_failed', message: e.failure.message };
67
+ case 'token_decode_failed':
68
+ return { kind: 'token_invalid', message: e.cause.message, code: e.cause.code };
69
+ case 'token_verify_failed':
70
+ return { kind: 'token_invalid', message: e.cause.message, code: e.cause.code };
71
+ case 'keyring_load_failed':
72
+ return { kind: 'internal_error', message: e.cause.message, code: e.cause.code };
73
+ case 'session_load_failed':
74
+ return { kind: 'session_error', message: e.cause.message, code: e.cause.code };
75
+ case 'snapshot_load_failed':
76
+ return { kind: 'storage_error', message: e.cause.message, code: e.cause.code };
77
+ case 'pinned_workflow_store_failed':
78
+ return { kind: 'storage_error', message: e.cause.message, code: e.cause.code };
79
+ case 'pinned_workflow_missing':
80
+ return { kind: 'storage_error', message: `Pinned workflow missing: ${e.workflowHash}` };
81
+ case 'token_signing_failed':
82
+ return { kind: 'token_signing_failed', message: String(e.cause) };
83
+ case 'advance_execution_failed':
84
+ return { kind: 'session_error', message: e.cause.message, code: e.cause.code };
85
+ case 'prompt_render_failed':
86
+ return { kind: 'prompt_render_failed', message: e.message };
87
+ }
88
+ }
89
+ function mapCheckpointError(e) {
90
+ switch (e.kind) {
91
+ case 'precondition_failed':
92
+ return { kind: 'precondition_failed', message: e.message };
93
+ case 'token_signing_failed':
94
+ return { kind: 'token_signing_failed', message: String(e.cause) };
95
+ case 'validation_failed':
96
+ return { kind: 'validation_failed', message: e.failure.message };
97
+ case 'missing_node_or_run':
98
+ return { kind: 'session_error', message: 'Node or run not found in session events' };
99
+ case 'event_schema_invalid':
100
+ return { kind: 'internal_error', message: `Event schema invalid: ${e.issues}` };
101
+ case 'gate_failed':
102
+ return { kind: 'session_error', message: e.cause.message, code: e.cause.code };
103
+ case 'store_failed':
104
+ return { kind: 'storage_error', message: e.cause.message, code: e.cause.code };
105
+ }
106
+ }
107
+ function mapPending(raw) {
108
+ if (!raw)
109
+ return null;
110
+ return {
111
+ stepId: raw.stepId,
112
+ title: raw.title,
113
+ prompt: raw.prompt,
114
+ ...(raw.agentRole ? { agentRole: raw.agentRole } : {}),
115
+ };
116
+ }
117
+ function mapStartOutput(out) {
118
+ const ct = out.continueToken ?? '';
119
+ return {
120
+ kind: 'ok',
121
+ stateToken: (0, types_js_1.asStateToken)(ct),
122
+ ackToken: (0, types_js_1.asAckToken)(ct),
123
+ checkpointToken: out.checkpointToken ? (0, types_js_1.asCheckpointToken)(out.checkpointToken) : null,
124
+ isComplete: out.isComplete,
125
+ pending: mapPending(out.pending),
126
+ preferences: out.preferences,
127
+ nextIntent: out.nextIntent,
128
+ };
129
+ }
130
+ function mapContinueOutput(out) {
131
+ const ct = out.continueToken ?? '';
132
+ const base = {
133
+ stateToken: (0, types_js_1.asStateToken)(ct),
134
+ ackToken: (0, types_js_1.asAckToken)(ct),
135
+ checkpointToken: out.checkpointToken ? (0, types_js_1.asCheckpointToken)(out.checkpointToken) : null,
136
+ isComplete: out.isComplete,
137
+ pending: mapPending(out.pending),
138
+ preferences: out.preferences,
139
+ nextIntent: out.nextIntent,
140
+ };
141
+ if (out.kind === 'blocked') {
142
+ const blocked = {
143
+ kind: 'blocked',
144
+ ...base,
145
+ blockers: out.blockers.blockers.map(b => ({
146
+ code: b.code,
147
+ message: b.message,
148
+ ...(b.suggestedFix ? { suggestedFix: b.suggestedFix } : {}),
149
+ })),
150
+ retryable: out.retryable ?? false,
151
+ retryAckToken: out.retryContinueToken ? (0, types_js_1.asAckToken)(out.retryContinueToken) : null,
152
+ };
153
+ return blocked;
154
+ }
155
+ return { kind: 'ok', ...base };
156
+ }
157
+ let engineActive = false;
158
+ async function createWorkRailEngine(config = {}) {
159
+ if (engineActive) {
160
+ return (0, types_js_1.engineErr)({
161
+ kind: 'precondition_failed',
162
+ message: 'An engine is already active. Call engine.close() before creating another instance.',
163
+ });
164
+ }
165
+ await (0, container_js_1.initializeContainer)({ runtimeMode: { kind: 'library' } });
166
+ if (config.dataDir) {
167
+ const customEnv = { ...process.env, WORKRAIL_DATA_DIR: config.dataDir };
168
+ container_js_1.container.register(tokens_js_1.DI.V2.DataDir, { useValue: new index_js_1.LocalDataDirV2(customEnv) });
169
+ }
170
+ const workflowService = container_js_1.container.resolve(tokens_js_1.DI.Services.Workflow);
171
+ const gate = container_js_1.container.resolve(tokens_js_1.DI.V2.ExecutionGate);
172
+ const sessionStore = container_js_1.container.resolve(tokens_js_1.DI.V2.SessionStore);
173
+ const snapshotStore = container_js_1.container.resolve(tokens_js_1.DI.V2.SnapshotStore);
174
+ const pinnedStore = container_js_1.container.resolve(tokens_js_1.DI.V2.PinnedWorkflowStore);
175
+ const keyringPort = container_js_1.container.resolve(tokens_js_1.DI.V2.Keyring);
176
+ const keyringResult = await keyringPort.loadOrCreate();
177
+ if (keyringResult.isErr()) {
178
+ (0, container_js_1.resetContainer)();
179
+ return (0, types_js_1.engineErr)({
180
+ kind: 'internal_error',
181
+ message: keyringResult.error.message,
182
+ code: keyringResult.error.code,
183
+ });
184
+ }
185
+ const sha256 = container_js_1.container.resolve(tokens_js_1.DI.V2.Sha256);
186
+ const crypto = container_js_1.container.resolve(tokens_js_1.DI.V2.Crypto);
187
+ const entropy = container_js_1.container.resolve(tokens_js_1.DI.V2.RandomEntropy);
188
+ const hmac = container_js_1.container.resolve(tokens_js_1.DI.V2.HmacSha256);
189
+ const base64url = container_js_1.container.resolve(tokens_js_1.DI.V2.Base64Url);
190
+ const base32 = container_js_1.container.resolve(tokens_js_1.DI.V2.Base32);
191
+ const bech32m = container_js_1.container.resolve(tokens_js_1.DI.V2.Bech32m);
192
+ const idFactory = container_js_1.container.resolve(tokens_js_1.DI.V2.IdFactory);
193
+ const tokenCodecPorts = (0, token_codec_ports_js_1.unsafeTokenCodecPorts)({
194
+ keyring: keyringResult.value,
195
+ hmac,
196
+ base64url,
197
+ base32,
198
+ bech32m,
199
+ });
200
+ const validationEngine = container_js_1.container.resolve(tokens_js_1.DI.Infra.ValidationEngine);
201
+ const compiler = container_js_1.container.resolve(tokens_js_1.DI.Services.WorkflowCompiler);
202
+ const validationPipelineDeps = {
203
+ schemaValidate: validation_js_1.validateWorkflowSchema,
204
+ structuralValidate: validationEngine.validateWorkflowStructureOnly.bind(validationEngine),
205
+ compiler,
206
+ normalizeToExecutable: v1_to_v2_shim_js_1.normalizeV1WorkflowToPinnedSnapshot,
207
+ };
208
+ const dataDir = container_js_1.container.resolve(tokens_js_1.DI.V2.DataDir);
209
+ const tokenAliasStore = container_js_1.container.resolve(tokens_js_1.DI.V2.TokenAliasStore);
210
+ const aliasLoadResult = await tokenAliasStore.loadIndex();
211
+ if (aliasLoadResult.isErr()) {
212
+ console.error(`[engine-factory] Token alias index load warning: ${aliasLoadResult.error.message}`);
213
+ }
214
+ const v2 = {
215
+ gate,
216
+ sessionStore,
217
+ snapshotStore,
218
+ pinnedStore,
219
+ sha256,
220
+ crypto,
221
+ entropy,
222
+ idFactory,
223
+ tokenCodecPorts,
224
+ tokenAliasStore,
225
+ validationPipelineDeps,
226
+ resolvedRootUris: [],
227
+ dataDir,
228
+ };
229
+ const featureFlags = new feature_flags_js_1.StaticFeatureFlagProvider({ v2Tools: true });
230
+ const ctx = {
231
+ workflowService,
232
+ featureFlags,
233
+ sessionManager: null,
234
+ httpServer: null,
235
+ v2,
236
+ };
237
+ const v2Ctx = ctx;
238
+ engineActive = true;
239
+ const engine = {
240
+ async startWorkflow(workflowId) {
241
+ const result = await (0, start_js_1.executeStartWorkflow)({ workflowId }, v2Ctx);
242
+ if (result.isErr()) {
243
+ return (0, types_js_1.engineErr)(mapStartError(result.error));
244
+ }
245
+ return (0, types_js_1.engineOk)(mapStartOutput(result.value));
246
+ },
247
+ async continueWorkflow(stateToken, ackToken, output, context) {
248
+ const intent = ackToken ? 'advance' : 'rehydrate';
249
+ const input = {
250
+ continueToken: (0, types_js_1.unwrapToken)(stateToken),
251
+ intent: intent,
252
+ ...(output ? {
253
+ output: {
254
+ notesMarkdown: output.notesMarkdown,
255
+ ...(output.artifacts?.length ? { artifacts: [...output.artifacts] } : {}),
256
+ },
257
+ } : {}),
258
+ ...(context ? { context } : {}),
259
+ };
260
+ const result = await (0, index_js_2.executeContinueWorkflow)(input, v2Ctx);
261
+ if (result.isErr()) {
262
+ return (0, types_js_1.engineErr)(mapContinueError(result.error));
263
+ }
264
+ return (0, types_js_1.engineOk)(mapContinueOutput(result.value));
265
+ },
266
+ async checkpointWorkflow(checkpointToken) {
267
+ const result = await (0, v2_checkpoint_js_1.executeCheckpoint)({ checkpointToken: (0, types_js_1.unwrapToken)(checkpointToken) }, v2Ctx);
268
+ if (result.isErr()) {
269
+ return (0, types_js_1.engineErr)(mapCheckpointError(result.error));
270
+ }
271
+ return (0, types_js_1.engineOk)({
272
+ checkpointNodeId: result.value.checkpointNodeId,
273
+ stateToken: (0, types_js_1.asStateToken)(result.value.stateToken),
274
+ });
275
+ },
276
+ async listWorkflows() {
277
+ const result = await safeAsync(() => workflowService.listWorkflowSummaries());
278
+ if (!result.ok)
279
+ return result;
280
+ return (0, types_js_1.engineOk)({
281
+ workflows: result.value.map((s) => ({
282
+ workflowId: s.id,
283
+ name: s.name,
284
+ description: s.description,
285
+ version: s.version,
286
+ })),
287
+ });
288
+ },
289
+ async close() {
290
+ (0, container_js_1.resetContainer)();
291
+ engineActive = false;
292
+ },
293
+ };
294
+ return (0, types_js_1.engineOk)(engine);
295
+ }
@@ -0,0 +1,3 @@
1
+ export { createWorkRailEngine } from './engine-factory.js';
2
+ export type { WorkRailEngine, EngineConfig, EngineResult, EngineError, InfraErrorCode, StepResponse, StepResponseOk, StepResponseBlocked, CheckpointResponse, WorkflowListResponse, WorkflowListItem, PendingStep, StepPreferences, Autonomy, RiskPolicy, NextIntent, Blocker, BlockerCode, StateToken, AckToken, CheckpointToken, } from './types.js';
3
+ export { engineOk, engineErr, asStateToken, asAckToken, asCheckpointToken, unwrapToken } from './types.js';
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.unwrapToken = exports.asCheckpointToken = exports.asAckToken = exports.asStateToken = exports.engineErr = exports.engineOk = exports.createWorkRailEngine = void 0;
4
+ var engine_factory_js_1 = require("./engine-factory.js");
5
+ Object.defineProperty(exports, "createWorkRailEngine", { enumerable: true, get: function () { return engine_factory_js_1.createWorkRailEngine; } });
6
+ var types_js_1 = require("./types.js");
7
+ Object.defineProperty(exports, "engineOk", { enumerable: true, get: function () { return types_js_1.engineOk; } });
8
+ Object.defineProperty(exports, "engineErr", { enumerable: true, get: function () { return types_js_1.engineErr; } });
9
+ Object.defineProperty(exports, "asStateToken", { enumerable: true, get: function () { return types_js_1.asStateToken; } });
10
+ Object.defineProperty(exports, "asAckToken", { enumerable: true, get: function () { return types_js_1.asAckToken; } });
11
+ Object.defineProperty(exports, "asCheckpointToken", { enumerable: true, get: function () { return types_js_1.asCheckpointToken; } });
12
+ Object.defineProperty(exports, "unwrapToken", { enumerable: true, get: function () { return types_js_1.unwrapToken; } });