@exaudeus/workrail 3.15.0 → 3.16.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/workflow-service.d.ts +2 -0
- package/dist/application/services/workflow-service.js +3 -0
- package/dist/console/assets/index-BE5PAgPO.js +28 -0
- package/dist/console/assets/index-BZNM03t1.css +1 -0
- package/dist/console/index.html +2 -2
- package/dist/env-flags.d.ts +1 -0
- package/dist/env-flags.js +4 -0
- package/dist/infrastructure/session/HttpServer.d.ts +3 -3
- package/dist/infrastructure/session/HttpServer.js +68 -74
- package/dist/infrastructure/storage/caching-workflow-storage.d.ts +2 -0
- package/dist/infrastructure/storage/caching-workflow-storage.js +15 -6
- package/dist/infrastructure/storage/file-workflow-storage.js +3 -4
- package/dist/infrastructure/storage/schema-validating-workflow-storage.js +9 -8
- package/dist/manifest.json +257 -193
- package/dist/mcp/assert-output.d.ts +37 -0
- package/dist/mcp/assert-output.js +52 -0
- package/dist/mcp/boundary-coercion.d.ts +1 -0
- package/dist/mcp/boundary-coercion.js +44 -0
- package/dist/mcp/dev-mode.d.ts +1 -0
- package/dist/mcp/dev-mode.js +4 -0
- package/dist/mcp/handler-factory.js +12 -9
- package/dist/mcp/handlers/session.js +8 -9
- package/dist/mcp/handlers/v2-advance-core/event-builders.d.ts +2 -0
- package/dist/mcp/handlers/v2-advance-core/event-builders.js +6 -6
- package/dist/mcp/handlers/v2-advance-core/index.d.ts +2 -0
- package/dist/mcp/handlers/v2-advance-core/index.js +4 -3
- package/dist/mcp/handlers/v2-advance-core/input-validation.d.ts +2 -0
- package/dist/mcp/handlers/v2-advance-core/input-validation.js +32 -9
- package/dist/mcp/handlers/v2-advance-core/outcome-blocked.d.ts +2 -0
- package/dist/mcp/handlers/v2-advance-core/outcome-blocked.js +1 -1
- package/dist/mcp/handlers/v2-advance-core/outcome-success.d.ts +2 -0
- package/dist/mcp/handlers/v2-advance-core/outcome-success.js +1 -1
- package/dist/mcp/handlers/v2-checkpoint.d.ts +1 -1
- package/dist/mcp/handlers/v2-checkpoint.js +5 -6
- package/dist/mcp/handlers/v2-execution/advance.d.ts +4 -2
- package/dist/mcp/handlers/v2-execution/advance.js +5 -7
- package/dist/mcp/handlers/v2-execution/continue-advance.js +56 -26
- package/dist/mcp/handlers/v2-execution/continue-rehydrate.d.ts +1 -1
- package/dist/mcp/handlers/v2-execution/continue-rehydrate.js +9 -9
- package/dist/mcp/handlers/v2-execution/replay.d.ts +6 -4
- package/dist/mcp/handlers/v2-execution/replay.js +47 -30
- package/dist/mcp/handlers/v2-execution/start.d.ts +2 -3
- package/dist/mcp/handlers/v2-execution/start.js +11 -11
- package/dist/mcp/handlers/v2-execution/workflow-object-cache.d.ts +5 -0
- package/dist/mcp/handlers/v2-execution/workflow-object-cache.js +19 -0
- package/dist/mcp/handlers/v2-execution-helpers.d.ts +1 -0
- package/dist/mcp/handlers/v2-execution-helpers.js +23 -7
- package/dist/mcp/handlers/v2-resume.d.ts +1 -1
- package/dist/mcp/handlers/v2-resume.js +3 -4
- package/dist/mcp/handlers/v2-state-conversion.js +5 -1
- package/dist/mcp/handlers/v2-workflow.d.ts +80 -0
- package/dist/mcp/handlers/v2-workflow.js +36 -21
- package/dist/mcp/handlers/workflow.d.ts +2 -5
- package/dist/mcp/handlers/workflow.js +15 -12
- package/dist/mcp/output-schemas.d.ts +20 -27
- package/dist/mcp/output-schemas.js +5 -7
- package/dist/mcp/server.js +22 -4
- package/dist/mcp/tool-call-timing.d.ts +24 -0
- package/dist/mcp/tool-call-timing.js +85 -0
- package/dist/mcp/transports/http-entry.js +3 -2
- package/dist/mcp/transports/http-listener.d.ts +1 -0
- package/dist/mcp/transports/http-listener.js +25 -0
- package/dist/mcp/transports/shutdown-hooks.d.ts +4 -1
- package/dist/mcp/transports/shutdown-hooks.js +3 -2
- package/dist/mcp/transports/stdio-entry.js +6 -28
- package/dist/mcp/v2-response-formatter.js +2 -4
- package/dist/mcp/validation/schema-introspection.d.ts +1 -0
- package/dist/mcp/validation/schema-introspection.js +15 -5
- package/dist/mcp/validation/suggestion-generator.js +2 -2
- package/dist/runtime/adapters/node-process-signals.d.ts +1 -0
- package/dist/runtime/adapters/node-process-signals.js +5 -0
- package/dist/runtime/adapters/noop-process-signals.d.ts +1 -0
- package/dist/runtime/adapters/noop-process-signals.js +2 -0
- package/dist/runtime/ports/process-signals.d.ts +1 -0
- package/dist/types/workflow-definition.d.ts +2 -0
- package/dist/types/workflow.d.ts +3 -0
- package/dist/types/workflow.js +35 -26
- package/dist/v2/durable-core/domain/context-template-resolver.js +2 -2
- package/dist/v2/durable-core/domain/function-definition-expander.js +2 -17
- package/dist/v2/durable-core/domain/prompt-renderer.d.ts +1 -0
- package/dist/v2/durable-core/domain/prompt-renderer.js +23 -18
- package/dist/v2/durable-core/domain/recap-recovery.js +23 -16
- package/dist/v2/durable-core/domain/retrieval-contract.js +13 -7
- package/dist/v2/durable-core/session-index.d.ts +22 -0
- package/dist/v2/durable-core/session-index.js +58 -0
- package/dist/v2/durable-core/sorted-event-log.d.ts +6 -0
- package/dist/v2/durable-core/sorted-event-log.js +15 -0
- package/dist/v2/infra/local/fs/index.js +8 -8
- package/dist/v2/infra/local/session-store/index.d.ts +1 -1
- package/dist/v2/infra/local/session-store/index.js +71 -61
- package/dist/v2/infra/local/session-summary-provider/index.js +9 -4
- package/dist/v2/infra/local/snapshot-store/index.js +2 -1
- package/dist/v2/ports/session-event-log-store.port.d.ts +1 -1
- package/dist/v2/projections/assessment-consequences.d.ts +2 -1
- package/dist/v2/projections/assessment-consequences.js +0 -5
- package/dist/v2/projections/assessments.d.ts +2 -1
- package/dist/v2/projections/assessments.js +2 -4
- package/dist/v2/projections/gaps.d.ts +2 -1
- package/dist/v2/projections/gaps.js +0 -5
- package/dist/v2/projections/preferences.d.ts +2 -1
- package/dist/v2/projections/preferences.js +0 -5
- package/dist/v2/projections/run-context.d.ts +2 -2
- package/dist/v2/projections/run-context.js +0 -5
- package/dist/v2/projections/run-dag.js +7 -1
- package/dist/v2/projections/run-execution-trace.d.ts +8 -0
- package/dist/v2/projections/run-execution-trace.js +124 -0
- package/dist/v2/projections/run-status-signals.d.ts +2 -2
- package/dist/v2/usecases/console-routes.d.ts +3 -1
- package/dist/v2/usecases/console-routes.js +123 -25
- package/dist/v2/usecases/console-service.d.ts +1 -0
- package/dist/v2/usecases/console-service.js +83 -25
- package/dist/v2/usecases/console-types.d.ts +53 -0
- package/dist/v2/usecases/worktree-service.js +32 -1
- package/package.json +6 -5
- package/spec/workflow.schema.json +18 -0
- package/workflows/adaptive-ticket-creation.json +23 -16
- package/workflows/architecture-scalability-audit.json +29 -22
- package/workflows/bug-investigation.agentic.v2.json +7 -0
- package/workflows/coding-task-workflow-agentic.json +7 -0
- package/workflows/coding-task-workflow-agentic.lean.v2.json +16 -8
- package/workflows/coding-task-workflow-agentic.v2.json +7 -0
- package/workflows/cross-platform-code-conversion.v2.json +7 -0
- package/workflows/document-creation-workflow.json +15 -8
- package/workflows/documentation-update-workflow.json +15 -8
- package/workflows/intelligent-test-case-generation.json +7 -0
- package/workflows/learner-centered-course-workflow.json +9 -2
- package/workflows/mr-review-workflow.agentic.v2.json +7 -0
- package/workflows/personal-learning-materials-creation-branched.json +15 -8
- package/workflows/presentation-creation.json +12 -5
- package/workflows/production-readiness-audit.json +7 -0
- package/workflows/relocation-workflow-us.json +39 -32
- package/workflows/scoped-documentation-workflow.json +33 -26
- package/workflows/ui-ux-design-workflow.json +7 -0
- package/workflows/workflow-diagnose-environment.json +6 -0
- package/workflows/workflow-for-workflows.json +7 -0
- package/workflows/workflow-for-workflows.v2.json +23 -11
- package/workflows/wr.discovery.json +8 -1
- package/dist/console/assets/index-BZYIjrzJ.js +0 -28
- package/dist/console/assets/index-OLCKbDdm.css +0 -1
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export declare function assertOutput<T>(data: T, check: (data: T) => void): T;
|
|
2
|
+
type BlockerPointer = {
|
|
3
|
+
readonly kind: 'context_key';
|
|
4
|
+
readonly key: string;
|
|
5
|
+
} | {
|
|
6
|
+
readonly kind: 'context_budget';
|
|
7
|
+
} | {
|
|
8
|
+
readonly kind: 'output_contract';
|
|
9
|
+
readonly contractRef: string;
|
|
10
|
+
} | {
|
|
11
|
+
readonly kind: 'capability';
|
|
12
|
+
readonly capability: string;
|
|
13
|
+
} | {
|
|
14
|
+
readonly kind: 'assessment_dimension';
|
|
15
|
+
readonly assessmentId: string;
|
|
16
|
+
readonly dimensionId: string;
|
|
17
|
+
} | {
|
|
18
|
+
readonly kind: 'workflow_step';
|
|
19
|
+
readonly stepId: string;
|
|
20
|
+
};
|
|
21
|
+
type BlockerLike = {
|
|
22
|
+
readonly code: string;
|
|
23
|
+
readonly pointer: BlockerPointer;
|
|
24
|
+
};
|
|
25
|
+
type BlockerReportLike = {
|
|
26
|
+
readonly blockers: readonly BlockerLike[];
|
|
27
|
+
};
|
|
28
|
+
export declare function assertBlockerReportInvariants(report: BlockerReportLike): void;
|
|
29
|
+
type PendingLike = {
|
|
30
|
+
readonly stepId: string;
|
|
31
|
+
} | null;
|
|
32
|
+
type ContinueTokenHolder = {
|
|
33
|
+
readonly continueToken?: string | null | undefined;
|
|
34
|
+
readonly pending: PendingLike;
|
|
35
|
+
};
|
|
36
|
+
export declare function assertContinueTokenPresence(data: ContinueTokenHolder): void;
|
|
37
|
+
export {};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.assertOutput = assertOutput;
|
|
4
|
+
exports.assertBlockerReportInvariants = assertBlockerReportInvariants;
|
|
5
|
+
exports.assertContinueTokenPresence = assertContinueTokenPresence;
|
|
6
|
+
function assertOutput(data, check) {
|
|
7
|
+
if (process.env['WORKRAIL_DEV'] === '1') {
|
|
8
|
+
check(data);
|
|
9
|
+
}
|
|
10
|
+
return data;
|
|
11
|
+
}
|
|
12
|
+
function assertBlockerReportInvariants(report) {
|
|
13
|
+
const keyFor = (b) => {
|
|
14
|
+
const p = b.pointer;
|
|
15
|
+
let ptrStable;
|
|
16
|
+
switch (p.kind) {
|
|
17
|
+
case 'context_key':
|
|
18
|
+
ptrStable = p.key;
|
|
19
|
+
break;
|
|
20
|
+
case 'output_contract':
|
|
21
|
+
ptrStable = p.contractRef;
|
|
22
|
+
break;
|
|
23
|
+
case 'capability':
|
|
24
|
+
ptrStable = p.capability;
|
|
25
|
+
break;
|
|
26
|
+
case 'assessment_dimension':
|
|
27
|
+
ptrStable = `${p.assessmentId}|${p.dimensionId}`;
|
|
28
|
+
break;
|
|
29
|
+
case 'workflow_step':
|
|
30
|
+
ptrStable = p.stepId;
|
|
31
|
+
break;
|
|
32
|
+
case 'context_budget':
|
|
33
|
+
ptrStable = '';
|
|
34
|
+
break;
|
|
35
|
+
default: {
|
|
36
|
+
const _exhaustive = p;
|
|
37
|
+
ptrStable = String(_exhaustive);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return `${b.code}|${p.kind}|${String(ptrStable)}`;
|
|
41
|
+
};
|
|
42
|
+
for (let i = 1; i < report.blockers.length; i++) {
|
|
43
|
+
if (keyFor(report.blockers[i - 1]) > keyFor(report.blockers[i])) {
|
|
44
|
+
throw new Error('assertOutput: blockers must be deterministically sorted by composite key');
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function assertContinueTokenPresence(data) {
|
|
49
|
+
if (data.pending != null && data.continueToken == null) {
|
|
50
|
+
throw new Error('assertOutput: continueToken is required when a pending step exists');
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
export declare function buildCoercionFn(shapeSchema: z.ZodObject<z.ZodRawShape>, aliasMap?: Readonly<Record<string, string>>): (args: unknown) => unknown;
|
|
2
3
|
export declare function coerceJsonStringObjectFields(args: unknown, shapeSchema: z.ZodObject<z.ZodRawShape>, aliasMap?: Readonly<Record<string, string>>): unknown;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildCoercionFn = buildCoercionFn;
|
|
3
4
|
exports.coerceJsonStringObjectFields = coerceJsonStringObjectFields;
|
|
4
5
|
const zod_1 = require("zod");
|
|
6
|
+
const schema_introspection_js_1 = require("./validation/schema-introspection.js");
|
|
5
7
|
function unwrapToBaseType(schema) {
|
|
6
8
|
let current = schema;
|
|
7
9
|
for (;;) {
|
|
@@ -32,6 +34,48 @@ function tryParseJsonObject(value) {
|
|
|
32
34
|
return null;
|
|
33
35
|
}
|
|
34
36
|
}
|
|
37
|
+
function buildCoercionFn(shapeSchema, aliasMap) {
|
|
38
|
+
const shape = (0, schema_introspection_js_1.getCachedShape)(shapeSchema);
|
|
39
|
+
const objectFields = new Set();
|
|
40
|
+
for (const [key, fieldSchema] of Object.entries(shape)) {
|
|
41
|
+
if (expectsObjectValue(fieldSchema)) {
|
|
42
|
+
objectFields.add(key);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
const aliasesToCoerce = new Set();
|
|
46
|
+
if (aliasMap) {
|
|
47
|
+
for (const [alias, canonical] of Object.entries(aliasMap)) {
|
|
48
|
+
if (objectFields.has(canonical)) {
|
|
49
|
+
aliasesToCoerce.add(alias);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
const hasCoercibleFields = objectFields.size > 0 || aliasesToCoerce.size > 0;
|
|
54
|
+
return (args) => {
|
|
55
|
+
if (!hasCoercibleFields)
|
|
56
|
+
return args;
|
|
57
|
+
if (typeof args !== 'object' || args === null)
|
|
58
|
+
return args;
|
|
59
|
+
const input = args;
|
|
60
|
+
let result = null;
|
|
61
|
+
const coerceField = (key) => {
|
|
62
|
+
const value = input[key];
|
|
63
|
+
if (typeof value !== 'string')
|
|
64
|
+
return;
|
|
65
|
+
const parsed = tryParseJsonObject(value);
|
|
66
|
+
if (parsed === null)
|
|
67
|
+
return;
|
|
68
|
+
if (result === null)
|
|
69
|
+
result = { ...input };
|
|
70
|
+
result[key] = parsed;
|
|
71
|
+
};
|
|
72
|
+
for (const key of objectFields)
|
|
73
|
+
coerceField(key);
|
|
74
|
+
for (const alias of aliasesToCoerce)
|
|
75
|
+
coerceField(alias);
|
|
76
|
+
return result ?? args;
|
|
77
|
+
};
|
|
78
|
+
}
|
|
35
79
|
function coerceJsonStringObjectFields(args, shapeSchema, aliasMap) {
|
|
36
80
|
if (typeof args !== 'object' || args === null)
|
|
37
81
|
return args;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const DEV_MODE: boolean;
|
|
@@ -36,7 +36,7 @@ function toMcpResult(result) {
|
|
|
36
36
|
return {
|
|
37
37
|
content: [{
|
|
38
38
|
type: 'text',
|
|
39
|
-
text: JSON.stringify(jsonPayload
|
|
39
|
+
text: JSON.stringify(jsonPayload),
|
|
40
40
|
}],
|
|
41
41
|
};
|
|
42
42
|
}
|
|
@@ -49,17 +49,18 @@ function toMcpResult(result) {
|
|
|
49
49
|
message: result.message,
|
|
50
50
|
retry: result.retry,
|
|
51
51
|
...(result.details !== undefined ? { details: result.details } : {}),
|
|
52
|
-
}
|
|
52
|
+
}),
|
|
53
53
|
}],
|
|
54
54
|
isError: true,
|
|
55
55
|
};
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
function createHandler(schema, handler, shapeSchema, aliasMap) {
|
|
59
|
+
const coerce = shapeSchema !== undefined
|
|
60
|
+
? (0, boundary_coercion_js_1.buildCoercionFn)(shapeSchema, aliasMap)
|
|
61
|
+
: null;
|
|
59
62
|
return async (args, ctx) => {
|
|
60
|
-
const normalizedArgs =
|
|
61
|
-
? (0, boundary_coercion_js_1.coerceJsonStringObjectFields)(args, shapeSchema, aliasMap)
|
|
62
|
-
: args;
|
|
63
|
+
const normalizedArgs = coerce !== null ? coerce(args) : args;
|
|
63
64
|
const parseResult = schema.safeParse(normalizedArgs);
|
|
64
65
|
if (!parseResult.success) {
|
|
65
66
|
const introspectionSchema = shapeSchema ?? schema;
|
|
@@ -87,10 +88,12 @@ function createHandler(schema, handler, shapeSchema, aliasMap) {
|
|
|
87
88
|
};
|
|
88
89
|
}
|
|
89
90
|
function createValidatingHandler(schema, preValidate, handler, shapeSchema, aliasMap) {
|
|
91
|
+
const coerce = shapeSchema !== undefined
|
|
92
|
+
? (0, boundary_coercion_js_1.buildCoercionFn)(shapeSchema, aliasMap)
|
|
93
|
+
: null;
|
|
94
|
+
const innerHandler = createHandler(schema, handler, shapeSchema);
|
|
90
95
|
return async (args, ctx) => {
|
|
91
|
-
const normalizedArgs =
|
|
92
|
-
? (0, boundary_coercion_js_1.coerceJsonStringObjectFields)(args, shapeSchema, aliasMap)
|
|
93
|
-
: args;
|
|
96
|
+
const normalizedArgs = coerce !== null ? coerce(args) : args;
|
|
94
97
|
const pre = preValidate(normalizedArgs);
|
|
95
98
|
if (!pre.ok) {
|
|
96
99
|
const error = pre.error;
|
|
@@ -110,6 +113,6 @@ function createValidatingHandler(schema, preValidate, handler, shapeSchema, alia
|
|
|
110
113
|
}
|
|
111
114
|
return toMcpResult(error);
|
|
112
115
|
}
|
|
113
|
-
return
|
|
116
|
+
return innerHandler(normalizedArgs, ctx);
|
|
114
117
|
};
|
|
115
118
|
}
|
|
@@ -5,7 +5,6 @@ exports.handleUpdateSession = handleUpdateSession;
|
|
|
5
5
|
exports.handleReadSession = handleReadSession;
|
|
6
6
|
exports.handleOpenDashboard = handleOpenDashboard;
|
|
7
7
|
const types_js_1 = require("../types.js");
|
|
8
|
-
const output_schemas_js_1 = require("../output-schemas.js");
|
|
9
8
|
const SESSION_SCHEMA_OVERVIEW = {
|
|
10
9
|
description: 'Bug Investigation Session Data Structure',
|
|
11
10
|
mainSections: {
|
|
@@ -58,13 +57,13 @@ async function handleCreateSession(input, ctx) {
|
|
|
58
57
|
const session = res.value;
|
|
59
58
|
const baseUrl = httpServer.getBaseUrl();
|
|
60
59
|
const dashboardUrl = baseUrl ? `${baseUrl}?session=${input.sessionId}` : null;
|
|
61
|
-
const payload =
|
|
60
|
+
const payload = {
|
|
62
61
|
sessionId: session.id,
|
|
63
62
|
workflowId: session.workflowId,
|
|
64
63
|
path: sessionManager.getSessionPath(input.workflowId, input.sessionId),
|
|
65
64
|
dashboardUrl,
|
|
66
65
|
createdAt: session.createdAt,
|
|
67
|
-
}
|
|
66
|
+
};
|
|
68
67
|
return (0, types_js_1.success)(payload);
|
|
69
68
|
}
|
|
70
69
|
async function handleUpdateSession(input, ctx) {
|
|
@@ -81,7 +80,7 @@ async function handleUpdateSession(input, ctx) {
|
|
|
81
80
|
}
|
|
82
81
|
return (0, types_js_1.errNotRetryable)('INTERNAL_ERROR', res.error.message);
|
|
83
82
|
}
|
|
84
|
-
const payload =
|
|
83
|
+
const payload = { updatedAt: new Date().toISOString() };
|
|
85
84
|
return (0, types_js_1.success)(payload);
|
|
86
85
|
}
|
|
87
86
|
async function handleReadSession(input, ctx) {
|
|
@@ -90,10 +89,10 @@ async function handleReadSession(input, ctx) {
|
|
|
90
89
|
return guardError;
|
|
91
90
|
const sessionManager = ctx.sessionManager;
|
|
92
91
|
if (input.path === '$schema') {
|
|
93
|
-
const payload =
|
|
92
|
+
const payload = {
|
|
94
93
|
query: '$schema',
|
|
95
94
|
schema: SESSION_SCHEMA_OVERVIEW,
|
|
96
|
-
}
|
|
95
|
+
};
|
|
97
96
|
return (0, types_js_1.success)(payload);
|
|
98
97
|
}
|
|
99
98
|
const res = await sessionManager.readSession(input.workflowId, input.sessionId, input.path);
|
|
@@ -105,10 +104,10 @@ async function handleReadSession(input, ctx) {
|
|
|
105
104
|
}
|
|
106
105
|
return (0, types_js_1.errNotRetryable)('INTERNAL_ERROR', res.error.message);
|
|
107
106
|
}
|
|
108
|
-
const payload =
|
|
107
|
+
const payload = {
|
|
109
108
|
query: input.path ?? '(full session)',
|
|
110
109
|
data: res.value,
|
|
111
|
-
}
|
|
110
|
+
};
|
|
112
111
|
return (0, types_js_1.success)(payload);
|
|
113
112
|
}
|
|
114
113
|
async function handleOpenDashboard(input, ctx) {
|
|
@@ -118,7 +117,7 @@ async function handleOpenDashboard(input, ctx) {
|
|
|
118
117
|
const httpServer = ctx.httpServer;
|
|
119
118
|
try {
|
|
120
119
|
const url = await httpServer.openDashboard(input.sessionId);
|
|
121
|
-
const payload =
|
|
120
|
+
const payload = { url };
|
|
122
121
|
return (0, types_js_1.success)(payload);
|
|
123
122
|
}
|
|
124
123
|
catch (err) {
|
|
@@ -10,8 +10,10 @@ import type { V2ContinueWorkflowInput } from '../../v2/tools.js';
|
|
|
10
10
|
import { type OutputToAppend } from '../../../v2/durable-core/domain/outputs.js';
|
|
11
11
|
import type { InternalError } from '../v2-error-mapping.js';
|
|
12
12
|
import type { AdvanceCorePorts } from './index.js';
|
|
13
|
+
import type { SessionIndex } from '../../../v2/durable-core/session-index.js';
|
|
13
14
|
type BuildAppendPlanArgs = {
|
|
14
15
|
readonly truth: LoadedSessionTruthV2;
|
|
16
|
+
readonly lockedIndex: SessionIndex;
|
|
15
17
|
readonly sessionId: SessionId;
|
|
16
18
|
readonly runId: RunId;
|
|
17
19
|
readonly currentNodeId: NodeId;
|
|
@@ -11,15 +11,15 @@ const outputs_js_1 = require("../../../v2/durable-core/domain/outputs.js");
|
|
|
11
11
|
const ack_advance_append_plan_js_1 = require("../../../v2/durable-core/domain/ack-advance-append-plan.js");
|
|
12
12
|
const constants_js_1 = require("../../../v2/durable-core/constants.js");
|
|
13
13
|
function buildAndAppendPlan(args) {
|
|
14
|
-
const { truth, sessionId, runId, currentNodeId, attemptId, workflowHash, extraEventsToAppend, sessionStore, idFactory, lock } = args;
|
|
15
|
-
const nextEventIndex =
|
|
14
|
+
const { truth, lockedIndex, sessionId, runId, currentNodeId, attemptId, workflowHash, extraEventsToAppend, sessionStore, idFactory, lock } = args;
|
|
15
|
+
const nextEventIndex = lockedIndex.nextEventIndex;
|
|
16
16
|
const evtAdvanceRecorded = idFactory.mintEventId();
|
|
17
17
|
if (args.kind === 'blocked') {
|
|
18
18
|
const toNodeId = String(idFactory.mintNodeId());
|
|
19
19
|
const evtNodeCreated = idFactory.mintEventId();
|
|
20
20
|
const evtEdgeCreated = idFactory.mintEventId();
|
|
21
21
|
const outputEventIds = (args.outputsToAppend ?? []).map(() => idFactory.mintEventId());
|
|
22
|
-
const hasChildren =
|
|
22
|
+
const hasChildren = lockedIndex.hasChildEdgeByFromNodeId.has(String(currentNodeId));
|
|
23
23
|
const causeKind = hasChildren ? constants_js_1.EDGE_CAUSE.NON_TIP_ADVANCE : constants_js_1.EDGE_CAUSE.INTENTIONAL_FORK;
|
|
24
24
|
const planRes = (0, ack_advance_append_plan_js_1.buildAckAdvanceAppendPlanV1)({
|
|
25
25
|
sessionId: String(sessionId),
|
|
@@ -44,12 +44,12 @@ function buildAndAppendPlan(args) {
|
|
|
44
44
|
});
|
|
45
45
|
if (planRes.isErr())
|
|
46
46
|
return (0, neverthrow_1.errAsync)({ kind: 'invariant_violation', message: planRes.error.message });
|
|
47
|
-
return sessionStore.append(lock, planRes.value);
|
|
47
|
+
return sessionStore.append(lock, planRes.value, truth);
|
|
48
48
|
}
|
|
49
49
|
const toNodeId = String(idFactory.mintNodeId());
|
|
50
50
|
const evtNodeCreated = idFactory.mintEventId();
|
|
51
51
|
const evtEdgeCreated = idFactory.mintEventId();
|
|
52
|
-
const hasChildren =
|
|
52
|
+
const hasChildren = lockedIndex.hasChildEdgeByFromNodeId.has(String(currentNodeId));
|
|
53
53
|
const causeKind = hasChildren ? constants_js_1.EDGE_CAUSE.NON_TIP_ADVANCE : constants_js_1.EDGE_CAUSE.INTENTIONAL_FORK;
|
|
54
54
|
const normalizedOutputs = (0, outputs_js_1.normalizeOutputsForAppend)(args.outputsToAppend);
|
|
55
55
|
const outputEventIds = normalizedOutputs.map(() => idFactory.mintEventId());
|
|
@@ -76,7 +76,7 @@ function buildAndAppendPlan(args) {
|
|
|
76
76
|
});
|
|
77
77
|
if (planRes.isErr())
|
|
78
78
|
return (0, neverthrow_1.errAsync)({ kind: 'invariant_violation', message: planRes.error.message });
|
|
79
|
-
return sessionStore.append(lock, planRes.value);
|
|
79
|
+
return sessionStore.append(lock, planRes.value, truth);
|
|
80
80
|
}
|
|
81
81
|
function buildNotesOutputs(allowNotesAppend, attemptId, inputOutput) {
|
|
82
82
|
if (!allowNotesAppend || !inputOutput?.notesMarkdown)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ResultAsync as RA } from 'neverthrow';
|
|
2
|
+
import type { SessionIndex } from '../../../v2/durable-core/session-index.js';
|
|
2
3
|
import type { ExecutionSnapshotFileV1, EngineStateV1 } from '../../../v2/durable-core/schemas/execution-snapshot/index.js';
|
|
3
4
|
import type { SessionId, RunId, NodeId, WorkflowHash } from '../../../v2/durable-core/ids/index.js';
|
|
4
5
|
import type { AttemptId } from '../../../v2/durable-core/tokens/index.js';
|
|
@@ -63,4 +64,5 @@ export declare function executeAdvanceCore(args: {
|
|
|
63
64
|
readonly lock: WithHealthySessionLock;
|
|
64
65
|
readonly pinnedWorkflow: ReturnType<typeof createWorkflow>;
|
|
65
66
|
readonly ports: AdvanceCorePorts;
|
|
67
|
+
readonly lockedIndex: SessionIndex;
|
|
66
68
|
}): RA<void, InternalError | SessionEventLogStoreError | SnapshotStoreError>;
|
|
@@ -39,6 +39,7 @@ function executeAdvanceCore(args) {
|
|
|
39
39
|
}
|
|
40
40
|
const validatedRes = (0, input_validation_js_1.validateAdvanceInputs)({
|
|
41
41
|
truth, runId, currentNodeId, inputContext, inputOutput, pinnedWorkflow, pendingStep,
|
|
42
|
+
precomputedIndex: args.lockedIndex,
|
|
42
43
|
});
|
|
43
44
|
if (validatedRes.isErr())
|
|
44
45
|
return errAsync(validatedRes.error);
|
|
@@ -71,7 +72,7 @@ function executeAdvanceCore(args) {
|
|
|
71
72
|
const ctx = { truth, sessionId, runId, currentNodeId, attemptId, workflowHash, inputOutput, pinnedWorkflow, engineState, pendingStep };
|
|
72
73
|
const computed = { reasons: effectiveReasons, outputRequirement, validation: evalValidation };
|
|
73
74
|
const portsLocal = { snapshotStore, sessionStore, sha256, idFactory };
|
|
74
|
-
return (0, outcome_blocked_js_1.buildBlockedOutcome)({ mode, snap, ctx, computed, v, lock, ports: portsLocal });
|
|
75
|
+
return (0, outcome_blocked_js_1.buildBlockedOutcome)({ mode, snap, ctx, computed, v, lock, ports: portsLocal, lockedIndex: args.lockedIndex });
|
|
75
76
|
}
|
|
76
77
|
const validation = phase.validation;
|
|
77
78
|
const effectiveValidation = v.assessmentValidation && !v.assessmentValidation.validation.valid
|
|
@@ -110,9 +111,9 @@ function executeAdvanceCore(args) {
|
|
|
110
111
|
const computed = { reasons, outputRequirement, validation: effectiveValidation };
|
|
111
112
|
const ports = { snapshotStore, sessionStore, sha256, idFactory };
|
|
112
113
|
if (shouldBlockNow) {
|
|
113
|
-
return (0, outcome_blocked_js_1.buildBlockedOutcome)({ mode, snap, ctx, computed, v, lock, ports });
|
|
114
|
+
return (0, outcome_blocked_js_1.buildBlockedOutcome)({ mode, snap, ctx, computed, v, lock, ports, lockedIndex: args.lockedIndex });
|
|
114
115
|
}
|
|
115
|
-
return (0, outcome_success_js_1.buildSuccessOutcome)({ mode, ctx, computed, v, lock, ports });
|
|
116
|
+
return (0, outcome_success_js_1.buildSuccessOutcome)({ mode, ctx, computed, v, lock, ports, lockedIndex: args.lockedIndex });
|
|
116
117
|
});
|
|
117
118
|
}
|
|
118
119
|
function derivePendingStepForMode(mode, engineState) {
|
|
@@ -9,6 +9,7 @@ import type { AssessmentArtifactV1 } from '../../../v2/durable-core/schemas/arti
|
|
|
9
9
|
import type { RecordedAssessmentV1 } from '../../../v2/durable-core/domain/assessment-record.js';
|
|
10
10
|
import type { TriggeredAssessmentConsequenceV1 } from './assessment-consequences.js';
|
|
11
11
|
import type { InternalError } from '../v2-error-mapping.js';
|
|
12
|
+
import type { SessionIndex } from '../../../v2/durable-core/session-index.js';
|
|
12
13
|
export interface ValidatedAdvanceInputs {
|
|
13
14
|
readonly pendingStep: {
|
|
14
15
|
readonly stepId: string;
|
|
@@ -50,4 +51,5 @@ export declare function validateAdvanceInputs(args: {
|
|
|
50
51
|
readonly iteration: number;
|
|
51
52
|
}[];
|
|
52
53
|
};
|
|
54
|
+
readonly precomputedIndex?: SessionIndex;
|
|
53
55
|
}): Result<ValidatedAdvanceInputs, InternalError>;
|
|
@@ -5,14 +5,28 @@ const neverthrow_1 = require("neverthrow");
|
|
|
5
5
|
const workflow_js_1 = require("../../../types/workflow.js");
|
|
6
6
|
const run_context_js_1 = require("../../../v2/projections/run-context.js");
|
|
7
7
|
const preferences_js_1 = require("../../../v2/projections/preferences.js");
|
|
8
|
+
const sorted_event_log_js_1 = require("../../../v2/durable-core/sorted-event-log.js");
|
|
8
9
|
const context_merge_js_1 = require("../../../v2/durable-core/domain/context-merge.js");
|
|
9
10
|
const constants_js_1 = require("../../../v2/durable-core/constants.js");
|
|
10
11
|
const assessment_validation_js_1 = require("./assessment-validation.js");
|
|
11
12
|
const assessment_consequences_js_1 = require("./assessment-consequences.js");
|
|
12
13
|
function validateAdvanceInputs(args) {
|
|
13
14
|
const { truth, runId, currentNodeId, inputContext, inputOutput, pinnedWorkflow, pendingStep } = args;
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
let sortedEvents;
|
|
16
|
+
let storedContext;
|
|
17
|
+
if (args.precomputedIndex) {
|
|
18
|
+
sortedEvents = args.precomputedIndex.sortedEvents;
|
|
19
|
+
storedContext = args.precomputedIndex.runContextByRunId.get(String(runId));
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
const sortedEventsRes = (0, sorted_event_log_js_1.asSortedEventLog)(truth.events);
|
|
23
|
+
if (sortedEventsRes.isErr()) {
|
|
24
|
+
return (0, neverthrow_1.err)({ kind: 'invariant_violation', message: sortedEventsRes.error.message });
|
|
25
|
+
}
|
|
26
|
+
sortedEvents = sortedEventsRes.value;
|
|
27
|
+
const storedContextRes = (0, run_context_js_1.projectRunContextV2)(sortedEvents);
|
|
28
|
+
storedContext = storedContextRes.isOk() ? storedContextRes.value.byRunId[String(runId)]?.context : undefined;
|
|
29
|
+
}
|
|
16
30
|
const inputContextObj = inputContext && typeof inputContext === 'object' && inputContext !== null && !Array.isArray(inputContext)
|
|
17
31
|
? inputContext
|
|
18
32
|
: undefined;
|
|
@@ -39,14 +53,23 @@ function validateAdvanceInputs(args) {
|
|
|
39
53
|
const notesOptional = outputContract !== undefined ||
|
|
40
54
|
(step !== null && step !== undefined && 'notesOptional' in step && step.notesOptional === true);
|
|
41
55
|
const parentByNodeId = {};
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
56
|
+
if (args.precomputedIndex) {
|
|
57
|
+
for (const [nodeId, evt] of args.precomputedIndex.nodeCreatedByNodeId) {
|
|
58
|
+
if (evt.scope.runId === String(runId)) {
|
|
59
|
+
parentByNodeId[nodeId] = evt.data.parentNodeId ?? null;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
for (const e of truth.events) {
|
|
65
|
+
if (e.kind !== constants_js_1.EVENT_KIND.NODE_CREATED)
|
|
66
|
+
continue;
|
|
67
|
+
if (e.scope?.runId !== String(runId))
|
|
68
|
+
continue;
|
|
69
|
+
parentByNodeId[String(e.scope.nodeId)] = e.data.parentNodeId;
|
|
70
|
+
}
|
|
48
71
|
}
|
|
49
|
-
const prefs = (0, preferences_js_1.projectPreferencesV2)(
|
|
72
|
+
const prefs = (0, preferences_js_1.projectPreferencesV2)(sortedEvents, parentByNodeId);
|
|
50
73
|
const effectivePrefs = prefs.isOk() ? prefs.value.byNodeId[String(currentNodeId)]?.effective : undefined;
|
|
51
74
|
const rawAutonomy = effectivePrefs?.autonomy ?? 'guided';
|
|
52
75
|
const rawRiskPolicy = effectivePrefs?.riskPolicy ?? 'conservative';
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ResultAsync as RA } from 'neverthrow';
|
|
2
|
+
import type { SessionIndex } from '../../../v2/durable-core/session-index.js';
|
|
2
3
|
import type { ExecutionSnapshotFileV1 } from '../../../v2/durable-core/schemas/execution-snapshot/index.js';
|
|
3
4
|
import type { SessionEventLogStoreError } from '../../../v2/ports/session-event-log-store.port.js';
|
|
4
5
|
import type { SnapshotStoreError } from '../../../v2/ports/snapshot-store.port.js';
|
|
@@ -15,4 +16,5 @@ export declare function buildBlockedOutcome(args: {
|
|
|
15
16
|
readonly v: ValidatedAdvanceInputs;
|
|
16
17
|
readonly lock: WithHealthySessionLock;
|
|
17
18
|
readonly ports: AdvanceCorePorts;
|
|
19
|
+
readonly lockedIndex: SessionIndex;
|
|
18
20
|
}): RA<void, InternalError | SessionEventLogStoreError | SnapshotStoreError>;
|
|
@@ -102,7 +102,7 @@ function buildBlockedOutcome(args) {
|
|
|
102
102
|
return snapshotStore.putExecutionSnapshotV1(blockedSnapshotRes.value).andThen((blockedSnapshotRef) => {
|
|
103
103
|
return (0, event_builders_js_1.buildAndAppendPlan)({
|
|
104
104
|
kind: 'blocked',
|
|
105
|
-
truth, sessionId, runId, currentNodeId, attemptId, workflowHash,
|
|
105
|
+
truth, lockedIndex: args.lockedIndex, sessionId, runId, currentNodeId, attemptId, workflowHash,
|
|
106
106
|
extraEventsToAppend, blockers: blockersRes.value, snapshotRef: blockedSnapshotRef,
|
|
107
107
|
outputsToAppend,
|
|
108
108
|
sessionStore, idFactory, lock,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ResultAsync as RA } from 'neverthrow';
|
|
2
|
+
import type { SessionIndex } from '../../../v2/durable-core/session-index.js';
|
|
2
3
|
import type { SessionEventLogStoreError } from '../../../v2/ports/session-event-log-store.port.js';
|
|
3
4
|
import type { SnapshotStoreError } from '../../../v2/ports/snapshot-store.port.js';
|
|
4
5
|
import type { WithHealthySessionLock } from '../../../v2/durable-core/ids/with-healthy-session-lock.js';
|
|
@@ -12,4 +13,5 @@ export declare function buildSuccessOutcome(args: {
|
|
|
12
13
|
readonly v: ValidatedAdvanceInputs;
|
|
13
14
|
readonly lock: WithHealthySessionLock;
|
|
14
15
|
readonly ports: AdvanceCorePorts;
|
|
16
|
+
readonly lockedIndex: SessionIndex;
|
|
15
17
|
}): RA<void, InternalError | SessionEventLogStoreError | SnapshotStoreError>;
|
|
@@ -149,7 +149,7 @@ function buildSuccessOutcome(args) {
|
|
|
149
149
|
const outputsToAppend = [...notesOutputs, ...artifactOutputsRes.value];
|
|
150
150
|
return (0, event_builders_js_1.buildAndAppendPlan)({
|
|
151
151
|
kind: 'advanced',
|
|
152
|
-
truth, sessionId, runId, currentNodeId, attemptId, workflowHash,
|
|
152
|
+
truth, lockedIndex: args.lockedIndex, sessionId, runId, currentNodeId, attemptId, workflowHash,
|
|
153
153
|
extraEventsToAppend, toNodeKind: successNodeKind(mode),
|
|
154
154
|
snapshotRef: newSnapshotRef, outputsToAppend,
|
|
155
155
|
sessionStore, idFactory, lock,
|
|
@@ -2,7 +2,7 @@ import type { z } from 'zod';
|
|
|
2
2
|
import type { ResultAsync as RA } from 'neverthrow';
|
|
3
3
|
import type { ToolContext, ToolResult, V2ToolContext } from '../types.js';
|
|
4
4
|
import type { V2CheckpointWorkflowInput } from '../v2/tools.js';
|
|
5
|
-
import { V2CheckpointWorkflowOutputSchema } from '../output-schemas.js';
|
|
5
|
+
import type { V2CheckpointWorkflowOutputSchema } from '../output-schemas.js';
|
|
6
6
|
import { type ToolFailure } from './v2-execution-helpers.js';
|
|
7
7
|
import type { ExecutionSessionGateErrorV2 } from '../../v2/usecases/execution-session-gate.js';
|
|
8
8
|
import type { SessionEventLogStoreError } from '../../v2/ports/session-event-log-store.port.js';
|
|
@@ -4,7 +4,6 @@ exports.handleV2CheckpointWorkflow = handleV2CheckpointWorkflow;
|
|
|
4
4
|
exports.executeCheckpoint = executeCheckpoint;
|
|
5
5
|
const neverthrow_1 = require("neverthrow");
|
|
6
6
|
const types_js_1 = require("../types.js");
|
|
7
|
-
const output_schemas_js_1 = require("../output-schemas.js");
|
|
8
7
|
const v2_token_ops_js_1 = require("./v2-token-ops.js");
|
|
9
8
|
const v2_execution_helpers_js_1 = require("./v2-execution-helpers.js");
|
|
10
9
|
const index_js_1 = require("../../v2/durable-core/ids/index.js");
|
|
@@ -107,11 +106,11 @@ function replayCheckpoint(events, dedupeKey, originalNode, sessionId, runId, nod
|
|
|
107
106
|
.andThen((resumeTokenValue) => (0, v2_token_ops_js_1.mintContinueAndCheckpointTokens)({
|
|
108
107
|
entry: { sessionId: String(sessionId), runId: String(runId), nodeId: String(nodeId), attemptId: String(attemptId), workflowHashRef },
|
|
109
108
|
ports: tokenCodecPorts, aliasStore, entropy,
|
|
110
|
-
}).andThen(({ continueToken }) => (0, neverthrow_1.okAsync)(
|
|
109
|
+
}).andThen(({ continueToken }) => (0, neverthrow_1.okAsync)({
|
|
111
110
|
checkpointNodeId,
|
|
112
111
|
resumeToken: resumeTokenValue,
|
|
113
112
|
nextCall: { tool: 'continue_workflow', params: { continueToken } },
|
|
114
|
-
})))
|
|
113
|
+
})))
|
|
115
114
|
.mapErr((e) => ({ kind: 'store_failed', cause: e }));
|
|
116
115
|
}
|
|
117
116
|
function writeCheckpoint(truth, dedupeKey, originalNode, sessionId, runId, nodeId, attemptId, checkpointNodeId, mintEventId, lock, sessionStore, tokenCodecPorts, aliasStore, entropy) {
|
|
@@ -161,7 +160,7 @@ function writeCheckpoint(truth, dedupeKey, originalNode, sessionId, runId, nodeI
|
|
|
161
160
|
eventIndex: truth.events.length,
|
|
162
161
|
createdByEventId: nodeCreatedEventId,
|
|
163
162
|
}];
|
|
164
|
-
return sessionStore.append(lock, { events: validated, snapshotPins })
|
|
163
|
+
return sessionStore.append(lock, { events: validated, snapshotPins }, truth)
|
|
165
164
|
.mapErr((cause) => ({ kind: 'store_failed', cause }))
|
|
166
165
|
.andThen(() => {
|
|
167
166
|
const workflowHashRefRes = (0, workflow_hash_ref_js_1.deriveWorkflowHashRef)(originalNode.data.workflowHash);
|
|
@@ -170,11 +169,11 @@ function writeCheckpoint(truth, dedupeKey, originalNode, sessionId, runId, nodeI
|
|
|
170
169
|
.andThen((resumeTokenValue) => (0, v2_token_ops_js_1.mintContinueAndCheckpointTokens)({
|
|
171
170
|
entry: { sessionId: String(sessionId), runId: String(runId), nodeId: String(nodeId), attemptId: String(attemptId), workflowHashRef },
|
|
172
171
|
ports: tokenCodecPorts, aliasStore, entropy,
|
|
173
|
-
}).andThen(({ continueToken }) => (0, neverthrow_1.okAsync)(
|
|
172
|
+
}).andThen(({ continueToken }) => (0, neverthrow_1.okAsync)({
|
|
174
173
|
checkpointNodeId: String(checkpointNodeId),
|
|
175
174
|
resumeToken: resumeTokenValue,
|
|
176
175
|
nextCall: { tool: 'continue_workflow', params: { continueToken } },
|
|
177
|
-
})))
|
|
176
|
+
})))
|
|
178
177
|
.mapErr((e) => ({ kind: 'store_failed', cause: e }));
|
|
179
178
|
});
|
|
180
179
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { V2ContinueWorkflowInput } from '../../v2/tools.js';
|
|
2
|
-
import {
|
|
2
|
+
import type { SessionIndex } from '../../../v2/durable-core/session-index.js';
|
|
3
|
+
import type { Workflow } from '../../../types/workflow.js';
|
|
3
4
|
import { type AttemptId } from '../../../v2/durable-core/tokens/index.js';
|
|
4
5
|
import { type SessionId, type RunId, type NodeId, type WorkflowHash } from '../../../v2/durable-core/ids/index.js';
|
|
5
6
|
import type { LoadedSessionTruthV2 } from '../../../v2/ports/session-event-log-store.port.js';
|
|
@@ -21,7 +22,7 @@ export declare function advanceAndRecord(args: {
|
|
|
21
22
|
readonly inputContext: JsonValue | undefined;
|
|
22
23
|
readonly inputOutput: V2ContinueWorkflowInput['output'];
|
|
23
24
|
readonly lock: WithHealthySessionLock;
|
|
24
|
-
readonly pinnedWorkflow:
|
|
25
|
+
readonly pinnedWorkflow: Workflow;
|
|
25
26
|
readonly snapshotStore: import('../../../v2/ports/snapshot-store.port.js').SnapshotStorePortV2;
|
|
26
27
|
readonly sessionStore: import('../../../v2/ports/session-event-log-store.port.js').SessionEventLogAppendStorePortV2 & import('../../../v2/ports/session-event-log-store.port.js').SessionEventLogReadonlyStorePortV2;
|
|
27
28
|
readonly sha256: Sha256PortV2;
|
|
@@ -29,4 +30,5 @@ export declare function advanceAndRecord(args: {
|
|
|
29
30
|
readonly mintNodeId: () => NodeId;
|
|
30
31
|
readonly mintEventId: () => string;
|
|
31
32
|
};
|
|
33
|
+
readonly lockedIndex: SessionIndex;
|
|
32
34
|
}): RA<void, InternalError | SessionEventLogStoreError | SnapshotStoreError>;
|
|
@@ -3,18 +3,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.advanceAndRecord = advanceAndRecord;
|
|
4
4
|
const neverthrow_1 = require("neverthrow");
|
|
5
5
|
const v2_advance_core_js_1 = require("../v2-advance-core.js");
|
|
6
|
-
const constants_js_1 = require("../../../v2/durable-core/constants.js");
|
|
7
6
|
function advanceAndRecord(args) {
|
|
8
7
|
const { truth, sessionId, runId, nodeId, attemptId, workflowHash, dedupeKey, inputContext, inputOutput, lock, pinnedWorkflow, snapshotStore, sessionStore, sha256, idFactory } = args;
|
|
9
|
-
const hasRun =
|
|
10
|
-
const
|
|
8
|
+
const hasRun = args.lockedIndex.runStartedByRunId.has(String(runId));
|
|
9
|
+
const nodeCreated = args.lockedIndex.nodeCreatedByNodeId.get(String(nodeId));
|
|
10
|
+
const hasNode = nodeCreated !== undefined;
|
|
11
11
|
if (!hasRun || !hasNode) {
|
|
12
12
|
return (0, neverthrow_1.errAsync)({ kind: 'missing_node_or_run' });
|
|
13
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
14
|
if (String(nodeCreated.data.workflowHash) !== String(workflowHash)) {
|
|
19
15
|
return (0, neverthrow_1.errAsync)({ kind: 'workflow_hash_mismatch' });
|
|
20
16
|
}
|
|
@@ -38,6 +34,7 @@ function advanceAndRecord(args) {
|
|
|
38
34
|
truth, sessionId, runId, attemptId, workflowHash, dedupeKey,
|
|
39
35
|
inputContext, inputOutput, lock, pinnedWorkflow,
|
|
40
36
|
ports: { snapshotStore, sessionStore, sha256, idFactory },
|
|
37
|
+
lockedIndex: args.lockedIndex,
|
|
41
38
|
});
|
|
42
39
|
}
|
|
43
40
|
return (0, v2_advance_core_js_1.executeAdvanceCore)({
|
|
@@ -45,6 +42,7 @@ function advanceAndRecord(args) {
|
|
|
45
42
|
truth, sessionId, runId, attemptId, workflowHash, dedupeKey,
|
|
46
43
|
inputContext, inputOutput, lock, pinnedWorkflow,
|
|
47
44
|
ports: { snapshotStore, sessionStore, sha256, idFactory },
|
|
45
|
+
lockedIndex: args.lockedIndex,
|
|
48
46
|
});
|
|
49
47
|
});
|
|
50
48
|
}
|