@exaudeus/workrail 1.3.0 → 1.4.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.
@@ -553,6 +553,14 @@
553
553
  "sha256": "d22e4b954022e82bf3017b5fca7101c0499f76fdad1efb86131f189bc9c4602b",
554
554
  "bytes": 22251
555
555
  },
556
+ "mcp/handlers/v2-checkpoint.d.ts": {
557
+ "sha256": "97e1d3ddcb5f92137312c6516b6c4ff2f18dec7a7a83657db30198aedd67e7e1",
558
+ "bytes": 259
559
+ },
560
+ "mcp/handlers/v2-checkpoint.js": {
561
+ "sha256": "20a8d8524bb64a641d4c82ecabadf70ba84c599636808ba4fe19d594d1f04b8c",
562
+ "bytes": 9123
563
+ },
556
564
  "mcp/handlers/v2-context-budget.d.ts": {
557
565
  "sha256": "cbad1741a183d52c9cbe558be2e09f776843d1f3ec8cd28d6d0d230668e4298c",
558
566
  "bytes": 674
@@ -582,8 +590,8 @@
582
590
  "bytes": 944
583
591
  },
584
592
  "mcp/handlers/v2-execution.js": {
585
- "sha256": "dccf1b219b0962743cd53ef5c1fca00d356161df388b42524ddf7380ec1c371b",
586
- "bytes": 48280
593
+ "sha256": "561e34c59e1640dd419644b1abc750b2750e8a99bce000abef593e5047badc23",
594
+ "bytes": 50334
587
595
  },
588
596
  "mcp/handlers/v2-state-conversion.d.ts": {
589
597
  "sha256": "e8d70753ed1b83d9396864ef50929ba32cb008bda24bcb2ce624df24adb72570",
@@ -594,12 +602,12 @@
594
602
  "bytes": 5216
595
603
  },
596
604
  "mcp/handlers/v2-token-ops.d.ts": {
597
- "sha256": "64b143576c2741497f393513bb2d04010f3754c8d066c47cbff5819d072f8eea",
598
- "bytes": 1504
605
+ "sha256": "2101c6f44398909b045adf0904dcec10448bb0fd69d85eab352488ee752959e0",
606
+ "bytes": 1853
599
607
  },
600
608
  "mcp/handlers/v2-token-ops.js": {
601
- "sha256": "27d5b08e3ce3ba984a8258cfbbede7e525039cbcde55a411c74f3c0fd60f91bf",
602
- "bytes": 2851
609
+ "sha256": "c786c2a8de7240989b2368762552373a2c3d397edd47122144c51e31a22d6203",
610
+ "bytes": 3817
603
611
  },
604
612
  "mcp/handlers/v2-workflow.d.ts": {
605
613
  "sha256": "9fbd4d44854e2060c54982b21e72c608970bb2bd107bb15a8388b26c6b492e55",
@@ -626,12 +634,12 @@
626
634
  "bytes": 7535
627
635
  },
628
636
  "mcp/output-schemas.d.ts": {
629
- "sha256": "2e26bc2e2f457dcd2325bbab67a19ce4ed81896eb87b0981094f68c76937f08c",
630
- "bytes": 42678
637
+ "sha256": "ae6188036f2e379c9f5498f7256f658e5bdd5301024e7bd863d02ca3dfad9f41",
638
+ "bytes": 43607
631
639
  },
632
640
  "mcp/output-schemas.js": {
633
- "sha256": "11fbd471a6b56aa8df3c3d002e4d660da3d034b4fbab82871d810c1d25152283",
634
- "bytes": 10346
641
+ "sha256": "3ad98beeb67c03622651e100e8a4c02374318e1967fa062335d6dda80664ad8e",
642
+ "bytes": 10889
635
643
  },
636
644
  "mcp/server.d.ts": {
637
645
  "sha256": "bec49b8d07e189a53db7100d2f0e1e84ffe03150f04e1b06908ee3282982b4a2",
@@ -654,8 +662,8 @@
654
662
  "bytes": 132
655
663
  },
656
664
  "mcp/tool-descriptions.js": {
657
- "sha256": "4a713e4cad3b59077c42d95c78b5a1b68b93830def6f0d39db4ed79562c8a6e3",
658
- "bytes": 14568
665
+ "sha256": "e5f98cd0791507b87b3d0883155e74aaf4a9f03fd17b795195f21835962bd4cf",
666
+ "bytes": 15369
659
667
  },
660
668
  "mcp/tool-factory.d.ts": {
661
669
  "sha256": "0fe3c6b863b2d7aef0c3d659ff54f3a9ee8a0a3c2005b6565d2f8ad517bc7211",
@@ -670,8 +678,8 @@
670
678
  "bytes": 5976
671
679
  },
672
680
  "mcp/tools.js": {
673
- "sha256": "0af59932b32bad5ebc9cbc925279d325350c91b43085561d0d218035250b641a",
674
- "bytes": 8020
681
+ "sha256": "813dad3f02046e200d99c2228cbf53ad9de58a79e609356730c93b75903d4c01",
682
+ "bytes": 8198
675
683
  },
676
684
  "mcp/types.d.ts": {
677
685
  "sha256": "9e29d5ae4ec1f80640f073f0d58b603158fe5b22897f44c1c77ed4abaef374f9",
@@ -682,16 +690,16 @@
682
690
  "bytes": 1253
683
691
  },
684
692
  "mcp/types/tool-description-types.d.ts": {
685
- "sha256": "7d0fb489a829f7d21ed0d3fe9cef221ff71b63619054070287bc790bf5142a28",
686
- "bytes": 782
693
+ "sha256": "41e31c87b6d5b2e0fb4b66b1e8fac3f74c9769c3ded8a26577804aeccb79ae7b",
694
+ "bytes": 805
687
695
  },
688
696
  "mcp/types/tool-description-types.js": {
689
- "sha256": "a1c1fdd901bf6a074d9a48cef09e0020c59d9838bfb8754ed2aaf9c23191a533",
690
- "bytes": 750
697
+ "sha256": "689e74ea09e25e51de6020e42de42c37965e55980635d8739fc9ad19ba341955",
698
+ "bytes": 777
691
699
  },
692
700
  "mcp/types/workflow-tool-edition.d.ts": {
693
- "sha256": "7407d318a9f0cc7d6dc81d7cb003e474b3a31a52bf3e600e07ee94f556e2555a",
694
- "bytes": 1470
701
+ "sha256": "e7228be685155777e3035963056edd503e6660985fe7b5f17032402ca6582c8c",
702
+ "bytes": 1494
695
703
  },
