@exaudeus/workrail 1.3.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/dist/manifest.json +108 -36
  2. package/dist/mcp/handlers/v2-checkpoint.d.ts +3 -0
  3. package/dist/mcp/handlers/v2-checkpoint.js +184 -0
  4. package/dist/mcp/handlers/v2-execution.js +32 -0
  5. package/dist/mcp/handlers/v2-resume.d.ts +8 -0
  6. package/dist/mcp/handlers/v2-resume.js +70 -0
  7. package/dist/mcp/handlers/v2-token-ops.d.ts +10 -0
  8. package/dist/mcp/handlers/v2-token-ops.js +20 -0
  9. package/dist/mcp/output-schemas.d.ts +65 -0
  10. package/dist/mcp/output-schemas.js +25 -1
  11. package/dist/mcp/server.js +12 -0
  12. package/dist/mcp/tool-descriptions.js +38 -0
  13. package/dist/mcp/tools.js +12 -0
  14. package/dist/mcp/types/tool-description-types.d.ts +1 -1
  15. package/dist/mcp/types/tool-description-types.js +2 -0
  16. package/dist/mcp/types/workflow-tool-edition.d.ts +1 -1
  17. package/dist/mcp/types.d.ts +6 -0
  18. package/dist/mcp/v2/tool-registry.js +16 -0
  19. package/dist/mcp/v2/tools.d.ts +24 -0
  20. package/dist/mcp/v2/tools.js +14 -1
  21. package/dist/v2/infra/local/directory-listing/index.d.ts +8 -0
  22. package/dist/v2/infra/local/directory-listing/index.js +18 -0
  23. package/dist/v2/infra/local/fs/index.d.ts +1 -0
  24. package/dist/v2/infra/local/fs/index.js +3 -0
  25. package/dist/v2/infra/local/session-summary-provider/index.d.ts +18 -0
  26. package/dist/v2/infra/local/session-summary-provider/index.js +141 -0
  27. package/dist/v2/ports/directory-listing.port.d.ts +5 -0
  28. package/dist/v2/ports/directory-listing.port.js +2 -0
  29. package/dist/v2/ports/fs.port.d.ts +1 -0
  30. package/dist/v2/ports/session-summary-provider.port.d.ts +9 -0
  31. package/dist/v2/ports/session-summary-provider.port.js +2 -0
  32. package/dist/v2/projections/resume-ranking.d.ts +62 -0
  33. package/dist/v2/projections/resume-ranking.js +105 -0
  34. package/dist/v2/usecases/enumerate-sessions.d.ts +9 -0
  35. package/dist/v2/usecases/enumerate-sessions.js +13 -0
  36. package/dist/v2/usecases/resume-session.d.ts +4 -0
  37. package/dist/v2/usecases/resume-session.js +9 -0
  38. package/package.json +1 -1
@@ -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,16 @@
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
595
+ },
596
+ "mcp/handlers/v2-resume.d.ts": {
597
+ "sha256": "d88f6c35bcaf946666c837b72fda3702a2ebab5e478eb90f7b4b672a0e5fa24f",
598
+ "bytes": 471
599
+ },
600
+ "mcp/handlers/v2-resume.js": {
601
+ "sha256": "b4ce6f9cc3dffef91ca7da2e428d659c4ff79ceaf984c87d672290215936db97",
602
+ "bytes": 2771
587
603
  },
588
604
  "mcp/handlers/v2-state-conversion.d.ts": {
589
605
  "sha256": "e8d70753ed1b83d9396864ef50929ba32cb008bda24bcb2ce624df24adb72570",
@@ -594,12 +610,12 @@
594
610
  "bytes": 5216
595
611
  },
596
612
  "mcp/handlers/v2-token-ops.d.ts": {
597
- "sha256": "64b143576c2741497f393513bb2d04010f3754c8d066c47cbff5819d072f8eea",
598
- "bytes": 1504
613
+ "sha256": "2101c6f44398909b045adf0904dcec10448bb0fd69d85eab352488ee752959e0",
614
+ "bytes": 1853
599
615
  },
