@exaudeus/workrail 3.3.0 → 3.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/application/services/compiler/binding-registry.d.ts +3 -0
- package/dist/application/services/compiler/binding-registry.js +71 -0
- package/dist/application/services/compiler/resolve-bindings.d.ts +18 -0
- package/dist/application/services/compiler/resolve-bindings.js +162 -0
- package/dist/application/services/compiler/sentinel-scan.d.ts +9 -0
- package/dist/application/services/compiler/sentinel-scan.js +37 -0
- package/dist/application/services/validation-engine.js +104 -0
- package/dist/application/services/workflow-compiler.d.ts +10 -2
- package/dist/application/services/workflow-compiler.js +25 -6
- package/dist/application/services/workflow-validation-pipeline.js +8 -1
- package/dist/cli.js +2 -2
- package/dist/engine/engine-factory.js +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +4 -2
- package/dist/manifest.json +149 -101
- package/dist/mcp/handler-factory.d.ts +1 -1
- package/dist/mcp/handler-factory.js +2 -2
- package/dist/mcp/handlers/v2-checkpoint.js +5 -5
- package/dist/mcp/handlers/v2-error-mapping.js +4 -4
- package/dist/mcp/handlers/v2-execution/continue-advance.js +2 -2
- package/dist/mcp/handlers/v2-execution/continue-rehydrate.d.ts +1 -0
- package/dist/mcp/handlers/v2-execution/continue-rehydrate.js +76 -60
- package/dist/mcp/handlers/v2-execution/index.js +86 -44
- package/dist/mcp/handlers/v2-execution-helpers.js +1 -1
- package/dist/mcp/handlers/v2-resume.js +10 -5
- package/dist/mcp/handlers/v2-token-ops.d.ts +1 -1
- package/dist/mcp/handlers/v2-token-ops.js +5 -5
- package/dist/mcp/handlers/v2-workspace-resolution.d.ts +1 -0
- package/dist/mcp/handlers/v2-workspace-resolution.js +12 -0
- package/dist/mcp/index.d.ts +4 -1
- package/dist/mcp/index.js +6 -2
- package/dist/mcp/output-schemas.d.ts +148 -8
- package/dist/mcp/output-schemas.js +22 -4
- package/dist/mcp/server.d.ts +6 -4
- package/dist/mcp/server.js +2 -57
- package/dist/mcp/tool-descriptions.js +9 -158
- package/dist/mcp/transports/http-entry.js +6 -25
- package/dist/mcp/transports/shutdown-hooks.d.ts +5 -0
- package/dist/mcp/transports/shutdown-hooks.js +38 -0
- package/dist/mcp/transports/stdio-entry.js +6 -28
- package/dist/mcp/v2/tool-registry.js +2 -1
- package/dist/mcp/v2/tools.d.ts +28 -11
- package/dist/mcp/v2/tools.js +28 -4
- package/dist/mcp/v2-response-formatter.js +28 -1
- package/dist/mcp/validation/suggestion-generator.d.ts +1 -1
- package/dist/mcp/validation/suggestion-generator.js +13 -3
- package/dist/mcp/workflow-protocol-contracts.d.ts +31 -0
- package/dist/mcp/workflow-protocol-contracts.js +207 -0
- package/dist/mcp-server.d.ts +3 -1
- package/dist/mcp-server.js +6 -2
- package/dist/types/workflow-definition.d.ts +7 -0
- package/dist/types/workflow-definition.js +1 -0
- package/dist/v2/durable-core/domain/binding-drift.d.ts +8 -0
- package/dist/v2/durable-core/domain/binding-drift.js +29 -0
- package/dist/v2/durable-core/domain/reason-model.js +2 -2
- package/dist/v2/durable-core/schemas/compiled-workflow/index.d.ts +12 -0
- package/dist/v2/durable-core/schemas/compiled-workflow/index.js +2 -0
- package/dist/v2/durable-core/schemas/export-bundle/index.d.ts +56 -56
- package/dist/v2/durable-core/schemas/session/events.d.ts +16 -16
- package/dist/v2/durable-core/schemas/session/gaps.d.ts +6 -6
- package/dist/v2/projections/resume-ranking.d.ts +1 -0
- package/dist/v2/projections/resume-ranking.js +1 -0
- package/dist/v2/read-only/v1-to-v2-shim.js +27 -10
- package/dist/v2/usecases/resume-session.d.ts +5 -1
- package/dist/v2/usecases/resume-session.js +4 -1
- package/package.json +1 -1
- package/spec/authoring-spec.json +1373 -0
- package/spec/workflow.schema.json +132 -2
- package/workflows/coding-task-workflow-agentic.json +15 -15
- package/workflows/coding-task-workflow-agentic.lean.v2.json +10 -10
- package/workflows/coding-task-workflow-agentic.v2.json +12 -12
- package/workflows/coding-task-workflow-with-loops.json +2 -2
- package/workflows/cross-platform-code-conversion.v2.json +199 -0
- package/workflows/document-creation-workflow.json +1 -1
- package/workflows/exploration-workflow.json +3 -3
- package/workflows/mr-review-workflow.agentic.v2.json +11 -11
- package/workflows/routines/parallel-work-partitioning.json +43 -0
- package/workflows/workflow-for-workflows.v2.json +186 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.wireShutdownHooks = wireShutdownHooks;
|
|
4
|
+
exports.wireStdinShutdown = wireStdinShutdown;
|
|
5
|
+
const container_js_1 = require("../../di/container.js");
|
|
6
|
+
const tokens_js_1 = require("../../di/tokens.js");
|
|
7
|
+
function wireShutdownHooks(opts) {
|
|
8
|
+
const shutdownEvents = container_js_1.container.resolve(tokens_js_1.DI.Runtime.ShutdownEvents);
|
|
9
|
+
const processSignals = container_js_1.container.resolve(tokens_js_1.DI.Runtime.ProcessSignals);
|
|
10
|
+
const terminator = container_js_1.container.resolve(tokens_js_1.DI.Runtime.ProcessTerminator);
|
|
11
|
+
processSignals.on('SIGINT', () => shutdownEvents.emit({ kind: 'shutdown_requested', signal: 'SIGINT' }));
|
|
12
|
+
processSignals.on('SIGTERM', () => shutdownEvents.emit({ kind: 'shutdown_requested', signal: 'SIGTERM' }));
|
|
13
|
+
processSignals.on('SIGHUP', () => shutdownEvents.emit({ kind: 'shutdown_requested', signal: 'SIGHUP' }));
|
|
14
|
+
let shutdownStarted = false;
|
|
15
|
+
shutdownEvents.onShutdown((event) => {
|
|
16
|
+
if (shutdownStarted)
|
|
17
|
+
return;
|
|
18
|
+
shutdownStarted = true;
|
|
19
|
+
void (async () => {
|
|
20
|
+
try {
|
|
21
|
+
console.error(`[Shutdown] Requested by ${event.signal}. Stopping services...`);
|
|
22
|
+
await opts.onBeforeTerminate();
|
|
23
|
+
terminator.terminate({ kind: 'success' });
|
|
24
|
+
}
|
|
25
|
+
catch (err) {
|
|
26
|
+
console.error('[Shutdown] Error while stopping services:', err);
|
|
27
|
+
terminator.terminate({ kind: 'failure' });
|
|
28
|
+
}
|
|
29
|
+
})();
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
function wireStdinShutdown() {
|
|
33
|
+
const shutdownEvents = container_js_1.container.resolve(tokens_js_1.DI.Runtime.ShutdownEvents);
|
|
34
|
+
process.stdin.on('end', () => {
|
|
35
|
+
console.error('[MCP] stdin closed, initiating shutdown');
|
|
36
|
+
shutdownEvents.emit({ kind: 'shutdown_requested', signal: 'SIGHUP' });
|
|
37
|
+
});
|
|
38
|
+
}
|
|
@@ -35,8 +35,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.startStdioServer = startStdioServer;
|
|
37
37
|
const server_js_1 = require("../server.js");
|
|
38
|
-
const
|
|
39
|
-
const tokens_js_1 = require("../../di/tokens.js");
|
|
38
|
+
const shutdown_hooks_js_1 = require("./shutdown-hooks.js");
|
|
40
39
|
async function startStdioServer() {
|
|
41
40
|
const { server, ctx, rootsManager } = await (0, server_js_1.composeServer)();
|
|
42
41
|
const { StdioServerTransport } = await Promise.resolve().then(() => __importStar(require('@modelcontextprotocol/sdk/server/stdio.js')));
|
|
@@ -62,31 +61,10 @@ async function startStdioServer() {
|
|
|
62
61
|
console.error('[Roots] Client does not support roots/list; workspace context will use server CWD fallback');
|
|
63
62
|
}
|
|
64
63
|
console.error('[Transport] WorkRail MCP Server running on stdio');
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
processSignals.on('SIGTERM', () => shutdownEvents.emit({ kind: 'shutdown_requested', signal: 'SIGTERM' }));
|
|
70
|
-
processSignals.on('SIGHUP', () => shutdownEvents.emit({ kind: 'shutdown_requested', signal: 'SIGHUP' }));
|
|
71
|
-
process.stdin.on('end', () => {
|
|
72
|
-
console.error('[MCP] stdin closed, initiating shutdown');
|
|
73
|
-
shutdownEvents.emit({ kind: 'shutdown_requested', signal: 'SIGHUP' });
|
|
74
|
-
});
|
|
75
|
-
let shutdownStarted = false;
|
|
76
|
-
shutdownEvents.onShutdown((event) => {
|
|
77
|
-
if (shutdownStarted)
|
|
78
|
-
return;
|
|
79
|
-
shutdownStarted = true;
|
|
80
|
-
void (async () => {
|
|
81
|
-
try {
|
|
82
|
-
console.error(`[Shutdown] Requested by ${event.signal}. Stopping services...`);
|
|
83
|
-
await ctx.httpServer?.stop();
|
|
84
|
-
terminator.terminate({ kind: 'success' });
|
|
85
|
-
}
|
|
86
|
-
catch (err) {
|
|
87
|
-
console.error('[Shutdown] Error while stopping services:', err);
|
|
88
|
-
terminator.terminate({ kind: 'failure' });
|
|
89
|
-
}
|
|
90
|
-
})();
|
|
64
|
+
(0, shutdown_hooks_js_1.wireShutdownHooks)({
|
|
65
|
+
onBeforeTerminate: async () => {
|
|
66
|
+
await ctx.httpServer?.stop();
|
|
67
|
+
},
|
|
91
68
|
});
|
|
69
|
+
(0, shutdown_hooks_js_1.wireStdinShutdown)();
|
|
92
70
|
}
|
|
@@ -7,6 +7,7 @@ const v2_execution_js_1 = require("../handlers/v2-execution.js");
|
|
|
7
7
|
const v2_workflow_js_1 = require("../handlers/v2-workflow.js");
|
|
8
8
|
const v2_checkpoint_js_1 = require("../handlers/v2-checkpoint.js");
|
|
9
9
|
const v2_resume_js_1 = require("../handlers/v2-resume.js");
|
|
10
|
+
const workflow_protocol_contracts_js_1 = require("../workflow-protocol-contracts.js");
|
|
10
11
|
function buildV2ToolRegistry(buildTool) {
|
|
11
12
|
const tools = [
|
|
12
13
|
buildTool({
|
|
@@ -50,7 +51,7 @@ function buildV2ToolRegistry(buildTool) {
|
|
|
50
51
|
list_workflows: (0, handler_factory_js_1.createHandler)(tools_js_1.V2ListWorkflowsInput, v2_workflow_js_1.handleV2ListWorkflows),
|
|
51
52
|
inspect_workflow: (0, handler_factory_js_1.createHandler)(tools_js_1.V2InspectWorkflowInput, v2_workflow_js_1.handleV2InspectWorkflow),
|
|
52
53
|
start_workflow: (0, handler_factory_js_1.createHandler)(tools_js_1.V2StartWorkflowInput, v2_execution_js_1.handleV2StartWorkflow),
|
|
53
|
-
continue_workflow: (0, handler_factory_js_1.createHandler)(tools_js_1.V2ContinueWorkflowInput, v2_execution_js_1.handleV2ContinueWorkflow, tools_js_1.V2ContinueWorkflowInputShape),
|
|
54
|
+
continue_workflow: (0, handler_factory_js_1.createHandler)(tools_js_1.V2ContinueWorkflowInput, v2_execution_js_1.handleV2ContinueWorkflow, tools_js_1.V2ContinueWorkflowInputShape, workflow_protocol_contracts_js_1.CONTINUE_WORKFLOW_PROTOCOL.aliasMap),
|
|
54
55
|
checkpoint_workflow: (0, handler_factory_js_1.createHandler)(tools_js_1.V2CheckpointWorkflowInput, v2_checkpoint_js_1.handleV2CheckpointWorkflow),
|
|
55
56
|
resume_session: (0, handler_factory_js_1.createHandler)(tools_js_1.V2ResumeSessionInput, v2_resume_js_1.handleV2ResumeSession),
|
|
56
57
|
};
|
package/dist/mcp/v2/tools.d.ts
CHANGED
|
@@ -18,8 +18,8 @@ export declare const V2InspectWorkflowInput: z.ZodObject<{
|
|
|
18
18
|
workspacePath?: string | undefined;
|
|
19
19
|
}, {
|
|
20
20
|
workflowId: string;
|
|
21
|
-
mode?: "metadata" | "preview" | undefined;
|
|
22
21
|
workspacePath?: string | undefined;
|
|
22
|
+
mode?: "metadata" | "preview" | undefined;
|
|
23
23
|
}>;
|
|
24
24
|
export type V2InspectWorkflowInput = z.infer<typeof V2InspectWorkflowInput>;
|
|
25
25
|
export declare const V2StartWorkflowInput: z.ZodObject<{
|
|
@@ -34,6 +34,7 @@ export declare const V2StartWorkflowInput: z.ZodObject<{
|
|
|
34
34
|
}>;
|
|
35
35
|
export type V2StartWorkflowInput = z.infer<typeof V2StartWorkflowInput>;
|
|
36
36
|
export declare const V2ContinueWorkflowInputShape: z.ZodObject<{
|
|
37
|
+
workspacePath: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
|
|
37
38
|
continueToken: z.ZodString;
|
|
38
39
|
intent: z.ZodOptional<z.ZodEnum<["advance", "rehydrate"]>>;
|
|
39
40
|
context: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
@@ -50,21 +51,24 @@ export declare const V2ContinueWorkflowInputShape: z.ZodObject<{
|
|
|
50
51
|
}, "strict", z.ZodTypeAny, {
|
|
51
52
|
continueToken: string;
|
|
52
53
|
context?: Record<string, unknown> | undefined;
|
|
54
|
+
workspacePath?: string | undefined;
|
|
55
|
+
intent?: "advance" | "rehydrate" | undefined;
|
|
53
56
|
output?: {
|
|
54
57
|
notesMarkdown?: string | undefined;
|
|
55
58
|
artifacts?: unknown[] | undefined;
|
|
56
59
|
} | undefined;
|
|
57
|
-
intent?: "advance" | "rehydrate" | undefined;
|
|
58
60
|
}, {
|
|
59
61
|
continueToken: string;
|
|
60
62
|
context?: Record<string, unknown> | undefined;
|
|
63
|
+
workspacePath?: string | undefined;
|
|
64
|
+
intent?: "advance" | "rehydrate" | undefined;
|
|
61
65
|
output?: {
|
|
62
66
|
notesMarkdown?: string | undefined;
|
|
63
67
|
artifacts?: unknown[] | undefined;
|
|
64
68
|
} | undefined;
|
|
65
|
-
intent?: "advance" | "rehydrate" | undefined;
|
|
66
69
|
}>;
|
|
67
70
|
export declare const V2ContinueWorkflowInput: z.ZodEffects<z.ZodEffects<z.ZodObject<{
|
|
71
|
+
workspacePath: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
|
|
68
72
|
continueToken: z.ZodString;
|
|
69
73
|
intent: z.ZodOptional<z.ZodEnum<["advance", "rehydrate"]>>;
|
|
70
74
|
context: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
@@ -78,54 +82,67 @@ export declare const V2ContinueWorkflowInput: z.ZodEffects<z.ZodEffects<z.ZodObj
|
|
|
78
82
|
notesMarkdown?: string | undefined;
|
|
79
83
|
artifacts?: unknown[] | undefined;
|
|
80
84
|
}>>;
|
|
85
|
+
} & {
|
|
86
|
+
contextVariables: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
81
87
|
}, "strict", z.ZodTypeAny, {
|
|
82
88
|
continueToken: string;
|
|
83
89
|
context?: Record<string, unknown> | undefined;
|
|
90
|
+
workspacePath?: string | undefined;
|
|
91
|
+
intent?: "advance" | "rehydrate" | undefined;
|
|
84
92
|
output?: {
|
|
85
93
|
notesMarkdown?: string | undefined;
|
|
86
94
|
artifacts?: unknown[] | undefined;
|
|
87
95
|
} | undefined;
|
|
88
|
-
|
|
96
|
+
contextVariables?: Record<string, unknown> | undefined;
|
|
89
97
|
}, {
|
|
90
98
|
continueToken: string;
|
|
91
99
|
context?: Record<string, unknown> | undefined;
|
|
100
|
+
workspacePath?: string | undefined;
|
|
101
|
+
intent?: "advance" | "rehydrate" | undefined;
|
|
92
102
|
output?: {
|
|
93
103
|
notesMarkdown?: string | undefined;
|
|
94
104
|
artifacts?: unknown[] | undefined;
|
|
95
105
|
} | undefined;
|
|
96
|
-
|
|
106
|
+
contextVariables?: Record<string, unknown> | undefined;
|
|
97
107
|
}>, {
|
|
98
108
|
continueToken: string;
|
|
99
109
|
context?: Record<string, unknown> | undefined;
|
|
110
|
+
workspacePath?: string | undefined;
|
|
111
|
+
intent?: "advance" | "rehydrate" | undefined;
|
|
100
112
|
output?: {
|
|
101
113
|
notesMarkdown?: string | undefined;
|
|
102
114
|
artifacts?: unknown[] | undefined;
|
|
103
115
|
} | undefined;
|
|
104
|
-
|
|
116
|
+
contextVariables?: Record<string, unknown> | undefined;
|
|
105
117
|
}, {
|
|
106
118
|
continueToken: string;
|
|
107
119
|
context?: Record<string, unknown> | undefined;
|
|
120
|
+
workspacePath?: string | undefined;
|
|
121
|
+
intent?: "advance" | "rehydrate" | undefined;
|
|
108
122
|
output?: {
|
|
109
123
|
notesMarkdown?: string | undefined;
|
|
110
124
|
artifacts?: unknown[] | undefined;
|
|
111
125
|
} | undefined;
|
|
112
|
-
|
|
126
|
+
contextVariables?: Record<string, unknown> | undefined;
|
|
113
127
|
}>, {
|
|
128
|
+
workspacePath?: string | undefined;
|
|
114
129
|
output?: {
|
|
115
130
|
notesMarkdown?: string | undefined;
|
|
116
131
|
artifacts?: unknown[] | undefined;
|
|
117
132
|
} | undefined;
|
|
118
|
-
context?:
|
|
133
|
+
context?: {} | undefined;
|
|
119
134
|
intent: "advance" | "rehydrate";
|
|
120
135
|
continueToken: string;
|
|
121
136
|
}, {
|
|
122
137
|
continueToken: string;
|
|
123
138
|
context?: Record<string, unknown> | undefined;
|
|
139
|
+
workspacePath?: string | undefined;
|
|
140
|
+
intent?: "advance" | "rehydrate" | undefined;
|
|
124
141
|
output?: {
|
|
125
142
|
notesMarkdown?: string | undefined;
|
|
126
143
|
artifacts?: unknown[] | undefined;
|
|
127
144
|
} | undefined;
|
|
128
|
-
|
|
145
|
+
contextVariables?: Record<string, unknown> | undefined;
|
|
129
146
|
}>;
|
|
130
147
|
export type V2ContinueWorkflowInput = z.infer<typeof V2ContinueWorkflowInput>;
|
|
131
148
|
export declare const V2ResumeSessionInput: z.ZodObject<{
|
|
@@ -134,13 +151,13 @@ export declare const V2ResumeSessionInput: z.ZodObject<{
|
|
|
134
151
|
gitHeadSha: z.ZodOptional<z.ZodString>;
|
|
135
152
|
workspacePath: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
|
|
136
153
|
}, "strict", z.ZodTypeAny, {
|
|
137
|
-
query?: string | undefined;
|
|
138
154
|
workspacePath?: string | undefined;
|
|
155
|
+
query?: string | undefined;
|
|
139
156
|
gitBranch?: string | undefined;
|
|
140
157
|
gitHeadSha?: string | undefined;
|
|
141
158
|
}, {
|
|
142
|
-
query?: string | undefined;
|
|
143
159
|
workspacePath?: string | undefined;
|
|
160
|
+
query?: string | undefined;
|
|
144
161
|
gitBranch?: string | undefined;
|
|
145
162
|
gitHeadSha?: string | undefined;
|
|
146
163
|
}>;
|
package/dist/mcp/v2/tools.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.V2_TOOL_ANNOTATIONS = exports.V2_TOOL_TITLES = exports.V2CheckpointWorkflowInput = exports.V2ResumeSessionInput = exports.V2ContinueWorkflowInput = exports.V2ContinueWorkflowInputShape = exports.V2StartWorkflowInput = exports.V2InspectWorkflowInput = exports.V2ListWorkflowsInput = void 0;
|
|
4
4
|
const zod_1 = require("zod");
|
|
5
|
+
const workflow_protocol_contracts_js_1 = require("../workflow-protocol-contracts.js");
|
|
5
6
|
const workspacePathField = zod_1.z.string()
|
|
6
7
|
.refine((p) => p.startsWith('/'), 'workspacePath must be an absolute path (starting with /)')
|
|
7
8
|
.optional()
|
|
@@ -19,8 +20,11 @@ exports.V2StartWorkflowInput = zod_1.z.object({
|
|
|
19
20
|
workspacePath: workspacePathField.describe('Absolute path to your current workspace directory (e.g. the "Workspace:" value from your system parameters). Used to resolve the correct project-scoped workflow variant and to anchor this session to your workspace for future resume_session discovery. Pass this on every start_workflow call. If omitted, WorkRail uses MCP roots when available, then falls back to the server process directory.'),
|
|
20
21
|
});
|
|
21
22
|
exports.V2ContinueWorkflowInputShape = zod_1.z.object({
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
workspacePath: workspacePathField,
|
|
24
|
+
continueToken: zod_1.z.string().min(1).describe('The token for your next continue_workflow call. Two valid token kinds: ' +
|
|
25
|
+
'(1) A continueToken (ct_...) from start_workflow or a previous continue_workflow — carries session identity AND advance authority. ' +
|
|
26
|
+
'(2) A resumeToken (st_...) from resume_session or checkpoint_workflow — carries session identity only; valid for intent: "rehydrate", not "advance". ' +
|
|
27
|
+
'Round-trip exactly as received — never decode, inspect, or modify it.'),
|
|
24
28
|
intent: zod_1.z.enum(['advance', 'rehydrate']).optional().describe('What you want to do. Auto-inferred if omitted: ' +
|
|
25
29
|
'output present → "advance", output absent → "rehydrate". ' +
|
|
26
30
|
'"advance": I completed the current step. ' +
|
|
@@ -40,8 +44,23 @@ exports.V2ContinueWorkflowInputShape = zod_1.z.object({
|
|
|
40
44
|
.optional()
|
|
41
45
|
.describe('Durable output to attach to the current node. Only valid when intent is "advance".'),
|
|
42
46
|
}).strict();
|
|
47
|
+
const continueWorkflowContextAliasField = zod_1.z.record(zod_1.z.unknown()).optional().describe('Compatibility alias for context. Canonical field name: "context".');
|
|
43
48
|
exports.V2ContinueWorkflowInput = exports.V2ContinueWorkflowInputShape
|
|
49
|
+
.extend({
|
|
50
|
+
contextVariables: continueWorkflowContextAliasField,
|
|
51
|
+
})
|
|
44
52
|
.superRefine((data, ctx) => {
|
|
53
|
+
const aliasMap = workflow_protocol_contracts_js_1.CONTINUE_WORKFLOW_PROTOCOL.aliasMap;
|
|
54
|
+
const conflicts = aliasMap
|
|
55
|
+
? (0, workflow_protocol_contracts_js_1.findAliasFieldConflicts)(data, aliasMap)
|
|
56
|
+
: [];
|
|
57
|
+
for (const { alias, canonical } of conflicts) {
|
|
58
|
+
ctx.addIssue({
|
|
59
|
+
code: zod_1.z.ZodIssueCode.custom,
|
|
60
|
+
path: [alias],
|
|
61
|
+
message: `Provide either "${canonical}" or "${alias}", not both. Canonical field: "${canonical}".`,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
45
64
|
if (data.intent === 'rehydrate' && data.output) {
|
|
46
65
|
ctx.addIssue({
|
|
47
66
|
code: zod_1.z.ZodIssueCode.custom,
|
|
@@ -52,16 +71,21 @@ exports.V2ContinueWorkflowInput = exports.V2ContinueWorkflowInputShape
|
|
|
52
71
|
}
|
|
53
72
|
})
|
|
54
73
|
.transform((data) => {
|
|
74
|
+
const normalized = workflow_protocol_contracts_js_1.CONTINUE_WORKFLOW_PROTOCOL.aliasMap
|
|
75
|
+
? (0, workflow_protocol_contracts_js_1.normalizeAliasedFields)(data, workflow_protocol_contracts_js_1.CONTINUE_WORKFLOW_PROTOCOL.aliasMap)
|
|
76
|
+
: data;
|
|
55
77
|
const intent = data.intent ?? (data.output ? 'advance' : 'rehydrate');
|
|
56
78
|
return {
|
|
57
79
|
intent,
|
|
58
80
|
continueToken: data.continueToken,
|
|
59
|
-
...(
|
|
81
|
+
...(normalized.context ? { context: normalized.context } : {}),
|
|
60
82
|
...(data.output ? { output: data.output } : {}),
|
|
83
|
+
...(data.workspacePath !== undefined ? { workspacePath: data.workspacePath } : {}),
|
|
61
84
|
};
|
|
62
85
|
});
|
|
63
86
|
exports.V2ResumeSessionInput = zod_1.z.object({
|
|
64
|
-
query: zod_1.z.string().max(256).optional().describe('Free text search to find a relevant session. Matches against recap notes and workflow IDs.'
|
|
87
|
+
query: zod_1.z.string().min(1).max(256).optional().describe('Free text search to find a relevant session. Matches against recap notes and workflow IDs. ' +
|
|
88
|
+
'Without query, only git-context matching runs — the semantic (notes) tier is skipped.'),
|
|
65
89
|
gitBranch: zod_1.z.string().max(256).optional().describe('Git branch name to match against session observations. Overrides auto-detected branch.'),
|
|
66
90
|
gitHeadSha: zod_1.z.string().regex(/^[0-9a-f]{40}$/).optional().describe('Git HEAD SHA to match against session observations. Overrides auto-detected HEAD.'),
|
|
67
91
|
workspacePath: zod_1.z.string()
|
|
@@ -59,13 +59,30 @@ function formatTokenBlock(data) {
|
|
|
59
59
|
lines.push('```');
|
|
60
60
|
return lines.join('\n');
|
|
61
61
|
}
|
|
62
|
-
function
|
|
62
|
+
function formatBindingDriftWarnings(data) {
|
|
63
|
+
if (!data.warnings || data.warnings.length === 0)
|
|
64
|
+
return '';
|
|
65
|
+
const lines = [
|
|
66
|
+
'',
|
|
67
|
+
'> **⚠ Binding Drift Detected**',
|
|
68
|
+
'> Your `.workrail/bindings.json` has changed since this session was started.',
|
|
69
|
+
'> The session continues with the original compiled bindings. Start a new session to pick up the changes.',
|
|
70
|
+
'>',
|
|
71
|
+
];
|
|
72
|
+
for (const w of data.warnings) {
|
|
73
|
+
lines.push(`> - \`${w.slotId}\`: was \`${w.pinnedValue}\`, now \`${w.currentValue}\``);
|
|
74
|
+
}
|
|
75
|
+
return lines.join('\n');
|
|
76
|
+
}
|
|
77
|
+
function formatComplete(data) {
|
|
78
|
+
const driftBlock = formatBindingDriftWarnings(data);
|
|
63
79
|
return [
|
|
64
80
|
PERSONA_SYSTEM,
|
|
65
81
|
'',
|
|
66
82
|
'# Workflow Complete',
|
|
67
83
|
'',
|
|
68
84
|
'The workflow has finished. No further steps to execute.',
|
|
85
|
+
...(driftBlock ? [driftBlock] : []),
|
|
69
86
|
].join('\n');
|
|
70
87
|
}
|
|
71
88
|
function formatBlocked(data) {
|
|
@@ -155,6 +172,11 @@ function formatRehydrate(data) {
|
|
|
155
172
|
lines.push('No pending step. The workflow may be complete or waiting for external input.');
|
|
156
173
|
lines.push('');
|
|
157
174
|
}
|
|
175
|
+
const driftBlock = formatBindingDriftWarnings(data);
|
|
176
|
+
if (driftBlock) {
|
|
177
|
+
lines.push(driftBlock);
|
|
178
|
+
lines.push('');
|
|
179
|
+
}
|
|
158
180
|
lines.push('Continue working on this step. When done, call `continue_workflow` to advance.');
|
|
159
181
|
return lines.join('\n');
|
|
160
182
|
}
|
|
@@ -178,6 +200,11 @@ function formatSuccess(data) {
|
|
|
178
200
|
lines.push('Include `output.notesMarkdown` documenting your work — what you did, key decisions, what you produced, and anything notable.');
|
|
179
201
|
lines.push('');
|
|
180
202
|
lines.push(formatPreferences(data.preferences));
|
|
203
|
+
const driftBlock = formatBindingDriftWarnings(data);
|
|
204
|
+
if (driftBlock) {
|
|
205
|
+
lines.push('');
|
|
206
|
+
lines.push(driftBlock);
|
|
207
|
+
}
|
|
181
208
|
return lines.join('\n');
|
|
182
209
|
}
|
|
183
210
|
function formatV2ExecutionResponse(data) {
|
|
@@ -2,7 +2,7 @@ import { z } from 'zod';
|
|
|
2
2
|
import type { SuggestionConfig } from './suggestion-config.js';
|
|
3
3
|
import type { SuggestionResult } from './suggestion-types.js';
|
|
4
4
|
export type { ZodIssue } from 'zod';
|
|
5
|
-
export declare function generateSuggestions(args: unknown, schema: z.ZodType, config: SuggestionConfig): SuggestionResult;
|
|
5
|
+
export declare function generateSuggestions(args: unknown, schema: z.ZodType, config: SuggestionConfig, aliasMap?: Readonly<Record<string, string>>): SuggestionResult;
|
|
6
6
|
export declare function formatSuggestionDetails(result: SuggestionResult): Record<string, unknown>;
|
|
7
7
|
export declare function hasSuggestions(result: SuggestionResult): boolean;
|
|
8
8
|
export declare function patchTemplateForFailedOptionals(correctTemplate: Readonly<Record<string, unknown>> | null, args: unknown, zodErrors: readonly z.ZodIssue[], schema: z.ZodType, maxDepth: number): Readonly<Record<string, unknown>> | null;
|
|
@@ -8,9 +8,19 @@ const zod_1 = require("zod");
|
|
|
8
8
|
const suggestion_types_js_1 = require("./suggestion-types.js");
|
|
9
9
|
const string_similarity_js_1 = require("./string-similarity.js");
|
|
10
10
|
const schema_introspection_js_1 = require("./schema-introspection.js");
|
|
11
|
-
function generateUnknownKeySuggestions(unknownKeys, expectedKeys, config) {
|
|
11
|
+
function generateUnknownKeySuggestions(unknownKeys, expectedKeys, config, aliasMap) {
|
|
12
12
|
const suggestions = [];
|
|
13
13
|
for (const unknownKey of unknownKeys) {
|
|
14
|
+
const aliasTarget = aliasMap?.[unknownKey];
|
|
15
|
+
if (aliasTarget) {
|
|
16
|
+
suggestions.push({
|
|
17
|
+
kind: 'unknown_key',
|
|
18
|
+
provided: unknownKey,
|
|
19
|
+
didYouMean: aliasTarget,
|
|
20
|
+
similarity: (0, suggestion_types_js_1.similarity)(1),
|
|
21
|
+
});
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
14
24
|
const match = (0, string_similarity_js_1.findClosestMatch)(unknownKey, expectedKeys, config.similarityThreshold);
|
|
15
25
|
if (match) {
|
|
16
26
|
suggestions.push({
|
|
@@ -43,11 +53,11 @@ function generateMissingRequiredSuggestions(missingKeys, schema, config) {
|
|
|
43
53
|
suggestions.sort((a, b) => a.param.localeCompare(b.param));
|
|
44
54
|
return suggestions.slice(0, config.maxSuggestions);
|
|
45
55
|
}
|
|
46
|
-
function generateSuggestions(args, schema, config) {
|
|
56
|
+
function generateSuggestions(args, schema, config, aliasMap) {
|
|
47
57
|
const suggestions = [];
|
|
48
58
|
const expectedKeys = (0, schema_introspection_js_1.extractExpectedKeys)(schema);
|
|
49
59
|
const unknownKeys = (0, schema_introspection_js_1.findUnknownKeys)(args, schema);
|
|
50
|
-
const unknownKeySuggestions = generateUnknownKeySuggestions(unknownKeys, expectedKeys, config);
|
|
60
|
+
const unknownKeySuggestions = generateUnknownKeySuggestions(unknownKeys, expectedKeys, config, aliasMap);
|
|
51
61
|
suggestions.push(...unknownKeySuggestions);
|
|
52
62
|
const missingKeys = (0, schema_introspection_js_1.findMissingRequiredKeys)(args, schema);
|
|
53
63
|
const missingRequiredSuggestions = generateMissingRequiredSuggestions(missingKeys, schema, config);
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { DescriptionMode } from './types/tool-description-types.js';
|
|
2
|
+
export type ProtocolAliasMap = Readonly<Record<string, string>>;
|
|
3
|
+
export interface ProtocolParams {
|
|
4
|
+
readonly required: readonly string[];
|
|
5
|
+
readonly optional?: readonly string[];
|
|
6
|
+
}
|
|
7
|
+
export interface CompactDescriptionSpec {
|
|
8
|
+
readonly purpose: string;
|
|
9
|
+
readonly whenToUse?: string;
|
|
10
|
+
readonly rules?: readonly string[];
|
|
11
|
+
readonly examplePayload?: Readonly<Record<string, unknown>>;
|
|
12
|
+
readonly returns?: string;
|
|
13
|
+
}
|
|
14
|
+
export interface WorkflowProtocolContract {
|
|
15
|
+
readonly canonicalParams: ProtocolParams;
|
|
16
|
+
readonly aliasMap?: ProtocolAliasMap;
|
|
17
|
+
readonly descriptions: Readonly<Record<DescriptionMode, CompactDescriptionSpec>>;
|
|
18
|
+
}
|
|
19
|
+
export declare const CONTINUE_WORKFLOW_CONTEXT_OBJECT_GUIDANCE = "Set these keys in the next `continue_workflow` call's `context` object:";
|
|
20
|
+
export declare const CONTINUE_WORKFLOW_SINGLE_CONTEXT_OBJECT_GUIDANCE = "Set this key in the next `continue_workflow` call's `context` object:";
|
|
21
|
+
export declare function renderCompactDescription(spec: CompactDescriptionSpec, canonicalParams: ProtocolParams): string;
|
|
22
|
+
export declare function normalizeAliasedFields(value: Readonly<Record<string, unknown>>, aliasMap: ProtocolAliasMap): Record<string, unknown>;
|
|
23
|
+
export declare function findAliasFieldConflicts(value: Readonly<Record<string, unknown>>, aliasMap: ProtocolAliasMap): readonly {
|
|
24
|
+
alias: string;
|
|
25
|
+
canonical: string;
|
|
26
|
+
}[];
|
|
27
|
+
export declare const START_WORKFLOW_PROTOCOL: WorkflowProtocolContract;
|
|
28
|
+
export declare const CONTINUE_WORKFLOW_PROTOCOL: WorkflowProtocolContract;
|
|
29
|
+
export declare const CHECKPOINT_WORKFLOW_PROTOCOL: WorkflowProtocolContract;
|
|
30
|
+
export declare const RESUME_SESSION_PROTOCOL: WorkflowProtocolContract;
|
|
31
|
+
export declare function renderProtocolDescription(contract: WorkflowProtocolContract, mode: DescriptionMode): string;
|