@juspay/neurolink 6.1.0 → 6.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -6
- package/dist/cli/commands/config.d.ts +13 -13
- package/dist/cli/index.js +3 -9
- package/dist/core/analytics.d.ts +11 -1
- package/dist/core/analytics.js +2 -2
- package/dist/core/base-provider.js +4 -18
- package/dist/core/dynamic-models.d.ts +8 -8
- package/dist/core/factory.js +3 -11
- package/dist/index.d.ts +2 -4
- package/dist/index.js +2 -11
- package/dist/lib/core/analytics.d.ts +11 -1
- package/dist/lib/core/analytics.js +2 -2
- package/dist/lib/core/base-provider.js +4 -18
- package/dist/lib/core/dynamic-models.d.ts +8 -8
- package/dist/lib/core/factory.js +3 -11
- package/dist/lib/index.d.ts +2 -4
- package/dist/lib/index.js +2 -11
- package/dist/lib/mcp/factory.d.ts +1 -1
- package/dist/lib/mcp/index.d.ts +7 -19
- package/dist/lib/mcp/index.js +15 -56
- package/dist/lib/neurolink.d.ts +1 -9
- package/dist/lib/neurolink.js +21 -70
- package/dist/lib/providers/amazon-bedrock.js +5 -16
- package/dist/lib/providers/anthropic-baseprovider.js +3 -21
- package/dist/lib/providers/anthropic.js +4 -7
- package/dist/lib/providers/azure-openai.js +4 -2
- package/dist/lib/providers/google-vertex.js +5 -9
- package/dist/lib/providers/huggingFace.js +5 -10
- package/dist/lib/providers/mistral.js +5 -8
- package/dist/lib/providers/openAI.js +4 -7
- package/dist/lib/utils/providerConfig.d.ts +117 -0
- package/dist/lib/utils/providerConfig.js +353 -0
- package/dist/lib/utils/providerUtils.d.ts +2 -1
- package/dist/lib/utils/providerUtils.js +53 -36
- package/dist/lib/utils/timeout.d.ts +72 -1
- package/dist/lib/utils/timeout.js +203 -2
- package/dist/mcp/factory.d.ts +1 -1
- package/dist/mcp/index.d.ts +7 -19
- package/dist/mcp/index.js +15 -56
- package/dist/neurolink.d.ts +1 -9
- package/dist/neurolink.js +21 -70
- package/dist/providers/amazon-bedrock.js +5 -16
- package/dist/providers/anthropic-baseprovider.js +3 -21
- package/dist/providers/anthropic.js +4 -7
- package/dist/providers/azure-openai.js +4 -2
- package/dist/providers/google-vertex.js +5 -9
- package/dist/providers/huggingFace.js +5 -10
- package/dist/providers/mistral.js +5 -8
- package/dist/providers/openAI.js +4 -7
- package/dist/utils/providerConfig.d.ts +117 -0
- package/dist/utils/providerConfig.js +353 -0
- package/dist/utils/providerUtils.d.ts +2 -1
- package/dist/utils/providerUtils.js +53 -36
- package/dist/utils/timeout.d.ts +72 -1
- package/dist/utils/timeout.js +203 -2
- package/package.json +1 -1
- package/dist/chat/client-utils.d.ts +0 -95
- package/dist/chat/client-utils.js +0 -315
- package/dist/chat/index.d.ts +0 -24
- package/dist/chat/index.js +0 -33
- package/dist/chat/session-storage.d.ts +0 -77
- package/dist/chat/session-storage.js +0 -233
- package/dist/chat/session.d.ts +0 -96
- package/dist/chat/session.js +0 -257
- package/dist/chat/sse-handler.d.ts +0 -49
- package/dist/chat/sse-handler.js +0 -259
- package/dist/chat/types.d.ts +0 -74
- package/dist/chat/types.js +0 -5
- package/dist/chat/websocket-chat-handler.d.ts +0 -37
- package/dist/chat/websocket-chat-handler.js +0 -262
- package/dist/cli/commands/mcp.d.ts +0 -20
- package/dist/cli/commands/mcp.js +0 -1272
- package/dist/core/defaults.d.ts +0 -19
- package/dist/core/defaults.js +0 -29
- package/dist/core/evaluation-config.d.ts +0 -29
- package/dist/core/evaluation-config.js +0 -144
- package/dist/factories/compatibility-factory.d.ts +0 -35
- package/dist/factories/compatibility-factory.js +0 -71
- package/dist/factories/provider-generate-factory.d.ts +0 -20
- package/dist/factories/provider-generate-factory.js +0 -93
- package/dist/lib/chat/client-utils.d.ts +0 -95
- package/dist/lib/chat/client-utils.js +0 -315
- package/dist/lib/chat/index.d.ts +0 -24
- package/dist/lib/chat/index.js +0 -33
- package/dist/lib/chat/session-storage.d.ts +0 -77
- package/dist/lib/chat/session-storage.js +0 -233
- package/dist/lib/chat/session.d.ts +0 -96
- package/dist/lib/chat/session.js +0 -257
- package/dist/lib/chat/sse-handler.d.ts +0 -49
- package/dist/lib/chat/sse-handler.js +0 -259
- package/dist/lib/chat/types.d.ts +0 -74
- package/dist/lib/chat/types.js +0 -5
- package/dist/lib/chat/websocket-chat-handler.d.ts +0 -37
- package/dist/lib/chat/websocket-chat-handler.js +0 -262
- package/dist/lib/core/defaults.d.ts +0 -19
- package/dist/lib/core/defaults.js +0 -29
- package/dist/lib/core/evaluation-config.d.ts +0 -29
- package/dist/lib/core/evaluation-config.js +0 -144
- package/dist/lib/factories/compatibility-factory.d.ts +0 -35
- package/dist/lib/factories/compatibility-factory.js +0 -71
- package/dist/lib/factories/provider-generate-factory.d.ts +0 -20
- package/dist/lib/factories/provider-generate-factory.js +0 -93
- package/dist/lib/mcp/adapters/plugin-bridge.d.ts +0 -40
- package/dist/lib/mcp/adapters/plugin-bridge.js +0 -89
- package/dist/lib/mcp/auto-discovery.d.ts +0 -62
- package/dist/lib/mcp/auto-discovery.js +0 -149
- package/dist/lib/mcp/client.d.ts +0 -68
- package/dist/lib/mcp/client.js +0 -248
- package/dist/lib/mcp/config.d.ts +0 -31
- package/dist/lib/mcp/config.js +0 -99
- package/dist/lib/mcp/context-manager.d.ts +0 -171
- package/dist/lib/mcp/context-manager.js +0 -362
- package/dist/lib/mcp/contracts/mcp-contract.d.ts +0 -169
- package/dist/lib/mcp/contracts/mcp-contract.js +0 -58
- package/dist/lib/mcp/core/plugin-manager.d.ts +0 -46
- package/dist/lib/mcp/core/plugin-manager.js +0 -110
- package/dist/lib/mcp/demo/plugin-demo.d.ts +0 -20
- package/dist/lib/mcp/demo/plugin-demo.js +0 -118
- package/dist/lib/mcp/dynamic-chain-executor.d.ts +0 -225
- package/dist/lib/mcp/dynamic-chain-executor.js +0 -489
- package/dist/lib/mcp/dynamic-orchestrator.d.ts +0 -115
- package/dist/lib/mcp/dynamic-orchestrator.js +0 -351
- package/dist/lib/mcp/ecosystem.d.ts +0 -75
- package/dist/lib/mcp/ecosystem.js +0 -161
- package/dist/lib/mcp/error-manager.d.ts +0 -254
- package/dist/lib/mcp/error-manager.js +0 -501
- package/dist/lib/mcp/error-recovery.d.ts +0 -159
- package/dist/lib/mcp/error-recovery.js +0 -405
- package/dist/lib/mcp/external-client.d.ts +0 -88
- package/dist/lib/mcp/external-client.js +0 -331
- package/dist/lib/mcp/external-manager.d.ts +0 -112
- package/dist/lib/mcp/external-manager.js +0 -308
- package/dist/lib/mcp/function-calling.d.ts +0 -65
- package/dist/lib/mcp/function-calling.js +0 -642
- package/dist/lib/mcp/health-monitor.d.ts +0 -257
- package/dist/lib/mcp/health-monitor.js +0 -630
- package/dist/lib/mcp/initialize-tools.d.ts +0 -29
- package/dist/lib/mcp/initialize-tools.js +0 -261
- package/dist/lib/mcp/initialize.d.ts +0 -18
- package/dist/lib/mcp/initialize.js +0 -62
- package/dist/lib/mcp/manager.d.ts +0 -68
- package/dist/lib/mcp/manager.js +0 -176
- package/dist/lib/mcp/neurolink-mcp-client.d.ts +0 -97
- package/dist/lib/mcp/neurolink-mcp-client.js +0 -462
- package/dist/lib/mcp/orchestrator.d.ts +0 -302
- package/dist/lib/mcp/orchestrator.js +0 -703
- package/dist/lib/mcp/plugin-manager.d.ts +0 -98
- package/dist/lib/mcp/plugin-manager.js +0 -296
- package/dist/lib/mcp/plugins/core/filesystem-mcp.d.ts +0 -36
- package/dist/lib/mcp/plugins/core/filesystem-mcp.js +0 -142
- package/dist/lib/mcp/plugins/filesystem-mcp.d.ts +0 -37
- package/dist/lib/mcp/plugins/filesystem-mcp.js +0 -54
- package/dist/lib/mcp/security-manager.d.ts +0 -87
- package/dist/lib/mcp/security-manager.js +0 -344
- package/dist/lib/mcp/semaphore-manager.d.ts +0 -137
- package/dist/lib/mcp/semaphore-manager.js +0 -329
- package/dist/lib/mcp/session-manager.d.ts +0 -187
- package/dist/lib/mcp/session-manager.js +0 -400
- package/dist/lib/mcp/session-persistence.d.ts +0 -93
- package/dist/lib/mcp/session-persistence.js +0 -301
- package/dist/lib/mcp/tool-integration.d.ts +0 -58
- package/dist/lib/mcp/tool-integration.js +0 -203
- package/dist/lib/mcp/transport-manager.d.ts +0 -154
- package/dist/lib/mcp/transport-manager.js +0 -334
- package/dist/lib/mcp/unified-mcp.d.ts +0 -133
- package/dist/lib/mcp/unified-mcp.js +0 -251
- package/dist/lib/mcp/unified-registry.d.ts +0 -165
- package/dist/lib/mcp/unified-registry.js +0 -538
- package/dist/lib/providers/analytics-helper.d.ts +0 -38
- package/dist/lib/providers/analytics-helper.js +0 -216
- package/dist/lib/providers/function-calling-provider.d.ts +0 -142
- package/dist/lib/providers/function-calling-provider.js +0 -630
- package/dist/lib/providers/mcp-provider.d.ts +0 -75
- package/dist/lib/providers/mcp-provider.js +0 -283
- package/dist/lib/providers/timeout-wrapper.d.ts +0 -40
- package/dist/lib/providers/timeout-wrapper.js +0 -100
- package/dist/lib/sdk/tool-extension.d.ts +0 -181
- package/dist/lib/sdk/tool-extension.js +0 -284
- package/dist/lib/services/streaming/streaming-manager.d.ts +0 -29
- package/dist/lib/services/streaming/streaming-manager.js +0 -245
- package/dist/lib/services/types.d.ts +0 -156
- package/dist/lib/services/types.js +0 -2
- package/dist/lib/services/websocket/websocket-server.d.ts +0 -34
- package/dist/lib/services/websocket/websocket-server.js +0 -305
- package/dist/lib/utils/provider-validation.d.ts +0 -36
- package/dist/lib/utils/provider-validation.js +0 -625
- package/dist/lib/utils/providerUtils-fixed.d.ts +0 -8
- package/dist/lib/utils/providerUtils-fixed.js +0 -94
- package/dist/lib/utils/streaming-utils.d.ts +0 -79
- package/dist/lib/utils/streaming-utils.js +0 -198
- package/dist/lib/utils/timeout-manager.d.ts +0 -75
- package/dist/lib/utils/timeout-manager.js +0 -244
- package/dist/mcp/adapters/plugin-bridge.d.ts +0 -40
- package/dist/mcp/adapters/plugin-bridge.js +0 -89
- package/dist/mcp/auto-discovery.d.ts +0 -62
- package/dist/mcp/auto-discovery.js +0 -149
- package/dist/mcp/client.d.ts +0 -68
- package/dist/mcp/client.js +0 -248
- package/dist/mcp/config.d.ts +0 -31
- package/dist/mcp/config.js +0 -99
- package/dist/mcp/context-manager.d.ts +0 -171
- package/dist/mcp/context-manager.js +0 -362
- package/dist/mcp/contracts/mcp-contract.d.ts +0 -169
- package/dist/mcp/contracts/mcp-contract.js +0 -58
- package/dist/mcp/core/plugin-manager.d.ts +0 -46
- package/dist/mcp/core/plugin-manager.js +0 -110
- package/dist/mcp/demo/plugin-demo.d.ts +0 -20
- package/dist/mcp/demo/plugin-demo.js +0 -118
- package/dist/mcp/dynamic-chain-executor.d.ts +0 -225
- package/dist/mcp/dynamic-chain-executor.js +0 -489
- package/dist/mcp/dynamic-orchestrator.d.ts +0 -115
- package/dist/mcp/dynamic-orchestrator.js +0 -351
- package/dist/mcp/ecosystem.d.ts +0 -75
- package/dist/mcp/ecosystem.js +0 -162
- package/dist/mcp/error-manager.d.ts +0 -254
- package/dist/mcp/error-manager.js +0 -501
- package/dist/mcp/error-recovery.d.ts +0 -159
- package/dist/mcp/error-recovery.js +0 -405
- package/dist/mcp/external-client.d.ts +0 -88
- package/dist/mcp/external-client.js +0 -331
- package/dist/mcp/external-manager.d.ts +0 -112
- package/dist/mcp/external-manager.js +0 -308
- package/dist/mcp/function-calling.d.ts +0 -65
- package/dist/mcp/function-calling.js +0 -642
- package/dist/mcp/health-monitor.d.ts +0 -257
- package/dist/mcp/health-monitor.js +0 -630
- package/dist/mcp/initialize-tools.d.ts +0 -29
- package/dist/mcp/initialize-tools.js +0 -262
- package/dist/mcp/initialize.d.ts +0 -18
- package/dist/mcp/initialize.js +0 -62
- package/dist/mcp/manager.d.ts +0 -68
- package/dist/mcp/manager.js +0 -176
- package/dist/mcp/neurolink-mcp-client.d.ts +0 -97
- package/dist/mcp/neurolink-mcp-client.js +0 -462
- package/dist/mcp/orchestrator.d.ts +0 -302
- package/dist/mcp/orchestrator.js +0 -703
- package/dist/mcp/plugin-manager.d.ts +0 -98
- package/dist/mcp/plugin-manager.js +0 -297
- package/dist/mcp/plugins/core/filesystem-mcp.d.ts +0 -36
- package/dist/mcp/plugins/core/filesystem-mcp.js +0 -142
- package/dist/mcp/plugins/core/neurolink-mcp.json +0 -17
- package/dist/mcp/plugins/filesystem-mcp.d.ts +0 -37
- package/dist/mcp/plugins/filesystem-mcp.js +0 -54
- package/dist/mcp/security-manager.d.ts +0 -87
- package/dist/mcp/security-manager.js +0 -344
- package/dist/mcp/semaphore-manager.d.ts +0 -137
- package/dist/mcp/semaphore-manager.js +0 -329
- package/dist/mcp/session-manager.d.ts +0 -187
- package/dist/mcp/session-manager.js +0 -400
- package/dist/mcp/session-persistence.d.ts +0 -93
- package/dist/mcp/session-persistence.js +0 -302
- package/dist/mcp/tool-integration.d.ts +0 -58
- package/dist/mcp/tool-integration.js +0 -203
- package/dist/mcp/transport-manager.d.ts +0 -154
- package/dist/mcp/transport-manager.js +0 -335
- package/dist/mcp/unified-mcp.d.ts +0 -133
- package/dist/mcp/unified-mcp.js +0 -251
- package/dist/mcp/unified-registry.d.ts +0 -165
- package/dist/mcp/unified-registry.js +0 -539
- package/dist/providers/analytics-helper.d.ts +0 -38
- package/dist/providers/analytics-helper.js +0 -216
- package/dist/providers/function-calling-provider.d.ts +0 -142
- package/dist/providers/function-calling-provider.js +0 -630
- package/dist/providers/mcp-provider.d.ts +0 -75
- package/dist/providers/mcp-provider.js +0 -283
- package/dist/providers/timeout-wrapper.d.ts +0 -40
- package/dist/providers/timeout-wrapper.js +0 -100
- package/dist/sdk/tool-extension.d.ts +0 -181
- package/dist/sdk/tool-extension.js +0 -284
- package/dist/services/streaming/streaming-manager.d.ts +0 -29
- package/dist/services/streaming/streaming-manager.js +0 -245
- package/dist/services/types.d.ts +0 -156
- package/dist/services/types.js +0 -2
- package/dist/services/websocket/websocket-server.d.ts +0 -34
- package/dist/services/websocket/websocket-server.js +0 -306
- package/dist/utils/provider-validation.d.ts +0 -36
- package/dist/utils/provider-validation.js +0 -625
- package/dist/utils/providerUtils-fixed.d.ts +0 -8
- package/dist/utils/providerUtils-fixed.js +0 -94
- package/dist/utils/streaming-utils.d.ts +0 -79
- package/dist/utils/streaming-utils.js +0 -198
- package/dist/utils/timeout-manager.d.ts +0 -75
- package/dist/utils/timeout-manager.js +0 -244
|
@@ -1,642 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* MCP Function-Calling Integration
|
|
3
|
-
* Converts MCP tools to AI SDK function definitions and handles function calls
|
|
4
|
-
* Enables true AI function calling with discovered MCP tools
|
|
5
|
-
*/
|
|
6
|
-
import { tool } from "ai";
|
|
7
|
-
import { z } from "zod";
|
|
8
|
-
import { unifiedRegistry } from "./unified-registry.js";
|
|
9
|
-
import { createExecutionContext } from "./context-manager.js";
|
|
10
|
-
import { mcpLogger } from "./logging.js";
|
|
11
|
-
/**
|
|
12
|
-
* Parses neurolink-specific function name patterns to extract the server ID and tool name.
|
|
13
|
-
*
|
|
14
|
-
* @param {string[]} parts - An array of strings representing parts of a function name,
|
|
15
|
-
* typically obtained by splitting the function name on underscores.
|
|
16
|
-
* @returns {{ serverId: string; toolName: string } | null} An object containing the `serverId`
|
|
17
|
-
* and `toolName` if the input matches a neurolink-specific pattern, or `null` if no match is found.
|
|
18
|
-
*
|
|
19
|
-
* @example
|
|
20
|
-
* // Returns { serverId: "neurolink_ai_core", toolName: "generate" }
|
|
21
|
-
* parseNeuroLinkPattern(["neurolink", "ai", "core", "generate"]);
|
|
22
|
-
*
|
|
23
|
-
* @example
|
|
24
|
-
* // Returns { serverId: "neurolink_utility", toolName: "format_number" }
|
|
25
|
-
* parseNeuroLinkPattern(["neurolink", "utility", "format_number"]);
|
|
26
|
-
*
|
|
27
|
-
* @example
|
|
28
|
-
* // Returns null
|
|
29
|
-
* parseNeuroLinkPattern(["other", "pattern"]);
|
|
30
|
-
*/
|
|
31
|
-
function parseNeuroLinkPattern(parts) {
|
|
32
|
-
if (parts.length >= 3 &&
|
|
33
|
-
parts[0] === "neurolink" &&
|
|
34
|
-
(parts[1] === "ai" || parts[1] === "utility")) {
|
|
35
|
-
// neurolink_ai_core_generate -> serverId: "neurolink_ai_core", toolName: "generate"
|
|
36
|
-
// neurolink_utility_format_number -> serverId: "neurolink_utility", toolName: "format_number"
|
|
37
|
-
if (parts[1] === "ai" && parts[2] === "core") {
|
|
38
|
-
return {
|
|
39
|
-
serverId: "neurolink_ai_core",
|
|
40
|
-
toolName: parts.slice(3).join("_"),
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
else if (parts[1] === "utility") {
|
|
44
|
-
return {
|
|
45
|
-
serverId: "neurolink_utility",
|
|
46
|
-
toolName: parts.slice(2).join("_"),
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
return null;
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Parse underscore-separated function name format
|
|
54
|
-
*/
|
|
55
|
-
function parseUnderscoreFormat(functionName) {
|
|
56
|
-
const parts = functionName.split("_");
|
|
57
|
-
if (parts.length >= 2) {
|
|
58
|
-
// Try neurolink-specific patterns first
|
|
59
|
-
const neurolinkResult = parseNeuroLinkPattern(parts);
|
|
60
|
-
if (neurolinkResult) {
|
|
61
|
-
return neurolinkResult;
|
|
62
|
-
}
|
|
63
|
-
// Default underscore parsing
|
|
64
|
-
return {
|
|
65
|
-
serverId: parts[0],
|
|
66
|
-
toolName: parts.slice(1).join("_"),
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
return null;
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* Parse dot-separated function name format (legacy support)
|
|
73
|
-
*/
|
|
74
|
-
function parseDotFormat(functionName) {
|
|
75
|
-
const parts = functionName.split(".");
|
|
76
|
-
if (parts.length >= 2) {
|
|
77
|
-
return {
|
|
78
|
-
serverId: parts[0],
|
|
79
|
-
toolName: parts.slice(1).join("."),
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
return null;
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Parse function name to extract server ID and tool name
|
|
86
|
-
* Handles various naming patterns including neurolink server patterns
|
|
87
|
-
*/
|
|
88
|
-
function parseFunctionName(functionName) {
|
|
89
|
-
// Try underscore format first (most common)
|
|
90
|
-
const underscoreResult = parseUnderscoreFormat(functionName);
|
|
91
|
-
if (underscoreResult) {
|
|
92
|
-
return underscoreResult;
|
|
93
|
-
}
|
|
94
|
-
// Fallback to dot format for backward compatibility
|
|
95
|
-
const dotResult = parseDotFormat(functionName);
|
|
96
|
-
if (dotResult) {
|
|
97
|
-
return dotResult;
|
|
98
|
-
}
|
|
99
|
-
// Final fallback - return as-is with unknown server
|
|
100
|
-
return {
|
|
101
|
-
serverId: "unknown",
|
|
102
|
-
toolName: functionName,
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* Convert MCP tool to AI SDK function definition
|
|
107
|
-
*/
|
|
108
|
-
export function mcpToolToAISDKTool(tool, serverId) {
|
|
109
|
-
// Create basic JSON Schema for AI SDK
|
|
110
|
-
const parameters = {
|
|
111
|
-
type: "object",
|
|
112
|
-
properties: {},
|
|
113
|
-
required: [],
|
|
114
|
-
};
|
|
115
|
-
// If we have an input schema, try to extract basic information
|
|
116
|
-
if (tool.inputSchema) {
|
|
117
|
-
try {
|
|
118
|
-
// For now, create a simple schema that accepts any object
|
|
119
|
-
// This could be enhanced with proper Zod-to-JSON-Schema conversion
|
|
120
|
-
parameters.properties = {
|
|
121
|
-
// Generic parameter support
|
|
122
|
-
data: {
|
|
123
|
-
type: "object",
|
|
124
|
-
description: "Tool parameters",
|
|
125
|
-
},
|
|
126
|
-
};
|
|
127
|
-
}
|
|
128
|
-
catch (error) {
|
|
129
|
-
mcpLogger.warn(`[Function-Calling] Failed to convert schema for tool ${tool.name}:`, error);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
return {
|
|
133
|
-
description: tool.description,
|
|
134
|
-
parameters,
|
|
135
|
-
execute: async (args) => {
|
|
136
|
-
// This will be handled by the AI SDK's function calling mechanism
|
|
137
|
-
// We'll implement the actual execution in the provider level
|
|
138
|
-
mcpLogger.debug(`[Function-Calling] AI SDK tool executed: ${serverId}.${tool.name}`, args);
|
|
139
|
-
return {
|
|
140
|
-
success: true,
|
|
141
|
-
message: "Tool execution handled by MCP integration",
|
|
142
|
-
};
|
|
143
|
-
},
|
|
144
|
-
};
|
|
145
|
-
}
|
|
146
|
-
/**
|
|
147
|
-
* Get all available MCP tools as AI SDK function definitions
|
|
148
|
-
*/
|
|
149
|
-
export async function getAvailableFunctionTools() {
|
|
150
|
-
const functionTag = "getAvailableFunctionTools";
|
|
151
|
-
const tools = [];
|
|
152
|
-
const toolsObject = {};
|
|
153
|
-
const toolMap = new Map();
|
|
154
|
-
try {
|
|
155
|
-
// Add overall timeout for the entire function
|
|
156
|
-
const overallTimeoutMs = process.env.NODE_ENV === "test" ? 30000 : 15000; // 30s for tests, 15s for production
|
|
157
|
-
let overallTimeoutId;
|
|
158
|
-
const overallTimeoutPromise = new Promise((_, reject) => {
|
|
159
|
-
overallTimeoutId = setTimeout(() => {
|
|
160
|
-
mcpLogger.warn(`[${functionTag}] Overall timeout reached, returning empty tools`);
|
|
161
|
-
reject(new Error("getAvailableFunctionTools overall timeout"));
|
|
162
|
-
}, overallTimeoutMs);
|
|
163
|
-
// CRITICAL FIX: Unref timeout to prevent event loop hanging
|
|
164
|
-
overallTimeoutId.unref();
|
|
165
|
-
});
|
|
166
|
-
const toolsLoadingPromise = (async () => {
|
|
167
|
-
try {
|
|
168
|
-
// Ensure NeuroLink MCP is initialized first
|
|
169
|
-
const { initializeNeuroLinkMCP } = await import("./initialize.js");
|
|
170
|
-
await initializeNeuroLinkMCP();
|
|
171
|
-
// Ensure unified registry is initialized
|
|
172
|
-
await unifiedRegistry.initialize();
|
|
173
|
-
// Try to activate important servers like filesystem
|
|
174
|
-
mcpLogger.debug(`[${functionTag}] Attempting to activate important servers...`);
|
|
175
|
-
try {
|
|
176
|
-
// Get auto-discovered servers
|
|
177
|
-
const autoServers = unifiedRegistry.getAutoDiscoveredServers();
|
|
178
|
-
// Try to activate filesystem server specifically
|
|
179
|
-
for (const server of autoServers) {
|
|
180
|
-
if (server.metadata.name.includes("filesystem")) {
|
|
181
|
-
mcpLogger.debug(`[${functionTag}] Activating filesystem server: ${server.metadata.name}`);
|
|
182
|
-
const serverName = server.metadata.name;
|
|
183
|
-
if (typeof serverName === "string" && serverName.length > 0) {
|
|
184
|
-
// @ts-ignore - serverName is verified as string with length > 0 above
|
|
185
|
-
await unifiedRegistry.lazyActivateServer(serverName);
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
catch (error) {
|
|
191
|
-
mcpLogger.debug(`[${functionTag}] Error activating servers: ${error}`);
|
|
192
|
-
}
|
|
193
|
-
// Get all tools from unified registry directly
|
|
194
|
-
const allTools = await unifiedRegistry.listAllTools();
|
|
195
|
-
mcpLogger.debug(`[${functionTag}] Found ${allTools.length} total tools`);
|
|
196
|
-
// Try to activate servers that have "-tools" entries to get real tools
|
|
197
|
-
const serversToActivate = allTools
|
|
198
|
-
.filter((tool) => tool.name.endsWith("-tools") || tool.name.includes("placeholder"))
|
|
199
|
-
.map((tool) => tool.server);
|
|
200
|
-
mcpLogger.debug(`[${functionTag}] Attempting to activate ${serversToActivate.length} servers for real tool discovery`);
|
|
201
|
-
// Activate servers to convert placeholders to real tools
|
|
202
|
-
for (const serverId of [...new Set(serversToActivate)].filter((id) => typeof id === "string" && id !== "unknown")) {
|
|
203
|
-
try {
|
|
204
|
-
mcpLogger.debug(`[${functionTag}] Activating server: ${serverId}`);
|
|
205
|
-
// Get the server entry from auto-discovered or manual servers
|
|
206
|
-
const autoServers = unifiedRegistry.getAutoDiscoveredServers();
|
|
207
|
-
const manualServers = unifiedRegistry.getManualServers();
|
|
208
|
-
const serverEntry = autoServers.find((s) => s.metadata.name === serverId) ||
|
|
209
|
-
manualServers.get(serverId);
|
|
210
|
-
if (serverEntry && serverId.length > 0) {
|
|
211
|
-
await unifiedRegistry.lazyActivateServer(serverId);
|
|
212
|
-
}
|
|
213
|
-
else {
|
|
214
|
-
mcpLogger.debug(`[${functionTag}] Server entry not found for: ${serverId || "undefined"}`);
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
catch (error) {
|
|
218
|
-
mcpLogger.debug(`[${functionTag}] Failed to activate server ${serverId}:`, error);
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
// Get tools again after activation
|
|
222
|
-
const activatedTools = await unifiedRegistry.listAllTools();
|
|
223
|
-
mcpLogger.debug(`[${functionTag}] Found ${activatedTools.length} total tools after activation`);
|
|
224
|
-
// Filter to get real, individual tools (not placeholder or grouped tools)
|
|
225
|
-
const realTools = activatedTools.filter((toolInfo) => {
|
|
226
|
-
// Skip placeholder tools that weren't activated
|
|
227
|
-
if (toolInfo.name.includes("placeholder") &&
|
|
228
|
-
toolInfo.isImplemented === false) {
|
|
229
|
-
return false;
|
|
230
|
-
}
|
|
231
|
-
// Skip grouped "-tools" entries unless they're the only ones available
|
|
232
|
-
if (toolInfo.name.endsWith("-tools")) {
|
|
233
|
-
// Check if we have individual tools from the same server
|
|
234
|
-
const serverTools = activatedTools.filter((t) => t.server === toolInfo.server &&
|
|
235
|
-
!t.name.endsWith("-tools") &&
|
|
236
|
-
!t.name.includes("placeholder"));
|
|
237
|
-
// If we have individual tools, skip the grouped entry
|
|
238
|
-
if (serverTools.length > 0) {
|
|
239
|
-
return false;
|
|
240
|
-
}
|
|
241
|
-
// Otherwise, include the grouped tool (better than nothing)
|
|
242
|
-
}
|
|
243
|
-
// Include all other real tools
|
|
244
|
-
return true;
|
|
245
|
-
});
|
|
246
|
-
mcpLogger.debug(`[${functionTag}] Filtered to ${realTools.length} real tools from ${activatedTools.length} total`);
|
|
247
|
-
// Process tools and create function definitions
|
|
248
|
-
for (const toolInfo of realTools) {
|
|
249
|
-
try {
|
|
250
|
-
// Check if tool name already includes server info (e.g., from unified registry)
|
|
251
|
-
let functionName;
|
|
252
|
-
let originalFunctionName;
|
|
253
|
-
// Convert server name to underscore format to check if it's embedded in tool name
|
|
254
|
-
const serverName = typeof toolInfo.serverId === "string"
|
|
255
|
-
? toolInfo.serverId
|
|
256
|
-
: "unknown";
|
|
257
|
-
const sanitizedServerCheck = serverName.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
258
|
-
if (toolInfo.name.includes(sanitizedServerCheck) ||
|
|
259
|
-
toolInfo.name.endsWith("-tools") ||
|
|
260
|
-
toolInfo.name.startsWith("github_com_") ||
|
|
261
|
-
toolInfo.name.length > 50) {
|
|
262
|
-
// Tool name already includes server info, sanitize and shorten it
|
|
263
|
-
let sanitized = toolInfo.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
264
|
-
// Shorten long MCP server names
|
|
265
|
-
if (sanitized.startsWith("github_com_modelcontextprotocol_servers_tree_main_src_")) {
|
|
266
|
-
// Replace the long prefix with just 'mcp_'
|
|
267
|
-
sanitized =
|
|
268
|
-
"mcp_" +
|
|
269
|
-
sanitized.substring("github_com_modelcontextprotocol_servers_tree_main_src_"
|
|
270
|
-
.length);
|
|
271
|
-
mcpLogger.debug(`[${functionTag}] Shortened MCP name: ${toolInfo.name} -> ${sanitized}`);
|
|
272
|
-
}
|
|
273
|
-
else if (sanitized.startsWith("github_com_") &&
|
|
274
|
-
sanitized.length > 64) {
|
|
275
|
-
// Shorten other github paths
|
|
276
|
-
const parts = sanitized.split("_");
|
|
277
|
-
// Keep only the meaningful parts (skip github_com)
|
|
278
|
-
sanitized = parts.slice(2).join("_");
|
|
279
|
-
mcpLogger.debug(`[${functionTag}] Shortened github name: ${toolInfo.name} -> ${sanitized}`);
|
|
280
|
-
}
|
|
281
|
-
// If still too long, truncate intelligently
|
|
282
|
-
if (sanitized.length > 64) {
|
|
283
|
-
// Keep the ending part which usually has the actual tool name
|
|
284
|
-
sanitized = sanitized.substring(sanitized.length - 63);
|
|
285
|
-
}
|
|
286
|
-
// Ensure it starts with a letter or underscore (Google AI requirement)
|
|
287
|
-
if (!/^[a-zA-Z_]/.test(sanitized)) {
|
|
288
|
-
sanitized = "_" + sanitized;
|
|
289
|
-
}
|
|
290
|
-
// Final length check after adding prefix
|
|
291
|
-
if (sanitized.length > 64) {
|
|
292
|
-
// For filesystem tools, create a shorter name
|
|
293
|
-
if (sanitized.includes("filesystem")) {
|
|
294
|
-
const toolPart = sanitized.split("_").pop() || "tool";
|
|
295
|
-
sanitized = "fs_" + toolPart;
|
|
296
|
-
}
|
|
297
|
-
else {
|
|
298
|
-
// Generic truncation from the beginning, keeping the end
|
|
299
|
-
sanitized = "_" + sanitized.substring(sanitized.length - 63);
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
functionName = sanitized;
|
|
303
|
-
originalFunctionName = toolInfo.name;
|
|
304
|
-
}
|
|
305
|
-
else {
|
|
306
|
-
// Tool name doesn't include server info, create compound name
|
|
307
|
-
const serverName = typeof toolInfo.serverId === "string"
|
|
308
|
-
? toolInfo.serverId
|
|
309
|
-
: "unknown";
|
|
310
|
-
const sanitizedServerName = serverName.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
311
|
-
const sanitizedToolName = toolInfo.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
312
|
-
// Check if it's a filesystem tool from MCP
|
|
313
|
-
if (sanitizedServerName.includes("modelcontextprotocol") &&
|
|
314
|
-
sanitizedServerName.includes("filesystem")) {
|
|
315
|
-
functionName = `mcp_${sanitizedToolName}`;
|
|
316
|
-
}
|
|
317
|
-
else if (sanitizedServerName.length > 40) {
|
|
318
|
-
// For other long server names, use a shortened version
|
|
319
|
-
const serverParts = sanitizedServerName.split("_");
|
|
320
|
-
const shortServer = serverParts.length > 2
|
|
321
|
-
? serverParts.slice(-2).join("_")
|
|
322
|
-
: sanitizedServerName.substring(0, 20);
|
|
323
|
-
functionName = `${shortServer}_${sanitizedToolName}`;
|
|
324
|
-
}
|
|
325
|
-
else {
|
|
326
|
-
functionName = `${sanitizedServerName}_${sanitizedToolName}`;
|
|
327
|
-
}
|
|
328
|
-
// Ensure it starts with a letter or underscore
|
|
329
|
-
if (!/^[a-zA-Z_]/.test(functionName)) {
|
|
330
|
-
functionName = "_" + functionName;
|
|
331
|
-
}
|
|
332
|
-
// Final length check
|
|
333
|
-
if (functionName.length > 64) {
|
|
334
|
-
// Create a very short version
|
|
335
|
-
functionName = `tool_${sanitizedToolName}`;
|
|
336
|
-
if (functionName.length > 64) {
|
|
337
|
-
functionName = sanitizedToolName.substring(0, 63);
|
|
338
|
-
if (!/^[a-zA-Z_]/.test(functionName)) {
|
|
339
|
-
functionName = "_" + functionName.substring(1);
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
originalFunctionName = `${toolInfo.server || "unknown"}.${toolInfo.name}`;
|
|
344
|
-
}
|
|
345
|
-
// Create AI SDK tool using the proper tool() helper
|
|
346
|
-
const aiTool = tool({
|
|
347
|
-
description: toolInfo.description || `Tool from ${toolInfo.server}`,
|
|
348
|
-
parameters: z.object({
|
|
349
|
-
// Create a generic parameter schema for all MCP tools
|
|
350
|
-
input: z
|
|
351
|
-
.unknown()
|
|
352
|
-
.optional()
|
|
353
|
-
.describe("Input parameters for the tool"),
|
|
354
|
-
}),
|
|
355
|
-
execute: async ({ input }) => {
|
|
356
|
-
mcpLogger.debug(`[Function-Calling] AI SDK tool executed: ${functionName}`, { input });
|
|
357
|
-
try {
|
|
358
|
-
// Execute the actual MCP tool
|
|
359
|
-
const result = await executeFunctionCall(functionName, input || {});
|
|
360
|
-
if (result.success) {
|
|
361
|
-
return (result.data || {
|
|
362
|
-
success: true,
|
|
363
|
-
message: "Tool executed successfully",
|
|
364
|
-
});
|
|
365
|
-
}
|
|
366
|
-
else {
|
|
367
|
-
return { error: result.error || "Tool execution failed" };
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
catch (error) {
|
|
371
|
-
mcpLogger.error(`[Function-Calling] Tool execution error: ${functionName}`, error);
|
|
372
|
-
return {
|
|
373
|
-
error: error instanceof Error ? error.message : String(error),
|
|
374
|
-
};
|
|
375
|
-
}
|
|
376
|
-
},
|
|
377
|
-
});
|
|
378
|
-
tools.push(aiTool);
|
|
379
|
-
// Store tool with proper name association
|
|
380
|
-
toolsObject[functionName] = aiTool;
|
|
381
|
-
// Store mapping for execution - CRITICAL: Use sanitized functionName as key
|
|
382
|
-
toolMap.set(functionName, {
|
|
383
|
-
serverId: typeof toolInfo.serverId === "string"
|
|
384
|
-
? toolInfo.serverId
|
|
385
|
-
: "unknown",
|
|
386
|
-
toolName: toolInfo.name,
|
|
387
|
-
});
|
|
388
|
-
mcpLogger.debug(`[${functionTag}] Converted tool: ${functionName} (original: ${originalFunctionName})`);
|
|
389
|
-
}
|
|
390
|
-
catch (error) {
|
|
391
|
-
mcpLogger.warn(`[${functionTag}] Failed to convert tool ${toolInfo.name}:`, error);
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
mcpLogger.debug(`[${functionTag}] Converted ${tools.length} tools for function calling`);
|
|
395
|
-
// Log the tool names for debugging
|
|
396
|
-
const toolNames = Array.from(toolMap.keys());
|
|
397
|
-
mcpLogger.debug(`[${functionTag}] Tool names:`, toolNames);
|
|
398
|
-
mcpLogger.debug(`[${functionTag}] First 5 tool names:`, toolNames.slice(0, 5));
|
|
399
|
-
if (overallTimeoutId) {
|
|
400
|
-
clearTimeout(overallTimeoutId);
|
|
401
|
-
}
|
|
402
|
-
return { tools, toolsObject, toolMap };
|
|
403
|
-
}
|
|
404
|
-
catch (error) {
|
|
405
|
-
if (overallTimeoutId) {
|
|
406
|
-
clearTimeout(overallTimeoutId);
|
|
407
|
-
}
|
|
408
|
-
throw error;
|
|
409
|
-
}
|
|
410
|
-
})();
|
|
411
|
-
return await Promise.race([toolsLoadingPromise, overallTimeoutPromise]);
|
|
412
|
-
}
|
|
413
|
-
catch (error) {
|
|
414
|
-
mcpLogger.error(`[${functionTag}] Error getting function tools:`, error);
|
|
415
|
-
return { tools: [], toolsObject: {}, toolMap: new Map() };
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
/**
|
|
419
|
-
* Execute MCP tool from AI function call
|
|
420
|
-
*/
|
|
421
|
-
export async function executeFunctionCall(functionName, parameters, context) {
|
|
422
|
-
const functionTag = "executeFunctionCall";
|
|
423
|
-
try {
|
|
424
|
-
// CRITICAL FIX: Unwrap 'input' parameter if it exists
|
|
425
|
-
// AI function calling wraps parameters in { input: { actualParams } }
|
|
426
|
-
// but MCP tools expect direct parameters
|
|
427
|
-
let actualParameters = parameters;
|
|
428
|
-
if (parameters.input &&
|
|
429
|
-
typeof parameters.input === "object" &&
|
|
430
|
-
parameters.input !== null) {
|
|
431
|
-
actualParameters = parameters.input;
|
|
432
|
-
mcpLogger.debug(`[${functionTag}] Unwrapped input parameter for ${functionName}`, { original: parameters, unwrapped: actualParameters });
|
|
433
|
-
}
|
|
434
|
-
mcpLogger.debug(`[${functionTag}] Executing function call: ${functionName}`, { parameters: actualParameters });
|
|
435
|
-
// Create context if not provided
|
|
436
|
-
let finalContext = context;
|
|
437
|
-
if (!finalContext) {
|
|
438
|
-
finalContext = createExecutionContext({
|
|
439
|
-
sessionId: `function-call-${Date.now()}`,
|
|
440
|
-
userId: "ai-function-caller",
|
|
441
|
-
aiProvider: "function-calling",
|
|
442
|
-
});
|
|
443
|
-
}
|
|
444
|
-
// Parse server and tool name from function name
|
|
445
|
-
const { serverId, toolName } = parseFunctionName(functionName);
|
|
446
|
-
if (serverId === "unknown") {
|
|
447
|
-
// Can't parse - try executing as-is through unified registry
|
|
448
|
-
mcpLogger.debug(`[${functionTag}] Cannot parse function name format: ${functionName}, trying unified registry`);
|
|
449
|
-
const result = await unifiedRegistry.executeTool(functionName, actualParameters, finalContext);
|
|
450
|
-
return result;
|
|
451
|
-
}
|
|
452
|
-
// Handle built-in NeuroLink servers directly
|
|
453
|
-
if (serverId === "neurolink-utility" ||
|
|
454
|
-
serverId === "neurolink-ai-core" ||
|
|
455
|
-
serverId === "neurolink_utility" ||
|
|
456
|
-
serverId === "neurolink_ai_core") {
|
|
457
|
-
mcpLogger.debug(`[${functionTag}] Executing built-in tool: ${toolName} from ${serverId}`);
|
|
458
|
-
// Import and execute from default registry
|
|
459
|
-
const { defaultToolRegistry } = await import("./tool-registry.js");
|
|
460
|
-
return await defaultToolRegistry.executeTool(toolName, actualParameters, finalContext);
|
|
461
|
-
}
|
|
462
|
-
// Handle filesystem server with special activation logic
|
|
463
|
-
if (serverId === "filesystem") {
|
|
464
|
-
mcpLogger.debug(`[${functionTag}] Executing filesystem tool: ${toolName}`);
|
|
465
|
-
try {
|
|
466
|
-
// First, try to execute through unified registry
|
|
467
|
-
const result = await unifiedRegistry.executeTool(functionName, actualParameters, finalContext);
|
|
468
|
-
if (result.success) {
|
|
469
|
-
return result;
|
|
470
|
-
}
|
|
471
|
-
}
|
|
472
|
-
catch {
|
|
473
|
-
mcpLogger.debug(`[${functionTag}] Unified registry execution failed for ${functionName}, trying fallback`);
|
|
474
|
-
}
|
|
475
|
-
// Fallback: Try to trigger activation and retry
|
|
476
|
-
try {
|
|
477
|
-
// Force activation by attempting to activate the filesystem server directly
|
|
478
|
-
// This should convert placeholders to real tools
|
|
479
|
-
await unifiedRegistry.initialize();
|
|
480
|
-
// Try a few common activation patterns
|
|
481
|
-
const activationAttempts = [
|
|
482
|
-
`${serverId}.list_directory`,
|
|
483
|
-
`${serverId}.${toolName}`,
|
|
484
|
-
toolName,
|
|
485
|
-
];
|
|
486
|
-
for (const attempt of activationAttempts) {
|
|
487
|
-
try {
|
|
488
|
-
const result = await unifiedRegistry.executeTool(attempt, actualParameters, finalContext);
|
|
489
|
-
if (result.success) {
|
|
490
|
-
mcpLogger.debug(`[${functionTag}] Filesystem tool executed successfully with: ${attempt}`);
|
|
491
|
-
return result;
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
catch {
|
|
495
|
-
// Continue to next attempt
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
// If all attempts fail, return a helpful error
|
|
499
|
-
return {
|
|
500
|
-
success: false,
|
|
501
|
-
error: `Filesystem tool '${toolName}' could not be activated. Available parameters: ${JSON.stringify(actualParameters)}`,
|
|
502
|
-
metadata: {
|
|
503
|
-
functionName,
|
|
504
|
-
timestamp: Date.now(),
|
|
505
|
-
source: "function-calling-filesystem-fallback",
|
|
506
|
-
},
|
|
507
|
-
};
|
|
508
|
-
}
|
|
509
|
-
catch (fallbackError) {
|
|
510
|
-
mcpLogger.error(`[${functionTag}] Filesystem fallback failed:`, fallbackError);
|
|
511
|
-
return {
|
|
512
|
-
success: false,
|
|
513
|
-
error: `Filesystem tool execution failed: ${fallbackError instanceof Error ? fallbackError.message : String(fallbackError)}`,
|
|
514
|
-
metadata: {
|
|
515
|
-
functionName,
|
|
516
|
-
timestamp: Date.now(),
|
|
517
|
-
source: "function-calling-filesystem-fallback",
|
|
518
|
-
},
|
|
519
|
-
};
|
|
520
|
-
}
|
|
521
|
-
}
|
|
522
|
-
// For other tools, use unified registry
|
|
523
|
-
mcpLogger.debug(`[${functionTag}] Executing through unified registry: ${functionName}`);
|
|
524
|
-
const result = await unifiedRegistry.executeTool(functionName, actualParameters, finalContext);
|
|
525
|
-
mcpLogger.debug(`[${functionTag}] Function call completed: ${functionName}`, {
|
|
526
|
-
success: result.success,
|
|
527
|
-
hasData: !!result.data,
|
|
528
|
-
});
|
|
529
|
-
return result;
|
|
530
|
-
}
|
|
531
|
-
catch (error) {
|
|
532
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
533
|
-
mcpLogger.error(`[${functionTag}] Function call failed: ${functionName}`, {
|
|
534
|
-
error: errorMessage,
|
|
535
|
-
});
|
|
536
|
-
return {
|
|
537
|
-
success: false,
|
|
538
|
-
error: errorMessage,
|
|
539
|
-
metadata: {
|
|
540
|
-
functionName,
|
|
541
|
-
timestamp: Date.now(),
|
|
542
|
-
source: "function-calling-integration",
|
|
543
|
-
},
|
|
544
|
-
};
|
|
545
|
-
}
|
|
546
|
-
}
|
|
547
|
-
/**
|
|
548
|
-
* Handle multiple function calls and format results for AI
|
|
549
|
-
*/
|
|
550
|
-
export async function handleFunctionCalls(functionCalls, context) {
|
|
551
|
-
const functionTag = "handleFunctionCalls";
|
|
552
|
-
const results = [];
|
|
553
|
-
mcpLogger.debug(`[${functionTag}] Handling ${functionCalls.length} function calls`);
|
|
554
|
-
for (const call of functionCalls) {
|
|
555
|
-
const result = await executeFunctionCall(call.name, call.parameters, context);
|
|
556
|
-
// Format result for AI consumption
|
|
557
|
-
let formattedForAI = "";
|
|
558
|
-
if (result.success) {
|
|
559
|
-
if (typeof result.data === "string") {
|
|
560
|
-
formattedForAI = result.data;
|
|
561
|
-
}
|
|
562
|
-
else if (result.data) {
|
|
563
|
-
formattedForAI = JSON.stringify(result.data, null, 2);
|
|
564
|
-
}
|
|
565
|
-
else {
|
|
566
|
-
formattedForAI = "Function executed successfully (no data returned)";
|
|
567
|
-
}
|
|
568
|
-
}
|
|
569
|
-
else {
|
|
570
|
-
formattedForAI = `Error: ${result.error || "Function execution failed"}`;
|
|
571
|
-
}
|
|
572
|
-
results.push({
|
|
573
|
-
id: call.id,
|
|
574
|
-
result,
|
|
575
|
-
formattedForAI,
|
|
576
|
-
});
|
|
577
|
-
}
|
|
578
|
-
return results;
|
|
579
|
-
}
|
|
580
|
-
/**
|
|
581
|
-
* Create a subset of tools for specific categories or capabilities
|
|
582
|
-
*/
|
|
583
|
-
export async function getFunctionToolsForCategory(category, maxTools) {
|
|
584
|
-
const { tools, toolMap } = await getAvailableFunctionTools();
|
|
585
|
-
if (!category) {
|
|
586
|
-
return maxTools
|
|
587
|
-
? {
|
|
588
|
-
tools: tools.slice(0, maxTools),
|
|
589
|
-
toolMap,
|
|
590
|
-
}
|
|
591
|
-
: { tools, toolMap };
|
|
592
|
-
}
|
|
593
|
-
// Filter by category (simplified - just include all for now)
|
|
594
|
-
const filteredTools = tools;
|
|
595
|
-
return maxTools
|
|
596
|
-
? {
|
|
597
|
-
tools: filteredTools.slice(0, maxTools),
|
|
598
|
-
toolMap,
|
|
599
|
-
}
|
|
600
|
-
: { tools: filteredTools, toolMap };
|
|
601
|
-
}
|
|
602
|
-
/**
|
|
603
|
-
* Check if function calling is available
|
|
604
|
-
*/
|
|
605
|
-
export async function isFunctionCallingAvailable() {
|
|
606
|
-
try {
|
|
607
|
-
const { tools } = await getAvailableFunctionTools();
|
|
608
|
-
return tools.length > 0;
|
|
609
|
-
}
|
|
610
|
-
catch (error) {
|
|
611
|
-
mcpLogger.warn("[isFunctionCallingAvailable] Failed to check availability:", error);
|
|
612
|
-
return false;
|
|
613
|
-
}
|
|
614
|
-
}
|
|
615
|
-
/**
|
|
616
|
-
* Utility function to create a named tool object for debugging
|
|
617
|
-
*/
|
|
618
|
-
export function createNamedTool(name, toolDef) {
|
|
619
|
-
return {
|
|
620
|
-
name,
|
|
621
|
-
description: toolDef.description,
|
|
622
|
-
parameters: toolDef.parameters,
|
|
623
|
-
execute: toolDef.execute,
|
|
624
|
-
};
|
|
625
|
-
}
|
|
626
|
-
/**
|
|
627
|
-
* Get tools with proper name properties for debugging
|
|
628
|
-
*/
|
|
629
|
-
export async function getToolsWithNames() {
|
|
630
|
-
try {
|
|
631
|
-
const { toolsObject } = await getAvailableFunctionTools();
|
|
632
|
-
const namedTools = {};
|
|
633
|
-
for (const [name, tool] of Object.entries(toolsObject)) {
|
|
634
|
-
namedTools[name] = createNamedTool(name, tool);
|
|
635
|
-
}
|
|
636
|
-
return namedTools;
|
|
637
|
-
}
|
|
638
|
-
catch (error) {
|
|
639
|
-
mcpLogger.warn("[getToolsWithNames] Failed to get tools with names:", error);
|
|
640
|
-
return {};
|
|
641
|
-
}
|
|
642
|
-
}
|