600
616
  "mcp/handlers/v2-token-ops.js": {
601
- "sha256": "27d5b08e3ce3ba984a8258cfbbede7e525039cbcde55a411c74f3c0fd60f91bf",
602
- "bytes": 2851
617
+ "sha256": "c786c2a8de7240989b2368762552373a2c3d397edd47122144c51e31a22d6203",
618
+ "bytes": 3817
603
619
  },
604
620
  "mcp/handlers/v2-workflow.d.ts": {
605
621
  "sha256": "9fbd4d44854e2060c54982b21e72c608970bb2bd107bb15a8388b26c6b492e55",
@@ -626,20 +642,20 @@
626
642
  "bytes": 7535
627
643
  },
628
644
  "mcp/output-schemas.d.ts": {
629
- "sha256": "2e26bc2e2f457dcd2325bbab67a19ce4ed81896eb87b0981094f68c76937f08c",
630
- "bytes": 42678
645
+ "sha256": "f18366a180449212d9a2b280dc9706f4f96a77ccead38bf11035c3859121fd84",
646
+ "bytes": 45137
631
647
  },
632
648
  "mcp/output-schemas.js": {
633
- "sha256": "11fbd471a6b56aa8df3c3d002e4d660da3d034b4fbab82871d810c1d25152283",
634
- "bytes": 10346
649
+ "sha256": "e7aeb43d06950e4a9ed1fa4ecd56418dc7eb32f54453634701b5dc39456eb3e8",
650
+ "bytes": 11565
635
651
  },
636
652
  "mcp/server.d.ts": {
637
653
  "sha256": "bec49b8d07e189a53db7100d2f0e1e84ffe03150f04e1b06908ee3282982b4a2",
638
654
  "bytes": 168
639
655
  },
640
656
  "mcp/server.js": {
641
- "sha256": "8c7afb047807dd5fcd461b813b7bc714ea375d0999dfe9a7c901bf1462798455",
642
- "bytes": 9940
657
+ "sha256": "37ab570be76b379a4076e78e5bc82a06b7ee1fc73d3d5010ad48b5650e54365a",
658
+ "bytes": 10631
643
659
  },
644
660
  "mcp/tool-description-provider.d.ts": {
645
661
  "sha256": "1d46abc3112e11b68e57197e846f5708293ec9b2281fa71a9124ee2aad71e41b",
@@ -654,8 +670,8 @@
654
670
  "bytes": 132
655
671
  },
656
672
  "mcp/tool-descriptions.js": {
657
- "sha256": "4a713e4cad3b59077c42d95c78b5a1b68b93830def6f0d39db4ed79562c8a6e3",
658
- "bytes": 14568
673
+ "sha256": "76d25a3a2bba38227ad199c4d1240769b6b14411ebecf965e9e00eaac2f2e01c",
674
+ "bytes": 16389
659
675
  },
660
676
  "mcp/tool-factory.d.ts": {
661
677
  "sha256": "0fe3c6b863b2d7aef0c3d659ff54f3a9ee8a0a3c2005b6565d2f8ad517bc7211",
@@ -670,28 +686,28 @@
670
686
  "bytes": 5976
671
687
  },
672
688
  "mcp/tools.js": {
673
- "sha256": "0af59932b32bad5ebc9cbc925279d325350c91b43085561d0d218035250b641a",
674
- "bytes": 8020
689
+ "sha256": "aa364f3e613fc61a39fc7336a723231da06852d92ec7840a95327aa370e42e1c",
690
+ "bytes": 8360
675
691
  },
676
692
  "mcp/types.d.ts": {
677
- "sha256": "9e29d5ae4ec1f80640f073f0d58b603158fe5b22897f44c1c77ed4abaef374f9",
678
- "bytes": 3638
693
+ "sha256": "564136878ad3e71300d5e82913590b1f43d3dfbafab36479c9a590853cd07a0a",
694
+ "bytes": 4050
679
695
  },
