@juspay/neurolink 1.6.0 → 1.9.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.
Files changed (176) hide show
  1. package/CHANGELOG.md +193 -7
  2. package/README.md +100 -17
  3. package/dist/agent/direct-tools.d.ts +1203 -0
  4. package/dist/agent/direct-tools.js +387 -0
  5. package/dist/cli/commands/agent-generate.d.ts +2 -0
  6. package/dist/cli/commands/agent-generate.js +70 -0
  7. package/dist/cli/commands/config.d.ts +6 -6
  8. package/dist/cli/commands/config.js +326 -273
  9. package/dist/cli/commands/mcp.d.ts +2 -1
  10. package/dist/cli/commands/mcp.js +874 -146
  11. package/dist/cli/commands/ollama.d.ts +1 -1
  12. package/dist/cli/commands/ollama.js +153 -143
  13. package/dist/cli/index.js +589 -323
  14. package/dist/cli/utils/complete-setup.d.ts +19 -0
  15. package/dist/cli/utils/complete-setup.js +81 -0
  16. package/dist/cli/utils/env-manager.d.ts +44 -0
  17. package/dist/cli/utils/env-manager.js +226 -0
  18. package/dist/cli/utils/interactive-setup.d.ts +48 -0
  19. package/dist/cli/utils/interactive-setup.js +302 -0
  20. package/dist/core/dynamic-models.d.ts +208 -0
  21. package/dist/core/dynamic-models.js +250 -0
  22. package/dist/core/factory.d.ts +13 -6
  23. package/dist/core/factory.js +176 -61
  24. package/dist/core/types.d.ts +4 -2
  25. package/dist/core/types.js +4 -4
  26. package/dist/index.d.ts +16 -16
  27. package/dist/index.js +16 -16
  28. package/dist/lib/agent/direct-tools.d.ts +1203 -0
  29. package/dist/lib/agent/direct-tools.js +387 -0
  30. package/dist/lib/core/dynamic-models.d.ts +208 -0
  31. package/dist/lib/core/dynamic-models.js +250 -0
  32. package/dist/lib/core/factory.d.ts +13 -6
  33. package/dist/lib/core/factory.js +176 -61
  34. package/dist/lib/core/types.d.ts +4 -2
  35. package/dist/lib/core/types.js +4 -4
  36. package/dist/lib/index.d.ts +16 -16
  37. package/dist/lib/index.js +16 -16
  38. package/dist/lib/mcp/auto-discovery.d.ts +120 -0
  39. package/dist/lib/mcp/auto-discovery.js +793 -0
  40. package/dist/lib/mcp/client.d.ts +66 -0
  41. package/dist/lib/mcp/client.js +245 -0
  42. package/dist/lib/mcp/config.d.ts +31 -0
  43. package/dist/lib/mcp/config.js +74 -0
  44. package/dist/lib/mcp/context-manager.d.ts +4 -4
  45. package/dist/lib/mcp/context-manager.js +24 -18
  46. package/dist/lib/mcp/factory.d.ts +28 -11
  47. package/dist/lib/mcp/factory.js +36 -29
  48. package/dist/lib/mcp/function-calling.d.ts +51 -0
  49. package/dist/lib/mcp/function-calling.js +510 -0
  50. package/dist/lib/mcp/index.d.ts +190 -0
  51. package/dist/lib/mcp/index.js +156 -0
  52. package/dist/lib/mcp/initialize-tools.d.ts +28 -0
  53. package/dist/lib/mcp/initialize-tools.js +209 -0
  54. package/dist/lib/mcp/initialize.d.ts +17 -0
  55. package/dist/lib/mcp/initialize.js +51 -0
  56. package/dist/lib/mcp/logging.d.ts +71 -0
  57. package/dist/lib/mcp/logging.js +183 -0
  58. package/dist/lib/mcp/manager.d.ts +67 -0
  59. package/dist/lib/mcp/manager.js +176 -0
  60. package/dist/lib/mcp/neurolink-mcp-client.d.ts +96 -0
  61. package/dist/lib/mcp/neurolink-mcp-client.js +417 -0
  62. package/dist/lib/mcp/orchestrator.d.ts +3 -3
  63. package/dist/lib/mcp/orchestrator.js +46 -43
  64. package/dist/lib/mcp/registry.d.ts +2 -2
  65. package/dist/lib/mcp/registry.js +42 -33
  66. package/dist/lib/mcp/servers/ai-providers/ai-analysis-tools.d.ts +1 -1
  67. package/dist/lib/mcp/servers/ai-providers/ai-analysis-tools.js +204 -65
  68. package/dist/lib/mcp/servers/ai-providers/ai-core-server.js +142 -102
  69. package/dist/lib/mcp/servers/ai-providers/ai-workflow-tools.d.ts +6 -6
  70. package/dist/lib/mcp/servers/ai-providers/ai-workflow-tools.js +197 -142
  71. package/dist/lib/mcp/servers/utilities/utility-server.d.ts +8 -0
  72. package/dist/lib/mcp/servers/utilities/utility-server.js +326 -0
  73. package/dist/lib/mcp/tool-integration.d.ts +67 -0
  74. package/dist/lib/mcp/tool-integration.js +179 -0
  75. package/dist/lib/mcp/unified-registry.d.ts +269 -0
  76. package/dist/lib/mcp/unified-registry.js +1411 -0
  77. package/dist/lib/neurolink.d.ts +68 -6
  78. package/dist/lib/neurolink.js +304 -42
  79. package/dist/lib/providers/agent-enhanced-provider.d.ts +59 -0
  80. package/dist/lib/providers/agent-enhanced-provider.js +242 -0
  81. package/dist/lib/providers/amazonBedrock.d.ts +3 -3
  82. package/dist/lib/providers/amazonBedrock.js +54 -50
  83. package/dist/lib/providers/anthropic.d.ts +2 -2
  84. package/dist/lib/providers/anthropic.js +92 -84
  85. package/dist/lib/providers/azureOpenAI.d.ts +2 -2
  86. package/dist/lib/providers/azureOpenAI.js +97 -86
  87. package/dist/lib/providers/function-calling-provider.d.ts +70 -0
  88. package/dist/lib/providers/function-calling-provider.js +359 -0
  89. package/dist/lib/providers/googleAIStudio.d.ts +10 -5
  90. package/dist/lib/providers/googleAIStudio.js +60 -38
  91. package/dist/lib/providers/googleVertexAI.d.ts +3 -3
  92. package/dist/lib/providers/googleVertexAI.js +96 -86
  93. package/dist/lib/providers/huggingFace.d.ts +3 -3
  94. package/dist/lib/providers/huggingFace.js +70 -63
  95. package/dist/lib/providers/index.d.ts +11 -11
  96. package/dist/lib/providers/index.js +18 -18
  97. package/dist/lib/providers/mcp-provider.d.ts +62 -0
  98. package/dist/lib/providers/mcp-provider.js +183 -0
  99. package/dist/lib/providers/mistralAI.d.ts +3 -3
  100. package/dist/lib/providers/mistralAI.js +42 -36
  101. package/dist/lib/providers/ollama.d.ts +4 -4
  102. package/dist/lib/providers/ollama.js +113 -98
  103. package/dist/lib/providers/openAI.d.ts +7 -3
  104. package/dist/lib/providers/openAI.js +45 -33
  105. package/dist/lib/utils/logger.js +2 -2
  106. package/dist/lib/utils/providerUtils.js +53 -31
  107. package/dist/mcp/auto-discovery.d.ts +120 -0
  108. package/dist/mcp/auto-discovery.js +794 -0
  109. package/dist/mcp/client.d.ts +66 -0
  110. package/dist/mcp/client.js +245 -0
  111. package/dist/mcp/config.d.ts +31 -0
  112. package/dist/mcp/config.js +74 -0
  113. package/dist/mcp/context-manager.d.ts +4 -4
  114. package/dist/mcp/context-manager.js +24 -18
  115. package/dist/mcp/factory.d.ts +28 -11
  116. package/dist/mcp/factory.js +36 -29
  117. package/dist/mcp/function-calling.d.ts +51 -0
  118. package/dist/mcp/function-calling.js +510 -0
  119. package/dist/mcp/index.d.ts +190 -0
  120. package/dist/mcp/index.js +156 -0
  121. package/dist/mcp/initialize-tools.d.ts +28 -0
  122. package/dist/mcp/initialize-tools.js +210 -0
  123. package/dist/mcp/initialize.d.ts +17 -0
  124. package/dist/mcp/initialize.js +51 -0
  125. package/dist/mcp/logging.d.ts +71 -0
  126. package/dist/mcp/logging.js +183 -0
  127. package/dist/mcp/manager.d.ts +67 -0
  128. package/dist/mcp/manager.js +176 -0
  129. package/dist/mcp/neurolink-mcp-client.d.ts +96 -0
  130. package/dist/mcp/neurolink-mcp-client.js +417 -0
  131. package/dist/mcp/orchestrator.d.ts +3 -3
  132. package/dist/mcp/orchestrator.js +46 -43
  133. package/dist/mcp/registry.d.ts +2 -2
  134. package/dist/mcp/registry.js +42 -33
  135. package/dist/mcp/servers/ai-providers/ai-analysis-tools.d.ts +1 -1
  136. package/dist/mcp/servers/ai-providers/ai-analysis-tools.js +204 -65
  137. package/dist/mcp/servers/ai-providers/ai-core-server.js +142 -102
  138. package/dist/mcp/servers/ai-providers/ai-workflow-tools.d.ts +6 -6
  139. package/dist/mcp/servers/ai-providers/ai-workflow-tools.js +197 -142
  140. package/dist/mcp/servers/utilities/utility-server.d.ts +8 -0
  141. package/dist/mcp/servers/utilities/utility-server.js +326 -0
  142. package/dist/mcp/tool-integration.d.ts +67 -0
  143. package/dist/mcp/tool-integration.js +179 -0
  144. package/dist/mcp/unified-registry.d.ts +269 -0
  145. package/dist/mcp/unified-registry.js +1411 -0
  146. package/dist/neurolink.d.ts +68 -6
  147. package/dist/neurolink.js +304 -42
  148. package/dist/providers/agent-enhanced-provider.d.ts +59 -0
  149. package/dist/providers/agent-enhanced-provider.js +242 -0
  150. package/dist/providers/amazonBedrock.d.ts +3 -3
  151. package/dist/providers/amazonBedrock.js +54 -50
  152. package/dist/providers/anthropic.d.ts +2 -2
  153. package/dist/providers/anthropic.js +92 -84
  154. package/dist/providers/azureOpenAI.d.ts +2 -2
  155. package/dist/providers/azureOpenAI.js +97 -86
  156. package/dist/providers/function-calling-provider.d.ts +70 -0
  157. package/dist/providers/function-calling-provider.js +359 -0
  158. package/dist/providers/googleAIStudio.d.ts +10 -5
  159. package/dist/providers/googleAIStudio.js +60 -38
  160. package/dist/providers/googleVertexAI.d.ts +3 -3
  161. package/dist/providers/googleVertexAI.js +96 -86
  162. package/dist/providers/huggingFace.d.ts +3 -3
  163. package/dist/providers/huggingFace.js +70 -63
  164. package/dist/providers/index.d.ts +11 -11
  165. package/dist/providers/index.js +18 -18
  166. package/dist/providers/mcp-provider.d.ts +62 -0
  167. package/dist/providers/mcp-provider.js +183 -0
  168. package/dist/providers/mistralAI.d.ts +3 -3
  169. package/dist/providers/mistralAI.js +42 -36
  170. package/dist/providers/ollama.d.ts +4 -4
  171. package/dist/providers/ollama.js +113 -98
  172. package/dist/providers/openAI.d.ts +7 -3
  173. package/dist/providers/openAI.js +45 -33
  174. package/dist/utils/logger.js +2 -2
  175. package/dist/utils/providerUtils.js +53 -31
  176. package/package.json +175 -161
