@exaudeus/workrail 1.0.0 → 1.2.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/output-normalizer.d.ts +9 -0
- package/dist/application/services/output-normalizer.js +38 -0
- package/dist/application/services/validation-engine.d.ts +15 -1
- package/dist/application/services/validation-engine.js +81 -51
- package/dist/application/services/workflow-compiler.d.ts +3 -0
- package/dist/application/services/workflow-compiler.js +26 -0
- package/dist/application/services/workflow-interpreter.d.ts +4 -1
- package/dist/application/services/workflow-interpreter.js +85 -24
- package/dist/application/services/workflow-service.js +19 -2
- package/dist/manifest.json +379 -75
- package/dist/mcp/handler-factory.d.ts +7 -0
- package/dist/mcp/handler-factory.js +70 -0
- package/dist/mcp/handlers/shared/with-timeout.d.ts +1 -0
- package/dist/mcp/handlers/shared/with-timeout.js +9 -0
- package/dist/mcp/handlers/v2-advance-core.d.ts +45 -0
- package/dist/mcp/handlers/v2-advance-core.js +433 -0
- package/dist/mcp/handlers/v2-context-budget.d.ts +17 -0
- package/dist/mcp/handlers/v2-context-budget.js +169 -0
- package/dist/mcp/handlers/v2-error-mapping.d.ts +34 -0
- package/dist/mcp/handlers/v2-error-mapping.js +125 -0
- package/dist/mcp/handlers/v2-execution-helpers.js +4 -1
- package/dist/mcp/handlers/v2-execution.d.ts +19 -0
- package/dist/mcp/handlers/v2-execution.js +366 -589
- package/dist/mcp/handlers/v2-state-conversion.d.ts +40 -0
- package/dist/mcp/handlers/v2-state-conversion.js +132 -0
- package/dist/mcp/handlers/v2-token-ops.d.ts +33 -0
- package/dist/mcp/handlers/v2-token-ops.js +62 -0
- package/dist/mcp/handlers/v2-workflow.js +3 -8
- package/dist/mcp/handlers/workflow.js +4 -11
- package/dist/mcp/output-schemas.d.ts +514 -38
- package/dist/mcp/output-schemas.js +102 -7
- package/dist/mcp/server.js +23 -127
- package/dist/mcp/tool-descriptions.js +142 -18
- package/dist/mcp/types/workflow-tool-edition.d.ts +28 -0
- package/dist/mcp/types/workflow-tool-edition.js +10 -0
- package/dist/mcp/types.d.ts +2 -0
- package/dist/mcp/v1/tool-registry.d.ts +8 -0
- package/dist/mcp/v1/tool-registry.js +49 -0
- package/dist/mcp/v2/tool-registry.d.ts +2 -5
- package/dist/mcp/v2/tool-registry.js +33 -32
- package/dist/mcp/v2/tools.d.ts +23 -2
- package/dist/mcp/v2/tools.js +38 -7
- package/dist/mcp/workflow-tool-edition-selector.d.ts +4 -0
- package/dist/mcp/workflow-tool-edition-selector.js +13 -0
- package/dist/types/workflow-definition.d.ts +19 -0
- package/dist/v2/durable-core/constants.d.ts +3 -0
- package/dist/v2/durable-core/constants.js +4 -1
- package/dist/v2/durable-core/domain/ack-advance-append-plan.d.ts +15 -7
- package/dist/v2/durable-core/domain/ack-advance-append-plan.js +89 -24
- package/dist/v2/durable-core/domain/artifact-contract-validator.d.ts +31 -0
- package/dist/v2/durable-core/domain/artifact-contract-validator.js +98 -0
- package/dist/v2/durable-core/domain/blocked-node-builder.d.ts +20 -0
- package/dist/v2/durable-core/domain/blocked-node-builder.js +94 -0
- package/dist/v2/durable-core/domain/blocking-decision.d.ts +32 -0
- package/dist/v2/durable-core/domain/blocking-decision.js +41 -0
- package/dist/v2/durable-core/domain/context-merge.d.ts +8 -0
- package/dist/v2/durable-core/domain/context-merge.js +40 -0
- package/dist/v2/durable-core/domain/decision-trace-builder.d.ts +33 -0
- package/dist/v2/durable-core/domain/decision-trace-builder.js +92 -0
- package/dist/v2/durable-core/domain/function-definition-expander.d.ts +14 -0
- package/dist/v2/durable-core/domain/function-definition-expander.js +66 -0
- package/dist/v2/durable-core/domain/gap-builder.d.ts +19 -0
- package/dist/v2/durable-core/domain/gap-builder.js +24 -0
- package/dist/v2/durable-core/domain/loop-control-evaluator.d.ts +13 -0
- package/dist/v2/durable-core/domain/loop-control-evaluator.js +24 -0
- package/dist/v2/durable-core/domain/observation-builder.d.ts +16 -0
- package/dist/v2/durable-core/domain/observation-builder.js +42 -0
- package/dist/v2/durable-core/domain/outputs.js +2 -2
- package/dist/v2/durable-core/domain/prompt-renderer.d.ts +24 -0
- package/dist/v2/durable-core/domain/prompt-renderer.js +200 -0
- package/dist/v2/durable-core/domain/reason-model.d.ts +96 -0
- package/dist/v2/durable-core/domain/reason-model.js +241 -0
- package/dist/v2/durable-core/domain/recap-recovery.d.ts +24 -0
- package/dist/v2/durable-core/domain/recap-recovery.js +71 -0
- package/dist/v2/durable-core/domain/recommendation-warnings.d.ts +20 -0
- package/dist/v2/durable-core/domain/recommendation-warnings.js +35 -0
- package/dist/v2/durable-core/domain/risk-policy-guardrails.d.ts +15 -0
- package/dist/v2/durable-core/domain/risk-policy-guardrails.js +78 -0
- package/dist/v2/durable-core/domain/validation-criteria-validator.d.ts +16 -0
- package/dist/v2/durable-core/domain/validation-criteria-validator.js +46 -0
- package/dist/v2/durable-core/domain/validation-event-builder.d.ts +26 -0
- package/dist/v2/durable-core/domain/validation-event-builder.js +100 -0
- package/dist/v2/durable-core/domain/validation-loader.d.ts +11 -0
- package/dist/v2/durable-core/domain/validation-loader.js +21 -0
- package/dist/v2/durable-core/domain/validation-requirements-extractor.d.ts +2 -0
- package/dist/v2/durable-core/domain/validation-requirements-extractor.js +58 -0
- package/dist/v2/durable-core/projections/snapshot-state.js +1 -1
- package/dist/v2/durable-core/schemas/artifacts/index.d.ts +4 -0
- package/dist/v2/durable-core/schemas/artifacts/index.js +18 -0
- package/dist/v2/durable-core/schemas/artifacts/loop-control.d.ts +66 -0
- package/dist/v2/durable-core/schemas/artifacts/loop-control.js +47 -0
- package/dist/v2/durable-core/schemas/execution-snapshot/blocked-snapshot.d.ts +598 -0
- package/dist/v2/durable-core/schemas/execution-snapshot/blocked-snapshot.js +89 -0
- package/dist/v2/durable-core/schemas/execution-snapshot/execution-snapshot.v1.d.ts +3801 -57
- package/dist/v2/durable-core/schemas/execution-snapshot/execution-snapshot.v1.js +12 -2
- package/dist/v2/durable-core/schemas/execution-snapshot/index.d.ts +2 -0
- package/dist/v2/durable-core/schemas/execution-snapshot/index.js +3 -1
- package/dist/v2/durable-core/schemas/export-bundle/index.d.ts +6201 -2071
- package/dist/v2/durable-core/schemas/session/events.d.ts +216 -45
- package/dist/v2/durable-core/schemas/session/events.js +17 -1
- package/dist/v2/durable-core/schemas/session/validation-event.d.ts +68 -0
- package/dist/v2/durable-core/schemas/session/validation-event.js +52 -0
- package/dist/v2/durable-core/tokens/payloads.d.ts +16 -16
- package/dist/v2/infra/local/workspace-anchor/index.d.ts +9 -0
- package/dist/v2/infra/local/workspace-anchor/index.js +44 -0
- package/dist/v2/ports/workspace-anchor.port.d.ts +18 -0
- package/dist/v2/ports/workspace-anchor.port.js +2 -0
- package/dist/v2/projections/artifacts.d.ts +22 -0
- package/dist/v2/projections/artifacts.js +53 -0
- package/dist/v2/projections/projection-timing.d.ts +13 -0
- package/dist/v2/projections/projection-timing.js +23 -0
- package/dist/v2/projections/run-context.d.ts +22 -0
- package/dist/v2/projections/run-context.js +33 -0
- package/dist/v2/projections/run-dag.d.ts +1 -1
- package/dist/v2/projections/run-status-signals.js +3 -8
- package/package.json +1 -1
- package/spec/workflow.schema.json +60 -0
- package/spec/workflow.schema.v0.0.1.json +38 -0
- package/workflows/coding-task-workflow-agentic.json +11 -18
- package/workflows/test-artifact-loop-control.json +59 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.OpenDashboardOutputSchema = exports.ReadSessionSchemaOutputSchema = exports.ReadSessionOutputSchema = exports.UpdateSessionOutputSchema = exports.CreateSessionOutputSchema = exports.V2StartWorkflowOutputSchema = exports.V2ContinueWorkflowOutputSchema = exports.V2BlockerReportSchema = exports.V2PendingStepSchema = exports.V2WorkflowInspectOutputSchema = exports.V2WorkflowListOutputSchema = exports.V2WorkflowListItemSchema = exports.WorkflowGetSchemaOutputSchema = exports.WorkflowValidateJsonOutputSchema = exports.WorkflowNextOutputSchema = exports.WorkflowGetOutputSchema = exports.WorkflowListOutputSchema = exports.WorkflowSummarySchema = exports.JsonValueSchema = void 0;
|
|
3
|
+
exports.OpenDashboardOutputSchema = exports.ReadSessionSchemaOutputSchema = exports.ReadSessionOutputSchema = exports.UpdateSessionOutputSchema = exports.CreateSessionOutputSchema = exports.V2StartWorkflowOutputSchema = exports.V2ContinueWorkflowOutputSchema = exports.V2BlockerReportSchema = exports.V2NextCallSchema = exports.V2NextIntentSchema = exports.V2PreferencesSchema = exports.V2PendingStepSchema = exports.V2WorkflowInspectOutputSchema = exports.V2WorkflowListOutputSchema = exports.V2WorkflowListItemSchema = exports.WorkflowGetSchemaOutputSchema = exports.WorkflowValidateJsonOutputSchema = exports.WorkflowNextOutputSchema = exports.WorkflowGetOutputSchema = exports.WorkflowListOutputSchema = exports.WorkflowSummarySchema = exports.JsonValueSchema = void 0;
|
|
4
4
|
const zod_1 = require("zod");
|
|
5
5
|
const state_js_1 = require("../domain/execution/state.js");
|
|
6
6
|
const JsonPrimitiveSchema = zod_1.z.union([zod_1.z.string(), zod_1.z.number(), zod_1.z.boolean(), zod_1.z.null()]);
|
|
@@ -67,11 +67,43 @@ exports.V2PendingStepSchema = zod_1.z.object({
|
|
|
67
67
|
title: zod_1.z.string().min(1),
|
|
68
68
|
prompt: zod_1.z.string().min(1),
|
|
69
69
|
});
|
|
70
|
+
exports.V2PreferencesSchema = zod_1.z.object({
|
|
71
|
+
autonomy: zod_1.z.enum(['guided', 'full_auto_stop_on_user_deps', 'full_auto_never_stop']),
|
|
72
|
+
riskPolicy: zod_1.z.enum(['conservative', 'balanced', 'aggressive']),
|
|
73
|
+
});
|
|
74
|
+
exports.V2NextIntentSchema = zod_1.z.enum([
|
|
75
|
+
'perform_pending_then_continue',
|
|
76
|
+
'await_user_confirmation',
|
|
77
|
+
'rehydrate_only',
|
|
78
|
+
'complete',
|
|
79
|
+
]);
|
|
80
|
+
exports.V2NextCallSchema = zod_1.z.object({
|
|
81
|
+
tool: zod_1.z.literal('continue_workflow'),
|
|
82
|
+
params: zod_1.z.object({
|
|
83
|
+
intent: zod_1.z.literal('advance'),
|
|
84
|
+
stateToken: zod_1.z.string().min(1),
|
|
85
|
+
ackToken: zod_1.z.string().min(1),
|
|
86
|
+
}),
|
|
87
|
+
}).nullable();
|
|
88
|
+
function utf8ByteLength(s) {
|
|
89
|
+
return new TextEncoder().encode(s).length;
|
|
90
|
+
}
|
|
91
|
+
const MAX_BLOCKER_MESSAGE_BYTES = 512;
|
|
92
|
+
const MAX_BLOCKER_SUGGESTED_FIX_BYTES = 1024;
|
|
93
|
+
const MAX_BLOCKERS = 10;
|
|
94
|
+
const DELIMITER_SAFE_ID_PATTERN = /^[a-z0-9_-]+$/;
|
|
70
95
|
const V2BlockerPointerSchema = zod_1.z.discriminatedUnion('kind', [
|
|
71
|
-
zod_1.z.object({
|
|
96
|
+
zod_1.z.object({
|
|
97
|
+
kind: zod_1.z.literal('context_key'),
|
|
98
|
+
key: zod_1.z.string().min(1).regex(DELIMITER_SAFE_ID_PATTERN, 'context_key must be delimiter-safe: [a-z0-9_-]+'),
|
|
99
|
+
}),
|
|
100
|
+
zod_1.z.object({ kind: zod_1.z.literal('context_budget') }),
|
|
72
101
|
zod_1.z.object({ kind: zod_1.z.literal('output_contract'), contractRef: zod_1.z.string().min(1) }),
|
|
73
102
|
zod_1.z.object({ kind: zod_1.z.literal('capability'), capability: zod_1.z.enum(['delegation', 'web_browsing']) }),
|
|
74
|
-
zod_1.z.object({
|
|
103
|
+
zod_1.z.object({
|
|
104
|
+
kind: zod_1.z.literal('workflow_step'),
|
|
105
|
+
stepId: zod_1.z.string().min(1).regex(DELIMITER_SAFE_ID_PATTERN, 'stepId must be delimiter-safe: [a-z0-9_-]+'),
|
|
106
|
+
}),
|
|
75
107
|
]);
|
|
76
108
|
const V2BlockerSchema = zod_1.z.object({
|
|
77
109
|
code: zod_1.z.enum([
|
|
@@ -84,11 +116,57 @@ const V2BlockerSchema = zod_1.z.object({
|
|
|
84
116
|
'STORAGE_CORRUPTION_DETECTED',
|
|
85
117
|
]),
|
|
86
118
|
pointer: V2BlockerPointerSchema,
|
|
87
|
-
message: zod_1.z
|
|
88
|
-
|
|
119
|
+
message: zod_1.z
|
|
120
|
+
.string()
|
|
121
|
+
.min(1)
|
|
122
|
+
.refine((s) => utf8ByteLength(s) <= MAX_BLOCKER_MESSAGE_BYTES, {
|
|
123
|
+
message: `Blocker message exceeds ${MAX_BLOCKER_MESSAGE_BYTES} bytes (UTF-8)`,
|
|
124
|
+
}),
|
|
125
|
+
suggestedFix: zod_1.z
|
|
126
|
+
.string()
|
|
127
|
+
.min(1)
|
|
128
|
+
.refine((s) => utf8ByteLength(s) <= MAX_BLOCKER_SUGGESTED_FIX_BYTES, {
|
|
129
|
+
message: `Blocker suggestedFix exceeds ${MAX_BLOCKER_SUGGESTED_FIX_BYTES} bytes (UTF-8)`,
|
|
130
|
+
})
|
|
131
|
+
.optional(),
|
|
89
132
|
});
|
|
90
|
-
exports.V2BlockerReportSchema = zod_1.z
|
|
91
|
-
|
|
133
|
+
exports.V2BlockerReportSchema = zod_1.z
|
|
134
|
+
.object({
|
|
135
|
+
blockers: zod_1.z.array(V2BlockerSchema).min(1).max(MAX_BLOCKERS).readonly(),
|
|
136
|
+
})
|
|
137
|
+
.superRefine((v, ctx) => {
|
|
138
|
+
const keyFor = (b) => {
|
|
139
|
+
const p = b.pointer;
|
|
140
|
+
let ptrStable;
|
|
141
|
+
switch (p.kind) {
|
|
142
|
+
case 'context_key':
|
|
143
|
+
ptrStable = p.key;
|
|
144
|
+
break;
|
|
145
|
+
case 'output_contract':
|
|
146
|
+
ptrStable = p.contractRef;
|
|
147
|
+
break;
|
|
148
|
+
case 'capability':
|
|
149
|
+
ptrStable = p.capability;
|
|
150
|
+
break;
|
|
151
|
+
case 'workflow_step':
|
|
152
|
+
ptrStable = p.stepId;
|
|
153
|
+
break;
|
|
154
|
+
case 'context_budget':
|
|
155
|
+
ptrStable = '';
|
|
156
|
+
break;
|
|
157
|
+
default: {
|
|
158
|
+
const _exhaustive = p;
|
|
159
|
+
ptrStable = _exhaustive;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return `${b.code}|${p.kind}|${String(ptrStable)}`;
|
|
163
|
+
};
|
|
164
|
+
for (let i = 1; i < v.blockers.length; i++) {
|
|
165
|
+
if (keyFor(v.blockers[i - 1]) > keyFor(v.blockers[i])) {
|
|
166
|
+
ctx.addIssue({ code: zod_1.z.ZodIssueCode.custom, message: 'blockers must be deterministically sorted', path: ['blockers'] });
|
|
167
|
+
break;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
92
170
|
});
|
|
93
171
|
const V2ContinueWorkflowOkSchema = zod_1.z.object({
|
|
94
172
|
kind: zod_1.z.literal('ok'),
|
|
@@ -96,6 +174,9 @@ const V2ContinueWorkflowOkSchema = zod_1.z.object({
|
|
|
96
174
|
ackToken: zod_1.z.string().regex(/^ack1[023456789acdefghjklmnpqrstuvwxyz]+$/, 'Invalid ackToken format').optional(),
|
|
97
175
|
isComplete: zod_1.z.boolean(),
|
|
98
176
|
pending: exports.V2PendingStepSchema.nullable(),
|
|
177
|
+
preferences: exports.V2PreferencesSchema,
|
|
178
|
+
nextIntent: exports.V2NextIntentSchema,
|
|
179
|
+
nextCall: exports.V2NextCallSchema,
|
|
99
180
|
});
|
|
100
181
|
const V2ContinueWorkflowBlockedSchema = zod_1.z.object({
|
|
101
182
|
kind: zod_1.z.literal('blocked'),
|
|
@@ -103,7 +184,18 @@ const V2ContinueWorkflowBlockedSchema = zod_1.z.object({
|
|
|
103
184
|
ackToken: zod_1.z.string().regex(/^ack1[023456789acdefghjklmnpqrstuvwxyz]+$/, 'Invalid ackToken format').optional(),
|
|
104
185
|
isComplete: zod_1.z.boolean(),
|
|
105
186
|
pending: exports.V2PendingStepSchema.nullable(),
|
|
187
|
+
preferences: exports.V2PreferencesSchema,
|
|
188
|
+
nextIntent: exports.V2NextIntentSchema,
|
|
189
|
+
nextCall: exports.V2NextCallSchema,
|
|
106
190
|
blockers: exports.V2BlockerReportSchema,
|
|
191
|
+
retryable: zod_1.z.boolean().optional(),
|
|
192
|
+
retryAckToken: zod_1.z.string().optional(),
|
|
193
|
+
validation: zod_1.z
|
|
194
|
+
.object({
|
|
195
|
+
issues: zod_1.z.array(zod_1.z.string()),
|
|
196
|
+
suggestions: zod_1.z.array(zod_1.z.string()),
|
|
197
|
+
})
|
|
198
|
+
.optional(),
|
|
107
199
|
});
|
|
108
200
|
exports.V2ContinueWorkflowOutputSchema = zod_1.z.discriminatedUnion('kind', [
|
|
109
201
|
V2ContinueWorkflowOkSchema,
|
|
@@ -114,6 +206,9 @@ exports.V2StartWorkflowOutputSchema = zod_1.z.object({
|
|
|
114
206
|
ackToken: zod_1.z.string().regex(/^ack1[023456789acdefghjklmnpqrstuvwxyz]+$/, 'Invalid ackToken format').optional(),
|
|
115
207
|
isComplete: zod_1.z.boolean(),
|
|
116
208
|
pending: exports.V2PendingStepSchema.nullable(),
|
|
209
|
+
preferences: exports.V2PreferencesSchema,
|
|
210
|
+
nextIntent: exports.V2NextIntentSchema,
|
|
211
|
+
nextCall: exports.V2NextCallSchema,
|
|
117
212
|
}).refine((data) => (data.pending ? data.ackToken != null : true), { message: 'ackToken is required when a pending step exists' });
|
|
118
213
|
exports.CreateSessionOutputSchema = zod_1.z.object({
|
|
119
214
|
sessionId: zod_1.z.string().min(1),
|
package/dist/mcp/server.js
CHANGED
|
@@ -38,37 +38,14 @@ 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
|
|
41
|
+
const assert_never_js_1 = require("../runtime/assert-never.js");
|
|
42
42
|
const token_codec_ports_js_1 = require("../v2/durable-core/tokens/token-codec-ports.js");
|
|
43
|
+
const index_js_1 = require("../v2/infra/local/workspace-anchor/index.js");
|
|
43
44
|
const tool_factory_js_1 = require("./tool-factory.js");
|
|
44
|
-
const
|
|
45
|
-
const
|
|
46
|
-
const index_js_1 = require("./validation/index.js");
|
|
45
|
+
const handler_factory_js_1 = require("./handler-factory.js");
|
|
46
|
+
const workflow_tool_edition_selector_js_1 = require("./workflow-tool-edition-selector.js");
|
|
47
47
|
const tools_js_1 = require("./tools.js");
|
|
48
|
-
const tool_registry_js_1 = require("./v2/tool-registry.js");
|
|
49
|
-
const workflow_js_1 = require("./handlers/workflow.js");
|
|
50
48
|
const session_js_1 = require("./handlers/session.js");
|
|
51
|
-
function toMcpResult(result) {
|
|
52
|
-
switch (result.type) {
|
|
53
|
-
case 'success':
|
|
54
|
-
return {
|
|
55
|
-
content: [{ type: 'text', text: JSON.stringify(result.data, null, 2) }],
|
|
56
|
-
};
|
|
57
|
-
case 'error':
|
|
58
|
-
return {
|
|
59
|
-
content: [{
|
|
60
|
-
type: 'text',
|
|
61
|
-
text: JSON.stringify({
|
|
62
|
-
code: result.code,
|
|
63
|
-
message: result.message,
|
|
64
|
-
retry: result.retry,
|
|
65
|
-
...(result.details !== undefined ? { details: result.details } : {}),
|
|
66
|
-
}, null, 2),
|
|
67
|
-
}],
|
|
68
|
-
isError: true,
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
49
|
async function createToolContext() {
|
|
73
50
|
const workflowService = container_js_1.container.resolve(tokens_js_1.DI.Services.Workflow);
|
|
74
51
|
const featureFlags = container_js_1.container.resolve(tokens_js_1.DI.Infra.FeatureFlags);
|
|
@@ -119,6 +96,7 @@ async function createToolContext() {
|
|
|
119
96
|
crypto,
|
|
120
97
|
idFactory,
|
|
121
98
|
tokenCodecPorts,
|
|
99
|
+
workspaceAnchor: new index_js_1.LocalWorkspaceAnchorV2(process.cwd()),
|
|
122
100
|
};
|
|
123
101
|
console.error('[FeatureFlags] v2 tools enabled');
|
|
124
102
|
}
|
|
@@ -142,81 +120,22 @@ function toMcpTool(tool) {
|
|
|
142
120
|
annotations: tool.annotations,
|
|
143
121
|
};
|
|
144
122
|
}
|
|
145
|
-
function createHandler(schema, handler) {
|
|
146
|
-
return async (args, ctx) => {
|
|
147
|
-
const parseResult = schema.safeParse(args);
|
|
148
|
-
if (!parseResult.success) {
|
|
149
|
-
const suggestionResult = (0, index_js_1.generateSuggestions)(args, schema, index_js_1.DEFAULT_SUGGESTION_CONFIG);
|
|
150
|
-
const suggestionDetails = (0, index_js_1.formatSuggestionDetails)(suggestionResult);
|
|
151
|
-
return toMcpResult((0, types_js_1.errNotRetryable)('VALIDATION_ERROR', 'Invalid input', {
|
|
152
|
-
validationErrors: parseResult.error.errors.map(e => ({
|
|
153
|
-
path: e.path.join('.'),
|
|
154
|
-
message: e.message,
|
|
155
|
-
})),
|
|
156
|
-
...suggestionDetails,
|
|
157
|
-
}));
|
|
158
|
-
}
|
|
159
|
-
return toMcpResult(await handler(parseResult.data, ctx));
|
|
160
|
-
};
|
|
161
|
-
}
|
|
162
|
-
function createValidatingHandler(schema, preValidate, handler) {
|
|
163
|
-
return async (args, ctx) => {
|
|
164
|
-
const pre = preValidate(args);
|
|
165
|
-
if ('error' in pre && !pre.ok) {
|
|
166
|
-
const error = pre.error;
|
|
167
|
-
const details = error.details && typeof error.details === 'object' ? error.details : {};
|
|
168
|
-
const correctTemplate = details.correctTemplate;
|
|
169
|
-
if (correctTemplate !== undefined) {
|
|
170
|
-
const boundedTemplate = (0, bounded_json_js_1.toBoundedJsonValue)(correctTemplate, 512);
|
|
171
|
-
const boundedError = {
|
|
172
|
-
...error,
|
|
173
|
-
details: {
|
|
174
|
-
...details,
|
|
175
|
-
correctTemplate: boundedTemplate,
|
|
176
|
-
},
|
|
177
|
-
};
|
|
178
|
-
return toMcpResult(boundedError);
|
|
179
|
-
}
|
|
180
|
-
return toMcpResult(error);
|
|
181
|
-
}
|
|
182
|
-
return createHandler(schema, handler)(args, ctx);
|
|
183
|
-
};
|
|
184
|
-
}
|
|
185
123
|
async function startServer() {
|
|
186
124
|
await (0, container_js_1.bootstrap)({ runtimeMode: { kind: 'production' } });
|
|
187
125
|
const ctx = await createToolContext();
|
|
188
126
|
const descriptionProvider = container_js_1.container.resolve(tokens_js_1.DI.Mcp.DescriptionProvider);
|
|
189
127
|
const buildTool = (0, tool_factory_js_1.createToolFactory)(descriptionProvider);
|
|
190
|
-
const
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
});
|
|
202
|
-
const advanceWorkflowTool = buildTool({
|
|
203
|
-
name: 'advance_workflow',
|
|
204
|
-
title: tools_js_1.WORKFLOW_TOOL_TITLES.advance_workflow,
|
|
205
|
-
inputSchema: tools_js_1.WorkflowNextInput,
|
|
206
|
-
annotations: tools_js_1.WORKFLOW_TOOL_ANNOTATIONS.advance_workflow,
|
|
207
|
-
});
|
|
208
|
-
const validateWorkflowTool = buildTool({
|
|
209
|
-
name: 'validate_workflow',
|
|
210
|
-
title: tools_js_1.WORKFLOW_TOOL_TITLES.validate_workflow,
|
|
211
|
-
inputSchema: tools_js_1.WorkflowValidateJsonInput,
|
|
212
|
-
annotations: tools_js_1.WORKFLOW_TOOL_ANNOTATIONS.validate_workflow,
|
|
213
|
-
});
|
|
214
|
-
const getWorkflowSchemaTool = buildTool({
|
|
215
|
-
name: 'get_workflow_schema',
|
|
216
|
-
title: tools_js_1.WORKFLOW_TOOL_TITLES.get_workflow_schema,
|
|
217
|
-
inputSchema: tools_js_1.WorkflowGetSchemaInput,
|
|
218
|
-
annotations: tools_js_1.WORKFLOW_TOOL_ANNOTATIONS.get_workflow_schema,
|
|
219
|
-
});
|
|
128
|
+
const workflowEdition = (0, workflow_tool_edition_selector_js_1.selectWorkflowToolEdition)(ctx.featureFlags, buildTool);
|
|
129
|
+
switch (workflowEdition.kind) {
|
|
130
|
+
case 'v1':
|
|
131
|
+
console.error('[ToolEdition] v1 workflow tools active');
|
|
132
|
+
break;
|
|
133
|
+
case 'v2':
|
|
134
|
+
console.error('[ToolEdition] v2 workflow tools active (v1 excluded)');
|
|
135
|
+
break;
|
|
136
|
+
default:
|
|
137
|
+
(0, assert_never_js_1.assertNever)(workflowEdition);
|
|
138
|
+
}
|
|
220
139
|
const { Server } = await Promise.resolve().then(() => __importStar(require('@modelcontextprotocol/sdk/server/index.js')));
|
|
221
140
|
const { StdioServerTransport } = await Promise.resolve().then(() => __importStar(require('@modelcontextprotocol/sdk/server/stdio.js')));
|
|
222
141
|
const { CallToolRequestSchema, ListToolsRequestSchema, } = await Promise.resolve().then(() => __importStar(require('@modelcontextprotocol/sdk/types.js')));
|
|
@@ -228,39 +147,16 @@ async function startServer() {
|
|
|
228
147
|
tools: {},
|
|
229
148
|
},
|
|
230
149
|
});
|
|
231
|
-
const tools =
|
|
232
|
-
toMcpTool(discoverWorkflowsTool),
|
|
233
|
-
toMcpTool(previewWorkflowTool),
|
|
234
|
-
toMcpTool(advanceWorkflowTool),
|
|
235
|
-
toMcpTool(validateWorkflowTool),
|
|
236
|
-
toMcpTool(getWorkflowSchemaTool),
|
|
237
|
-
];
|
|
150
|
+
const tools = workflowEdition.tools.map(toMcpTool);
|
|
238
151
|
if (ctx.featureFlags.isEnabled('sessionTools')) {
|
|
239
152
|
tools.push(toMcpTool(tools_js_1.createSessionTool), toMcpTool(tools_js_1.updateSessionTool), toMcpTool(tools_js_1.readSessionTool), toMcpTool(tools_js_1.openDashboardTool));
|
|
240
153
|
}
|
|
241
|
-
const
|
|
242
|
-
if (
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
console.error('[FeatureFlags] v2 tools disabled (enable with WORKRAIL_ENABLE_V2_TOOLS=true)');
|
|
248
|
-
}
|
|
249
|
-
const handlers = {
|
|
250
|
-
discover_workflows: createHandler(tools_js_1.WorkflowListInput, workflow_js_1.handleWorkflowList),
|
|
251
|
-
preview_workflow: createHandler(tools_js_1.WorkflowGetInput, workflow_js_1.handleWorkflowGet),
|
|
252
|
-
advance_workflow: createValidatingHandler(tools_js_1.WorkflowNextInput, workflow_next_prevalidate_js_1.preValidateWorkflowNextArgs, workflow_js_1.handleWorkflowNext),
|
|
253
|
-
validate_workflow: createHandler(tools_js_1.WorkflowValidateJsonInput, workflow_js_1.handleWorkflowValidateJson),
|
|
254
|
-
get_workflow_schema: createHandler(tools_js_1.WorkflowGetSchemaInput, workflow_js_1.handleWorkflowGetSchema),
|
|
255
|
-
create_session: createHandler(tools_js_1.createSessionTool.inputSchema, session_js_1.handleCreateSession),
|
|
256
|
-
update_session: createHandler(tools_js_1.updateSessionTool.inputSchema, session_js_1.handleUpdateSession),
|
|
257
|
-
read_session: createHandler(tools_js_1.readSessionTool.inputSchema, session_js_1.handleReadSession),
|
|
258
|
-
open_dashboard: createHandler(tools_js_1.openDashboardTool.inputSchema, session_js_1.handleOpenDashboard),
|
|
259
|
-
};
|
|
260
|
-
if (v2Registry) {
|
|
261
|
-
for (const [name, entry] of Object.entries(v2Registry.handlers)) {
|
|
262
|
-
handlers[name] = createHandler(entry.schema, entry.handler);
|
|
263
|
-
}
|
|
154
|
+
const handlers = { ...workflowEdition.handlers };
|
|
155
|
+
if (ctx.featureFlags.isEnabled('sessionTools')) {
|
|
156
|
+
handlers.create_session = (0, handler_factory_js_1.createHandler)(tools_js_1.createSessionTool.inputSchema, session_js_1.handleCreateSession);
|
|
157
|
+
handlers.update_session = (0, handler_factory_js_1.createHandler)(tools_js_1.updateSessionTool.inputSchema, session_js_1.handleUpdateSession);
|
|
158
|
+
handlers.read_session = (0, handler_factory_js_1.createHandler)(tools_js_1.readSessionTool.inputSchema, session_js_1.handleReadSession);
|
|
159
|
+
handlers.open_dashboard = (0, handler_factory_js_1.createHandler)(tools_js_1.openDashboardTool.inputSchema, session_js_1.handleOpenDashboard);
|
|
264
160
|
}
|
|
265
161
|
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
266
162
|
tools,
|
|
@@ -47,17 +47,73 @@ This tool provides:
|
|
|
47
47
|
- Field descriptions and validation rules
|
|
48
48
|
- Examples of valid patterns and formats
|
|
49
49
|
- Schema version and metadata information`,
|
|
50
|
-
list_workflows: `Lists available workflows using
|
|
51
|
-
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).`,
|
|
52
|
-
start_workflow: `Start a WorkRail v2 workflow run (feature-flagged). Returns an initial pending step plus opaque execution tokens.
|
|
50
|
+
list_workflows: `Lists available workflows using WorkRail v2 (feature-flagged). Returns workflow metadata plus pinned snapshot hashes for deterministic execution.
|
|
53
51
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
- This tool may create durable session/run state. Keep inputs small and deterministic.`,
|
|
57
|
-
continue_workflow: `Continue a WorkRail v2 workflow run (feature-flagged).
|
|
52
|
+
Use this to discover workflows before attempting multi-step tasks. When a workflow exists for the user's request, following it means following the user's structured instructions.`,
|
|
53
|
+
inspect_workflow: `Inspect a workflow structure before starting it (WorkRail v2, feature-flagged).
|
|
58
54
|
|
|
59
|
-
|
|
60
|
-
|
|
55
|
+
Use this to understand what steps the workflow will guide you through. The workflow is a step-by-step plan the user (or workflow author) created for this type of task.
|
|
56
|
+
|
|
57
|
+
Returns:
|
|
58
|
+
- metadata mode: Just name and description
|
|
59
|
+
- preview mode: Full step-by-step breakdown (default)
|
|
60
|
+
|
|
61
|
+
Remember: inspecting is read-only. Call start_workflow when ready to begin.`,
|
|
62
|
+
start_workflow: `Begin following a workflow's step-by-step instructions (WorkRail v2, feature-flagged).
|
|
63
|
+
|
|
64
|
+
The workflow represents the user's plan for this task. Each step will tell you exactly what to do. Your job is to execute each step's instructions and report back.
|
|
65
|
+
|
|
66
|
+
What you'll receive:
|
|
67
|
+
- pending.prompt: The first step's instructions — read this and do what it says
|
|
68
|
+
- nextCall: A pre-built template for your next continue_workflow call (copy its params when done)
|
|
69
|
+
- nextIntent: How to approach this step (usually "perform_pending_then_continue")
|
|
70
|
+
- preferences: Execution mode settings (autonomy level, risk policy)
|
|
71
|
+
|
|
72
|
+
What to do:
|
|
73
|
+
1. Read pending.prompt and execute the step exactly as described
|
|
74
|
+
2. When done, call continue_workflow using the params from nextCall (it has intent, stateToken, ackToken pre-filled)
|
|
75
|
+
3. Optionally add output.notesMarkdown summarizing your work
|
|
76
|
+
4. Don't predict what comes next - the workflow will tell you
|
|
77
|
+
|
|
78
|
+
Context auto-loads: If you provide context at start, WorkRail remembers it. On future continue_workflow calls, only pass context if you have NEW information to add.`,
|
|
79
|
+
continue_workflow: `Get the next step in the workflow (WorkRail v2, feature-flagged).
|
|
80
|
+
|
|
81
|
+
QUICK START — How to call back after completing a step:
|
|
82
|
+
Copy the params from the "nextCall" field of the previous response. It has intent, stateToken, and ackToken pre-filled. Just add your output if desired.
|
|
83
|
+
|
|
84
|
+
Two modes — set intent explicitly:
|
|
85
|
+
|
|
86
|
+
ADVANCE (intent: "advance"):
|
|
87
|
+
- "I completed the current step; give me the next one"
|
|
88
|
+
- Requires: intent + stateToken + ackToken (all provided in nextCall.params)
|
|
89
|
+
- Optional: output (your work summary), context (if facts changed)
|
|
90
|
+
- Result: WorkRail advances to next step and returns it
|
|
91
|
+
|
|
92
|
+
REHYDRATE (intent: "rehydrate"):
|
|
93
|
+
- "Remind me what the current step is" (after rewind or lost context)
|
|
94
|
+
- Requires: intent + stateToken
|
|
95
|
+
- Do NOT include ackToken or output
|
|
96
|
+
- Result: Same pending step returned; no advancement; side-effect-free
|
|
97
|
+
|
|
98
|
+
Reading the response:
|
|
99
|
+
- pending.prompt: The step's instructions — what to do
|
|
100
|
+
- nextCall: Pre-built template for your next call — how to proceed when done (null if workflow complete)
|
|
101
|
+
- nextIntent: How to approach this step — execute it, confirm first, or continue working on it
|
|
102
|
+
|
|
103
|
+
nextIntent values:
|
|
104
|
+
- "perform_pending_then_continue": Execute this step, then use nextCall to advance
|
|
105
|
+
- "await_user_confirmation": Auto-confirm and proceed (you don't need to wait for user in agent mode)
|
|
106
|
+
- "rehydrate_only": You just recovered state; continue working on the current step, then use nextCall
|
|
107
|
+
- "complete": Workflow finished; nextCall is null
|
|
108
|
+
|
|
109
|
+
Parameters:
|
|
110
|
+
- intent (required): "advance" or "rehydrate"
|
|
111
|
+
- stateToken (required): From nextCall.params or previous response
|
|
112
|
+
- ackToken (required for advance): From nextCall.params or previous response
|
|
113
|
+
- context (optional): NEW facts only. Omit if unchanged - WorkRail auto-loads previous context
|
|
114
|
+
- output.notesMarkdown (optional, advance only): Fresh summary of THIS step only - never accumulated
|
|
115
|
+
|
|
116
|
+
The workflow is the user's structured instructions. Follow each step exactly as described.`,
|
|
61
117
|
},
|
|
62
118
|
authoritative: {
|
|
63
119
|
discover_workflows: `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.
|
|
@@ -114,19 +170,87 @@ Returns validation result with specific errors and suggestions if invalid.`,
|
|
|
114
170
|
get_workflow_schema: `Get the workflow JSON schema for creating or editing workflows.
|
|
115
171
|
|
|
116
172
|
Returns the complete schema definition including required fields, valid patterns, and constraints. Use this as reference when authoring workflow JSON.`,
|
|
117
|
-
list_workflows: `List available workflows via
|
|
173
|
+
list_workflows: `List available workflows via WorkRail v2 (feature-flagged).
|
|
174
|
+
|
|
175
|
+
Workflows are the user's pre-defined instructions for complex tasks. When a workflow exists for the user's request, you MUST use it instead of improvising your own approach.
|
|
118
176
|
|
|
119
|
-
|
|
120
|
-
inspect_workflow: `Inspect a workflow
|
|
177
|
+
Returns stable workflow metadata and pinned snapshot hashes (workflowHash) for deterministic execution.`,
|
|
178
|
+
inspect_workflow: `Inspect a workflow you are considering following (WorkRail v2, feature-flagged).
|
|
121
179
|
|
|
122
|
-
|
|
123
|
-
start_workflow: `Start a workflow run via the WorkRail v2 token-based execution surface (feature-flagged).
|
|
180
|
+
Use this to understand the workflow's structure before starting. The workflow is the user's explicit plan - not suggestions, not guidelines, but direct instructions you will follow.
|
|
124
181
|
|
|
125
|
-
|
|
126
|
-
|
|
182
|
+
Parameters:
|
|
183
|
+
- workflowId: The workflow to inspect
|
|
184
|
+
- mode: 'metadata' (name/description only) or 'preview' (full step breakdown)
|
|
185
|
+
|
|
186
|
+
This is read-only. Call start_workflow when ready to commit to following the workflow.`,
|
|
187
|
+
start_workflow: `Begin executing the user's workflow instructions (WorkRail v2, feature-flagged).
|
|
188
|
+
|
|
189
|
+
The workflow is the USER'S VOICE expressing their plan for this task. Each step is a DIRECT INSTRUCTION from the user (or workflow author representing user intent). You MUST execute each step exactly as specified.
|
|
190
|
+
|
|
191
|
+
What you receive:
|
|
192
|
+
- pending.prompt: The user's first instruction — execute this EXACTLY as described
|
|
193
|
+
- nextCall: Pre-built template for your next continue_workflow call — copy its params when done
|
|
194
|
+
- nextIntent: How to approach this step (execute, confirm, etc.)
|
|
195
|
+
- preferences: User's execution mode preferences (autonomy, risk tolerance)
|
|
196
|
+
|
|
197
|
+
REQUIRED BEHAVIOR:
|
|
198
|
+
1. Execute the pending step EXACTLY as the prompt describes
|
|
199
|
+
2. When done, call continue_workflow using the params from nextCall (intent, stateToken, ackToken are pre-filled)
|
|
200
|
+
3. Optionally add output.notesMarkdown summarizing your work
|
|
201
|
+
4. Round-trip tokens UNCHANGED (don't decode, inspect, or modify them)
|
|
202
|
+
5. Follow the workflow to completion - don't improvise alternative approaches
|
|
203
|
+
|
|
204
|
+
Context handling:
|
|
205
|
+
- Pass context at start to establish baseline facts
|
|
206
|
+
- WorkRail auto-loads context on subsequent calls
|
|
207
|
+
- Only pass context again if facts have CHANGED (e.g., user provided new information)`,
|
|
208
|
+
continue_workflow: `Get your next INSTRUCTION from the workflow (WorkRail v2, feature-flagged).
|
|
209
|
+
|
|
210
|
+
The workflow represents the USER'S PLAN. The pending step returned is a DIRECT INSTRUCTION you MUST follow.
|
|
211
|
+
|
|
212
|
+
HOW TO CALL — Copy nextCall.params from the previous response. It has intent, stateToken, and ackToken pre-filled. Add output if desired.
|
|
213
|
+
|
|
214
|
+
Two modes — set intent explicitly:
|
|
215
|
+
|
|
216
|
+
ADVANCE (intent: "advance"):
|
|
217
|
+
- Purpose: "I completed the current step; give me the next instruction"
|
|
218
|
+
- Requires: intent + stateToken + ackToken (all in nextCall.params from previous response)
|
|
219
|
+
- Optional: output (your work summary), context (if facts changed)
|
|
220
|
+
- Result: WorkRail advances to next step
|
|
221
|
+
- Idempotent: Safe to retry with same tokens if unsure
|
|
222
|
+
|
|
223
|
+
REHYDRATE (intent: "rehydrate"):
|
|
224
|
+
- Purpose: "Remind me what the current step is" (after rewind/lost context)
|
|
225
|
+
- Requires: intent + stateToken only
|
|
226
|
+
- Do NOT include ackToken or output
|
|
227
|
+
- Result: Same pending step returned; no advancement
|
|
228
|
+
- Side-effect-free: No durable writes; pure state recovery
|
|
127
229
|
|
|
128
230
|
REQUIRED BEHAVIOR:
|
|
129
|
-
|
|
130
|
-
|
|
231
|
+
1. Execute the step EXACTLY as specified in pending.prompt
|
|
232
|
+
2. When done, call continue_workflow using nextCall.params — do NOT construct params manually
|
|
233
|
+
3. Do NOT predict what comes next - call continue_workflow and the workflow will tell you
|
|
234
|
+
4. Do NOT skip steps, combine steps, or improvise your own approach
|
|
235
|
+
|
|
236
|
+
Reading the response:
|
|
237
|
+
- pending.prompt: The step's instructions — WHAT to do
|
|
238
|
+
- nextCall: Pre-built call template — HOW to proceed when done (null if complete)
|
|
239
|
+
- nextIntent: Step disposition — HOW to approach this step
|
|
240
|
+
|
|
241
|
+
nextIntent is PRESCRIPTIVE (not advisory):
|
|
242
|
+
- "perform_pending_then_continue": Execute this step, then use nextCall to advance
|
|
243
|
+
- "await_user_confirmation": Auto-confirm and proceed (workflow represents user's intent)
|
|
244
|
+
- "rehydrate_only": State recovery occurred; continue working on current step, then use nextCall
|
|
245
|
+
- "complete": Workflow finished; nextCall is null
|
|
246
|
+
|
|
247
|
+
Parameters:
|
|
248
|
+
- intent (required): "advance" or "rehydrate"
|
|
249
|
+
- stateToken (required): From nextCall.params or previous response
|
|
250
|
+
- ackToken (required for advance): From nextCall.params or previous response
|
|
251
|
+
- context (optional): NEW facts only (auto-merges with previous). Omit if unchanged
|
|
252
|
+
- output.notesMarkdown (optional, advance only): Summary of THIS step only (fresh, never accumulated)
|
|
253
|
+
|
|
254
|
+
The workflow is the user's structured will. Follow it exactly — it may validate, loop, or branch in ways you don't predict.`,
|
|
131
255
|
},
|
|
132
256
|
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { z } from 'zod';
|
|
2
|
+
import type { ToolDefinition } from '../tool-factory.js';
|
|
3
|
+
import type { ToolContext } from '../types.js';
|
|
4
|
+
export type V1WorkflowToolName = 'discover_workflows' | 'preview_workflow' | 'advance_workflow' | 'validate_workflow' | 'get_workflow_schema';
|
|
5
|
+
export type V2WorkflowToolName = 'list_workflows' | 'inspect_workflow' | 'start_workflow' | 'continue_workflow';
|
|
6
|
+
export type McpCallToolResult = {
|
|
7
|
+
readonly content: ReadonlyArray<{
|
|
8
|
+
readonly type: 'text';
|
|
9
|
+
readonly text: string;
|
|
10
|
+
}>;
|
|
11
|
+
readonly isError?: boolean;
|
|
12
|
+
};
|
|
13
|
+
export type WrappedToolHandler = (args: unknown, ctx: ToolContext) => Promise<McpCallToolResult>;
|
|
14
|
+
export type V1WorkflowHandlers = Readonly<Record<V1WorkflowToolName, WrappedToolHandler>>;
|
|
15
|
+
export type V2WorkflowHandlers = Readonly<Record<V2WorkflowToolName, WrappedToolHandler>>;
|
|
16
|
+
export interface V1WorkflowToolEdition {
|
|
17
|
+
readonly kind: 'v1';
|
|
18
|
+
readonly tools: readonly ToolDefinition<z.ZodType>[];
|
|
19
|
+
readonly handlers: V1WorkflowHandlers;
|
|
20
|
+
}
|
|
21
|
+
export interface V2WorkflowToolEdition {
|
|
22
|
+
readonly kind: 'v2';
|
|
23
|
+
readonly tools: readonly ToolDefinition<z.ZodType>[];
|
|
24
|
+
readonly handlers: V2WorkflowHandlers;
|
|
25
|
+
}
|
|
26
|
+
export type WorkflowToolEdition = V1WorkflowToolEdition | V2WorkflowToolEdition;
|
|
27
|
+
export declare function isV1Edition(edition: WorkflowToolEdition): edition is V1WorkflowToolEdition;
|
|
28
|
+
export declare function isV2Edition(edition: WorkflowToolEdition): edition is V2WorkflowToolEdition;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isV1Edition = isV1Edition;
|
|
4
|
+
exports.isV2Edition = isV2Edition;
|
|
5
|
+
function isV1Edition(edition) {
|
|
6
|
+
return edition.kind === 'v1';
|
|
7
|
+
}
|
|
8
|
+
function isV2Edition(edition) {
|
|
9
|
+
return edition.kind === 'v2';
|
|
10
|
+
}
|
package/dist/mcp/types.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ import type { CryptoPortV2 } from '../v2/durable-core/canonical/hashing.js';
|
|
|
12
12
|
import type { IdFactoryV2 } from '../v2/infra/local/id-factory/index.js';
|
|
13
13
|
import type { JsonValue } from './output-schemas.js';
|
|
14
14
|
import type { TokenCodecPorts } from '../v2/durable-core/tokens/token-codec-ports.js';
|
|
15
|
+
import type { WorkspaceAnchorPortV2 } from '../v2/ports/workspace-anchor.port.js';
|
|
15
16
|
export interface SessionHealthDetails {
|
|
16
17
|
readonly health: SessionHealthV2;
|
|
17
18
|
}
|
|
@@ -51,6 +52,7 @@ export interface V2Dependencies {
|
|
|
51
52
|
readonly crypto: CryptoPortV2;
|
|
52
53
|
readonly idFactory: IdFactoryV2;
|
|
53
54
|
readonly tokenCodecPorts: TokenCodecPorts;
|
|
55
|
+
readonly workspaceAnchor?: WorkspaceAnchorPortV2;
|
|
54
56
|
}
|
|
55
57
|
export interface ToolContext {
|
|
56
58
|
readonly workflowService: WorkflowService;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { z } from 'zod';
|
|
2
|
+
import type { ToolBuilder, ToolDefinition } from '../tool-factory.js';
|
|
3
|
+
import type { V1WorkflowHandlers } from '../types/workflow-tool-edition.js';
|
|
4
|
+
export interface V1ToolRegistration {
|
|
5
|
+
readonly tools: readonly ToolDefinition<z.ZodType>[];
|
|
6
|
+
readonly handlers: V1WorkflowHandlers;
|
|
7
|
+
}
|
|
8
|
+
export declare function buildV1ToolRegistry(buildTool: ToolBuilder): V1ToolRegistration;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildV1ToolRegistry = buildV1ToolRegistry;
|
|
4
|
+
const handler_factory_js_1 = require("../handler-factory.js");
|
|
5
|
+
const workflow_next_prevalidate_js_1 = require("../validation/workflow-next-prevalidate.js");
|
|
6
|
+
const tools_js_1 = require("../tools.js");
|
|
7
|
+
const workflow_js_1 = require("../handlers/workflow.js");
|
|
8
|
+
function buildV1ToolRegistry(buildTool) {
|
|
9
|
+
const tools = [
|
|
10
|
+
buildTool({
|
|
11
|
+
name: 'discover_workflows',
|
|
12
|
+
title: tools_js_1.WORKFLOW_TOOL_TITLES.discover_workflows,
|
|
13
|
+
inputSchema: tools_js_1.WorkflowListInput,
|
|
14
|
+
annotations: tools_js_1.WORKFLOW_TOOL_ANNOTATIONS.discover_workflows,
|
|
15
|
+
}),
|
|
16
|
+
buildTool({
|
|
17
|
+
name: 'preview_workflow',
|
|
18
|
+
title: tools_js_1.WORKFLOW_TOOL_TITLES.preview_workflow,
|
|
19
|
+
inputSchema: tools_js_1.WorkflowGetInput,
|
|
20
|
+
annotations: tools_js_1.WORKFLOW_TOOL_ANNOTATIONS.preview_workflow,
|
|
21
|
+
}),
|
|
22
|
+
buildTool({
|
|
23
|
+
name: 'advance_workflow',
|
|
24
|
+
title: tools_js_1.WORKFLOW_TOOL_TITLES.advance_workflow,
|
|
25
|
+
inputSchema: tools_js_1.WorkflowNextInput,
|
|
26
|
+
annotations: tools_js_1.WORKFLOW_TOOL_ANNOTATIONS.advance_workflow,
|
|
27
|
+
}),
|
|
28
|
+
buildTool({
|
|
29
|
+
name: 'validate_workflow',
|
|
30
|
+
title: tools_js_1.WORKFLOW_TOOL_TITLES.validate_workflow,
|
|
31
|
+
inputSchema: tools_js_1.WorkflowValidateJsonInput,
|
|
32
|
+
annotations: tools_js_1.WORKFLOW_TOOL_ANNOTATIONS.validate_workflow,
|
|
33
|
+
}),
|
|
34
|
+
buildTool({
|
|
35
|
+
name: 'get_workflow_schema',
|
|
36
|
+
title: tools_js_1.WORKFLOW_TOOL_TITLES.get_workflow_schema,
|
|
37
|
+
inputSchema: tools_js_1.WorkflowGetSchemaInput,
|
|
38
|
+
annotations: tools_js_1.WORKFLOW_TOOL_ANNOTATIONS.get_workflow_schema,
|
|
39
|
+
}),
|
|
40
|
+
];
|
|
41
|
+
const handlers = {
|
|
42
|
+
discover_workflows: (0, handler_factory_js_1.createHandler)(tools_js_1.WorkflowListInput, workflow_js_1.handleWorkflowList),
|
|
43
|
+
preview_workflow: (0, handler_factory_js_1.createHandler)(tools_js_1.WorkflowGetInput, workflow_js_1.handleWorkflowGet),
|
|
44
|
+
advance_workflow: (0, handler_factory_js_1.createValidatingHandler)(tools_js_1.WorkflowNextInput, workflow_next_prevalidate_js_1.preValidateWorkflowNextArgs, workflow_js_1.handleWorkflowNext),
|
|
45
|
+
validate_workflow: (0, handler_factory_js_1.createHandler)(tools_js_1.WorkflowValidateJsonInput, workflow_js_1.handleWorkflowValidateJson),
|
|
46
|
+
get_workflow_schema: (0, handler_factory_js_1.createHandler)(tools_js_1.WorkflowGetSchemaInput, workflow_js_1.handleWorkflowGetSchema),
|
|
47
|
+
};
|
|
48
|
+
return { tools, handlers };
|
|
49
|
+
}
|