680
696
  "mcp/types.js": {
681
697
  "sha256": "0c12576fd0053115ff096fe26b38f77f1e830b7ec4781aaf94564827c4c9e81a",
682
698
  "bytes": 1253
683
699
  },
684
700
  "mcp/types/tool-description-types.d.ts": {
685
- "sha256": "7d0fb489a829f7d21ed0d3fe9cef221ff71b63619054070287bc790bf5142a28",
686
- "bytes": 782
701
+ "sha256": "80984afa5283a0d651ff22c0c9b2d3ff14c85087aeaf735d306ae291d8cdfe4d",
702
+ "bytes": 823
687
703
  },
688
704
  "mcp/types/tool-description-types.js": {
689
- "sha256": "a1c1fdd901bf6a074d9a48cef09e0020c59d9838bfb8754ed2aaf9c23191a533",
690
- "bytes": 750
705
+ "sha256": "40c1e5f76edcbfbdf18f203dae2f295cce191b6af670436aeff5bc65d74d1a6b",
706
+ "bytes": 799
691
707
  },
692
708
  "mcp/types/workflow-tool-edition.d.ts": {
693
- "sha256": "7407d318a9f0cc7d6dc81d7cb003e474b3a31a52bf3e600e07ee94f556e2555a",
694
- "bytes": 1470
709
+ "sha256": "ebde63f0ea9de501946d75e050c9676c03d08b77b27ad858d88600249e480f6c",
710
+ "bytes": 1513
695
711
  },
696
712
  "mcp/types/workflow-tool-edition.js": {
697
713
  "sha256": "2dfd26acd3da2c249b728e7fc48c7eab3dc675f786e7689dbdeec53c25589369",
@@ -710,16 +726,16 @@
710
726
  "bytes": 408
711
727
  },
712
728
  "mcp/v2/tool-registry.js": {
713
- "sha256": "8c94984fed94f049daeb01559a2490b7db6fedac2544b3e7e50a60b8c7dfa561",
714
- "bytes": 2121
729
+ "sha256": "4b192604ddafd986416865041db7e395d205da6fa1d398bec07646900f6ce28c",
730
+ "bytes": 3078
715
731
  },
716
732
  "mcp/v2/tools.d.ts": {
717
- "sha256": "a262c0c17ff9474f017ac1e83d4458c773791604ec4f344f777dcdbefff9318b",
718
- "bytes": 3263
733
+ "sha256": "5da50237fcbce6240737441d134c8070256a23649b387d5c3438b41b2705905e",
734
+ "bytes": 4156
719
735
  },
720
736
  "mcp/v2/tools.js": {
721
- "sha256": "00c6710f31a9cb42215a1427f48b3e22a1065996dfdaaaf4ae2389f3c23e9aa5",
722
- "bytes": 5221
737
+ "sha256": "5c9b958f1a9eb609557ed5867fc9ea131a2a0a4aaf52ff05a38246dffe2b359d",
738
+ "bytes": 6435
723
739
  },
724
740
  "mcp/validation/bounded-json.d.ts": {
725
741
  "sha256": "82203ac6123d5c6989606c3b5405aaea99ab829c8958835f9ae3ba45b8bc8fd5",
@@ -1521,13 +1537,21 @@
1521
1537
  "sha256": "02d0ad7e3b8c615c6fa3fead6698664d282b2375ea3fc8bd563c12cc7853691c",
1522
1538
  "bytes": 3012
1523
1539
  },
