@exaudeus/workrail 1.5.1 → 1.5.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.
Files changed (44) hide show
  1. package/dist/application/services/workflow-compiler.js +14 -2
  2. package/dist/infrastructure/session/HttpServer.js +7 -2
  3. package/dist/infrastructure/session/SessionManager.d.ts +12 -4
  4. package/dist/infrastructure/session/SessionManager.js +30 -15
  5. package/dist/manifest.json +74 -74
  6. package/dist/mcp/error-mapper.d.ts +1 -1
  7. package/dist/mcp/error-mapper.js +12 -8
  8. package/dist/mcp/handler-factory.js +8 -1
  9. package/dist/mcp/handlers/session.js +36 -58
  10. package/dist/mcp/handlers/v2-advance-core/index.js +27 -8
  11. package/dist/mcp/handlers/v2-checkpoint.js +6 -10
  12. package/dist/mcp/handlers/v2-error-mapping.d.ts +3 -3
  13. package/dist/mcp/handlers/v2-error-mapping.js +31 -27
  14. package/dist/mcp/handlers/v2-execution/continue-advance.js +3 -6
  15. package/dist/mcp/handlers/v2-execution/continue-rehydrate.js +0 -1
  16. package/dist/mcp/handlers/v2-execution/index.d.ts +9 -1
  17. package/dist/mcp/handlers/v2-execution/index.js +8 -19
  18. package/dist/mcp/handlers/v2-execution/replay.js +2 -4
  19. package/dist/mcp/handlers/v2-execution/start.d.ts +2 -2
  20. package/dist/mcp/handlers/v2-execution/start.js +0 -19
  21. package/dist/mcp/handlers/v2-execution-helpers.d.ts +3 -2
  22. package/dist/mcp/handlers/v2-execution-helpers.js +34 -59
  23. package/dist/mcp/handlers/v2-workflow.js +13 -18
  24. package/dist/mcp/output-schemas.d.ts +197 -34
  25. package/dist/mcp/output-schemas.js +12 -5
  26. package/dist/mcp/tool-descriptions.js +22 -16
  27. package/dist/mcp/types.d.ts +10 -0
  28. package/dist/mcp/types.js +10 -0
  29. package/dist/mcp/v2/tools.d.ts +45 -7
  30. package/dist/mcp/v2/tools.js +7 -3
  31. package/dist/types/workflow-definition.d.ts +3 -2
  32. package/dist/v2/durable-core/canonical/jcs.js +8 -1
  33. package/dist/v2/durable-core/domain/ack-advance-append-plan.d.ts +1 -10
  34. package/dist/v2/durable-core/domain/ack-advance-append-plan.js +8 -28
  35. package/dist/v2/durable-core/domain/blocked-node-builder.js +1 -1
  36. package/dist/v2/durable-core/schemas/artifacts/loop-control.d.ts +6 -6
  37. package/dist/v2/durable-core/schemas/execution-snapshot/blocked-snapshot.d.ts +4 -4
  38. package/dist/v2/durable-core/schemas/execution-snapshot/execution-snapshot.v1.d.ts +116 -116
  39. package/dist/v2/durable-core/schemas/export-bundle/index.d.ts +184 -184
  40. package/dist/v2/durable-core/schemas/session/dag-topology.d.ts +2 -2
  41. package/dist/v2/durable-core/schemas/session/events.d.ts +20 -20
  42. package/package.json +1 -1
  43. package/workflows/coding-task-workflow-agentic.json +0 -9
  44. package/workflows/workflow-for-workflows.json +18 -5
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.defaultPreferences = void 0;
4
+ exports.internalSuggestion = internalSuggestion;
4
5
  exports.mapStartWorkflowErrorToToolError = mapStartWorkflowErrorToToolError;
5
6
  exports.mapContinueWorkflowErrorToToolError = mapContinueWorkflowErrorToToolError;
6
7
  exports.mapTokenDecodeErrorToToolError = mapTokenDecodeErrorToToolError;
@@ -16,28 +17,30 @@ exports.renderPendingPromptOrDefault = renderPendingPromptOrDefault;
16
17
  exports.derivePreferencesOrDefault = derivePreferencesOrDefault;
17
18
  const types_js_1 = require("../types.js");
18
19
  const types_js_2 = require("../types.js");
