@exaudeus/workrail 1.4.0 → 1.5.1

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 (168) hide show
  1. package/dist/manifest.json +464 -200
  2. package/dist/mcp/handlers/v2-advance-core/event-builders.d.ts +37 -0
  3. package/dist/mcp/handlers/v2-advance-core/event-builders.js +114 -0
  4. package/dist/mcp/handlers/v2-advance-core/index.d.ts +67 -0
  5. package/dist/mcp/handlers/v2-advance-core/index.js +100 -0
  6. package/dist/mcp/handlers/v2-advance-core/input-validation.d.ts +44 -0
  7. package/dist/mcp/handlers/v2-advance-core/input-validation.js +58 -0
  8. package/dist/mcp/handlers/v2-advance-core/outcome-blocked.d.ts +16 -0
  9. package/dist/mcp/handlers/v2-advance-core/outcome-blocked.js +64 -0
  10. package/dist/mcp/handlers/v2-advance-core/outcome-success.d.ts +15 -0
  11. package/dist/mcp/handlers/v2-advance-core/outcome-success.js +136 -0
  12. package/dist/mcp/handlers/v2-advance-core.d.ts +3 -45
  13. package/dist/mcp/handlers/v2-advance-core.js +3 -431
  14. package/dist/mcp/handlers/v2-advance-events.d.ts +61 -0
  15. package/dist/mcp/handlers/v2-advance-events.js +126 -0
  16. package/dist/mcp/handlers/v2-checkpoint.js +5 -4
  17. package/dist/mcp/handlers/v2-context-budget.js +2 -2
  18. package/dist/mcp/handlers/v2-execution/advance.d.ts +32 -0
  19. package/dist/mcp/handlers/v2-execution/advance.js +50 -0
  20. package/dist/mcp/handlers/v2-execution/continue-advance.d.ts +29 -0
  21. package/dist/mcp/handlers/v2-execution/continue-advance.js +170 -0
  22. package/dist/mcp/handlers/v2-execution/continue-rehydrate.d.ts +22 -0
  23. package/dist/mcp/handlers/v2-execution/continue-rehydrate.js +146 -0
  24. package/dist/mcp/handlers/v2-execution/index.d.ts +23 -0
  25. package/dist/mcp/handlers/v2-execution/index.js +113 -0
  26. package/dist/mcp/handlers/v2-execution/replay.d.ts +55 -0
  27. package/dist/mcp/handlers/v2-execution/replay.js +227 -0
  28. package/dist/mcp/handlers/v2-execution/start.d.ts +52 -0
  29. package/dist/mcp/handlers/v2-execution/start.js +350 -0
  30. package/dist/mcp/handlers/v2-execution-helpers.d.ts +23 -0
  31. package/dist/mcp/handlers/v2-execution-helpers.js +42 -1
  32. package/dist/mcp/handlers/v2-execution.d.ts +1 -23
  33. package/dist/mcp/handlers/v2-execution.js +5 -898
  34. package/dist/mcp/handlers/v2-resume.d.ts +8 -0
  35. package/dist/mcp/handlers/v2-resume.js +70 -0
  36. package/dist/mcp/handlers/v2-state-conversion.d.ts +0 -5
  37. package/dist/mcp/handlers/v2-state-conversion.js +2 -21
  38. package/dist/mcp/handlers/v2-token-ops.d.ts +1 -1
  39. package/dist/mcp/handlers/v2-workflow.js +76 -64
  40. package/dist/mcp/output-schemas.d.ts +40 -0
  41. package/dist/mcp/output-schemas.js +17 -1
  42. package/dist/mcp/server.js +12 -0
  43. package/dist/mcp/tool-descriptions.js +22 -0
  44. package/dist/mcp/tools.js +6 -0
  45. package/dist/mcp/types/tool-description-types.d.ts +1 -1
  46. package/dist/mcp/types/tool-description-types.js +1 -0
  47. package/dist/mcp/types/workflow-tool-edition.d.ts +1 -1
  48. package/dist/mcp/types.d.ts +6 -0
  49. package/dist/mcp/v2/tool-registry.js +8 -0
  50. package/dist/mcp/v2/tools.d.ts +15 -0
  51. package/dist/mcp/v2/tools.js +8 -1
  52. package/dist/v2/durable-core/constants.d.ts +60 -0
  53. package/dist/v2/durable-core/constants.js +55 -1
  54. package/dist/v2/durable-core/domain/ack-advance-append-plan.d.ts +23 -13
  55. package/dist/v2/durable-core/domain/ack-advance-append-plan.js +160 -113
  56. package/dist/v2/durable-core/domain/blocked-node-builder.js +8 -2
  57. package/dist/v2/durable-core/domain/blocking-decision.d.ts +2 -0
  58. package/dist/v2/durable-core/domain/blocking-decision.js +29 -12
  59. package/dist/v2/durable-core/domain/bundle-builder.d.ts +1 -0
  60. package/dist/v2/durable-core/domain/bundle-builder.js +1 -1
  61. package/dist/v2/durable-core/domain/bundle-validator.js +3 -2
  62. package/dist/v2/durable-core/domain/decision-trace-builder.js +7 -9
  63. package/dist/v2/durable-core/domain/function-definition-expander.js +1 -3
  64. package/dist/v2/durable-core/domain/gap-builder.js +2 -1
  65. package/dist/v2/durable-core/domain/observation-builder.js +2 -1
  66. package/dist/v2/durable-core/domain/outputs.d.ts +2 -1
  67. package/dist/v2/durable-core/domain/outputs.js +3 -2
  68. package/dist/v2/durable-core/domain/reason-model.d.ts +1 -1
  69. package/dist/v2/durable-core/domain/reason-model.js +4 -9
  70. package/dist/v2/durable-core/domain/validation-criteria-validator.js +2 -2
  71. package/dist/v2/durable-core/domain/validation-event-builder.js +4 -6
  72. package/dist/v2/durable-core/domain/validation-loader.js +2 -1
  73. package/dist/v2/durable-core/domain/validation-requirements-extractor.js +12 -18
  74. package/dist/v2/durable-core/encoding/base32-lower.d.ts +13 -1
  75. package/dist/v2/durable-core/encoding/base32-lower.js +13 -3
  76. package/dist/v2/durable-core/encoding/hex-to-bytes.d.ts +6 -0
  77. package/dist/v2/durable-core/encoding/hex-to-bytes.js +19 -0
  78. package/dist/v2/durable-core/ids/attempt-id-derivation.d.ts +6 -1
  79. package/dist/v2/durable-core/ids/attempt-id-derivation.js +9 -19
  80. package/dist/v2/durable-core/ids/event-ids.d.ts +9 -0
  81. package/dist/v2/durable-core/ids/event-ids.js +18 -0
  82. package/dist/v2/durable-core/ids/index.d.ts +13 -33
  83. package/dist/v2/durable-core/ids/index.js +22 -63
  84. package/dist/v2/durable-core/ids/session-ids.d.ts +9 -0
  85. package/dist/v2/durable-core/ids/session-ids.js +18 -0
  86. package/dist/v2/durable-core/ids/snapshot-ids.d.ts +6 -0
  87. package/dist/v2/durable-core/ids/snapshot-ids.js +10 -0
  88. package/dist/v2/durable-core/ids/token-ids.d.ts +3 -0
  89. package/dist/v2/durable-core/ids/token-ids.js +6 -0
  90. package/dist/v2/durable-core/ids/workflow-hash-ref.d.ts +3 -0
  91. package/dist/v2/durable-core/ids/workflow-hash-ref.js +5 -4
  92. package/dist/v2/durable-core/ids/workflow-ids.d.ts +11 -0
  93. package/dist/v2/durable-core/ids/workflow-ids.js +21 -0
  94. package/dist/v2/durable-core/lib/utf8-byte-length.d.ts +1 -0
  95. package/dist/v2/durable-core/lib/utf8-byte-length.js +6 -0
  96. package/dist/v2/durable-core/schemas/artifacts/loop-control.js +2 -1
  97. package/dist/v2/durable-core/schemas/execution-snapshot/blocked-snapshot.d.ts +24 -24
  98. package/dist/v2/durable-core/schemas/execution-snapshot/blocked-snapshot.js +5 -7
  99. package/dist/v2/durable-core/schemas/execution-snapshot/execution-snapshot.v1.d.ts +180 -180
  100. package/dist/v2/durable-core/schemas/export-bundle/index.d.ts +282 -287
  101. package/dist/v2/durable-core/schemas/export-bundle/index.js +0 -8
  102. package/dist/v2/durable-core/schemas/lib/dedupe-key.d.ts +9 -1
  103. package/dist/v2/durable-core/schemas/lib/dedupe-key.js +4 -3
  104. package/dist/v2/durable-core/schemas/lib/utf8-byte-length.d.ts +1 -0
  105. package/dist/v2/durable-core/schemas/lib/utf8-byte-length.js +6 -0
  106. package/dist/v2/durable-core/schemas/session/blockers.d.ts +305 -0
  107. package/dist/v2/durable-core/schemas/session/blockers.js +80 -0
  108. package/dist/v2/durable-core/schemas/session/dag-topology.d.ts +77 -0
  109. package/dist/v2/durable-core/schemas/session/dag-topology.js +45 -0
  110. package/dist/v2/durable-core/schemas/session/events.d.ts +36 -36
  111. package/dist/v2/durable-core/schemas/session/events.js +11 -182
  112. package/dist/v2/durable-core/schemas/session/gaps.d.ts +211 -0
  113. package/dist/v2/durable-core/schemas/session/gaps.js +37 -0
  114. package/dist/v2/durable-core/schemas/session/outputs.d.ts +148 -0
  115. package/dist/v2/durable-core/schemas/session/outputs.js +44 -0
  116. package/dist/v2/durable-core/schemas/session/validation-event.js +5 -7
  117. package/dist/v2/durable-core/tokens/token-codec.d.ts +1 -18
  118. package/dist/v2/durable-core/tokens/token-codec.js +0 -67
  119. package/dist/v2/durable-core/tokens/token-signer.d.ts +1 -8
  120. package/dist/v2/durable-core/tokens/token-signer.js +0 -43
  121. package/dist/v2/infra/local/base32/index.js +1 -23
  122. package/dist/v2/infra/local/bech32m/index.js +1 -1
  123. package/dist/v2/infra/local/data-dir/index.d.ts +7 -6
  124. package/dist/v2/infra/local/data-dir/index.js +3 -3
  125. package/dist/v2/infra/local/directory-listing/index.d.ts +8 -0
  126. package/dist/v2/infra/local/directory-listing/index.js +18 -0
  127. package/dist/v2/infra/local/fs/index.d.ts +1 -0
  128. package/dist/v2/infra/local/fs/index.js +3 -0
  129. package/dist/v2/infra/local/session-store/index.js +198 -182
  130. package/dist/v2/infra/local/session-summary-provider/index.d.ts +18 -0
  131. package/dist/v2/infra/local/session-summary-provider/index.js +144 -0
  132. package/dist/v2/infra/local/snapshot-store/index.js +2 -2
  133. package/dist/v2/ports/data-dir.port.d.ts +7 -6
  134. package/dist/v2/ports/directory-listing.port.d.ts +5 -0
  135. package/dist/v2/ports/directory-listing.port.js +2 -0
  136. package/dist/v2/ports/fs.port.d.ts +19 -7
  137. package/dist/v2/ports/session-event-log-store.port.d.ts +5 -2
  138. package/dist/v2/ports/session-summary-provider.port.d.ts +9 -0
  139. package/dist/v2/ports/session-summary-provider.port.js +2 -0
  140. package/dist/v2/projections/advance-outcomes.d.ts +1 -7
  141. package/dist/v2/projections/advance-outcomes.js +2 -1
  142. package/dist/v2/projections/artifacts.js +3 -2
  143. package/dist/v2/projections/capabilities.d.ts +1 -7
  144. package/dist/v2/projections/capabilities.js +2 -1
  145. package/dist/v2/projections/gaps.d.ts +1 -7
  146. package/dist/v2/projections/gaps.js +2 -1
  147. package/dist/v2/projections/node-outputs.d.ts +1 -7
  148. package/dist/v2/projections/node-outputs.js +4 -3
  149. package/dist/v2/projections/preferences.d.ts +1 -7
  150. package/dist/v2/projections/preferences.js +2 -1
  151. package/dist/v2/projections/projection-error.d.ts +7 -0
  152. package/dist/v2/projections/projection-error.js +2 -0
  153. package/dist/v2/projections/resume-ranking.d.ts +62 -0
  154. package/dist/v2/projections/resume-ranking.js +105 -0
  155. package/dist/v2/projections/run-context.d.ts +1 -7
  156. package/dist/v2/projections/run-context.js +4 -2
  157. package/dist/v2/projections/run-dag.d.ts +9 -9
  158. package/dist/v2/projections/run-dag.js +88 -65
  159. package/dist/v2/projections/run-status-signals.d.ts +1 -7
  160. package/dist/v2/projections/run-status-signals.js +3 -2
  161. package/dist/v2/usecases/enumerate-sessions.d.ts +9 -0
  162. package/dist/v2/usecases/enumerate-sessions.js +13 -0
  163. package/dist/v2/usecases/execution-session-gate.js +2 -5
  164. package/dist/v2/usecases/export-session.js +4 -2
  165. package/dist/v2/usecases/import-session.d.ts +3 -3
  166. package/dist/v2/usecases/resume-session.d.ts +4 -0
  167. package/dist/v2/usecases/resume-session.js +9 -0
  168. package/package.json +1 -1