1540
+ "v2/infra/local/directory-listing/index.d.ts": {
1541
+ "sha256": "18fd3d9d74c5541fe95f01be6dd276c6cf6ecf1426fcd0ad1e695d756d9ef93e",
1542
+ "bytes": 429
1543
+ },
1544
+ "v2/infra/local/directory-listing/index.js": {
1545
+ "sha256": "1930cb982b9034f46751a000011ea069b6e03becd898973afad4b74e6ebc1759",
1546
+ "bytes": 566
1547
+ },
1524
1548
  "v2/infra/local/fs/index.d.ts": {
1525
- "sha256": "d830aed74ebb3372ea5efa21ec96680cd188fc76dea6078286f5788b3736d2bf",
1526
- "bytes": 1252
1549
+ "sha256": "fe3f06badea2d62e9ade3954f716d0b7aa4778c4d49e5fb9f6f58db6d2e9429a",
1550
+ "bytes": 1323
1527
1551
  },
1528
1552
  "v2/infra/local/fs/index.js": {
1529
- "sha256": "97ce973a4bd48aa43e890fb18dc7b8c8b3f8451400539bf15b4c79f3680e2ba3",
1530
- "bytes": 7045
1553
+ "sha256": "05fcd1345b3f003c19a13ee8db4ef657f23815c253e4fa36fa4bd7092f0a0b68",
1554
+ "bytes": 7179
1531
1555
  },
1532
1556
  "v2/infra/local/hmac-sha256/index.d.ts": {
1533
1557
  "sha256": "dda3865510dfaf2f13947410d998da6ffecc9a2e728b3574f81e69d5db859815",
@@ -1585,6 +1609,14 @@
1585
1609
  "sha256": "53b9ee8545d99e23cfeecb12b39d202fc552c3e89de9fe71b5d1aaaf9afa6d95",
1586
1610
  "bytes": 29559
1587
1611
  },
1612
+ "v2/infra/local/session-summary-provider/index.d.ts": {
1613
+ "sha256": "8843c26694d12147c322a4ff1f220cef53774c1ea7087241cb6badd12a360fda",
1614
+ "bytes": 1069
1615
+ },
1616
+ "v2/infra/local/session-summary-provider/index.js": {
1617
+ "sha256": "d75b34ff09b4e5b0e4cd1b75b67c4efe643db0231afc919da54c29034c1c5c1d",
1618
+ "bytes": 5566
1619
+ },
1588
1620
  "v2/infra/local/sha256/index.d.ts": {
1589
1621
  "sha256": "8a727b7e54a38275ca6f9f1b8730f97cfc0a212df035df1bdc58e716e6824230",
1590
1622
  "bytes": 246
@@ -1657,9 +1689,17 @@
1657
1689
  "sha256": "d43aa81f5bc89faa359e0f97c814ba25155591ff078fbb9bfd40f8c7c9683230",
1658
1690
  "bytes": 77
1659
1691
  },
1692
+ "v2/ports/directory-listing.port.d.ts": {
1693
+ "sha256": "3184229b7793bbd3100611c6308d33a96145c4dc63ba451d8c29ff507084e7b4",
1694
+ "bytes": 207
1695
+ },
1696
+ "v2/ports/directory-listing.port.js": {
1697
+ "sha256": "d43aa81f5bc89faa359e0f97c814ba25155591ff078fbb9bfd40f8c7c9683230",
1698
+ "bytes": 77
1699
+ },
1660
1700
  "v2/ports/fs.port.d.ts": {
1661
- "sha256": "e752765aa1154de19c720590410a370c3ae485d73363dd66cf9cc17fcf75c103",
1662
- "bytes": 1534
1701
+ "sha256": "e4d80716cbfe86352f9017480af31f21e25dfea97c7449b384fe64237bba961d",
1702
+ "bytes": 1605
1663
1703
  },
1664
1704
  "v2/ports/fs.port.js": {
1665
1705
  "sha256": "d43aa81f5bc89faa359e0f97c814ba25155591ff078fbb9bfd40f8c7c9683230",
@@ -1713,6 +1753,14 @@
1713
1753
  "sha256": "d43aa81f5bc89faa359e0f97c814ba25155591ff078fbb9bfd40f8c7c9683230",
1714
1754
  "bytes": 77
1715
1755
  },
