@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.
- package/dist/manifest.json +34 -26
- package/dist/mcp/handlers/v2-checkpoint.d.ts +3 -0
- package/dist/mcp/handlers/v2-checkpoint.js +184 -0
- package/dist/mcp/handlers/v2-execution.js +32 -0
- package/dist/mcp/handlers/v2-token-ops.d.ts +10 -0
- package/dist/mcp/handlers/v2-token-ops.js +20 -0
- package/dist/mcp/output-schemas.d.ts +25 -0
- package/dist/mcp/output-schemas.js +9 -1
- package/dist/mcp/tool-descriptions.js +16 -0
- package/dist/mcp/tools.js +6 -0
- package/dist/mcp/types/tool-description-types.d.ts +1 -1
- package/dist/mcp/types/tool-description-types.js +1 -0
- package/dist/mcp/types/workflow-tool-edition.d.ts +1 -1
- package/dist/mcp/v2/tool-registry.js +8 -0
- package/dist/mcp/v2/tools.d.ts +9 -0
- package/dist/mcp/v2/tools.js +7 -1
- package/package.json +1 -1
package/dist/manifest.json
CHANGED
|
@@ -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": "
|
|
586
|
-
"bytes":
|
|
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": "
|
|
598
|
-
"bytes":
|
|
605
|
+
"sha256": "2101c6f44398909b045adf0904dcec10448bb0fd69d85eab352488ee752959e0",
|
|
606
|
+
"bytes": 1853
|
|
599
607
|
},
|
|
600
608
|
"mcp/handlers/v2-token-ops.js": {
|
|
601
|
-
"sha256": "
|
|
602
|
-
"bytes":
|
|
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": "
|
|
630
|
-
"bytes":
|
|
637
|
+
"sha256": "ae6188036f2e379c9f5498f7256f658e5bdd5301024e7bd863d02ca3dfad9f41",
|
|
638
|
+
"bytes": 43607
|
|
631
639
|
},
|
|
632
640
|
"mcp/output-schemas.js": {
|
|
633
|
-
"sha256": "
|
|
634
|
-
"bytes":
|
|
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": "
|
|
658
|
-
"bytes":
|
|
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": "
|
|
674
|
-
"bytes":
|
|
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": "
|
|
686
|
-
"bytes":
|
|
693
|
+
"sha256": "41e31c87b6d5b2e0fb4b66b1e8fac3f74c9769c3ded8a26577804aeccb79ae7b",
|
|
694
|
+
"bytes": 805
|
|
687
695
|
},
|
|
688
696
|
"mcp/types/tool-description-types.js": {
|
|
689
|
-
"sha256": "
|
|
690
|
-
"bytes":
|
|
697
|
+
"sha256": "689e74ea09e25e51de6020e42de42c37965e55980635d8739fc9ad19ba341955",
|
|
698
|
+
"bytes": 777
|
|
691
699
|
},
|
|
692
700
|
"mcp/types/workflow-tool-edition.d.ts": {
|
|
693
|
-
"sha256": "
|
|
694
|
-
"bytes":
|
|
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": "
|
|
714
|
-
"bytes":
|
|
721
|
+
"sha256": "719429102bc33c9e5bcd7cf38b0242ecc038484de4159811fbe9b0efa2ebc460",
|
|
722
|
+
"bytes": 2623
|
|
715
723
|
},
|
|
716
724
|
"mcp/v2/tools.d.ts": {
|
|
717
|
-
"sha256": "
|
|
718
|
-
"bytes":
|
|
725
|
+
"sha256": "8fba15da4a60a46ed803046f9b61ea0b8947967880563562473d8a87de68d27c",
|
|
726
|
+
"bytes": 3600
|
|
719
727
|
},
|
|
720
728
|
"mcp/v2/tools.js": {
|
|
721
|
-
"sha256": "
|
|
722
|
-
"bytes":
|
|
729
|
+
"sha256": "93f33152aebe0cbeb92daa727a3dc43ccb3f4cc1001e7564fdd7b31ee78b2475",
|
|
730
|
+
"bytes": 5743
|
|
723
731
|
},
|
|
724
732
|
"mcp/validation/bounded-json.d.ts": {
|
|
725
733
|
"sha256": "82203ac6123d5c6989606c3b5405aaea99ab829c8958835f9ae3ba45b8bc8fd5",
|
|
@@ -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>>;
|
|
@@ -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
|
}
|
package/dist/mcp/v2/tools.d.ts
CHANGED
|
@@ -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>>;
|
package/dist/mcp/v2/tools.js
CHANGED
|
@@ -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
|
};
|