@exaudeus/workrail 0.11.0 → 0.12.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/config/feature-flags.js +1 -1
- package/dist/di/container.js +72 -0
- package/dist/di/tokens.d.ts +13 -0
- package/dist/di/tokens.js +13 -0
- package/dist/manifest.json +109 -93
- package/dist/mcp/error-mapper.d.ts +3 -8
- package/dist/mcp/error-mapper.js +41 -19
- package/dist/mcp/handlers/session.js +25 -11
- package/dist/mcp/handlers/v2-execution-helpers.d.ts +99 -0
- package/dist/mcp/handlers/v2-execution-helpers.js +249 -0
- package/dist/mcp/handlers/v2-execution.d.ts +4 -0
- package/dist/mcp/handlers/v2-execution.js +1061 -0
- package/dist/mcp/handlers/v2-workflow.js +7 -7
- package/dist/mcp/handlers/workflow.js +21 -12
- package/dist/mcp/index.d.ts +1 -1
- package/dist/mcp/index.js +4 -1
- package/dist/mcp/output-schemas.d.ts +411 -4
- package/dist/mcp/output-schemas.js +57 -1
- package/dist/mcp/server.d.ts +1 -1
- package/dist/mcp/server.js +57 -31
- package/dist/mcp/tool-descriptions.js +17 -0
- package/dist/mcp/tools.js +12 -0
- package/dist/mcp/types/tool-description-types.d.ts +1 -1
- package/dist/mcp/types/tool-description-types.js +2 -0
- package/dist/mcp/types.d.ts +38 -3
- package/dist/mcp/types.js +32 -3
- package/dist/mcp/v2/tool-registry.js +16 -1
- package/dist/mcp/v2/tools.d.ts +45 -0
- package/dist/mcp/v2/tools.js +21 -1
- package/dist/mcp/validation/workflow-next-prevalidate.d.ts +2 -3
- package/dist/mcp/validation/workflow-next-prevalidate.js +38 -27
- package/dist/v2/durable-core/ids/index.d.ts +2 -0
- package/dist/v2/durable-core/ids/index.js +4 -0
- package/dist/v2/durable-core/schemas/compiled-workflow/index.d.ts +100 -6
- package/dist/v2/durable-core/schemas/compiled-workflow/index.js +18 -3
- package/dist/v2/durable-core/schemas/session/events.d.ts +80 -50
- package/dist/v2/durable-core/schemas/session/events.js +27 -9
- package/dist/v2/durable-core/schemas/session/manifest.d.ts +2 -2
- package/dist/v2/durable-core/tokens/index.d.ts +2 -0
- package/dist/v2/durable-core/tokens/index.js +4 -1
- package/dist/v2/durable-core/tokens/payloads.d.ts +4 -4
- package/dist/v2/infra/local/pinned-workflow-store/index.d.ts +3 -3
- package/dist/v2/infra/local/pinned-workflow-store/index.js +1 -1
- package/dist/v2/infra/local/session-lock/index.js +1 -1
- package/dist/v2/infra/local/session-store/index.d.ts +0 -1
- package/dist/v2/infra/local/session-store/index.js +348 -280
- package/dist/v2/ports/pinned-workflow-store.port.d.ts +3 -3
- package/dist/v2/ports/session-event-log-store.port.d.ts +1 -1
- package/dist/v2/ports/session-lock.port.d.ts +1 -1
- package/dist/v2/read-only/v1-to-v2-shim.d.ts +6 -1
- package/dist/v2/read-only/v1-to-v2-shim.js +16 -4
- package/dist/v2/usecases/execution-session-gate.d.ts +3 -2
- package/dist/v2/usecases/execution-session-gate.js +98 -101
- package/package.json +2 -1
- package/workflows/coding-task-workflow-agentic.json +326 -69
- package/workflows/design-thinking-workflow-autonomous.agentic.json +1 -1
- package/workflows/design-thinking-workflow.json +1 -1
package/dist/mcp/server.js
CHANGED
|
@@ -38,6 +38,7 @@ exports.startServer = startServer;
|
|
|
38
38
|
const zod_to_json_schema_js_1 = require("./zod-to-json-schema.js");
|
|
39
39
|
const container_js_1 = require("../di/container.js");
|
|
40
40
|
const tokens_js_1 = require("../di/tokens.js");
|
|
41
|
+
const types_js_1 = require("./types.js");
|
|
41
42
|
const tool_factory_js_1 = require("./tool-factory.js");
|
|
42
43
|
const workflow_next_prevalidate_js_1 = require("./validation/workflow-next-prevalidate.js");
|
|
43
44
|
const bounded_json_js_1 = require("./validation/bounded-json.js");
|
|
@@ -56,16 +57,17 @@ function toMcpResult(result) {
|
|
|
56
57
|
content: [{
|
|
57
58
|
type: 'text',
|
|
58
59
|
text: JSON.stringify({
|
|
59
|
-
error: result.message,
|
|
60
60
|
code: result.code,
|
|
61
|
-
|
|
61
|
+
message: result.message,
|
|
62
|
+
retry: result.retry,
|
|
63
|
+
...(result.details !== undefined ? { details: result.details } : {}),
|
|
62
64
|
}, null, 2),
|
|
63
65
|
}],
|
|
64
66
|
isError: true,
|
|
65
67
|
};
|
|
66
68
|
}
|
|
67
69
|
}
|
|
68
|
-
function createToolContext() {
|
|
70
|
+
async function createToolContext() {
|
|
69
71
|
const workflowService = container_js_1.container.resolve(tokens_js_1.DI.Services.Workflow);
|
|
70
72
|
const featureFlags = container_js_1.container.resolve(tokens_js_1.DI.Infra.FeatureFlags);
|
|
71
73
|
let sessionManager = null;
|
|
@@ -78,11 +80,40 @@ function createToolContext() {
|
|
|
78
80
|
else {
|
|
79
81
|
console.error('[FeatureFlags] Session tools disabled (enable with WORKRAIL_ENABLE_SESSION_TOOLS=true)');
|
|
80
82
|
}
|
|
83
|
+
let v2 = null;
|
|
84
|
+
if (featureFlags.isEnabled('v2Tools')) {
|
|
85
|
+
const gate = container_js_1.container.resolve(tokens_js_1.DI.V2.ExecutionGate);
|
|
86
|
+
const sessionStore = container_js_1.container.resolve(tokens_js_1.DI.V2.SessionStore);
|
|
87
|
+
const snapshotStore = container_js_1.container.resolve(tokens_js_1.DI.V2.SnapshotStore);
|
|
88
|
+
const pinnedStore = container_js_1.container.resolve(tokens_js_1.DI.V2.PinnedWorkflowStore);
|
|
89
|
+
const keyringPort = container_js_1.container.resolve(tokens_js_1.DI.V2.Keyring);
|
|
90
|
+
const keyringResult = await keyringPort.loadOrCreate();
|
|
91
|
+
if (keyringResult.isErr()) {
|
|
92
|
+
console.error(`[FeatureFlags] v2 tools enabled but keyring load failed: ${keyringResult.error.code}`);
|
|
93
|
+
throw new Error(`Failed to initialize v2 keyring: ${keyringResult.error.message}`);
|
|
94
|
+
}
|
|
95
|
+
const crypto = container_js_1.container.resolve(tokens_js_1.DI.V2.Crypto);
|
|
96
|
+
const hmac = container_js_1.container.resolve(tokens_js_1.DI.V2.HmacSha256);
|
|
97
|
+
v2 = {
|
|
98
|
+
gate,
|
|
99
|
+
sessionStore,
|
|
100
|
+
snapshotStore,
|
|
101
|
+
pinnedStore,
|
|
102
|
+
keyring: keyringResult.value,
|
|
103
|
+
crypto,
|
|
104
|
+
hmac,
|
|
105
|
+
};
|
|
106
|
+
console.error('[FeatureFlags] v2 tools enabled');
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
console.error('[FeatureFlags] v2 tools disabled (enable with WORKRAIL_ENABLE_V2_TOOLS=true)');
|
|
110
|
+
}
|
|
81
111
|
return {
|
|
82
112
|
workflowService,
|
|
83
113
|
featureFlags,
|
|
84
114
|
sessionManager,
|
|
85
115
|
httpServer,
|
|
116
|
+
v2,
|
|
86
117
|
};
|
|
87
118
|
}
|
|
88
119
|
function toMcpTool(tool) {
|
|
@@ -97,20 +128,12 @@ function createHandler(schema, handler) {
|
|
|
97
128
|
return async (args, ctx) => {
|
|
98
129
|
const parseResult = schema.safeParse(args);
|
|
99
130
|
if (!parseResult.success) {
|
|
100
|
-
return {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
details: parseResult.error.errors.map(e => ({
|
|
107
|
-
path: e.path.join('.'),
|
|
108
|
-
message: e.message,
|
|
109
|
-
})),
|
|
110
|
-
}, null, 2),
|
|
111
|
-
}],
|
|
112
|
-
isError: true,
|
|
113
|
-
};
|
|
131
|
+
return toMcpResult((0, types_js_1.errNotRetryable)('VALIDATION_ERROR', 'Invalid input', {
|
|
132
|
+
validationErrors: parseResult.error.errors.map(e => ({
|
|
133
|
+
path: e.path.join('.'),
|
|
134
|
+
message: e.message,
|
|
135
|
+
})),
|
|
136
|
+
}));
|
|
114
137
|
}
|
|
115
138
|
return toMcpResult(await handler(parseResult.data, ctx));
|
|
116
139
|
};
|
|
@@ -118,26 +141,29 @@ function createHandler(schema, handler) {
|
|
|
118
141
|
function createValidatingHandler(schema, preValidate, handler) {
|
|
119
142
|
return async (args, ctx) => {
|
|
120
143
|
const pre = preValidate(args);
|
|
121
|
-
if (!pre.ok) {
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
144
|
+
if ('error' in pre && !pre.ok) {
|
|
145
|
+
const error = pre.error;
|
|
146
|
+
const details = error.details && typeof error.details === 'object' ? error.details : {};
|
|
147
|
+
const correctTemplate = details.correctTemplate;
|
|
148
|
+
if (correctTemplate !== undefined) {
|
|
149
|
+
const boundedTemplate = (0, bounded_json_js_1.toBoundedJsonValue)(correctTemplate, 512);
|
|
150
|
+
const boundedError = {
|
|
151
|
+
...error,
|
|
152
|
+
details: {
|
|
153
|
+
...details,
|
|
154
|
+
correctTemplate: boundedTemplate,
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
return toMcpResult(boundedError);
|
|
158
|
+
}
|
|
159
|
+
return toMcpResult(error);
|
|
134
160
|
}
|
|
135
161
|
return createHandler(schema, handler)(args, ctx);
|
|
136
162
|
};
|
|
137
163
|
}
|
|
138
164
|
async function startServer() {
|
|
139
165
|
await (0, container_js_1.bootstrap)({ runtimeMode: { kind: 'production' } });
|
|
140
|
-
const ctx = createToolContext();
|
|
166
|
+
const ctx = await createToolContext();
|
|
141
167
|
const descriptionProvider = container_js_1.container.resolve(tokens_js_1.DI.Mcp.DescriptionProvider);
|
|
142
168
|
const buildTool = (0, tool_factory_js_1.createToolFactory)(descriptionProvider);
|
|
143
169
|
const workflowListTool = buildTool({
|
|
@@ -45,6 +45,15 @@ This tool provides:
|
|
|
45
45
|
- Schema version and metadata information`,
|
|
46
46
|
list_workflows: `Lists available workflows using the WorkRail v2 read-only surface (feature-flagged). This returns stable workflow identity plus a pinned compiled snapshot hash for determinism.`,
|
|
47
47
|
inspect_workflow: `Read-only inspection of a workflow using the WorkRail v2 surface (feature-flagged). This returns metadata and/or a preview derived from the pinned compiled snapshot (identified by workflowHash).`,
|
|
48
|
+
start_workflow: `Start a WorkRail v2 workflow run (feature-flagged). Returns an initial pending step plus opaque execution tokens.
|
|
49
|
+
|
|
50
|
+
Notes:
|
|
51
|
+
- Tokens are opaque: round-trip them unchanged.
|
|
52
|
+
- This tool may create durable session/run state. Keep inputs small and deterministic.`,
|
|
53
|
+
continue_workflow: `Continue a WorkRail v2 workflow run (feature-flagged).
|
|
54
|
+
|
|
55
|
+
- If you provide \`ackToken\`: acknowledge completion of the pending step for the given snapshot (idempotent).
|
|
56
|
+
- If you omit \`ackToken\`: rehydrate the pending step for the given snapshot (MUST be side-effect-free).`,
|
|
48
57
|
},
|
|
49
58
|
authoritative: {
|
|
50
59
|
workflow_list: `Check for workflows that apply to the user's request. Workflows are the user's pre-defined instructions that you MUST follow when they exist.
|
|
@@ -105,5 +114,13 @@ This tool is read-only and is intended to validate the v2 determinism substrate
|
|
|
105
114
|
inspect_workflow: `Inspect a workflow via the WorkRail v2 tool surface (feature-flagged).
|
|
106
115
|
|
|
107
116
|
This tool is read-only. It MUST reflect the pinned compiled snapshot identified by workflowHash (not mutable on-disk source).`,
|
|
117
|
+
start_workflow: `Start a workflow run via the WorkRail v2 token-based execution surface (feature-flagged).
|
|
118
|
+
|
|
119
|
+
You MUST treat returned tokens as opaque and round-trip them unchanged.`,
|
|
120
|
+
continue_workflow: `Continue a workflow run via the WorkRail v2 token-based execution surface (feature-flagged).
|
|
121
|
+
|
|
122
|
+
REQUIRED BEHAVIOR:
|
|
123
|
+
- If \`ackToken\` is omitted: rehydrate-only MUST be side-effect-free (no durable writes).
|
|
124
|
+
- If \`ackToken\` is provided: advancement MUST be idempotent and replay-safe for the given tokens.`,
|
|
108
125
|
},
|
|
109
126
|
};
|
package/dist/mcp/tools.js
CHANGED
|
@@ -72,6 +72,16 @@ exports.WORKFLOW_TOOL_ANNOTATIONS = {
|
|
|
72
72
|
destructiveHint: false,
|
|
73
73
|
idempotentHint: true,
|
|
74
74
|
},
|
|
75
|
+
start_workflow: {
|
|
76
|
+
readOnlyHint: false,
|
|
77
|
+
destructiveHint: false,
|
|
78
|
+
idempotentHint: false,
|
|
79
|
+
},
|
|
80
|
+
continue_workflow: {
|
|
81
|
+
readOnlyHint: false,
|
|
82
|
+
destructiveHint: false,
|
|
83
|
+
idempotentHint: true,
|
|
84
|
+
},
|
|
75
85
|
};
|
|
76
86
|
exports.WORKFLOW_TOOL_TITLES = {
|
|
77
87
|
workflow_list: 'List Available Workflows',
|
|
@@ -81,6 +91,8 @@ exports.WORKFLOW_TOOL_TITLES = {
|
|
|
81
91
|
workflow_get_schema: 'Get Workflow Schema',
|
|
82
92
|
list_workflows: 'List Workflows (v2)',
|
|
83
93
|
inspect_workflow: 'Inspect Workflow (v2)',
|
|
94
|
+
start_workflow: 'Start Workflow (v2)',
|
|
95
|
+
continue_workflow: 'Continue Workflow (v2)',
|
|
84
96
|
};
|
|
85
97
|
exports.CreateSessionInput = zod_1.z.object({
|
|
86
98
|
workflowId: zod_1.z
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export declare const DESCRIPTION_MODES: readonly ["standard", "authoritative"];
|
|
2
2
|
export type DescriptionMode = typeof DESCRIPTION_MODES[number];
|
|
3
|
-
export declare const WORKFLOW_TOOL_NAMES: readonly ["workflow_list", "workflow_get", "workflow_next", "workflow_validate_json", "workflow_get_schema", "list_workflows", "inspect_workflow"];
|
|
3
|
+
export declare const WORKFLOW_TOOL_NAMES: readonly ["workflow_list", "workflow_get", "workflow_next", "workflow_validate_json", "workflow_get_schema", "list_workflows", "inspect_workflow", "start_workflow", "continue_workflow"];
|
|
4
4
|
export type WorkflowToolName = typeof WORKFLOW_TOOL_NAMES[number];
|
|
5
5
|
export type ToolDescriptionMap = Readonly<Record<WorkflowToolName, string>>;
|
|
6
6
|
export type DescriptionsByMode = Readonly<Record<DescriptionMode, ToolDescriptionMap>>;
|
package/dist/mcp/types.d.ts
CHANGED
|
@@ -2,7 +2,27 @@ import type { WorkflowService } from '../application/services/workflow-service.j
|
|
|
2
2
|
import type { IFeatureFlagProvider } from '../config/feature-flags.js';
|
|
3
3
|
import type { SessionManager } from '../infrastructure/session/SessionManager.js';
|
|
4
4
|
import type { HttpServer } from '../infrastructure/session/HttpServer.js';
|
|
5
|
-
|
|
5
|
+
import type { SessionHealthV2 } from '../v2/durable-core/schemas/session/session-health.js';
|
|
6
|
+
import type { ExecutionSessionGateV2 } from '../v2/usecases/execution-session-gate.js';
|
|
7
|
+
import type { SessionEventLogAppendStorePortV2, SessionEventLogReadonlyStorePortV2 } from '../v2/ports/session-event-log-store.port.js';
|
|
8
|
+
import type { SnapshotStorePortV2 } from '../v2/ports/snapshot-store.port.js';
|
|
9
|
+
import type { PinnedWorkflowStorePortV2 } from '../v2/ports/pinned-workflow-store.port.js';
|
|
10
|
+
import type { KeyringV1 } from '../v2/ports/keyring.port.js';
|
|
11
|
+
import type { CryptoPortV2 } from '../v2/durable-core/canonical/hashing.js';
|
|
12
|
+
import type { HmacSha256PortV2 } from '../v2/ports/hmac-sha256.port.js';
|
|
13
|
+
import type { JsonValue } from './output-schemas.js';
|
|
14
|
+
export interface SessionHealthDetails {
|
|
15
|
+
readonly health: SessionHealthV2;
|
|
16
|
+
}
|
|
17
|
+
export type ErrorCode = 'VALIDATION_ERROR' | 'NOT_FOUND' | 'PRECONDITION_FAILED' | 'TIMEOUT' | 'INTERNAL_ERROR' | 'TOKEN_INVALID_FORMAT' | 'TOKEN_UNSUPPORTED_VERSION' | 'TOKEN_BAD_SIGNATURE' | 'TOKEN_SCOPE_MISMATCH' | 'TOKEN_UNKNOWN_NODE' | 'TOKEN_WORKFLOW_HASH_MISMATCH' | 'TOKEN_SESSION_LOCKED' | 'SESSION_NOT_HEALTHY';
|
|
18
|
+
export type ToolRetry = {
|
|
19
|
+
readonly kind: 'not_retryable';
|
|
20
|
+
} | {
|
|
21
|
+
readonly kind: 'retryable_immediate';
|
|
22
|
+
} | {
|
|
23
|
+
readonly kind: 'retryable_after_ms';
|
|
24
|
+
readonly afterMs: number;
|
|
25
|
+
};
|
|
6
26
|
export interface ToolSuccess<T> {
|
|
7
27
|
readonly type: 'success';
|
|
8
28
|
readonly data: T;
|
|
@@ -11,15 +31,30 @@ export interface ToolError {
|
|
|
11
31
|
readonly type: 'error';
|
|
12
32
|
readonly code: ErrorCode;
|
|
13
33
|
readonly message: string;
|
|
14
|
-
readonly
|
|
34
|
+
readonly retry: ToolRetry;
|
|
35
|
+
readonly details?: JsonValue;
|
|
15
36
|
}
|
|
16
37
|
export type ToolResult<T> = ToolSuccess<T> | ToolError;
|
|
17
38
|
export declare const success: <T>(data: T) => ToolResult<T>;
|
|
18
|
-
export declare const
|
|
39
|
+
export declare const errNotRetryable: (code: ErrorCode, message: string, details?: JsonValue) => ToolError;
|
|
40
|
+
export declare const errRetryAfterMs: (code: ErrorCode, message: string, afterMs: number, details?: JsonValue) => ToolError;
|
|
41
|
+
export declare const errRetryImmediate: (code: ErrorCode, message: string, details?: JsonValue) => ToolError;
|
|
42
|
+
export declare const error: (code: ErrorCode, message: string, suggestion?: string, retry?: ToolRetry) => ToolError;
|
|
43
|
+
export declare function detailsSessionHealth(health: SessionHealthV2): SessionHealthDetails;
|
|
44
|
+
export interface V2Dependencies {
|
|
45
|
+
readonly gate: ExecutionSessionGateV2;
|
|
46
|
+
readonly sessionStore: SessionEventLogAppendStorePortV2 & SessionEventLogReadonlyStorePortV2;
|
|
47
|
+
readonly snapshotStore: SnapshotStorePortV2;
|
|
48
|
+
readonly pinnedStore: PinnedWorkflowStorePortV2;
|
|
49
|
+
readonly keyring: KeyringV1;
|
|
50
|
+
readonly crypto: CryptoPortV2;
|
|
51
|
+
readonly hmac: HmacSha256PortV2;
|
|
52
|
+
}
|
|
19
53
|
export interface ToolContext {
|
|
20
54
|
readonly workflowService: WorkflowService;
|
|
21
55
|
readonly featureFlags: IFeatureFlagProvider;
|
|
22
56
|
readonly sessionManager: SessionManager | null;
|
|
23
57
|
readonly httpServer: HttpServer | null;
|
|
58
|
+
readonly v2: V2Dependencies | null;
|
|
24
59
|
}
|
|
25
60
|
export type ToolHandler<TInput, TOutput> = (input: TInput, ctx: ToolContext) => Promise<ToolResult<TOutput>>;
|
package/dist/mcp/types.js
CHANGED
|
@@ -1,15 +1,44 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.error = exports.success = void 0;
|
|
3
|
+
exports.error = exports.errRetryImmediate = exports.errRetryAfterMs = exports.errNotRetryable = exports.success = void 0;
|
|
4
|
+
exports.detailsSessionHealth = detailsSessionHealth;
|
|
4
5
|
const success = (data) => ({
|
|
5
6
|
type: 'success',
|
|
6
7
|
data,
|
|
7
8
|
});
|
|
8
9
|
exports.success = success;
|
|
9
|
-
const
|
|
10
|
+
const errNotRetryable = (code, message, details) => ({
|
|
10
11
|
type: 'error',
|
|
11
12
|
code,
|
|
12
13
|
message,
|
|
13
|
-
|
|
14
|
+
retry: { kind: 'not_retryable' },
|
|
15
|
+
details,
|
|
16
|
+
});
|
|
17
|
+
exports.errNotRetryable = errNotRetryable;
|
|
18
|
+
const errRetryAfterMs = (code, message, afterMs, details) => ({
|
|
19
|
+
type: 'error',
|
|
20
|
+
code,
|
|
21
|
+
message,
|
|
22
|
+
retry: { kind: 'retryable_after_ms', afterMs },
|
|
23
|
+
details,
|
|
24
|
+
});
|
|
25
|
+
exports.errRetryAfterMs = errRetryAfterMs;
|
|
26
|
+
const errRetryImmediate = (code, message, details) => ({
|
|
27
|
+
type: 'error',
|
|
28
|
+
code,
|
|
29
|
+
message,
|
|
30
|
+
retry: { kind: 'retryable_immediate' },
|
|
31
|
+
details,
|
|
32
|
+
});
|
|
33
|
+
exports.errRetryImmediate = errRetryImmediate;
|
|
34
|
+
const error = (code, message, suggestion, retry) => ({
|
|
35
|
+
type: 'error',
|
|
36
|
+
code,
|
|
37
|
+
message,
|
|
38
|
+
retry: retry ?? { kind: 'not_retryable' },
|
|
39
|
+
details: suggestion ? { suggestion } : undefined,
|
|
14
40
|
});
|
|
15
41
|
exports.error = error;
|
|
42
|
+
function detailsSessionHealth(health) {
|
|
43
|
+
return { health };
|
|
44
|
+
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.buildV2ToolRegistry = buildV2ToolRegistry;
|
|
4
4
|
const tools_js_1 = require("./tools.js");
|
|
5
|
+
const v2_execution_js_1 = require("../handlers/v2-execution.js");
|
|
5
6
|
const v2_workflow_js_1 = require("../handlers/v2-workflow.js");
|
|
6
7
|
function buildV2ToolRegistry(buildTool) {
|
|
7
8
|
const listTool = buildTool({
|
|
@@ -16,11 +17,25 @@ function buildV2ToolRegistry(buildTool) {
|
|
|
16
17
|
inputSchema: tools_js_1.V2InspectWorkflowInput,
|
|
17
18
|
annotations: tools_js_1.V2_TOOL_ANNOTATIONS.inspect_workflow,
|
|
18
19
|
});
|
|
20
|
+
const startTool = buildTool({
|
|
21
|
+
name: 'start_workflow',
|
|
22
|
+
title: tools_js_1.V2_TOOL_TITLES.start_workflow,
|
|
23
|
+
inputSchema: tools_js_1.V2StartWorkflowInput,
|
|
24
|
+
annotations: tools_js_1.V2_TOOL_ANNOTATIONS.start_workflow,
|
|
25
|
+
});
|
|
26
|
+
const continueTool = buildTool({
|
|
27
|
+
name: 'continue_workflow',
|
|
28
|
+
title: tools_js_1.V2_TOOL_TITLES.continue_workflow,
|
|
29
|
+
inputSchema: tools_js_1.V2ContinueWorkflowInput,
|
|
30
|
+
annotations: tools_js_1.V2_TOOL_ANNOTATIONS.continue_workflow,
|
|
31
|
+
});
|
|
19
32
|
return {
|
|
20
|
-
tools: [listTool, inspectTool],
|
|
33
|
+
tools: [listTool, inspectTool, startTool, continueTool],
|
|
21
34
|
handlers: {
|
|
22
35
|
list_workflows: { schema: tools_js_1.V2ListWorkflowsInput, handler: v2_workflow_js_1.handleV2ListWorkflows },
|
|
23
36
|
inspect_workflow: { schema: tools_js_1.V2InspectWorkflowInput, handler: v2_workflow_js_1.handleV2InspectWorkflow },
|
|
37
|
+
start_workflow: { schema: tools_js_1.V2StartWorkflowInput, handler: v2_execution_js_1.handleV2StartWorkflow },
|
|
38
|
+
continue_workflow: { schema: tools_js_1.V2ContinueWorkflowInput, handler: v2_execution_js_1.handleV2ContinueWorkflow },
|
|
24
39
|
},
|
|
25
40
|
};
|
|
26
41
|
}
|
package/dist/mcp/v2/tools.d.ts
CHANGED
|
@@ -13,8 +13,53 @@ export declare const V2InspectWorkflowInput: z.ZodObject<{
|
|
|
13
13
|
mode?: "metadata" | "preview" | undefined;
|
|
14
14
|
}>;
|
|
15
15
|
export type V2InspectWorkflowInput = z.infer<typeof V2InspectWorkflowInput>;
|
|
16
|
+
export declare const V2StartWorkflowInput: z.ZodObject<{
|
|
17
|
+
workflowId: z.ZodString;
|
|
18
|
+
context: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
19
|
+
}, "strip", z.ZodTypeAny, {
|
|
20
|
+
workflowId: string;
|
|
21
|
+
context?: Record<string, unknown> | undefined;
|
|
22
|
+
}, {
|
|
23
|
+
workflowId: string;
|
|
24
|
+
context?: Record<string, unknown> | undefined;
|
|
25
|
+
}>;
|
|
26
|
+
export type V2StartWorkflowInput = z.infer<typeof V2StartWorkflowInput>;
|
|
27
|
+
export declare const V2ContinueWorkflowInput: z.ZodObject<{
|
|
28
|
+
stateToken: z.ZodString;
|
|
29
|
+
ackToken: z.ZodOptional<z.ZodString>;
|
|
30
|
+
context: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
31
|
+
output: z.ZodOptional<z.ZodObject<{
|
|
32
|
+
notesMarkdown: z.ZodOptional<z.ZodString>;
|
|
33
|
+
artifacts: z.ZodOptional<z.ZodArray<z.ZodUnknown, "many">>;
|
|
34
|
+
}, "strip", z.ZodTypeAny, {
|
|
35
|
+
notesMarkdown?: string | undefined;
|
|
36
|
+
artifacts?: unknown[] | undefined;
|
|
37
|
+
}, {
|
|
38
|
+
notesMarkdown?: string | undefined;
|
|
39
|
+
artifacts?: unknown[] | undefined;
|
|
40
|
+
}>>;
|
|
41
|
+
}, "strip", z.ZodTypeAny, {
|
|
42
|
+
stateToken: string;
|
|
43
|
+
context?: Record<string, unknown> | undefined;
|
|
44
|
+
output?: {
|
|
45
|
+
notesMarkdown?: string | undefined;
|
|
46
|
+
artifacts?: unknown[] | undefined;
|
|
47
|
+
} | undefined;
|
|
48
|
+
ackToken?: string | undefined;
|
|
49
|
+
}, {
|
|
50
|
+
stateToken: string;
|
|
51
|
+
context?: Record<string, unknown> | undefined;
|
|
52
|
+
output?: {
|
|
53
|
+
notesMarkdown?: string | undefined;
|
|
54
|
+
artifacts?: unknown[] | undefined;
|
|
55
|
+
} | undefined;
|
|
56
|
+
ackToken?: string | undefined;
|
|
57
|
+
}>;
|
|
58
|
+
export type V2ContinueWorkflowInput = z.infer<typeof V2ContinueWorkflowInput>;
|
|
16
59
|
export declare const V2_TOOL_TITLES: {
|
|
17
60
|
readonly list_workflows: "List Workflows (v2)";
|
|
18
61
|
readonly inspect_workflow: "Inspect Workflow (v2)";
|
|
62
|
+
readonly start_workflow: "Start Workflow (v2)";
|
|
63
|
+
readonly continue_workflow: "Continue Workflow (v2)";
|
|
19
64
|
};
|
|
20
65
|
export declare const V2_TOOL_ANNOTATIONS: Readonly<Record<keyof typeof V2_TOOL_TITLES, ToolAnnotations>>;
|
package/dist/mcp/v2/tools.js
CHANGED
|
@@ -1,17 +1,37 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.V2_TOOL_ANNOTATIONS = exports.V2_TOOL_TITLES = exports.V2InspectWorkflowInput = exports.V2ListWorkflowsInput = void 0;
|
|
3
|
+
exports.V2_TOOL_ANNOTATIONS = exports.V2_TOOL_TITLES = exports.V2ContinueWorkflowInput = exports.V2StartWorkflowInput = exports.V2InspectWorkflowInput = exports.V2ListWorkflowsInput = void 0;
|
|
4
4
|
const zod_1 = require("zod");
|
|
5
5
|
exports.V2ListWorkflowsInput = zod_1.z.object({});
|
|
6
6
|
exports.V2InspectWorkflowInput = zod_1.z.object({
|
|
7
7
|
workflowId: zod_1.z.string().min(1).describe('The workflow ID to inspect'),
|
|
8
8
|
mode: zod_1.z.enum(['metadata', 'preview']).default('preview').describe('Detail level'),
|
|
9
9
|
});
|
|
10
|
+
exports.V2StartWorkflowInput = zod_1.z.object({
|
|
11
|
+
workflowId: zod_1.z.string().min(1).describe('The workflow ID to start'),
|
|
12
|
+
context: zod_1.z.record(zod_1.z.unknown()).optional().describe('External context inputs (conditions, parameters). Do not include workflow progress state.'),
|
|
13
|
+
});
|
|
14
|
+
exports.V2ContinueWorkflowInput = zod_1.z.object({
|
|
15
|
+
stateToken: zod_1.z.string().min(1).describe('Opaque WorkRail-minted state token'),
|
|
16
|
+
ackToken: zod_1.z.string().min(1).optional().describe('Opaque WorkRail-minted ack token (omit for rehydrate-only)'),
|
|
17
|
+
context: zod_1.z.record(zod_1.z.unknown()).optional().describe('External context inputs (conditions, parameters). Do not include workflow progress state.'),
|
|
18
|
+
output: zod_1.z
|
|
19
|
+
.object({
|
|
20
|
+
notesMarkdown: zod_1.z.string().min(1).optional().describe('Durable recap notes (short; WorkRail may truncate deterministically)'),
|
|
21
|
+
artifacts: zod_1.z.array(zod_1.z.unknown()).optional().describe('Optional structured artifacts (schema is workflow/contract-defined)'),
|
|
22
|
+
})
|
|
23
|
+
.optional()
|
|
24
|
+
.describe('Optional durable output to attach to the current node'),
|
|
25
|
+
});
|
|
10
26
|
exports.V2_TOOL_TITLES = {
|
|
11
27
|
list_workflows: 'List Workflows (v2)',
|
|
12
28
|
inspect_workflow: 'Inspect Workflow (v2)',
|
|
29
|
+
start_workflow: 'Start Workflow (v2)',
|
|
30
|
+
continue_workflow: 'Continue Workflow (v2)',
|
|
13
31
|
};
|
|
14
32
|
exports.V2_TOOL_ANNOTATIONS = {
|
|
15
33
|
list_workflows: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
16
34
|
inspect_workflow: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
35
|
+
start_workflow: { readOnlyHint: false, destructiveHint: false, idempotentHint: false },
|
|
36
|
+
continue_workflow: { readOnlyHint: false, destructiveHint: false, idempotentHint: true },
|
|
17
37
|
};
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
+
import type { ToolError } from '../types.js';
|
|
1
2
|
export type PreValidateResult = {
|
|
2
3
|
readonly ok: true;
|
|
3
4
|
} | {
|
|
4
5
|
readonly ok: false;
|
|
5
|
-
readonly
|
|
6
|
-
readonly message: string;
|
|
7
|
-
readonly correctTemplate?: unknown;
|
|
6
|
+
readonly error: ToolError;
|
|
8
7
|
};
|
|
9
8
|
export declare function preValidateWorkflowNextArgs(args: unknown): PreValidateResult;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.preValidateWorkflowNextArgs = preValidateWorkflowNextArgs;
|
|
4
|
+
const types_js_1 = require("../types.js");
|
|
4
5
|
function normalizeWorkflowIdForTemplate(value) {
|
|
5
6
|
if (typeof value !== 'string')
|
|
6
7
|
return '<workflowId>';
|
|
@@ -13,45 +14,52 @@ function normalizeWorkflowIdForTemplate(value) {
|
|
|
13
14
|
function variablesToContextTemplate(value) {
|
|
14
15
|
if (value == null || typeof value !== 'object' || Array.isArray(value))
|
|
15
16
|
return {};
|
|
16
|
-
|
|
17
|
+
const obj = value;
|
|
18
|
+
const result = {};
|
|
19
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
20
|
+
if (v !== undefined) {
|
|
21
|
+
result[k] = v;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return result;
|
|
17
25
|
}
|
|
18
26
|
function preValidateWorkflowNextArgs(args) {
|
|
19
27
|
if (args == null || typeof args !== 'object' || Array.isArray(args)) {
|
|
20
|
-
return { ok: false,
|
|
28
|
+
return { ok: false, error: (0, types_js_1.errNotRetryable)('VALIDATION_ERROR', 'Invalid input: expected a JSON object.') };
|
|
21
29
|
}
|
|
22
30
|
const a = args;
|
|
23
31
|
const suggestedContext = variablesToContextTemplate(a.variables);
|
|
24
32
|
if (!('workflowId' in a)) {
|
|
25
|
-
return { ok: false,
|
|
33
|
+
return { ok: false, error: (0, types_js_1.errNotRetryable)('VALIDATION_ERROR', 'Missing required field: workflowId.') };
|
|
26
34
|
}
|
|
27
35
|
if (!('state' in a)) {
|
|
28
36
|
return {
|
|
29
37
|
ok: false,
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
},
|
|
38
|
+
error: (0, types_js_1.errNotRetryable)('VALIDATION_ERROR', 'Missing required field: state. For the first call, use { kind: "init" }.', {
|
|
39
|
+
correctTemplate: {
|
|
40
|
+
workflowId: normalizeWorkflowIdForTemplate(a.workflowId),
|
|
41
|
+
state: { kind: 'init' },
|
|
42
|
+
context: suggestedContext,
|
|
43
|
+
},
|
|
44
|
+
}),
|
|
37
45
|
};
|
|
38
46
|
}
|
|
39
47
|
const state = a.state;
|
|
40
48
|
if (state == null || typeof state !== 'object' || Array.isArray(state)) {
|
|
41
49
|
return {
|
|
42
50
|
ok: false,
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
51
|
+
error: (0, types_js_1.errNotRetryable)('VALIDATION_ERROR', 'Invalid state: expected an object with discriminator field "kind".', {
|
|
52
|
+
correctTemplate: { kind: 'init' },
|
|
53
|
+
}),
|
|
46
54
|
};
|
|
47
55
|
}
|
|
48
56
|
const kind = state.kind;
|
|
49
57
|
if (typeof kind !== 'string') {
|
|
50
58
|
return {
|
|
51
59
|
ok: false,
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
60
|
+
error: (0, types_js_1.errNotRetryable)('VALIDATION_ERROR', 'Invalid state: missing state.kind. Valid values: "init" | "running" | "complete".', {
|
|
61
|
+
correctTemplate: { kind: 'init' },
|
|
62
|
+
}),
|
|
55
63
|
};
|
|
56
64
|
}
|
|
57
65
|
if (kind === 'running') {
|
|
@@ -60,23 +68,26 @@ function preValidateWorkflowNextArgs(args) {
|
|
|
60
68
|
if (!Array.isArray(completed) || !Array.isArray(loopStack)) {
|
|
61
69
|
return {
|
|
62
70
|
ok: false,
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
71
|
+
error: (0, types_js_1.errNotRetryable)('VALIDATION_ERROR', 'Invalid state: state.kind="running" requires completed: string[] and loopStack: LoopFrame[].', {
|
|
72
|
+
correctTemplate: { kind: 'running', completed: [], loopStack: [] },
|
|
73
|
+
}),
|
|
66
74
|
};
|
|
67
75
|
}
|
|
68
76
|
}
|
|
69
77
|
if ('variables' in a && !('context' in a)) {
|
|
78
|
+
const correctTemplate = {
|
|
79
|
+
workflowId: normalizeWorkflowIdForTemplate(a.workflowId),
|
|
80
|
+
state: a.state,
|
|
81
|
+
context: suggestedContext,
|
|
82
|
+
};
|
|
83
|
+
if (a.event && typeof a.event === 'object') {
|
|
84
|
+
correctTemplate.event = a.event;
|
|
85
|
+
}
|
|
70
86
|
return {
|
|
71
87
|
ok: false,
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
workflowId: normalizeWorkflowIdForTemplate(a.workflowId),
|
|
76
|
-
state: a.state,
|
|
77
|
-
...(a.event ? { event: a.event } : {}),
|
|
78
|
-
context: suggestedContext,
|
|
79
|
-
},
|
|
88
|
+
error: (0, types_js_1.errNotRetryable)('VALIDATION_ERROR', 'Unexpected top-level key: variables. Use context (object) for condition evaluation and loop inputs.', {
|
|
89
|
+
correctTemplate,
|
|
90
|
+
}),
|
|
80
91
|
};
|
|
81
92
|
}
|
|
82
93
|
return { ok: true };
|
|
@@ -11,6 +11,7 @@ export type EventIndex = Brand<number, 'v2.EventIndex'>;
|
|
|
11
11
|
export type ManifestIndex = Brand<number, 'v2.ManifestIndex'>;
|
|
12
12
|
export type SnapshotRef = Brand<Sha256Digest, 'v2.SnapshotRef'>;
|
|
13
13
|
export type AttemptId = Brand<string, 'v2.AttemptId'>;
|
|
14
|
+
export type OutputId = Brand<string, 'v2.OutputId'>;
|
|
14
15
|
export type TokenStringV1 = Brand<string, 'v2.TokenStringV1'>;
|
|
15
16
|
export declare function asWorkflowId(value: string): WorkflowId;
|
|
16
17
|
export declare function asSha256Digest(value: string): Sha256Digest;
|
|
@@ -24,4 +25,5 @@ export declare function asEventIndex(value: number): EventIndex;
|
|
|
24
25
|
export declare function asManifestIndex(value: number): ManifestIndex;
|
|
25
26
|
export declare function asSnapshotRef(value: Sha256Digest): SnapshotRef;
|
|
26
27
|
export declare function asAttemptId(value: string): AttemptId;
|
|
28
|
+
export declare function asOutputId(value: string): OutputId;
|
|
27
29
|
export declare function asTokenStringV1(value: string): TokenStringV1;
|
|
@@ -12,6 +12,7 @@ exports.asEventIndex = asEventIndex;
|
|
|
12
12
|
exports.asManifestIndex = asManifestIndex;
|
|
13
13
|
exports.asSnapshotRef = asSnapshotRef;
|
|
14
14
|
exports.asAttemptId = asAttemptId;
|
|
15
|
+
exports.asOutputId = asOutputId;
|
|
15
16
|
exports.asTokenStringV1 = asTokenStringV1;
|
|
16
17
|
function asWorkflowId(value) {
|
|
17
18
|
return value;
|
|
@@ -49,6 +50,9 @@ function asSnapshotRef(value) {
|
|
|
49
50
|
function asAttemptId(value) {
|
|
50
51
|
return value;
|
|
51
52
|
}
|
|
53
|
+
function asOutputId(value) {
|
|
54
|
+
return value;
|
|
55
|
+
}
|
|
52
56
|
function asTokenStringV1(value) {
|
|
53
57
|
return value;
|
|
54
58
|
}
|