1756
+ "v2/ports/session-summary-provider.port.d.ts": {
1757
+ "sha256": "41861cb0e70ca81e0d931d9f504226c9c7361f59db21a8beab95c2b8ed13cb57",
1758
+ "bytes": 400
1759
+ },
1760
+ "v2/ports/session-summary-provider.port.js": {
1761
+ "sha256": "d43aa81f5bc89faa359e0f97c814ba25155591ff078fbb9bfd40f8c7c9683230",
1762
+ "bytes": 77
1763
+ },
1716
1764
  "v2/ports/sha256.port.d.ts": {
1717
1765
  "sha256": "2ca3e0558992a96614d005582e1f38435de4335df82f8231f69eabf191272022",
1718
1766
  "bytes": 145
@@ -1809,6 +1857,14 @@
1809
1857
  "sha256": "c8190e4899ba9695c7c7a9e58e872d4a56c90dcb4dfde659d6c2801a8cb895a7",
1810
1858
  "bytes": 732
1811
1859
  },
1860
+ "v2/projections/resume-ranking.d.ts": {
1861
+ "sha256": "50ef48d0b195f89f01c0051be453666e6a680e356ca9c328a754aced90ee8d7a",
1862
+ "bytes": 2337
1863
+ },
1864
+ "v2/projections/resume-ranking.js": {
1865
+ "sha256": "4253bd05c81e4b5a95b3472cca9ea3c2d7e9e28fdaabe95c984a1165ecc3a69c",
1866
+ "bytes": 4232
1867
+ },
1812
1868
  "v2/projections/run-context.d.ts": {
1813
1869
  "sha256": "7bdc4b2bacfb4b42005b7a83d7ddaf8a8d414bed90b948c02dbeeacd741b31cc",
1814
1870
  "bytes": 909
@@ -1849,6 +1905,14 @@
1849
1905
  "sha256": "6ea788b80605db6d2057b3d5e520be48ace8afe6d8f37bf55cef00ba1471a6b7",
1850
1906
  "bytes": 1935
1851
1907
  },
1908
+ "v2/usecases/enumerate-sessions.d.ts": {
1909
+ "sha256": "6043d64b45360dfc6a15b822d9f013a0832127596706bf81569dfce256236d2d",
1910
+ "bytes": 499
1911
+ },
1912
+ "v2/usecases/enumerate-sessions.js": {
1913
+ "sha256": "99e135a7c7411ce850c9dd89963ef6a05d3488078d6c6b2c540cb2d2043a2e89",
1914
+ "bytes": 526
1915
+ },
1852
1916
  "v2/usecases/execution-session-gate.d.ts": {
1853
1917
  "sha256": "339c4a8e02a77416e725e063a57d39a20788244498ae2c7a31dc48d111af6280",
1854
1918
  "bytes": 2084
@@ -1872,6 +1936,14 @@
1872
1936
  "v2/usecases/import-session.js": {
1873
1937
  "sha256": "9b9c8922cc2e6d6904f564c35ff0e402a2e755187f36ee7e54e76826f51bed5c",
1874
1938
  "bytes": 2788
1939
+ },
1940
+ "v2/usecases/resume-session.d.ts": {
1941
+ "sha256": "02eec4908e02dc591bff06b0d38d686aad64719694fd353670b2b1d17d8f9543",
1942
+ "bytes": 434
1943
+ },
1944
+ "v2/usecases/resume-session.js": {
1945
+ "sha256": "db50776bbbd18f0a07c0c1b0d94689f78596d980824f4fe73f5cbe47a62d0d60",
1946
+ "bytes": 393
1875
1947
  }
1876
1948
  }
1877
1949
  }