@@ -8,8 +8,9 @@ const v2_token_ops_js_1 = require("./v2-token-ops.js");
8
8
  const index_js_1 = require("../../v2/durable-core/ids/index.js");
9
9
  const workflow_hash_ref_js_1 = require("../../v2/durable-core/ids/workflow-hash-ref.js");
10
10
  const index_js_2 = require("../../v2/durable-core/schemas/session/index.js");
11
+ const constants_js_1 = require("../../v2/durable-core/constants.js");
11
12
  function findNodeCreated(events, nodeId) {
12
- return events.find((e) => e.kind === 'node_created' && e.scope?.nodeId === String(nodeId));
13
+ return events.find((e) => e.kind === constants_js_1.EVENT_KIND.NODE_CREATED && e.scope?.nodeId === String(nodeId));
13
14
  }
14
15
  function mintStateTokenForNode(originalNode, sessionId, runId, nodeId, tokenCodecPorts) {
15
16
  const wfRefRes = (0, workflow_hash_ref_js_1.deriveWorkflowHashRef)(originalNode.data.workflowHash);
@@ -85,7 +86,7 @@ function executeCheckpoint(input, ctx) {
85
86
  });
86
87
  }
87
88
  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 existingCheckpointNode = events.find((e) => e.kind === constants_js_1.EVENT_KIND.NODE_CREATED && e.dedupeKey === `checkpoint_node:${dedupeKey}`);
