@mcpc-tech/core 0.2.0-beta.10
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/LICENSE +21 -0
- package/mod.mjs +2963 -0
- package/package.json +38 -0
- package/plugins.mjs +289 -0
- package/src/plugins/large-result.mjs +290 -0
- package/src/plugins/search-tool.mjs +217 -0
- package/types/mod.d.ts +54 -0
- package/types/mod.d.ts.map +1 -0
- package/types/plugins.d.ts +43 -0
- package/types/plugins.d.ts.map +1 -0
- package/types/src/compose.d.ts +119 -0
- package/types/src/compose.d.ts.map +1 -0
- package/types/src/plugin-types.d.ts +50 -0
- package/types/src/plugin-types.d.ts.map +1 -0
- package/types/src/set-up-mcp-compose.d.ts +68 -0
- package/types/src/set-up-mcp-compose.d.ts.map +1 -0
- package/types/src/types.d.ts +18 -0
- package/types/src/types.d.ts.map +1 -0
package/mod.mjs
ADDED
|
@@ -0,0 +1,2963 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
3
|
+
var __esm = (fn, res) => function __init() {
|
|
4
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
5
|
+
};
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
// ../__mcpc__core_0.2.0-beta.10/node_modules/@mcpc/core/src/plugins/built-in/config-plugin.js
|
|
12
|
+
var createConfigPlugin, config_plugin_default;
|
|
13
|
+
var init_config_plugin = __esm({
|
|
14
|
+
"../__mcpc__core_0.2.0-beta.10/node_modules/@mcpc/core/src/plugins/built-in/config-plugin.js"() {
|
|
15
|
+
createConfigPlugin = () => ({
|
|
16
|
+
name: "built-in-config",
|
|
17
|
+
enforce: "pre",
|
|
18
|
+
transformTool: (tool, context) => {
|
|
19
|
+
const server = context.server;
|
|
20
|
+
const config = server.findToolConfig?.(context.toolName);
|
|
21
|
+
if (config?.description) {
|
|
22
|
+
tool.description = config.description;
|
|
23
|
+
}
|
|
24
|
+
return tool;
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
config_plugin_default = createConfigPlugin();
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
// ../__mcpc__core_0.2.0-beta.10/node_modules/@mcpc/core/src/plugins/built-in/tool-name-mapping-plugin.js
|
|
32
|
+
var createToolNameMappingPlugin, tool_name_mapping_plugin_default;
|
|
33
|
+
var init_tool_name_mapping_plugin = __esm({
|
|
34
|
+
"../__mcpc__core_0.2.0-beta.10/node_modules/@mcpc/core/src/plugins/built-in/tool-name-mapping-plugin.js"() {
|
|
35
|
+
createToolNameMappingPlugin = () => ({
|
|
36
|
+
name: "built-in-tool-name-mapping",
|
|
37
|
+
enforce: "pre",
|
|
38
|
+
transformTool: (tool, context) => {
|
|
39
|
+
const server = context.server;
|
|
40
|
+
const toolName = context.toolName;
|
|
41
|
+
const dotNotation = toolName.replace(/_/g, ".");
|
|
42
|
+
const underscoreNotation = toolName.replace(/\./g, "_");
|
|
43
|
+
if (dotNotation !== toolName && server.toolNameMapping) {
|
|
44
|
+
server.toolNameMapping.set(dotNotation, toolName);
|
|
45
|
+
server.toolNameMapping.set(toolName, dotNotation);
|
|
46
|
+
}
|
|
47
|
+
if (underscoreNotation !== toolName && server.toolNameMapping) {
|
|
48
|
+
server.toolNameMapping.set(underscoreNotation, toolName);
|
|
49
|
+
server.toolNameMapping.set(toolName, underscoreNotation);
|
|
50
|
+
}
|
|
51
|
+
return tool;
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
tool_name_mapping_plugin_default = createToolNameMappingPlugin();
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
// ../__mcpc__core_0.2.0-beta.10/node_modules/@mcpc/core/src/plugins/built-in/logging-plugin.js
|
|
59
|
+
var createLoggingPlugin, logging_plugin_default;
|
|
60
|
+
var init_logging_plugin = __esm({
|
|
61
|
+
"../__mcpc__core_0.2.0-beta.10/node_modules/@mcpc/core/src/plugins/built-in/logging-plugin.js"() {
|
|
62
|
+
createLoggingPlugin = (options = {}) => {
|
|
63
|
+
const { enabled = true, verbose = false, compact: compact2 = true } = options;
|
|
64
|
+
return {
|
|
65
|
+
name: "built-in-logging",
|
|
66
|
+
composeEnd: (context) => {
|
|
67
|
+
if (!enabled) return;
|
|
68
|
+
if (compact2) {
|
|
69
|
+
const pluginCount = context.pluginNames.length;
|
|
70
|
+
const server = context.server;
|
|
71
|
+
const externalList = server.getExternalToolNames();
|
|
72
|
+
const internalList = server.getInternalToolNames();
|
|
73
|
+
const hiddenList = server.getHiddenToolNames();
|
|
74
|
+
const publicToolNames = server.getPublicToolNames();
|
|
75
|
+
const externalCount = externalList.length;
|
|
76
|
+
const internalCount = internalList.length;
|
|
77
|
+
const hiddenCount = hiddenList.length;
|
|
78
|
+
const globalCount = publicToolNames.length;
|
|
79
|
+
console.log(`\u{1F9E9} [${context.toolName}] ${pluginCount} plugins \u2022 ${externalCount} external \u2022 ${internalCount} internal \u2022 ${hiddenCount} hidden \u2022 ${globalCount} global`);
|
|
80
|
+
} else if (verbose) {
|
|
81
|
+
console.log(`\u{1F9E9} [${context.toolName}]`);
|
|
82
|
+
console.log(` \u251C\u2500 Plugins: ${context.pluginNames.join(", ")}`);
|
|
83
|
+
const server = context.server;
|
|
84
|
+
const globalToolNames = Array.from(new Set(server.getPublicToolNames().map(String)));
|
|
85
|
+
const external = Array.from(new Set(server.getExternalToolNames().map(String)));
|
|
86
|
+
const internal = Array.from(new Set(server.getInternalToolNames().map(String)));
|
|
87
|
+
const hidden = Array.from(new Set(server.getHiddenToolNames().map(String)));
|
|
88
|
+
const globalNames = globalToolNames.map(String);
|
|
89
|
+
const totalSet = /* @__PURE__ */ new Set([
|
|
90
|
+
...external,
|
|
91
|
+
...internal,
|
|
92
|
+
...globalNames
|
|
93
|
+
]);
|
|
94
|
+
const totalList = Array.from(totalSet);
|
|
95
|
+
if (external.length > 0) {
|
|
96
|
+
console.log(` \u251C\u2500 External: ${external.join(", ")}`);
|
|
97
|
+
}
|
|
98
|
+
if (internal.length > 0) {
|
|
99
|
+
console.log(` \u251C\u2500 Internal: ${internal.join(", ")}`);
|
|
100
|
+
}
|
|
101
|
+
if (globalNames.length > 0) {
|
|
102
|
+
console.log(` \u251C\u2500 Global: ${globalNames.join(", ")}`);
|
|
103
|
+
}
|
|
104
|
+
if (hidden.length > 0) {
|
|
105
|
+
console.log(` \u251C\u2500 Hidden: ${hidden.join(", ")}`);
|
|
106
|
+
}
|
|
107
|
+
if (totalList.length > 0) {
|
|
108
|
+
console.log(` \u2514\u2500 Total: ${totalList.length} tools`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
};
|
|
114
|
+
logging_plugin_default = createLoggingPlugin({
|
|
115
|
+
verbose: true,
|
|
116
|
+
compact: false
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
// ../__mcpc__core_0.2.0-beta.10/node_modules/@mcpc/core/src/plugins/built-in/index.js
|
|
122
|
+
var built_in_exports = {};
|
|
123
|
+
__export(built_in_exports, {
|
|
124
|
+
createConfigPlugin: () => createConfigPlugin,
|
|
125
|
+
createLoggingPlugin: () => createLoggingPlugin,
|
|
126
|
+
createToolNameMappingPlugin: () => createToolNameMappingPlugin,
|
|
127
|
+
getBuiltInPlugins: () => getBuiltInPlugins
|
|
128
|
+
});
|
|
129
|
+
function getBuiltInPlugins() {
|
|
130
|
+
return [
|
|
131
|
+
tool_name_mapping_plugin_default,
|
|
132
|
+
config_plugin_default,
|
|
133
|
+
logging_plugin_default
|
|
134
|
+
];
|
|
135
|
+
}
|
|
136
|
+
var init_built_in = __esm({
|
|
137
|
+
"../__mcpc__core_0.2.0-beta.10/node_modules/@mcpc/core/src/plugins/built-in/index.js"() {
|
|
138
|
+
init_config_plugin();
|
|
139
|
+
init_tool_name_mapping_plugin();
|
|
140
|
+
init_logging_plugin();
|
|
141
|
+
init_config_plugin();
|
|
142
|
+
init_tool_name_mapping_plugin();
|
|
143
|
+
init_logging_plugin();
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
// ../__mcpc__core_0.2.0-beta.10/node_modules/@mcpc/core/src/compose.js
|
|
148
|
+
import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
|
|
149
|
+
import { jsonSchema as jsonSchema3 } from "ai";
|
|
150
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
151
|
+
|
|
152
|
+
// ../__mcpc__core_0.2.0-beta.10/node_modules/@jsr/mcpc__utils/src/json.js
|
|
153
|
+
import { jsonrepair } from "jsonrepair";
|
|
154
|
+
function parseJSON(text, throwError) {
|
|
155
|
+
try {
|
|
156
|
+
return JSON.parse(text);
|
|
157
|
+
} catch (_error) {
|
|
158
|
+
try {
|
|
159
|
+
const repairedText = jsonrepair(text);
|
|
160
|
+
console.warn(`Failed to parse JSON, attempting to repair, result: ${text}`);
|
|
161
|
+
if (throwError) {
|
|
162
|
+
throw _error;
|
|
163
|
+
}
|
|
164
|
+
return JSON.parse(repairedText);
|
|
165
|
+
} catch {
|
|
166
|
+
if (throwError) {
|
|
167
|
+
throw new Error("Failed to parse repaired JSON");
|
|
168
|
+
}
|
|
169
|
+
return null;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// ../__mcpc__core_0.2.0-beta.10/node_modules/@jsr/mcpc__utils/src/ai.js
|
|
175
|
+
var p = (template, options = {}) => {
|
|
176
|
+
const { missingVariableHandling = "warn" } = options;
|
|
177
|
+
const names = /* @__PURE__ */ new Set();
|
|
178
|
+
const regex = /\{((\w|\.)+)\}/g;
|
|
179
|
+
let match;
|
|
180
|
+
while ((match = regex.exec(template)) !== null) {
|
|
181
|
+
names.add(match[1]);
|
|
182
|
+
}
|
|
183
|
+
const required = Array.from(names);
|
|
184
|
+
return (input) => {
|
|
185
|
+
let result = template;
|
|
186
|
+
for (const name of required) {
|
|
187
|
+
const key = name;
|
|
188
|
+
const value = input[key];
|
|
189
|
+
const re = new RegExp(`\\{${String(name)}\\}`, "g");
|
|
190
|
+
if (value !== void 0 && value !== null) {
|
|
191
|
+
result = result.replace(re, String(value));
|
|
192
|
+
} else {
|
|
193
|
+
switch (missingVariableHandling) {
|
|
194
|
+
case "error":
|
|
195
|
+
throw new Error(`Missing variable "${String(name)}" in input for template.`);
|
|
196
|
+
case "empty":
|
|
197
|
+
result = result.replace(re, "");
|
|
198
|
+
break;
|
|
199
|
+
case "warn":
|
|
200
|
+
case "ignore":
|
|
201
|
+
default:
|
|
202
|
+
break;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return result;
|
|
207
|
+
};
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
// ../__mcpc__core_0.2.0-beta.10/node_modules/@jsr/mcpc__utils/src/tool-tags.js
|
|
211
|
+
import { load } from "cheerio";
|
|
212
|
+
function parseTags(htmlString, tags) {
|
|
213
|
+
const $ = load(htmlString, {
|
|
214
|
+
xml: {
|
|
215
|
+
decodeEntities: false
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
const tagToResults = {};
|
|
219
|
+
for (const tag of tags) {
|
|
220
|
+
const elements = $(tag);
|
|
221
|
+
tagToResults[tag] = elements.toArray();
|
|
222
|
+
}
|
|
223
|
+
return {
|
|
224
|
+
tagToResults,
|
|
225
|
+
$
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// ../__mcpc__core_0.2.0-beta.10/node_modules/@jsr/mcpc__utils/src/transport/sse.js
|
|
230
|
+
import { JSONRPCMessageSchema } from "@modelcontextprotocol/sdk/types.js";
|
|
231
|
+
|
|
232
|
+
// ../__mcpc__core_0.2.0-beta.10/node_modules/@jsr/std__http/server_sent_event_stream.js
|
|
233
|
+
var NEWLINE_REGEXP = /\r\n|\r|\n/;
|
|
234
|
+
var encoder = new TextEncoder();
|
|
235
|
+
function assertHasNoNewline(value, varName, errPrefix) {
|
|
236
|
+
if (value.match(NEWLINE_REGEXP) !== null) {
|
|
237
|
+
throw new SyntaxError(`${errPrefix}: ${varName} cannot contain a newline`);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
function stringify(message) {
|
|
241
|
+
const lines = [];
|
|
242
|
+
if (message.comment) {
|
|
243
|
+
assertHasNoNewline(message.comment, "`message.comment`", "Cannot serialize message");
|
|
244
|
+
lines.push(`:${message.comment}`);
|
|
245
|
+
}
|
|
246
|
+
if (message.event) {
|
|
247
|
+
assertHasNoNewline(message.event, "`message.event`", "Cannot serialize message");
|
|
248
|
+
lines.push(`event:${message.event}`);
|
|
249
|
+
}
|
|
250
|
+
if (message.data) {
|
|
251
|
+
message.data.split(NEWLINE_REGEXP).forEach((line) => lines.push(`data:${line}`));
|
|
252
|
+
}
|
|
253
|
+
if (message.id) {
|
|
254
|
+
assertHasNoNewline(message.id.toString(), "`message.id`", "Cannot serialize message");
|
|
255
|
+
lines.push(`id:${message.id}`);
|
|
256
|
+
}
|
|
257
|
+
if (message.retry) lines.push(`retry:${message.retry}`);
|
|
258
|
+
return encoder.encode(lines.join("\n") + "\n\n");
|
|
259
|
+
}
|
|
260
|
+
var ServerSentEventStream = class extends TransformStream {
|
|
261
|
+
constructor() {
|
|
262
|
+
super({
|
|
263
|
+
transform: (message, controller) => {
|
|
264
|
+
controller.enqueue(stringify(message));
|
|
265
|
+
}
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
// ../__mcpc__core_0.2.0-beta.10/node_modules/@mcpc/core/src/utils/common/mcp.js
|
|
271
|
+
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
272
|
+
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
|
|
273
|
+
import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
|
|
274
|
+
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
275
|
+
|
|
276
|
+
// ../__mcpc__core_0.2.0-beta.10/node_modules/@mcpc/core/src/utils/common/registory.js
|
|
277
|
+
function connectToSmitheryServer(smitheryConfig) {
|
|
278
|
+
const serverUrl = new URL(smitheryConfig.deploymentUrl);
|
|
279
|
+
serverUrl.searchParams.set("config", btoa(JSON.stringify(smitheryConfig.config)));
|
|
280
|
+
serverUrl.searchParams.set("api_key", smitheryConfig?.smitheryApiKey ?? smitheryConfig?.config?.smitheryApiKey);
|
|
281
|
+
return {
|
|
282
|
+
url: serverUrl.toString()
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
function smitheryToolNameCompatibale(name, scope) {
|
|
286
|
+
if (!name.startsWith("toolbox_")) {
|
|
287
|
+
return {
|
|
288
|
+
toolNameWithScope: `${scope}.${name}`,
|
|
289
|
+
toolName: name
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
const [, ...toolNames] = name.split("_");
|
|
293
|
+
const toolName = toolNames.join("_");
|
|
294
|
+
const toolNameWithScope = `${scope}.${toolName}`;
|
|
295
|
+
return {
|
|
296
|
+
toolNameWithScope,
|
|
297
|
+
toolName
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// ../__mcpc__core_0.2.0-beta.10/node_modules/@mcpc/core/src/utils/common/mcp.js
|
|
302
|
+
import { cwd } from "node:process";
|
|
303
|
+
import process2 from "node:process";
|
|
304
|
+
import { createHash } from "node:crypto";
|
|
305
|
+
var mcpClientPool = /* @__PURE__ */ new Map();
|
|
306
|
+
var mcpClientConnecting = /* @__PURE__ */ new Map();
|
|
307
|
+
var shortHash = (s) => createHash("sha256").update(s).digest("hex").slice(0, 8);
|
|
308
|
+
function defSignature(def) {
|
|
309
|
+
return JSON.stringify(def);
|
|
310
|
+
}
|
|
311
|
+
async function getOrCreateMcpClient(defKey, def) {
|
|
312
|
+
const pooled = mcpClientPool.get(defKey);
|
|
313
|
+
if (pooled) {
|
|
314
|
+
pooled.refCount += 1;
|
|
315
|
+
return pooled.client;
|
|
316
|
+
}
|
|
317
|
+
const existingConnecting = mcpClientConnecting.get(defKey);
|
|
318
|
+
if (existingConnecting) {
|
|
319
|
+
const client = await existingConnecting;
|
|
320
|
+
const entry = mcpClientPool.get(defKey);
|
|
321
|
+
if (entry) entry.refCount += 1;
|
|
322
|
+
return client;
|
|
323
|
+
}
|
|
324
|
+
let transport;
|
|
325
|
+
if (typeof def.transportType === "string" && def.transportType === "sse") {
|
|
326
|
+
const options = {};
|
|
327
|
+
if (def.headers) {
|
|
328
|
+
options.requestInit = {
|
|
329
|
+
headers: def.headers
|
|
330
|
+
};
|
|
331
|
+
options.eventSourceInit = {
|
|
332
|
+
headers: def.headers
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
transport = new SSEClientTransport(new URL(def.url), options);
|
|
336
|
+
} else if ("url" in def && typeof def.url === "string") {
|
|
337
|
+
const options = {};
|
|
338
|
+
if (def.headers) {
|
|
339
|
+
options.requestInit = {
|
|
340
|
+
headers: def.headers
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
transport = new StreamableHTTPClientTransport(new URL(def.url), options);
|
|
344
|
+
} else if (typeof def.transportType === "string" && def.transportType === "stdio" || "command" in def) {
|
|
345
|
+
transport = new StdioClientTransport({
|
|
346
|
+
command: def.command,
|
|
347
|
+
args: def.args,
|
|
348
|
+
env: {
|
|
349
|
+
...process2.env,
|
|
350
|
+
...def.env ?? {}
|
|
351
|
+
},
|
|
352
|
+
cwd: cwd()
|
|
353
|
+
});
|
|
354
|
+
} else {
|
|
355
|
+
throw new Error(`Unsupported transport type: ${JSON.stringify(def)}`);
|
|
356
|
+
}
|
|
357
|
+
const connecting = (async () => {
|
|
358
|
+
const client = new Client({
|
|
359
|
+
name: `mcp_${shortHash(defSignature(def))}`,
|
|
360
|
+
version: "1.0.0"
|
|
361
|
+
});
|
|
362
|
+
await client.connect(transport, {
|
|
363
|
+
timeout: 6e4 * 10
|
|
364
|
+
});
|
|
365
|
+
return client;
|
|
366
|
+
})();
|
|
367
|
+
mcpClientConnecting.set(defKey, connecting);
|
|
368
|
+
try {
|
|
369
|
+
const client = await connecting;
|
|
370
|
+
mcpClientPool.set(defKey, {
|
|
371
|
+
client,
|
|
372
|
+
refCount: 1
|
|
373
|
+
});
|
|
374
|
+
return client;
|
|
375
|
+
} finally {
|
|
376
|
+
mcpClientConnecting.delete(defKey);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
async function releaseMcpClient(defKey) {
|
|
380
|
+
const entry = mcpClientPool.get(defKey);
|
|
381
|
+
if (!entry) return;
|
|
382
|
+
entry.refCount -= 1;
|
|
383
|
+
if (entry.refCount <= 0) {
|
|
384
|
+
mcpClientPool.delete(defKey);
|
|
385
|
+
try {
|
|
386
|
+
await entry.client.close();
|
|
387
|
+
} catch (err) {
|
|
388
|
+
console.error("Error closing MCP client:", err);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
var cleanupAllPooledClients = async () => {
|
|
393
|
+
const entries = Array.from(mcpClientPool.entries());
|
|
394
|
+
mcpClientPool.clear();
|
|
395
|
+
await Promise.all(entries.map(async ([, { client }]) => {
|
|
396
|
+
try {
|
|
397
|
+
await client.close();
|
|
398
|
+
} catch (err) {
|
|
399
|
+
console.error("Error closing MCP client:", err);
|
|
400
|
+
}
|
|
401
|
+
}));
|
|
402
|
+
};
|
|
403
|
+
process2.once?.("exit", () => {
|
|
404
|
+
cleanupAllPooledClients();
|
|
405
|
+
});
|
|
406
|
+
process2.once?.("SIGINT", () => {
|
|
407
|
+
cleanupAllPooledClients().finally(() => process2.exit(0));
|
|
408
|
+
});
|
|
409
|
+
async function composeMcpDepTools(mcpConfig, filterIn) {
|
|
410
|
+
const allTools = {};
|
|
411
|
+
const allClients = {};
|
|
412
|
+
const acquiredKeys = [];
|
|
413
|
+
for (const [name, definition] of Object.entries(mcpConfig.mcpServers)) {
|
|
414
|
+
const def = definition;
|
|
415
|
+
if (def.disabled) continue;
|
|
416
|
+
const defKey = shortHash(defSignature(def));
|
|
417
|
+
const serverId = name;
|
|
418
|
+
try {
|
|
419
|
+
const client = await getOrCreateMcpClient(defKey, def);
|
|
420
|
+
acquiredKeys.push(defKey);
|
|
421
|
+
allClients[serverId] = client;
|
|
422
|
+
const { tools } = await client.listTools();
|
|
423
|
+
tools.forEach((tool) => {
|
|
424
|
+
const { toolNameWithScope, toolName: internalToolName } = smitheryToolNameCompatibale(tool.name, name);
|
|
425
|
+
const toolId = `${serverId}_${internalToolName}`;
|
|
426
|
+
if (filterIn && !filterIn({
|
|
427
|
+
action: internalToolName,
|
|
428
|
+
tool,
|
|
429
|
+
mcpName: name,
|
|
430
|
+
toolNameWithScope,
|
|
431
|
+
internalToolName,
|
|
432
|
+
toolId
|
|
433
|
+
})) {
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
436
|
+
const execute = (args) => allClients[serverId].callTool({
|
|
437
|
+
name: internalToolName,
|
|
438
|
+
arguments: args
|
|
439
|
+
}, void 0, {
|
|
440
|
+
timeout: def.toolCallTimeout
|
|
441
|
+
});
|
|
442
|
+
allTools[toolId] = {
|
|
443
|
+
...tool,
|
|
444
|
+
execute
|
|
445
|
+
};
|
|
446
|
+
});
|
|
447
|
+
} catch (error) {
|
|
448
|
+
console.error(`Error creating MCP client for ${name}:`, error);
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
const cleanupClients = async () => {
|
|
452
|
+
await Promise.all(acquiredKeys.map((k) => releaseMcpClient(k)));
|
|
453
|
+
acquiredKeys.length = 0;
|
|
454
|
+
Object.keys(allTools).forEach((key) => delete allTools[key]);
|
|
455
|
+
Object.keys(allClients).forEach((key) => delete allClients[key]);
|
|
456
|
+
};
|
|
457
|
+
return {
|
|
458
|
+
tools: allTools,
|
|
459
|
+
clients: allClients,
|
|
460
|
+
cleanupClients
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
// ../__mcpc__core_0.2.0-beta.10/node_modules/@mcpc/core/src/utils/common/schema.js
|
|
465
|
+
import traverse from "json-schema-traverse";
|
|
466
|
+
function updateRefPaths(schema, wrapperPath) {
|
|
467
|
+
if (!schema || typeof schema !== "object") {
|
|
468
|
+
return schema;
|
|
469
|
+
}
|
|
470
|
+
if (!wrapperPath || typeof wrapperPath !== "string") {
|
|
471
|
+
throw new Error("wrapperPath must be a non-empty string");
|
|
472
|
+
}
|
|
473
|
+
const clonedSchema = JSON.parse(JSON.stringify(schema));
|
|
474
|
+
try {
|
|
475
|
+
traverse(clonedSchema, {
|
|
476
|
+
allKeys: true,
|
|
477
|
+
cb: function(schemaNode, _jsonPtr, _rootSchema, _parentJsonPtr, _parentKeyword, _parentSchema, _keyIndex) {
|
|
478
|
+
if (schemaNode && typeof schemaNode === "object" && schemaNode.$ref) {
|
|
479
|
+
const ref = schemaNode.$ref;
|
|
480
|
+
if (ref.startsWith("#/properties/")) {
|
|
481
|
+
const relativePath = ref.substring(13);
|
|
482
|
+
schemaNode.$ref = `#/properties/${wrapperPath}/properties/${relativePath}`;
|
|
483
|
+
} else if (ref === "#") {
|
|
484
|
+
schemaNode.$ref = `#/properties/${wrapperPath}`;
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
});
|
|
489
|
+
} catch (error) {
|
|
490
|
+
console.warn(`Failed to traverse schema for path "${wrapperPath}":`, error);
|
|
491
|
+
return clonedSchema;
|
|
492
|
+
}
|
|
493
|
+
return clonedSchema;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
// ../__mcpc__core_0.2.0-beta.10/node_modules/@mcpc/core/src/executors/agentic/agentic-tool-registrar.js
|
|
497
|
+
import { jsonSchema } from "ai";
|
|
498
|
+
|
|
499
|
+
// ../__mcpc__core_0.2.0-beta.10/node_modules/@mcpc/core/src/utils/common/config.js
|
|
500
|
+
import process3 from "node:process";
|
|
501
|
+
var GEMINI_PREFERRED_FORMAT = process3.env.GEMINI_PREFERRED_FORMAT === "0" ? false : true;
|
|
502
|
+
|
|
503
|
+
// ../__mcpc__core_0.2.0-beta.10/node_modules/@mcpc/core/src/utils/common/json.js
|
|
504
|
+
import { jsonrepair as jsonrepair2 } from "jsonrepair";
|
|
505
|
+
import { inspect } from "node:util";
|
|
506
|
+
function parseJSON2(text, throwError) {
|
|
507
|
+
try {
|
|
508
|
+
return JSON.parse(text);
|
|
509
|
+
} catch (_error) {
|
|
510
|
+
try {
|
|
511
|
+
const repairedText = jsonrepair2(text);
|
|
512
|
+
console.warn(`Failed to parse JSON, attempting to repair, result: ${text}`);
|
|
513
|
+
if (throwError) {
|
|
514
|
+
throw _error;
|
|
515
|
+
}
|
|
516
|
+
return JSON.parse(repairedText);
|
|
517
|
+
} catch {
|
|
518
|
+
if (throwError) {
|
|
519
|
+
throw new Error("Failed to parse repaired JSON");
|
|
520
|
+
}
|
|
521
|
+
return null;
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
function truncateJSON(obj) {
|
|
526
|
+
return inspect(obj, {
|
|
527
|
+
depth: 3,
|
|
528
|
+
colors: false,
|
|
529
|
+
maxStringLength: 120
|
|
530
|
+
});
|
|
531
|
+
}
|
|
532
|
+
function optionalObject(obj, condition) {
|
|
533
|
+
if (condition) {
|
|
534
|
+
return obj;
|
|
535
|
+
}
|
|
536
|
+
return {};
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
// ../__mcpc__core_0.2.0-beta.10/node_modules/@mcpc/core/src/utils/common/provider.js
|
|
540
|
+
var createGoogleCompatibleJSONSchema = (schema) => {
|
|
541
|
+
if (!GEMINI_PREFERRED_FORMAT) {
|
|
542
|
+
return schema;
|
|
543
|
+
}
|
|
544
|
+
const { oneOf: _oneOf, allOf: _allOf, anyOf: _anyOf, ...cleanSchema } = schema;
|
|
545
|
+
const removeAdditionalProperties = (obj) => {
|
|
546
|
+
if (Array.isArray(obj)) {
|
|
547
|
+
return obj.map(removeAdditionalProperties);
|
|
548
|
+
}
|
|
549
|
+
if (obj && typeof obj === "object") {
|
|
550
|
+
const result = {};
|
|
551
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
552
|
+
if (key !== "additionalProperties") {
|
|
553
|
+
result[key] = removeAdditionalProperties(value);
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
return result;
|
|
557
|
+
}
|
|
558
|
+
return obj;
|
|
559
|
+
};
|
|
560
|
+
return removeAdditionalProperties(cleanSchema);
|
|
561
|
+
};
|
|
562
|
+
|
|
563
|
+
// ../__mcpc__core_0.2.0-beta.10/node_modules/@mcpc/core/src/prompts/index.js
|
|
564
|
+
var SystemPrompts = {
|
|
565
|
+
/**
|
|
566
|
+
* Base system prompt for autonomous MCP execution
|
|
567
|
+
*/
|
|
568
|
+
AUTONOMOUS_EXECUTION: `Autonomous AI Agent \`{toolName}\` that answers user questions through iterative self-invocation and collecting feedback.
|
|
569
|
+
|
|
570
|
+
<instructions>{description}</instructions>
|
|
571
|
+
|
|
572
|
+
## Execution Rules
|
|
573
|
+
1. **Follow instructions above** carefully
|
|
574
|
+
2. **Answer user question** as primary goal
|
|
575
|
+
3. **Execute** one action per call
|
|
576
|
+
4. **Collect feedback** from each action result
|
|
577
|
+
5. **Decide** next step:
|
|
578
|
+
- **proceed**: More work needed
|
|
579
|
+
- **complete**: Question answered
|
|
580
|
+
- **retry**: Current action failed
|
|
581
|
+
6. **Provide** parameter object matching action name
|
|
582
|
+
7. **Continue** until complete
|
|
583
|
+
|
|
584
|
+
## Call Format
|
|
585
|
+
\`\`\`json
|
|
586
|
+
{
|
|
587
|
+
"action": "tool_name",
|
|
588
|
+
"decision": "proceed|retry|complete",
|
|
589
|
+
"tool_name": { /* tool parameters */ }
|
|
590
|
+
}
|
|
591
|
+
\`\`\``,
|
|
592
|
+
/**
|
|
593
|
+
* Workflow execution system prompt
|
|
594
|
+
*/
|
|
595
|
+
WORKFLOW_EXECUTION: `Agentic workflow execution tool \`{toolName}\` that processes requests through structured multi-step workflows.
|
|
596
|
+
|
|
597
|
+
<instructions>{description}</instructions>
|
|
598
|
+
|
|
599
|
+
## Workflow Execution Protocol
|
|
600
|
+
|
|
601
|
+
**\u{1F3AF} FIRST CALL (Planning):**
|
|
602
|
+
{planningInstructions}
|
|
603
|
+
|
|
604
|
+
**\u26A1 SUBSEQUENT CALLS (Execution):**
|
|
605
|
+
- Provide ONLY current step parameters
|
|
606
|
+
- **ADVANCE STEP**: Set \`decision: "proceed"\` to move to next step
|
|
607
|
+
- **RETRY STEP**: Set \`decision: "retry"\`
|
|
608
|
+
- **COMPLETE WORKFLOW**: Set \`decision: "complete"\` when ready to finish
|
|
609
|
+
|
|
610
|
+
**\u{1F6AB} Do NOT include \`steps\` parameter during normal execution**
|
|
611
|
+
**\u2705 Include \`steps\` parameter ONLY when restarting workflow with \`init: true\`**
|
|
612
|
+
**\u26A0\uFE0F CRITICAL: When retrying failed steps, MUST use \`decision: "retry"\`**`,
|
|
613
|
+
/**
|
|
614
|
+
* JSON-only execution system prompt
|
|
615
|
+
*/
|
|
616
|
+
SAMPLING_EXECUTION: `Autonomous AI Agent \`{toolName}\` that answers user questions by iteratively collecting feedback and adapting your approach.
|
|
617
|
+
|
|
618
|
+
<instructions>{description}</instructions>
|
|
619
|
+
|
|
620
|
+
## Execution Rules
|
|
621
|
+
- Respond with valid JSON only
|
|
622
|
+
- **Follow instructions above** carefully
|
|
623
|
+
- **Answer user question** as primary goal
|
|
624
|
+
- **Collect feedback** from each action result
|
|
625
|
+
- **Adapt approach** based on gathered information
|
|
626
|
+
- action = "X" \u2192 provide parameter "X"
|
|
627
|
+
- Continue until question answered
|
|
628
|
+
|
|
629
|
+
## JSON Response Format
|
|
630
|
+
\`\`\`json
|
|
631
|
+
{
|
|
632
|
+
"action": "tool_name",
|
|
633
|
+
"decision": "proceed|retry|complete",
|
|
634
|
+
"tool_name": { /* tool parameters */ }
|
|
635
|
+
}
|
|
636
|
+
\`\`\`
|
|
637
|
+
|
|
638
|
+
## Available Tools
|
|
639
|
+
{toolList}`,
|
|
640
|
+
/**
|
|
641
|
+
* Sampling workflow execution system prompt combining sampling with workflow capabilities
|
|
642
|
+
*/
|
|
643
|
+
SAMPLING_WORKFLOW_EXECUTION: `You are an autonomous AI Agent named \`{toolName}\` that processes instructions through iterative sampling execution within structured workflows.
|
|
644
|
+
|
|
645
|
+
<instructions>{description}</instructions>
|
|
646
|
+
|
|
647
|
+
## Agentic Sampling Workflow Protocol
|
|
648
|
+
|
|
649
|
+
**\u{1F9E0} AGENTIC REASONING (First Call - Workflow Planning):**
|
|
650
|
+
1. **Autonomous Analysis:** Independently analyze the user's instruction and identify the end goal
|
|
651
|
+
2. **Workflow Design:** Autonomously design a structured workflow with clear steps
|
|
652
|
+
3. **Tool Mapping:** Determine which tools are needed for each workflow step
|
|
653
|
+
4. **Initialization:** Start the workflow with proper step definitions
|
|
654
|
+
|
|
655
|
+
**\u26A1 AGENTIC EXECUTION RULES (Subsequent Calls):**
|
|
656
|
+
- Each response demonstrates autonomous reasoning and decision-making within workflow context
|
|
657
|
+
- Make self-directed choices about step execution, retry, or advancement
|
|
658
|
+
- Adapt your approach based on previous step results without external guidance
|
|
659
|
+
- Balance workflow structure with autonomous flexibility
|
|
660
|
+
|
|
661
|
+
**\u{1F504} JSON Response Format (Agentic Workflow Decision Output):**
|
|
662
|
+
You MUST respond with a JSON object for workflow execution:
|
|
663
|
+
|
|
664
|
+
**For Workflow Initialization (First Call):**
|
|
665
|
+
- action: "{toolName}"
|
|
666
|
+
- init: true
|
|
667
|
+
- steps: Autonomously designed workflow steps array
|
|
668
|
+
- [other workflow parameters]: As you autonomously determine
|
|
669
|
+
|
|
670
|
+
**For Step Execution (Subsequent Calls):**
|
|
671
|
+
- action: "{toolName}"
|
|
672
|
+
- decision: "proceed" (advance), "retry" (retry), or "complete" (finish - sampling mode only)
|
|
673
|
+
- [step parameters]: Tool-specific parameters you autonomously determine for current step
|
|
674
|
+
|
|
675
|
+
**\u{1F3AF} AGENTIC WORKFLOW CONSTRAINTS:**
|
|
676
|
+
- Response must be pure JSON demonstrating autonomous decision-making within workflow structure
|
|
677
|
+
- Invalid JSON indicates failure in agentic workflow reasoning
|
|
678
|
+
- Tool parameters must reflect your independent analysis and workflow planning
|
|
679
|
+
- Balance autonomous decision-making with structured workflow progression
|
|
680
|
+
|
|
681
|
+
**\u{1F6AB} Do NOT include \`steps\` parameter during normal execution**
|
|
682
|
+
**\u2705 Include \`steps\` parameter ONLY when restarting workflow with \`init: true\`**
|
|
683
|
+
**\u26A0\uFE0F CRITICAL: When retrying failed steps, MUST use \`decision: "retry"\`**`
|
|
684
|
+
};
|
|
685
|
+
var WorkflowPrompts = {
|
|
686
|
+
/**
|
|
687
|
+
* Workflow initialization instructions
|
|
688
|
+
*/
|
|
689
|
+
WORKFLOW_INIT: `Workflow initialized with {stepCount} steps. Agent MUST start the workflow with the first step to \`{currentStepDescription}\`.
|
|
690
|
+
|
|
691
|
+
## EXECUTE tool \`{toolName}\` with the following new parameter definition
|
|
692
|
+
|
|
693
|
+
{schemaDefinition}
|
|
694
|
+
|
|
695
|
+
## Important Instructions
|
|
696
|
+
- **Include 'steps' parameter ONLY when restarting workflow (with 'init: true')**
|
|
697
|
+
- **Do NOT include 'steps' parameter during normal step execution**
|
|
698
|
+
- **MUST Use the provided JSON schema definition above for parameter generation and validation**
|
|
699
|
+
- **ADVANCE STEP: Set 'decision' to "proceed" to advance to next step**
|
|
700
|
+
- **RETRY STEP: Set 'decision' to "retry" to re-execute current step**
|
|
701
|
+
- **FINAL STEP: Execute normally for workflow completion, do NOT use 'decision: complete' unless workflow is truly finished**
|
|
702
|
+
- **\u26A0\uFE0F CRITICAL: When retrying failed steps, MUST set 'decision' to "retry"**
|
|
703
|
+
- **\u26A0\uFE0F CRITICAL: Only use 'decision: complete' when the entire workflow has been successfully executed**
|
|
704
|
+
|
|
705
|
+
{workflowSteps}`,
|
|
706
|
+
/**
|
|
707
|
+
* Tool description enhancement for workflow mode
|
|
708
|
+
*/
|
|
709
|
+
WORKFLOW_TOOL_DESCRIPTION: `{description}
|
|
710
|
+
{initTitle}
|
|
711
|
+
{ensureStepActions}
|
|
712
|
+
{schemaDefinition}`,
|
|
713
|
+
/**
|
|
714
|
+
* Planning instructions for predefined workflows
|
|
715
|
+
*/
|
|
716
|
+
PREDEFINED_WORKFLOW_PLANNING: `- Set \`init: true\` (steps are predefined)`,
|
|
717
|
+
/**
|
|
718
|
+
* Planning instructions for dynamic workflows
|
|
719
|
+
*/
|
|
720
|
+
DYNAMIC_WORKFLOW_PLANNING: `- Set \`init: true\` and define complete \`steps\` array`,
|
|
721
|
+
/**
|
|
722
|
+
* Next step decision prompt
|
|
723
|
+
*/
|
|
724
|
+
NEXT_STEP_DECISION: `**Next Step Decision Required**
|
|
725
|
+
|
|
726
|
+
Previous step completed. Choose your action:
|
|
727
|
+
|
|
728
|
+
**\u{1F504} RETRY Current Step:**
|
|
729
|
+
- Call \`{toolName}\` with current parameters
|
|
730
|
+
- \u26A0\uFE0F CRITICAL: Set \`decision: "retry"\`
|
|
731
|
+
|
|
732
|
+
**\u25B6\uFE0F PROCEED to Next Step:**
|
|
733
|
+
- Call \`{toolName}\` with parameters below
|
|
734
|
+
- Set \`decision: "proceed"\`
|
|
735
|
+
|
|
736
|
+
Next step: \`{nextStepDescription}\`
|
|
737
|
+
|
|
738
|
+
{nextStepSchema}
|
|
739
|
+
|
|
740
|
+
**Important:** Exclude \`steps\` key from parameters`,
|
|
741
|
+
/**
|
|
742
|
+
* Final step completion prompt
|
|
743
|
+
*/
|
|
744
|
+
FINAL_STEP_COMPLETION: `**Final Step Complete** {statusIcon}
|
|
745
|
+
|
|
746
|
+
Step executed {statusText}. Choose action:
|
|
747
|
+
|
|
748
|
+
**\u{1F504} RETRY:** Call \`{toolName}\` with \`decision: "retry"\`
|
|
749
|
+
**\u2705 COMPLETE:** Call \`{toolName}\` with \`decision: "complete"\`
|
|
750
|
+
**\u{1F195} NEW:** Call \`{toolName}\` with \`init: true\`{newWorkflowInstructions}`,
|
|
751
|
+
/**
|
|
752
|
+
* Workflow completion success message
|
|
753
|
+
*/
|
|
754
|
+
WORKFLOW_COMPLETED: `**Workflow Completed Successfully** \u2705
|
|
755
|
+
|
|
756
|
+
All workflow steps have been executed and the workflow is now complete.
|
|
757
|
+
|
|
758
|
+
**Summary:**
|
|
759
|
+
- Total steps: {totalSteps}
|
|
760
|
+
- All steps executed successfully
|
|
761
|
+
|
|
762
|
+
Agent can now start a new workflow if needed by calling \`{toolName}\` with \`init: true\`{newWorkflowInstructions}.`,
|
|
763
|
+
/**
|
|
764
|
+
* Error messages
|
|
765
|
+
*/
|
|
766
|
+
ERRORS: {
|
|
767
|
+
NOT_INITIALIZED: {
|
|
768
|
+
WITH_PREDEFINED: "Error: Workflow not initialized. Please provide 'init' parameter to start a new workflow.",
|
|
769
|
+
WITHOUT_PREDEFINED: "Error: Workflow not initialized. Please provide 'init' and 'steps' parameter to start a new workflow."
|
|
770
|
+
},
|
|
771
|
+
ALREADY_AT_FINAL: "Error: Cannot proceed, already at the final step.",
|
|
772
|
+
CANNOT_COMPLETE_NOT_AT_FINAL: "Error: Cannot complete workflow - you are not at the final step. Please use decision=proceed to continue to the next step.",
|
|
773
|
+
NO_STEPS_PROVIDED: "Error: No steps provided",
|
|
774
|
+
NO_CURRENT_STEP: "Error: No current step to execute"
|
|
775
|
+
}
|
|
776
|
+
};
|
|
777
|
+
var ResponseTemplates = {
|
|
778
|
+
/**
|
|
779
|
+
* Success response for action execution
|
|
780
|
+
*/
|
|
781
|
+
ACTION_SUCCESS: `**Action Completed Successfully** \u2705
|
|
782
|
+
|
|
783
|
+
Previous action (\`{currentAction}\`) executed successfully.
|
|
784
|
+
|
|
785
|
+
**Next Action Required:** \`{nextAction}\`
|
|
786
|
+
|
|
787
|
+
Agent MUST call tool \`{toolName}\` again with the \`{nextAction}\` action to continue the autonomous execution sequence.
|
|
788
|
+
|
|
789
|
+
**Instructions:**
|
|
790
|
+
- Analyze the result from previous action: \`{currentAction}\`
|
|
791
|
+
- Execute the next planned action: \`{nextAction}\`
|
|
792
|
+
- Maintain execution context and progress toward the final goal`,
|
|
793
|
+
/**
|
|
794
|
+
* Planning prompt when no next action is specified
|
|
795
|
+
*/
|
|
796
|
+
PLANNING_PROMPT: `**Action Evaluation & Planning Required** \u{1F3AF}
|
|
797
|
+
|
|
798
|
+
Previous action (\`{currentAction}\`) completed. You need to determine the next step.
|
|
799
|
+
|
|
800
|
+
**Evaluation & Planning Process:**
|
|
801
|
+
1. **Analyze Results:** Review the outcome of \`{currentAction}\`
|
|
802
|
+
2. **Assess Progress:** Determine how close you are to fulfilling the user request
|
|
803
|
+
3. **Plan Next Action:** Identify the most appropriate next action (if needed)
|
|
804
|
+
4. **Execute Decision:** Call \`{toolName}\` with the planned action
|
|
805
|
+
|
|
806
|
+
**Options:**
|
|
807
|
+
- **Continue:** If more actions are needed to fulfill the request
|
|
808
|
+
- **Complete:** If the user request has been fully satisfied
|
|
809
|
+
|
|
810
|
+
Choose the next action that best advances toward completing the user's request.`,
|
|
811
|
+
/**
|
|
812
|
+
* Error response template
|
|
813
|
+
*/
|
|
814
|
+
ERROR_RESPONSE: `Action argument validation failed: {errorMessage}`,
|
|
815
|
+
WORKFLOW_ERROR_RESPONSE: `Action argument validation failed: {errorMessage}
|
|
816
|
+
Set \`decision: "retry"\` to retry the current step, or check your parameters and try again.`,
|
|
817
|
+
/**
|
|
818
|
+
* Completion message
|
|
819
|
+
*/
|
|
820
|
+
COMPLETION_MESSAGE: `Completed, no dependent actions to execute`,
|
|
821
|
+
/**
|
|
822
|
+
* Security validation messages
|
|
823
|
+
*/
|
|
824
|
+
SECURITY_VALIDATION: {
|
|
825
|
+
PASSED: `Security validation PASSED for {operation} on {path}`,
|
|
826
|
+
FAILED: `Security validation FAILED for {operation} on {path}`
|
|
827
|
+
},
|
|
828
|
+
/**
|
|
829
|
+
* Audit log messages
|
|
830
|
+
*/
|
|
831
|
+
AUDIT_LOG: `Audit log entry created: [{timestamp}] {level}: {action} on {resource}{userInfo}`
|
|
832
|
+
};
|
|
833
|
+
var CompiledPrompts = {
|
|
834
|
+
autonomousExecution: p(SystemPrompts.AUTONOMOUS_EXECUTION),
|
|
835
|
+
workflowExecution: p(SystemPrompts.WORKFLOW_EXECUTION),
|
|
836
|
+
samplingExecution: p(SystemPrompts.SAMPLING_EXECUTION),
|
|
837
|
+
samplingWorkflowExecution: p(SystemPrompts.SAMPLING_WORKFLOW_EXECUTION),
|
|
838
|
+
workflowInit: p(WorkflowPrompts.WORKFLOW_INIT),
|
|
839
|
+
workflowToolDescription: p(WorkflowPrompts.WORKFLOW_TOOL_DESCRIPTION),
|
|
840
|
+
nextStepDecision: p(WorkflowPrompts.NEXT_STEP_DECISION),
|
|
841
|
+
finalStepCompletion: p(WorkflowPrompts.FINAL_STEP_COMPLETION),
|
|
842
|
+
workflowCompleted: p(WorkflowPrompts.WORKFLOW_COMPLETED),
|
|
843
|
+
actionSuccess: p(ResponseTemplates.ACTION_SUCCESS),
|
|
844
|
+
planningPrompt: p(ResponseTemplates.PLANNING_PROMPT),
|
|
845
|
+
errorResponse: p(ResponseTemplates.ERROR_RESPONSE),
|
|
846
|
+
workflowErrorResponse: p(ResponseTemplates.WORKFLOW_ERROR_RESPONSE),
|
|
847
|
+
securityPassed: p(ResponseTemplates.SECURITY_VALIDATION.PASSED),
|
|
848
|
+
securityFailed: p(ResponseTemplates.SECURITY_VALIDATION.FAILED),
|
|
849
|
+
auditLog: p(ResponseTemplates.AUDIT_LOG),
|
|
850
|
+
completionMessage: () => ResponseTemplates.COMPLETION_MESSAGE
|
|
851
|
+
};
|
|
852
|
+
var PromptUtils = {
|
|
853
|
+
/**
|
|
854
|
+
* Generate tool list for descriptions
|
|
855
|
+
*/
|
|
856
|
+
generateToolList: (tools) => {
|
|
857
|
+
return tools.filter((tool) => !tool.hide).map((tool) => `<tool name="${tool.name}"${tool.description ? ` description="${tool.description}"` : ""}/>`).join("\n");
|
|
858
|
+
},
|
|
859
|
+
/**
|
|
860
|
+
* Generate hidden tool list for descriptions
|
|
861
|
+
*/
|
|
862
|
+
generateHiddenToolList: (tools) => {
|
|
863
|
+
return tools.filter((tool) => tool.hide).map((tool) => `<tool name="${tool.name}" hide/>`).join("\n");
|
|
864
|
+
},
|
|
865
|
+
/**
|
|
866
|
+
* Format workflow steps for display
|
|
867
|
+
*/
|
|
868
|
+
formatWorkflowSteps: (steps) => {
|
|
869
|
+
if (!steps.length) return "";
|
|
870
|
+
return `## Workflow Steps
|
|
871
|
+
${JSON.stringify(steps, null, 2)}`;
|
|
872
|
+
},
|
|
873
|
+
/**
|
|
874
|
+
* Format workflow progress display with status icons
|
|
875
|
+
*/
|
|
876
|
+
formatWorkflowProgress: (progressData) => {
|
|
877
|
+
const statusIcons = {
|
|
878
|
+
pending: "\u23F3",
|
|
879
|
+
running: "\u{1F504}",
|
|
880
|
+
completed: "\u2705",
|
|
881
|
+
failed: "\u274C"
|
|
882
|
+
};
|
|
883
|
+
return progressData.steps.map((step, index) => {
|
|
884
|
+
const status = progressData.statuses[index] || "pending";
|
|
885
|
+
const icon = statusIcons[status] || "\u23F3";
|
|
886
|
+
const current = index === progressData.currentStepIndex ? " **[CURRENT]**" : "";
|
|
887
|
+
const actions = step.actions.length > 0 ? ` | Action: ${step.actions.join(", ")}` : "";
|
|
888
|
+
return `${icon} **Step ${index + 1}:** ${step.description}${actions}${current}`;
|
|
889
|
+
}).join("\n");
|
|
890
|
+
},
|
|
891
|
+
/**
|
|
892
|
+
* Generate user info for audit logs
|
|
893
|
+
*/
|
|
894
|
+
formatUserInfo: (user) => {
|
|
895
|
+
return user ? ` by ${user}` : "";
|
|
896
|
+
},
|
|
897
|
+
/**
|
|
898
|
+
* Format timestamp for logs
|
|
899
|
+
*/
|
|
900
|
+
formatTimestamp: () => {
|
|
901
|
+
return (/* @__PURE__ */ new Date()).toISOString();
|
|
902
|
+
}
|
|
903
|
+
};
|
|
904
|
+
|
|
905
|
+
// ../__mcpc__core_0.2.0-beta.10/node_modules/@mcpc/core/src/executors/agentic/agentic-executor.js
|
|
906
|
+
import { Ajv } from "ajv";
|
|
907
|
+
import { AggregateAjvError } from "@segment/ajv-human-errors";
|
|
908
|
+
import addFormats from "ajv-formats";
|
|
909
|
+
var ajv = new Ajv({
|
|
910
|
+
allErrors: true,
|
|
911
|
+
verbose: true
|
|
912
|
+
});
|
|
913
|
+
addFormats(ajv);
|
|
914
|
+
var AgenticExecutor = class {
|
|
915
|
+
name;
|
|
916
|
+
allToolNames;
|
|
917
|
+
toolNameToDetailList;
|
|
918
|
+
server;
|
|
919
|
+
ACTION_KEY;
|
|
920
|
+
NEXT_ACTION_KEY;
|
|
921
|
+
constructor(name, allToolNames, toolNameToDetailList, server, ACTION_KEY = "action", NEXT_ACTION_KEY = "nextAction") {
|
|
922
|
+
this.name = name;
|
|
923
|
+
this.allToolNames = allToolNames;
|
|
924
|
+
this.toolNameToDetailList = toolNameToDetailList;
|
|
925
|
+
this.server = server;
|
|
926
|
+
this.ACTION_KEY = ACTION_KEY;
|
|
927
|
+
this.NEXT_ACTION_KEY = NEXT_ACTION_KEY;
|
|
928
|
+
}
|
|
929
|
+
async execute(args, schema) {
|
|
930
|
+
const validationResult = this.validate(args, schema);
|
|
931
|
+
if (!validationResult.valid) {
|
|
932
|
+
return {
|
|
933
|
+
content: [
|
|
934
|
+
{
|
|
935
|
+
type: "text",
|
|
936
|
+
text: CompiledPrompts.errorResponse({
|
|
937
|
+
errorMessage: validationResult.error || "Validation failed"
|
|
938
|
+
})
|
|
939
|
+
}
|
|
940
|
+
],
|
|
941
|
+
isError: true
|
|
942
|
+
};
|
|
943
|
+
}
|
|
944
|
+
const actionName = args[this.ACTION_KEY];
|
|
945
|
+
const currentTool = this.toolNameToDetailList.find(([name, _detail]) => name === actionName)?.[1];
|
|
946
|
+
if (currentTool) {
|
|
947
|
+
const nextAction = args[this.NEXT_ACTION_KEY];
|
|
948
|
+
const currentResult = await currentTool.execute({
|
|
949
|
+
...args[actionName]
|
|
950
|
+
});
|
|
951
|
+
if (args[nextAction]) {
|
|
952
|
+
currentResult?.content?.push({
|
|
953
|
+
type: "text",
|
|
954
|
+
text: CompiledPrompts.actionSuccess({
|
|
955
|
+
toolName: this.name,
|
|
956
|
+
nextAction,
|
|
957
|
+
currentAction: actionName
|
|
958
|
+
})
|
|
959
|
+
});
|
|
960
|
+
} else {
|
|
961
|
+
currentResult?.content?.push({
|
|
962
|
+
type: "text",
|
|
963
|
+
text: CompiledPrompts.planningPrompt({
|
|
964
|
+
currentAction: actionName
|
|
965
|
+
})
|
|
966
|
+
});
|
|
967
|
+
}
|
|
968
|
+
return currentResult;
|
|
969
|
+
}
|
|
970
|
+
if (this.allToolNames.includes(actionName)) {
|
|
971
|
+
try {
|
|
972
|
+
const result = await this.server.callTool(actionName, args[actionName]);
|
|
973
|
+
const nextAction = args[this.NEXT_ACTION_KEY];
|
|
974
|
+
const callToolResult = result ?? {
|
|
975
|
+
content: []
|
|
976
|
+
};
|
|
977
|
+
if (nextAction && this.allToolNames.includes(nextAction)) {
|
|
978
|
+
callToolResult.content.push({
|
|
979
|
+
type: "text",
|
|
980
|
+
text: CompiledPrompts.actionSuccess({
|
|
981
|
+
toolName: this.name,
|
|
982
|
+
nextAction,
|
|
983
|
+
currentAction: actionName
|
|
984
|
+
})
|
|
985
|
+
});
|
|
986
|
+
} else {
|
|
987
|
+
callToolResult.content.push({
|
|
988
|
+
type: "text",
|
|
989
|
+
text: CompiledPrompts.planningPrompt({
|
|
990
|
+
currentAction: actionName
|
|
991
|
+
})
|
|
992
|
+
});
|
|
993
|
+
}
|
|
994
|
+
return callToolResult;
|
|
995
|
+
} catch (error) {
|
|
996
|
+
return {
|
|
997
|
+
content: [
|
|
998
|
+
{
|
|
999
|
+
type: "text",
|
|
1000
|
+
text: `Error executing internal tool ${actionName}: ${error instanceof Error ? error.message : String(error)}`
|
|
1001
|
+
}
|
|
1002
|
+
],
|
|
1003
|
+
isError: true
|
|
1004
|
+
};
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
return {
|
|
1008
|
+
content: [
|
|
1009
|
+
{
|
|
1010
|
+
type: "text",
|
|
1011
|
+
text: CompiledPrompts.completionMessage()
|
|
1012
|
+
}
|
|
1013
|
+
]
|
|
1014
|
+
};
|
|
1015
|
+
}
|
|
1016
|
+
// Validate arguments using JSON schema
|
|
1017
|
+
validate(args, schema) {
|
|
1018
|
+
if (args.decision === "complete") {
|
|
1019
|
+
return {
|
|
1020
|
+
valid: true
|
|
1021
|
+
};
|
|
1022
|
+
}
|
|
1023
|
+
const validate = ajv.compile(schema);
|
|
1024
|
+
if (!validate(args)) {
|
|
1025
|
+
const errors = new AggregateAjvError(validate.errors);
|
|
1026
|
+
return {
|
|
1027
|
+
valid: false,
|
|
1028
|
+
error: errors.message
|
|
1029
|
+
};
|
|
1030
|
+
}
|
|
1031
|
+
return {
|
|
1032
|
+
valid: true
|
|
1033
|
+
};
|
|
1034
|
+
}
|
|
1035
|
+
};
|
|
1036
|
+
|
|
1037
|
+
// ../__mcpc__core_0.2.0-beta.10/node_modules/@jsr/es-toolkit__es-toolkit/src/function/partial.js
|
|
1038
|
+
function partial(func, ...partialArgs) {
|
|
1039
|
+
return partialImpl(func, placeholderSymbol, ...partialArgs);
|
|
1040
|
+
}
|
|
1041
|
+
function partialImpl(func, placeholder, ...partialArgs) {
|
|
1042
|
+
const partialed = function(...providedArgs) {
|
|
1043
|
+
let providedArgsIndex = 0;
|
|
1044
|
+
const substitutedArgs = partialArgs.slice().map((arg) => arg === placeholder ? providedArgs[providedArgsIndex++] : arg);
|
|
1045
|
+
const remainingArgs = providedArgs.slice(providedArgsIndex);
|
|
1046
|
+
return func.apply(this, substitutedArgs.concat(remainingArgs));
|
|
1047
|
+
};
|
|
1048
|
+
if (func.prototype) {
|
|
1049
|
+
partialed.prototype = Object.create(func.prototype);
|
|
1050
|
+
}
|
|
1051
|
+
return partialed;
|
|
1052
|
+
}
|
|
1053
|
+
var placeholderSymbol = Symbol("partial.placeholder");
|
|
1054
|
+
partial.placeholder = placeholderSymbol;
|
|
1055
|
+
|
|
1056
|
+
// ../__mcpc__core_0.2.0-beta.10/node_modules/@jsr/es-toolkit__es-toolkit/src/function/partialRight.js
|
|
1057
|
+
function partialRight(func, ...partialArgs) {
|
|
1058
|
+
return partialRightImpl(func, placeholderSymbol2, ...partialArgs);
|
|
1059
|
+
}
|
|
1060
|
+
function partialRightImpl(func, placeholder, ...partialArgs) {
|
|
1061
|
+
const partialedRight = function(...providedArgs) {
|
|
1062
|
+
const placeholderLength = partialArgs.filter((arg) => arg === placeholder).length;
|
|
1063
|
+
const rangeLength = Math.max(providedArgs.length - placeholderLength, 0);
|
|
1064
|
+
const remainingArgs = providedArgs.slice(0, rangeLength);
|
|
1065
|
+
let providedArgsIndex = rangeLength;
|
|
1066
|
+
const substitutedArgs = partialArgs.slice().map((arg) => arg === placeholder ? providedArgs[providedArgsIndex++] : arg);
|
|
1067
|
+
return func.apply(this, remainingArgs.concat(substitutedArgs));
|
|
1068
|
+
};
|
|
1069
|
+
if (func.prototype) {
|
|
1070
|
+
partialedRight.prototype = Object.create(func.prototype);
|
|
1071
|
+
}
|
|
1072
|
+
return partialedRight;
|
|
1073
|
+
}
|
|
1074
|
+
var placeholderSymbol2 = Symbol("partialRight.placeholder");
|
|
1075
|
+
partialRight.placeholder = placeholderSymbol2;
|
|
1076
|
+
|
|
1077
|
+
// ../__mcpc__core_0.2.0-beta.10/node_modules/@jsr/es-toolkit__es-toolkit/src/function/retry.js
|
|
1078
|
+
var DEFAULT_RETRIES = Number.POSITIVE_INFINITY;
|
|
1079
|
+
|
|
1080
|
+
// ../__mcpc__core_0.2.0-beta.10/node_modules/@jsr/es-toolkit__es-toolkit/src/object/pick.js
|
|
1081
|
+
function pick(obj, keys) {
|
|
1082
|
+
const result = {};
|
|
1083
|
+
for (let i = 0; i < keys.length; i++) {
|
|
1084
|
+
const key = keys[i];
|
|
1085
|
+
if (Object.hasOwn(obj, key)) {
|
|
1086
|
+
result[key] = obj[key];
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
1089
|
+
return result;
|
|
1090
|
+
}
|
|
1091
|
+
|
|
1092
|
+
// ../__mcpc__core_0.2.0-beta.10/node_modules/@jsr/es-toolkit__es-toolkit/src/string/deburr.js
|
|
1093
|
+
var deburrMap = new Map(
|
|
1094
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
1095
|
+
Object.entries({
|
|
1096
|
+
\u00C6: "Ae",
|
|
1097
|
+
\u00D0: "D",
|
|
1098
|
+
\u00D8: "O",
|
|
1099
|
+
\u00DE: "Th",
|
|
1100
|
+
\u00DF: "ss",
|
|
1101
|
+
\u00E6: "ae",
|
|
1102
|
+
\u00F0: "d",
|
|
1103
|
+
\u00F8: "o",
|
|
1104
|
+
\u00FE: "th",
|
|
1105
|
+
\u0110: "D",
|
|
1106
|
+
\u0111: "d",
|
|
1107
|
+
\u0126: "H",
|
|
1108
|
+
\u0127: "h",
|
|
1109
|
+
\u0131: "i",
|
|
1110
|
+
\u0132: "IJ",
|
|
1111
|
+
\u0133: "ij",
|
|
1112
|
+
\u0138: "k",
|
|
1113
|
+
\u013F: "L",
|
|
1114
|
+
\u0140: "l",
|
|
1115
|
+
\u0141: "L",
|
|
1116
|
+
\u0142: "l",
|
|
1117
|
+
\u0149: "'n",
|
|
1118
|
+
\u014A: "N",
|
|
1119
|
+
\u014B: "n",
|
|
1120
|
+
\u0152: "Oe",
|
|
1121
|
+
\u0153: "oe",
|
|
1122
|
+
\u0166: "T",
|
|
1123
|
+
\u0167: "t",
|
|
1124
|
+
\u017F: "s"
|
|
1125
|
+
})
|
|
1126
|
+
);
|
|
1127
|
+
|
|
1128
|
+
// ../__mcpc__core_0.2.0-beta.10/node_modules/@mcpc/core/src/factories/args-def-factory.js
|
|
1129
|
+
var DECISION_OPTIONS = {
|
|
1130
|
+
RETRY: "retry",
|
|
1131
|
+
PROCEED: "proceed",
|
|
1132
|
+
COMPLETE: "complete"
|
|
1133
|
+
};
|
|
1134
|
+
function createArgsDefFactory(name, allToolNames, depGroups, predefinedSteps, ensureStepActions) {
|
|
1135
|
+
const formatEnsureStepActions = () => {
|
|
1136
|
+
if (!ensureStepActions || ensureStepActions.length === 0) {
|
|
1137
|
+
return "";
|
|
1138
|
+
}
|
|
1139
|
+
return `
|
|
1140
|
+
|
|
1141
|
+
## Required Actions
|
|
1142
|
+
The workflow MUST include at least one of these actions:
|
|
1143
|
+
${ensureStepActions.map((action) => `- \`${action}\``).join("\n")}`;
|
|
1144
|
+
};
|
|
1145
|
+
return {
|
|
1146
|
+
common: (extra, optionalFields = []) => {
|
|
1147
|
+
const requiredFields = Object.keys(extra).filter((key) => !optionalFields.includes(key));
|
|
1148
|
+
return {
|
|
1149
|
+
type: "object",
|
|
1150
|
+
description: `**Tool parameters dynamically update per workflow step**`,
|
|
1151
|
+
properties: {
|
|
1152
|
+
...extra
|
|
1153
|
+
},
|
|
1154
|
+
required: requiredFields
|
|
1155
|
+
};
|
|
1156
|
+
},
|
|
1157
|
+
steps: () => ({
|
|
1158
|
+
type: "array",
|
|
1159
|
+
description: `
|
|
1160
|
+
Workflow step definitions - provide ONLY on initial call.
|
|
1161
|
+
|
|
1162
|
+
**CRITICAL RULES:**
|
|
1163
|
+
- **Sequential Dependency:** If Action B depends on Action A's result \u2192 separate steps
|
|
1164
|
+
- **Concurrent Actions:** Independent actions can share one step
|
|
1165
|
+
- **Complete Mapping:** Include ALL requested operations
|
|
1166
|
+
- **Predefined Steps:** Leave unspecified if predefined steps exist
|
|
1167
|
+
|
|
1168
|
+
**BEST PRACTICES:**
|
|
1169
|
+
- Atomic, focused steps
|
|
1170
|
+
- Idempotent actions for safe retries
|
|
1171
|
+
- Clear step descriptions with input/output context`,
|
|
1172
|
+
items: {
|
|
1173
|
+
type: "object",
|
|
1174
|
+
description: `A single step containing actions that execute concurrently. All actions in this step run simultaneously with no guaranteed order.`,
|
|
1175
|
+
properties: {
|
|
1176
|
+
description: {
|
|
1177
|
+
type: "string",
|
|
1178
|
+
description: `**Step purpose, required inputs, and expected outputs**`
|
|
1179
|
+
},
|
|
1180
|
+
actions: {
|
|
1181
|
+
type: "array",
|
|
1182
|
+
description: `Array of action names for this step. **CURRENT LIMITATION: Only 1 action per step is allowed.** Action names must match available tool names exactly.`,
|
|
1183
|
+
items: {
|
|
1184
|
+
...{
|
|
1185
|
+
enum: allToolNames
|
|
1186
|
+
},
|
|
1187
|
+
type: "string",
|
|
1188
|
+
description: `Individual action name from available tools. Must be exactly one of the allowed tool names.`
|
|
1189
|
+
},
|
|
1190
|
+
uniqueItems: true,
|
|
1191
|
+
minItems: 0,
|
|
1192
|
+
// TODO: remove this restriction when workflow planning is good enough
|
|
1193
|
+
maxItems: 1
|
|
1194
|
+
}
|
|
1195
|
+
},
|
|
1196
|
+
required: [
|
|
1197
|
+
"description",
|
|
1198
|
+
"actions"
|
|
1199
|
+
],
|
|
1200
|
+
additionalProperties: false
|
|
1201
|
+
},
|
|
1202
|
+
default: predefinedSteps ? predefinedSteps : void 0,
|
|
1203
|
+
minItems: 1
|
|
1204
|
+
}),
|
|
1205
|
+
init: () => ({
|
|
1206
|
+
type: "boolean",
|
|
1207
|
+
description: `Init a new workflow`,
|
|
1208
|
+
enum: [
|
|
1209
|
+
true
|
|
1210
|
+
]
|
|
1211
|
+
}),
|
|
1212
|
+
decision: () => ({
|
|
1213
|
+
type: "string",
|
|
1214
|
+
enum: Object.values(DECISION_OPTIONS),
|
|
1215
|
+
description: `**Step control: \`${DECISION_OPTIONS.PROCEED}\` = next step, \`${DECISION_OPTIONS.RETRY}\` = retry/repeat current, \`${DECISION_OPTIONS.COMPLETE}\` = finish workflow**`
|
|
1216
|
+
}),
|
|
1217
|
+
action: () => ({
|
|
1218
|
+
type: "string",
|
|
1219
|
+
description: "Define the current workflow action to be performed",
|
|
1220
|
+
enum: allToolNames,
|
|
1221
|
+
required: [
|
|
1222
|
+
"action"
|
|
1223
|
+
]
|
|
1224
|
+
}),
|
|
1225
|
+
forTool: function() {
|
|
1226
|
+
return this.common({});
|
|
1227
|
+
},
|
|
1228
|
+
forCurrentState: function(state) {
|
|
1229
|
+
const currentStep = state.getCurrentStep();
|
|
1230
|
+
if (!state.isWorkflowInitialized() || !currentStep) {
|
|
1231
|
+
state.reset();
|
|
1232
|
+
const initSchema = {
|
|
1233
|
+
init: this.init()
|
|
1234
|
+
};
|
|
1235
|
+
if (!predefinedSteps) {
|
|
1236
|
+
initSchema.steps = this.steps();
|
|
1237
|
+
}
|
|
1238
|
+
return this.common(initSchema);
|
|
1239
|
+
}
|
|
1240
|
+
const stepDependencies = {
|
|
1241
|
+
...pick(depGroups, currentStep.actions)
|
|
1242
|
+
};
|
|
1243
|
+
stepDependencies["decision"] = this.decision();
|
|
1244
|
+
stepDependencies["action"] = this.action();
|
|
1245
|
+
return this.common(stepDependencies);
|
|
1246
|
+
},
|
|
1247
|
+
forSampling: function() {
|
|
1248
|
+
return {
|
|
1249
|
+
type: "object",
|
|
1250
|
+
description: "Provide user request for autonomous tool execution",
|
|
1251
|
+
properties: {
|
|
1252
|
+
userRequest: {
|
|
1253
|
+
type: "string",
|
|
1254
|
+
description: "The task or request that should be completed autonomously by the agentic system using available tools"
|
|
1255
|
+
}
|
|
1256
|
+
},
|
|
1257
|
+
required: [
|
|
1258
|
+
"userRequest"
|
|
1259
|
+
]
|
|
1260
|
+
};
|
|
1261
|
+
},
|
|
1262
|
+
forAgentic: function(toolNameToDetailList, _sampling = false, ACTION_KEY = "action", NEXT_ACTION_KEY = "nextAction") {
|
|
1263
|
+
const allOf = toolNameToDetailList.map(([toolName, _toolDetail]) => {
|
|
1264
|
+
return {
|
|
1265
|
+
if: {
|
|
1266
|
+
properties: {
|
|
1267
|
+
[ACTION_KEY]: {
|
|
1268
|
+
const: toolName
|
|
1269
|
+
}
|
|
1270
|
+
},
|
|
1271
|
+
required: [
|
|
1272
|
+
ACTION_KEY
|
|
1273
|
+
]
|
|
1274
|
+
},
|
|
1275
|
+
then: {
|
|
1276
|
+
required: [
|
|
1277
|
+
toolName
|
|
1278
|
+
]
|
|
1279
|
+
}
|
|
1280
|
+
};
|
|
1281
|
+
});
|
|
1282
|
+
const actionDescription = `Specifies the action to be performed from the enum. **\u26A0\uFE0F When setting \`action: "example_action"\`, you MUST also provide \`"example_action": { ... }\`**`;
|
|
1283
|
+
const baseProperties = {
|
|
1284
|
+
[ACTION_KEY]: {
|
|
1285
|
+
type: "string",
|
|
1286
|
+
enum: allToolNames,
|
|
1287
|
+
description: actionDescription
|
|
1288
|
+
},
|
|
1289
|
+
[NEXT_ACTION_KEY]: {
|
|
1290
|
+
type: "string",
|
|
1291
|
+
enum: allToolNames,
|
|
1292
|
+
description: "Optional: Specify the next action to execute. Only include this when you know additional actions are needed after the current one completes."
|
|
1293
|
+
},
|
|
1294
|
+
decision: this.decision(),
|
|
1295
|
+
...depGroups
|
|
1296
|
+
};
|
|
1297
|
+
const requiredFields = [
|
|
1298
|
+
ACTION_KEY,
|
|
1299
|
+
"decision"
|
|
1300
|
+
];
|
|
1301
|
+
const schema = {
|
|
1302
|
+
additionalProperties: false,
|
|
1303
|
+
type: "object",
|
|
1304
|
+
properties: baseProperties,
|
|
1305
|
+
required: requiredFields
|
|
1306
|
+
};
|
|
1307
|
+
if (allOf.length > 0) {
|
|
1308
|
+
schema.allOf = allOf;
|
|
1309
|
+
}
|
|
1310
|
+
return schema;
|
|
1311
|
+
},
|
|
1312
|
+
forNextState: function(state) {
|
|
1313
|
+
if (!state.isWorkflowInitialized() || !state.hasNextStep()) {
|
|
1314
|
+
throw new Error(`Cannot get next state schema: no next step available`);
|
|
1315
|
+
}
|
|
1316
|
+
const currentStepIndex = state.getCurrentStepIndex();
|
|
1317
|
+
const allSteps = state.getSteps();
|
|
1318
|
+
const nextStep = allSteps[currentStepIndex + 1];
|
|
1319
|
+
if (!nextStep) {
|
|
1320
|
+
throw new Error(`Next step not found`);
|
|
1321
|
+
}
|
|
1322
|
+
const stepDependencies = {
|
|
1323
|
+
...pick(depGroups, nextStep.actions)
|
|
1324
|
+
};
|
|
1325
|
+
stepDependencies["decision"] = this.decision();
|
|
1326
|
+
stepDependencies["action"] = this.action();
|
|
1327
|
+
return this.common(stepDependencies);
|
|
1328
|
+
},
|
|
1329
|
+
forToolDescription: function(description, state) {
|
|
1330
|
+
const enforceToolArgs = this.forCurrentState(state);
|
|
1331
|
+
const initTitle = predefinedSteps ? `**YOU MUST execute this tool with following tool arguments to init the workflow**
|
|
1332
|
+
NOTE: The \`steps\` has been predefined` : `**You MUST execute this tool with following tool arguments to plan and init the workflow**`;
|
|
1333
|
+
return CompiledPrompts.workflowToolDescription({
|
|
1334
|
+
description,
|
|
1335
|
+
initTitle,
|
|
1336
|
+
ensureStepActions: formatEnsureStepActions(),
|
|
1337
|
+
schemaDefinition: JSON.stringify(enforceToolArgs, null, 2)
|
|
1338
|
+
});
|
|
1339
|
+
},
|
|
1340
|
+
forInitialStepDescription: function(steps, state) {
|
|
1341
|
+
return CompiledPrompts.workflowInit({
|
|
1342
|
+
stepCount: steps.length.toString(),
|
|
1343
|
+
currentStepDescription: state.getCurrentStep()?.description || "",
|
|
1344
|
+
toolName: name,
|
|
1345
|
+
schemaDefinition: JSON.stringify(this.forCurrentState(state), null, 2),
|
|
1346
|
+
// Remove redundant workflow steps display
|
|
1347
|
+
workflowSteps: ""
|
|
1348
|
+
});
|
|
1349
|
+
}
|
|
1350
|
+
};
|
|
1351
|
+
}
|
|
1352
|
+
|
|
1353
|
+
// ../__mcpc__core_0.2.0-beta.10/node_modules/@mcpc/core/src/executors/sampling/base-sampling-executor.js
|
|
1354
|
+
import { Ajv as Ajv2 } from "ajv";
|
|
1355
|
+
import { AggregateAjvError as AggregateAjvError2 } from "@segment/ajv-human-errors";
|
|
1356
|
+
import addFormats2 from "ajv-formats";
|
|
1357
|
+
import { inspect as inspect2 } from "node:util";
|
|
1358
|
+
var ajv2 = new Ajv2({
|
|
1359
|
+
allErrors: true,
|
|
1360
|
+
verbose: true
|
|
1361
|
+
});
|
|
1362
|
+
addFormats2(ajv2);
|
|
1363
|
+
var BaseSamplingExecutor = class {
|
|
1364
|
+
name;
|
|
1365
|
+
description;
|
|
1366
|
+
allToolNames;
|
|
1367
|
+
toolNameToDetailList;
|
|
1368
|
+
server;
|
|
1369
|
+
conversationHistory;
|
|
1370
|
+
maxIterations;
|
|
1371
|
+
currentIteration;
|
|
1372
|
+
constructor(name, description, allToolNames, toolNameToDetailList, server, config) {
|
|
1373
|
+
this.name = name;
|
|
1374
|
+
this.description = description;
|
|
1375
|
+
this.allToolNames = allToolNames;
|
|
1376
|
+
this.toolNameToDetailList = toolNameToDetailList;
|
|
1377
|
+
this.server = server;
|
|
1378
|
+
this.conversationHistory = [];
|
|
1379
|
+
this.maxIterations = 33;
|
|
1380
|
+
this.currentIteration = 0;
|
|
1381
|
+
if (config?.maxIterations) {
|
|
1382
|
+
this.maxIterations = config.maxIterations;
|
|
1383
|
+
}
|
|
1384
|
+
}
|
|
1385
|
+
async runSamplingLoop(systemPrompt, schema, state) {
|
|
1386
|
+
this.conversationHistory = [];
|
|
1387
|
+
try {
|
|
1388
|
+
for (this.currentIteration = 0; this.currentIteration < this.maxIterations; this.currentIteration++) {
|
|
1389
|
+
const response = await this.server.createMessage({
|
|
1390
|
+
systemPrompt: systemPrompt(),
|
|
1391
|
+
messages: this.conversationHistory,
|
|
1392
|
+
maxTokens: Number.MAX_SAFE_INTEGER
|
|
1393
|
+
});
|
|
1394
|
+
const responseContent = response.content.text || "{}";
|
|
1395
|
+
let parsedData;
|
|
1396
|
+
try {
|
|
1397
|
+
parsedData = parseJSON(responseContent.trim(), true);
|
|
1398
|
+
} catch (parseError) {
|
|
1399
|
+
this.addParsingErrorToHistory(responseContent, parseError);
|
|
1400
|
+
continue;
|
|
1401
|
+
}
|
|
1402
|
+
if (parsedData) {
|
|
1403
|
+
this.conversationHistory.push({
|
|
1404
|
+
role: "assistant",
|
|
1405
|
+
content: {
|
|
1406
|
+
type: "text",
|
|
1407
|
+
text: JSON.stringify(parsedData, null, 2)
|
|
1408
|
+
}
|
|
1409
|
+
});
|
|
1410
|
+
}
|
|
1411
|
+
const result = await this.processAction(parsedData, schema, state);
|
|
1412
|
+
this.logIterationProgress(parsedData, result);
|
|
1413
|
+
if (result.isError) {
|
|
1414
|
+
this.conversationHistory.push({
|
|
1415
|
+
role: "user",
|
|
1416
|
+
content: {
|
|
1417
|
+
type: "text",
|
|
1418
|
+
text: result.content[0].text
|
|
1419
|
+
}
|
|
1420
|
+
});
|
|
1421
|
+
continue;
|
|
1422
|
+
}
|
|
1423
|
+
if (result.isComplete) {
|
|
1424
|
+
return result;
|
|
1425
|
+
}
|
|
1426
|
+
}
|
|
1427
|
+
return this.createMaxIterationsError();
|
|
1428
|
+
} catch (error) {
|
|
1429
|
+
return this.createExecutionError(error);
|
|
1430
|
+
}
|
|
1431
|
+
}
|
|
1432
|
+
addParsingErrorToHistory(responseText, parseError) {
|
|
1433
|
+
this.conversationHistory.push({
|
|
1434
|
+
role: "assistant",
|
|
1435
|
+
content: {
|
|
1436
|
+
type: "text",
|
|
1437
|
+
text: `JSON parsing failed. Response was: ${responseText}`
|
|
1438
|
+
}
|
|
1439
|
+
});
|
|
1440
|
+
this.conversationHistory.push({
|
|
1441
|
+
role: "user",
|
|
1442
|
+
content: {
|
|
1443
|
+
type: "text",
|
|
1444
|
+
text: CompiledPrompts.errorResponse({
|
|
1445
|
+
errorMessage: `JSON parsing failed: ${parseError instanceof Error ? parseError.message : String(parseError)}
|
|
1446
|
+
|
|
1447
|
+
Please respond with valid JSON.`
|
|
1448
|
+
})
|
|
1449
|
+
}
|
|
1450
|
+
});
|
|
1451
|
+
}
|
|
1452
|
+
createMaxIterationsError() {
|
|
1453
|
+
const result = this.createCompletionResult(`Action argument validation failed: Execution reached maximum iterations (${this.maxIterations}). Please try with a more specific request or break down the task into smaller parts.`);
|
|
1454
|
+
return {
|
|
1455
|
+
...result,
|
|
1456
|
+
isError: true,
|
|
1457
|
+
isComplete: false
|
|
1458
|
+
};
|
|
1459
|
+
}
|
|
1460
|
+
createExecutionError(error) {
|
|
1461
|
+
const errorMessage = `Sampling execution error: ${error instanceof Error ? error.message : String(error)}`;
|
|
1462
|
+
const result = this.createCompletionResult(errorMessage);
|
|
1463
|
+
return {
|
|
1464
|
+
...result,
|
|
1465
|
+
isError: true,
|
|
1466
|
+
isComplete: false
|
|
1467
|
+
};
|
|
1468
|
+
}
|
|
1469
|
+
createCompletionResult(text) {
|
|
1470
|
+
const conversationDetails = this.getConversationDetails();
|
|
1471
|
+
return {
|
|
1472
|
+
content: [
|
|
1473
|
+
{
|
|
1474
|
+
type: "text",
|
|
1475
|
+
text: `Task Completed
|
|
1476
|
+
${text}
|
|
1477
|
+
**Execution Summary:**
|
|
1478
|
+
- Iterations used: ${this.currentIteration + 1}/${this.maxIterations}
|
|
1479
|
+
- Agent: ${this.name}${conversationDetails}`
|
|
1480
|
+
}
|
|
1481
|
+
],
|
|
1482
|
+
isError: false,
|
|
1483
|
+
isComplete: true
|
|
1484
|
+
};
|
|
1485
|
+
}
|
|
1486
|
+
getConversationDetails() {
|
|
1487
|
+
if (this.conversationHistory.length === 0) {
|
|
1488
|
+
return "\n\n**No conversation history available**";
|
|
1489
|
+
}
|
|
1490
|
+
let details = "\n\n**Detailed Conversation History:**";
|
|
1491
|
+
this.conversationHistory.forEach((message) => {
|
|
1492
|
+
if (message.role === "assistant") {
|
|
1493
|
+
try {
|
|
1494
|
+
const parsed = JSON.parse(message.content.text);
|
|
1495
|
+
details += "\n```json\n" + JSON.stringify(parsed, null, 2) + "\n```";
|
|
1496
|
+
} catch {
|
|
1497
|
+
details += "\n```\n" + message.content.text + "\n```";
|
|
1498
|
+
}
|
|
1499
|
+
} else {
|
|
1500
|
+
details += "\n```\n" + message.content.text + "\n```";
|
|
1501
|
+
}
|
|
1502
|
+
});
|
|
1503
|
+
return details;
|
|
1504
|
+
}
|
|
1505
|
+
logIterationProgress(parsedData, result) {
|
|
1506
|
+
console.log(`Iteration ${this.currentIteration + 1}/${this.maxIterations}:`, {
|
|
1507
|
+
parsedData,
|
|
1508
|
+
isError: result.isError,
|
|
1509
|
+
isComplete: result.isComplete,
|
|
1510
|
+
result: inspect2(result, {
|
|
1511
|
+
depth: 5,
|
|
1512
|
+
maxArrayLength: 10,
|
|
1513
|
+
breakLength: 120,
|
|
1514
|
+
compact: true,
|
|
1515
|
+
maxStringLength: 120
|
|
1516
|
+
})
|
|
1517
|
+
});
|
|
1518
|
+
}
|
|
1519
|
+
injectJsonInstruction({ prompt, schema, schemaPrefix = "JSON schema:", schemaSuffix = `STRICT REQUIREMENTS:
|
|
1520
|
+
1. Return ONLY raw JSON that passes JSON.parse() - no markdown, code blocks, explanatory text, or extra characters
|
|
1521
|
+
2. Include ALL required fields with correct data types and satisfy ALL schema constraints (anyOf, oneOf, allOf, not, enum, pattern, min/max, conditionals)
|
|
1522
|
+
3. Your response must be the JSON object itself, nothing else
|
|
1523
|
+
|
|
1524
|
+
INVALID: \`\`\`json{"key":"value"}\`\`\` or "Here is: {"key":"value"}"
|
|
1525
|
+
VALID: {"key":"value"}` }) {
|
|
1526
|
+
return [
|
|
1527
|
+
prompt != null && prompt.length > 0 ? prompt : void 0,
|
|
1528
|
+
prompt != null && prompt.length > 0 ? "" : void 0,
|
|
1529
|
+
schemaPrefix,
|
|
1530
|
+
schema != null ? JSON.stringify(schema, null, 2) : void 0,
|
|
1531
|
+
schemaSuffix
|
|
1532
|
+
].filter((line) => line != null).join("\n");
|
|
1533
|
+
}
|
|
1534
|
+
// Validate arguments using JSON schema
|
|
1535
|
+
validateSchema(args, schema) {
|
|
1536
|
+
const validate = ajv2.compile(schema);
|
|
1537
|
+
if (!validate(args)) {
|
|
1538
|
+
const errors = new AggregateAjvError2(validate.errors);
|
|
1539
|
+
return {
|
|
1540
|
+
valid: false,
|
|
1541
|
+
error: errors.message
|
|
1542
|
+
};
|
|
1543
|
+
}
|
|
1544
|
+
return {
|
|
1545
|
+
valid: true
|
|
1546
|
+
};
|
|
1547
|
+
}
|
|
1548
|
+
};
|
|
1549
|
+
|
|
1550
|
+
// ../__mcpc__core_0.2.0-beta.10/node_modules/@mcpc/core/src/executors/sampling/agentic-sampling-executor.js
|
|
1551
|
+
var SamplingExecutor = class extends BaseSamplingExecutor {
|
|
1552
|
+
agenticExecutor;
|
|
1553
|
+
constructor(name, description, allToolNames, toolNameToDetailList, server, config) {
|
|
1554
|
+
super(name, description, allToolNames, toolNameToDetailList, server, config);
|
|
1555
|
+
this.agenticExecutor = new AgenticExecutor(name, allToolNames, toolNameToDetailList, server);
|
|
1556
|
+
}
|
|
1557
|
+
buildDepGroups() {
|
|
1558
|
+
const depGroups = {};
|
|
1559
|
+
this.toolNameToDetailList.forEach(([toolName, tool]) => {
|
|
1560
|
+
if (tool?.inputSchema) {
|
|
1561
|
+
depGroups[toolName] = {
|
|
1562
|
+
type: "object",
|
|
1563
|
+
description: tool.description || `Tool: ${toolName}`,
|
|
1564
|
+
...tool.inputSchema
|
|
1565
|
+
};
|
|
1566
|
+
} else {
|
|
1567
|
+
const toolSchema = this.server.getInternalToolSchema(toolName);
|
|
1568
|
+
if (toolSchema) {
|
|
1569
|
+
depGroups[toolName] = {
|
|
1570
|
+
...toolSchema.schema,
|
|
1571
|
+
description: toolSchema.description
|
|
1572
|
+
};
|
|
1573
|
+
}
|
|
1574
|
+
}
|
|
1575
|
+
});
|
|
1576
|
+
return depGroups;
|
|
1577
|
+
}
|
|
1578
|
+
executeSampling(args, schema) {
|
|
1579
|
+
const validationResult = this.validateSchema(args, schema);
|
|
1580
|
+
if (!validationResult.valid) {
|
|
1581
|
+
return {
|
|
1582
|
+
content: [
|
|
1583
|
+
{
|
|
1584
|
+
type: "text",
|
|
1585
|
+
text: CompiledPrompts.errorResponse({
|
|
1586
|
+
errorMessage: validationResult.error || "Validation failed"
|
|
1587
|
+
})
|
|
1588
|
+
}
|
|
1589
|
+
],
|
|
1590
|
+
isError: true
|
|
1591
|
+
};
|
|
1592
|
+
}
|
|
1593
|
+
const createArgsDef = createArgsDefFactory(this.name, this.allToolNames, this.buildDepGroups(), void 0, void 0);
|
|
1594
|
+
const agenticSchema = createArgsDef.forAgentic(this.toolNameToDetailList, true);
|
|
1595
|
+
const systemPrompt = this.buildSystemPrompt(args.userRequest, agenticSchema);
|
|
1596
|
+
return this.runSamplingLoop(() => systemPrompt, agenticSchema);
|
|
1597
|
+
}
|
|
1598
|
+
async processAction(parsedData, schema) {
|
|
1599
|
+
const toolCallData = parsedData;
|
|
1600
|
+
if (toolCallData.decision === "complete") {
|
|
1601
|
+
return this.createCompletionResult("Task completed");
|
|
1602
|
+
}
|
|
1603
|
+
try {
|
|
1604
|
+
const { action: _action, decision: _decision, ..._toolArgs } = toolCallData;
|
|
1605
|
+
const toolResult = await this.agenticExecutor.execute(toolCallData, schema);
|
|
1606
|
+
const resultText = toolResult.content?.filter((content) => content.type === "text")?.map((content) => content.text)?.join("\n") || "No result";
|
|
1607
|
+
this.conversationHistory.push({
|
|
1608
|
+
role: "assistant",
|
|
1609
|
+
content: {
|
|
1610
|
+
type: "text",
|
|
1611
|
+
text: resultText
|
|
1612
|
+
}
|
|
1613
|
+
});
|
|
1614
|
+
return toolResult;
|
|
1615
|
+
} catch (error) {
|
|
1616
|
+
return this.createExecutionError(error);
|
|
1617
|
+
}
|
|
1618
|
+
}
|
|
1619
|
+
buildSystemPrompt(userRequest, agenticSchema) {
|
|
1620
|
+
const toolList = this.allToolNames.map((name) => {
|
|
1621
|
+
const tool = this.toolNameToDetailList.find(([toolName]) => toolName === name);
|
|
1622
|
+
const toolSchema = this.server.getInternalToolSchema(name);
|
|
1623
|
+
if (tool && tool[1]) {
|
|
1624
|
+
return `- ${name}: ${tool[1].description || `Tool: ${name}`}`;
|
|
1625
|
+
} else if (toolSchema) {
|
|
1626
|
+
return `- ${name}: ${toolSchema.description}`;
|
|
1627
|
+
}
|
|
1628
|
+
return `- ${name}`;
|
|
1629
|
+
}).join("\n");
|
|
1630
|
+
const basePrompt = CompiledPrompts.samplingExecution({
|
|
1631
|
+
toolName: this.name,
|
|
1632
|
+
description: this.description,
|
|
1633
|
+
toolList
|
|
1634
|
+
});
|
|
1635
|
+
const taskPrompt = `
|
|
1636
|
+
|
|
1637
|
+
## Current Task
|
|
1638
|
+
I will now use agentic sampling to complete the following task: "${userRequest}"
|
|
1639
|
+
|
|
1640
|
+
When I need to use a tool, I should specify the tool name in 'action' and provide tool-specific parameters as additional properties.
|
|
1641
|
+
When the task is complete, I should use "action": "complete".`;
|
|
1642
|
+
return this.injectJsonInstruction({
|
|
1643
|
+
prompt: basePrompt + taskPrompt,
|
|
1644
|
+
schema: agenticSchema
|
|
1645
|
+
});
|
|
1646
|
+
}
|
|
1647
|
+
};
|
|
1648
|
+
|
|
1649
|
+
// ../__mcpc__core_0.2.0-beta.10/node_modules/@mcpc/core/src/executors/agentic/agentic-tool-registrar.js
|
|
1650
|
+
function registerAgenticTool(server, { description, name, allToolNames, depGroups, toolNameToDetailList, sampling = false }) {
|
|
1651
|
+
const createArgsDef = createArgsDefFactory(name, allToolNames, depGroups, void 0, void 0);
|
|
1652
|
+
const isSamplingMode = sampling === true || typeof sampling === "object";
|
|
1653
|
+
const samplingConfig = typeof sampling === "object" ? sampling : void 0;
|
|
1654
|
+
const agenticExecutor = new AgenticExecutor(name, allToolNames, toolNameToDetailList, server);
|
|
1655
|
+
const samplingExecutor = new SamplingExecutor(name, description, allToolNames, toolNameToDetailList, server, samplingConfig);
|
|
1656
|
+
description = isSamplingMode ? CompiledPrompts.samplingExecution({
|
|
1657
|
+
toolName: name,
|
|
1658
|
+
description,
|
|
1659
|
+
toolList: allToolNames.map((name2) => `- ${name2}`).join("\n")
|
|
1660
|
+
}) : CompiledPrompts.autonomousExecution({
|
|
1661
|
+
toolName: name,
|
|
1662
|
+
description
|
|
1663
|
+
});
|
|
1664
|
+
const agenticArgsDef = createArgsDef.forAgentic(toolNameToDetailList, false);
|
|
1665
|
+
const argsDef = isSamplingMode ? createArgsDef.forSampling() : agenticArgsDef;
|
|
1666
|
+
const schema = allToolNames.length > 0 ? argsDef : {
|
|
1667
|
+
type: "object",
|
|
1668
|
+
properties: {}
|
|
1669
|
+
};
|
|
1670
|
+
server.tool(name, description, jsonSchema(createGoogleCompatibleJSONSchema(schema)), async (args) => {
|
|
1671
|
+
if (isSamplingMode) {
|
|
1672
|
+
return await samplingExecutor.executeSampling(args, schema);
|
|
1673
|
+
} else {
|
|
1674
|
+
return await agenticExecutor.execute(args, schema);
|
|
1675
|
+
}
|
|
1676
|
+
});
|
|
1677
|
+
}
|
|
1678
|
+
|
|
1679
|
+
// ../__mcpc__core_0.2.0-beta.10/node_modules/@mcpc/core/src/executors/workflow/workflow-tool-registrar.js
|
|
1680
|
+
import { jsonSchema as jsonSchema2 } from "ai";
|
|
1681
|
+
|
|
1682
|
+
// ../__mcpc__core_0.2.0-beta.10/node_modules/@mcpc/core/src/utils/state.js
|
|
1683
|
+
var WorkflowState = class {
|
|
1684
|
+
currentStepIndex = -1;
|
|
1685
|
+
steps = [];
|
|
1686
|
+
stepStatuses = [];
|
|
1687
|
+
stepResults = [];
|
|
1688
|
+
stepErrors = [];
|
|
1689
|
+
isInitialized = false;
|
|
1690
|
+
isStarted = false;
|
|
1691
|
+
constructor(steps) {
|
|
1692
|
+
if (steps) {
|
|
1693
|
+
this.initialize(steps);
|
|
1694
|
+
}
|
|
1695
|
+
}
|
|
1696
|
+
getCurrentStepIndex() {
|
|
1697
|
+
return this.currentStepIndex;
|
|
1698
|
+
}
|
|
1699
|
+
getSteps() {
|
|
1700
|
+
return this.steps;
|
|
1701
|
+
}
|
|
1702
|
+
isWorkflowInitialized() {
|
|
1703
|
+
return this.isInitialized;
|
|
1704
|
+
}
|
|
1705
|
+
getCurrentStep() {
|
|
1706
|
+
if (!this.isInitialized || this.currentStepIndex < 0) {
|
|
1707
|
+
return null;
|
|
1708
|
+
}
|
|
1709
|
+
return this.steps[this.currentStepIndex] || null;
|
|
1710
|
+
}
|
|
1711
|
+
getNextStep() {
|
|
1712
|
+
if (!this.isInitialized) return null;
|
|
1713
|
+
const nextIndex = this.currentStepIndex + 1;
|
|
1714
|
+
return this.steps[nextIndex] || null;
|
|
1715
|
+
}
|
|
1716
|
+
// Get the previous step in the workflow
|
|
1717
|
+
getPreviousStep() {
|
|
1718
|
+
if (!this.isInitialized) return null;
|
|
1719
|
+
const prevIndex = this.currentStepIndex - 1;
|
|
1720
|
+
return this.steps[prevIndex] || null;
|
|
1721
|
+
}
|
|
1722
|
+
hasNextStep() {
|
|
1723
|
+
return this.getNextStep() !== null;
|
|
1724
|
+
}
|
|
1725
|
+
// Check if there is a previous step available
|
|
1726
|
+
hasPreviousStep() {
|
|
1727
|
+
return this.getPreviousStep() !== null;
|
|
1728
|
+
}
|
|
1729
|
+
// Check if currently at the first step
|
|
1730
|
+
isAtFirstStep() {
|
|
1731
|
+
return this.isInitialized && this.currentStepIndex === 0;
|
|
1732
|
+
}
|
|
1733
|
+
// Check if currently at the last step
|
|
1734
|
+
isAtLastStep() {
|
|
1735
|
+
return this.isInitialized && this.currentStepIndex >= this.steps.length - 1;
|
|
1736
|
+
}
|
|
1737
|
+
isWorkflowStarted() {
|
|
1738
|
+
return this.isStarted;
|
|
1739
|
+
}
|
|
1740
|
+
isCompleted() {
|
|
1741
|
+
return this.isInitialized && this.currentStepIndex > this.steps.length - 1;
|
|
1742
|
+
}
|
|
1743
|
+
// Mark workflow as completed by moving beyond the last step
|
|
1744
|
+
markCompleted() {
|
|
1745
|
+
if (this.isInitialized) {
|
|
1746
|
+
this.currentStepIndex = this.steps.length;
|
|
1747
|
+
}
|
|
1748
|
+
}
|
|
1749
|
+
initialize(steps) {
|
|
1750
|
+
this.steps = steps;
|
|
1751
|
+
this.stepStatuses = new Array(steps.length).fill("pending");
|
|
1752
|
+
this.stepResults = new Array(steps.length).fill("");
|
|
1753
|
+
this.stepErrors = new Array(steps.length).fill("");
|
|
1754
|
+
this.currentStepIndex = 0;
|
|
1755
|
+
this.isInitialized = true;
|
|
1756
|
+
this.isStarted = false;
|
|
1757
|
+
}
|
|
1758
|
+
// Mark current step as running
|
|
1759
|
+
markCurrentStepRunning() {
|
|
1760
|
+
if (this.isInitialized && this.currentStepIndex >= 0 && this.currentStepIndex < this.steps.length) {
|
|
1761
|
+
this.stepStatuses[this.currentStepIndex] = "running";
|
|
1762
|
+
}
|
|
1763
|
+
}
|
|
1764
|
+
// Mark current step as completed
|
|
1765
|
+
markCurrentStepCompleted(result) {
|
|
1766
|
+
if (this.isInitialized && this.currentStepIndex >= 0 && this.currentStepIndex < this.steps.length) {
|
|
1767
|
+
this.stepStatuses[this.currentStepIndex] = "completed";
|
|
1768
|
+
if (result) {
|
|
1769
|
+
this.stepResults[this.currentStepIndex] = result;
|
|
1770
|
+
}
|
|
1771
|
+
}
|
|
1772
|
+
}
|
|
1773
|
+
// Mark current step as failed
|
|
1774
|
+
markCurrentStepFailed(error) {
|
|
1775
|
+
if (this.isInitialized && this.currentStepIndex >= 0 && this.currentStepIndex < this.steps.length) {
|
|
1776
|
+
this.stepStatuses[this.currentStepIndex] = "failed";
|
|
1777
|
+
if (error) {
|
|
1778
|
+
this.stepErrors[this.currentStepIndex] = error;
|
|
1779
|
+
}
|
|
1780
|
+
}
|
|
1781
|
+
}
|
|
1782
|
+
// Get steps with their status
|
|
1783
|
+
getStepsWithStatus() {
|
|
1784
|
+
return this.steps.map((step, index) => ({
|
|
1785
|
+
...step,
|
|
1786
|
+
status: this.stepStatuses[index] || "pending",
|
|
1787
|
+
result: this.stepResults[index] || void 0,
|
|
1788
|
+
error: this.stepErrors[index] || void 0
|
|
1789
|
+
}));
|
|
1790
|
+
}
|
|
1791
|
+
// Get basic workflow progress data for template rendering
|
|
1792
|
+
getProgressData() {
|
|
1793
|
+
return {
|
|
1794
|
+
steps: this.steps,
|
|
1795
|
+
statuses: this.stepStatuses,
|
|
1796
|
+
results: this.stepResults,
|
|
1797
|
+
errors: this.stepErrors,
|
|
1798
|
+
currentStepIndex: this.currentStepIndex,
|
|
1799
|
+
totalSteps: this.steps.length
|
|
1800
|
+
};
|
|
1801
|
+
}
|
|
1802
|
+
start() {
|
|
1803
|
+
this.isStarted = true;
|
|
1804
|
+
}
|
|
1805
|
+
moveToNextStep() {
|
|
1806
|
+
if (!this.hasNextStep()) {
|
|
1807
|
+
return false;
|
|
1808
|
+
}
|
|
1809
|
+
this.currentStepIndex++;
|
|
1810
|
+
return true;
|
|
1811
|
+
}
|
|
1812
|
+
// Move to the previous step in the workflow
|
|
1813
|
+
moveToPreviousStep() {
|
|
1814
|
+
if (!this.hasPreviousStep()) {
|
|
1815
|
+
return false;
|
|
1816
|
+
}
|
|
1817
|
+
this.currentStepIndex--;
|
|
1818
|
+
return true;
|
|
1819
|
+
}
|
|
1820
|
+
// Move to a specific step by index (optional feature)
|
|
1821
|
+
moveToStep(stepIndex) {
|
|
1822
|
+
if (!this.isInitialized || stepIndex < 0 || stepIndex >= this.steps.length) {
|
|
1823
|
+
return false;
|
|
1824
|
+
}
|
|
1825
|
+
this.currentStepIndex = stepIndex;
|
|
1826
|
+
return true;
|
|
1827
|
+
}
|
|
1828
|
+
reset() {
|
|
1829
|
+
this.currentStepIndex = -1;
|
|
1830
|
+
this.steps = [];
|
|
1831
|
+
this.stepStatuses = [];
|
|
1832
|
+
this.stepResults = [];
|
|
1833
|
+
this.stepErrors = [];
|
|
1834
|
+
this.isInitialized = false;
|
|
1835
|
+
this.isStarted = false;
|
|
1836
|
+
}
|
|
1837
|
+
getDebugInfo() {
|
|
1838
|
+
return {
|
|
1839
|
+
currentStepIndex: this.currentStepIndex,
|
|
1840
|
+
totalSteps: this.steps.length,
|
|
1841
|
+
isInitialized: this.isInitialized,
|
|
1842
|
+
currentStep: this.getCurrentStep()?.description,
|
|
1843
|
+
nextStep: this.getNextStep()?.description,
|
|
1844
|
+
previousStep: this.getPreviousStep()?.description,
|
|
1845
|
+
isAtFirstStep: this.isAtFirstStep(),
|
|
1846
|
+
hasPreviousStep: this.hasPreviousStep()
|
|
1847
|
+
};
|
|
1848
|
+
}
|
|
1849
|
+
};
|
|
1850
|
+
|
|
1851
|
+
// ../__mcpc__core_0.2.0-beta.10/node_modules/@mcpc/core/src/executors/workflow/workflow-executor.js
|
|
1852
|
+
import { Ajv as Ajv3 } from "ajv";
|
|
1853
|
+
import { AggregateAjvError as AggregateAjvError3 } from "@segment/ajv-human-errors";
|
|
1854
|
+
import addFormats3 from "ajv-formats";
|
|
1855
|
+
var ajv3 = new Ajv3({
|
|
1856
|
+
allErrors: true,
|
|
1857
|
+
verbose: true
|
|
1858
|
+
});
|
|
1859
|
+
addFormats3(ajv3);
|
|
1860
|
+
var WorkflowExecutor = class {
|
|
1861
|
+
name;
|
|
1862
|
+
allToolNames;
|
|
1863
|
+
toolNameToDetailList;
|
|
1864
|
+
createArgsDef;
|
|
1865
|
+
server;
|
|
1866
|
+
predefinedSteps;
|
|
1867
|
+
ensureStepActions;
|
|
1868
|
+
toolNameToIdMapping;
|
|
1869
|
+
constructor(name, allToolNames, toolNameToDetailList, createArgsDef, server, predefinedSteps, ensureStepActions, toolNameToIdMapping) {
|
|
1870
|
+
this.name = name;
|
|
1871
|
+
this.allToolNames = allToolNames;
|
|
1872
|
+
this.toolNameToDetailList = toolNameToDetailList;
|
|
1873
|
+
this.createArgsDef = createArgsDef;
|
|
1874
|
+
this.server = server;
|
|
1875
|
+
this.predefinedSteps = predefinedSteps;
|
|
1876
|
+
this.ensureStepActions = ensureStepActions;
|
|
1877
|
+
this.toolNameToIdMapping = toolNameToIdMapping;
|
|
1878
|
+
}
|
|
1879
|
+
// Helper method to validate required actions are present in workflow steps
|
|
1880
|
+
validateRequiredActions(steps) {
|
|
1881
|
+
if (!this.ensureStepActions || this.ensureStepActions.length === 0) {
|
|
1882
|
+
return {
|
|
1883
|
+
valid: true,
|
|
1884
|
+
missing: []
|
|
1885
|
+
};
|
|
1886
|
+
}
|
|
1887
|
+
const allStepActions = /* @__PURE__ */ new Set();
|
|
1888
|
+
steps.forEach((step) => {
|
|
1889
|
+
step.actions.forEach((action) => allStepActions.add(action));
|
|
1890
|
+
});
|
|
1891
|
+
const missing = [];
|
|
1892
|
+
for (const requiredAction of this.ensureStepActions) {
|
|
1893
|
+
if (allStepActions.has(requiredAction)) {
|
|
1894
|
+
continue;
|
|
1895
|
+
}
|
|
1896
|
+
if (this.toolNameToIdMapping) {
|
|
1897
|
+
const mappedToolId = this.toolNameToIdMapping.get(requiredAction);
|
|
1898
|
+
if (mappedToolId && allStepActions.has(mappedToolId)) {
|
|
1899
|
+
continue;
|
|
1900
|
+
}
|
|
1901
|
+
}
|
|
1902
|
+
missing.push(requiredAction);
|
|
1903
|
+
}
|
|
1904
|
+
return {
|
|
1905
|
+
valid: missing.length === 0,
|
|
1906
|
+
missing
|
|
1907
|
+
};
|
|
1908
|
+
}
|
|
1909
|
+
// Helper method to format workflow progress
|
|
1910
|
+
formatProgress(state) {
|
|
1911
|
+
const progressData = state.getProgressData();
|
|
1912
|
+
return PromptUtils.formatWorkflowProgress(progressData);
|
|
1913
|
+
}
|
|
1914
|
+
async execute(args, state) {
|
|
1915
|
+
if (args.init) {
|
|
1916
|
+
state.reset();
|
|
1917
|
+
} else {
|
|
1918
|
+
if (!state.isWorkflowInitialized() && !args.init) {
|
|
1919
|
+
return {
|
|
1920
|
+
content: [
|
|
1921
|
+
{
|
|
1922
|
+
type: "text",
|
|
1923
|
+
text: this.predefinedSteps ? WorkflowPrompts.ERRORS.NOT_INITIALIZED.WITH_PREDEFINED : WorkflowPrompts.ERRORS.NOT_INITIALIZED.WITHOUT_PREDEFINED
|
|
1924
|
+
}
|
|
1925
|
+
],
|
|
1926
|
+
isError: true
|
|
1927
|
+
};
|
|
1928
|
+
}
|
|
1929
|
+
const decision2 = args.decision;
|
|
1930
|
+
if (decision2 === "proceed") {
|
|
1931
|
+
if (state.isAtLastStep() && state.isWorkflowStarted()) {
|
|
1932
|
+
state.markCompleted();
|
|
1933
|
+
return {
|
|
1934
|
+
content: [
|
|
1935
|
+
{
|
|
1936
|
+
type: "text",
|
|
1937
|
+
text: `## Workflow Completed!
|
|
1938
|
+
|
|
1939
|
+
${this.formatProgress(state)}
|
|
1940
|
+
|
|
1941
|
+
${CompiledPrompts.workflowCompleted({
|
|
1942
|
+
totalSteps: state.getSteps().length,
|
|
1943
|
+
toolName: this.name,
|
|
1944
|
+
newWorkflowInstructions: this.predefinedSteps ? "" : " and new `steps` array"
|
|
1945
|
+
})}`
|
|
1946
|
+
}
|
|
1947
|
+
],
|
|
1948
|
+
isError: false
|
|
1949
|
+
};
|
|
1950
|
+
}
|
|
1951
|
+
if (state.isCompleted()) {
|
|
1952
|
+
return {
|
|
1953
|
+
content: [
|
|
1954
|
+
{
|
|
1955
|
+
type: "text",
|
|
1956
|
+
text: WorkflowPrompts.ERRORS.ALREADY_AT_FINAL
|
|
1957
|
+
}
|
|
1958
|
+
],
|
|
1959
|
+
isError: true
|
|
1960
|
+
};
|
|
1961
|
+
}
|
|
1962
|
+
const currentStepIndex = state.getCurrentStepIndex();
|
|
1963
|
+
const wasStarted = state.isWorkflowStarted();
|
|
1964
|
+
if (state.isWorkflowStarted()) {
|
|
1965
|
+
state.moveToNextStep();
|
|
1966
|
+
} else {
|
|
1967
|
+
state.start();
|
|
1968
|
+
}
|
|
1969
|
+
const nextStepValidationSchema = this.createArgsDef.forCurrentState(state);
|
|
1970
|
+
const nextStepValidationResult = this.validate(args, nextStepValidationSchema);
|
|
1971
|
+
if (!nextStepValidationResult.valid) {
|
|
1972
|
+
if (wasStarted) {
|
|
1973
|
+
state.moveToStep(currentStepIndex);
|
|
1974
|
+
} else {
|
|
1975
|
+
state.moveToStep(currentStepIndex);
|
|
1976
|
+
}
|
|
1977
|
+
return {
|
|
1978
|
+
content: [
|
|
1979
|
+
{
|
|
1980
|
+
type: "text",
|
|
1981
|
+
text: CompiledPrompts.workflowErrorResponse({
|
|
1982
|
+
errorMessage: `Cannot proceed to next step: ${nextStepValidationResult.error || "Arguments validation failed"}`
|
|
1983
|
+
})
|
|
1984
|
+
}
|
|
1985
|
+
],
|
|
1986
|
+
isError: true
|
|
1987
|
+
};
|
|
1988
|
+
}
|
|
1989
|
+
} else if (decision2 === "complete") {
|
|
1990
|
+
if (state.isAtLastStep() && state.isWorkflowStarted()) {
|
|
1991
|
+
state.markCompleted();
|
|
1992
|
+
return {
|
|
1993
|
+
content: [
|
|
1994
|
+
{
|
|
1995
|
+
type: "text",
|
|
1996
|
+
text: `## Workflow Completed!
|
|
1997
|
+
|
|
1998
|
+
${this.formatProgress(state)}
|
|
1999
|
+
|
|
2000
|
+
${CompiledPrompts.workflowCompleted({
|
|
2001
|
+
totalSteps: state.getSteps().length,
|
|
2002
|
+
toolName: this.name,
|
|
2003
|
+
newWorkflowInstructions: this.predefinedSteps ? "" : " and new `steps` array"
|
|
2004
|
+
})}`
|
|
2005
|
+
}
|
|
2006
|
+
],
|
|
2007
|
+
isError: false
|
|
2008
|
+
};
|
|
2009
|
+
} else {
|
|
2010
|
+
return {
|
|
2011
|
+
content: [
|
|
2012
|
+
{
|
|
2013
|
+
type: "text",
|
|
2014
|
+
text: WorkflowPrompts.ERRORS.CANNOT_COMPLETE_NOT_AT_FINAL
|
|
2015
|
+
}
|
|
2016
|
+
],
|
|
2017
|
+
isError: true
|
|
2018
|
+
};
|
|
2019
|
+
}
|
|
2020
|
+
}
|
|
2021
|
+
}
|
|
2022
|
+
const decision = args.decision;
|
|
2023
|
+
if (decision !== "proceed") {
|
|
2024
|
+
const validationSchema = this.createArgsDef.forCurrentState(state);
|
|
2025
|
+
const validationResult = this.validate(args, validationSchema);
|
|
2026
|
+
if (!validationResult.valid) {
|
|
2027
|
+
return {
|
|
2028
|
+
content: [
|
|
2029
|
+
{
|
|
2030
|
+
type: "text",
|
|
2031
|
+
text: CompiledPrompts.workflowErrorResponse({
|
|
2032
|
+
errorMessage: validationResult.error || "Arguments validation failed"
|
|
2033
|
+
})
|
|
2034
|
+
}
|
|
2035
|
+
],
|
|
2036
|
+
isError: true
|
|
2037
|
+
};
|
|
2038
|
+
}
|
|
2039
|
+
}
|
|
2040
|
+
if (args.init) {
|
|
2041
|
+
return this.initialize(args, state);
|
|
2042
|
+
}
|
|
2043
|
+
return await this.executeStep(args, state);
|
|
2044
|
+
}
|
|
2045
|
+
initialize(args, state) {
|
|
2046
|
+
const steps = args.steps ?? this.predefinedSteps;
|
|
2047
|
+
if (!steps || steps.length === 0) {
|
|
2048
|
+
return {
|
|
2049
|
+
content: [
|
|
2050
|
+
{
|
|
2051
|
+
type: "text",
|
|
2052
|
+
text: WorkflowPrompts.ERRORS.NO_STEPS_PROVIDED
|
|
2053
|
+
}
|
|
2054
|
+
],
|
|
2055
|
+
isError: true
|
|
2056
|
+
};
|
|
2057
|
+
}
|
|
2058
|
+
const validation = this.validateRequiredActions(steps);
|
|
2059
|
+
if (!validation.valid) {
|
|
2060
|
+
return {
|
|
2061
|
+
content: [
|
|
2062
|
+
{
|
|
2063
|
+
type: "text",
|
|
2064
|
+
text: `## Workflow Validation Failed \u274C
|
|
2065
|
+
|
|
2066
|
+
**Missing Required Actions:** The following actions must be included in the workflow steps:
|
|
2067
|
+
|
|
2068
|
+
${validation.missing.map((action) => `- \`${this.toolNameToIdMapping?.get(action) ?? action}\``).join("\n")}`
|
|
2069
|
+
}
|
|
2070
|
+
],
|
|
2071
|
+
isError: true
|
|
2072
|
+
};
|
|
2073
|
+
}
|
|
2074
|
+
state.initialize(steps);
|
|
2075
|
+
return {
|
|
2076
|
+
content: [
|
|
2077
|
+
{
|
|
2078
|
+
type: "text",
|
|
2079
|
+
text: `## Workflow Initialized
|
|
2080
|
+
${this.formatProgress(state)}
|
|
2081
|
+
${this.createArgsDef.forInitialStepDescription(steps, state)}`
|
|
2082
|
+
}
|
|
2083
|
+
],
|
|
2084
|
+
isError: false
|
|
2085
|
+
};
|
|
2086
|
+
}
|
|
2087
|
+
async executeStep(args, state) {
|
|
2088
|
+
const currentStep = state.getCurrentStep();
|
|
2089
|
+
if (!currentStep) {
|
|
2090
|
+
return {
|
|
2091
|
+
content: [
|
|
2092
|
+
{
|
|
2093
|
+
type: "text",
|
|
2094
|
+
text: WorkflowPrompts.ERRORS.NO_CURRENT_STEP
|
|
2095
|
+
}
|
|
2096
|
+
],
|
|
2097
|
+
isError: true
|
|
2098
|
+
};
|
|
2099
|
+
}
|
|
2100
|
+
state.markCurrentStepRunning();
|
|
2101
|
+
const results = {
|
|
2102
|
+
content: [],
|
|
2103
|
+
isError: false
|
|
2104
|
+
};
|
|
2105
|
+
for (const action of currentStep.actions) {
|
|
2106
|
+
try {
|
|
2107
|
+
const actionArgs = args[action] || {};
|
|
2108
|
+
const actionResult = await this.server.callTool(action, actionArgs);
|
|
2109
|
+
if (!results.isError) {
|
|
2110
|
+
results.isError = actionResult.isError;
|
|
2111
|
+
}
|
|
2112
|
+
results.content = results.content.concat(actionResult.content ?? []);
|
|
2113
|
+
results.content.push({
|
|
2114
|
+
type: "text",
|
|
2115
|
+
text: `Action \`${action}\` executed ${actionResult.isError ? "\u274C **FAILED**" : "\u2705 **SUCCESS**"}:`
|
|
2116
|
+
});
|
|
2117
|
+
} catch (error) {
|
|
2118
|
+
results.content.push({
|
|
2119
|
+
type: "text",
|
|
2120
|
+
text: `${error.message}`
|
|
2121
|
+
});
|
|
2122
|
+
results.content.push({
|
|
2123
|
+
type: "text",
|
|
2124
|
+
text: `Action \`${action}\` \u274C **FAILED** with error: `
|
|
2125
|
+
});
|
|
2126
|
+
results.isError = true;
|
|
2127
|
+
}
|
|
2128
|
+
}
|
|
2129
|
+
if (results.isError) {
|
|
2130
|
+
state.markCurrentStepFailed("Step execution failed");
|
|
2131
|
+
} else {
|
|
2132
|
+
state.markCurrentStepCompleted("Step completed successfully");
|
|
2133
|
+
}
|
|
2134
|
+
if (state.hasNextStep()) {
|
|
2135
|
+
const nextStepArgsDef = this.createArgsDef.forNextState(state);
|
|
2136
|
+
results.content.push({
|
|
2137
|
+
type: "text",
|
|
2138
|
+
text: CompiledPrompts.nextStepDecision({
|
|
2139
|
+
toolName: this.name,
|
|
2140
|
+
nextStepDescription: state.getNextStep()?.description || "Unknown step",
|
|
2141
|
+
nextStepSchema: JSON.stringify(nextStepArgsDef, null, 2)
|
|
2142
|
+
})
|
|
2143
|
+
});
|
|
2144
|
+
} else {
|
|
2145
|
+
results.content.push({
|
|
2146
|
+
type: "text",
|
|
2147
|
+
text: CompiledPrompts.finalStepCompletion({
|
|
2148
|
+
statusIcon: results.isError ? "\u274C" : "\u2705",
|
|
2149
|
+
statusText: results.isError ? "with errors" : "successfully",
|
|
2150
|
+
toolName: this.name,
|
|
2151
|
+
newWorkflowInstructions: this.predefinedSteps ? "" : " and new `steps` array"
|
|
2152
|
+
})
|
|
2153
|
+
});
|
|
2154
|
+
}
|
|
2155
|
+
results.content.push({
|
|
2156
|
+
type: "text",
|
|
2157
|
+
text: `## Workflow Progress
|
|
2158
|
+
${this.formatProgress(state)}`
|
|
2159
|
+
});
|
|
2160
|
+
return results;
|
|
2161
|
+
}
|
|
2162
|
+
// Validate arguments using JSON schema
|
|
2163
|
+
validate(args, schema) {
|
|
2164
|
+
const validate = ajv3.compile(schema);
|
|
2165
|
+
if (!validate(args)) {
|
|
2166
|
+
const errors = new AggregateAjvError3(validate.errors);
|
|
2167
|
+
return {
|
|
2168
|
+
valid: false,
|
|
2169
|
+
error: errors.message
|
|
2170
|
+
};
|
|
2171
|
+
}
|
|
2172
|
+
return {
|
|
2173
|
+
valid: true
|
|
2174
|
+
};
|
|
2175
|
+
}
|
|
2176
|
+
};
|
|
2177
|
+
|
|
2178
|
+
// ../__mcpc__core_0.2.0-beta.10/node_modules/@mcpc/core/src/executors/sampling/workflow-sampling-executor.js
|
|
2179
|
+
var WorkflowSamplingExecutor = class extends BaseSamplingExecutor {
|
|
2180
|
+
createArgsDef;
|
|
2181
|
+
predefinedSteps;
|
|
2182
|
+
workflowExecutor;
|
|
2183
|
+
constructor(name, description, allToolNames, toolNameToDetailList, createArgsDef, server, predefinedSteps, config) {
|
|
2184
|
+
super(name, description, allToolNames, toolNameToDetailList, server, config), this.createArgsDef = createArgsDef, this.predefinedSteps = predefinedSteps;
|
|
2185
|
+
this.workflowExecutor = new WorkflowExecutor(name, allToolNames, toolNameToDetailList, createArgsDef, server, predefinedSteps);
|
|
2186
|
+
}
|
|
2187
|
+
async executeWorkflowSampling(args, schema, state) {
|
|
2188
|
+
const validationResult = this.validateSchema(args, schema);
|
|
2189
|
+
if (!validationResult.valid) {
|
|
2190
|
+
return {
|
|
2191
|
+
content: [
|
|
2192
|
+
{
|
|
2193
|
+
type: "text",
|
|
2194
|
+
text: CompiledPrompts.workflowErrorResponse({
|
|
2195
|
+
errorMessage: validationResult.error || "Validation failed"
|
|
2196
|
+
})
|
|
2197
|
+
}
|
|
2198
|
+
],
|
|
2199
|
+
isError: true
|
|
2200
|
+
};
|
|
2201
|
+
}
|
|
2202
|
+
return await this.runSamplingLoop(() => this.buildWorkflowSystemPrompt(args, state), schema, state);
|
|
2203
|
+
}
|
|
2204
|
+
async processAction(parsedData, _schema, state) {
|
|
2205
|
+
const workflowState = state;
|
|
2206
|
+
if (!workflowState) {
|
|
2207
|
+
throw new Error("WorkflowState is required for workflow");
|
|
2208
|
+
}
|
|
2209
|
+
const toolCallData = parsedData;
|
|
2210
|
+
if (toolCallData.decision === "complete") {
|
|
2211
|
+
return this.createCompletionResult("Task completed");
|
|
2212
|
+
}
|
|
2213
|
+
try {
|
|
2214
|
+
const workflowResult = await this.workflowExecutor.execute(parsedData, workflowState);
|
|
2215
|
+
const resultText = workflowResult.content?.filter((content) => content.type === "text")?.map((content) => content.text)?.join("\n") || "No result";
|
|
2216
|
+
this.conversationHistory.push({
|
|
2217
|
+
role: "assistant",
|
|
2218
|
+
content: {
|
|
2219
|
+
type: "text",
|
|
2220
|
+
text: resultText
|
|
2221
|
+
}
|
|
2222
|
+
});
|
|
2223
|
+
return workflowResult;
|
|
2224
|
+
} catch (error) {
|
|
2225
|
+
return this.createExecutionError(error);
|
|
2226
|
+
}
|
|
2227
|
+
}
|
|
2228
|
+
buildWorkflowSystemPrompt(args, state) {
|
|
2229
|
+
const workflowSchema = this.createArgsDef.forCurrentState(state);
|
|
2230
|
+
const basePrompt = CompiledPrompts.samplingWorkflowExecution({
|
|
2231
|
+
toolName: this.name,
|
|
2232
|
+
description: this.description,
|
|
2233
|
+
workflowSchema: `${JSON.stringify(workflowSchema, null, 2)}`
|
|
2234
|
+
});
|
|
2235
|
+
const workflowPrompt = `
|
|
2236
|
+
|
|
2237
|
+
Current Task: <user_request>${args.userRequest}</user_request>`;
|
|
2238
|
+
return this.injectJsonInstruction({
|
|
2239
|
+
prompt: basePrompt + workflowPrompt,
|
|
2240
|
+
schema: workflowSchema
|
|
2241
|
+
});
|
|
2242
|
+
}
|
|
2243
|
+
};
|
|
2244
|
+
|
|
2245
|
+
// ../__mcpc__core_0.2.0-beta.10/node_modules/@mcpc/core/src/executors/workflow/workflow-tool-registrar.js
|
|
2246
|
+
function registerAgenticWorkflowTool(server, { description, name, allToolNames, depGroups, toolNameToDetailList, predefinedSteps, sampling = false, ensureStepActions, toolNameToIdMapping }) {
|
|
2247
|
+
const createArgsDef = createArgsDefFactory(name, allToolNames, depGroups, predefinedSteps, ensureStepActions);
|
|
2248
|
+
const isSamplingMode = sampling === true || typeof sampling === "object";
|
|
2249
|
+
const samplingConfig = typeof sampling === "object" ? sampling : void 0;
|
|
2250
|
+
const workflowExecutor = new WorkflowExecutor(name, allToolNames, toolNameToDetailList, createArgsDef, server, predefinedSteps, ensureStepActions, toolNameToIdMapping);
|
|
2251
|
+
const workflowSamplingExecutor = new WorkflowSamplingExecutor(name, description, allToolNames, toolNameToDetailList, createArgsDef, server, predefinedSteps, samplingConfig);
|
|
2252
|
+
const workflowState = new WorkflowState();
|
|
2253
|
+
const planningInstructions = predefinedSteps ? "- Set `init: true` (steps are predefined)" : "- Set `init: true` and define complete `steps` array";
|
|
2254
|
+
const baseDescription = isSamplingMode ? CompiledPrompts.samplingExecution({
|
|
2255
|
+
toolName: name,
|
|
2256
|
+
description,
|
|
2257
|
+
toolList: allToolNames.map((name2) => `- ${name2}`).join("\n")
|
|
2258
|
+
}) : CompiledPrompts.workflowExecution({
|
|
2259
|
+
toolName: name,
|
|
2260
|
+
description,
|
|
2261
|
+
planningInstructions
|
|
2262
|
+
});
|
|
2263
|
+
const argsDef = isSamplingMode ? createArgsDef.forSampling() : createArgsDef.forTool();
|
|
2264
|
+
const toolDescription = isSamplingMode ? baseDescription : createArgsDef.forToolDescription(baseDescription, workflowState);
|
|
2265
|
+
server.tool(name, toolDescription, jsonSchema2(createGoogleCompatibleJSONSchema(argsDef)), async (args) => {
|
|
2266
|
+
try {
|
|
2267
|
+
if (isSamplingMode) {
|
|
2268
|
+
return await workflowSamplingExecutor.executeWorkflowSampling(args, argsDef, workflowState);
|
|
2269
|
+
} else {
|
|
2270
|
+
return await workflowExecutor.execute(args, workflowState);
|
|
2271
|
+
}
|
|
2272
|
+
} catch (error) {
|
|
2273
|
+
workflowState.reset();
|
|
2274
|
+
return {
|
|
2275
|
+
content: [
|
|
2276
|
+
{
|
|
2277
|
+
type: "text",
|
|
2278
|
+
text: `Workflow execution error: ${error.message}`
|
|
2279
|
+
}
|
|
2280
|
+
],
|
|
2281
|
+
isError: true
|
|
2282
|
+
};
|
|
2283
|
+
}
|
|
2284
|
+
});
|
|
2285
|
+
}
|
|
2286
|
+
|
|
2287
|
+
// ../__mcpc__core_0.2.0-beta.10/node_modules/@mcpc/core/src/utils/common/tool-tag-processor.js
|
|
2288
|
+
var ALL_TOOLS_PLACEHOLDER = "__ALL__";
|
|
2289
|
+
function findToolId(toolName, tools, toolNameMapping) {
|
|
2290
|
+
const mappedId = toolNameMapping?.get(toolName);
|
|
2291
|
+
if (mappedId) {
|
|
2292
|
+
return mappedId;
|
|
2293
|
+
}
|
|
2294
|
+
return Object.keys(tools).find((id) => {
|
|
2295
|
+
const dotNotation = id.replace(/_/g, ".");
|
|
2296
|
+
return toolName === id || toolName === dotNotation;
|
|
2297
|
+
});
|
|
2298
|
+
}
|
|
2299
|
+
function processToolTags({ description, tagToResults, $, tools, toolOverrides, toolNameMapping }) {
|
|
2300
|
+
tagToResults.tool.forEach((toolEl) => {
|
|
2301
|
+
const toolName = toolEl.attribs.name;
|
|
2302
|
+
if (!toolName || toolName.includes(ALL_TOOLS_PLACEHOLDER)) {
|
|
2303
|
+
$(toolEl).remove();
|
|
2304
|
+
return;
|
|
2305
|
+
}
|
|
2306
|
+
const override = toolOverrides.get(toolName);
|
|
2307
|
+
if (override?.visibility?.hide) {
|
|
2308
|
+
$(toolEl).remove();
|
|
2309
|
+
} else if (override?.visibility?.global) {
|
|
2310
|
+
$(toolEl).replaceWith(`<tool name="${toolName}"/>`);
|
|
2311
|
+
} else {
|
|
2312
|
+
const toolId = findToolId(toolName, tools, toolNameMapping);
|
|
2313
|
+
if (toolId) {
|
|
2314
|
+
$(toolEl).replaceWith(`<action action="${toolId}"/>`);
|
|
2315
|
+
}
|
|
2316
|
+
}
|
|
2317
|
+
});
|
|
2318
|
+
return $.root().html() ?? description;
|
|
2319
|
+
}
|
|
2320
|
+
|
|
2321
|
+
// ../__mcpc__core_0.2.0-beta.10/node_modules/@mcpc/core/src/compose.js
|
|
2322
|
+
init_built_in();
|
|
2323
|
+
|
|
2324
|
+
// ../__mcpc__core_0.2.0-beta.10/node_modules/@mcpc/core/src/plugin-utils.js
|
|
2325
|
+
function shouldApplyPlugin(plugin, mode) {
|
|
2326
|
+
if (!plugin.apply) return true;
|
|
2327
|
+
if (typeof plugin.apply === "string") {
|
|
2328
|
+
return mode.includes(plugin.apply);
|
|
2329
|
+
}
|
|
2330
|
+
if (typeof plugin.apply === "function") {
|
|
2331
|
+
return plugin.apply(mode);
|
|
2332
|
+
}
|
|
2333
|
+
return plugin.apply;
|
|
2334
|
+
}
|
|
2335
|
+
function isValidPlugin(plugin) {
|
|
2336
|
+
return plugin && plugin.name && (plugin.configureServer || plugin.composeStart || plugin.transformTool || plugin.finalizeComposition || plugin.composeEnd);
|
|
2337
|
+
}
|
|
2338
|
+
async function loadPlugin(pluginPath) {
|
|
2339
|
+
try {
|
|
2340
|
+
const [rawPath, queryString] = pluginPath.split("?", 2);
|
|
2341
|
+
const searchParams = new URLSearchParams(queryString || "");
|
|
2342
|
+
const params = Object.fromEntries(searchParams.entries());
|
|
2343
|
+
const pluginModule = await import(rawPath);
|
|
2344
|
+
const pluginFactory = pluginModule.createPlugin;
|
|
2345
|
+
const defaultPlugin = pluginModule.default;
|
|
2346
|
+
let plugin;
|
|
2347
|
+
if (Object.keys(params).length > 0) {
|
|
2348
|
+
if (typeof pluginFactory === "function") {
|
|
2349
|
+
const typedParams = {};
|
|
2350
|
+
for (const [key, value] of Object.entries(params)) {
|
|
2351
|
+
const numValue = Number(value);
|
|
2352
|
+
if (!isNaN(numValue)) {
|
|
2353
|
+
typedParams[key] = numValue;
|
|
2354
|
+
} else if (value === "true") {
|
|
2355
|
+
typedParams[key] = true;
|
|
2356
|
+
} else if (value === "false") {
|
|
2357
|
+
typedParams[key] = false;
|
|
2358
|
+
} else {
|
|
2359
|
+
typedParams[key] = value;
|
|
2360
|
+
}
|
|
2361
|
+
}
|
|
2362
|
+
plugin = pluginFactory(typedParams);
|
|
2363
|
+
} else {
|
|
2364
|
+
throw new Error(`Plugin ${rawPath} has parameters but no createPlugin export`);
|
|
2365
|
+
}
|
|
2366
|
+
} else {
|
|
2367
|
+
plugin = defaultPlugin;
|
|
2368
|
+
}
|
|
2369
|
+
if (isValidPlugin(plugin)) {
|
|
2370
|
+
return plugin;
|
|
2371
|
+
} else {
|
|
2372
|
+
throw new Error(`Invalid plugin format in ${rawPath} - plugin must have a name and at least one lifecycle hook`);
|
|
2373
|
+
}
|
|
2374
|
+
} catch (error) {
|
|
2375
|
+
throw new Error(`Failed to load plugin from ${pluginPath}: ${error}`);
|
|
2376
|
+
}
|
|
2377
|
+
}
|
|
2378
|
+
|
|
2379
|
+
// ../__mcpc__core_0.2.0-beta.10/node_modules/@mcpc/core/src/compose.js
|
|
2380
|
+
var ALL_TOOLS_PLACEHOLDER2 = "__ALL__";
|
|
2381
|
+
var ComposableMCPServer = class extends Server {
|
|
2382
|
+
tools = [];
|
|
2383
|
+
toolRegistry = /* @__PURE__ */ new Map();
|
|
2384
|
+
toolConfigs = /* @__PURE__ */ new Map();
|
|
2385
|
+
globalPlugins = [];
|
|
2386
|
+
toolNameMapping = /* @__PURE__ */ new Map();
|
|
2387
|
+
constructor(_serverInfo, options) {
|
|
2388
|
+
super(_serverInfo, options);
|
|
2389
|
+
}
|
|
2390
|
+
/**
|
|
2391
|
+
* Initialize built-in plugins - called during setup
|
|
2392
|
+
*/
|
|
2393
|
+
async initBuiltInPlugins() {
|
|
2394
|
+
const builtInPlugins = getBuiltInPlugins();
|
|
2395
|
+
for (const plugin of builtInPlugins) {
|
|
2396
|
+
await this.addPlugin(plugin);
|
|
2397
|
+
}
|
|
2398
|
+
}
|
|
2399
|
+
/**
|
|
2400
|
+
* Apply plugin transformations to tool arguments/results
|
|
2401
|
+
* TODO: Implement transformResult lifecycle hooks
|
|
2402
|
+
*/
|
|
2403
|
+
applyPluginTransforms(_toolName, args, _mode, _originalArgs) {
|
|
2404
|
+
return args;
|
|
2405
|
+
}
|
|
2406
|
+
/**
|
|
2407
|
+
* Resolve a tool name to its internal format
|
|
2408
|
+
*/
|
|
2409
|
+
resolveToolName(name) {
|
|
2410
|
+
if (this.toolRegistry.has(name)) {
|
|
2411
|
+
return name;
|
|
2412
|
+
}
|
|
2413
|
+
const mappedName = this.toolNameMapping.get(name);
|
|
2414
|
+
if (mappedName && this.toolRegistry.has(mappedName)) {
|
|
2415
|
+
return mappedName;
|
|
2416
|
+
}
|
|
2417
|
+
if (this.toolConfigs.has(name)) {
|
|
2418
|
+
const cfgMapped = this.toolNameMapping.get(name);
|
|
2419
|
+
if (cfgMapped && this.toolRegistry.has(cfgMapped)) {
|
|
2420
|
+
return cfgMapped;
|
|
2421
|
+
}
|
|
2422
|
+
}
|
|
2423
|
+
return void 0;
|
|
2424
|
+
}
|
|
2425
|
+
tool(name, description, paramsSchema, cb, options = {}) {
|
|
2426
|
+
this.toolRegistry.set(name, {
|
|
2427
|
+
callback: cb,
|
|
2428
|
+
description,
|
|
2429
|
+
schema: paramsSchema.jsonSchema
|
|
2430
|
+
});
|
|
2431
|
+
if (options.plugins) {
|
|
2432
|
+
for (const plugin of options.plugins) {
|
|
2433
|
+
this.globalPlugins.push(plugin);
|
|
2434
|
+
}
|
|
2435
|
+
}
|
|
2436
|
+
if (options.internal) {
|
|
2437
|
+
this.toolConfigs.set(name, {
|
|
2438
|
+
visibility: {
|
|
2439
|
+
internal: true
|
|
2440
|
+
}
|
|
2441
|
+
});
|
|
2442
|
+
} else {
|
|
2443
|
+
const existingTool = this.tools.find((t) => t.name === name);
|
|
2444
|
+
if (!existingTool) {
|
|
2445
|
+
const newTool = {
|
|
2446
|
+
name,
|
|
2447
|
+
description,
|
|
2448
|
+
inputSchema: paramsSchema.jsonSchema
|
|
2449
|
+
};
|
|
2450
|
+
this.tools = [
|
|
2451
|
+
...this.tools,
|
|
2452
|
+
newTool
|
|
2453
|
+
];
|
|
2454
|
+
}
|
|
2455
|
+
}
|
|
2456
|
+
this.setRequestHandler(ListToolsRequestSchema, () => {
|
|
2457
|
+
return {
|
|
2458
|
+
tools: this.tools
|
|
2459
|
+
};
|
|
2460
|
+
});
|
|
2461
|
+
this.setRequestHandler(CallToolRequestSchema, (request, extra) => {
|
|
2462
|
+
const { name: toolName, arguments: args } = request.params;
|
|
2463
|
+
const handler = this.getToolCallback(toolName);
|
|
2464
|
+
if (!handler) {
|
|
2465
|
+
throw new Error(`Tool ${toolName} not found`);
|
|
2466
|
+
}
|
|
2467
|
+
const processedArgs = this.applyPluginTransforms(toolName, args, "input");
|
|
2468
|
+
const result = handler(processedArgs, extra);
|
|
2469
|
+
return this.applyPluginTransforms(toolName, result, "output", args);
|
|
2470
|
+
});
|
|
2471
|
+
}
|
|
2472
|
+
/**
|
|
2473
|
+
* Register a tool override with description, hide, args transformation, and/or custom handler
|
|
2474
|
+
*/
|
|
2475
|
+
/**
|
|
2476
|
+
* Get tool callback from registry
|
|
2477
|
+
*/
|
|
2478
|
+
getToolCallback(name) {
|
|
2479
|
+
return this.toolRegistry.get(name)?.callback;
|
|
2480
|
+
}
|
|
2481
|
+
/**
|
|
2482
|
+
* Find tool configuration (simplified - dot/underscore mapping now handled by plugin)
|
|
2483
|
+
*/
|
|
2484
|
+
findToolConfig(toolId) {
|
|
2485
|
+
const directConfig = this.toolConfigs.get(toolId);
|
|
2486
|
+
if (directConfig) {
|
|
2487
|
+
return directConfig;
|
|
2488
|
+
}
|
|
2489
|
+
const mappedName = this.toolNameMapping.get(toolId);
|
|
2490
|
+
if (mappedName && this.toolConfigs.has(mappedName)) {
|
|
2491
|
+
return this.toolConfigs.get(mappedName);
|
|
2492
|
+
}
|
|
2493
|
+
return void 0;
|
|
2494
|
+
}
|
|
2495
|
+
/**
|
|
2496
|
+
* Call any registered tool directly, whether it's public or internal
|
|
2497
|
+
*/
|
|
2498
|
+
async callTool(name, args) {
|
|
2499
|
+
const resolvedName = this.resolveToolName(name);
|
|
2500
|
+
if (!resolvedName) {
|
|
2501
|
+
throw new Error(`Tool ${name} not found`);
|
|
2502
|
+
}
|
|
2503
|
+
const callback = this.getToolCallback(resolvedName);
|
|
2504
|
+
if (!callback) {
|
|
2505
|
+
throw new Error(`Tool ${name} not found`);
|
|
2506
|
+
}
|
|
2507
|
+
const processedArgs = this.applyPluginTransforms(resolvedName, args, "input");
|
|
2508
|
+
const result = await callback(processedArgs);
|
|
2509
|
+
return this.applyPluginTransforms(resolvedName, result, "output", args);
|
|
2510
|
+
}
|
|
2511
|
+
/**
|
|
2512
|
+
* Get all internal tool names
|
|
2513
|
+
*/
|
|
2514
|
+
getInternalToolNames() {
|
|
2515
|
+
return Array.from(this.toolConfigs.entries()).filter(([_name, config]) => config.visibility?.internal).map(([name]) => this.resolveToolName(name) ?? name);
|
|
2516
|
+
}
|
|
2517
|
+
/**
|
|
2518
|
+
* Get all public tool names
|
|
2519
|
+
*/
|
|
2520
|
+
getPublicToolNames() {
|
|
2521
|
+
return Array.from(this.toolConfigs.entries()).filter(([_name, config]) => config.visibility?.global).map(([name]) => this.resolveToolName(name) ?? name);
|
|
2522
|
+
}
|
|
2523
|
+
/**
|
|
2524
|
+
* Get all external (non-global, non-internal, non-hidden) tool names
|
|
2525
|
+
*/
|
|
2526
|
+
getExternalToolNames() {
|
|
2527
|
+
const allRegistered = Array.from(this.toolRegistry.keys());
|
|
2528
|
+
const publicSet = new Set(this.getPublicToolNames());
|
|
2529
|
+
const internalSet = new Set(this.getInternalToolNames());
|
|
2530
|
+
const hiddenSet = new Set(this.getHiddenToolNames());
|
|
2531
|
+
return allRegistered.filter((n) => !publicSet.has(n) && !internalSet.has(n) && !hiddenSet.has(n));
|
|
2532
|
+
}
|
|
2533
|
+
/**
|
|
2534
|
+
* Get all hidden tool names
|
|
2535
|
+
*/
|
|
2536
|
+
getHiddenToolNames() {
|
|
2537
|
+
return Array.from(this.toolConfigs.entries()).filter(([_name, config]) => config.visibility?.hide).map(([name]) => this.resolveToolName(name) ?? name);
|
|
2538
|
+
}
|
|
2539
|
+
/**
|
|
2540
|
+
* Get internal tool schema by name
|
|
2541
|
+
*/
|
|
2542
|
+
getInternalToolSchema(name) {
|
|
2543
|
+
const tool = this.toolRegistry.get(name);
|
|
2544
|
+
const config = this.toolConfigs.get(name);
|
|
2545
|
+
if (tool && config?.visibility?.internal && tool.schema) {
|
|
2546
|
+
return {
|
|
2547
|
+
description: tool.description,
|
|
2548
|
+
schema: tool.schema
|
|
2549
|
+
};
|
|
2550
|
+
}
|
|
2551
|
+
return void 0;
|
|
2552
|
+
}
|
|
2553
|
+
/**
|
|
2554
|
+
* Check if a tool exists (visible or internal)
|
|
2555
|
+
*/
|
|
2556
|
+
hasToolNamed(name) {
|
|
2557
|
+
return this.toolRegistry.has(name) || this.toolNameMapping.has(name) && this.toolRegistry.has(this.toolNameMapping.get(name));
|
|
2558
|
+
}
|
|
2559
|
+
/**
|
|
2560
|
+
* Configure tool behavior (simplified replacement for middleware)
|
|
2561
|
+
* @example
|
|
2562
|
+
* ```typescript
|
|
2563
|
+
* // Override description
|
|
2564
|
+
* server.configTool('myTool', {
|
|
2565
|
+
* callback: originalCallback,
|
|
2566
|
+
* description: 'Enhanced tool description'
|
|
2567
|
+
* });
|
|
2568
|
+
*
|
|
2569
|
+
* // Hide tool from agentic execution
|
|
2570
|
+
* server.configTool('myTool', {
|
|
2571
|
+
* callback: originalCallback,
|
|
2572
|
+
* description: 'Hidden tool',
|
|
2573
|
+
* visibility: { hide: true }
|
|
2574
|
+
* });
|
|
2575
|
+
*
|
|
2576
|
+
* // Make tool globally available
|
|
2577
|
+
* server.configTool('myTool', {
|
|
2578
|
+
* callback: originalCallback,
|
|
2579
|
+
* description: 'Global tool',
|
|
2580
|
+
* visibility: { global: true }
|
|
2581
|
+
* });
|
|
2582
|
+
* ```
|
|
2583
|
+
*/
|
|
2584
|
+
configTool(toolName, config) {
|
|
2585
|
+
this.toolConfigs.set(toolName, config);
|
|
2586
|
+
}
|
|
2587
|
+
/**
|
|
2588
|
+
* Get tool configuration
|
|
2589
|
+
*/
|
|
2590
|
+
getToolConfig(toolName) {
|
|
2591
|
+
return this.toolConfigs.get(toolName);
|
|
2592
|
+
}
|
|
2593
|
+
/**
|
|
2594
|
+
* Remove tool configuration
|
|
2595
|
+
*/
|
|
2596
|
+
removeToolConfig(toolName) {
|
|
2597
|
+
return this.toolConfigs.delete(toolName);
|
|
2598
|
+
}
|
|
2599
|
+
/**
|
|
2600
|
+
* Register a tool plugin
|
|
2601
|
+
* @example
|
|
2602
|
+
* ```typescript
|
|
2603
|
+
* // Global plugin for all tools
|
|
2604
|
+
* server.addPlugin({
|
|
2605
|
+
* name: 'logger',
|
|
2606
|
+
* transformTool: (tool, context) => {
|
|
2607
|
+
* const originalExecute = tool.execute;
|
|
2608
|
+
* tool.execute = async (args, extra) => {
|
|
2609
|
+
* console.log(`Calling ${tool.name} with:`, args);
|
|
2610
|
+
* const result = await originalExecute(args, extra);
|
|
2611
|
+
* console.log(`Result:`, result);
|
|
2612
|
+
* return result;
|
|
2613
|
+
* };
|
|
2614
|
+
* return tool;
|
|
2615
|
+
* }
|
|
2616
|
+
* });
|
|
2617
|
+
* ```
|
|
2618
|
+
*/
|
|
2619
|
+
async addPlugin(plugin) {
|
|
2620
|
+
if (plugin.configureServer) {
|
|
2621
|
+
await plugin.configureServer(this);
|
|
2622
|
+
}
|
|
2623
|
+
this.globalPlugins.push(plugin);
|
|
2624
|
+
}
|
|
2625
|
+
/**
|
|
2626
|
+
* Load and register a plugin from a file path with optional parameters
|
|
2627
|
+
*
|
|
2628
|
+
* Supports parameter passing via query string syntax:
|
|
2629
|
+
* loadPluginFromPath("path/to/plugin.ts?param1=value1¶m2=value2")
|
|
2630
|
+
*/
|
|
2631
|
+
async loadPluginFromPath(pluginPath) {
|
|
2632
|
+
const plugin = await loadPlugin(pluginPath);
|
|
2633
|
+
this.addPlugin(plugin);
|
|
2634
|
+
}
|
|
2635
|
+
/**
|
|
2636
|
+
* Apply transformTool hook to a tool during composition
|
|
2637
|
+
*/
|
|
2638
|
+
async applyTransformToolHooks(tool, toolName, mode) {
|
|
2639
|
+
const transformPlugins = this.globalPlugins.filter((p2) => p2.transformTool && shouldApplyPlugin(p2, mode));
|
|
2640
|
+
if (transformPlugins.length === 0) {
|
|
2641
|
+
return tool;
|
|
2642
|
+
}
|
|
2643
|
+
const sortedPlugins = [
|
|
2644
|
+
...transformPlugins.filter((p2) => p2.enforce === "pre"),
|
|
2645
|
+
...transformPlugins.filter((p2) => !p2.enforce),
|
|
2646
|
+
...transformPlugins.filter((p2) => p2.enforce === "post")
|
|
2647
|
+
];
|
|
2648
|
+
const context = {
|
|
2649
|
+
toolName,
|
|
2650
|
+
server: this,
|
|
2651
|
+
mode
|
|
2652
|
+
};
|
|
2653
|
+
let currentTool = tool;
|
|
2654
|
+
for (const plugin of sortedPlugins) {
|
|
2655
|
+
if (plugin.transformTool) {
|
|
2656
|
+
const result = await plugin.transformTool(currentTool, context);
|
|
2657
|
+
if (result) {
|
|
2658
|
+
currentTool = result;
|
|
2659
|
+
}
|
|
2660
|
+
}
|
|
2661
|
+
}
|
|
2662
|
+
return currentTool;
|
|
2663
|
+
}
|
|
2664
|
+
/**
|
|
2665
|
+
* Apply plugins to all tools in registry and handle visibility configurations
|
|
2666
|
+
*/
|
|
2667
|
+
async processToolsWithPlugins(externalTools, mode) {
|
|
2668
|
+
for (const [toolId, toolData] of this.toolRegistry.entries()) {
|
|
2669
|
+
const defaultSchema = {
|
|
2670
|
+
type: "object",
|
|
2671
|
+
properties: {},
|
|
2672
|
+
additionalProperties: true
|
|
2673
|
+
};
|
|
2674
|
+
const tempTool = {
|
|
2675
|
+
name: toolId,
|
|
2676
|
+
description: toolData.description,
|
|
2677
|
+
inputSchema: toolData.schema || defaultSchema,
|
|
2678
|
+
execute: toolData.callback
|
|
2679
|
+
};
|
|
2680
|
+
const processedTool = await this.applyTransformToolHooks(tempTool, toolId, mode);
|
|
2681
|
+
this.toolRegistry.set(toolId, {
|
|
2682
|
+
callback: processedTool.execute,
|
|
2683
|
+
description: processedTool.description || toolData.description,
|
|
2684
|
+
schema: processedTool.inputSchema
|
|
2685
|
+
});
|
|
2686
|
+
if (externalTools[toolId]) {
|
|
2687
|
+
try {
|
|
2688
|
+
const builtIn = await Promise.resolve().then(() => (init_built_in(), built_in_exports));
|
|
2689
|
+
if (builtIn && typeof builtIn.processToolVisibility === "function") {
|
|
2690
|
+
builtIn.processToolVisibility(toolId, processedTool, this, externalTools);
|
|
2691
|
+
}
|
|
2692
|
+
} catch {
|
|
2693
|
+
}
|
|
2694
|
+
externalTools[toolId] = processedTool;
|
|
2695
|
+
}
|
|
2696
|
+
}
|
|
2697
|
+
}
|
|
2698
|
+
/**
|
|
2699
|
+
* Trigger composeEnd hooks for all plugins
|
|
2700
|
+
*/
|
|
2701
|
+
async triggerComposeEndHooks(context) {
|
|
2702
|
+
const endPlugins = this.globalPlugins.filter((p2) => p2.composeEnd && shouldApplyPlugin(p2, context.mode));
|
|
2703
|
+
for (const plugin of endPlugins) {
|
|
2704
|
+
if (plugin.composeEnd) {
|
|
2705
|
+
await plugin.composeEnd(context);
|
|
2706
|
+
}
|
|
2707
|
+
}
|
|
2708
|
+
}
|
|
2709
|
+
async compose(name, description, depsConfig = {
|
|
2710
|
+
mcpServers: {}
|
|
2711
|
+
}, options = {
|
|
2712
|
+
mode: "agentic"
|
|
2713
|
+
}) {
|
|
2714
|
+
const refDesc = options.refs?.join("") ?? "";
|
|
2715
|
+
const { tagToResults } = parseTags(description + refDesc, [
|
|
2716
|
+
"tool",
|
|
2717
|
+
"fn"
|
|
2718
|
+
]);
|
|
2719
|
+
tagToResults.tool.forEach((toolEl) => {
|
|
2720
|
+
const toolName = toolEl.attribs.name;
|
|
2721
|
+
const toolDescription = toolEl.attribs.description;
|
|
2722
|
+
const isHidden = toolEl.attribs.hide !== void 0;
|
|
2723
|
+
const isGlobal = toolEl.attribs.global !== void 0;
|
|
2724
|
+
if (toolName) {
|
|
2725
|
+
this.toolConfigs.set(toolName, {
|
|
2726
|
+
description: toolDescription,
|
|
2727
|
+
visibility: {
|
|
2728
|
+
hide: isHidden,
|
|
2729
|
+
global: isGlobal
|
|
2730
|
+
}
|
|
2731
|
+
});
|
|
2732
|
+
}
|
|
2733
|
+
});
|
|
2734
|
+
const toolNameToIdMapping = /* @__PURE__ */ new Map();
|
|
2735
|
+
const requestedToolNames = /* @__PURE__ */ new Set();
|
|
2736
|
+
const availableToolNames = /* @__PURE__ */ new Set();
|
|
2737
|
+
tagToResults.tool.forEach((tool) => {
|
|
2738
|
+
if (tool.attribs.name) {
|
|
2739
|
+
requestedToolNames.add(tool.attribs.name);
|
|
2740
|
+
}
|
|
2741
|
+
});
|
|
2742
|
+
const { tools, cleanupClients } = await composeMcpDepTools(depsConfig, ({ mcpName, toolNameWithScope, toolId }) => {
|
|
2743
|
+
toolNameToIdMapping.set(toolNameWithScope, toolId);
|
|
2744
|
+
availableToolNames.add(toolNameWithScope);
|
|
2745
|
+
availableToolNames.add(toolId);
|
|
2746
|
+
availableToolNames.add(`${mcpName}.${ALL_TOOLS_PLACEHOLDER2}`);
|
|
2747
|
+
availableToolNames.add(mcpName);
|
|
2748
|
+
this.toolNameMapping.set(toolNameWithScope, toolId);
|
|
2749
|
+
const internalName = toolNameWithScope.includes(".") ? toolNameWithScope.split(".").slice(1).join(".") : toolNameWithScope;
|
|
2750
|
+
if (!this.toolNameMapping.has(internalName)) {
|
|
2751
|
+
this.toolNameMapping.set(internalName, toolId);
|
|
2752
|
+
}
|
|
2753
|
+
const matchingStep = options.steps?.find((step) => step.actions.includes(toolNameWithScope));
|
|
2754
|
+
if (matchingStep) {
|
|
2755
|
+
const actionIndex = matchingStep.actions.indexOf(toolNameWithScope);
|
|
2756
|
+
if (actionIndex !== -1) {
|
|
2757
|
+
matchingStep.actions[actionIndex] = toolId;
|
|
2758
|
+
}
|
|
2759
|
+
return true;
|
|
2760
|
+
}
|
|
2761
|
+
return tagToResults.tool.find((tool) => {
|
|
2762
|
+
const selectAll = tool.attribs.name === `${mcpName}.${ALL_TOOLS_PLACEHOLDER2}` || tool.attribs.name === `${mcpName}`;
|
|
2763
|
+
if (selectAll) {
|
|
2764
|
+
return true;
|
|
2765
|
+
}
|
|
2766
|
+
return tool.attribs.name === toolNameWithScope || tool.attribs.name === toolId;
|
|
2767
|
+
});
|
|
2768
|
+
});
|
|
2769
|
+
const unmatchedTools = Array.from(requestedToolNames).filter((toolName) => !availableToolNames.has(toolName));
|
|
2770
|
+
if (unmatchedTools.length > 0) {
|
|
2771
|
+
console.warn(`\u26A0\uFE0F Tool matching warnings for agent "${name}":`);
|
|
2772
|
+
unmatchedTools.forEach((toolName) => {
|
|
2773
|
+
console.warn(` \u2022 Tool not found: "${toolName}"`);
|
|
2774
|
+
});
|
|
2775
|
+
console.warn(` Available tools: ${Array.from(availableToolNames).sort().join(", ")}`);
|
|
2776
|
+
}
|
|
2777
|
+
Object.entries(tools).forEach(([toolId, tool]) => {
|
|
2778
|
+
this.toolRegistry.set(toolId, {
|
|
2779
|
+
callback: tool.execute,
|
|
2780
|
+
description: tool.description || "No description available",
|
|
2781
|
+
schema: tool.inputSchema
|
|
2782
|
+
});
|
|
2783
|
+
});
|
|
2784
|
+
await this.processToolsWithPlugins(tools, options.mode ?? "agentic");
|
|
2785
|
+
this.onclose = async () => {
|
|
2786
|
+
await cleanupClients();
|
|
2787
|
+
console.log(`\u{1F9E9} [${name}]`);
|
|
2788
|
+
console.log(` \u251C\u2500 Event: closed`);
|
|
2789
|
+
console.log(` \u2514\u2500 Action: cleaned up dependent clients`);
|
|
2790
|
+
};
|
|
2791
|
+
this.onerror = async (error) => {
|
|
2792
|
+
console.log(`\u{1F9E9} [${name}]`);
|
|
2793
|
+
console.log(` \u251C\u2500 Event: error, ${error?.stack ?? String(error)}`);
|
|
2794
|
+
await cleanupClients();
|
|
2795
|
+
console.log(` \u2514\u2500 Action: cleaned up dependent clients`);
|
|
2796
|
+
};
|
|
2797
|
+
const toolNameToDetailList = Object.entries(tools);
|
|
2798
|
+
const globalToolNames = this.getPublicToolNames();
|
|
2799
|
+
const hideToolNames = this.getHiddenToolNames();
|
|
2800
|
+
const internalToolNames = this.getInternalToolNames();
|
|
2801
|
+
const contextToolNames = toolNameToDetailList.map(([name2]) => name2).filter((n) => !globalToolNames.includes(n) && !hideToolNames.includes(n));
|
|
2802
|
+
const allToolNames = [
|
|
2803
|
+
...contextToolNames,
|
|
2804
|
+
...internalToolNames
|
|
2805
|
+
];
|
|
2806
|
+
globalToolNames.forEach((toolId) => {
|
|
2807
|
+
const tool = tools[toolId];
|
|
2808
|
+
if (!tool) {
|
|
2809
|
+
throw new Error(`Global tool ${toolId} not found in registry, available: ${Object.keys(tools).join(", ")}`);
|
|
2810
|
+
}
|
|
2811
|
+
this.tool(toolId, tool.description || "No description available", jsonSchema3(tool.inputSchema), tool.execute);
|
|
2812
|
+
});
|
|
2813
|
+
await this.triggerComposeEndHooks({
|
|
2814
|
+
toolName: name,
|
|
2815
|
+
pluginNames: this.globalPlugins.map((p2) => p2.name),
|
|
2816
|
+
mode: options.mode ?? "agentic",
|
|
2817
|
+
server: this
|
|
2818
|
+
});
|
|
2819
|
+
if (!name) {
|
|
2820
|
+
return;
|
|
2821
|
+
}
|
|
2822
|
+
const desTags = parseTags(description, [
|
|
2823
|
+
"tool",
|
|
2824
|
+
"fn"
|
|
2825
|
+
]);
|
|
2826
|
+
description = processToolTags({
|
|
2827
|
+
...desTags,
|
|
2828
|
+
description,
|
|
2829
|
+
tools,
|
|
2830
|
+
toolOverrides: this.toolConfigs,
|
|
2831
|
+
toolNameMapping: toolNameToIdMapping
|
|
2832
|
+
});
|
|
2833
|
+
const depGroups = {};
|
|
2834
|
+
toolNameToDetailList.forEach(([toolName, tool]) => {
|
|
2835
|
+
if (hideToolNames.includes(this.resolveToolName(toolName) ?? "") || globalToolNames.includes(this.resolveToolName(toolName) ?? "")) {
|
|
2836
|
+
return;
|
|
2837
|
+
}
|
|
2838
|
+
if (!tool) {
|
|
2839
|
+
throw new Error(`Action ${toolName} not found, available action list: ${allToolNames.join(", ")}`);
|
|
2840
|
+
}
|
|
2841
|
+
const baseSchema = (
|
|
2842
|
+
// Compatiable with ComposiableleMCPServer.tool() definition
|
|
2843
|
+
tool.inputSchema.jsonSchema ?? // Standard definition
|
|
2844
|
+
tool.inputSchema ?? {
|
|
2845
|
+
type: "object",
|
|
2846
|
+
properties: {},
|
|
2847
|
+
required: []
|
|
2848
|
+
}
|
|
2849
|
+
);
|
|
2850
|
+
const baseProperties = baseSchema.type === "object" && baseSchema.properties ? baseSchema.properties : {};
|
|
2851
|
+
const baseRequired = baseSchema.type === "object" && Array.isArray(baseSchema.required) ? baseSchema.required : [];
|
|
2852
|
+
const updatedProperties = updateRefPaths(baseProperties, toolName);
|
|
2853
|
+
depGroups[toolName] = {
|
|
2854
|
+
type: "object",
|
|
2855
|
+
description: tool.description,
|
|
2856
|
+
properties: updatedProperties,
|
|
2857
|
+
required: [
|
|
2858
|
+
...baseRequired
|
|
2859
|
+
],
|
|
2860
|
+
additionalProperties: false
|
|
2861
|
+
};
|
|
2862
|
+
});
|
|
2863
|
+
internalToolNames.forEach((toolName) => {
|
|
2864
|
+
const toolSchema = this.getInternalToolSchema(toolName);
|
|
2865
|
+
if (toolSchema) {
|
|
2866
|
+
depGroups[toolName] = {
|
|
2867
|
+
...toolSchema.schema,
|
|
2868
|
+
description: toolSchema.description
|
|
2869
|
+
};
|
|
2870
|
+
} else {
|
|
2871
|
+
throw new Error(`Internal tool schema not found for: ${toolName}`);
|
|
2872
|
+
}
|
|
2873
|
+
});
|
|
2874
|
+
switch (options.mode ?? "agentic") {
|
|
2875
|
+
case "agentic":
|
|
2876
|
+
registerAgenticTool(this, {
|
|
2877
|
+
description,
|
|
2878
|
+
name,
|
|
2879
|
+
allToolNames,
|
|
2880
|
+
depGroups,
|
|
2881
|
+
toolNameToDetailList,
|
|
2882
|
+
sampling: options.sampling
|
|
2883
|
+
});
|
|
2884
|
+
break;
|
|
2885
|
+
case "agentic_workflow":
|
|
2886
|
+
registerAgenticWorkflowTool(this, {
|
|
2887
|
+
description,
|
|
2888
|
+
name,
|
|
2889
|
+
allToolNames,
|
|
2890
|
+
depGroups,
|
|
2891
|
+
toolNameToDetailList,
|
|
2892
|
+
predefinedSteps: options.steps,
|
|
2893
|
+
sampling: options.sampling,
|
|
2894
|
+
ensureStepActions: options.ensureStepActions,
|
|
2895
|
+
toolNameToIdMapping
|
|
2896
|
+
});
|
|
2897
|
+
break;
|
|
2898
|
+
}
|
|
2899
|
+
}
|
|
2900
|
+
};
|
|
2901
|
+
|
|
2902
|
+
// ../__mcpc__core_0.2.0-beta.10/node_modules/@mcpc/core/src/utils/common/env.js
|
|
2903
|
+
import process4 from "node:process";
|
|
2904
|
+
var isProdEnv = () => process4.env.NODE_ENV === "production";
|
|
2905
|
+
var isSCF = () => Boolean(process4.env.SCF_RUNTIME || process4.env.PROD_SCF);
|
|
2906
|
+
if (isSCF()) {
|
|
2907
|
+
console.log({
|
|
2908
|
+
isSCF: isSCF(),
|
|
2909
|
+
SCF_RUNTIME: process4.env.SCF_RUNTIME
|
|
2910
|
+
});
|
|
2911
|
+
}
|
|
2912
|
+
|
|
2913
|
+
// ../__mcpc__core_0.2.0-beta.10/node_modules/@mcpc/core/src/set-up-mcp-compose.js
|
|
2914
|
+
function parseMcpcConfigs(conf) {
|
|
2915
|
+
const mcpcConfigs = conf ?? [];
|
|
2916
|
+
const newMcpcConfigs = [];
|
|
2917
|
+
for (const mcpcConfig of mcpcConfigs) {
|
|
2918
|
+
if (mcpcConfig?.deps?.mcpServers) {
|
|
2919
|
+
for (const [name, config] of Object.entries(mcpcConfig.deps.mcpServers)) {
|
|
2920
|
+
if (config.smitheryConfig) {
|
|
2921
|
+
const streamConfig = connectToSmitheryServer(config.smitheryConfig);
|
|
2922
|
+
mcpcConfig.deps.mcpServers[name] = streamConfig;
|
|
2923
|
+
}
|
|
2924
|
+
}
|
|
2925
|
+
}
|
|
2926
|
+
newMcpcConfigs.push(mcpcConfig);
|
|
2927
|
+
}
|
|
2928
|
+
return newMcpcConfigs;
|
|
2929
|
+
}
|
|
2930
|
+
async function mcpc(serverConf, composeConf, setupCallback) {
|
|
2931
|
+
const server = new ComposableMCPServer(...serverConf);
|
|
2932
|
+
const parsed = parseMcpcConfigs(composeConf);
|
|
2933
|
+
await server.initBuiltInPlugins();
|
|
2934
|
+
for (const mcpcConfig of parsed) {
|
|
2935
|
+
if (mcpcConfig.plugins) {
|
|
2936
|
+
for (const plugin of mcpcConfig.plugins) {
|
|
2937
|
+
if (typeof plugin === "string") {
|
|
2938
|
+
await server.loadPluginFromPath(plugin);
|
|
2939
|
+
} else {
|
|
2940
|
+
await server.addPlugin(plugin);
|
|
2941
|
+
}
|
|
2942
|
+
}
|
|
2943
|
+
}
|
|
2944
|
+
}
|
|
2945
|
+
if (setupCallback) {
|
|
2946
|
+
await setupCallback(server);
|
|
2947
|
+
}
|
|
2948
|
+
for (const mcpcConfig of parsed) {
|
|
2949
|
+
await server.compose(mcpcConfig.name, mcpcConfig.description ?? "", mcpcConfig.deps, mcpcConfig.options);
|
|
2950
|
+
}
|
|
2951
|
+
return server;
|
|
2952
|
+
}
|
|
2953
|
+
export {
|
|
2954
|
+
ComposableMCPServer,
|
|
2955
|
+
composeMcpDepTools,
|
|
2956
|
+
isProdEnv,
|
|
2957
|
+
isSCF,
|
|
2958
|
+
mcpc,
|
|
2959
|
+
optionalObject,
|
|
2960
|
+
parseJSON2 as parseJSON,
|
|
2961
|
+
parseMcpcConfigs,
|
|
2962
|
+
truncateJSON
|
|
2963
|
+
};
|