696
704
  "mcp/types/workflow-tool-edition.js": {
697
705
  "sha256": "2dfd26acd3da2c249b728e7fc48c7eab3dc675f786e7689dbdeec53c25589369",
@@ -710,16 +718,16 @@
710
718
  "bytes": 408
711
719
  },
712
720
  "mcp/v2/tool-registry.js": {
713
- "sha256": "8c94984fed94f049daeb01559a2490b7db6fedac2544b3e7e50a60b8c7dfa561",
714
- "bytes": 2121
721
+ "sha256": "719429102bc33c9e5bcd7cf38b0242ecc038484de4159811fbe9b0efa2ebc460",
722
+ "bytes": 2623
715
723
  },
716
724
  "mcp/v2/tools.d.ts": {
717
- "sha256": "a262c0c17ff9474f017ac1e83d4458c773791604ec4f344f777dcdbefff9318b",
718
- "bytes": 3263
725
+ "sha256": "8fba15da4a60a46ed803046f9b61ea0b8947967880563562473d8a87de68d27c",
726
+ "bytes": 3600
719
727
  },
720
728
  "mcp/v2/tools.js": {
721
- "sha256": "00c6710f31a9cb42215a1427f48b3e22a1065996dfdaaaf4ae2389f3c23e9aa5",
722
- "bytes": 5221
729
+ "sha256": "93f33152aebe0cbeb92daa727a3dc43ccb3f4cc1001e7564fdd7b31ee78b2475",
730
+ "bytes": 5743
723
731
  },