@@ -0,0 +1,359 @@
1
+ /**
2
+ * Enhanced AI Provider with Real Function Calling Support
3
+ * Integrates MCP tools directly with AI SDK's function calling capabilities
4
+ * This is the missing piece that enables true AI function calling!
5
+ */
6
+ import { generateText as aiGenerateText, Output, } from "ai";
7
+ import { getAvailableFunctionTools, executeFunctionCall, isFunctionCallingAvailable, } from "../mcp/function-calling.js";
8
+ import { createExecutionContext } from "../mcp/context-manager.js";
9
+ import { mcpLogger } from "../mcp/logging.js";
10
+ /**
11
+ * Enhanced provider that enables real function calling with MCP tools
12
+ */
13
+ export class FunctionCallingProvider {
14
+ baseProvider;
15
+ enableFunctionCalling;
16
+ sessionId;
17
+ userId;
18
+ constructor(baseProvider, options = {}) {
19
+ this.baseProvider = baseProvider;
20
+ this.enableFunctionCalling = options.enableFunctionCalling ?? true;
21
+ this.sessionId = options.sessionId || `function-calling-${Date.now()}`;
22
+ this.userId = options.userId || "function-calling-user";
23
+ }
24
+ /**
25
+ * Generate text with real function calling support
26
+ */
27
+ async generateText(optionsOrPrompt, analysisSchema) {
28
+ const options = typeof optionsOrPrompt === "string"
29
+ ? { prompt: optionsOrPrompt }
30
+ : optionsOrPrompt;
31
+ const functionTag = "FunctionCallingProvider.generateText";
32
+ // If function calling is disabled, use base provider
33
+ if (!this.enableFunctionCalling) {
34
+ mcpLogger.debug(`[${functionTag}] Function calling disabled, using base provider`);
35
+ return this.baseProvider.generateText(options, analysisSchema);
36
+ }
37
+ try {
38
+ // Check if function calling is available
39
+ const functionsAvailable = await isFunctionCallingAvailable();
40
+ if (!functionsAvailable) {
41
+ mcpLogger.debug(`[${functionTag}] No functions available, using base provider`);
42
+ return this.baseProvider.generateText(options, analysisSchema);
43
+ }
44
+ // Get available function tools
45
+ const { tools, toolMap } = await getAvailableFunctionTools();
46
+ if (tools.length === 0) {
47
+ mcpLogger.debug(`[${functionTag}] No tools available, using base provider`);
48
+ return this.baseProvider.generateText(options, analysisSchema);
49
+ }
50
+ mcpLogger.debug(`[${functionTag}] Function calling enabled with ${tools.length} tools`);
51
+ // Create execution context
52
+ const context = createExecutionContext({
53
+ sessionId: this.sessionId,
54
+ userId: this.userId,
55
+ aiProvider: this.baseProvider.constructor.name,
56
+ });
57
+ // Use the AI SDK's native function calling by calling generateText directly
58
+ // We need to get the underlying model from the base provider
59
+ const result = await this.generateTextWithTools(options, tools, toolMap, context, analysisSchema);
60
+ if (!result) {
61
+ return null;
62
+ }
63
+ // Enhance result with function calling metadata
64
+ const enhancedResult = {
65
+ ...result,
66
+ functionCallingEnabled: true,
67
+ availableFunctions: tools.length,
68
+ mcpIntegration: {
69
+ sessionId: this.sessionId,
70
+ functionCallsSupported: true,
71
+ toolsRegistered: tools.length,
72
+ },
73
+ };
74
+ mcpLogger.debug(`[${functionTag}] Function-calling generation completed with ${result.toolCalls?.length || 0} tool calls`);
75
+ return enhancedResult;
76
+ }
77
+ catch (error) {
78
+ mcpLogger.warn(`[${functionTag}] Function calling failed, using base provider:`, error);
79
+ return this.baseProvider.generateText(options, analysisSchema);
80
+ }
81
+ }
82
+ /**
83
+ * Generate text using AI SDK's native function calling
84
+ */
85
+ async generateTextWithTools(options, tools, toolMap, context, analysisSchema) {
86
+ const functionTag = "FunctionCallingProvider.generateTextWithTools";
87
+ try {
88
+ // Convert our tools to AI SDK format with proper execution
89
+ const toolsWithExecution = this.convertToAISDKTools(tools, toolMap, context);
90
+ mcpLogger.debug(`[${functionTag}] Calling AI SDK generateText with ${Object.keys(toolsWithExecution).length} tools and maxSteps: 5`);
91
+ mcpLogger.debug(`[${functionTag}] Sanitized tool names:`, Object.keys(toolsWithExecution));
92
+ // Log the first few tools to debug the issue
93
+ const toolNames = Object.keys(toolsWithExecution);
94
+ mcpLogger.debug(`[${functionTag}] First 5 tool names:`, toolNames.slice(0, 5));
95
+ // Get the model from base provider (this requires accessing the private model property)
96
+ // For now, we'll create the model directly based on the provider type
97
+ // This is a temporary solution until we have proper model access
98
+ const modelInfo = await this.getModelFromProvider();
99
+ if (!modelInfo) {
100
+ mcpLogger.warn(`[${functionTag}] Could not get model from provider, falling back to base provider`);
101
+ return this.baseProvider.generateText(options, analysisSchema);
102
+ }
103
+ // Use AI SDK's generateText directly with tools
104
+ const generateOptions = {
105
+ model: modelInfo.model,
106
+ prompt: options.prompt,
107
+ system: options.systemPrompt || "You are a helpful AI assistant.",
108
+ temperature: options.temperature || 0.7,
109
+ maxTokens: options.maxTokens || 500,
110
+ tools: toolsWithExecution,
111
+ toolChoice: "auto", // Let the AI decide when to use tools
112
+ maxSteps: 5, // CRITICAL: Enable multi-turn tool execution
113
+ };
114
+ // Add experimental_output if schema is provided
115
+ if (analysisSchema) {
116
+ generateOptions.experimental_output = Output.object({
117
+ schema: analysisSchema,
118
+ });
119
+ }
120
+ const result = await aiGenerateText(generateOptions);
121
+ mcpLogger.debug(`[${functionTag}] AI SDK generateText completed`, {
122
+ toolCalls: result.toolCalls?.length || 0,
123
+ finishReason: result.finishReason,
124
+ usage: result.usage,
125
+ });
126
+ return result;
127
+ }
128
+ catch (error) {
129
+ mcpLogger.error(`[${functionTag}] Failed to generate text with tools:`, error);
130
+ throw error;
131
+ }
132
+ }
133
+ /**
134
+ * Get the model from the base provider
135
+ * This is a temporary solution - ideally we'd have a getModel() method on AIProvider
136
+ */
137
+ async getModelFromProvider() {
138
+ const functionTag = "FunctionCallingProvider.getModelFromProvider";
139
+ try {
140
+ // Try to access the model property if it exists
141
+ const provider = this.baseProvider;
142
+ // Check if provider has a model property
143
+ if (provider.model) {
144
+ mcpLogger.debug(`[${functionTag}] Found model property on provider`);
145
+ return { model: provider.model };
146
+ }
147
+ // Check if provider has a getModel method
148
+ if (typeof provider.getModel === "function") {
149
+ mcpLogger.debug(`[${functionTag}] Found getModel method on provider`);
150
+ const model = await provider.getModel();
151
+ return { model };
152
+ }
153
+ mcpLogger.warn(`[${functionTag}] Could not find model on provider`);
154
+ return null;
155
+ }
156
+ catch (error) {
157
+ mcpLogger.error(`[${functionTag}] Error getting model from provider:`, error);
158
+ return null;
159
+ }
160
+ }
161
+ /**
162
+ * Sanitize tool name to comply with AI provider requirements
163
+ */
164
+ sanitizeToolName(name) {
165
+ // Replace any character that's not alphanumeric, underscore, dot, or dash
166
+ // Also ensure it starts with a letter or underscore
167
+ let sanitized = name.replace(/[^a-zA-Z0-9_.-]/g, "_");
168
+ // If it doesn't start with a letter or underscore, prepend an underscore
169
+ if (!/^[a-zA-Z_]/.test(sanitized)) {
170
+ sanitized = "_" + sanitized;
171
+ }
172
+ // Ensure it's not longer than 64 characters
173
+ if (sanitized.length > 64) {
174
+ sanitized = sanitized.substring(0, 64);
175
+ }
176
+ return sanitized;
177
+ }
178
+ /**
179
+ * Convert our tools to AI SDK format with proper execution
180
+ */
181
+ convertToAISDKTools(tools, toolMap, context) {
182
+ const functionTag = "FunctionCallingProvider.convertToAISDKTools";
183
+ const convertedTools = {};
184
+ const sanitizedNameMap = new Map(); // Maps sanitized names back to original
185
+ // Convert the toolMap to easily access by index
186
+ const toolInfoArray = Array.from(toolMap.entries());
187
+ tools.forEach((tool, index) => {
188
+ // Use the actual tool name from the map for better debugging
189
+ const [mapKey, toolInfo] = toolInfoArray[index] || [
190
+ `tool_${index}`,
191
+ null,
192
+ ];
193
+ // Use the already sanitized mapKey instead of re-sanitizing the raw toolName
194
+ const sanitizedToolName = mapKey;
195
+ const originalToolName = toolInfo ? toolInfo.toolName : `tool_${index}`;
196
+ // Store the mapping for later reference
197
+ sanitizedNameMap.set(sanitizedToolName, originalToolName);
198
+ // Create a version with actual MCP execution
199
+ convertedTools[sanitizedToolName] = {
200
+ description: tool.description,
201
+ parameters: tool.parameters,
202
+ execute: async (args) => {
203
+ // Enhanced debug logging for Gemini debugging
204
+ const providerName = this.baseProvider.constructor.name;
205
+ console.log(`[GEMINI DEBUG] Provider: ${providerName}`);
206
+ console.log(`[GEMINI DEBUG] Tool: ${sanitizedToolName} (original: ${originalToolName})`);
207
+ console.log(`[GEMINI DEBUG] Args received:`, JSON.stringify(args, null, 2));
208
+ console.log(`[GEMINI DEBUG] Args type:`, typeof args);
209
+ console.log(`[GEMINI DEBUG] Args keys:`, Object.keys(args));
210
+ mcpLogger.debug(`[${functionTag}] Executing MCP tool: ${sanitizedToolName} (original: ${originalToolName}, ${toolInfo?.serverId}.${toolInfo?.toolName})`, args);
211
+ try {
212
+ if (toolInfo) {
213
+ const mcpToolName = `${toolInfo.serverId}.${toolInfo.toolName}`;
214
+ // Log exactly what we're sending to executeFunctionCall
215
+ console.log(`[GEMINI DEBUG] Calling executeFunctionCall with:`);
216
+ console.log(`[GEMINI DEBUG] - mcpToolName:`, mcpToolName);
217
+ console.log(`[GEMINI DEBUG] - args:`, args);
218
+ const result = await executeFunctionCall(mcpToolName, args, context);
219
+ console.log(`[GEMINI DEBUG] Tool execution result:`, {
220
+ success: result.success,
221
+ hasData: !!result.data,
222
+ error: result.error,
223
+ data: result.data,
224
+ });
225
+ mcpLogger.debug(`[${functionTag}] Tool execution result for ${sanitizedToolName}:`, {
226
+ success: result.success,
227
+ hasData: !!result.data,
228
+ error: result.error,
229
+ });
230
+ if (result.success) {
231
+ return (result.data || {
232
+ success: true,
233
+ message: "Tool executed successfully",
234
+ });
235
+ }
236
+ else {
237
+ return { error: result.error || "Tool execution failed" };
238
+ }
239
+ }
240
+ // Fallback execution - Tool info not found
241
+ mcpLogger.warn(`[${functionTag}] Tool info not found for ${sanitizedToolName}, using fallback`);
242
+ return { success: false, error: "Tool mapping not found" };
243
+ }
244
+ catch (error) {
245
+ console.log(`[GEMINI DEBUG] Tool execution error:`, error);
246
+ mcpLogger.error(`[${functionTag}] Tool execution failed for ${sanitizedToolName}:`, error);
247
+ return {
248
+ error: error instanceof Error ? error.message : String(error),
249
+ };
250
+ }
251
+ },
252
+ };
253
+ });
254
+ mcpLogger.debug(`[${functionTag}] Converted ${Object.keys(convertedTools).length} tools for AI SDK:`, Object.keys(convertedTools));
255
+ // Log first tool details for debugging
256
+ const firstToolName = Object.keys(convertedTools)[0];
257
+ if (firstToolName) {
258
+ console.log(`[GEMINI DEBUG] First tool details:`);
259
+ console.log(`[GEMINI DEBUG] - Name:`, firstToolName);
260
+ console.log(`[GEMINI DEBUG] - Description:`, convertedTools[firstToolName].description);
261
+ console.log(`[GEMINI DEBUG] - Parameters:`, convertedTools[firstToolName].parameters);
262
+ }
263
+ return convertedTools;
264
+ }
265
+ /**
266
+ * Create function-aware system prompt
267
+ */
268
+ createFunctionAwareSystemPrompt(originalPrompt, tools) {
269
+ const basePrompt = originalPrompt || "You are a helpful AI assistant.";
270
+ if (tools.length === 0) {
271
+ return basePrompt;
272
+ }
273
+ const functionList = tools
274
+ .map((tool, index) => `${index + 1}. ${tool.description || "No description available"}`)
275
+ .join("\n");
276
+ return `${basePrompt}
277
+
278
+ IMPORTANT: You have access to ${tools.length} specialized functions that can provide real-time information and capabilities:
279
+
280
+ ${functionList}
281
+
282
+ CRITICAL INSTRUCTIONS:
283
+ - When asked about the current time, date, or timezone, you MUST use the time/date functions
284
+ - When asked to list files or access the filesystem, you MUST use the filesystem functions
285
+ - When asked about system information, you MUST use the appropriate system functions
286
+ - DO NOT say "I cannot access" or "I don't have access" - you DO have access through these functions
287
+ - Always use available functions instead of providing placeholder or estimated information
288
+
289
+ These functions provide accurate, real-time data. Use them actively to enhance your responses.`;
290
+ }
291
+ /**
292
+ * Stream text with function calling support
293
+ */
294
+ async streamText(optionsOrPrompt, analysisSchema) {
295
+ const options = typeof optionsOrPrompt === "string"
296
+ ? { prompt: optionsOrPrompt }
297
+ : optionsOrPrompt;
298
+ const functionTag = "FunctionCallingProvider.streamText";
299
+ // If function calling is disabled, use base provider
300
+ if (!this.enableFunctionCalling) {
301
+ mcpLogger.debug(`[${functionTag}] Function calling disabled, using base provider`);
302
+ return this.baseProvider.streamText(options, analysisSchema);
303
+ }
304
+ try {
305
+ // Check if function calling is available
306
+ const functionsAvailable = await isFunctionCallingAvailable();
307
+ if (!functionsAvailable) {
308
+ mcpLogger.debug(`[${functionTag}] No functions available, using base provider`);
309
+ return this.baseProvider.streamText(options, analysisSchema);
310
+ }
311
+ // Get available function tools
312
+ const { tools } = await getAvailableFunctionTools();
313
+ if (tools.length === 0) {
314
+ mcpLogger.debug(`[${functionTag}] No tools available, using base provider`);
315
+ return this.baseProvider.streamText(options, analysisSchema);
316
+ }
317
+ mcpLogger.debug(`[${functionTag}] Streaming with ${tools.length} functions available`);
318
+ // Enhance system prompt
319
+ const enhancedSystemPrompt = this.createFunctionAwareSystemPrompt(options.systemPrompt, tools);
320
+ // Stream with enhanced prompt
321
+ return this.baseProvider.streamText({
322
+ ...options,
323
+ systemPrompt: enhancedSystemPrompt,
324
+ }, analysisSchema);
325
+ }
326
+ catch (error) {
327
+ mcpLogger.warn(`[${functionTag}] Function calling failed, using base provider:`, error);
328
+ return this.baseProvider.streamText(options, analysisSchema);
329
+ }
330
+ }
331
+ }
332
+ /**
333
+ * Create a function-calling enhanced version of any AI provider
334
+ */
335
+ export function createFunctionCallingProvider(baseProvider, options) {
336
+ return new FunctionCallingProvider(baseProvider, options);
337
+ }
338
+ /**
339
+ * Enhanced MCP Provider Factory that creates function-calling enabled providers
340
+ */
341
+ export function createMCPAwareProviderV3(baseProvider, options = {}) {
342
+ const functionTag = "createMCPAwareProviderV3";
343
+ // If MCP is disabled, return base provider
344
+ if (options.enableMCP === false) {
345
+ mcpLogger.debug(`[${functionTag}] MCP disabled, returning base provider`);
346
+ return baseProvider;
347
+ }
348
+ // Create function-calling enhanced provider
349
+ const enhancedProvider = createFunctionCallingProvider(baseProvider, {
350
+ enableFunctionCalling: options.enableFunctionCalling,
351
+ sessionId: options.sessionId,
352
+ userId: options.userId,
353
+ });
354
+ mcpLogger.debug(`[${functionTag}] Created MCP-aware provider with function calling`, {
355
+ providerName: options.providerName,
356
+ enableFunctionCalling: options.enableFunctionCalling !== false,
357
+ });
358
+ return enhancedProvider;
359
+ }
@@ -1,6 +1,6 @@
1
- import type { ZodType, ZodTypeDef } from 'zod';
2
- import { type StreamTextResult, type ToolSet, type Schema, type GenerateTextResult } from 'ai';
3
- import type { AIProvider, TextGenerationOptions, StreamTextOptions } from '../core/types.js';
1
+ import type { ZodType, ZodTypeDef } from "zod";
2
+ import { type StreamTextResult, type ToolSet, type Schema, type GenerateTextResult, type LanguageModelV1 } from "ai";
3
+ import type { AIProvider, TextGenerationOptions, StreamTextOptions } from "../core/types.js";
4
4
  export declare class GoogleAIStudio implements AIProvider {
5
5
  private modelName;
6
6
  /**
@@ -10,9 +10,14 @@ export declare class GoogleAIStudio implements AIProvider {
10
10
  constructor(modelName?: string | null);
11
11
  /**
12
12
  * Gets the appropriate model instance
13
- * @private
13
+ * Made public to support FunctionCallingProvider integration
14
14
  */
15
- private getModel;
15
+ getModel(): LanguageModelV1;
16
+ /**
17
+ * Expose model property for FunctionCallingProvider
18
+ * This allows the enhanced provider to access the underlying model
19
+ */
20
+ get model(): LanguageModelV1;
16
21
  /**
17
22
  * Processes text using streaming approach with enhanced error handling callbacks
18
23
  * @param prompt - The input text prompt to analyze
@@ -1,20 +1,20 @@
1
- import { createGoogleGenerativeAI } from '@ai-sdk/google';
2
- import { streamText, generateText, Output } from 'ai';
3
- import { logger } from '../utils/logger.js';
1
+ import { createGoogleGenerativeAI } from "@ai-sdk/google";
2
+ import { streamText, generateText, Output, } from "ai";
3
+ import { logger } from "../utils/logger.js";
4
4
  // Default system context
5
5
  const DEFAULT_SYSTEM_CONTEXT = {
6
- systemPrompt: 'You are a helpful AI assistant.'
6
+ systemPrompt: "You are a helpful AI assistant.",
7
7
  };
8
8
  // Configuration helpers
9
9
  const getGoogleAIApiKey = () => {
10
10
  const apiKey = process.env.GOOGLE_AI_API_KEY || process.env.GOOGLE_GENERATIVE_AI_API_KEY;
11
11
  if (!apiKey) {
12
- throw new Error('GOOGLE_AI_API_KEY environment variable is not set');
12
+ throw new Error("GOOGLE_AI_API_KEY environment variable is not set");
13
13
  }
14
14
  return apiKey;
15
15
  };
16
16
  const getGoogleAIModelId = () => {
17
- return process.env.GOOGLE_AI_MODEL || 'gemini-1.5-pro-latest';
17
+ return process.env.GOOGLE_AI_MODEL || "gemini-2.5-pro";
18
18
  };
19
19
  const hasValidAuth = () => {
20
20
  return !!(process.env.GOOGLE_AI_API_KEY || process.env.GOOGLE_GENERATIVE_AI_API_KEY);
@@ -27,8 +27,8 @@ function getGoogleInstance() {
27
27
  _google = createGoogleGenerativeAI({
28
28
  apiKey: apiKey,
29
29
  headers: {
30
- 'X-Powered-By': 'NeuroLink'
31
- }
30
+ "X-Powered-By": "NeuroLink",
31
+ },
32
32
  });
33
33
  }
34
34
  return _google;
@@ -41,38 +41,45 @@ export class GoogleAIStudio {
41
41
  * @param modelName - Optional model name to override the default from config
42
42
  */
43
43
  constructor(modelName) {
44
- const functionTag = 'GoogleAIStudio.constructor';
44
+ const functionTag = "GoogleAIStudio.constructor";
45
45
  this.modelName = modelName || getGoogleAIModelId();
46
46
  try {
47
47
  logger.debug(`[${functionTag}] Initialization started`, {
48
48
  modelName: this.modelName,
49
- hasApiKey: hasValidAuth()
49
+ hasApiKey: hasValidAuth(),
50
50
  });
51
51
  logger.debug(`[${functionTag}] Initialization completed`, {
52
52
  modelName: this.modelName,
53
- success: true
53
+ success: true,
54
54
  });
55
55
  }
56
56
  catch (err) {
57
57
  logger.error(`[${functionTag}] Initialization failed`, {
58
- message: 'Error in initializing Google AI Studio',
58
+ message: "Error in initializing Google AI Studio",
59
59
  modelName: this.modelName,
60
60
  error: err instanceof Error ? err.message : String(err),
61
- stack: err instanceof Error ? err.stack : undefined
61
+ stack: err instanceof Error ? err.stack : undefined,
62
62
  });
63
63
  }
64
64
  }
65
65
  /**
66
66
  * Gets the appropriate model instance
67
- * @private
67
+ * Made public to support FunctionCallingProvider integration
68
68
  */
69
69
  getModel() {
70
- logger.debug('GoogleAIStudio.getModel - Google AI model selected', {
71
- modelName: this.modelName
70
+ logger.debug("GoogleAIStudio.getModel - Google AI model selected", {
71
+ modelName: this.modelName,
72
72
  });
73
73
  const google = getGoogleInstance();
74
74
  return google(this.modelName);
75
75
  }
76
+ /**
77
+ * Expose model property for FunctionCallingProvider
78
+ * This allows the enhanced provider to access the underlying model
79
+ */
80
+ get model() {
81
+ return this.getModel();
82
+ }
76
83
  /**
77
84
  * Processes text using streaming approach with enhanced error handling callbacks
78
85
  * @param prompt - The input text prompt to analyze
@@ -80,15 +87,15 @@ export class GoogleAIStudio {
80
87
  * @returns Promise resolving to StreamTextResult or null if operation fails
81
88
  */
82
89
  async streamText(optionsOrPrompt, analysisSchema) {
83
- const functionTag = 'GoogleAIStudio.streamText';
84
- const provider = 'google-ai';
90
+ const functionTag = "GoogleAIStudio.streamText";
91
+ const provider = "google-ai";
85
92
  let chunkCount = 0;
86
93
  try {
87
94
  // Parse parameters - support both string and options object
88
- const options = typeof optionsOrPrompt === 'string'
95
+ const options = typeof optionsOrPrompt === "string"
89
96
  ? { prompt: optionsOrPrompt }
90
97
  : optionsOrPrompt;
91
- const { prompt, temperature = 0.7, maxTokens = 500, systemPrompt = DEFAULT_SYSTEM_CONTEXT.systemPrompt, schema } = options;
98
+ const { prompt, temperature = 0.7, maxTokens = 500, systemPrompt = DEFAULT_SYSTEM_CONTEXT.systemPrompt, schema, tools, } = options;
92
99
  // Use schema from options or fallback parameter
93
100
  const finalSchema = schema || analysisSchema;
94
101
  logger.debug(`[${functionTag}] Stream request started`, {
@@ -97,7 +104,9 @@ export class GoogleAIStudio {
97
104
  promptLength: prompt.length,
98
105
  temperature,
99
106
  maxTokens,
100
- hasSchema: !!finalSchema
107
+ hasSchema: !!finalSchema,
108
+ hasTools: !!tools,
109
+ toolCount: tools ? Object.keys(tools).length : 0,
101
110
  });
102
111
  const model = this.getModel();
103
112
  const streamOptions = {
@@ -106,6 +115,7 @@ export class GoogleAIStudio {
106
115
  system: systemPrompt,
107
116
  temperature,
108
117
  maxTokens,
118
+ ...(tools && { tools }), // Add tools if provided
109
119
  onError: (event) => {
110
120
  const error = event.error;
111
121
  const errorMessage = error instanceof Error ? error.message : String(error);
@@ -116,7 +126,7 @@ export class GoogleAIStudio {
116
126
  error: errorMessage,
117
127
  stack: errorStack,
118
128
  promptLength: prompt.length,
119
- chunkCount
129
+ chunkCount,
120
130
  });
121
131
  },
122
132
  onFinish: (event) => {
@@ -127,7 +137,7 @@ export class GoogleAIStudio {
127
137
  usage: event.usage,
128
138
  totalChunks: chunkCount,
129
139
  promptLength: prompt.length,
130
- responseLength: event.text?.length || 0
140
+ responseLength: event.text?.length || 0,
131
141
  });
132
142
  },
133
143
  onChunk: (event) => {
@@ -137,12 +147,14 @@ export class GoogleAIStudio {
137
147
  modelName: this.modelName,
138
148
  chunkNumber: chunkCount,
139
149
  chunkLength: event.chunk.text?.length || 0,
140
- chunkType: event.chunk.type
150
+ chunkType: event.chunk.type,
141
151
  });
142
- }
152
+ },
143
153
  };
144
154
  if (analysisSchema) {
145
- streamOptions.experimental_output = Output.object({ schema: analysisSchema });
155
+ streamOptions.experimental_output = Output.object({
156
+ schema: analysisSchema,
157
+ });
146
158
  }
147
159
  const result = streamText(streamOptions);
148
160
  return result;
@@ -151,9 +163,11 @@ export class GoogleAIStudio {
151
163
  logger.error(`[${functionTag}] Exception`, {
152
164
  provider,
153
165
  modelName: this.modelName,
154
- message: 'Error in streaming text',
166
+ message: "Error in streaming text",
155
167
  err: String(err),
156
- promptLength: typeof optionsOrPrompt === 'string' ? optionsOrPrompt.length : optionsOrPrompt.prompt.length
168
+ promptLength: typeof optionsOrPrompt === "string"
169
+ ? optionsOrPrompt.length
170
+ : optionsOrPrompt.prompt.length,
157
171
  });
158
172
  throw err; // Re-throw error to trigger fallback
159
173
  }
@@ -165,14 +179,14 @@ export class GoogleAIStudio {
165
179
  * @returns Promise resolving to GenerateTextResult or null if operation fails
166
180
  */
167
181
  async generateText(optionsOrPrompt, analysisSchema) {
168
- const functionTag = 'GoogleAIStudio.generateText';
169
- const provider = 'google-ai';
182
+ const functionTag = "GoogleAIStudio.generateText";
183
+ const provider = "google-ai";
170
184
  try {
171
185
  // Parse parameters - support both string and options object
172
- const options = typeof optionsOrPrompt === 'string'
186
+ const options = typeof optionsOrPrompt === "string"
173
187
  ? { prompt: optionsOrPrompt }
174
188
  : optionsOrPrompt;
175
- const { prompt, temperature = 0.7, maxTokens = 500, systemPrompt = DEFAULT_SYSTEM_CONTEXT.systemPrompt, schema } = options;
189
+ const { prompt, temperature = 0.7, maxTokens = 500, systemPrompt = DEFAULT_SYSTEM_CONTEXT.systemPrompt, schema, tools, } = options;
176
190
  // Use schema from options or fallback parameter
177
191
  const finalSchema = schema || analysisSchema;
178
192
  logger.debug(`[${functionTag}] Generate request started`, {
@@ -180,7 +194,9 @@ export class GoogleAIStudio {
180
194
  modelName: this.modelName,
181
195
  promptLength: prompt.length,
182
196
  temperature,
183
- maxTokens
197
+ maxTokens,
198
+ hasTools: !!tools,
199
+ toolCount: tools ? Object.keys(tools).length : 0,
184
200
  });
185
201
  const model = this.getModel();
186
202
  const generateOptions = {
@@ -188,10 +204,16 @@ export class GoogleAIStudio {
188
204
  prompt: prompt,
189
205
  system: systemPrompt,
190
206
  temperature,
191
- maxTokens
207
+ maxTokens,
208
+ ...(tools && {
209
+ tools,
210
+ maxSteps: 5, // Allow multiple steps for tool execution and response generation
211
+ }), // Add tools if provided
192
212
  };
193
213
  if (finalSchema) {
194
- generateOptions.experimental_output = Output.object({ schema: finalSchema });
214
+ generateOptions.experimental_output = Output.object({
215
+ schema: finalSchema,
216
+ });
195
217
  }
196
218
  const result = await generateText(generateOptions);
197
219
  logger.debug(`[${functionTag}] Generate text completed`, {
@@ -199,7 +221,7 @@ export class GoogleAIStudio {
199
221
  modelName: this.modelName,
200
222
  usage: result.usage,
201
223
  finishReason: result.finishReason,
202
- responseLength: result.text?.length || 0
224
+ responseLength: result.text?.length || 0,
203
225
  });
204
226
  return result;
205
227
  }
@@ -207,8 +229,8 @@ export class GoogleAIStudio {
207
229
  logger.error(`[${functionTag}] Exception`, {
208
230
  provider,
209
231
  modelName: this.modelName,
210
- message: 'Error in generating text',
211
- err: String(err)
232
+ message: "Error in generating text",
233
+ err: String(err),
212
234
  });
213
235
  throw err; // Re-throw error to trigger fallback
214
236
  }
@@ -1,6 +1,6 @@
1
- import type { ZodType, ZodTypeDef } from 'zod';
2
- import { type StreamTextResult, type ToolSet, type Schema, type GenerateTextResult } from 'ai';
3
- import type { AIProvider, TextGenerationOptions, StreamTextOptions } from '../core/types.js';
1
+ import type { ZodType, ZodTypeDef } from "zod";
2
+ import { type StreamTextResult, type ToolSet, type Schema, type GenerateTextResult } from "ai";
3
+ import type { AIProvider, TextGenerationOptions, StreamTextOptions } from "../core/types.js";
4
4
  export declare class GoogleVertexAI implements AIProvider {
5
5
  private modelName;
6
6
  /**