@exaudeus/workrail 2.1.0 → 3.1.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/application/services/compiler/resolve-templates.d.ts +5 -0
- package/dist/application/services/compiler/resolve-templates.js +35 -0
- package/dist/application/services/compiler/routine-loader.d.ts +11 -0
- package/dist/application/services/compiler/routine-loader.js +45 -0
- package/dist/application/services/compiler/template-registry.d.ts +4 -2
- package/dist/application/services/compiler/template-registry.js +105 -4
- package/dist/application/services/workflow-compiler.js +34 -3
- package/dist/di/container.js +10 -1
- package/dist/di/tokens.d.ts +1 -0
- package/dist/di/tokens.js +1 -0
- package/dist/engine/engine-factory.d.ts +3 -0
- package/dist/engine/engine-factory.js +295 -0
- package/dist/engine/index.d.ts +3 -0
- package/dist/engine/index.js +12 -0
- package/dist/engine/types.d.ts +130 -0
- package/dist/engine/types.js +18 -0
- package/dist/manifest.json +146 -74
- package/dist/mcp/handlers/v2-checkpoint.d.ts +31 -1
- package/dist/mcp/handlers/v2-checkpoint.js +76 -64
- package/dist/mcp/handlers/v2-execution/continue-advance.d.ts +2 -0
- package/dist/mcp/handlers/v2-execution/continue-advance.js +5 -5
- package/dist/mcp/handlers/v2-execution/continue-rehydrate.d.ts +2 -0
- package/dist/mcp/handlers/v2-execution/continue-rehydrate.js +17 -22
- package/dist/mcp/handlers/v2-execution/index.d.ts +10 -17
- package/dist/mcp/handlers/v2-execution/index.js +44 -54
- package/dist/mcp/handlers/v2-execution/replay.d.ts +4 -15
- package/dist/mcp/handlers/v2-execution/replay.js +52 -128
- package/dist/mcp/handlers/v2-execution/start.d.ts +3 -2
- package/dist/mcp/handlers/v2-execution/start.js +18 -46
- package/dist/mcp/handlers/v2-token-ops.d.ts +45 -24
- package/dist/mcp/handlers/v2-token-ops.js +372 -32
- package/dist/mcp/output-schemas.d.ts +104 -283
- package/dist/mcp/output-schemas.js +24 -22
- package/dist/mcp/server.js +8 -0
- package/dist/mcp/types.d.ts +4 -0
- package/dist/mcp/v2/tools.d.ts +22 -52
- package/dist/mcp/v2/tools.js +18 -32
- package/dist/mcp/v2-response-formatter.js +12 -16
- package/dist/runtime/runtime-mode.d.ts +2 -0
- package/dist/v2/durable-core/domain/prompt-renderer.d.ts +1 -0
- package/dist/v2/durable-core/domain/prompt-renderer.js +5 -3
- package/dist/v2/durable-core/schemas/export-bundle/index.d.ts +14 -14
- package/dist/v2/durable-core/schemas/session/events.d.ts +4 -4
- package/dist/v2/durable-core/schemas/session/validation-event.d.ts +2 -2
- package/dist/v2/durable-core/tokens/payloads.d.ts +32 -32
- package/dist/v2/durable-core/tokens/short-token.d.ts +38 -0
- package/dist/v2/durable-core/tokens/short-token.js +126 -0
- package/dist/v2/durable-core/tokens/token-patterns.d.ts +4 -0
- package/dist/v2/durable-core/tokens/token-patterns.js +9 -0
- package/dist/v2/infra/in-memory/token-alias-store/index.d.ts +11 -0
- package/dist/v2/infra/in-memory/token-alias-store/index.js +38 -0
- package/dist/v2/infra/local/data-dir/index.d.ts +1 -0
- package/dist/v2/infra/local/data-dir/index.js +3 -0
- package/dist/v2/infra/local/token-alias-store/index.d.ts +16 -0
- package/dist/v2/infra/local/token-alias-store/index.js +117 -0
- package/dist/v2/ports/data-dir.port.d.ts +1 -0
- package/dist/v2/ports/token-alias-store.port.d.ts +33 -0
- package/dist/v2/ports/token-alias-store.port.js +2 -0
- package/package.json +8 -1
- package/workflows/coding-task-workflow-agentic.lean.v2.json +41 -3
- package/workflows/examples/routine-injection-example.json +28 -0
|
@@ -26,4 +26,6 @@ export declare function handleAdvanceIntent(args: {
|
|
|
26
26
|
readonly mintEventId: () => string;
|
|
27
27
|
};
|
|
28
28
|
readonly sha256: Sha256PortV2;
|
|
29
|
+
readonly aliasStore: import('../../../v2/ports/token-alias-store.port.js').TokenAliasStorePortV2;
|
|
30
|
+
readonly entropy: import('../../../v2/ports/random-entropy.port.js').RandomEntropyPortV2;
|
|
29
31
|
}): RA<z.infer<typeof V2ContinueWorkflowOutputSchema>, ContinueWorkflowError>;
|
|
@@ -11,7 +11,7 @@ const constants_js_1 = require("../../../v2/durable-core/constants.js");
|
|
|
11
11
|
const replay_js_1 = require("./replay.js");
|
|
12
12
|
const advance_js_1 = require("./advance.js");
|
|
13
13
|
function handleAdvanceIntent(args) {
|
|
14
|
-
const { input, sessionId, runId, nodeId, attemptId, workflowHashRef, truth, gate, sessionStore, snapshotStore, pinnedStore, tokenCodecPorts, idFactory, sha256 } = args;
|
|
14
|
+
const { input, sessionId, runId, nodeId, attemptId, workflowHashRef, truth, gate, sessionStore, snapshotStore, pinnedStore, tokenCodecPorts, idFactory, sha256, aliasStore, entropy } = args;
|
|
15
15
|
const dedupeKey = `advance_recorded:${sessionId}:${nodeId}:${attemptId}`;
|
|
16
16
|
const runStarted = truth.events.find((e) => e.kind === constants_js_1.EVENT_KIND.RUN_STARTED && e.scope.runId === String(runId));
|
|
17
17
|
if (!runStarted) {
|
|
@@ -85,12 +85,12 @@ function handleAdvanceIntent(args) {
|
|
|
85
85
|
nodeId,
|
|
86
86
|
workflowHash,
|
|
87
87
|
attemptId,
|
|
88
|
-
inputStateToken: input.stateToken,
|
|
89
|
-
inputAckToken: input.ackToken,
|
|
90
88
|
pinnedWorkflow,
|
|
91
89
|
snapshotStore,
|
|
92
90
|
sha256,
|
|
93
91
|
tokenCodecPorts,
|
|
92
|
+
aliasStore,
|
|
93
|
+
entropy,
|
|
94
94
|
});
|
|
95
95
|
}
|
|
96
96
|
return gate
|
|
@@ -162,12 +162,12 @@ function handleAdvanceIntent(args) {
|
|
|
162
162
|
nodeId,
|
|
163
163
|
workflowHash,
|
|
164
164
|
attemptId,
|
|
165
|
-
inputStateToken: input.stateToken,
|
|
166
|
-
inputAckToken: input.ackToken,
|
|
167
165
|
pinnedWorkflow,
|
|
168
166
|
snapshotStore,
|
|
169
167
|
sha256,
|
|
170
168
|
tokenCodecPorts,
|
|
169
|
+
aliasStore,
|
|
170
|
+
entropy,
|
|
171
171
|
});
|
|
172
172
|
});
|
|
173
173
|
});
|
|
@@ -19,4 +19,6 @@ export declare function handleRehydrateIntent(args: {
|
|
|
19
19
|
readonly idFactory: {
|
|
20
20
|
readonly mintAttemptId: () => import('../../../v2/durable-core/tokens/index.js').AttemptId;
|
|
21
21
|
};
|
|
22
|
+
readonly aliasStore: import('../../../v2/ports/token-alias-store.port.js').TokenAliasStorePortV2;
|
|
23
|
+
readonly entropy: import('../../../v2/ports/random-entropy.port.js').RandomEntropyPortV2;
|
|
22
24
|
}): RA<z.infer<typeof V2ContinueWorkflowOutputSchema>, ContinueWorkflowError>;
|
|
@@ -16,7 +16,7 @@ const v2_state_conversion_js_1 = require("../v2-state-conversion.js");
|
|
|
16
16
|
const constants_js_1 = require("../../../v2/durable-core/constants.js");
|
|
17
17
|
const index_js_2 = require("./index.js");
|
|
18
18
|
function handleRehydrateIntent(args) {
|
|
19
|
-
const { input, sessionId, runId, nodeId, workflowHashRef, truth, tokenCodecPorts, pinnedStore, snapshotStore, idFactory } = args;
|
|
19
|
+
const { input, sessionId, runId, nodeId, workflowHashRef, truth, tokenCodecPorts, pinnedStore, snapshotStore, idFactory, aliasStore, entropy } = args;
|
|
20
20
|
const runStarted = truth.events.find((e) => e.kind === constants_js_1.EVENT_KIND.RUN_STARTED && e.scope.runId === String(runId));
|
|
21
21
|
const workflowId = runStarted?.data.workflowId;
|
|
22
22
|
if (!runStarted || typeof workflowId !== 'string' || workflowId.trim() === '') {
|
|
@@ -75,28 +75,24 @@ function handleRehydrateIntent(args) {
|
|
|
75
75
|
const nextIntent = (0, v2_state_conversion_js_1.deriveNextIntent)({ rehydrateOnly: true, isComplete, pending: null });
|
|
76
76
|
return (0, neverthrow_1.okAsync)(output_schemas_js_1.V2ContinueWorkflowOutputSchema.parse({
|
|
77
77
|
kind: 'ok',
|
|
78
|
-
stateToken: input.stateToken,
|
|
79
78
|
isComplete,
|
|
80
79
|
pending: null,
|
|
81
80
|
preferences,
|
|
82
81
|
nextIntent,
|
|
83
|
-
nextCall:
|
|
82
|
+
nextCall: null,
|
|
84
83
|
}));
|
|
85
84
|
}
|
|
86
85
|
const attemptId = (0, v2_token_ops_js_1.newAttemptId)(idFactory);
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
if (checkpointTokenRes.isErr())
|
|
98
|
-
return (0, neverthrow_1.errAsync)({ kind: 'token_signing_failed', cause: checkpointTokenRes.error });
|
|
99
|
-
return pinnedStore.get(workflowHash)
|
|
86
|
+
const entryBase = {
|
|
87
|
+
sessionId: String(sessionId),
|
|
88
|
+
runId: String(runId),
|
|
89
|
+
nodeId: String(nodeId),
|
|
90
|
+
attemptId: String(attemptId),
|
|
91
|
+
workflowHashRef: String(workflowHashRef),
|
|
92
|
+
};
|
|
93
|
+
return (0, v2_token_ops_js_1.mintContinueAndCheckpointTokens)({ entry: entryBase, ports: tokenCodecPorts, aliasStore, entropy })
|
|
94
|
+
.mapErr((failure) => ({ kind: 'token_signing_failed', cause: failure }))
|
|
95
|
+
.andThen(({ continueToken: continueTokenValue, checkpointToken: checkpointTokenValue }) => pinnedStore.get(workflowHash)
|
|
100
96
|
.mapErr((cause) => ({ kind: 'pinned_workflow_store_failed', cause }))
|
|
101
97
|
.andThen((pinned) => {
|
|
102
98
|
if (!pinned)
|
|
@@ -131,15 +127,14 @@ function handleRehydrateIntent(args) {
|
|
|
131
127
|
const nextIntent = (0, v2_state_conversion_js_1.deriveNextIntent)({ rehydrateOnly: true, isComplete, pending: meta });
|
|
132
128
|
return (0, neverthrow_1.okAsync)(output_schemas_js_1.V2ContinueWorkflowOutputSchema.parse({
|
|
133
129
|
kind: 'ok',
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
checkpointToken: checkpointTokenRes.value,
|
|
130
|
+
continueToken: continueTokenValue,
|
|
131
|
+
checkpointToken: checkpointTokenValue,
|
|
137
132
|
isComplete,
|
|
138
|
-
pending:
|
|
133
|
+
pending: (0, output_schemas_js_1.toPendingStep)(meta),
|
|
139
134
|
preferences,
|
|
140
135
|
nextIntent,
|
|
141
|
-
nextCall: (0, index_js_2.buildNextCall)({
|
|
136
|
+
nextCall: (0, index_js_2.buildNextCall)({ continueToken: continueTokenValue, isComplete, pending: meta }),
|
|
142
137
|
}));
|
|
143
|
-
});
|
|
138
|
+
}));
|
|
144
139
|
});
|
|
145
140
|
}
|
|
@@ -1,31 +1,24 @@
|
|
|
1
|
-
import type { ToolContext, ToolResult } from '../../types.js';
|
|
1
|
+
import type { ToolContext, ToolResult, V2ToolContext } from '../../types.js';
|
|
2
2
|
import type { V2ContinueWorkflowInput, V2StartWorkflowInput } from '../../v2/tools.js';
|
|
3
|
-
|
|
3
|
+
import { V2ContinueWorkflowOutputSchema } from '../../output-schemas.js';
|
|
4
|
+
import { ResultAsync as RA } from 'neverthrow';
|
|
5
|
+
import { type ContinueWorkflowError } from '../v2-execution-helpers.js';
|
|
6
|
+
import * as z from 'zod';
|
|
7
|
+
type NextCallTemplate = {
|
|
4
8
|
readonly tool: 'continue_workflow';
|
|
5
9
|
readonly params: {
|
|
6
|
-
readonly
|
|
7
|
-
readonly stateToken: string;
|
|
8
|
-
readonly ackToken: string;
|
|
10
|
+
readonly continueToken: string;
|
|
9
11
|
};
|
|
10
12
|
};
|
|
11
|
-
type NextCallRehydrate = {
|
|
12
|
-
readonly tool: 'continue_workflow';
|
|
13
|
-
readonly params: {
|
|
14
|
-
readonly intent: 'rehydrate';
|
|
15
|
-
readonly stateToken: string;
|
|
16
|
-
};
|
|
17
|
-
};
|
|
18
|
-
type NextCallTemplate = NextCallAdvance | NextCallRehydrate;
|
|
19
13
|
export declare function buildNextCall(args: {
|
|
20
|
-
readonly
|
|
21
|
-
readonly ackToken: string | undefined;
|
|
14
|
+
readonly continueToken?: string;
|
|
22
15
|
readonly isComplete: boolean;
|
|
23
16
|
readonly pending: {
|
|
24
17
|
readonly stepId: string;
|
|
25
18
|
} | null;
|
|
26
|
-
readonly
|
|
27
|
-
readonly retryAckToken?: string;
|
|
19
|
+
readonly retryContinueToken?: string;
|
|
28
20
|
}): NextCallTemplate | null;
|
|
29
21
|
export declare function handleV2StartWorkflow(input: V2StartWorkflowInput, ctx: ToolContext): Promise<ToolResult<unknown>>;
|
|
30
22
|
export declare function handleV2ContinueWorkflow(input: V2ContinueWorkflowInput, ctx: ToolContext): Promise<ToolResult<unknown>>;
|
|
23
|
+
export declare function executeContinueWorkflow(input: V2ContinueWorkflowInput, ctx: V2ToolContext): RA<z.infer<typeof V2ContinueWorkflowOutputSchema>, ContinueWorkflowError>;
|
|
31
24
|
export {};
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.buildNextCall = buildNextCall;
|
|
4
4
|
exports.handleV2StartWorkflow = handleV2StartWorkflow;
|
|
5
5
|
exports.handleV2ContinueWorkflow = handleV2ContinueWorkflow;
|
|
6
|
+
exports.executeContinueWorkflow = executeContinueWorkflow;
|
|
6
7
|
const types_js_1 = require("../../types.js");
|
|
7
8
|
const index_js_1 = require("../../../v2/durable-core/tokens/index.js");
|
|
8
9
|
const index_js_2 = require("../../../v2/durable-core/ids/index.js");
|
|
@@ -16,18 +17,13 @@ const continue_advance_js_1 = require("./continue-advance.js");
|
|
|
16
17
|
function buildNextCall(args) {
|
|
17
18
|
if (args.isComplete && !args.pending)
|
|
18
19
|
return null;
|
|
19
|
-
if (args.
|
|
20
|
-
return {
|
|
21
|
-
tool: 'continue_workflow',
|
|
22
|
-
params: { intent: 'advance', stateToken: args.stateToken, ackToken: args.retryAckToken },
|
|
23
|
-
};
|
|
20
|
+
if (args.retryContinueToken) {
|
|
21
|
+
return { tool: 'continue_workflow', params: { continueToken: args.retryContinueToken } };
|
|
24
22
|
}
|
|
25
|
-
if (
|
|
26
|
-
return
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
params: { intent: 'advance', stateToken: args.stateToken, ackToken: args.ackToken },
|
|
30
|
-
};
|
|
23
|
+
if (args.continueToken) {
|
|
24
|
+
return { tool: 'continue_workflow', params: { continueToken: args.continueToken } };
|
|
25
|
+
}
|
|
26
|
+
return null;
|
|
31
27
|
}
|
|
32
28
|
async function handleV2StartWorkflow(input, ctx) {
|
|
33
29
|
const guard = (0, types_js_1.requireV2Context)(ctx);
|
|
@@ -42,61 +38,55 @@ async function handleV2ContinueWorkflow(input, ctx) {
|
|
|
42
38
|
return executeContinueWorkflow(input, guard.ctx).match((payload) => (0, types_js_1.success)(payload), (e) => (0, v2_execution_helpers_js_1.mapContinueWorkflowErrorToToolError)(e));
|
|
43
39
|
}
|
|
44
40
|
function executeContinueWorkflow(input, ctx) {
|
|
45
|
-
const { gate, sessionStore, snapshotStore, pinnedStore, sha256, tokenCodecPorts, idFactory } = ctx.v2;
|
|
46
|
-
const stateRes = (0, v2_token_ops_js_1.parseStateTokenOrFail)(input.stateToken, tokenCodecPorts);
|
|
47
|
-
if (!stateRes.ok)
|
|
48
|
-
return (0, neverthrow_1.errAsync)({ kind: 'validation_failed', failure: stateRes.failure });
|
|
49
|
-
const state = stateRes.token;
|
|
41
|
+
const { gate, sessionStore, snapshotStore, pinnedStore, sha256, tokenCodecPorts, idFactory, tokenAliasStore, entropy } = ctx.v2;
|
|
50
42
|
const ctxCheck = (0, v2_context_budget_js_1.checkContextBudget)({ tool: 'continue_workflow', context: input.context });
|
|
51
43
|
if (!ctxCheck.ok)
|
|
52
44
|
return (0, neverthrow_1.errAsync)({ kind: 'validation_failed', failure: ctxCheck.error });
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
45
|
+
return (0, v2_token_ops_js_1.parseContinueTokenOrFail)(input.continueToken, tokenCodecPorts, tokenAliasStore)
|
|
46
|
+
.mapErr((failure) => ({ kind: 'validation_failed', failure }))
|
|
47
|
+
.andThen((resolved) => {
|
|
48
|
+
const sessionId = (0, index_js_2.asSessionId)(resolved.sessionId);
|
|
49
|
+
const runId = (0, index_js_2.asRunId)(resolved.runId);
|
|
50
|
+
const nodeId = (0, index_js_2.asNodeId)(resolved.nodeId);
|
|
51
|
+
const workflowHashRef = resolved.workflowHashRef;
|
|
52
|
+
if (input.intent === 'rehydrate') {
|
|
53
|
+
return sessionStore.load(sessionId)
|
|
54
|
+
.mapErr((cause) => ({ kind: 'session_load_failed', cause }))
|
|
55
|
+
.andThen((truth) => (0, continue_rehydrate_js_1.handleRehydrateIntent)({
|
|
56
|
+
input,
|
|
57
|
+
sessionId,
|
|
58
|
+
runId,
|
|
59
|
+
nodeId,
|
|
60
|
+
workflowHashRef,
|
|
61
|
+
truth,
|
|
62
|
+
tokenCodecPorts,
|
|
63
|
+
pinnedStore,
|
|
64
|
+
snapshotStore,
|
|
65
|
+
idFactory,
|
|
66
|
+
aliasStore: tokenAliasStore,
|
|
67
|
+
entropy,
|
|
68
|
+
}));
|
|
69
|
+
}
|
|
70
|
+
const attemptId = (0, index_js_1.asAttemptId)(resolved.attemptId);
|
|
58
71
|
return sessionStore.load(sessionId)
|
|
59
72
|
.mapErr((cause) => ({ kind: 'session_load_failed', cause }))
|
|
60
|
-
.andThen((truth) => (0,
|
|
73
|
+
.andThen((truth) => (0, continue_advance_js_1.handleAdvanceIntent)({
|
|
61
74
|
input,
|
|
62
75
|
sessionId,
|
|
63
76
|
runId,
|
|
64
77
|
nodeId,
|
|
78
|
+
attemptId,
|
|
65
79
|
workflowHashRef,
|
|
66
80
|
truth,
|
|
67
|
-
|
|
68
|
-
|
|
81
|
+
gate,
|
|
82
|
+
sessionStore,
|
|
69
83
|
snapshotStore,
|
|
84
|
+
pinnedStore,
|
|
85
|
+
tokenCodecPorts,
|
|
70
86
|
idFactory,
|
|
87
|
+
sha256,
|
|
88
|
+
aliasStore: tokenAliasStore,
|
|
89
|
+
entropy,
|
|
71
90
|
}));
|
|
72
|
-
}
|
|
73
|
-
if (!input.ackToken) {
|
|
74
|
-
return (0, neverthrow_1.errAsync)({ kind: 'validation_failed', failure: (0, types_js_1.error)('VALIDATION_ERROR', 'ackToken is required for advance intent') });
|
|
75
|
-
}
|
|
76
|
-
const ackRes = (0, v2_token_ops_js_1.parseAckTokenOrFail)(input.ackToken, tokenCodecPorts);
|
|
77
|
-
if (!ackRes.ok)
|
|
78
|
-
return (0, neverthrow_1.errAsync)({ kind: 'validation_failed', failure: ackRes.failure });
|
|
79
|
-
const ack = ackRes.token;
|
|
80
|
-
const scopeRes = (0, index_js_1.assertTokenScopeMatchesStateBinary)(state, ack);
|
|
81
|
-
if (scopeRes.isErr())
|
|
82
|
-
return (0, neverthrow_1.errAsync)({ kind: 'validation_failed', failure: (0, v2_execution_helpers_js_1.mapTokenDecodeErrorToToolError)(scopeRes.error) });
|
|
83
|
-
const attemptId = (0, index_js_1.asAttemptId)(ack.payload.attemptId);
|
|
84
|
-
return sessionStore.load(sessionId)
|
|
85
|
-
.mapErr((cause) => ({ kind: 'session_load_failed', cause }))
|
|
86
|
-
.andThen((truth) => (0, continue_advance_js_1.handleAdvanceIntent)({
|
|
87
|
-
input,
|
|
88
|
-
sessionId,
|
|
89
|
-
runId,
|
|
90
|
-
nodeId,
|
|
91
|
-
attemptId,
|
|
92
|
-
workflowHashRef,
|
|
93
|
-
truth,
|
|
94
|
-
gate,
|
|
95
|
-
sessionStore,
|
|
96
|
-
snapshotStore,
|
|
97
|
-
pinnedStore,
|
|
98
|
-
tokenCodecPorts,
|
|
99
|
-
idFactory,
|
|
100
|
-
sha256,
|
|
101
|
-
}));
|
|
91
|
+
});
|
|
102
92
|
}
|
|
@@ -10,19 +10,6 @@ import type { TokenCodecPorts } from '../../../v2/durable-core/tokens/token-code
|
|
|
10
10
|
import { ResultAsync as RA } from 'neverthrow';
|
|
11
11
|
import { type ContinueWorkflowError } from '../v2-execution-helpers.js';
|
|
12
12
|
import * as z from 'zod';
|
|
13
|
-
export declare function buildBlockedReplayResponse(args: {
|
|
14
|
-
readonly sessionId: SessionId;
|
|
15
|
-
readonly runId: RunId;
|
|
16
|
-
readonly nodeId: NodeId;
|
|
17
|
-
readonly attemptId: AttemptId;
|
|
18
|
-
readonly blockers: import('../../../v2/durable-core/schemas/session/blockers.js').BlockerReportV1;
|
|
19
|
-
readonly snapshot: ExecutionSnapshotFileV1 | null;
|
|
20
|
-
readonly truth: LoadedSessionTruthV2;
|
|
21
|
-
readonly workflow: ReturnType<typeof createWorkflow>;
|
|
22
|
-
readonly inputStateToken: string;
|
|
23
|
-
readonly inputAckToken: string;
|
|
24
|
-
readonly ports: TokenCodecPorts;
|
|
25
|
-
}): RA<z.infer<typeof V2ContinueWorkflowOutputSchema>, ContinueWorkflowError>;
|
|
26
13
|
export declare function buildAdvancedReplayResponse(args: {
|
|
27
14
|
readonly sessionId: SessionId;
|
|
28
15
|
readonly runId: RunId;
|
|
@@ -35,6 +22,8 @@ export declare function buildAdvancedReplayResponse(args: {
|
|
|
35
22
|
readonly workflowHash: WorkflowHash;
|
|
36
23
|
readonly ports: TokenCodecPorts;
|
|
37
24
|
readonly sha256: Sha256PortV2;
|
|
25
|
+
readonly aliasStore: import('../../../v2/ports/token-alias-store.port.js').TokenAliasStorePortV2;
|
|
26
|
+
readonly entropy: import('../../../v2/ports/random-entropy.port.js').RandomEntropyPortV2;
|
|
38
27
|
}): RA<z.infer<typeof V2ContinueWorkflowOutputSchema>, ContinueWorkflowError>;
|
|
39
28
|
export declare function replayFromRecordedAdvance(args: {
|
|
40
29
|
readonly recordedEvent: Extract<DomainEventV1, {
|
|
@@ -46,10 +35,10 @@ export declare function replayFromRecordedAdvance(args: {
|
|
|
46
35
|
readonly nodeId: NodeId;
|
|
47
36
|
readonly workflowHash: WorkflowHash;
|
|
48
37
|
readonly attemptId: AttemptId;
|
|
49
|
-
readonly inputStateToken: string;
|
|
50
|
-
readonly inputAckToken: string;
|
|
51
38
|
readonly pinnedWorkflow: ReturnType<typeof createWorkflow>;
|
|
52
39
|
readonly snapshotStore: import('../../../v2/ports/snapshot-store.port.js').SnapshotStorePortV2;
|
|
53
40
|
readonly sha256: Sha256PortV2;
|
|
54
41
|
readonly tokenCodecPorts: TokenCodecPorts;
|
|
42
|
+
readonly aliasStore: import('../../../v2/ports/token-alias-store.port.js').TokenAliasStorePortV2;
|
|
43
|
+
readonly entropy: import('../../../v2/ports/random-entropy.port.js').RandomEntropyPortV2;
|
|
55
44
|
}): RA<z.infer<typeof V2ContinueWorkflowOutputSchema>, ContinueWorkflowError>;
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.buildBlockedReplayResponse = buildBlockedReplayResponse;
|
|
4
3
|
exports.buildAdvancedReplayResponse = buildAdvancedReplayResponse;
|
|
5
4
|
exports.replayFromRecordedAdvance = replayFromRecordedAdvance;
|
|
6
5
|
const output_schemas_js_1 = require("../../output-schemas.js");
|
|
7
6
|
const snapshot_state_js_1 = require("../../../v2/durable-core/projections/snapshot-state.js");
|
|
8
|
-
const index_js_1 = require("../../../v2/durable-core/
|
|
9
|
-
const index_js_2 = require("../../../v2/durable-core/ids/index.js");
|
|
7
|
+
const index_js_1 = require("../../../v2/durable-core/ids/index.js");
|
|
10
8
|
const workflow_hash_ref_js_1 = require("../../../v2/durable-core/ids/workflow-hash-ref.js");
|
|
11
9
|
const neverthrow_1 = require("neverthrow");
|
|
12
10
|
const validation_loader_js_1 = require("../../../v2/durable-core/domain/validation-loader.js");
|
|
@@ -15,54 +13,10 @@ const prompt_renderer_js_1 = require("../../../v2/durable-core/domain/prompt-ren
|
|
|
15
13
|
const v2_token_ops_js_1 = require("../v2-token-ops.js");
|
|
16
14
|
const v2_state_conversion_js_1 = require("../v2-state-conversion.js");
|
|
17
15
|
const constants_js_1 = require("../../../v2/durable-core/constants.js");
|
|
18
|
-
const
|
|
19
|
-
function buildBlockedReplayResponse(args) {
|
|
20
|
-
const { sessionId, runId, nodeId, attemptId, blockers, snapshot, truth, workflow, inputStateToken, inputAckToken, ports } = args;
|
|
21
|
-
const pendingNow = snapshot ? (0, snapshot_state_js_1.derivePendingStep)(snapshot.enginePayload.engineState) : null;
|
|
22
|
-
const isCompleteNow = snapshot ? (0, snapshot_state_js_1.deriveIsComplete)(snapshot.enginePayload.engineState) : false;
|
|
23
|
-
let metaOrNull = null;
|
|
24
|
-
if (pendingNow) {
|
|
25
|
-
const result = (0, prompt_renderer_js_1.renderPendingPrompt)({
|
|
26
|
-
workflow,
|
|
27
|
-
stepId: String(pendingNow.stepId),
|
|
28
|
-
loopPath: pendingNow.loopPath,
|
|
29
|
-
truth,
|
|
30
|
-
runId: (0, index_js_2.asRunId)(String(runId)),
|
|
31
|
-
nodeId: (0, index_js_2.asNodeId)(String(nodeId)),
|
|
32
|
-
rehydrateOnly: false,
|
|
33
|
-
});
|
|
34
|
-
if (result.isErr()) {
|
|
35
|
-
return (0, neverthrow_1.errAsync)({ kind: 'prompt_render_failed', message: result.error.message });
|
|
36
|
-
}
|
|
37
|
-
metaOrNull = result.value;
|
|
38
|
-
}
|
|
39
|
-
const preferences = (0, v2_execution_helpers_js_1.derivePreferencesOrDefault)({ truth, runId, nodeId });
|
|
40
|
-
const nextIntent = (0, v2_state_conversion_js_1.deriveNextIntent)({ rehydrateOnly: false, isComplete: isCompleteNow, pending: metaOrNull });
|
|
41
|
-
const replayCheckpointTokenRes = pendingNow
|
|
42
|
-
? (0, v2_token_ops_js_1.signTokenOrErr)({
|
|
43
|
-
payload: { tokenVersion: 1, tokenKind: 'checkpoint', sessionId, runId, nodeId, attemptId },
|
|
44
|
-
ports,
|
|
45
|
-
})
|
|
46
|
-
: (0, neverthrow_1.ok)(undefined);
|
|
47
|
-
return (0, neverthrow_1.okAsync)(output_schemas_js_1.V2ContinueWorkflowOutputSchema.parse({
|
|
48
|
-
kind: 'blocked',
|
|
49
|
-
stateToken: inputStateToken,
|
|
50
|
-
ackToken: inputAckToken,
|
|
51
|
-
checkpointToken: replayCheckpointTokenRes.isOk() ? replayCheckpointTokenRes.value : undefined,
|
|
52
|
-
isComplete: isCompleteNow,
|
|
53
|
-
pending: metaOrNull ? { stepId: metaOrNull.stepId, title: metaOrNull.title, prompt: metaOrNull.prompt } : null,
|
|
54
|
-
preferences,
|
|
55
|
-
nextIntent,
|
|
56
|
-
nextCall: (0, index_js_3.buildNextCall)({ stateToken: inputStateToken, ackToken: inputAckToken, isComplete: isCompleteNow, pending: metaOrNull }),
|
|
57
|
-
blockers,
|
|
58
|
-
retryable: undefined,
|
|
59
|
-
retryAckToken: undefined,
|
|
60
|
-
validation: (0, validation_loader_js_1.loadValidationResultV1)(truth.events, `validation_${String(attemptId)}`).unwrapOr(null) ?? undefined,
|
|
61
|
-
}));
|
|
62
|
-
}
|
|
16
|
+
const index_js_2 = require("./index.js");
|
|
63
17
|
function buildAdvancedReplayResponse(args) {
|
|
64
|
-
const { sessionId, runId, toNodeId, attemptId, toSnapshot, workflow, truth, workflowHash, ports, sha256 } = args;
|
|
65
|
-
const toNodeIdBranded = (0,
|
|
18
|
+
const { sessionId, runId, toNodeId, attemptId, toSnapshot, workflow, truth, workflowHash, ports, sha256, aliasStore, entropy } = args;
|
|
19
|
+
const toNodeIdBranded = (0, index_js_1.asNodeId)(String(toNodeId));
|
|
66
20
|
const pending = (0, snapshot_state_js_1.derivePendingStep)(toSnapshot.enginePayload.engineState);
|
|
67
21
|
const isComplete = (0, snapshot_state_js_1.deriveIsComplete)(toSnapshot.enginePayload.engineState);
|
|
68
22
|
const nextAttemptIdRes = (0, v2_token_ops_js_1.attemptIdForNextNode)(attemptId, sha256);
|
|
@@ -70,55 +24,39 @@ function buildAdvancedReplayResponse(args) {
|
|
|
70
24
|
return (0, neverthrow_1.errAsync)({ kind: 'invariant_violation', message: `Failed to derive next attemptId: ${nextAttemptIdRes.error.message}` });
|
|
71
25
|
}
|
|
72
26
|
const nextAttemptId = nextAttemptIdRes.value;
|
|
73
|
-
const nextAckTokenRes = pending
|
|
74
|
-
? (0, v2_token_ops_js_1.signTokenOrErr)({
|
|
75
|
-
payload: { tokenVersion: 1, tokenKind: 'ack', sessionId, runId, nodeId: toNodeIdBranded, attemptId: nextAttemptId },
|
|
76
|
-
ports,
|
|
77
|
-
})
|
|
78
|
-
: (0, neverthrow_1.ok)(undefined);
|
|
79
|
-
if (nextAckTokenRes.isErr()) {
|
|
80
|
-
return (0, neverthrow_1.errAsync)({ kind: 'token_signing_failed', cause: nextAckTokenRes.error });
|
|
81
|
-
}
|
|
82
|
-
const nextCheckpointTokenRes = pending
|
|
83
|
-
? (0, v2_token_ops_js_1.signTokenOrErr)({
|
|
84
|
-
payload: { tokenVersion: 1, tokenKind: 'checkpoint', sessionId, runId, nodeId: toNodeIdBranded, attemptId: nextAttemptId },
|
|
85
|
-
ports,
|
|
86
|
-
})
|
|
87
|
-
: (0, neverthrow_1.ok)(undefined);
|
|
88
|
-
if (nextCheckpointTokenRes.isErr()) {
|
|
89
|
-
return (0, neverthrow_1.errAsync)({ kind: 'token_signing_failed', cause: nextCheckpointTokenRes.error });
|
|
90
|
-
}
|
|
91
27
|
const wfRefRes = (0, workflow_hash_ref_js_1.deriveWorkflowHashRef)(workflowHash);
|
|
92
28
|
if (wfRefRes.isErr()) {
|
|
93
29
|
return (0, neverthrow_1.errAsync)({ kind: 'precondition_failed', message: wfRefRes.error.message, suggestion: 'Ensure workflowHash is a valid sha256 digest.' });
|
|
94
30
|
}
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
}
|
|
31
|
+
const entryBase = {
|
|
32
|
+
sessionId: String(sessionId),
|
|
33
|
+
runId: String(runId),
|
|
34
|
+
nodeId: String(toNodeIdBranded),
|
|
35
|
+
attemptId: String(nextAttemptId),
|
|
36
|
+
workflowHashRef: String(wfRefRes.value),
|
|
37
|
+
};
|
|
38
|
+
const nextTokensMint = (0, v2_token_ops_js_1.mintContinueAndCheckpointTokens)({ entry: entryBase, ports, aliasStore, entropy })
|
|
39
|
+
.mapErr((failure) => ({ kind: 'token_signing_failed', cause: failure }));
|
|
102
40
|
if (toSnapshot.enginePayload.engineState.kind === 'blocked') {
|
|
103
41
|
const blocked = toSnapshot.enginePayload.engineState.blocked;
|
|
104
42
|
const blockers = blocked.blockers;
|
|
105
43
|
const retryable = blocked.kind === 'retryable_block';
|
|
106
|
-
const
|
|
107
|
-
? (0, v2_token_ops_js_1.
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
44
|
+
const retryContinueMint = retryable
|
|
45
|
+
? (0, v2_token_ops_js_1.mintContinueAndCheckpointTokens)({
|
|
46
|
+
entry: {
|
|
47
|
+
aliasSlot: 'retry',
|
|
48
|
+
sessionId: String(sessionId),
|
|
49
|
+
runId: String(runId),
|
|
50
|
+
nodeId: String(toNodeIdBranded),
|
|
51
|
+
attemptId: String(blocked.retryAttemptId),
|
|
52
|
+
workflowHashRef: String(wfRefRes.value),
|
|
115
53
|
},
|
|
116
54
|
ports,
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
55
|
+
aliasStore,
|
|
56
|
+
entropy,
|
|
57
|
+
}).map((tokens) => tokens.continueToken)
|
|
58
|
+
.mapErr((failure) => ({ kind: 'token_signing_failed', cause: failure }))
|
|
59
|
+
: (0, neverthrow_1.okAsync)(undefined);
|
|
122
60
|
const validation = (0, validation_loader_js_1.loadValidationResultV1)(truth.events, String(blocked.validationRef)).unwrapOr(null) ?? undefined;
|
|
123
61
|
let blockedMeta = null;
|
|
124
62
|
if (pending) {
|
|
@@ -127,8 +65,8 @@ function buildAdvancedReplayResponse(args) {
|
|
|
127
65
|
stepId: String(pending.stepId),
|
|
128
66
|
loopPath: pending.loopPath,
|
|
129
67
|
truth,
|
|
130
|
-
runId: (0,
|
|
131
|
-
nodeId: (0,
|
|
68
|
+
runId: (0, index_js_1.asRunId)(String(runId)),
|
|
69
|
+
nodeId: (0, index_js_1.asNodeId)(String(toNodeIdBranded)),
|
|
132
70
|
rehydrateOnly: false,
|
|
133
71
|
});
|
|
134
72
|
if (result.isErr()) {
|
|
@@ -138,21 +76,20 @@ function buildAdvancedReplayResponse(args) {
|
|
|
138
76
|
}
|
|
139
77
|
const preferences = (0, v2_execution_helpers_js_1.derivePreferencesOrDefault)({ truth, runId, nodeId: toNodeIdBranded });
|
|
140
78
|
const nextIntent = (0, v2_state_conversion_js_1.deriveNextIntent)({ rehydrateOnly: false, isComplete, pending: blockedMeta });
|
|
141
|
-
return (0, neverthrow_1.okAsync)(output_schemas_js_1.V2ContinueWorkflowOutputSchema.parse({
|
|
79
|
+
return nextTokensMint.andThen((nextTokens) => retryContinueMint.andThen((retryContinueToken) => (0, neverthrow_1.okAsync)(output_schemas_js_1.V2ContinueWorkflowOutputSchema.parse({
|
|
142
80
|
kind: 'blocked',
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
checkpointToken: pending ? nextCheckpointTokenRes.value : undefined,
|
|
81
|
+
continueToken: pending ? nextTokens.continueToken : undefined,
|
|
82
|
+
checkpointToken: pending ? nextTokens.checkpointToken : undefined,
|
|
146
83
|
isComplete,
|
|
147
|
-
pending:
|
|
84
|
+
pending: (0, output_schemas_js_1.toPendingStep)(blockedMeta),
|
|
148
85
|
preferences,
|
|
149
86
|
nextIntent,
|
|
150
|
-
nextCall: (0,
|
|
87
|
+
nextCall: (0, index_js_2.buildNextCall)({ continueToken: pending ? nextTokens.continueToken : undefined, isComplete, pending: blockedMeta, retryContinueToken }),
|
|
151
88
|
blockers,
|
|
152
89
|
retryable,
|
|
153
|
-
|
|
90
|
+
retryContinueToken,
|
|
154
91
|
validation,
|
|
155
|
-
}));
|
|
92
|
+
}))));
|
|
156
93
|
}
|
|
157
94
|
let okMeta = null;
|
|
158
95
|
if (pending) {
|
|
@@ -161,8 +98,8 @@ function buildAdvancedReplayResponse(args) {
|
|
|
161
98
|
stepId: String(pending.stepId),
|
|
162
99
|
loopPath: pending.loopPath,
|
|
163
100
|
truth,
|
|
164
|
-
runId: (0,
|
|
165
|
-
nodeId: (0,
|
|
101
|
+
runId: (0, index_js_1.asRunId)(String(runId)),
|
|
102
|
+
nodeId: (0, index_js_1.asNodeId)(String(toNodeIdBranded)),
|
|
166
103
|
rehydrateOnly: false,
|
|
167
104
|
});
|
|
168
105
|
if (result.isErr()) {
|
|
@@ -172,41 +109,26 @@ function buildAdvancedReplayResponse(args) {
|
|
|
172
109
|
}
|
|
173
110
|
const preferences = (0, v2_execution_helpers_js_1.derivePreferencesOrDefault)({ truth, runId, nodeId: toNodeIdBranded });
|
|
174
111
|
const nextIntent = (0, v2_state_conversion_js_1.deriveNextIntent)({ rehydrateOnly: false, isComplete, pending: okMeta });
|
|
175
|
-
return (0, neverthrow_1.okAsync)(output_schemas_js_1.V2ContinueWorkflowOutputSchema.parse({
|
|
112
|
+
return nextTokensMint.andThen((nextTokens) => (0, neverthrow_1.okAsync)(output_schemas_js_1.V2ContinueWorkflowOutputSchema.parse({
|
|
176
113
|
kind: 'ok',
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
checkpointToken: pending ? nextCheckpointTokenRes.value : undefined,
|
|
114
|
+
continueToken: pending ? nextTokens.continueToken : undefined,
|
|
115
|
+
checkpointToken: pending ? nextTokens.checkpointToken : undefined,
|
|
180
116
|
isComplete,
|
|
181
|
-
pending:
|
|
117
|
+
pending: (0, output_schemas_js_1.toPendingStep)(okMeta),
|
|
182
118
|
preferences,
|
|
183
119
|
nextIntent,
|
|
184
|
-
nextCall: (0,
|
|
185
|
-
}));
|
|
120
|
+
nextCall: (0, index_js_2.buildNextCall)({ continueToken: pending ? nextTokens.continueToken : undefined, isComplete, pending: okMeta }),
|
|
121
|
+
})));
|
|
186
122
|
}
|
|
187
123
|
function replayFromRecordedAdvance(args) {
|
|
188
|
-
const { recordedEvent, truth, sessionId, runId, nodeId, workflowHash, attemptId,
|
|
124
|
+
const { recordedEvent, truth, sessionId, runId, nodeId, workflowHash, attemptId, pinnedWorkflow, snapshotStore, sha256, tokenCodecPorts, aliasStore, entropy, } = args;
|
|
189
125
|
if (recordedEvent.data.outcome.kind === 'blocked') {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
: (0, neverthrow_1.okAsync)(null);
|
|
195
|
-
return snapRA.andThen((snapshot) => buildBlockedReplayResponse({
|
|
196
|
-
sessionId,
|
|
197
|
-
runId,
|
|
198
|
-
nodeId,
|
|
199
|
-
attemptId,
|
|
200
|
-
blockers,
|
|
201
|
-
snapshot,
|
|
202
|
-
truth,
|
|
203
|
-
workflow: pinnedWorkflow,
|
|
204
|
-
inputStateToken,
|
|
205
|
-
inputAckToken,
|
|
206
|
-
ports: tokenCodecPorts,
|
|
207
|
-
}));
|
|
126
|
+
return (0, neverthrow_1.errAsync)({
|
|
127
|
+
kind: 'invariant_violation',
|
|
128
|
+
message: 'Legacy blocked advance_recorded outcomes are no longer supported. Sessions must be re-created.',
|
|
129
|
+
});
|
|
208
130
|
}
|
|
209
|
-
const toNodeId = (0,
|
|
131
|
+
const toNodeId = (0, index_js_1.asNodeId)(String(recordedEvent.data.outcome.toNodeId));
|
|
210
132
|
const toNode = truth.events.find((e) => e.kind === constants_js_1.EVENT_KIND.NODE_CREATED && e.scope?.nodeId === String(toNodeId));
|
|
211
133
|
if (!toNode) {
|
|
212
134
|
return (0, neverthrow_1.errAsync)({
|
|
@@ -236,6 +158,8 @@ function replayFromRecordedAdvance(args) {
|
|
|
236
158
|
workflowHash,
|
|
237
159
|
ports: tokenCodecPorts,
|
|
238
160
|
sha256,
|
|
161
|
+
aliasStore,
|
|
162
|
+
entropy,
|
|
239
163
|
});
|
|
240
164
|
});
|
|
241
165
|
}
|
|
@@ -45,9 +45,10 @@ export declare function mintStartTokens(args: {
|
|
|
45
45
|
readonly attemptId: import('../../../v2/durable-core/tokens/index.js').AttemptId;
|
|
46
46
|
readonly workflowHashRef: import('../../../v2/durable-core/ids/index.js').WorkflowHashRef;
|
|
47
47
|
readonly ports: TokenCodecPorts;
|
|
48
|
+
readonly aliasStore: import('../../../v2/ports/token-alias-store.port.js').TokenAliasStorePortV2;
|
|
49
|
+
readonly entropy: import('../../../v2/ports/random-entropy.port.js').RandomEntropyPortV2;
|
|
48
50
|
}): RA<{
|
|
49
|
-
readonly
|
|
50
|
-
readonly ackToken: string;
|
|
51
|
+
readonly continueToken: string;
|
|
51
52
|
readonly checkpointToken: string;
|
|
52
53
|
}, StartWorkflowError>;
|
|
53
54
|
export declare function executeStartWorkflow(input: import('../../v2/tools.js').V2StartWorkflowInput, ctx: V2ToolContext): RA<z.infer<typeof V2StartWorkflowOutputSchema>, StartWorkflowError>;
|