20
+ const ESCALATION_SUFFIX = ' To report this, share the name of the tool you called, the input you provided, and this error message with the user so they can forward it to the WorkRail developer.';
21
+ function internalSuggestion(retryAdvice, userMessage) {
22
+ return `${retryAdvice} If the error persists, tell the user: "${userMessage}"${ESCALATION_SUFFIX}`;
23
+ }
19
24
  function mapStartWorkflowErrorToToolError(e) {
20
25
  switch (e.kind) {
21
26
  case 'precondition_failed':
22
27
  return (0, types_js_1.errNotRetryable)('PRECONDITION_FAILED', e.message, e.suggestion ? { suggestion: e.suggestion } : undefined);
23
28
  case 'invariant_violation':
24
- return (0, types_js_1.errNotRetryable)('INTERNAL_ERROR', e.message, e.suggestion ? { suggestion: e.suggestion } : undefined);
29
+ return (0, types_js_1.errNotRetryable)('INTERNAL_ERROR', 'WorkRail encountered an unexpected error while starting the workflow. This is not caused by your input.', { suggestion: internalSuggestion('Retry start_workflow.', 'WorkRail has an internal error.') });
25
30
  case 'validation_failed':
26
31
  return e.failure;
27
32
  case 'workflow_not_found':
28
33
  return (0, types_js_1.errNotRetryable)('NOT_FOUND', `Workflow not found: ${e.workflowId}`, {
29
- suggestion: 'Use list_workflows to discover available workflows.',
34
+ suggestion: 'Call list_workflows to see available workflows and verify the workflowId.',
30
35
  });
31
36
  case 'workflow_has_no_steps':
32
- return (0, types_js_1.errNotRetryable)('PRECONDITION_FAILED', 'Workflow has no steps and cannot be started.', {
33
- suggestion: 'Fix the workflow definition (must contain at least one step).',
37
+ return (0, types_js_1.errNotRetryable)('PRECONDITION_FAILED', `Workflow "${e.workflowId}" has no steps and cannot be started.`, {
38
+ suggestion: 'Tell the user: "This workflow definition is empty (no steps). The workflow JSON file needs to be fixed."',
34
39
  });
35
40
  case 'keyring_load_failed':
36
41
  return mapKeyringErrorToToolError(e.cause);
37
42
  case 'hash_computation_failed':
38
- return (0, types_js_1.errNotRetryable)('INTERNAL_ERROR', `Failed to compute workflow hash: ${e.message}`, {
39
- suggestion: 'Retry start_workflow; if this persists, treat as invariant violation.',
40
- });
43
+ return (0, types_js_1.errNotRetryable)('INTERNAL_ERROR', 'WorkRail could not compute a content hash for the workflow definition. This is not caused by your input.', { suggestion: internalSuggestion('Retry start_workflow.', 'WorkRail has an internal error computing workflow hashes.') });
41
44
  case 'pinned_workflow_store_failed':
42
45
  return mapPinnedWorkflowStoreErrorToToolError(e.cause);
43
46
  case 'snapshot_creation_failed':
@@ -58,7 +61,7 @@ function mapContinueWorkflowErrorToToolError(e) {
58
61
  case 'token_unknown_node':
59
62
  return (0, types_js_1.errNotRetryable)('TOKEN_UNKNOWN_NODE', e.message, e.suggestion ? { suggestion: e.suggestion } : undefined);
60
63
  case 'invariant_violation':
61
- return (0, types_js_1.errNotRetryable)('INTERNAL_ERROR', e.message, e.suggestion ? { suggestion: e.suggestion } : undefined);
64
+ return (0, types_js_1.errNotRetryable)('INTERNAL_ERROR', 'WorkRail encountered an unexpected error while continuing the workflow. This is not caused by your input.', { suggestion: internalSuggestion('Retry continue_workflow.', 'WorkRail has an internal error.') });
62
65
  case 'validation_failed':
63
66
  return e.failure;
64
67
  case 'token_decode_failed':
@@ -74,9 +77,7 @@ function mapContinueWorkflowErrorToToolError(e) {
74
77
  case 'pinned_workflow_store_failed':
75
78
  return mapPinnedWorkflowStoreErrorToToolError(e.cause);
76
79
  case 'pinned_workflow_missing':
77
- return (0, types_js_1.errNotRetryable)('PRECONDITION_FAILED', `Pinned workflow snapshot is missing for hash: ${e.workflowHash}`, {
78
- suggestion: 'Re-run start_workflow or re-pin the workflow via inspect_workflow.',
79
- });
80
+ return (0, types_js_1.errNotRetryable)('PRECONDITION_FAILED', 'The stored workflow definition for this session is missing. The session may have been created with a different WorkRail data directory.', { suggestion: 'Call start_workflow again to create a fresh session for this workflow.' });
80
81
  case 'token_signing_failed':
81
82
  return mapTokenSigningErrorToToolError(e.cause);
82
83
  case 'advance_execution_failed':
@@ -160,13 +161,9 @@ function mapTokenSigningErrorToToolError(e) {
160
161
  suggestion: 'Use the exact tokens returned by WorkRail.',
161
162
  });
162
163
  case 'TOKEN_ENCODE_FAILED':
163
- return (0, types_js_1.errNotRetryable)('INTERNAL_ERROR', `Token encoding failed: ${e.message}`, {
164
- suggestion: 'Retry; if this persists, treat as invariant violation.',
165
- });
164
+ return (0, types_js_1.errNotRetryable)('INTERNAL_ERROR', 'WorkRail could not create a security token for this operation. This is not caused by your input.', { suggestion: internalSuggestion('Retry the call.', 'WorkRail has an internal error creating tokens.') });
166
165
  case 'KEYRING_INVALID':
167
- return (0, types_js_1.errNotRetryable)('INTERNAL_ERROR', `Keyring invalid: ${e.message}`, {
168
- suggestion: 'Regenerate v2 keyring by deleting the v2 data directory and retrying.',
169
- });
166
+ return (0, types_js_1.errNotRetryable)('INTERNAL_ERROR', 'WorkRail\'s security keys are in an invalid state and cannot sign tokens.', { suggestion: internalSuggestion('', 'WorkRail\'s security keys need to be regenerated. Delete the .workrail/v2 data directory and restart.') });
170
167
  case 'TOKEN_BAD_SIGNATURE':
171
168
  return (0, types_js_1.errNotRetryable)('TOKEN_BAD_SIGNATURE', e.message, {
172
169
  suggestion: 'Token signature verification failed. Use the exact tokens returned by WorkRail.',
@@ -183,17 +180,11 @@ function mapTokenSigningErrorToToolError(e) {
183
180
  function mapKeyringErrorToToolError(e) {
184
181
  switch (e.code) {
185
182
  case 'KEYRING_IO_ERROR':
186
- return (0, types_js_1.errNotRetryable)('INTERNAL_ERROR', `Keyring I/O error: ${e.message}`, {
187
- suggestion: 'Retry; check filesystem permissions. If this persists, treat as invariant violation.',
188
- });
183
+ return (0, types_js_1.errNotRetryable)('INTERNAL_ERROR', 'WorkRail could not read its security keys from disk.', { suggestion: internalSuggestion('Retry the call.', 'WorkRail cannot access its security keys. Check that the ~/.workrail directory is readable.') });
189
184
  case 'KEYRING_CORRUPTION_DETECTED':
190
- return (0, types_js_1.errNotRetryable)('INTERNAL_ERROR', `Keyring corruption detected: ${e.message}`, {
191
- suggestion: 'Delete the WorkRail v2 data directory for this repo and retry.',
192
- });
185
+ return (0, types_js_1.errNotRetryable)('INTERNAL_ERROR', 'WorkRail\'s security keys are corrupted and cannot be used.', { suggestion: internalSuggestion('', 'WorkRail\'s security keys are corrupted. Delete the .workrail/v2 directory and restart WorkRail to regenerate them.') });
193
186
  case 'KEYRING_INVARIANT_VIOLATION':
194
- return (0, types_js_1.errNotRetryable)('INTERNAL_ERROR', `Keyring invariant violation: ${e.message}`, {
195
- suggestion: 'Treat as invariant violation.',
196
- });
187
+ return (0, types_js_1.errNotRetryable)('INTERNAL_ERROR', 'WorkRail\'s security key system encountered an unexpected error. This is not caused by your input.', { suggestion: internalSuggestion('', 'WorkRail has an internal error with its security keys.') });
197
188
  default:
198
189
  const _exhaustive = e;
199
190
  return _exhaustive;
@@ -202,22 +193,16 @@ function mapKeyringErrorToToolError(e) {
202
193
  function mapSessionEventLogStoreErrorToToolError(e) {
203
194
  switch (e.code) {
204
195
  case 'SESSION_STORE_LOCK_BUSY':
205
- return (0, types_js_1.errRetryAfterMs)('INTERNAL_ERROR', e.message, e.retry.afterMs, {
206
- suggestion: 'Another WorkRail process may be writing to this session; retry.',
207
- });
196
+ return (0, types_js_1.errRetryAfterMs)('INTERNAL_ERROR', 'The session is temporarily busy (another operation is in progress).', e.retry.afterMs, { suggestion: internalSuggestion('Retry this call in a few seconds.', 'Another WorkRail process may be accessing this session.') });
208
197
  case 'SESSION_STORE_CORRUPTION_DETECTED':
209
- return (0, types_js_1.errNotRetryable)('SESSION_NOT_HEALTHY', `Session corruption detected: ${e.reason.code}`, {
210
- suggestion: 'Execution requires a healthy session. Export salvage view, then recreate.',
198
+ return (0, types_js_1.errNotRetryable)('SESSION_NOT_HEALTHY', 'This session\'s data is corrupted and cannot be used.', {
199
+ suggestion: `This session cannot be recovered. Call start_workflow to create a new session for this workflow.${ESCALATION_SUFFIX}`,
211
200
  details: (0, types_js_2.detailsSessionHealth)({ kind: e.location === 'head' ? 'corrupt_head' : 'corrupt_tail', reason: e.reason }),
212
201
  });
213
202
  case 'SESSION_STORE_IO_ERROR':
214
- return (0, types_js_1.errNotRetryable)('INTERNAL_ERROR', e.message, {
215
- suggestion: 'Retry; check filesystem permissions.',
216
- });
203
+ return (0, types_js_1.errNotRetryable)('INTERNAL_ERROR', 'WorkRail could not read or write session data to disk.', { suggestion: internalSuggestion('Retry the call.', 'WorkRail cannot access its data files. Check that the ~/.workrail directory exists and is writable.') });
217
204
  case 'SESSION_STORE_INVARIANT_VIOLATION':
218
- return (0, types_js_1.errNotRetryable)('INTERNAL_ERROR', e.message, {
219
- suggestion: 'Treat as invariant violation.',
220
- });
205
+ return (0, types_js_1.errNotRetryable)('INTERNAL_ERROR', 'WorkRail encountered an unexpected error with session storage. This is not caused by your input.', { suggestion: internalSuggestion('Retry the call.', 'WorkRail has an internal storage error.') });
221
206
  default:
222
207
  const _exhaustive = e;
223
208
  return _exhaustive;
@@ -226,42 +211,32 @@ function mapSessionEventLogStoreErrorToToolError(e) {
226
211
  function mapExecutionSessionGateErrorToToolError(e) {
227
212
  switch (e.code) {
228
213
  case 'SESSION_LOCKED':
229
- return (0, types_js_1.errRetryAfterMs)('TOKEN_SESSION_LOCKED', e.message, e.retry.afterMs, {
230
- suggestion: 'Retry in 1–3 seconds; if this persists >10s, ensure no other WorkRail process is running.',
231
- });
214
+ return (0, types_js_1.errRetryAfterMs)('TOKEN_SESSION_LOCKED', 'This session is currently being modified by another operation.', e.retry.afterMs, { suggestion: internalSuggestion('Wait a moment and retry this call.', 'Another WorkRail process may be accessing this session.') });
232
215
  case 'LOCK_RELEASE_FAILED':
233
- return (0, types_js_1.errRetryAfterMs)('TOKEN_SESSION_LOCKED', e.message, e.retry.afterMs, {
234
- suggestion: 'Retry in 1–3 seconds; if this persists >10s, ensure no other WorkRail process is running.',
235
- });
216
+ return (0, types_js_1.errRetryAfterMs)('TOKEN_SESSION_LOCKED', 'A previous operation on this session did not release cleanly.', e.retry.afterMs, { suggestion: 'Wait a moment and retry this call. The lock will auto-expire shortly.' });
236
217
  case 'SESSION_NOT_HEALTHY':
237
- return (0, types_js_1.errNotRetryable)('SESSION_NOT_HEALTHY', e.message, {
238
- suggestion: 'Execution requires healthy session.',
218
+ return (0, types_js_1.errNotRetryable)('SESSION_NOT_HEALTHY', 'This session is in an unhealthy state and cannot accept new operations.', {
219
+ suggestion: `This session cannot be used. Call start_workflow to create a new session.${ESCALATION_SUFFIX}`,
239
220
  details: (0, types_js_2.detailsSessionHealth)(e.health),
240
221
  });
241
222
  case 'SESSION_LOCK_REENTRANT':
242
- return (0, types_js_1.errRetryAfterMs)('TOKEN_SESSION_LOCKED', e.message, 1000, {
243
- suggestion: 'Session is currently locked by concurrent execution. Retry in 1 second.',
244
- });
223
+ return (0, types_js_1.errRetryAfterMs)('TOKEN_SESSION_LOCKED', 'This session is already being modified by a concurrent call you made. Only one operation at a time is allowed per session.', 1000, { suggestion: 'Wait for your other call to complete, then retry this one.' });
245
224
  case 'SESSION_LOAD_FAILED':
225
+ return (0, types_js_1.errNotRetryable)('INTERNAL_ERROR', 'WorkRail could not load the session data for this operation.', { suggestion: internalSuggestion('Retry the call.', 'WorkRail cannot load session data.') });
246
226
  case 'LOCK_ACQUIRE_FAILED':
227
+ return (0, types_js_1.errNotRetryable)('INTERNAL_ERROR', 'WorkRail could not acquire a lock on this session.', { suggestion: internalSuggestion('Retry the call.', 'WorkRail is having trouble with session locking — check if another WorkRail process is running.') });
247
228
  case 'GATE_CALLBACK_FAILED':
248
- return (0, types_js_1.errNotRetryable)('INTERNAL_ERROR', e.message, {
249
- suggestion: 'Retry; if this persists, treat as invariant violation.',
250
- });
229
+ return (0, types_js_1.errNotRetryable)('INTERNAL_ERROR', 'WorkRail encountered an error while processing this session operation. This is not caused by your input.', { suggestion: internalSuggestion('Retry the call.', 'WorkRail has an internal error.') });
251
230
  default:
252
231
  const _exhaustive = e;
253
232
  return _exhaustive;
254
233
  }
255
234
  }
256
- function mapSnapshotStoreErrorToToolError(e, suggestion) {
257
- return (0, types_js_1.errNotRetryable)('INTERNAL_ERROR', `Snapshot store error: ${e.message}`, {
258
- suggestion: suggestion ?? 'Retry; if this persists, treat as invariant violation.',
259
- });
235
+ function mapSnapshotStoreErrorToToolError(e, _suggestion) {
236
+ return (0, types_js_1.errNotRetryable)('INTERNAL_ERROR', 'WorkRail could not access its execution state data. This is not caused by your input.', { suggestion: internalSuggestion('Retry the call.', 'WorkRail has an internal storage error.') });
260
237
  }
261
- function mapPinnedWorkflowStoreErrorToToolError(e, suggestion) {
262
- return (0, types_js_1.errNotRetryable)('INTERNAL_ERROR', `Pinned workflow store error: ${e.message}`, {
263
- suggestion: suggestion ?? 'Retry; if this persists, treat as invariant violation.',
264
- });
238
+ function mapPinnedWorkflowStoreErrorToToolError(e, _suggestion) {
239
+ return (0, types_js_1.errNotRetryable)('INTERNAL_ERROR', 'WorkRail could not access the stored workflow definition. This is not caused by your input.', { suggestion: internalSuggestion('Retry the call.', 'WorkRail has an internal storage error.') });
265
240
  }
266
241
  function mapSessionOrGateErrorToToolError(e) {
267
242
  if (e.code === 'SESSION_LOCKED' ||
@@ -5,22 +5,17 @@ exports.handleV2InspectWorkflow = handleV2InspectWorkflow;
5
5
  const neverthrow_1 = require("neverthrow");
6
6
  const types_js_1 = require("../types.js");
7
7
  const error_mapper_js_1 = require("../error-mapper.js");
8
+ const v2_execution_helpers_js_1 = require("./v2-execution-helpers.js");
8
9
  const output_schemas_js_1 = require("../output-schemas.js");
9
10
  const v1_to_v2_shim_js_1 = require("../../v2/read-only/v1-to-v2-shim.js");
10
11
  const hashing_js_1 = require("../../v2/durable-core/canonical/hashing.js");
11
12
  const TIMEOUT_MS = 30000;
12
13
  const with_timeout_js_1 = require("./shared/with-timeout.js");
13
- function requireV2(ctx) {
14
- if (!ctx.v2) {
15
- return (0, types_js_1.errNotRetryable)('PRECONDITION_FAILED', 'v2 tools are not enabled');
16
- }
17
- return null;
18
- }
19
14
  async function handleV2ListWorkflows(_input, ctx) {
20
- const v2Err = requireV2(ctx);
21
- if (v2Err)
22
- return v2Err;
23
- const { crypto, pinnedStore } = ctx.v2;
15
+ const guard = (0, types_js_1.requireV2Context)(ctx);
16
+ if (!guard.ok)
17
+ return guard.error;
18
+ const { crypto, pinnedStore } = guard.ctx.v2;
24
19
  return neverthrow_1.ResultAsync.fromPromise((0, with_timeout_js_1.withTimeout)(ctx.workflowService.listWorkflowSummaries(), TIMEOUT_MS, 'list_workflows'), (err) => (0, error_mapper_js_1.mapUnknownErrorToToolError)(err))
25
20
  .andThen((summaries) => neverthrow_1.ResultAsync.combine(summaries.map((s) => neverthrow_1.ResultAsync.fromPromise(ctx.workflowService.getWorkflowById(s.id), (err) => (0, error_mapper_js_1.mapUnknownErrorToToolError)(err)).andThen((wf) => {
26
21
  if (!wf) {
@@ -80,10 +75,10 @@ async function handleV2ListWorkflows(_input, ctx) {
80
75
  .match((result) => Promise.resolve(result), (err) => Promise.resolve(err));
81
76
  }
82
77
  async function handleV2InspectWorkflow(input, ctx) {
83
- const v2Err = requireV2(ctx);
84
- if (v2Err)
85
- return v2Err;
86
- const { crypto, pinnedStore } = ctx.v2;
78
+ const guard = (0, types_js_1.requireV2Context)(ctx);
79
+ if (!guard.ok)
80
+ return guard.error;
81
+ const { crypto, pinnedStore } = guard.ctx.v2;
87
82
  return neverthrow_1.ResultAsync.fromPromise((0, with_timeout_js_1.withTimeout)(ctx.workflowService.getWorkflowById(input.workflowId), TIMEOUT_MS, 'inspect_workflow'), (err) => (0, error_mapper_js_1.mapUnknownErrorToToolError)(err))
88
83
  .andThen((workflow) => {
89
84
  if (!workflow) {
@@ -92,7 +87,7 @@ async function handleV2InspectWorkflow(input, ctx) {
92
87
  const snapshot = (0, v1_to_v2_shim_js_1.compileV1WorkflowToV2PreviewSnapshot)(workflow);
93
88
  const hashRes = (0, hashing_js_1.workflowHashForCompiledSnapshot)(snapshot, crypto);
94
89
  if (hashRes.isErr()) {
95
- return (0, neverthrow_1.errAsync)((0, types_js_1.errNotRetryable)('INTERNAL_ERROR', hashRes.error.message));
90
+ return (0, neverthrow_1.errAsync)((0, types_js_1.errNotRetryable)('INTERNAL_ERROR', 'WorkRail could not compute a content hash for the workflow definition. This is not caused by your input.', { suggestion: (0, v2_execution_helpers_js_1.internalSuggestion)('Retry inspect_workflow.', 'WorkRail has an internal error computing workflow hashes.') }));
96
91
  }
97
92
  const workflowHash = hashRes.value;
98
93
  return pinnedStore
@@ -104,9 +99,9 @@ async function handleV2InspectWorkflow(input, ctx) {
104
99
  return (0, neverthrow_1.okAsync)(existing);
105
100
  })
106
101
  .orElse(() => (0, neverthrow_1.okAsync)(snapshot))
107
- .map((compiled) => {
102
+ .andThen((compiled) => {
108
103
  if (!compiled) {
109
- throw new Error('Compiled workflow unexpectedly null');
104
+ return (0, neverthrow_1.errAsync)((0, types_js_1.errNotRetryable)('INTERNAL_ERROR', 'WorkRail could not produce a compiled workflow snapshot. This is not caused by your input.', { suggestion: (0, v2_execution_helpers_js_1.internalSuggestion)('Retry inspect_workflow.', 'WorkRail has an internal error.') }));
110
105
  }
111
106
  const body = input.mode === 'metadata'
112
107
  ? { schemaVersion: compiled.schemaVersion, sourceKind: compiled.sourceKind, workflowId: compiled.workflowId }
@@ -117,7 +112,7 @@ async function handleV2InspectWorkflow(input, ctx) {
117
112
  mode: input.mode,
118
113
  compiled: body,
119
114
  });
120
- return (0, types_js_1.success)(payload);
115
+ return (0, neverthrow_1.okAsync)((0, types_js_1.success)(payload));
121
116
  });
122
117
  })
123
118
  .match((result) => Promise.resolve(result), (err) => Promise.resolve(err));