@exaudeus/workrail 1.5.2 → 1.5.4

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.
@@ -606,8 +606,8 @@
606
606
  "bytes": 259
607
607
  },
608
608
  "mcp/handlers/v2-checkpoint.js": {
609
- "sha256": "24b7aaf920fd2c5e4ec801ab9c0f3f7d93aa8280c05b851f12e57343d352a4ec",
610
- "bytes": 9196
609
+ "sha256": "48c20ca225f9595f845c2692083d581a3e1ebdb3f423b210ef8b37c69e727954",
610
+ "bytes": 9558
611
611
  },
612
612
  "mcp/handlers/v2-context-budget.d.ts": {
613
613
  "sha256": "cbad1741a183d52c9cbe558be2e09f776843d1f3ec8cd28d6d0d230668e4298c",
@@ -5,6 +5,7 @@ const neverthrow_1 = require("neverthrow");
5
5
  const types_js_1 = require("../types.js");
6
6
  const output_schemas_js_1 = require("../output-schemas.js");
7
7
  const v2_token_ops_js_1 = require("./v2-token-ops.js");
8
+ const v2_execution_helpers_js_1 = require("./v2-execution-helpers.js");
8
9
  const index_js_1 = require("../../v2/durable-core/ids/index.js");
9
10
  const workflow_hash_ref_js_1 = require("../../v2/durable-core/ids/workflow-hash-ref.js");
10
11
  const index_js_2 = require("../../v2/durable-core/schemas/session/index.js");
@@ -58,25 +59,37 @@ function executeCheckpoint(input, ctx) {
58
59
  const nodeId = (0, index_js_1.asNodeId)(String(token.payload.nodeId));
59
60
  const attemptId = (0, index_js_1.asAttemptId)(String(token.payload.attemptId));
60
61
  const dedupeKey = `checkpoint:${String(sessionId)}:${String(runId)}:${String(nodeId)}:${String(attemptId)}`;
61
- return gate.withHealthySessionLock(sessionId, (lock) => {
62
- return sessionStore.load(sessionId)
63
- .mapErr((cause) => ({ kind: 'store_failed', cause }))
64
- .andThen((truth) => {
65
- const originalNode = findNodeCreated(truth.events, nodeId);
66
- if (!originalNode) {
67
- return (0, neverthrow_1.errAsync)({ kind: 'missing_node_or_run' });
68
- }
69
- const alreadyRecorded = truth.events.some((e) => e.dedupeKey === dedupeKey);
70
- if (alreadyRecorded) {
71
- return replayCheckpoint(truth.events, dedupeKey, originalNode, sessionId, runId, nodeId, tokenCodecPorts);
62
+ return sessionStore.load(sessionId)
63
+ .mapErr((cause) => ({ kind: 'store_failed', cause }))
64
+ .andThen((truth) => {
65
+ const originalNode = findNodeCreated(truth.events, nodeId);
66
+ if (!originalNode) {
67
+ return (0, neverthrow_1.errAsync)({ kind: 'missing_node_or_run' });
68
+ }
69
+ const alreadyRecorded = truth.events.some((e) => e.dedupeKey === dedupeKey);
70
+ if (alreadyRecorded) {
71
+ return replayCheckpoint(truth.events, dedupeKey, originalNode, sessionId, runId, nodeId, tokenCodecPorts);
72
+ }
73
+ return gate.withHealthySessionLock(sessionId, (lock) => {
74
+ return sessionStore.load(sessionId)
75
+ .mapErr((cause) => ({ kind: 'store_failed', cause }))
76
+ .andThen((truthLocked) => {
77
+ const originalNodeLocked = findNodeCreated(truthLocked.events, nodeId);
78
+ if (!originalNodeLocked) {
79
+ return (0, neverthrow_1.errAsync)({ kind: 'missing_node_or_run' });
80
+ }
81
+ const alreadyRecordedLocked = truthLocked.events.some((e) => e.dedupeKey === dedupeKey);
82
+ if (alreadyRecordedLocked) {
83
+ return replayCheckpoint(truthLocked.events, dedupeKey, originalNodeLocked, sessionId, runId, nodeId, tokenCodecPorts);
84
+ }
85
+ return writeCheckpoint(truthLocked, dedupeKey, originalNodeLocked, sessionId, runId, nodeId, idFactory.mintNodeId(), () => idFactory.mintEventId(), lock, sessionStore, tokenCodecPorts);
86
+ });
87
+ }).mapErr((gateErr) => {
88
+ if (isGateError(gateErr)) {
89
+ return { kind: 'gate_failed', cause: gateErr };
72
90
  }
73
- return writeCheckpoint(truth, dedupeKey, originalNode, sessionId, runId, nodeId, idFactory.mintNodeId(), () => idFactory.mintEventId(), lock, sessionStore, tokenCodecPorts);
91
+ return gateErr;
74
92
  });
75
- }).mapErr((gateErr) => {
76
- if (isGateError(gateErr)) {
77
- return { kind: 'gate_failed', cause: gateErr };
78
- }
79
- return gateErr;
80
93
  });
81
94
  }
82
95
  function replayCheckpoint(events, dedupeKey, originalNode, sessionId, runId, nodeId, tokenCodecPorts) {
@@ -165,16 +178,8 @@ function mapCheckpointErrorToToolError(e) {
165
178
  return (0, types_js_1.errNotRetryable)('TOKEN_UNKNOWN_NODE', 'No durable node state found for this checkpointToken. Use a checkpointToken returned by WorkRail.');
166
179
  case 'event_schema_invalid':
167
180
  return (0, types_js_1.errNotRetryable)('INTERNAL_ERROR', `Checkpoint events failed schema validation: ${e.issues}`);
168
- case 'gate_failed': {
169
- const code = e.cause.code;
170
- if (code === 'SESSION_LOCKED' || code === 'SESSION_LOCK_REENTRANT') {
171
- return (0, types_js_1.errNotRetryable)('TOKEN_SESSION_LOCKED', `Session is locked: ${code}`);
172
- }
173
- if (code === 'SESSION_NOT_HEALTHY') {
174
- return (0, types_js_1.errNotRetryable)('SESSION_NOT_HEALTHY', 'Session is not healthy.');
175
- }
176
- return (0, types_js_1.errNotRetryable)('INTERNAL_ERROR', `Session gate error: ${code}`);
177
- }
181
+ case 'gate_failed':
182
+ return (0, v2_execution_helpers_js_1.mapExecutionSessionGateErrorToToolError)(e.cause);
178
183
  case 'store_failed':
179
184
  return (0, types_js_1.errNotRetryable)('INTERNAL_ERROR', `Session store error: ${e.cause.code}`);
180
185
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@exaudeus/workrail",
3
- "version": "1.5.2",
3
+ "version": "1.5.4",
4
4
  "description": "Step-by-step workflow enforcement for AI agents via MCP",
5
5
  "license": "MIT",
6
6
  "repository": {