89
90
  const checkpointNodeId = existingCheckpointNode
90
91
  ? String(existingCheckpointNode.scope?.nodeId ?? 'unknown')
91
92
  : 'unknown';
@@ -106,7 +107,7 @@ function writeCheckpoint(truth, dedupeKey, originalNode, sessionId, runId, nodeI
106
107
  eventId: nodeCreatedEventId,
107
108
  eventIndex: truth.events.length,
108
109
  sessionId: String(sessionId),
109
- kind: 'node_created',
110
+ kind: constants_js_1.EVENT_KIND.NODE_CREATED,
110
111
  dedupeKey: `checkpoint_node:${dedupeKey}`,
111
112
  scope: { runId: String(runId), nodeId: String(checkpointNodeId) },
112
113
  data: {
@@ -121,7 +122,7 @@ function writeCheckpoint(truth, dedupeKey, originalNode, sessionId, runId, nodeI
121
122
  eventId: edgeCreatedEventId,
122
123
  eventIndex: truth.events.length + 1,
123
124
  sessionId: String(sessionId),
124
- kind: 'edge_created',
125
+ kind: constants_js_1.EVENT_KIND.EDGE_CREATED,
125
126
  dedupeKey,
126
127
  scope: { runId: String(runId) },
127
128
  data: {
@@ -154,9 +154,9 @@ function checkContextBudget(args) {
154
154
  function collectArtifactsForEvaluation(args) {
155
155
  const collected = [];
156
156
  for (const e of args.truthEvents) {
157
- if (e.kind !== 'node_output_appended')
157
+ if (e.kind !== constants_js_1.EVENT_KIND.NODE_OUTPUT_APPENDED)
158
158
  continue;
159
- if (e.data.outputChannel !== 'artifact')
159
+ if (e.data.outputChannel !== constants_js_1.OUTPUT_CHANNEL.ARTIFACT)
160
160
  continue;
161
161
  if (e.data.payload.payloadKind !== 'artifact_ref')
162
162
  continue;
@@ -0,0 +1,32 @@
1
+ import type { V2ContinueWorkflowInput } from '../../v2/tools.js';
2
+ import { createWorkflow } from '../../../types/workflow.js';
3
+ import { type AttemptId } from '../../../v2/durable-core/tokens/index.js';
4
+ import { type SessionId, type RunId, type NodeId, type WorkflowHash } from '../../../v2/durable-core/ids/index.js';
5
+ import type { LoadedSessionTruthV2 } from '../../../v2/ports/session-event-log-store.port.js';
6
+ import type { WithHealthySessionLock } from '../../../v2/durable-core/ids/with-healthy-session-lock.js';
7
+ import type { SessionEventLogStoreError } from '../../../v2/ports/session-event-log-store.port.js';
8
+ import type { SnapshotStoreError } from '../../../v2/ports/snapshot-store.port.js';
9
+ import type { Sha256PortV2 } from '../../../v2/ports/sha256.port.js';
10
+ import { ResultAsync as RA } from 'neverthrow';
11
+ import type { JsonValue } from '../../../v2/durable-core/canonical/json-types.js';
12
+ import { type InternalError } from '../v2-error-mapping.js';
13
+ export declare function advanceAndRecord(args: {
14
+ readonly truth: LoadedSessionTruthV2;
15
+ readonly sessionId: SessionId;
16
+ readonly runId: RunId;
17
+ readonly nodeId: NodeId;
18
+ readonly attemptId: AttemptId;
19
+ readonly workflowHash: WorkflowHash;
20
+ readonly dedupeKey: string;
21
+ readonly inputContext: JsonValue | undefined;
22
+ readonly inputOutput: V2ContinueWorkflowInput['output'];
23
+ readonly lock: WithHealthySessionLock;
24
+ readonly pinnedWorkflow: ReturnType<typeof createWorkflow>;
25
+ readonly snapshotStore: import('../../../v2/ports/snapshot-store.port.js').SnapshotStorePortV2;
26
+ readonly sessionStore: import('../../../v2/ports/session-event-log-store.port.js').SessionEventLogAppendStorePortV2 & import('../../../v2/ports/session-event-log-store.port.js').SessionEventLogReadonlyStorePortV2;
27
+ readonly sha256: Sha256PortV2;
28
+ readonly idFactory: {
29
+ readonly mintNodeId: () => NodeId;
30
+ readonly mintEventId: () => string;
31
+ };
32
+ }): RA<void, InternalError | SessionEventLogStoreError | SnapshotStoreError>;
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.advanceAndRecord = advanceAndRecord;
4
+ const neverthrow_1 = require("neverthrow");
5
+ const v2_advance_core_js_1 = require("../v2-advance-core.js");
6
+ const constants_js_1 = require("../../../v2/durable-core/constants.js");
7
+ function advanceAndRecord(args) {
8
+ const { truth, sessionId, runId, nodeId, attemptId, workflowHash, dedupeKey, inputContext, inputOutput, lock, pinnedWorkflow, snapshotStore, sessionStore, sha256, idFactory } = args;
9
+ const hasRun = truth.events.some((e) => e.kind === constants_js_1.EVENT_KIND.RUN_STARTED && e.scope?.runId === String(runId));
10
+ const hasNode = truth.events.some((e) => e.kind === constants_js_1.EVENT_KIND.NODE_CREATED && e.scope?.runId === String(runId) && e.scope?.nodeId === String(nodeId));
11
+ if (!hasRun || !hasNode) {
12
+ return (0, neverthrow_1.errAsync)({ kind: 'missing_node_or_run' });
13
+ }
14
+ const nodeCreated = truth.events.find((e) => e.kind === constants_js_1.EVENT_KIND.NODE_CREATED && e.scope?.nodeId === String(nodeId));
15
+ if (!nodeCreated) {
16
+ return (0, neverthrow_1.errAsync)({ kind: 'missing_node_or_run' });
17
+ }
18
+ if (String(nodeCreated.data.workflowHash) !== String(workflowHash)) {
19
+ return (0, neverthrow_1.errAsync)({ kind: 'workflow_hash_mismatch' });
20
+ }
21
+ return snapshotStore.getExecutionSnapshotV1(nodeCreated.data.snapshotRef).andThen((snap) => {
22
+ if (!snap)
23
+ return (0, neverthrow_1.errAsync)({ kind: 'missing_snapshot' });
24
+ const engineState = snap.enginePayload.engineState;
25
+ if (nodeCreated.data.nodeKind === 'blocked_attempt') {
26
+ if (engineState.kind !== 'blocked') {
27
+ return (0, neverthrow_1.errAsync)({ kind: 'invariant_violation', message: 'blocked_attempt node requires engineState.kind=blocked' });
28
+ }
29
+ const blocked = engineState.blocked;
30
+ if (blocked.kind !== 'retryable_block') {
31
+ return (0, neverthrow_1.errAsync)({
32
+ kind: 'token_scope_mismatch',
33
+ message: 'Cannot retry a terminal blocked_attempt node (blocked.kind=terminal_block).',
34
+ });
35
+ }
36
+ return (0, v2_advance_core_js_1.executeAdvanceCore)({
37
+ mode: { kind: 'retry', blockedNodeId: nodeId, blockedSnapshot: snap },
38
+ truth, sessionId, runId, attemptId, workflowHash, dedupeKey,
39
+ inputContext, inputOutput, lock, pinnedWorkflow,
40
+ ports: { snapshotStore, sessionStore, sha256, idFactory },
41
+ });
42
+ }
43
+ return (0, v2_advance_core_js_1.executeAdvanceCore)({
44
+ mode: { kind: 'fresh', sourceNodeId: nodeId, snapshot: snap },
45
+ truth, sessionId, runId, attemptId, workflowHash, dedupeKey,
46
+ inputContext, inputOutput, lock, pinnedWorkflow,
47
+ ports: { snapshotStore, sessionStore, sha256, idFactory },
48
+ });
49
+ });
50
+ }
@@ -0,0 +1,29 @@
1
+ import type { V2ContinueWorkflowInput } from '../../v2/tools.js';
2
+ import { V2ContinueWorkflowOutputSchema } from '../../output-schemas.js';
3
+ import { type AttemptId } from '../../../v2/durable-core/tokens/index.js';
4
+ import { type SessionId, type RunId, type NodeId } from '../../../v2/durable-core/ids/index.js';
5
+ import type { LoadedSessionTruthV2 } from '../../../v2/ports/session-event-log-store.port.js';
6
+ import type { Sha256PortV2 } from '../../../v2/ports/sha256.port.js';
7
+ import type { TokenCodecPorts } from '../../../v2/durable-core/tokens/token-codec-ports.js';
8
+ import { ResultAsync as RA } from 'neverthrow';
9
+ import { type ContinueWorkflowError } from '../v2-execution-helpers.js';
10
+ import * as z from 'zod';
11
+ export declare function handleAdvanceIntent(args: {
12
+ readonly input: V2ContinueWorkflowInput;
13
+ readonly sessionId: SessionId;
14
+ readonly runId: RunId;
15
+ readonly nodeId: NodeId;
16
+ readonly attemptId: AttemptId;
17
+ readonly workflowHashRef: string;
18
+ readonly truth: LoadedSessionTruthV2;
19
+ readonly gate: import('../../../v2/usecases/execution-session-gate.js').ExecutionSessionGateV2;
20
+ readonly sessionStore: import('../../../v2/ports/session-event-log-store.port.js').SessionEventLogAppendStorePortV2 & import('../../../v2/ports/session-event-log-store.port.js').SessionEventLogReadonlyStorePortV2;
21
+ readonly snapshotStore: import('../../../v2/ports/snapshot-store.port.js').SnapshotStorePortV2;
22
+ readonly pinnedStore: import('../../../v2/ports/pinned-workflow-store.port.js').PinnedWorkflowStorePortV2;
23
+ readonly tokenCodecPorts: TokenCodecPorts;
24
+ readonly idFactory: {
25
+ readonly mintNodeId: () => NodeId;
26
+ readonly mintEventId: () => string;
27
+ };
28
+ readonly sha256: Sha256PortV2;
29
+ }): RA<z.infer<typeof V2ContinueWorkflowOutputSchema>, ContinueWorkflowError>;
@@ -0,0 +1,170 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handleAdvanceIntent = handleAdvanceIntent;
4
+ const workflow_js_1 = require("../../../types/workflow.js");
5
+ const workflow_hash_ref_js_1 = require("../../../v2/durable-core/ids/workflow-hash-ref.js");
6
+ const neverthrow_1 = require("neverthrow");
7
+ const workflow_source_js_1 = require("../../../types/workflow-source.js");
8
+ const workflow_definition_js_1 = require("../../../types/workflow-definition.js");
9
+ const v2_error_mapping_js_1 = require("../v2-error-mapping.js");
10
+ const constants_js_1 = require("../../../v2/durable-core/constants.js");
11
+ const replay_js_1 = require("./replay.js");
12
+ const advance_js_1 = require("./advance.js");
13
+ function handleAdvanceIntent(args) {
14
+ const { input, sessionId, runId, nodeId, attemptId, workflowHashRef, truth, gate, sessionStore, snapshotStore, pinnedStore, tokenCodecPorts, idFactory, sha256 } = args;
15
+ const dedupeKey = `advance_recorded:${sessionId}:${nodeId}:${attemptId}`;
16
+ const runStarted = truth.events.find((e) => e.kind === constants_js_1.EVENT_KIND.RUN_STARTED && e.scope.runId === String(runId));
17
+ if (!runStarted) {
18
+ return (0, neverthrow_1.errAsync)({
19
+ kind: 'token_unknown_node',
20
+ message: 'No durable run state was found for this token (missing run_started).',
21
+ suggestion: 'Use start_workflow to mint a new run, or use tokens returned by WorkRail for an existing run.',
22
+ });
23
+ }
24
+ const workflowHash = runStarted.data.workflowHash;
25
+ const refRes = (0, workflow_hash_ref_js_1.deriveWorkflowHashRef)(workflowHash);
26
+ if (refRes.isErr()) {
27
+ return (0, neverthrow_1.errAsync)({
28
+ kind: 'precondition_failed',
29
+ message: refRes.error.message,
30
+ suggestion: 'Re-pin the workflow via start_workflow.',
31
+ });
32
+ }
33
+ if (String(refRes.value) !== String(workflowHashRef)) {
34
+ return (0, neverthrow_1.errAsync)({
35
+ kind: 'precondition_failed',
36
+ message: 'workflowHash mismatch for this run.',
37
+ suggestion: 'Use the stateToken returned by WorkRail for this run.',
38
+ });
39
+ }
40
+ const nodeCreated = truth.events.find((e) => e.kind === constants_js_1.EVENT_KIND.NODE_CREATED && e.scope.nodeId === String(nodeId) && e.scope.runId === String(runId));
41
+ if (!nodeCreated) {
42
+ return (0, neverthrow_1.errAsync)({
43
+ kind: 'token_unknown_node',
44
+ message: 'No durable node state was found for this token (missing node_created).',
45
+ suggestion: 'Use tokens returned by WorkRail for an existing node.',
46
+ });
47
+ }
48
+ const nodeRefRes = (0, workflow_hash_ref_js_1.deriveWorkflowHashRef)(nodeCreated.data.workflowHash);
49
+ if (nodeRefRes.isErr()) {
50
+ return (0, neverthrow_1.errAsync)({
51
+ kind: 'precondition_failed',
52
+ message: nodeRefRes.error.message,
53
+ suggestion: 'Re-pin the workflow via start_workflow.',
54
+ });
55
+ }
56
+ if (String(nodeRefRes.value) !== String(workflowHashRef)) {
57
+ return (0, neverthrow_1.errAsync)({
58
+ kind: 'precondition_failed',
59
+ message: 'workflowHash mismatch for this node.',
60
+ suggestion: 'Use the stateToken returned by WorkRail for this node.',
61
+ });
62
+ }
63
+ const existing = truth.events.find((e) => e.kind === constants_js_1.EVENT_KIND.ADVANCE_RECORDED && e.dedupeKey === dedupeKey);
64
+ return pinnedStore.get(workflowHash)
65
+ .mapErr((cause) => ({ kind: 'pinned_workflow_store_failed', cause }))
66
+ .andThen((compiled) => {
67
+ if (!compiled)
68
+ return (0, neverthrow_1.errAsync)({ kind: 'pinned_workflow_missing', workflowHash });
69
+ if (compiled.sourceKind !== 'v1_pinned')
70
+ return (0, neverthrow_1.errAsync)({ kind: 'precondition_failed', message: 'Pinned workflow snapshot is read-only (v1_preview) and cannot be executed.' });
71
+ if (!(0, workflow_definition_js_1.hasWorkflowDefinitionShape)(compiled.definition)) {
72
+ return (0, neverthrow_1.errAsync)({
73
+ kind: 'precondition_failed',
74
+ message: 'Pinned workflow snapshot has an invalid workflow definition shape.',
75
+ suggestion: 'Re-pin the workflow via start_workflow.',
76
+ });
77
+ }
78
+ const pinnedWorkflow = (0, workflow_js_1.createWorkflow)(compiled.definition, (0, workflow_source_js_1.createBundledSource)());
79
+ if (existing) {
80
+ return (0, replay_js_1.replayFromRecordedAdvance)({
81
+ recordedEvent: existing,
82
+ truth,
83
+ sessionId,
84
+ runId,
85
+ nodeId,
86
+ workflowHash,
87
+ attemptId,
88
+ inputStateToken: input.stateToken,
89
+ inputAckToken: input.ackToken,
90
+ pinnedWorkflow,
91
+ snapshotStore,
92
+ sha256,
93
+ tokenCodecPorts,
94
+ });
95
+ }
96
+ return gate
97
+ .withHealthySessionLock(sessionId, (lock) => sessionStore.load(sessionId).andThen((truthLocked) => {
98
+ const existingLocked = truthLocked.events.find((e) => e.kind === constants_js_1.EVENT_KIND.ADVANCE_RECORDED && e.dedupeKey === dedupeKey);
99
+ if (existingLocked)
100
+ return (0, neverthrow_1.okAsync)({ kind: 'replay', truth: truthLocked, recordedEvent: existingLocked });
101
+ return (0, advance_js_1.advanceAndRecord)({
102
+ truth: truthLocked,
103
+ sessionId,
104
+ runId,
105
+ nodeId,
106
+ attemptId,
107
+ workflowHash,
108
+ dedupeKey,
109
+ inputContext: input.context,
110
+ inputOutput: input.output,
111
+ lock,
112
+ pinnedWorkflow,
113
+ snapshotStore,
114
+ sessionStore,
115
+ sha256,
116
+ idFactory,
117
+ }).andThen(() => sessionStore
118
+ .load(sessionId)
119
+ .map((truthAfter) => ({ kind: 'replay', truth: truthAfter, recordedEvent: null })));
120
+ }))
121
+ .mapErr((cause) => {
122
+ if ((0, v2_error_mapping_js_1.isInternalError)(cause)) {
123
+ return {
124
+ kind: 'invariant_violation',
125
+ message: `Advance failed due to internal invariant violation: ${cause.kind}`,
126
+ suggestion: 'Retry; if this persists, treat as invariant violation.',
127
+ };
128
+ }
129
+ if (typeof cause === 'object' && cause !== null && 'code' in cause) {
130
+ const code = cause.code;
131
+ if (code.startsWith('SNAPSHOT_STORE_')) {
132
+ return { kind: 'snapshot_load_failed', cause: cause };
133
+ }
134
+ return { kind: 'advance_execution_failed', cause: cause };
135
+ }
136
+ return {
137
+ kind: 'invariant_violation',
138
+ message: 'Advance failed with an unknown error shape (invariant violation).',
139
+ suggestion: 'Retry; if this persists, treat as invariant violation.',
140
+ };
141
+ })
142
+ .andThen((res) => {
143
+ const truth2 = res.truth;
144
+ const recordedEvent = res.recordedEvent ??
145
+ truth2.events.find((e) => e.kind === constants_js_1.EVENT_KIND.ADVANCE_RECORDED && e.dedupeKey === dedupeKey);
146
+ if (!recordedEvent) {
147
+ return (0, neverthrow_1.errAsync)({
148
+ kind: 'invariant_violation',
149
+ message: 'Missing recorded advance outcome after successful append (invariant violation).',
150
+ suggestion: 'Retry; if this persists, treat as invariant violation.',
151
+ });
152
+ }
153
+ return (0, replay_js_1.replayFromRecordedAdvance)({
154
+ recordedEvent,
155
+ truth: truth2,
156
+ sessionId,
157
+ runId,
158
+ nodeId,
159
+ workflowHash,
160
+ attemptId,
161
+ inputStateToken: input.stateToken,
162
+ inputAckToken: input.ackToken,
163
+ pinnedWorkflow,
164
+ snapshotStore,
165
+ sha256,
166
+ tokenCodecPorts,
167
+ });
168
+ });
169
+ });
170
+ }
@@ -0,0 +1,22 @@
1
+ import type { V2ContinueWorkflowInput } from '../../v2/tools.js';
2
+ import { V2ContinueWorkflowOutputSchema } from '../../output-schemas.js';
3
+ import { type SessionId, type RunId, type NodeId } from '../../../v2/durable-core/ids/index.js';
4
+ import type { LoadedSessionTruthV2 } from '../../../v2/ports/session-event-log-store.port.js';
5
+ import type { TokenCodecPorts } from '../../../v2/durable-core/tokens/token-codec-ports.js';
6
+ import { ResultAsync as RA } from 'neverthrow';
7
+ import { type ContinueWorkflowError } from '../v2-execution-helpers.js';
8
+ import * as z from 'zod';
9
+ export declare function handleRehydrateIntent(args: {
10
+ readonly input: V2ContinueWorkflowInput;
11
+ readonly sessionId: SessionId;
12
+ readonly runId: RunId;
13
+ readonly nodeId: NodeId;
14
+ readonly workflowHashRef: string;
15
+ readonly truth: LoadedSessionTruthV2;
16
+ readonly tokenCodecPorts: TokenCodecPorts;
17
+ readonly pinnedStore: import('../../../v2/ports/pinned-workflow-store.port.js').PinnedWorkflowStorePortV2;
18
+ readonly snapshotStore: import('../../../v2/ports/snapshot-store.port.js').SnapshotStorePortV2;
19
+ readonly idFactory: {
20
+ readonly mintAttemptId: () => import('../../../v2/durable-core/tokens/index.js').AttemptId;
21
+ };
22
+ }): RA<z.infer<typeof V2ContinueWorkflowOutputSchema>, ContinueWorkflowError>;
@@ -0,0 +1,146 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handleRehydrateIntent = handleRehydrateIntent;
4
+ const output_schemas_js_1 = require("../../output-schemas.js");
5
+ const snapshot_state_js_1 = require("../../../v2/durable-core/projections/snapshot-state.js");
6
+ const workflow_js_1 = require("../../../types/workflow.js");
7
+ const index_js_1 = require("../../../v2/durable-core/ids/index.js");
8
+ const workflow_hash_ref_js_1 = require("../../../v2/durable-core/ids/workflow-hash-ref.js");
9
+ const neverthrow_1 = require("neverthrow");
10
+ const workflow_source_js_1 = require("../../../types/workflow-source.js");
11
+ const workflow_definition_js_1 = require("../../../types/workflow-definition.js");
12
+ const v2_execution_helpers_js_1 = require("../v2-execution-helpers.js");
13
+ const prompt_renderer_js_1 = require("../../../v2/durable-core/domain/prompt-renderer.js");
14
+ const v2_token_ops_js_1 = require("../v2-token-ops.js");
15
+ const v2_state_conversion_js_1 = require("../v2-state-conversion.js");
16
+ const constants_js_1 = require("../../../v2/durable-core/constants.js");
17
+ const index_js_2 = require("./index.js");
18
+ function handleRehydrateIntent(args) {
19
+ const { input, sessionId, runId, nodeId, workflowHashRef, truth, tokenCodecPorts, pinnedStore, snapshotStore, idFactory } = args;
20
+ const runStarted = truth.events.find((e) => e.kind === constants_js_1.EVENT_KIND.RUN_STARTED && e.scope.runId === String(runId));
21
+ const workflowId = runStarted?.data.workflowId;
22
+ if (!runStarted || typeof workflowId !== 'string' || workflowId.trim() === '') {
23
+ return (0, neverthrow_1.errAsync)({
24
+ kind: 'token_unknown_node',
25
+ message: 'No durable run state was found for this stateToken (missing run_started).',
26
+ suggestion: 'Use start_workflow to mint a new run, or use a stateToken returned by WorkRail for an existing run.',
27
+ });
28
+ }
29
+ const workflowHash = runStarted.data.workflowHash;
30
+ const expectedRefRes = (0, workflow_hash_ref_js_1.deriveWorkflowHashRef)(workflowHash);
31
+ if (expectedRefRes.isErr()) {
32
+ return (0, neverthrow_1.errAsync)({
33
+ kind: 'precondition_failed',
34
+ message: expectedRefRes.error.message,
35
+ suggestion: 'Re-pin the workflow via start_workflow.',
36
+ });
37
+ }
38
+ if (String(expectedRefRes.value) !== String(workflowHashRef)) {
39
+ return (0, neverthrow_1.errAsync)({ kind: 'precondition_failed', message: 'workflowHash mismatch for this run.', suggestion: 'Use the stateToken returned by WorkRail for this run.' });
40
+ }
41
+ const nodeCreated = truth.events.find((e) => e.kind === constants_js_1.EVENT_KIND.NODE_CREATED && e.scope.nodeId === String(nodeId) && e.scope.runId === String(runId));
42
+ if (!nodeCreated) {
43
+ return (0, neverthrow_1.errAsync)({
44
+ kind: 'token_unknown_node',
45
+ message: 'No durable node state was found for this stateToken (missing node_created).',
46
+ suggestion: 'Use a stateToken returned by WorkRail for an existing node.',
47
+ });
48
+ }
49
+ const expectedNodeRefRes = (0, workflow_hash_ref_js_1.deriveWorkflowHashRef)(nodeCreated.data.workflowHash);
50
+ if (expectedNodeRefRes.isErr()) {
51
+ return (0, neverthrow_1.errAsync)({
52
+ kind: 'precondition_failed',
53
+ message: expectedNodeRefRes.error.message,
54
+ suggestion: 'Re-pin the workflow via start_workflow.',
55
+ });
56
+ }
57
+ if (String(expectedNodeRefRes.value) !== String(workflowHashRef)) {
58
+ return (0, neverthrow_1.errAsync)({ kind: 'precondition_failed', message: 'workflowHash mismatch for this node.', suggestion: 'Use the stateToken returned by WorkRail for this node.' });
59
+ }
60
+ return snapshotStore.getExecutionSnapshotV1(nodeCreated.data.snapshotRef)
61
+ .mapErr((cause) => ({ kind: 'snapshot_load_failed', cause }))
62
+ .andThen((snapshot) => {
63
+ if (!snapshot) {
64
+ return (0, neverthrow_1.errAsync)({
65
+ kind: 'token_unknown_node',
66
+ message: 'No execution snapshot was found for this node.',
67
+ suggestion: 'Use a stateToken returned by WorkRail for an existing node.',
68
+ });
69
+ }
70
+ const engineState = snapshot.enginePayload.engineState;
71
+ const pending = (0, snapshot_state_js_1.derivePendingStep)(engineState);
72
+ const isComplete = (0, snapshot_state_js_1.deriveIsComplete)(engineState);
73
+ if (!pending) {
74
+ const preferences = (0, v2_execution_helpers_js_1.derivePreferencesOrDefault)({ truth, runId, nodeId });
75
+ const nextIntent = (0, v2_state_conversion_js_1.deriveNextIntent)({ rehydrateOnly: true, isComplete, pending: null });
76
+ return (0, neverthrow_1.okAsync)(output_schemas_js_1.V2ContinueWorkflowOutputSchema.parse({
77
+ kind: 'ok',
78
+ stateToken: input.stateToken,
79
+ isComplete,
80
+ pending: null,
81
+ preferences,
82
+ nextIntent,
83
+ nextCall: (0, index_js_2.buildNextCall)({ stateToken: input.stateToken, ackToken: undefined, isComplete, pending: null }),
84
+ }));
85
+ }
86
+ const attemptId = (0, v2_token_ops_js_1.newAttemptId)(idFactory);
87
+ const ackTokenRes = (0, v2_token_ops_js_1.signTokenOrErr)({
88
+ payload: { tokenVersion: 1, tokenKind: 'ack', sessionId, runId, nodeId, attemptId },
89
+ ports: tokenCodecPorts,
90
+ });
91
+ if (ackTokenRes.isErr())
92
+ return (0, neverthrow_1.errAsync)({ kind: 'token_signing_failed', cause: ackTokenRes.error });
93
+ const checkpointTokenRes = (0, v2_token_ops_js_1.signTokenOrErr)({
94
+ payload: { tokenVersion: 1, tokenKind: 'checkpoint', sessionId, runId, nodeId, attemptId },
95
+ ports: tokenCodecPorts,
96
+ });
97
+ if (checkpointTokenRes.isErr())
98
+ return (0, neverthrow_1.errAsync)({ kind: 'token_signing_failed', cause: checkpointTokenRes.error });
99
+ return pinnedStore.get(workflowHash)
100
+ .mapErr((cause) => ({ kind: 'pinned_workflow_store_failed', cause }))
101
+ .andThen((pinned) => {
102
+ if (!pinned)
103
+ return (0, neverthrow_1.errAsync)({ kind: 'pinned_workflow_missing', workflowHash });
104
+ if (pinned.sourceKind !== 'v1_pinned')
105
+ return (0, neverthrow_1.errAsync)({ kind: 'precondition_failed', message: 'Pinned workflow snapshot is read-only (v1_preview) and cannot be executed.' });
106
+ if (!(0, workflow_definition_js_1.hasWorkflowDefinitionShape)(pinned.definition)) {
107
+ return (0, neverthrow_1.errAsync)({
108
+ kind: 'precondition_failed',
109
+ message: 'Pinned workflow snapshot has an invalid workflow definition shape.',
110
+ suggestion: 'Re-pin the workflow via start_workflow.',
111
+ });
112
+ }
113
+ const wf = (0, workflow_js_1.createWorkflow)(pinned.definition, (0, workflow_source_js_1.createBundledSource)());
114
+ const metaRes = (0, prompt_renderer_js_1.renderPendingPrompt)({
115
+ workflow: wf,
116
+ stepId: String(pending.stepId),
117
+ loopPath: pending.loopPath,
118
+ truth,
119
+ runId: (0, index_js_1.asRunId)(String(runId)),
120
+ nodeId: (0, index_js_1.asNodeId)(String(nodeId)),
121
+ rehydrateOnly: true,
122
+ });
123
+ if (metaRes.isErr()) {
124
+ return (0, neverthrow_1.errAsync)({
125
+ kind: 'invariant_violation',
126
+ message: `Prompt rendering failed: ${metaRes.error.message}`,
127
+ suggestion: 'Retry; if this persists, treat as invariant violation.',
128
+ });
129
+ }
130
+ const meta = metaRes.value;
131
+ const preferences = (0, v2_execution_helpers_js_1.derivePreferencesOrDefault)({ truth, runId, nodeId });
132
+ const nextIntent = (0, v2_state_conversion_js_1.deriveNextIntent)({ rehydrateOnly: true, isComplete, pending: meta });
133
+ return (0, neverthrow_1.okAsync)(output_schemas_js_1.V2ContinueWorkflowOutputSchema.parse({
134
+ kind: 'ok',
135
+ stateToken: input.stateToken,
136
+ ackToken: ackTokenRes.value,
137
+ checkpointToken: checkpointTokenRes.value,
138
+ isComplete,
139
+ pending: { stepId: meta.stepId, title: meta.title, prompt: meta.prompt },
140
+ preferences,
141
+ nextIntent,
142
+ nextCall: (0, index_js_2.buildNextCall)({ stateToken: input.stateToken, ackToken: ackTokenRes.value, isComplete, pending: meta }),
143
+ }));
144
+ });
145
+ });
146
+ }
@@ -0,0 +1,23 @@
1
+ import type { ToolContext, ToolResult } from '../../types.js';
2
+ import type { V2ContinueWorkflowInput, V2StartWorkflowInput } from '../../v2/tools.js';
3
+ type NextCallTemplate = {
4
+ readonly tool: 'continue_workflow';
5
+ readonly params: {
6
+ readonly intent: 'advance';
7
+ readonly stateToken: string;
8
+ readonly ackToken: string;
9
+ };
10
+ };
11
+ export declare function buildNextCall(args: {
12
+ readonly stateToken: string;
13
+ readonly ackToken: string | undefined;
14
+ readonly isComplete: boolean;
15
+ readonly pending: {
16
+ readonly stepId: string;
17
+ } | null;
18
+ readonly retryable?: boolean;
19
+ readonly retryAckToken?: string;
20
+ }): NextCallTemplate | null;
21
+ export declare function handleV2StartWorkflow(input: V2StartWorkflowInput, ctx: ToolContext): Promise<ToolResult<unknown>>;
22
+ export declare function handleV2ContinueWorkflow(input: V2ContinueWorkflowInput, ctx: ToolContext): Promise<ToolResult<unknown>>;
23
+ export {};
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildNextCall = buildNextCall;
4
+ exports.handleV2StartWorkflow = handleV2StartWorkflow;
5
+ exports.handleV2ContinueWorkflow = handleV2ContinueWorkflow;
6
+ const types_js_1 = require("../../types.js");
7
+ const index_js_1 = require("../../../v2/durable-core/tokens/index.js");
8
+ const index_js_2 = require("../../../v2/durable-core/ids/index.js");
9
+ const neverthrow_1 = require("neverthrow");
10
+ const v2_execution_helpers_js_1 = require("../v2-execution-helpers.js");
11
+ const v2_token_ops_js_1 = require("../v2-token-ops.js");
12
+ const v2_context_budget_js_1 = require("../v2-context-budget.js");
13
+ const start_js_1 = require("./start.js");
14
+ const continue_rehydrate_js_1 = require("./continue-rehydrate.js");
15
+ const continue_advance_js_1 = require("./continue-advance.js");
16
+ function buildNextCall(args) {
17
+ if (args.isComplete && !args.pending)
18
+ return null;
19
+ if (args.retryable && args.retryAckToken) {
20
+ return {
21
+ tool: 'continue_workflow',
22
+ params: { intent: 'advance', stateToken: args.stateToken, ackToken: args.retryAckToken },
23
+ };
24
+ }
25
+ if (!args.ackToken)
26
+ return null;
27
+ return {
28
+ tool: 'continue_workflow',
29
+ params: { intent: 'advance', stateToken: args.stateToken, ackToken: args.ackToken },
30
+ };
31
+ }
32
+ async function handleV2StartWorkflow(input, ctx) {
33
+ return (0, start_js_1.executeStartWorkflow)(input, ctx).match((payload) => (0, types_js_1.success)(payload), (e) => (0, v2_execution_helpers_js_1.mapStartWorkflowErrorToToolError)(e));
34
+ }
35
+ async function handleV2ContinueWorkflow(input, ctx) {
36
+ return executeContinueWorkflow(input, ctx).match((payload) => (0, types_js_1.success)(payload), (e) => (0, v2_execution_helpers_js_1.mapContinueWorkflowErrorToToolError)(e));
37
+ }
38
+ function executeContinueWorkflow(input, ctx) {
39
+ if (!ctx.v2) {
40
+ return (0, neverthrow_1.errAsync)({ kind: 'precondition_failed', message: 'v2 tools disabled', suggestion: 'Enable v2Tools flag' });
41
+ }
42
+ const { gate, sessionStore, snapshotStore, pinnedStore, sha256, tokenCodecPorts, idFactory } = ctx.v2;
43
+ if (!sha256 || !idFactory) {
44
+ return (0, neverthrow_1.errAsync)({
45
+ kind: 'precondition_failed',
46
+ message: 'v2 context missing required dependencies',
47
+ suggestion: 'Reinitialize v2 tool context (sha256 and idFactory must be provided when v2Tools are enabled).',
48
+ });
49
+ }
50
+ if (!tokenCodecPorts) {
51
+ return (0, neverthrow_1.errAsync)({
52
+ kind: 'precondition_failed',
53
+ message: 'v2 context missing tokenCodecPorts dependency',
54
+ suggestion: 'Reinitialize v2 tool context (tokenCodecPorts must be provided when v2Tools are enabled).',
55
+ });
56
+ }
57
+ const stateRes = (0, v2_token_ops_js_1.parseStateTokenOrFail)(input.stateToken, tokenCodecPorts);
58
+ if (!stateRes.ok)
59
+ return (0, neverthrow_1.errAsync)({ kind: 'validation_failed', failure: stateRes.failure });
60
+ const state = stateRes.token;
61
+ const ctxCheck = (0, v2_context_budget_js_1.checkContextBudget)({ tool: 'continue_workflow', context: input.context });
62
+ if (!ctxCheck.ok)
63
+ return (0, neverthrow_1.errAsync)({ kind: 'validation_failed', failure: ctxCheck.error });
64
+ const sessionId = (0, index_js_2.asSessionId)(state.payload.sessionId);
65
+ const runId = (0, index_js_2.asRunId)(state.payload.runId);
66
+ const nodeId = (0, index_js_2.asNodeId)(state.payload.nodeId);
67
+ const workflowHashRef = state.payload.workflowHashRef;
68
+ if (input.intent === 'rehydrate') {
69
+ return sessionStore.load(sessionId)
70
+ .mapErr((cause) => ({ kind: 'session_load_failed', cause }))
71
+ .andThen((truth) => (0, continue_rehydrate_js_1.handleRehydrateIntent)({
72
+ input,
73
+ sessionId,
74
+ runId,
75
+ nodeId,
76
+ workflowHashRef,
77
+ truth,
78
+ tokenCodecPorts,
79
+ pinnedStore,
80
+ snapshotStore,
81
+ idFactory,
82
+ }));
83
+ }
84
+ if (!input.ackToken) {
85
+ return (0, neverthrow_1.errAsync)({ kind: 'validation_failed', failure: (0, types_js_1.error)('VALIDATION_ERROR', 'ackToken is required for advance intent') });
86
+ }
87
+ const ackRes = (0, v2_token_ops_js_1.parseAckTokenOrFail)(input.ackToken, tokenCodecPorts);
88
+ if (!ackRes.ok)
89
+ return (0, neverthrow_1.errAsync)({ kind: 'validation_failed', failure: ackRes.failure });
90
+ const ack = ackRes.token;
91
+ const scopeRes = (0, index_js_1.assertTokenScopeMatchesStateBinary)(state, ack);
92
+ if (scopeRes.isErr())
93
+ return (0, neverthrow_1.errAsync)({ kind: 'validation_failed', failure: (0, v2_execution_helpers_js_1.mapTokenDecodeErrorToToolError)(scopeRes.error) });
94
+ const attemptId = (0, index_js_1.asAttemptId)(ack.payload.attemptId);
95
+ return sessionStore.load(sessionId)
96
+ .mapErr((cause) => ({ kind: 'session_load_failed', cause }))
97
+ .andThen((truth) => (0, continue_advance_js_1.handleAdvanceIntent)({
98
+ input,
99
+ sessionId,
100
+ runId,
101
+ nodeId,
102
+ attemptId,
103
+ workflowHashRef,
104
+ truth,
105
+ gate,
106
+ sessionStore,
107
+ snapshotStore,
108
+ pinnedStore,
109
+ tokenCodecPorts,
110
+ idFactory,
111
+ sha256,
112
+ }));
113
+ }