724
732
  "mcp/validation/bounded-json.d.ts": {
725
733
  "sha256": "82203ac6123d5c6989606c3b5405aaea99ab829c8958835f9ae3ba45b8bc8fd5",
@@ -0,0 +1,3 @@
1
+ import type { ToolContext, ToolResult } from '../types.js';
2
+ import type { V2CheckpointWorkflowInput } from '../v2/tools.js';
3
+ export declare function handleV2CheckpointWorkflow(input: V2CheckpointWorkflowInput, ctx: ToolContext): Promise<ToolResult<unknown>>;
@@ -0,0 +1,184 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handleV2CheckpointWorkflow = handleV2CheckpointWorkflow;
4
+ const neverthrow_1 = require("neverthrow");
5
+ const types_js_1 = require("../types.js");
6
+ const output_schemas_js_1 = require("../output-schemas.js");
7
+ const v2_token_ops_js_1 = require("./v2-token-ops.js");
8
+ const index_js_1 = require("../../v2/durable-core/ids/index.js");
9
+ const workflow_hash_ref_js_1 = require("../../v2/durable-core/ids/workflow-hash-ref.js");
10
+ const index_js_2 = require("../../v2/durable-core/schemas/session/index.js");
11
+ function findNodeCreated(events, nodeId) {
12
+ return events.find((e) => e.kind === 'node_created' && e.scope?.nodeId === String(nodeId));
13
+ }
14
+ function mintStateTokenForNode(originalNode, sessionId, runId, nodeId, tokenCodecPorts) {
15
+ const wfRefRes = (0, workflow_hash_ref_js_1.deriveWorkflowHashRef)(originalNode.data.workflowHash);
16
+ if (wfRefRes.isErr()) {
17
+ return { ok: false, error: { kind: 'precondition_failed', message: 'Cannot derive workflowHashRef for stateToken.' } };
18
+ }
19
+ const stateTokenRes = (0, v2_token_ops_js_1.signTokenOrErr)({
20
+ payload: { tokenVersion: 1, tokenKind: 'state', sessionId, runId, nodeId, workflowHashRef: wfRefRes.value },
21
+ ports: tokenCodecPorts,
22
+ });
23
+ if (stateTokenRes.isErr()) {
24
+ return { ok: false, error: { kind: 'token_signing_failed', cause: stateTokenRes.error } };
25
+ }
26
+ return { ok: true, value: stateTokenRes.value };
27
+ }
28
+ function validateEvents(rawEvents) {
29
+ const validated = [];
30
+ for (const raw of rawEvents) {
31
+ const parsed = index_js_2.DomainEventV1Schema.safeParse(raw);
32
+ if (!parsed.success) {
33
+ return { issues: parsed.error.issues.map((i) => `${i.path.join('.')}: ${i.message}`).join('; ') };
34
+ }
35
+ validated.push(parsed.data);
36
+ }
37
+ return validated;
38
+ }
39
+ function isGateError(e) {
40
+ return typeof e === 'object' && e !== null && 'code' in e && typeof e.code === 'string' && !('kind' in e);
41
+ }
42
+ async function handleV2CheckpointWorkflow(input, ctx) {
43
+ return executeCheckpoint(input, ctx).match((payload) => (0, types_js_1.success)(payload), (e) => mapCheckpointErrorToToolError(e));
44
+ }
45
+ function executeCheckpoint(input, ctx) {
46
+ if (!ctx.v2) {
47
+ return (0, neverthrow_1.errAsync)({ kind: 'precondition_failed', message: 'v2 tools disabled' });
48
+ }
49
+ const { gate, sessionStore, tokenCodecPorts, idFactory } = ctx.v2;
50
+ if (!tokenCodecPorts) {
51
+ return (0, neverthrow_1.errAsync)({ kind: 'precondition_failed', message: 'v2 context missing tokenCodecPorts' });
52
+ }
53
+ if (!idFactory) {
54
+ return (0, neverthrow_1.errAsync)({ kind: 'precondition_failed', message: 'v2 context missing idFactory' });
55
+ }
56
+ const tokenRes = (0, v2_token_ops_js_1.parseCheckpointTokenOrFail)(input.checkpointToken, tokenCodecPorts);
57
+ if (!tokenRes.ok) {
58
+ return (0, neverthrow_1.errAsync)({ kind: 'validation_failed', failure: tokenRes.failure });
59
+ }
60
+ const token = tokenRes.token;
61
+ const sessionId = (0, index_js_1.asSessionId)(String(token.payload.sessionId));
62
+ const runId = (0, index_js_1.asRunId)(String(token.payload.runId));
63
+ const nodeId = (0, index_js_1.asNodeId)(String(token.payload.nodeId));
64
+ const attemptId = (0, index_js_1.asAttemptId)(String(token.payload.attemptId));
65
+ const dedupeKey = `checkpoint:${String(sessionId)}:${String(runId)}:${String(nodeId)}:${String(attemptId)}`;
66
+ return gate.withHealthySessionLock(sessionId, (lock) => {
67
+ return sessionStore.load(sessionId)
68
+ .mapErr((cause) => ({ kind: 'store_failed', cause }))
69
+ .andThen((truth) => {
70
+ const originalNode = findNodeCreated(truth.events, nodeId);
71
+ if (!originalNode) {
72
+ return (0, neverthrow_1.errAsync)({ kind: 'missing_node_or_run' });
73
+ }
74
+ const alreadyRecorded = truth.events.some((e) => e.dedupeKey === dedupeKey);
75
+ if (alreadyRecorded) {
76
+ return replayCheckpoint(truth.events, dedupeKey, originalNode, sessionId, runId, nodeId, tokenCodecPorts);
77
+ }
78
+ return writeCheckpoint(truth, dedupeKey, originalNode, sessionId, runId, nodeId, idFactory.mintNodeId(), () => idFactory.mintEventId(), lock, sessionStore, tokenCodecPorts);
79
+ });
80
+ }).mapErr((gateErr) => {
81
+ if (isGateError(gateErr)) {
82
+ return { kind: 'gate_failed', cause: gateErr };
83
+ }
84
+ return gateErr;
85
+ });
86
+ }
87
+ function replayCheckpoint(events, dedupeKey, originalNode, sessionId, runId, nodeId, tokenCodecPorts) {
88
+ const existingCheckpointNode = events.find((e) => e.kind === 'node_created' && e.dedupeKey === `checkpoint_node:${dedupeKey}`);
89
+ const checkpointNodeId = existingCheckpointNode
90
+ ? String(existingCheckpointNode.scope?.nodeId ?? 'unknown')
91
+ : 'unknown';
92
+ const tokenResult = mintStateTokenForNode(originalNode, sessionId, runId, nodeId, tokenCodecPorts);
93
+ if (!tokenResult.ok)
94
+ return (0, neverthrow_1.errAsync)(tokenResult.error);
95
+ return (0, neverthrow_1.okAsync)(output_schemas_js_1.V2CheckpointWorkflowOutputSchema.parse({
96
+ checkpointNodeId,
97
+ stateToken: tokenResult.value,
98
+ }));
99
+ }
100
+ function writeCheckpoint(truth, dedupeKey, originalNode, sessionId, runId, nodeId, checkpointNodeId, mintEventId, lock, sessionStore, tokenCodecPorts) {
101
+ const nodeCreatedEventId = mintEventId();
102
+ const edgeCreatedEventId = mintEventId();
103
+ const rawEvents = [
104
+ {
105
+ v: 1,
106
+ eventId: nodeCreatedEventId,
107
+ eventIndex: truth.events.length,
108
+ sessionId: String(sessionId),
109
+ kind: 'node_created',
110
+ dedupeKey: `checkpoint_node:${dedupeKey}`,
111
+ scope: { runId: String(runId), nodeId: String(checkpointNodeId) },
112
+ data: {
113
+ nodeKind: 'checkpoint',
114
+ parentNodeId: String(nodeId),
115
+ workflowHash: originalNode.data.workflowHash,
116
+ snapshotRef: originalNode.data.snapshotRef,
117
+ },
118
+ },
119
+ {
120
+ v: 1,
121
+ eventId: edgeCreatedEventId,
122
+ eventIndex: truth.events.length + 1,
123
+ sessionId: String(sessionId),
124
+ kind: 'edge_created',
125
+ dedupeKey,
126
+ scope: { runId: String(runId) },
127
+ data: {
128
+ edgeKind: 'checkpoint',
129
+ fromNodeId: String(nodeId),
130
+ toNodeId: String(checkpointNodeId),
131
+ cause: {
132
+ kind: 'checkpoint_created',
133
+ eventId: String(nodeCreatedEventId),
134
+ },
135
+ },
136
+ },
137
+ ];
138
+ const validated = validateEvents(rawEvents);
139
+ if ('issues' in validated) {
140
+ return (0, neverthrow_1.errAsync)({ kind: 'event_schema_invalid', issues: validated.issues });
141
+ }
142
+ const snapshotPins = [{
143
+ snapshotRef: originalNode.data.snapshotRef,
144
+ eventIndex: truth.events.length,
145
+ createdByEventId: nodeCreatedEventId,
146
+ }];
147
+ return sessionStore.append(lock, { events: validated, snapshotPins })
148
+ .mapErr((cause) => ({ kind: 'store_failed', cause }))
149
+ .andThen(() => {
150
+ const tokenResult = mintStateTokenForNode(originalNode, sessionId, runId, nodeId, tokenCodecPorts);
151
+ if (!tokenResult.ok)
152
+ return (0, neverthrow_1.errAsync)(tokenResult.error);
153
+ return (0, neverthrow_1.okAsync)(output_schemas_js_1.V2CheckpointWorkflowOutputSchema.parse({
154
+ checkpointNodeId: String(checkpointNodeId),
155
+ stateToken: tokenResult.value,
156
+ }));
157
+ });
158
+ }
159
+ function mapCheckpointErrorToToolError(e) {
160
+ switch (e.kind) {
161
+ case 'precondition_failed':
162
+ return (0, types_js_1.errNotRetryable)('PRECONDITION_FAILED', e.message);
163
+ case 'token_signing_failed':
164
+ return (0, types_js_1.errNotRetryable)('INTERNAL_ERROR', 'Failed to sign token.');
165
+ case 'validation_failed':
166
+ return e.failure;
167
+ case 'missing_node_or_run':
168
+ return (0, types_js_1.errNotRetryable)('TOKEN_UNKNOWN_NODE', 'No durable node state found for this checkpointToken. Use a checkpointToken returned by WorkRail.');
169
+ case 'event_schema_invalid':
170
+ return (0, types_js_1.errNotRetryable)('INTERNAL_ERROR', `Checkpoint events failed schema validation: ${e.issues}`);
171
+ case 'gate_failed': {
172
+ const code = e.cause.code;
173
+ if (code === 'SESSION_LOCKED' || code === 'SESSION_LOCK_REENTRANT') {
174
+ return (0, types_js_1.errNotRetryable)('TOKEN_SESSION_LOCKED', `Session is locked: ${code}`);
175
+ }
176
+ if (code === 'SESSION_NOT_HEALTHY') {
177
+ return (0, types_js_1.errNotRetryable)('SESSION_NOT_HEALTHY', 'Session is not healthy.');
178
+ }
179
+ return (0, types_js_1.errNotRetryable)('INTERNAL_ERROR', `Session gate error: ${code}`);
180
+ }
181
+ case 'store_failed':
182
+ return (0, types_js_1.errNotRetryable)('INTERNAL_ERROR', `Session store error: ${e.cause.code}`);
183
+ }
184
+ }
@@ -70,10 +70,17 @@ function replayFromRecordedAdvance(args) {
70
70
  : null;
71
71
  const preferences = (0, v2_state_conversion_js_1.derivePreferencesForNode)({ truth, runId, nodeId });
72
72
  const nextIntent = (0, v2_state_conversion_js_1.deriveNextIntent)({ rehydrateOnly: false, isComplete: isCompleteNow, pending: meta });
73
+ const replayCheckpointTokenRes = pendingNow
74
+ ? (0, v2_token_ops_js_1.signTokenOrErr)({
75
+ payload: { tokenVersion: 1, tokenKind: 'checkpoint', sessionId, runId, nodeId, attemptId },
76
+ ports: tokenCodecPorts,
77
+ })
78
+ : (0, neverthrow_1.ok)(undefined);
73
79
  return output_schemas_js_1.V2ContinueWorkflowOutputSchema.parse({
74
80
  kind: 'blocked',
75
81
  stateToken: inputStateToken,
76
82
  ackToken: inputAckToken,
83
+ checkpointToken: replayCheckpointTokenRes.isOk() ? replayCheckpointTokenRes.value : undefined,
77
84
  isComplete: isCompleteNow,
78
85
  pending: meta ? { stepId: meta.stepId, title: meta.title, prompt: meta.prompt } : null,
79
86
  preferences,
@@ -119,6 +126,15 @@ function replayFromRecordedAdvance(args) {
119
126
  if (nextAckTokenRes.isErr()) {
120
127
  return (0, neverthrow_1.errAsync)({ kind: 'token_signing_failed', cause: nextAckTokenRes.error });
121
128
  }
129
+ const nextCheckpointTokenRes = pending
130
+ ? (0, v2_token_ops_js_1.signTokenOrErr)({
131
+ payload: { tokenVersion: 1, tokenKind: 'checkpoint', sessionId, runId, nodeId: toNodeIdBranded, attemptId: nextAttemptId },
132
+ ports: tokenCodecPorts,
133
+ })
134
+ : (0, neverthrow_1.ok)(undefined);
135
+ if (nextCheckpointTokenRes.isErr()) {
136
+ return (0, neverthrow_1.errAsync)({ kind: 'token_signing_failed', cause: nextCheckpointTokenRes.error });
137
+ }
122
138
  const wfRefRes = (0, workflow_hash_ref_js_1.deriveWorkflowHashRef)(workflowHash);
123
139
  if (wfRefRes.isErr()) {
124
140
  return (0, neverthrow_1.errAsync)({ kind: 'precondition_failed', message: wfRefRes.error.message, suggestion: 'Ensure workflowHash is a valid sha256 digest.' });
@@ -173,6 +189,7 @@ function replayFromRecordedAdvance(args) {
173
189
  kind: 'blocked',
174
190
  stateToken: nextStateTokenRes.value,
175
191
  ackToken: pending ? nextAckTokenRes.value : undefined,
192
+ checkpointToken: pending ? nextCheckpointTokenRes.value : undefined,
176
193
  isComplete,
177
194
  pending: meta ? { stepId: meta.stepId, title: meta.title, prompt: meta.prompt } : null,
178
195
  preferences,
@@ -206,6 +223,7 @@ function replayFromRecordedAdvance(args) {
206
223
  kind: 'ok',
207
224
  stateToken: nextStateTokenRes.value,
208
225
  ackToken: pending ? nextAckTokenRes.value : undefined,
226
+ checkpointToken: pending ? nextCheckpointTokenRes.value : undefined,
209
227
  isComplete,
210
228
  pending: pending ? { stepId: meta.stepId, title: meta.title, prompt: meta.prompt } : null,
211
229
  preferences,
@@ -508,6 +526,12 @@ function executeStartWorkflow(input, ctx) {
508
526
  const ackToken = (0, v2_token_ops_js_1.signTokenOrErr)({ payload: ackPayload, ports: tokenCodecPorts });
509
527
  if (ackToken.isErr())
510
528
  return (0, neverthrow_1.errAsync)({ kind: 'token_signing_failed', cause: ackToken.error });
529
+ const checkpointToken = (0, v2_token_ops_js_1.signTokenOrErr)({
530
+ payload: { tokenVersion: 1, tokenKind: 'checkpoint', sessionId, runId, nodeId, attemptId },
531
+ ports: tokenCodecPorts,
532
+ });
533
+ if (checkpointToken.isErr())
534
+ return (0, neverthrow_1.errAsync)({ kind: 'token_signing_failed', cause: checkpointToken.error });
511
535
  const metaRes = (0, prompt_renderer_js_1.renderPendingPrompt)({
512
536
  workflow: pinnedWorkflow,
513
537
  stepId: firstStep.id,
@@ -529,6 +553,7 @@ function executeStartWorkflow(input, ctx) {
529
553
  return (0, neverthrow_1.okAsync)(output_schemas_js_1.V2StartWorkflowOutputSchema.parse({
530
554
  stateToken: stateToken.value,
531
555
  ackToken: ackToken.value,
556
+ checkpointToken: checkpointToken.value,
532
557
  isComplete: false,
533
558
  pending,
534
559
  preferences,
@@ -647,6 +672,12 @@ function executeContinueWorkflow(input, ctx) {
647
672
  });
648
673
  if (ackTokenRes.isErr())
649
674
  return (0, neverthrow_1.errAsync)({ kind: 'token_signing_failed', cause: ackTokenRes.error });
675
+ const checkpointTokenRes = (0, v2_token_ops_js_1.signTokenOrErr)({
676
+ payload: { tokenVersion: 1, tokenKind: 'checkpoint', sessionId, runId, nodeId, attemptId },
677
+ ports: tokenCodecPorts,
678
+ });
679
+ if (checkpointTokenRes.isErr())
680
+ return (0, neverthrow_1.errAsync)({ kind: 'token_signing_failed', cause: checkpointTokenRes.error });
650
681
  return pinnedStore.get(workflowHash)
651
682
  .mapErr((cause) => ({ kind: 'pinned_workflow_store_failed', cause }))
652
683
  .andThen((pinned) => {
@@ -685,6 +716,7 @@ function executeContinueWorkflow(input, ctx) {
685
716
  kind: 'ok',
686
717
  stateToken: input.stateToken,
687
718
  ackToken: ackTokenRes.value,
719
+ checkpointToken: checkpointTokenRes.value,
688
720
  isComplete,
689
721
  pending: { stepId: meta.stepId, title: meta.title, prompt: meta.prompt },
690
722
  preferences,
@@ -9,6 +9,9 @@ export type StateTokenInput = ParsedTokenV1Binary & {
9
9
  export type AckTokenInput = ParsedTokenV1Binary & {
10
10
  readonly payload: import('../../v2/durable-core/tokens/payloads.js').AckTokenPayloadV1;
11
11
  };
12
+ export type CheckpointTokenInput = ParsedTokenV1Binary & {
13
+ readonly payload: import('../../v2/durable-core/tokens/payloads.js').CheckpointTokenPayloadV1;
14
+ };
12
15
  export declare function parseStateTokenOrFail(raw: string, ports: TokenCodecPorts): {
13
16
  ok: true;
14
17
  token: StateTokenInput;
@@ -23,6 +26,13 @@ export declare function parseAckTokenOrFail(raw: string, ports: TokenCodecPorts)
23
26
  ok: false;
24
27
  failure: ToolFailure;
25
28
  };
29
+ export declare function parseCheckpointTokenOrFail(raw: string, ports: TokenCodecPorts): {
30
+ ok: true;
31
+ token: CheckpointTokenInput;
32
+ } | {
33
+ ok: false;
34
+ failure: ToolFailure;
35
+ };
26
36
  export declare function newAttemptId(idFactory: {
27
37
  readonly mintAttemptId: () => AttemptId;
28
38
  }): AttemptId;
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.parseStateTokenOrFail = parseStateTokenOrFail;
4
4
  exports.parseAckTokenOrFail = parseAckTokenOrFail;
5
+ exports.parseCheckpointTokenOrFail = parseCheckpointTokenOrFail;
5
6
  exports.newAttemptId = newAttemptId;
6
7
  exports.attemptIdForNextNode = attemptIdForNextNode;
7
8
  exports.signTokenOrErr = signTokenOrErr;
@@ -48,6 +49,25 @@ function parseAckTokenOrFail(raw, ports) {
48
49
  }
49
50
  return { ok: true, token: parsedRes.value };
50
51
  }
52
+ function parseCheckpointTokenOrFail(raw, ports) {
53
+ const parsedRes = (0, index_js_1.parseTokenV1Binary)(raw, ports);
54
+ if (parsedRes.isErr()) {
55
+ return { ok: false, failure: (0, v2_execution_helpers_js_1.mapTokenDecodeErrorToToolError)(parsedRes.error) };
56
+ }
57
+ const verified = (0, index_js_1.verifyTokenSignatureV1Binary)(parsedRes.value, ports);
58
+ if (verified.isErr()) {
59
+ return { ok: false, failure: (0, v2_execution_helpers_js_1.mapTokenVerifyErrorToToolError)(verified.error) };
60
+ }
61
+ if (parsedRes.value.payload.tokenKind !== 'checkpoint') {
62
+ return {
63
+ ok: false,
64
+ failure: (0, types_js_1.errNotRetryable)('TOKEN_INVALID_FORMAT', 'Expected a checkpoint token (chk1...).', {
65
+ suggestion: 'Use the checkpointToken returned by WorkRail.',
66
+ }),
67
+ };
68
+ }
69
+ return { ok: true, token: parsedRes.value };
70
+ }
51
71
  function newAttemptId(idFactory) {
52
72
  return idFactory.mintAttemptId();
53
73
  }
@@ -462,6 +462,7 @@ export declare const V2ContinueWorkflowOutputSchema: z.ZodEffects<z.ZodDiscrimin
462
462
  kind: z.ZodLiteral<"ok">;
463
463
  stateToken: z.ZodString;
464
464
  ackToken: z.ZodOptional<z.ZodString>;
465
+ checkpointToken: z.ZodOptional<z.ZodString>;
465
466
  isComplete: z.ZodBoolean;
466
467
  pending: z.ZodNullable<z.ZodObject<{
467
468
  stepId: z.ZodString;
@@ -540,6 +541,7 @@ export declare const V2ContinueWorkflowOutputSchema: z.ZodEffects<z.ZodDiscrimin
540
541
  tool: "continue_workflow";
541
542
  } | null;
542
543
  ackToken?: string | undefined;
544
+ checkpointToken?: string | undefined;
543
545
  }, {
544
546
  kind: "ok";
545
547
  pending: {
@@ -563,10 +565,12 @@ export declare const V2ContinueWorkflowOutputSchema: z.ZodEffects<z.ZodDiscrimin
563
565
  tool: "continue_workflow";
564
566
  } | null;
565
567
  ackToken?: string | undefined;
568
+ checkpointToken?: string | undefined;
566
569
  }>, z.ZodObject<{
567
570
  kind: z.ZodLiteral<"blocked">;
568
571
  stateToken: z.ZodString;
569
572
  ackToken: z.ZodOptional<z.ZodString>;
573
+ checkpointToken: z.ZodOptional<z.ZodString>;
570
574
  isComplete: z.ZodBoolean;
571
575
  pending: z.ZodNullable<z.ZodObject<{
572
576
  stepId: z.ZodString;
@@ -855,6 +859,7 @@ export declare const V2ContinueWorkflowOutputSchema: z.ZodEffects<z.ZodDiscrimin
855
859
  suggestions: string[];
856
860
  } | undefined;
857
861
  ackToken?: string | undefined;
862
+ checkpointToken?: string | undefined;
858
863
  retryable?: boolean | undefined;
859
864
  retryAckToken?: string | undefined;
860
865
  }, {
@@ -906,6 +911,7 @@ export declare const V2ContinueWorkflowOutputSchema: z.ZodEffects<z.ZodDiscrimin
906
911
  suggestions: string[];
907
912
  } | undefined;
908
913
  ackToken?: string | undefined;
914
+ checkpointToken?: string | undefined;
909
915
  retryable?: boolean | undefined;
910
916
  retryAckToken?: string | undefined;
911
917
  }>]>, {
@@ -931,6 +937,7 @@ export declare const V2ContinueWorkflowOutputSchema: z.ZodEffects<z.ZodDiscrimin
931
937
  tool: "continue_workflow";
932
938
  } | null;
933
939
  ackToken?: string | undefined;
940
+ checkpointToken?: string | undefined;
934
941
  } | {
935
942
  kind: "blocked";
936
943
  blockers: {
@@ -980,6 +987,7 @@ export declare const V2ContinueWorkflowOutputSchema: z.ZodEffects<z.ZodDiscrimin
980
987
  suggestions: string[];
981
988
  } | undefined;
982
989
  ackToken?: string | undefined;
990
+ checkpointToken?: string | undefined;
983
991
  retryable?: boolean | undefined;
984
992
  retryAckToken?: string | undefined;
985
993
  }, {
@@ -1005,6 +1013,7 @@ export declare const V2ContinueWorkflowOutputSchema: z.ZodEffects<z.ZodDiscrimin
1005
1013
  tool: "continue_workflow";
1006
1014
  } | null;
1007
1015
  ackToken?: string | undefined;
1016
+ checkpointToken?: string | undefined;
1008
1017
  } | {
1009
1018
  kind: "blocked";
1010
1019
  blockers: {
@@ -1054,12 +1063,24 @@ export declare const V2ContinueWorkflowOutputSchema: z.ZodEffects<z.ZodDiscrimin
1054
1063
  suggestions: string[];
1055
1064
  } | undefined;
1056
1065
  ackToken?: string | undefined;
1066
+ checkpointToken?: string | undefined;
1057
1067
  retryable?: boolean | undefined;
1058
1068
  retryAckToken?: string | undefined;
1059
1069
  }>;
1070
+ export declare const V2CheckpointWorkflowOutputSchema: z.ZodObject<{
1071
+ checkpointNodeId: z.ZodString;
1072
+ stateToken: z.ZodString;
1073
+ }, "strip", z.ZodTypeAny, {
1074
+ stateToken: string;
1075
+ checkpointNodeId: string;
1076
+ }, {
1077
+ stateToken: string;
1078
+ checkpointNodeId: string;
1079
+ }>;
1060
1080
  export declare const V2StartWorkflowOutputSchema: z.ZodEffects<z.ZodObject<{
1061
1081
  stateToken: z.ZodString;
1062
1082
  ackToken: z.ZodOptional<z.ZodString>;
1083
+ checkpointToken: z.ZodOptional<z.ZodString>;
1063
1084
  isComplete: z.ZodBoolean;
1064
1085
  pending: z.ZodNullable<z.ZodObject<{
1065
1086
  stepId: z.ZodString;
@@ -1137,6 +1158,7 @@ export declare const V2StartWorkflowOutputSchema: z.ZodEffects<z.ZodObject<{
1137
1158
  tool: "continue_workflow";
1138
1159
  } | null;
1139
1160
  ackToken?: string | undefined;
1161
+ checkpointToken?: string | undefined;
1140
1162
  }, {
1141
1163
  pending: {
1142
1164
  title: string;
@@ -1159,6 +1181,7 @@ export declare const V2StartWorkflowOutputSchema: z.ZodEffects<z.ZodObject<{
1159
1181
  tool: "continue_workflow";
1160
1182
  } | null;
1161
1183
  ackToken?: string | undefined;
1184
+ checkpointToken?: string | undefined;
1162
1185
  }>, {
1163
1186
  pending: {
1164
1187
  title: string;
@@ -1181,6 +1204,7 @@ export declare const V2StartWorkflowOutputSchema: z.ZodEffects<z.ZodObject<{
1181
1204
  tool: "continue_workflow";
1182
1205
  } | null;
1183
1206
  ackToken?: string | undefined;
1207
+ checkpointToken?: string | undefined;
1184
1208
  }, {
1185
1209
  pending: {
1186
1210
  title: string;
@@ -1203,6 +1227,7 @@ export declare const V2StartWorkflowOutputSchema: z.ZodEffects<z.ZodObject<{
1203
1227
  tool: "continue_workflow";
1204
1228
  } | null;
1205
1229
  ackToken?: string | undefined;
1230
+ checkpointToken?: string | undefined;
1206
1231
  }>;
1207
1232
  export declare const CreateSessionOutputSchema: z.ZodObject<{
1208
1233
  sessionId: z.ZodString;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.OpenDashboardOutputSchema = exports.ReadSessionSchemaOutputSchema = exports.ReadSessionOutputSchema = exports.UpdateSessionOutputSchema = exports.CreateSessionOutputSchema = exports.V2StartWorkflowOutputSchema = exports.V2ContinueWorkflowOutputSchema = exports.V2BlockerReportSchema = exports.V2NextCallSchema = exports.V2NextIntentSchema = exports.V2PreferencesSchema = exports.V2PendingStepSchema = exports.V2WorkflowInspectOutputSchema = exports.V2WorkflowListOutputSchema = exports.V2WorkflowListItemSchema = exports.WorkflowGetSchemaOutputSchema = exports.WorkflowValidateJsonOutputSchema = exports.WorkflowNextOutputSchema = exports.WorkflowGetOutputSchema = exports.WorkflowListOutputSchema = exports.WorkflowSummarySchema = exports.JsonValueSchema = void 0;
3
+ exports.OpenDashboardOutputSchema = exports.ReadSessionSchemaOutputSchema = exports.ReadSessionOutputSchema = exports.UpdateSessionOutputSchema = exports.CreateSessionOutputSchema = exports.V2StartWorkflowOutputSchema = exports.V2CheckpointWorkflowOutputSchema = exports.V2ContinueWorkflowOutputSchema = exports.V2BlockerReportSchema = exports.V2NextCallSchema = exports.V2NextIntentSchema = exports.V2PreferencesSchema = exports.V2PendingStepSchema = exports.V2WorkflowInspectOutputSchema = exports.V2WorkflowListOutputSchema = exports.V2WorkflowListItemSchema = exports.WorkflowGetSchemaOutputSchema = exports.WorkflowValidateJsonOutputSchema = exports.WorkflowNextOutputSchema = exports.WorkflowGetOutputSchema = exports.WorkflowListOutputSchema = exports.WorkflowSummarySchema = exports.JsonValueSchema = void 0;
4
4
  const zod_1 = require("zod");
5
5
  const state_js_1 = require("../domain/execution/state.js");
6
6
  const JsonPrimitiveSchema = zod_1.z.union([zod_1.z.string(), zod_1.z.number(), zod_1.z.boolean(), zod_1.z.null()]);
@@ -168,10 +168,12 @@ exports.V2BlockerReportSchema = zod_1.z
168
168
  }
169
169
  }
170
170
  });
171
+ const checkpointTokenSchema = zod_1.z.string().regex(/^chk1[023456789acdefghjklmnpqrstuvwxyz]+$/, 'Invalid checkpointToken format').optional();
171
172
  const V2ContinueWorkflowOkSchema = zod_1.z.object({
172
173
  kind: zod_1.z.literal('ok'),
173
174
  stateToken: zod_1.z.string().regex(/^st1[023456789acdefghjklmnpqrstuvwxyz]+$/, 'Invalid stateToken format'),
174
175
  ackToken: zod_1.z.string().regex(/^ack1[023456789acdefghjklmnpqrstuvwxyz]+$/, 'Invalid ackToken format').optional(),
176
+ checkpointToken: checkpointTokenSchema,
175
177
  isComplete: zod_1.z.boolean(),
176
178
  pending: exports.V2PendingStepSchema.nullable(),
177
179
  preferences: exports.V2PreferencesSchema,
@@ -182,6 +184,7 @@ const V2ContinueWorkflowBlockedSchema = zod_1.z.object({
182
184
  kind: zod_1.z.literal('blocked'),
183
185
  stateToken: zod_1.z.string().regex(/^st1[023456789acdefghjklmnpqrstuvwxyz]+$/, 'Invalid stateToken format'),
184
186
  ackToken: zod_1.z.string().regex(/^ack1[023456789acdefghjklmnpqrstuvwxyz]+$/, 'Invalid ackToken format').optional(),
187
+ checkpointToken: checkpointTokenSchema,
185
188
  isComplete: zod_1.z.boolean(),
186
189
  pending: exports.V2PendingStepSchema.nullable(),
187
190
  preferences: exports.V2PreferencesSchema,
@@ -201,9 +204,14 @@ exports.V2ContinueWorkflowOutputSchema = zod_1.z.discriminatedUnion('kind', [
201
204
  V2ContinueWorkflowOkSchema,
202
205
  V2ContinueWorkflowBlockedSchema,
203
206
  ]).refine((data) => (data.pending ? data.ackToken != null : true), { message: 'ackToken is required when a pending step exists' });
207
+ exports.V2CheckpointWorkflowOutputSchema = zod_1.z.object({
208
+ checkpointNodeId: zod_1.z.string().min(1),
209
+ stateToken: zod_1.z.string().regex(/^st1[023456789acdefghjklmnpqrstuvwxyz]+$/, 'Invalid stateToken format'),
210
+ });
204
211
  exports.V2StartWorkflowOutputSchema = zod_1.z.object({
205
212
  stateToken: zod_1.z.string().regex(/^st1[023456789acdefghjklmnpqrstuvwxyz]+$/, 'Invalid stateToken format'),
206
213
  ackToken: zod_1.z.string().regex(/^ack1[023456789acdefghjklmnpqrstuvwxyz]+$/, 'Invalid ackToken format').optional(),
214
+ checkpointToken: checkpointTokenSchema,
207
215
  isComplete: zod_1.z.boolean(),
208
216
  pending: exports.V2PendingStepSchema.nullable(),
209
217
  preferences: exports.V2PreferencesSchema,
@@ -114,6 +114,15 @@ Parameters:
114
114
  - output.notesMarkdown (optional, advance only): Fresh summary of THIS step only - never accumulated
115
115
 
116
116
  The workflow is the user's structured instructions. Follow each step exactly as described.`,
117
+ checkpoint_workflow: `Save a checkpoint on the current workflow step (WorkRail v2, feature-flagged).
118
+
119
+ Creates a durable checkpoint on your current step without advancing. Useful for saving progress on long-running steps.
120
+
121
+ Requires: checkpointToken (from the most recent start_workflow or continue_workflow response).
122
+
123
+ Idempotent: calling with the same checkpointToken multiple times is safe and returns the same result.
124
+
125
+ Returns: checkpointNodeId + a fresh stateToken.`,
117
126
  },
118
127
  authoritative: {
119
128
  discover_workflows: `Check for workflows that apply to the user's request. Workflows are the user's pre-defined instructions that you MUST follow when they exist.
@@ -252,5 +261,12 @@ Parameters:
252
261
  - output.notesMarkdown (optional, advance only): Summary of THIS step only (fresh, never accumulated)
253
262
 
254
263
  The workflow is the user's structured will. Follow it exactly — it may validate, loop, or branch in ways you don't predict.`,
264
+ checkpoint_workflow: `Save a checkpoint on the current workflow step (WorkRail v2, feature-flagged).
265
+
266
+ Creates a durable checkpoint without advancing. Use for long-running steps to save progress.
267
+
268
+ Requires: checkpointToken from the most recent response. Idempotent.
269
+
270
+ Returns: checkpointNodeId + fresh stateToken.`,
255
271
  },
256
272
  };
package/dist/mcp/tools.js CHANGED
@@ -82,6 +82,11 @@ exports.WORKFLOW_TOOL_ANNOTATIONS = {
82
82
  destructiveHint: false,
83
83
  idempotentHint: true,
84
84
  },
85
+ checkpoint_workflow: {
86
+ readOnlyHint: false,
87
+ destructiveHint: false,
88
+ idempotentHint: true,
89
+ },
85
90
  };
86
91
  exports.WORKFLOW_TOOL_TITLES = {
87
92
  discover_workflows: 'Discover Available Workflows',
@@ -93,6 +98,7 @@ exports.WORKFLOW_TOOL_TITLES = {
93
98
  inspect_workflow: 'Inspect Workflow (v2)',
94
99
  start_workflow: 'Start Workflow (v2)',
95
100
  continue_workflow: 'Continue Workflow (v2)',
101
+ checkpoint_workflow: 'Checkpoint Workflow (v2)',
96
102
  };
97
103
  exports.CreateSessionInput = zod_1.z.object({
98
104
  workflowId: zod_1.z
@@ -1,6 +1,6 @@
1
1
  export declare const DESCRIPTION_MODES: readonly ["standard", "authoritative"];
2
2
  export type DescriptionMode = typeof DESCRIPTION_MODES[number];
3
- export declare const WORKFLOW_TOOL_NAMES: readonly ["discover_workflows", "preview_workflow", "advance_workflow", "validate_workflow", "get_workflow_schema", "list_workflows", "inspect_workflow", "start_workflow", "continue_workflow"];
3
+ export declare const WORKFLOW_TOOL_NAMES: readonly ["discover_workflows", "preview_workflow", "advance_workflow", "validate_workflow", "get_workflow_schema", "list_workflows", "inspect_workflow", "start_workflow", "continue_workflow", "checkpoint_workflow"];
4
4
  export type WorkflowToolName = typeof WORKFLOW_TOOL_NAMES[number];
5
5
  export type ToolDescriptionMap = Readonly<Record<WorkflowToolName, string>>;
6
6
  export type DescriptionsByMode = Readonly<Record<DescriptionMode, ToolDescriptionMap>>;
@@ -17,6 +17,7 @@ exports.WORKFLOW_TOOL_NAMES = [
17
17
  'inspect_workflow',
18
18
  'start_workflow',
19
19
  'continue_workflow',
20
+ 'checkpoint_workflow',
20
21
  ];
21
22
  function isDescriptionMode(value) {
22
23
  return exports.DESCRIPTION_MODES.includes(value);
@@ -2,7 +2,7 @@ import type { z } from 'zod';
2
2
  import type { ToolDefinition } from '../tool-factory.js';
3
3
  import type { ToolContext } from '../types.js';
4
4
  export type V1WorkflowToolName = 'discover_workflows' | 'preview_workflow' | 'advance_workflow' | 'validate_workflow' | 'get_workflow_schema';
5
- export type V2WorkflowToolName = 'list_workflows' | 'inspect_workflow' | 'start_workflow' | 'continue_workflow';
5
+ export type V2WorkflowToolName = 'list_workflows' | 'inspect_workflow' | 'start_workflow' | 'continue_workflow' | 'checkpoint_workflow';
6
6
  export type McpCallToolResult = {
7
7
  readonly content: ReadonlyArray<{
8
8
  readonly type: 'text';
@@ -5,6 +5,7 @@ const handler_factory_js_1 = require("../handler-factory.js");
5
5
  const tools_js_1 = require("./tools.js");
6
6
  const v2_execution_js_1 = require("../handlers/v2-execution.js");
7
7
  const v2_workflow_js_1 = require("../handlers/v2-workflow.js");
8
+ const v2_checkpoint_js_1 = require("../handlers/v2-checkpoint.js");
8
9
  function buildV2ToolRegistry(buildTool) {
9
10
  const tools = [
10
11
  buildTool({
@@ -31,12 +32,19 @@ function buildV2ToolRegistry(buildTool) {
31
32
  inputSchema: tools_js_1.V2ContinueWorkflowInput,
32
33
  annotations: tools_js_1.V2_TOOL_ANNOTATIONS.continue_workflow,
33
34
  }),
35
+ buildTool({
36
+ name: 'checkpoint_workflow',
37
+ title: tools_js_1.V2_TOOL_TITLES.checkpoint_workflow,
38
+ inputSchema: tools_js_1.V2CheckpointWorkflowInput,
39
+ annotations: tools_js_1.V2_TOOL_ANNOTATIONS.checkpoint_workflow,
40
+ }),
34
41
  ];
35
42
  const handlers = {
36
43
  list_workflows: (0, handler_factory_js_1.createHandler)(tools_js_1.V2ListWorkflowsInput, v2_workflow_js_1.handleV2ListWorkflows),
37
44
  inspect_workflow: (0, handler_factory_js_1.createHandler)(tools_js_1.V2InspectWorkflowInput, v2_workflow_js_1.handleV2InspectWorkflow),
38
45
  start_workflow: (0, handler_factory_js_1.createHandler)(tools_js_1.V2StartWorkflowInput, v2_execution_js_1.handleV2StartWorkflow),
39
46
  continue_workflow: (0, handler_factory_js_1.createHandler)(tools_js_1.V2ContinueWorkflowInput, v2_execution_js_1.handleV2ContinueWorkflow),
47
+ checkpoint_workflow: (0, handler_factory_js_1.createHandler)(tools_js_1.V2CheckpointWorkflowInput, v2_checkpoint_js_1.handleV2CheckpointWorkflow),
40
48
  };
41
49
  return { tools, handlers };
42
50
  }
@@ -77,10 +77,19 @@ export declare const V2ContinueWorkflowInput: z.ZodEffects<z.ZodObject<{
77
77
  ackToken?: string | undefined;
78
78
  }>;
79
79
  export type V2ContinueWorkflowInput = z.infer<typeof V2ContinueWorkflowInput>;
80
+ export declare const V2CheckpointWorkflowInput: z.ZodObject<{
81
+ checkpointToken: z.ZodString;
82
+ }, "strict", z.ZodTypeAny, {
83
+ checkpointToken: string;
84
+ }, {
85
+ checkpointToken: string;
86
+ }>;
87
+ export type V2CheckpointWorkflowInput = z.infer<typeof V2CheckpointWorkflowInput>;
80
88
  export declare const V2_TOOL_TITLES: {
81
89
  readonly list_workflows: "List Workflows (v2)";
82
90
  readonly inspect_workflow: "Inspect Workflow (v2)";
83
91
  readonly start_workflow: "Start Workflow (v2)";
84
92
  readonly continue_workflow: "Continue Workflow (v2)";
93
+ readonly checkpoint_workflow: "Checkpoint Workflow (v2)";
85
94
  };
86
95
  export declare const V2_TOOL_ANNOTATIONS: Readonly<Record<keyof typeof V2_TOOL_TITLES, ToolAnnotations>>;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.V2_TOOL_ANNOTATIONS = exports.V2_TOOL_TITLES = exports.V2ContinueWorkflowInput = exports.V2StartWorkflowInput = exports.V2InspectWorkflowInput = exports.V2ListWorkflowsInput = void 0;
3
+ exports.V2_TOOL_ANNOTATIONS = exports.V2_TOOL_TITLES = exports.V2CheckpointWorkflowInput = exports.V2ContinueWorkflowInput = exports.V2StartWorkflowInput = exports.V2InspectWorkflowInput = exports.V2ListWorkflowsInput = void 0;
4
4
  const zod_1 = require("zod");
5
5
  exports.V2ListWorkflowsInput = zod_1.z.object({});
6
6
  exports.V2InspectWorkflowInput = zod_1.z.object({
@@ -54,15 +54,21 @@ exports.V2ContinueWorkflowInput = zod_1.z.object({
54
54
  });
55
55
  }
56
56
  });
57
+ exports.V2CheckpointWorkflowInput = zod_1.z.object({
58
+ checkpointToken: zod_1.z.string().min(1).describe('The checkpoint token from the most recent start_workflow or continue_workflow response. ' +
59
+ 'Creates a checkpoint on the current step without advancing. Idempotent — calling with the same token is safe.'),
60
+ }).strict();
57
61
  exports.V2_TOOL_TITLES = {
58
62
  list_workflows: 'List Workflows (v2)',
59
63
  inspect_workflow: 'Inspect Workflow (v2)',
60
64
  start_workflow: 'Start Workflow (v2)',
61
65
  continue_workflow: 'Continue Workflow (v2)',
66
+ checkpoint_workflow: 'Checkpoint Workflow (v2)',
62
67
  };
63
68
  exports.V2_TOOL_ANNOTATIONS = {
64
69
  list_workflows: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },
65
70
  inspect_workflow: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },
66
71
  start_workflow: { readOnlyHint: false, destructiveHint: false, idempotentHint: false },
67
72
  continue_workflow: { readOnlyHint: false, destructiveHint: false, idempotentHint: true },
73
+ checkpoint_workflow: { readOnlyHint: false, destructiveHint: false, idempotentHint: true },
68
74
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@exaudeus/workrail",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "description": "Step-by-step workflow enforcement for AI agents via MCP",
5
5
  "license": "MIT",
6
6
  "repository": {