@@ -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,
@@ -0,0 +1,8 @@
1
+ import type { z } from 'zod';
2
+ import type { V2ResumeSessionInput } from '../v2/tools.js';
3
+ import type { ToolContext, ToolResult } from '../types.js';
4
+ import { V2ResumeSessionOutputSchema } from '../output-schemas.js';
5
+ type ResumeInput = z.infer<typeof V2ResumeSessionInput>;
6
+ type ResumeOutput = z.infer<typeof V2ResumeSessionOutputSchema>;
7
+ export declare function handleV2ResumeSession(input: ResumeInput, ctx: ToolContext): Promise<ToolResult<ResumeOutput>>;
8
+ export {};
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handleV2ResumeSession = handleV2ResumeSession;
4
+ const types_js_1 = require("../types.js");
5
+ const output_schemas_js_1 = require("../output-schemas.js");
6
+ const v2_token_ops_js_1 = require("./v2-token-ops.js");
7
+ const index_js_1 = require("../../v2/durable-core/ids/index.js");
8
+ const resume_session_js_1 = require("../../v2/usecases/resume-session.js");
9
+ function anchorValue(anchors, key) {
10
+ const anchor = anchors.find((a) => a.key === key);
11
+ return anchor?.value;
12
+ }
13
+ async function handleV2ResumeSession(input, ctx) {
14
+ const v2 = ctx.v2;
15
+ if (!v2) {
16
+ return (0, types_js_1.errNotRetryable)('INTERNAL_ERROR', 'v2 dependencies not available');
17
+ }
18
+ if (!v2.sessionSummaryProvider) {
19
+ return (0, types_js_1.errNotRetryable)('INTERNAL_ERROR', 'resume_session requires sessionSummaryProvider port');
20
+ }
21
+ let anchors = [];
22
+ if (v2.workspaceAnchor) {
23
+ const anchorRes = await v2.workspaceAnchor.resolveAnchors();
24
+ if (anchorRes.isOk()) {
25
+ anchors = anchorRes.value;
26
+ }
27
+ }
28
+ const query = {
29
+ gitHeadSha: input.gitHeadSha ?? anchorValue(anchors, 'git_head_sha'),
30
+ gitBranch: input.gitBranch ?? anchorValue(anchors, 'git_branch'),
31
+ freeTextQuery: input.query,
32
+ };
33
+ const resumeResult = await (0, resume_session_js_1.resumeSession)(query, v2.sessionSummaryProvider);
34
+ if (resumeResult.isErr()) {
35
+ return (0, types_js_1.errNotRetryable)('INTERNAL_ERROR', `Resume failed: ${resumeResult.error.message}`);
36
+ }
37
+ const candidates = resumeResult.value;
38
+ const outputCandidates = [];
39
+ for (const candidate of candidates) {
40
+ const stateTokenRes = (0, v2_token_ops_js_1.signTokenOrErr)({
41
+ payload: {
42
+ tokenVersion: 1,
43
+ tokenKind: 'state',
44
+ sessionId: candidate.sessionId,
45
+ runId: (0, index_js_1.asRunId)(candidate.runId),
46
+ nodeId: (0, index_js_1.asNodeId)(candidate.preferredTipNodeId),
47
+ workflowHashRef: (0, index_js_1.asWorkflowHashRef)(''),
48
+ },
49
+ ports: v2.tokenCodecPorts,
50
+ });
51
+ if (stateTokenRes.isErr()) {
52
+ continue;
53
+ }
54
+ outputCandidates.push({
55
+ sessionId: candidate.sessionId,
56
+ runId: candidate.runId,
57
+ stateToken: stateTokenRes.value,
58
+ snippet: candidate.snippet,
59
+ whyMatched: [...candidate.whyMatched],
60
+ });
61
+ }
62
+ const output = output_schemas_js_1.V2ResumeSessionOutputSchema.parse({
63
+ candidates: outputCandidates,
64
+ totalEligible: candidates.length,
65
+ });
66
+ return {
67
+ type: 'success',
68
+ data: output,
69
+ };
70
+ }
@@ -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;