@juspay/neurolink 7.0.0 → 7.1.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 +9 -4
- package/dist/cli/factories/commandFactory.d.ts +53 -2
- package/dist/cli/factories/commandFactory.js +541 -92
- package/dist/cli/index.d.ts +6 -0
- package/dist/cli/index.js +18 -990
- package/dist/core/factory.js +2 -0
- package/dist/factories/providerRegistry.js +3 -1
- package/dist/lib/core/factory.js +3 -0
- package/dist/lib/factories/providerRegistry.js +3 -1
- package/dist/lib/mcp/toolRegistry.d.ts +5 -0
- package/dist/lib/mcp/toolRegistry.js +60 -0
- package/dist/lib/neurolink.js +9 -4
- package/dist/lib/sdk/toolRegistration.js +17 -0
- package/dist/lib/utils/logger.js +5 -6
- package/dist/lib/utils/providerUtils.js +9 -2
- package/dist/mcp/toolRegistry.d.ts +5 -0
- package/dist/mcp/toolRegistry.js +60 -0
- package/dist/neurolink.js +9 -4
- package/dist/sdk/toolRegistration.js +17 -0
- package/dist/utils/logger.js +5 -6
- package/dist/utils/providerUtils.js +9 -2
- package/package.json +1 -1
package/dist/core/factory.js
CHANGED
|
@@ -89,6 +89,8 @@ export class AIProviderFactory {
|
|
|
89
89
|
// );
|
|
90
90
|
// }
|
|
91
91
|
// }
|
|
92
|
+
// CRITICAL FIX: Initialize providers before using them
|
|
93
|
+
await ProviderRegistry.registerAllProviders();
|
|
92
94
|
// PURE FACTORY PATTERN: No switch statements - use ProviderFactory exclusively
|
|
93
95
|
const normalizedName = this.normalizeProviderName(providerName);
|
|
94
96
|
const finalModelName = resolvedModelName === "default" || resolvedModelName === null
|
|
@@ -48,7 +48,9 @@ export class ProviderRegistry {
|
|
|
48
48
|
ProviderFactory.registerProvider(AIProviderName.AZURE, async (modelName) => {
|
|
49
49
|
const { AzureOpenAIProvider } = await import("../providers/azureOpenai.js");
|
|
50
50
|
return new AzureOpenAIProvider(modelName);
|
|
51
|
-
},
|
|
51
|
+
}, process.env.AZURE_MODEL ||
|
|
52
|
+
process.env.AZURE_OPENAI_DEPLOYMENT_ID ||
|
|
53
|
+
"gpt-4o-mini", ["azure", "azureOpenai"]);
|
|
52
54
|
// Register Google Vertex AI provider
|
|
53
55
|
ProviderFactory.registerProvider(AIProviderName.VERTEX, async (modelName) => {
|
|
54
56
|
const { GoogleVertexProvider } = await import("../providers/googleVertex.js");
|
package/dist/lib/core/factory.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// ✅ CIRCULAR DEPENDENCY FIX: Remove barrel export import
|
|
2
2
|
// Providers are now managed via ProviderFactory instead of direct imports
|
|
3
3
|
import { ProviderFactory } from "../factories/providerFactory.js";
|
|
4
|
+
import { ProviderRegistry } from "../factories/providerRegistry.js";
|
|
4
5
|
import { getBestProvider } from "../utils/providerUtils.js";
|
|
5
6
|
import { logger } from "../utils/logger.js";
|
|
6
7
|
const componentIdentifier = "aiProviderFactory";
|
|
@@ -87,6 +88,8 @@ export class AIProviderFactory {
|
|
|
87
88
|
// );
|
|
88
89
|
// }
|
|
89
90
|
// }
|
|
91
|
+
// CRITICAL FIX: Initialize providers before using them
|
|
92
|
+
await ProviderRegistry.registerAllProviders();
|
|
90
93
|
// PURE FACTORY PATTERN: No switch statements - use ProviderFactory exclusively
|
|
91
94
|
const normalizedName = this.normalizeProviderName(providerName);
|
|
92
95
|
const finalModelName = resolvedModelName === "default" || resolvedModelName === null
|
|
@@ -48,7 +48,9 @@ export class ProviderRegistry {
|
|
|
48
48
|
ProviderFactory.registerProvider(AIProviderName.AZURE, async (modelName) => {
|
|
49
49
|
const { AzureOpenAIProvider } = await import("../providers/azureOpenai.js");
|
|
50
50
|
return new AzureOpenAIProvider(modelName);
|
|
51
|
-
},
|
|
51
|
+
}, process.env.AZURE_MODEL ||
|
|
52
|
+
process.env.AZURE_OPENAI_DEPLOYMENT_ID ||
|
|
53
|
+
"gpt-4o-mini", ["azure", "azureOpenai"]);
|
|
52
54
|
// Register Google Vertex AI provider
|
|
53
55
|
ProviderFactory.registerProvider(AIProviderName.VERTEX, async (modelName) => {
|
|
54
56
|
const { GoogleVertexProvider } = await import("../providers/googleVertex.js");
|
|
@@ -39,6 +39,11 @@ export declare class MCPToolRegistry extends MCPRegistry {
|
|
|
39
39
|
private tools;
|
|
40
40
|
private toolImpls;
|
|
41
41
|
private toolExecutionStats;
|
|
42
|
+
constructor();
|
|
43
|
+
/**
|
|
44
|
+
* Register all direct tools from directAgentTools
|
|
45
|
+
*/
|
|
46
|
+
private registerDirectTools;
|
|
42
47
|
/**
|
|
43
48
|
* Register a server with its tools (updated signature)
|
|
44
49
|
*/
|
|
@@ -5,10 +5,70 @@
|
|
|
5
5
|
import { MCPRegistry } from "./registry.js";
|
|
6
6
|
import { registryLogger } from "../utils/logger.js";
|
|
7
7
|
import { randomUUID } from "crypto";
|
|
8
|
+
import { directAgentTools } from "../agent/directTools.js";
|
|
8
9
|
export class MCPToolRegistry extends MCPRegistry {
|
|
9
10
|
tools = new Map();
|
|
10
11
|
toolImpls = new Map(); // Store actual tool implementations
|
|
11
12
|
toolExecutionStats = new Map();
|
|
13
|
+
constructor() {
|
|
14
|
+
super();
|
|
15
|
+
// Auto-register direct tools on initialization
|
|
16
|
+
this.registerDirectTools();
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Register all direct tools from directAgentTools
|
|
20
|
+
*/
|
|
21
|
+
registerDirectTools() {
|
|
22
|
+
registryLogger.info("Auto-registering direct tools...");
|
|
23
|
+
for (const [toolName, toolDef] of Object.entries(directAgentTools)) {
|
|
24
|
+
const toolId = `direct.${toolName}`;
|
|
25
|
+
const toolInfo = {
|
|
26
|
+
name: toolName,
|
|
27
|
+
description: toolDef.description || `Direct tool: ${toolName}`,
|
|
28
|
+
inputSchema: {},
|
|
29
|
+
serverId: "direct",
|
|
30
|
+
category: "built-in",
|
|
31
|
+
};
|
|
32
|
+
this.tools.set(toolId, toolInfo);
|
|
33
|
+
this.toolImpls.set(toolId, {
|
|
34
|
+
execute: async (params, context) => {
|
|
35
|
+
try {
|
|
36
|
+
// Direct tools from AI SDK expect their specific parameter structure
|
|
37
|
+
// Each tool validates its own parameters, so we safely pass them through
|
|
38
|
+
const result = await toolDef.execute(params, {
|
|
39
|
+
toolCallId: context?.sessionId || "unknown",
|
|
40
|
+
messages: [],
|
|
41
|
+
});
|
|
42
|
+
// Return the result wrapped in our standard format
|
|
43
|
+
return {
|
|
44
|
+
success: true,
|
|
45
|
+
data: result,
|
|
46
|
+
metadata: {
|
|
47
|
+
toolName,
|
|
48
|
+
serverId: "direct",
|
|
49
|
+
executionTime: 0,
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
return {
|
|
55
|
+
success: false,
|
|
56
|
+
error: error instanceof Error ? error.message : String(error),
|
|
57
|
+
metadata: {
|
|
58
|
+
toolName,
|
|
59
|
+
serverId: "direct",
|
|
60
|
+
executionTime: 0,
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
description: toolDef.description,
|
|
66
|
+
inputSchema: {},
|
|
67
|
+
});
|
|
68
|
+
registryLogger.debug(`Registered direct tool: ${toolName} as ${toolId}`);
|
|
69
|
+
}
|
|
70
|
+
registryLogger.info(`Auto-registered ${Object.keys(directAgentTools).length} direct tools`);
|
|
71
|
+
}
|
|
12
72
|
/**
|
|
13
73
|
* Register a server with its tools (updated signature)
|
|
14
74
|
*/
|
package/dist/lib/neurolink.js
CHANGED
|
@@ -355,7 +355,7 @@ export class NeuroLink {
|
|
|
355
355
|
const toolDescriptions = availableTools
|
|
356
356
|
.map((tool) => `- ${tool.name}: ${tool.description} (from ${tool.server})`)
|
|
357
357
|
.join("\n");
|
|
358
|
-
const toolPrompt = `\n\
|
|
358
|
+
const toolPrompt = `\n\nYou have access to these additional tools if needed:\n${toolDescriptions}\n\nIMPORTANT: You are a general-purpose AI assistant. Answer all requests directly and creatively. These tools are optional helpers - use them only when they would genuinely improve your response. For creative tasks like storytelling, writing, or general conversation, respond naturally without requiring tools.`;
|
|
359
359
|
return (originalSystemPrompt || "") + toolPrompt;
|
|
360
360
|
}
|
|
361
361
|
/**
|
|
@@ -649,9 +649,10 @@ export class NeuroLink {
|
|
|
649
649
|
* @returns Array of available tools with metadata
|
|
650
650
|
*/
|
|
651
651
|
async getAllAvailableTools() {
|
|
652
|
-
//
|
|
653
|
-
|
|
654
|
-
|
|
652
|
+
// MCP registry already includes direct tools, so just return MCP tools
|
|
653
|
+
// This prevents duplication since direct tools are auto-registered in MCP
|
|
654
|
+
const mcpTools = await toolRegistry.listTools();
|
|
655
|
+
return mcpTools;
|
|
655
656
|
}
|
|
656
657
|
// ============================================================================
|
|
657
658
|
// PROVIDER DIAGNOSTICS - SDK-First Architecture
|
|
@@ -661,6 +662,10 @@ export class NeuroLink {
|
|
|
661
662
|
* Primary method for provider health checking and diagnostics
|
|
662
663
|
*/
|
|
663
664
|
async getProviderStatus() {
|
|
665
|
+
// CRITICAL FIX: Ensure providers are registered before testing
|
|
666
|
+
console.log("🔍 DEBUG: Initializing MCP for provider status...");
|
|
667
|
+
await this.initializeMCP();
|
|
668
|
+
console.log("🔍 DEBUG: MCP initialized:", this.mcpInitialized);
|
|
664
669
|
const { AIProviderFactory } = await import("./core/factory.js");
|
|
665
670
|
const { hasProviderEnvVars } = await import("./utils/providerUtils.js");
|
|
666
671
|
const providers = [
|
|
@@ -139,6 +139,13 @@ export function validateTool(name, tool) {
|
|
|
139
139
|
`Received: ${typeof tool.execute}. ` +
|
|
140
140
|
`Example: { execute: async (params) => { return { success: true, data: result }; } }`);
|
|
141
141
|
}
|
|
142
|
+
// Check for common mistake: using 'schema' instead of 'parameters'
|
|
143
|
+
if ('schema' in tool && !('parameters' in tool)) {
|
|
144
|
+
throw new Error(`Tool '${name}' uses 'schema' property, but NeuroLink expects 'parameters'. ` +
|
|
145
|
+
`Please change 'schema' to 'parameters' and use a Zod schema: ` +
|
|
146
|
+
`{ parameters: z.object({ ... }), execute: ... } ` +
|
|
147
|
+
`See documentation: https://docs.neurolink.com/tools`);
|
|
148
|
+
}
|
|
142
149
|
// Validate parameters schema if provided - support both Zod and custom schemas
|
|
143
150
|
if (tool.parameters) {
|
|
144
151
|
if (typeof tool.parameters !== "object") {
|
|
@@ -150,6 +157,16 @@ export function validateTool(name, tool) {
|
|
|
150
157
|
const hasValidationMethod = typeof params.parse === "function" ||
|
|
151
158
|
typeof params.validate === "function" ||
|
|
152
159
|
"_def" in params; // Zod schemas have _def property
|
|
160
|
+
// Check for plain JSON schema objects (common mistake)
|
|
161
|
+
if ('type' in params && 'properties' in params && !hasValidationMethod) {
|
|
162
|
+
throw new Error(`Tool '${name}' appears to use a plain JSON schema object as parameters. ` +
|
|
163
|
+
`NeuroLink requires a Zod schema for proper type validation and tool integration. ` +
|
|
164
|
+
`Please change from:\n` +
|
|
165
|
+
` { type: 'object', properties: { ... } }\n` +
|
|
166
|
+
`To:\n` +
|
|
167
|
+
` z.object({ fieldName: z.string() })\n` +
|
|
168
|
+
`Import Zod with: import { z } from 'zod'`);
|
|
169
|
+
}
|
|
153
170
|
if (!hasValidationMethod) {
|
|
154
171
|
const errorMessage = typeof params.parse === "function" || "_def" in params
|
|
155
172
|
? `Tool '${name}' has a Zod-like schema but validation failed. Ensure it's a valid Zod schema: z.object({ ... })`
|
package/dist/lib/utils/logger.js
CHANGED
|
@@ -23,11 +23,7 @@ class NeuroLinkLogger {
|
|
|
23
23
|
process.argv.includes("--debug") ||
|
|
24
24
|
process.env.NEUROLINK_DEBUG === "true";
|
|
25
25
|
// Check NEUROLINK_LOG_LEVEL for consistency with the unified NeuroLink logger
|
|
26
|
-
|
|
27
|
-
// Fallback to MCP_LOG_LEVEL for backward compatibility (if needed)
|
|
28
|
-
if (!envLevel) {
|
|
29
|
-
envLevel = process.env.MCP_LOG_LEVEL?.toLowerCase();
|
|
30
|
-
}
|
|
26
|
+
const envLevel = process.env.NEUROLINK_LOG_LEVEL?.toLowerCase();
|
|
31
27
|
if (envLevel && ["debug", "info", "warn", "error"].includes(envLevel)) {
|
|
32
28
|
this.logLevel = envLevel;
|
|
33
29
|
}
|
|
@@ -36,8 +32,11 @@ class NeuroLinkLogger {
|
|
|
36
32
|
this.logLevel = level;
|
|
37
33
|
}
|
|
38
34
|
shouldLog(level) {
|
|
35
|
+
// Dynamic debug mode check to handle CLI middleware timing
|
|
36
|
+
const currentDebugMode = process.argv.includes("--debug") ||
|
|
37
|
+
process.env.NEUROLINK_DEBUG === "true";
|
|
39
38
|
// Hide all logs except errors unless debugging
|
|
40
|
-
if (!
|
|
39
|
+
if (!currentDebugMode && level !== "error") {
|
|
41
40
|
return false;
|
|
42
41
|
}
|
|
43
42
|
const levels = ["debug", "info", "warn", "error"];
|
|
@@ -105,10 +105,17 @@ export function hasProviderEnvVars(provider) {
|
|
|
105
105
|
case "aws":
|
|
106
106
|
return !!(process.env.AWS_ACCESS_KEY_ID && process.env.AWS_SECRET_ACCESS_KEY);
|
|
107
107
|
case "vertex":
|
|
108
|
+
case "googlevertex":
|
|
108
109
|
case "google":
|
|
109
110
|
case "gemini":
|
|
110
|
-
return !!(process.env.
|
|
111
|
-
process.env.
|
|
111
|
+
return !!((process.env.GOOGLE_CLOUD_PROJECT_ID ||
|
|
112
|
+
process.env.VERTEX_PROJECT_ID ||
|
|
113
|
+
process.env.GOOGLE_VERTEX_PROJECT ||
|
|
114
|
+
process.env.GOOGLE_CLOUD_PROJECT) &&
|
|
115
|
+
(process.env.GOOGLE_APPLICATION_CREDENTIALS ||
|
|
116
|
+
process.env.GOOGLE_SERVICE_ACCOUNT_KEY ||
|
|
117
|
+
(process.env.GOOGLE_AUTH_CLIENT_EMAIL &&
|
|
118
|
+
process.env.GOOGLE_AUTH_PRIVATE_KEY)));
|
|
112
119
|
case "openai":
|
|
113
120
|
case "gpt":
|
|
114
121
|
return !!process.env.OPENAI_API_KEY;
|
|
@@ -39,6 +39,11 @@ export declare class MCPToolRegistry extends MCPRegistry {
|
|
|
39
39
|
private tools;
|
|
40
40
|
private toolImpls;
|
|
41
41
|
private toolExecutionStats;
|
|
42
|
+
constructor();
|
|
43
|
+
/**
|
|
44
|
+
* Register all direct tools from directAgentTools
|
|
45
|
+
*/
|
|
46
|
+
private registerDirectTools;
|
|
42
47
|
/**
|
|
43
48
|
* Register a server with its tools (updated signature)
|
|
44
49
|
*/
|
package/dist/mcp/toolRegistry.js
CHANGED
|
@@ -5,10 +5,70 @@
|
|
|
5
5
|
import { MCPRegistry } from "./registry.js";
|
|
6
6
|
import { registryLogger } from "../utils/logger.js";
|
|
7
7
|
import { randomUUID } from "crypto";
|
|
8
|
+
import { directAgentTools } from "../agent/directTools.js";
|
|
8
9
|
export class MCPToolRegistry extends MCPRegistry {
|
|
9
10
|
tools = new Map();
|
|
10
11
|
toolImpls = new Map(); // Store actual tool implementations
|
|
11
12
|
toolExecutionStats = new Map();
|
|
13
|
+
constructor() {
|
|
14
|
+
super();
|
|
15
|
+
// Auto-register direct tools on initialization
|
|
16
|
+
this.registerDirectTools();
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Register all direct tools from directAgentTools
|
|
20
|
+
*/
|
|
21
|
+
registerDirectTools() {
|
|
22
|
+
registryLogger.info("Auto-registering direct tools...");
|
|
23
|
+
for (const [toolName, toolDef] of Object.entries(directAgentTools)) {
|
|
24
|
+
const toolId = `direct.${toolName}`;
|
|
25
|
+
const toolInfo = {
|
|
26
|
+
name: toolName,
|
|
27
|
+
description: toolDef.description || `Direct tool: ${toolName}`,
|
|
28
|
+
inputSchema: {},
|
|
29
|
+
serverId: "direct",
|
|
30
|
+
category: "built-in",
|
|
31
|
+
};
|
|
32
|
+
this.tools.set(toolId, toolInfo);
|
|
33
|
+
this.toolImpls.set(toolId, {
|
|
34
|
+
execute: async (params, context) => {
|
|
35
|
+
try {
|
|
36
|
+
// Direct tools from AI SDK expect their specific parameter structure
|
|
37
|
+
// Each tool validates its own parameters, so we safely pass them through
|
|
38
|
+
const result = await toolDef.execute(params, {
|
|
39
|
+
toolCallId: context?.sessionId || "unknown",
|
|
40
|
+
messages: [],
|
|
41
|
+
});
|
|
42
|
+
// Return the result wrapped in our standard format
|
|
43
|
+
return {
|
|
44
|
+
success: true,
|
|
45
|
+
data: result,
|
|
46
|
+
metadata: {
|
|
47
|
+
toolName,
|
|
48
|
+
serverId: "direct",
|
|
49
|
+
executionTime: 0,
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
return {
|
|
55
|
+
success: false,
|
|
56
|
+
error: error instanceof Error ? error.message : String(error),
|
|
57
|
+
metadata: {
|
|
58
|
+
toolName,
|
|
59
|
+
serverId: "direct",
|
|
60
|
+
executionTime: 0,
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
description: toolDef.description,
|
|
66
|
+
inputSchema: {},
|
|
67
|
+
});
|
|
68
|
+
registryLogger.debug(`Registered direct tool: ${toolName} as ${toolId}`);
|
|
69
|
+
}
|
|
70
|
+
registryLogger.info(`Auto-registered ${Object.keys(directAgentTools).length} direct tools`);
|
|
71
|
+
}
|
|
12
72
|
/**
|
|
13
73
|
* Register a server with its tools (updated signature)
|
|
14
74
|
*/
|
package/dist/neurolink.js
CHANGED
|
@@ -355,7 +355,7 @@ export class NeuroLink {
|
|
|
355
355
|
const toolDescriptions = availableTools
|
|
356
356
|
.map((tool) => `- ${tool.name}: ${tool.description} (from ${tool.server})`)
|
|
357
357
|
.join("\n");
|
|
358
|
-
const toolPrompt = `\n\
|
|
358
|
+
const toolPrompt = `\n\nYou have access to these additional tools if needed:\n${toolDescriptions}\n\nIMPORTANT: You are a general-purpose AI assistant. Answer all requests directly and creatively. These tools are optional helpers - use them only when they would genuinely improve your response. For creative tasks like storytelling, writing, or general conversation, respond naturally without requiring tools.`;
|
|
359
359
|
return (originalSystemPrompt || "") + toolPrompt;
|
|
360
360
|
}
|
|
361
361
|
/**
|
|
@@ -649,9 +649,10 @@ export class NeuroLink {
|
|
|
649
649
|
* @returns Array of available tools with metadata
|
|
650
650
|
*/
|
|
651
651
|
async getAllAvailableTools() {
|
|
652
|
-
//
|
|
653
|
-
|
|
654
|
-
|
|
652
|
+
// MCP registry already includes direct tools, so just return MCP tools
|
|
653
|
+
// This prevents duplication since direct tools are auto-registered in MCP
|
|
654
|
+
const mcpTools = await toolRegistry.listTools();
|
|
655
|
+
return mcpTools;
|
|
655
656
|
}
|
|
656
657
|
// ============================================================================
|
|
657
658
|
// PROVIDER DIAGNOSTICS - SDK-First Architecture
|
|
@@ -661,6 +662,10 @@ export class NeuroLink {
|
|
|
661
662
|
* Primary method for provider health checking and diagnostics
|
|
662
663
|
*/
|
|
663
664
|
async getProviderStatus() {
|
|
665
|
+
// CRITICAL FIX: Ensure providers are registered before testing
|
|
666
|
+
console.log("🔍 DEBUG: Initializing MCP for provider status...");
|
|
667
|
+
await this.initializeMCP();
|
|
668
|
+
console.log("🔍 DEBUG: MCP initialized:", this.mcpInitialized);
|
|
664
669
|
const { AIProviderFactory } = await import("./core/factory.js");
|
|
665
670
|
const { hasProviderEnvVars } = await import("./utils/providerUtils.js");
|
|
666
671
|
const providers = [
|
|
@@ -140,6 +140,13 @@ export function validateTool(name, tool) {
|
|
|
140
140
|
`Received: ${typeof tool.execute}. ` +
|
|
141
141
|
`Example: { execute: async (params) => { return { success: true, data: result }; } }`);
|
|
142
142
|
}
|
|
143
|
+
// Check for common mistake: using 'schema' instead of 'parameters'
|
|
144
|
+
if ('schema' in tool && !('parameters' in tool)) {
|
|
145
|
+
throw new Error(`Tool '${name}' uses 'schema' property, but NeuroLink expects 'parameters'. ` +
|
|
146
|
+
`Please change 'schema' to 'parameters' and use a Zod schema: ` +
|
|
147
|
+
`{ parameters: z.object({ ... }), execute: ... } ` +
|
|
148
|
+
`See documentation: https://docs.neurolink.com/tools`);
|
|
149
|
+
}
|
|
143
150
|
// Validate parameters schema if provided - support both Zod and custom schemas
|
|
144
151
|
if (tool.parameters) {
|
|
145
152
|
if (typeof tool.parameters !== "object") {
|
|
@@ -151,6 +158,16 @@ export function validateTool(name, tool) {
|
|
|
151
158
|
const hasValidationMethod = typeof params.parse === "function" ||
|
|
152
159
|
typeof params.validate === "function" ||
|
|
153
160
|
"_def" in params; // Zod schemas have _def property
|
|
161
|
+
// Check for plain JSON schema objects (common mistake)
|
|
162
|
+
if ('type' in params && 'properties' in params && !hasValidationMethod) {
|
|
163
|
+
throw new Error(`Tool '${name}' appears to use a plain JSON schema object as parameters. ` +
|
|
164
|
+
`NeuroLink requires a Zod schema for proper type validation and tool integration. ` +
|
|
165
|
+
`Please change from:\n` +
|
|
166
|
+
` { type: 'object', properties: { ... } }\n` +
|
|
167
|
+
`To:\n` +
|
|
168
|
+
` z.object({ fieldName: z.string() })\n` +
|
|
169
|
+
`Import Zod with: import { z } from 'zod'`);
|
|
170
|
+
}
|
|
154
171
|
if (!hasValidationMethod) {
|
|
155
172
|
const errorMessage = typeof params.parse === "function" || "_def" in params
|
|
156
173
|
? `Tool '${name}' has a Zod-like schema but validation failed. Ensure it's a valid Zod schema: z.object({ ... })`
|
package/dist/utils/logger.js
CHANGED
|
@@ -23,11 +23,7 @@ class NeuroLinkLogger {
|
|
|
23
23
|
process.argv.includes("--debug") ||
|
|
24
24
|
process.env.NEUROLINK_DEBUG === "true";
|
|
25
25
|
// Check NEUROLINK_LOG_LEVEL for consistency with the unified NeuroLink logger
|
|
26
|
-
|
|
27
|
-
// Fallback to MCP_LOG_LEVEL for backward compatibility (if needed)
|
|
28
|
-
if (!envLevel) {
|
|
29
|
-
envLevel = process.env.MCP_LOG_LEVEL?.toLowerCase();
|
|
30
|
-
}
|
|
26
|
+
const envLevel = process.env.NEUROLINK_LOG_LEVEL?.toLowerCase();
|
|
31
27
|
if (envLevel && ["debug", "info", "warn", "error"].includes(envLevel)) {
|
|
32
28
|
this.logLevel = envLevel;
|
|
33
29
|
}
|
|
@@ -36,8 +32,11 @@ class NeuroLinkLogger {
|
|
|
36
32
|
this.logLevel = level;
|
|
37
33
|
}
|
|
38
34
|
shouldLog(level) {
|
|
35
|
+
// Dynamic debug mode check to handle CLI middleware timing
|
|
36
|
+
const currentDebugMode = process.argv.includes("--debug") ||
|
|
37
|
+
process.env.NEUROLINK_DEBUG === "true";
|
|
39
38
|
// Hide all logs except errors unless debugging
|
|
40
|
-
if (!
|
|
39
|
+
if (!currentDebugMode && level !== "error") {
|
|
41
40
|
return false;
|
|
42
41
|
}
|
|
43
42
|
const levels = ["debug", "info", "warn", "error"];
|
|
@@ -105,10 +105,17 @@ export function hasProviderEnvVars(provider) {
|
|
|
105
105
|
case "aws":
|
|
106
106
|
return !!(process.env.AWS_ACCESS_KEY_ID && process.env.AWS_SECRET_ACCESS_KEY);
|
|
107
107
|
case "vertex":
|
|
108
|
+
case "googlevertex":
|
|
108
109
|
case "google":
|
|
109
110
|
case "gemini":
|
|
110
|
-
return !!(process.env.
|
|
111
|
-
process.env.
|
|
111
|
+
return !!((process.env.GOOGLE_CLOUD_PROJECT_ID ||
|
|
112
|
+
process.env.VERTEX_PROJECT_ID ||
|
|
113
|
+
process.env.GOOGLE_VERTEX_PROJECT ||
|
|
114
|
+
process.env.GOOGLE_CLOUD_PROJECT) &&
|
|
115
|
+
(process.env.GOOGLE_APPLICATION_CREDENTIALS ||
|
|
116
|
+
process.env.GOOGLE_SERVICE_ACCOUNT_KEY ||
|
|
117
|
+
(process.env.GOOGLE_AUTH_CLIENT_EMAIL &&
|
|
118
|
+
process.env.GOOGLE_AUTH_PRIVATE_KEY)));
|
|
112
119
|
case "openai":
|
|
113
120
|
case "gpt":
|
|
114
121
|
return !!process.env.OPENAI_API_KEY;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@juspay/neurolink",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.1.0",
|
|
4
4
|
"description": "Universal AI Development Platform with working MCP integration, multi-provider support, and professional CLI. Built-in tools operational, 58+ external MCP servers discoverable. Connect to filesystem, GitHub, database operations, and more. Build, test, and deploy AI applications with 9 major providers: OpenAI, Anthropic, Google AI, AWS Bedrock, Azure, Hugging Face, Ollama, and Mistral AI.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Juspay Technologies",
|