@juspay/neurolink 1.11.1 → 1.11.3
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 +16 -4
- package/README.md +36 -7
- package/dist/cli/commands/mcp.js +1 -1
- package/dist/lib/providers/agent-enhanced-provider.d.ts +20 -0
- package/dist/lib/providers/agent-enhanced-provider.js +243 -6
- package/dist/lib/providers/googleAIStudio.js +9 -1
- package/dist/providers/agent-enhanced-provider.d.ts +20 -0
- package/dist/providers/agent-enhanced-provider.js +244 -7
- package/dist/providers/googleAIStudio.js +9 -1
- package/package.json +47 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,16 +1,28 @@
|
|
|
1
|
-
## [1.11.
|
|
1
|
+
## [1.11.3](https://github.com/juspay/neurolink/compare/v1.11.2...v1.11.3) (2025-06-22)
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
### Bug Fixes
|
|
5
5
|
|
|
6
|
-
*
|
|
6
|
+
* resolve MCP external tools returning raw JSON instead of human-readable responses ([921a12b](https://github.com/juspay/neurolink/commit/921a12b5b31ca96bbfe3f1db05001ddb84470e14))
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
## [1.11.2](https://github.com/juspay/neurolink/compare/v1.11.1...v1.11.2) (2025-06-22)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* **ci:** refactor auto-converted Node.js scripts ([4088888](https://github.com/juspay/neurolink/commit/408888863f8223e64269423412f5c79a35ddfe36))
|
|
9
14
|
|
|
15
|
+
## [1.11.1](https://github.com/juspay/neurolink/compare/v1.11.0...v1.11.1) (2025-06-21)
|
|
16
|
+
|
|
17
|
+
### Bug Fixes
|
|
18
|
+
|
|
19
|
+
- add backward compatiblity for gemini ([5e84dab](https://github.com/juspay/neurolink/commit/5e84dab598156a5b77d05b343d0d69ecf91f31b0))
|
|
20
|
+
|
|
21
|
+
# [1.11.0](https://github.com/juspay/neurolink/compare/v1.10.0...v1.11.0) (2025-06-21)
|
|
10
22
|
|
|
11
23
|
### Features
|
|
12
24
|
|
|
13
|
-
|
|
25
|
+
- finalize MCP ecosystem and resolve all TypeScript errors ([605d8b2](https://github.com/juspay/neurolink/commit/605d8b2ea10c824077e1379ac47a0c065f0a8095))
|
|
14
26
|
|
|
15
27
|
# [1.10.0](https://github.com/juspay/neurolink/compare/v1.9.0...v1.10.0) (2025-06-21)
|
|
16
28
|
|
package/README.md
CHANGED
|
@@ -15,10 +15,10 @@
|
|
|
15
15
|
|
|
16
16
|
**MAJOR SUCCESS**: All blocking TypeScript compilation errors resolved + Complete CLI MCP integration achieved!
|
|
17
17
|
|
|
18
|
-
✅ **Function Calling Ready**: AI can now execute real filesystem operations, data analysis, and system commands
|
|
19
|
-
✅ **Production Validated**: 23,230+ token MCP context loading confirmed via comprehensive CLI testing
|
|
20
|
-
✅ **Zero Build Errors**: Clean TypeScript compilation after resolving all 13 blocking errors
|
|
21
|
-
✅ **CLI Tool Integration**: Both `generate-text` and `agent-generate` commands use full MCP capabilities
|
|
18
|
+
✅ **Function Calling Ready**: AI can now execute real filesystem operations, data analysis, and system commands
|
|
19
|
+
✅ **Production Validated**: 23,230+ token MCP context loading confirmed via comprehensive CLI testing
|
|
20
|
+
✅ **Zero Build Errors**: Clean TypeScript compilation after resolving all 13 blocking errors
|
|
21
|
+
✅ **CLI Tool Integration**: Both `generate-text` and `agent-generate` commands use full MCP capabilities
|
|
22
22
|
✅ **Backward Compatible**: Tools enabled by default with opt-out flag for traditional usage
|
|
23
23
|
|
|
24
24
|
```bash
|
|
@@ -91,13 +91,15 @@ npx @juspay/neurolink status
|
|
|
91
91
|
- 🌍 **Open Source Models** - Access 100,000+ models via Hugging Face
|
|
92
92
|
- 🇪🇺 **GDPR Compliance** - European data processing with Mistral AI
|
|
93
93
|
|
|
94
|
-
## 🛠️ MCP Integration Status (v1.
|
|
94
|
+
## 🛠️ MCP Integration Status (v1.11.1) ✅ **PRODUCTION READY**
|
|
95
95
|
|
|
96
96
|
| Component | Status | Description |
|
|
97
97
|
| ------------------- | ------------------ | --------------------------------------------------- |
|
|
98
98
|
| Built-in Tools | ✅ **Working** | Time tool, utilities - fully functional |
|
|
99
99
|
| External Discovery | ✅ **Working** | 58+ MCP servers auto-discovered from all AI tools |
|
|
100
100
|
| Tool Execution | ✅ **Working** | Real-time AI tool calling with built-in tools |
|
|
101
|
+
| **External Tools** | ✅ **SOLVED** | **Two-step tool calling fixed - human-readable responses** |
|
|
102
|
+
| **CLI Integration** | ✅ **READY** | **Production-ready AI assistant with external tools** |
|
|
101
103
|
| External Activation | 🔧 **Development** | Discovery complete, activation protocol in progress |
|
|
102
104
|
|
|
103
105
|
### ✅ Quick MCP Test (v1.7.1)
|
|
@@ -292,10 +294,37 @@ We welcome contributions! Please see our [Contributing Guidelines](./CONTRIBUTIN
|
|
|
292
294
|
git clone https://github.com/juspay/neurolink
|
|
293
295
|
cd neurolink
|
|
294
296
|
pnpm install
|
|
295
|
-
pnpm
|
|
296
|
-
pnpm
|
|
297
|
+
pnpm setup:complete # One-command setup with all automation
|
|
298
|
+
pnpm test:adaptive # Intelligent testing
|
|
299
|
+
pnpm build:complete # Full build pipeline
|
|
297
300
|
```
|
|
298
301
|
|
|
302
|
+
### New Developer Experience (v2.0)
|
|
303
|
+
|
|
304
|
+
NeuroLink now features **enterprise-grade automation** with 72+ commands:
|
|
305
|
+
|
|
306
|
+
```bash
|
|
307
|
+
# Environment & Setup (2-minute initialization)
|
|
308
|
+
pnpm setup:complete # Complete project setup
|
|
309
|
+
pnpm env:setup # Safe .env configuration
|
|
310
|
+
pnpm env:backup # Environment backup
|
|
311
|
+
|
|
312
|
+
# Testing & Quality (60-80% faster)
|
|
313
|
+
pnpm test:adaptive # Intelligent test selection
|
|
314
|
+
pnpm test:providers # AI provider validation
|
|
315
|
+
pnpm quality:check # Full quality pipeline
|
|
316
|
+
|
|
317
|
+
# Documentation & Content
|
|
318
|
+
pnpm docs:sync # Cross-file documentation sync
|
|
319
|
+
pnpm content:generate # Automated content creation
|
|
320
|
+
|
|
321
|
+
# Build & Deployment
|
|
322
|
+
pnpm build:complete # 7-phase enterprise pipeline
|
|
323
|
+
pnpm dev:health # System health monitoring
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
**[📖 Complete Automation Guide](./docs/CLI-GUIDE.md)** - All 72+ commands and automation features
|
|
327
|
+
|
|
299
328
|
## 📄 License
|
|
300
329
|
|
|
301
330
|
MIT © [Juspay Technologies](https://juspay.in)
|
package/dist/cli/commands/mcp.js
CHANGED
|
@@ -13,7 +13,7 @@ import { unifiedRegistry } from "../../lib/mcp/unified-registry.js";
|
|
|
13
13
|
import { ContextManager } from "../../lib/mcp/context-manager.js";
|
|
14
14
|
import { MCPOrchestrator } from "../../lib/mcp/orchestrator.js";
|
|
15
15
|
import { initializeNeuroLinkMCP } from "../../lib/mcp/initialize.js";
|
|
16
|
-
import { mcpLogger, setGlobalMCPLogLevel
|
|
16
|
+
import { mcpLogger, setGlobalMCPLogLevel } from "../../lib/mcp/logging.js";
|
|
17
17
|
// Default MCP config file location
|
|
18
18
|
const MCP_CONFIG_FILE = path.join(process.cwd(), ".mcp-config.json");
|
|
19
19
|
// Load MCP configuration
|
|
@@ -13,16 +13,36 @@ interface AgentConfig {
|
|
|
13
13
|
toolCategory?: "basic" | "filesystem" | "utility" | "all";
|
|
14
14
|
maxSteps?: number;
|
|
15
15
|
enableTools?: boolean;
|
|
16
|
+
enableMCP?: boolean;
|
|
17
|
+
mcpInitTimeoutMs?: number;
|
|
18
|
+
mcpDiscoveryOptions?: {
|
|
19
|
+
searchPaths?: string[];
|
|
20
|
+
configFiles?: string[];
|
|
21
|
+
autoDiscover?: boolean;
|
|
22
|
+
};
|
|
16
23
|
}
|
|
17
24
|
/**
|
|
18
25
|
* Agent-Enhanced Provider Class
|
|
19
26
|
* Provides AI generation with tool calling capabilities
|
|
27
|
+
* Now includes MCP tool integration alongside direct tools
|
|
20
28
|
*/
|
|
21
29
|
export declare class AgentEnhancedProvider implements AIProvider {
|
|
22
30
|
private config;
|
|
23
31
|
private model;
|
|
32
|
+
private mcpSystem;
|
|
33
|
+
private mcpInitialized;
|
|
34
|
+
private mcpInitializing;
|
|
35
|
+
private mcpInitFailed;
|
|
24
36
|
constructor(config: AgentConfig);
|
|
25
37
|
private createModel;
|
|
38
|
+
/**
|
|
39
|
+
* Initialize MCP registry with auto-discovery
|
|
40
|
+
*/
|
|
41
|
+
private initializeMCP;
|
|
42
|
+
/**
|
|
43
|
+
* Get combined tools: direct tools + MCP tools
|
|
44
|
+
*/
|
|
45
|
+
private getCombinedTools;
|
|
26
46
|
generateText(optionsOrPrompt: TextGenerationOptions | string): Promise<GenerateTextResult<ToolSet, unknown> | null>;
|
|
27
47
|
streamText(optionsOrPrompt: StreamTextOptions | string): Promise<StreamTextResult<ToolSet, unknown> | null>;
|
|
28
48
|
/**
|
|
@@ -7,22 +7,39 @@ import { google } from "@ai-sdk/google";
|
|
|
7
7
|
import { openai } from "@ai-sdk/openai";
|
|
8
8
|
import { anthropic } from "@ai-sdk/anthropic";
|
|
9
9
|
import { getToolsForCategory, } from "../agent/direct-tools.js";
|
|
10
|
+
import { UnifiedMCPSystem } from "../mcp/unified-mcp.js";
|
|
11
|
+
import { mcpLogger } from "../mcp/logging.js";
|
|
10
12
|
/**
|
|
11
13
|
* Agent-Enhanced Provider Class
|
|
12
14
|
* Provides AI generation with tool calling capabilities
|
|
15
|
+
* Now includes MCP tool integration alongside direct tools
|
|
13
16
|
*/
|
|
14
17
|
export class AgentEnhancedProvider {
|
|
15
18
|
config;
|
|
16
19
|
model;
|
|
20
|
+
mcpSystem = null;
|
|
21
|
+
mcpInitialized = false;
|
|
22
|
+
mcpInitializing = false;
|
|
23
|
+
mcpInitFailed = false;
|
|
17
24
|
constructor(config) {
|
|
18
25
|
this.config = {
|
|
19
26
|
maxSteps: 5,
|
|
20
27
|
toolCategory: "all",
|
|
21
28
|
enableTools: true,
|
|
29
|
+
enableMCP: true,
|
|
30
|
+
mcpDiscoveryOptions: {
|
|
31
|
+
autoDiscover: true,
|
|
32
|
+
searchPaths: [process.cwd()],
|
|
33
|
+
configFiles: [".mcp-config.json", ".mcp-servers.json"],
|
|
34
|
+
},
|
|
22
35
|
...config,
|
|
23
36
|
};
|
|
24
37
|
// Initialize the AI model based on provider
|
|
25
38
|
this.model = this.createModel();
|
|
39
|
+
// Initialize MCP registry if enabled
|
|
40
|
+
if (this.config.enableMCP) {
|
|
41
|
+
this.initializeMCP();
|
|
42
|
+
}
|
|
26
43
|
}
|
|
27
44
|
createModel() {
|
|
28
45
|
const { provider, model } = this.config;
|
|
@@ -37,28 +54,248 @@ export class AgentEnhancedProvider {
|
|
|
37
54
|
throw new Error(`Unsupported provider: ${provider}`);
|
|
38
55
|
}
|
|
39
56
|
}
|
|
57
|
+
/**
|
|
58
|
+
* Initialize MCP registry with auto-discovery
|
|
59
|
+
*/
|
|
60
|
+
async initializeMCP() {
|
|
61
|
+
if (this.mcpInitializing || this.mcpInitFailed) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
this.mcpInitializing = true;
|
|
65
|
+
try {
|
|
66
|
+
mcpLogger.info("[AgentEnhancedProvider] Initializing MCP integration...");
|
|
67
|
+
this.mcpSystem = new UnifiedMCPSystem({
|
|
68
|
+
configPath: this.config.mcpDiscoveryOptions?.configFiles?.[0] || ".mcp-config.json",
|
|
69
|
+
enableExternalServers: true,
|
|
70
|
+
enableInternalServers: true,
|
|
71
|
+
autoInitialize: false
|
|
72
|
+
});
|
|
73
|
+
// ADD TIMEOUT to prevent hanging forever
|
|
74
|
+
const initPromise = this.mcpSystem.initialize();
|
|
75
|
+
const timeoutPromise = new Promise((_, reject) => setTimeout(() => reject(new Error('MCP initialization timeout after 15 seconds')), this.config.mcpInitTimeoutMs || 15000));
|
|
76
|
+
await Promise.race([initPromise, timeoutPromise]);
|
|
77
|
+
this.mcpInitialized = true;
|
|
78
|
+
mcpLogger.info("[AgentEnhancedProvider] MCP integration initialized successfully");
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
mcpLogger.error("[AgentEnhancedProvider] Failed to initialize MCP:", error);
|
|
82
|
+
this.mcpSystem = null;
|
|
83
|
+
this.mcpInitialized = false;
|
|
84
|
+
this.mcpInitFailed = true;
|
|
85
|
+
// Don't throw - continue with direct tools only
|
|
86
|
+
}
|
|
87
|
+
finally {
|
|
88
|
+
this.mcpInitializing = false;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Get combined tools: direct tools + MCP tools
|
|
93
|
+
*/
|
|
94
|
+
async getCombinedTools() {
|
|
95
|
+
const directTools = this.config.enableTools
|
|
96
|
+
? getToolsForCategory(this.config.toolCategory)
|
|
97
|
+
: {};
|
|
98
|
+
// If MCP is disabled or failed to initialize, return only direct tools
|
|
99
|
+
if (!this.config.enableMCP || !this.mcpSystem) {
|
|
100
|
+
return directTools;
|
|
101
|
+
}
|
|
102
|
+
// Get MCP tools if available
|
|
103
|
+
let mcpTools = {};
|
|
104
|
+
try {
|
|
105
|
+
// Skip if MCP failed to initialize or is still initializing
|
|
106
|
+
if (this.mcpInitFailed || this.mcpInitializing || !this.mcpInitialized || !this.mcpSystem) {
|
|
107
|
+
return directTools;
|
|
108
|
+
}
|
|
109
|
+
const mcpToolInfos = await this.mcpSystem.listTools();
|
|
110
|
+
// Convert MCP tools to AI SDK format
|
|
111
|
+
for (const toolInfo of mcpToolInfos) {
|
|
112
|
+
const toolKey = `mcp_${toolInfo.name}`;
|
|
113
|
+
mcpTools[toolKey] = {
|
|
114
|
+
description: toolInfo.description || `MCP tool: ${toolInfo.name}`,
|
|
115
|
+
parameters: toolInfo.inputSchema || {},
|
|
116
|
+
execute: async (args) => {
|
|
117
|
+
try {
|
|
118
|
+
const context = {
|
|
119
|
+
sessionId: 'cli-session',
|
|
120
|
+
userId: 'cli-user',
|
|
121
|
+
secureFS: {
|
|
122
|
+
readFile: async (path, encoding) => {
|
|
123
|
+
const fs = await import('fs/promises');
|
|
124
|
+
return encoding ? fs.readFile(path, { encoding: encoding }) : fs.readFile(path);
|
|
125
|
+
},
|
|
126
|
+
writeFile: async (path, content) => {
|
|
127
|
+
const fs = await import('fs/promises');
|
|
128
|
+
await fs.writeFile(path, content);
|
|
129
|
+
},
|
|
130
|
+
readdir: async (path) => {
|
|
131
|
+
const fs = await import('fs/promises');
|
|
132
|
+
return fs.readdir(path);
|
|
133
|
+
},
|
|
134
|
+
stat: async (path) => {
|
|
135
|
+
const fs = await import('fs/promises');
|
|
136
|
+
return fs.stat(path);
|
|
137
|
+
},
|
|
138
|
+
mkdir: async (path, options) => {
|
|
139
|
+
const fs = await import('fs/promises');
|
|
140
|
+
await fs.mkdir(path, options);
|
|
141
|
+
},
|
|
142
|
+
exists: async (path) => {
|
|
143
|
+
const fs = await import('fs/promises');
|
|
144
|
+
try {
|
|
145
|
+
await fs.access(path);
|
|
146
|
+
return true;
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
path: {
|
|
154
|
+
join: (...paths) => {
|
|
155
|
+
const path = require('path');
|
|
156
|
+
return path.join(...paths);
|
|
157
|
+
},
|
|
158
|
+
resolve: (...paths) => {
|
|
159
|
+
const path = require('path');
|
|
160
|
+
return path.resolve(...paths);
|
|
161
|
+
},
|
|
162
|
+
relative: (from, to) => {
|
|
163
|
+
const path = require('path');
|
|
164
|
+
return path.relative(from, to);
|
|
165
|
+
},
|
|
166
|
+
dirname: (path) => {
|
|
167
|
+
const pathLib = require('path');
|
|
168
|
+
return pathLib.dirname(path);
|
|
169
|
+
},
|
|
170
|
+
basename: (path, ext) => {
|
|
171
|
+
const pathLib = require('path');
|
|
172
|
+
return pathLib.basename(path, ext);
|
|
173
|
+
}
|
|
174
|
+
},
|
|
175
|
+
grantedPermissions: ['read', 'write', 'execute'],
|
|
176
|
+
log: (level, message, data) => {
|
|
177
|
+
const logFn = mcpLogger[level];
|
|
178
|
+
if (typeof logFn === 'function') {
|
|
179
|
+
if (data) {
|
|
180
|
+
logFn(`${message} ${JSON.stringify(data)}`);
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
logFn(message);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
const result = await this.mcpSystem.executeTool(toolInfo.name, args, context);
|
|
189
|
+
return result.data || result;
|
|
190
|
+
}
|
|
191
|
+
catch (error) {
|
|
192
|
+
mcpLogger.error(`MCP tool ${toolInfo.name} execution failed:`, error);
|
|
193
|
+
throw error;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
mcpLogger.info(`[AgentEnhancedProvider] Loaded ${Object.keys(mcpTools).length} MCP tools`);
|
|
199
|
+
}
|
|
200
|
+
catch (error) {
|
|
201
|
+
mcpLogger.error("[AgentEnhancedProvider] Failed to load MCP tools:", error);
|
|
202
|
+
}
|
|
203
|
+
return { ...directTools, ...mcpTools };
|
|
204
|
+
}
|
|
40
205
|
async generateText(optionsOrPrompt) {
|
|
41
206
|
const options = typeof optionsOrPrompt === "string"
|
|
42
207
|
? { prompt: optionsOrPrompt }
|
|
43
208
|
: optionsOrPrompt;
|
|
44
209
|
const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt, schema, } = options;
|
|
45
|
-
// Get tools if enabled
|
|
210
|
+
// Get combined tools (direct + MCP) if enabled
|
|
46
211
|
const tools = this.config.enableTools
|
|
47
|
-
?
|
|
212
|
+
? await this.getCombinedTools()
|
|
48
213
|
: {};
|
|
214
|
+
const log = (msg, data) => {
|
|
215
|
+
mcpLogger.info(`[AgentEnhancedProvider] ${msg}`, data ? JSON.stringify(data, null, 2) : '');
|
|
216
|
+
};
|
|
217
|
+
log('Starting text generation', {
|
|
218
|
+
prompt: prompt.substring(0, 100),
|
|
219
|
+
toolsCount: Object.keys(tools).length,
|
|
220
|
+
maxSteps: this.config.maxSteps
|
|
221
|
+
});
|
|
49
222
|
try {
|
|
223
|
+
// The AI SDK with maxSteps automatically handles tool calling and result integration
|
|
50
224
|
const result = await generateText({
|
|
51
225
|
model: this.model,
|
|
52
226
|
prompt: systemPrompt
|
|
53
227
|
? `System: ${systemPrompt}\n\nUser: ${prompt}`
|
|
54
228
|
: prompt,
|
|
55
229
|
tools,
|
|
56
|
-
maxSteps: this.config.maxSteps,
|
|
230
|
+
maxSteps: this.config.maxSteps, // This enables automatic tool calling
|
|
57
231
|
temperature,
|
|
58
232
|
maxTokens,
|
|
59
|
-
// Force tool usage for specific patterns
|
|
60
233
|
toolChoice: this.shouldForceToolUsage(prompt) ? "required" : "auto",
|
|
61
234
|
});
|
|
235
|
+
log('Generation completed', {
|
|
236
|
+
text: result.text?.substring(0, 200),
|
|
237
|
+
finishReason: result.finishReason,
|
|
238
|
+
toolCallsCount: result.toolCalls?.length || 0,
|
|
239
|
+
toolResultsCount: result.toolResults?.length || 0,
|
|
240
|
+
stepsCount: result.steps?.length || 0
|
|
241
|
+
});
|
|
242
|
+
// Check if tools were called but no final text was generated
|
|
243
|
+
if (result.finishReason === 'tool-calls' && !result.text && result.toolResults?.length > 0) {
|
|
244
|
+
log('Tools called but no final text generated, creating summary response');
|
|
245
|
+
try {
|
|
246
|
+
// Extract tool results and create a summary prompt
|
|
247
|
+
let toolResultsSummary = '';
|
|
248
|
+
if (result.toolResults) {
|
|
249
|
+
for (const toolResult of result.toolResults) {
|
|
250
|
+
const resultData = toolResult.result || toolResult;
|
|
251
|
+
// Try to extract meaningful data from the result
|
|
252
|
+
if (typeof resultData === 'object' && resultData !== null) {
|
|
253
|
+
if (resultData.success && resultData.items) {
|
|
254
|
+
// This looks like a filesystem listing
|
|
255
|
+
toolResultsSummary += `Directory listing for ${resultData.path}:\n`;
|
|
256
|
+
for (const item of resultData.items) {
|
|
257
|
+
toolResultsSummary += `- ${item.name} (${item.type})\n`;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
else {
|
|
261
|
+
toolResultsSummary += JSON.stringify(resultData, null, 2);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
toolResultsSummary += String(resultData);
|
|
266
|
+
}
|
|
267
|
+
toolResultsSummary += '\n\n';
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
log('Tool results extracted', {
|
|
271
|
+
summaryLength: toolResultsSummary.length,
|
|
272
|
+
preview: toolResultsSummary.substring(0, 200)
|
|
273
|
+
});
|
|
274
|
+
// Create a simple, direct summary
|
|
275
|
+
const finalText = `Based on the user request "${prompt}", here's what I found:\n\n${toolResultsSummary}`;
|
|
276
|
+
log('Final text created', {
|
|
277
|
+
textLength: finalText.length,
|
|
278
|
+
preview: finalText.substring(0, 200)
|
|
279
|
+
});
|
|
280
|
+
// Return result with the formatted text
|
|
281
|
+
return {
|
|
282
|
+
...result,
|
|
283
|
+
text: finalText,
|
|
284
|
+
finishReason: 'stop'
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
catch (error) {
|
|
288
|
+
log('Error in summary generation', { error: error instanceof Error ? error.message : String(error) });
|
|
289
|
+
// Fallback: return raw tool results
|
|
290
|
+
const fallbackText = `Tool execution completed. Raw results: ${JSON.stringify(result.toolResults, null, 2)}`;
|
|
291
|
+
return {
|
|
292
|
+
...result,
|
|
293
|
+
text: fallbackText,
|
|
294
|
+
finishReason: 'stop'
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
// Return the full result - the AI SDK has already handled tool execution and integration
|
|
62
299
|
return result;
|
|
63
300
|
}
|
|
64
301
|
catch (error) {
|
|
@@ -71,9 +308,9 @@ export class AgentEnhancedProvider {
|
|
|
71
308
|
? { prompt: optionsOrPrompt }
|
|
72
309
|
: optionsOrPrompt;
|
|
73
310
|
const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt, } = options;
|
|
74
|
-
// Get tools if enabled
|
|
311
|
+
// Get combined tools (direct + MCP) if enabled
|
|
75
312
|
const tools = this.config.enableTools
|
|
76
|
-
?
|
|
313
|
+
? await this.getCombinedTools()
|
|
77
314
|
: {};
|
|
78
315
|
try {
|
|
79
316
|
const result = await streamText({
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import { createGoogleGenerativeAI } from "@ai-sdk/google";
|
|
2
2
|
import { streamText, generateText, Output, } from "ai";
|
|
3
3
|
import { logger } from "../utils/logger.js";
|
|
4
|
+
// CRITICAL: Setup environment variables early for AI SDK compatibility
|
|
5
|
+
// The AI SDK specifically looks for GOOGLE_GENERATIVE_AI_API_KEY
|
|
6
|
+
// We need to ensure this is set before any AI SDK operations
|
|
7
|
+
if (!process.env.GOOGLE_GENERATIVE_AI_API_KEY &&
|
|
8
|
+
process.env.GOOGLE_AI_API_KEY) {
|
|
9
|
+
process.env.GOOGLE_GENERATIVE_AI_API_KEY = process.env.GOOGLE_AI_API_KEY;
|
|
10
|
+
}
|
|
4
11
|
// Default system context
|
|
5
12
|
const DEFAULT_SYSTEM_CONTEXT = {
|
|
6
13
|
systemPrompt: "You are a helpful AI assistant.",
|
|
@@ -14,7 +21,8 @@ const getGoogleAIApiKey = () => {
|
|
|
14
21
|
}
|
|
15
22
|
// Ensure GOOGLE_GENERATIVE_AI_API_KEY is set for @ai-sdk/google compatibility
|
|
16
23
|
// The AI SDK specifically looks for this variable name
|
|
17
|
-
if (!process.env.GOOGLE_GENERATIVE_AI_API_KEY &&
|
|
24
|
+
if (!process.env.GOOGLE_GENERATIVE_AI_API_KEY &&
|
|
25
|
+
process.env.GOOGLE_AI_API_KEY) {
|
|
18
26
|
process.env.GOOGLE_GENERATIVE_AI_API_KEY = process.env.GOOGLE_AI_API_KEY;
|
|
19
27
|
}
|
|
20
28
|
return apiKey;
|
|
@@ -13,16 +13,36 @@ interface AgentConfig {
|
|
|
13
13
|
toolCategory?: "basic" | "filesystem" | "utility" | "all";
|
|
14
14
|
maxSteps?: number;
|
|
15
15
|
enableTools?: boolean;
|
|
16
|
+
enableMCP?: boolean;
|
|
17
|
+
mcpInitTimeoutMs?: number;
|
|
18
|
+
mcpDiscoveryOptions?: {
|
|
19
|
+
searchPaths?: string[];
|
|
20
|
+
configFiles?: string[];
|
|
21
|
+
autoDiscover?: boolean;
|
|
22
|
+
};
|
|
16
23
|
}
|
|
17
24
|
/**
|
|
18
25
|
* Agent-Enhanced Provider Class
|
|
19
26
|
* Provides AI generation with tool calling capabilities
|
|
27
|
+
* Now includes MCP tool integration alongside direct tools
|
|
20
28
|
*/
|
|
21
29
|
export declare class AgentEnhancedProvider implements AIProvider {
|
|
22
30
|
private config;
|
|
23
31
|
private model;
|
|
32
|
+
private mcpSystem;
|
|
33
|
+
private mcpInitialized;
|
|
34
|
+
private mcpInitializing;
|
|
35
|
+
private mcpInitFailed;
|
|
24
36
|
constructor(config: AgentConfig);
|
|
25
37
|
private createModel;
|
|
38
|
+
/**
|
|
39
|
+
* Initialize MCP registry with auto-discovery
|
|
40
|
+
*/
|
|
41
|
+
private initializeMCP;
|
|
42
|
+
/**
|
|
43
|
+
* Get combined tools: direct tools + MCP tools
|
|
44
|
+
*/
|
|
45
|
+
private getCombinedTools;
|
|
26
46
|
generateText(optionsOrPrompt: TextGenerationOptions | string): Promise<GenerateTextResult<ToolSet, unknown> | null>;
|
|
27
47
|
streamText(optionsOrPrompt: StreamTextOptions | string): Promise<StreamTextResult<ToolSet, unknown> | null>;
|
|
28
48
|
/**
|
|
@@ -2,27 +2,44 @@
|
|
|
2
2
|
* Agent-Enhanced Provider for NeuroLink CLI
|
|
3
3
|
* Integrates direct tools with AI providers for true agent functionality
|
|
4
4
|
*/
|
|
5
|
-
import { generateText, streamText, } from "ai";
|
|
5
|
+
import { generateText, streamText, tool, } from "ai";
|
|
6
6
|
import { google } from "@ai-sdk/google";
|
|
7
7
|
import { openai } from "@ai-sdk/openai";
|
|
8
8
|
import { anthropic } from "@ai-sdk/anthropic";
|
|
9
9
|
import { directAgentTools, getToolsForCategory, } from "../agent/direct-tools.js";
|
|
10
|
+
import { UnifiedMCPSystem } from "../mcp/unified-mcp.js";
|
|
11
|
+
import { mcpLogger } from "../mcp/logging.js";
|
|
10
12
|
/**
|
|
11
13
|
* Agent-Enhanced Provider Class
|
|
12
14
|
* Provides AI generation with tool calling capabilities
|
|
15
|
+
* Now includes MCP tool integration alongside direct tools
|
|
13
16
|
*/
|
|
14
17
|
export class AgentEnhancedProvider {
|
|
15
18
|
config;
|
|
16
19
|
model;
|
|
20
|
+
mcpSystem = null;
|
|
21
|
+
mcpInitialized = false;
|
|
22
|
+
mcpInitializing = false;
|
|
23
|
+
mcpInitFailed = false;
|
|
17
24
|
constructor(config) {
|
|
18
25
|
this.config = {
|
|
19
26
|
maxSteps: 5,
|
|
20
27
|
toolCategory: "all",
|
|
21
28
|
enableTools: true,
|
|
29
|
+
enableMCP: true,
|
|
30
|
+
mcpDiscoveryOptions: {
|
|
31
|
+
autoDiscover: true,
|
|
32
|
+
searchPaths: [process.cwd()],
|
|
33
|
+
configFiles: [".mcp-config.json", ".mcp-servers.json"],
|
|
34
|
+
},
|
|
22
35
|
...config,
|
|
23
36
|
};
|
|
24
37
|
// Initialize the AI model based on provider
|
|
25
38
|
this.model = this.createModel();
|
|
39
|
+
// Initialize MCP registry if enabled
|
|
40
|
+
if (this.config.enableMCP) {
|
|
41
|
+
this.initializeMCP();
|
|
42
|
+
}
|
|
26
43
|
}
|
|
27
44
|
createModel() {
|
|
28
45
|
const { provider, model } = this.config;
|
|
@@ -37,28 +54,248 @@ export class AgentEnhancedProvider {
|
|
|
37
54
|
throw new Error(`Unsupported provider: ${provider}`);
|
|
38
55
|
}
|
|
39
56
|
}
|
|
57
|
+
/**
|
|
58
|
+
* Initialize MCP registry with auto-discovery
|
|
59
|
+
*/
|
|
60
|
+
async initializeMCP() {
|
|
61
|
+
if (this.mcpInitializing || this.mcpInitFailed) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
this.mcpInitializing = true;
|
|
65
|
+
try {
|
|
66
|
+
mcpLogger.info("[AgentEnhancedProvider] Initializing MCP integration...");
|
|
67
|
+
this.mcpSystem = new UnifiedMCPSystem({
|
|
68
|
+
configPath: this.config.mcpDiscoveryOptions?.configFiles?.[0] || ".mcp-config.json",
|
|
69
|
+
enableExternalServers: true,
|
|
70
|
+
enableInternalServers: true,
|
|
71
|
+
autoInitialize: false
|
|
72
|
+
});
|
|
73
|
+
// ADD TIMEOUT to prevent hanging forever
|
|
74
|
+
const initPromise = this.mcpSystem.initialize();
|
|
75
|
+
const timeoutPromise = new Promise((_, reject) => setTimeout(() => reject(new Error('MCP initialization timeout after 15 seconds')), this.config.mcpInitTimeoutMs || 15000));
|
|
76
|
+
await Promise.race([initPromise, timeoutPromise]);
|
|
77
|
+
this.mcpInitialized = true;
|
|
78
|
+
mcpLogger.info("[AgentEnhancedProvider] MCP integration initialized successfully");
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
mcpLogger.error("[AgentEnhancedProvider] Failed to initialize MCP:", error);
|
|
82
|
+
this.mcpSystem = null;
|
|
83
|
+
this.mcpInitialized = false;
|
|
84
|
+
this.mcpInitFailed = true;
|
|
85
|
+
// Don't throw - continue with direct tools only
|
|
86
|
+
}
|
|
87
|
+
finally {
|
|
88
|
+
this.mcpInitializing = false;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Get combined tools: direct tools + MCP tools
|
|
93
|
+
*/
|
|
94
|
+
async getCombinedTools() {
|
|
95
|
+
const directTools = this.config.enableTools
|
|
96
|
+
? getToolsForCategory(this.config.toolCategory)
|
|
97
|
+
: {};
|
|
98
|
+
// If MCP is disabled or failed to initialize, return only direct tools
|
|
99
|
+
if (!this.config.enableMCP || !this.mcpSystem) {
|
|
100
|
+
return directTools;
|
|
101
|
+
}
|
|
102
|
+
// Get MCP tools if available
|
|
103
|
+
let mcpTools = {};
|
|
104
|
+
try {
|
|
105
|
+
// Skip if MCP failed to initialize or is still initializing
|
|
106
|
+
if (this.mcpInitFailed || this.mcpInitializing || !this.mcpInitialized || !this.mcpSystem) {
|
|
107
|
+
return directTools;
|
|
108
|
+
}
|
|
109
|
+
const mcpToolInfos = await this.mcpSystem.listTools();
|
|
110
|
+
// Convert MCP tools to AI SDK format
|
|
111
|
+
for (const toolInfo of mcpToolInfos) {
|
|
112
|
+
const toolKey = `mcp_${toolInfo.name}`;
|
|
113
|
+
mcpTools[toolKey] = {
|
|
114
|
+
description: toolInfo.description || `MCP tool: ${toolInfo.name}`,
|
|
115
|
+
parameters: toolInfo.inputSchema || {},
|
|
116
|
+
execute: async (args) => {
|
|
117
|
+
try {
|
|
118
|
+
const context = {
|
|
119
|
+
sessionId: 'cli-session',
|
|
120
|
+
userId: 'cli-user',
|
|
121
|
+
secureFS: {
|
|
122
|
+
readFile: async (path, encoding) => {
|
|
123
|
+
const fs = await import('fs/promises');
|
|
124
|
+
return encoding ? fs.readFile(path, { encoding: encoding }) : fs.readFile(path);
|
|
125
|
+
},
|
|
126
|
+
writeFile: async (path, content) => {
|
|
127
|
+
const fs = await import('fs/promises');
|
|
128
|
+
await fs.writeFile(path, content);
|
|
129
|
+
},
|
|
130
|
+
readdir: async (path) => {
|
|
131
|
+
const fs = await import('fs/promises');
|
|
132
|
+
return fs.readdir(path);
|
|
133
|
+
},
|
|
134
|
+
stat: async (path) => {
|
|
135
|
+
const fs = await import('fs/promises');
|
|
136
|
+
return fs.stat(path);
|
|
137
|
+
},
|
|
138
|
+
mkdir: async (path, options) => {
|
|
139
|
+
const fs = await import('fs/promises');
|
|
140
|
+
await fs.mkdir(path, options);
|
|
141
|
+
},
|
|
142
|
+
exists: async (path) => {
|
|
143
|
+
const fs = await import('fs/promises');
|
|
144
|
+
try {
|
|
145
|
+
await fs.access(path);
|
|
146
|
+
return true;
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
path: {
|
|
154
|
+
join: (...paths) => {
|
|
155
|
+
const path = require('path');
|
|
156
|
+
return path.join(...paths);
|
|
157
|
+
},
|
|
158
|
+
resolve: (...paths) => {
|
|
159
|
+
const path = require('path');
|
|
160
|
+
return path.resolve(...paths);
|
|
161
|
+
},
|
|
162
|
+
relative: (from, to) => {
|
|
163
|
+
const path = require('path');
|
|
164
|
+
return path.relative(from, to);
|
|
165
|
+
},
|
|
166
|
+
dirname: (path) => {
|
|
167
|
+
const pathLib = require('path');
|
|
168
|
+
return pathLib.dirname(path);
|
|
169
|
+
},
|
|
170
|
+
basename: (path, ext) => {
|
|
171
|
+
const pathLib = require('path');
|
|
172
|
+
return pathLib.basename(path, ext);
|
|
173
|
+
}
|
|
174
|
+
},
|
|
175
|
+
grantedPermissions: ['read', 'write', 'execute'],
|
|
176
|
+
log: (level, message, data) => {
|
|
177
|
+
const logFn = mcpLogger[level];
|
|
178
|
+
if (typeof logFn === 'function') {
|
|
179
|
+
if (data) {
|
|
180
|
+
logFn(`${message} ${JSON.stringify(data)}`);
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
logFn(message);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
const result = await this.mcpSystem.executeTool(toolInfo.name, args, context);
|
|
189
|
+
return result.data || result;
|
|
190
|
+
}
|
|
191
|
+
catch (error) {
|
|
192
|
+
mcpLogger.error(`MCP tool ${toolInfo.name} execution failed:`, error);
|
|
193
|
+
throw error;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
mcpLogger.info(`[AgentEnhancedProvider] Loaded ${Object.keys(mcpTools).length} MCP tools`);
|
|
199
|
+
}
|
|
200
|
+
catch (error) {
|
|
201
|
+
mcpLogger.error("[AgentEnhancedProvider] Failed to load MCP tools:", error);
|
|
202
|
+
}
|
|
203
|
+
return { ...directTools, ...mcpTools };
|
|
204
|
+
}
|
|
40
205
|
async generateText(optionsOrPrompt) {
|
|
41
206
|
const options = typeof optionsOrPrompt === "string"
|
|
42
207
|
? { prompt: optionsOrPrompt }
|
|
43
208
|
: optionsOrPrompt;
|
|
44
209
|
const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt, schema, } = options;
|
|
45
|
-
// Get tools if enabled
|
|
210
|
+
// Get combined tools (direct + MCP) if enabled
|
|
46
211
|
const tools = this.config.enableTools
|
|
47
|
-
?
|
|
212
|
+
? await this.getCombinedTools()
|
|
48
213
|
: {};
|
|
214
|
+
const log = (msg, data) => {
|
|
215
|
+
mcpLogger.info(`[AgentEnhancedProvider] ${msg}`, data ? JSON.stringify(data, null, 2) : '');
|
|
216
|
+
};
|
|
217
|
+
log('Starting text generation', {
|
|
218
|
+
prompt: prompt.substring(0, 100),
|
|
219
|
+
toolsCount: Object.keys(tools).length,
|
|
220
|
+
maxSteps: this.config.maxSteps
|
|
221
|
+
});
|
|
49
222
|
try {
|
|
223
|
+
// The AI SDK with maxSteps automatically handles tool calling and result integration
|
|
50
224
|
const result = await generateText({
|
|
51
225
|
model: this.model,
|
|
52
226
|
prompt: systemPrompt
|
|
53
227
|
? `System: ${systemPrompt}\n\nUser: ${prompt}`
|
|
54
228
|
: prompt,
|
|
55
229
|
tools,
|
|
56
|
-
maxSteps: this.config.maxSteps,
|
|
230
|
+
maxSteps: this.config.maxSteps, // This enables automatic tool calling
|
|
57
231
|
temperature,
|
|
58
232
|
maxTokens,
|
|
59
|
-
// Force tool usage for specific patterns
|
|
60
233
|
toolChoice: this.shouldForceToolUsage(prompt) ? "required" : "auto",
|
|
61
234
|
});
|
|
235
|
+
log('Generation completed', {
|
|
236
|
+
text: result.text?.substring(0, 200),
|
|
237
|
+
finishReason: result.finishReason,
|
|
238
|
+
toolCallsCount: result.toolCalls?.length || 0,
|
|
239
|
+
toolResultsCount: result.toolResults?.length || 0,
|
|
240
|
+
stepsCount: result.steps?.length || 0
|
|
241
|
+
});
|
|
242
|
+
// Check if tools were called but no final text was generated
|
|
243
|
+
if (result.finishReason === 'tool-calls' && !result.text && result.toolResults?.length > 0) {
|
|
244
|
+
log('Tools called but no final text generated, creating summary response');
|
|
245
|
+
try {
|
|
246
|
+
// Extract tool results and create a summary prompt
|
|
247
|
+
let toolResultsSummary = '';
|
|
248
|
+
if (result.toolResults) {
|
|
249
|
+
for (const toolResult of result.toolResults) {
|
|
250
|
+
const resultData = toolResult.result || toolResult;
|
|
251
|
+
// Try to extract meaningful data from the result
|
|
252
|
+
if (typeof resultData === 'object' && resultData !== null) {
|
|
253
|
+
if (resultData.success && resultData.items) {
|
|
254
|
+
// This looks like a filesystem listing
|
|
255
|
+
toolResultsSummary += `Directory listing for ${resultData.path}:\n`;
|
|
256
|
+
for (const item of resultData.items) {
|
|
257
|
+
toolResultsSummary += `- ${item.name} (${item.type})\n`;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
else {
|
|
261
|
+
toolResultsSummary += JSON.stringify(resultData, null, 2);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
toolResultsSummary += String(resultData);
|
|
266
|
+
}
|
|
267
|
+
toolResultsSummary += '\n\n';
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
log('Tool results extracted', {
|
|
271
|
+
summaryLength: toolResultsSummary.length,
|
|
272
|
+
preview: toolResultsSummary.substring(0, 200)
|
|
273
|
+
});
|
|
274
|
+
// Create a simple, direct summary
|
|
275
|
+
const finalText = `Based on the user request "${prompt}", here's what I found:\n\n${toolResultsSummary}`;
|
|
276
|
+
log('Final text created', {
|
|
277
|
+
textLength: finalText.length,
|
|
278
|
+
preview: finalText.substring(0, 200)
|
|
279
|
+
});
|
|
280
|
+
// Return result with the formatted text
|
|
281
|
+
return {
|
|
282
|
+
...result,
|
|
283
|
+
text: finalText,
|
|
284
|
+
finishReason: 'stop'
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
catch (error) {
|
|
288
|
+
log('Error in summary generation', { error: error instanceof Error ? error.message : String(error) });
|
|
289
|
+
// Fallback: return raw tool results
|
|
290
|
+
const fallbackText = `Tool execution completed. Raw results: ${JSON.stringify(result.toolResults, null, 2)}`;
|
|
291
|
+
return {
|
|
292
|
+
...result,
|
|
293
|
+
text: fallbackText,
|
|
294
|
+
finishReason: 'stop'
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
// Return the full result - the AI SDK has already handled tool execution and integration
|
|
62
299
|
return result;
|
|
63
300
|
}
|
|
64
301
|
catch (error) {
|
|
@@ -71,9 +308,9 @@ export class AgentEnhancedProvider {
|
|
|
71
308
|
? { prompt: optionsOrPrompt }
|
|
72
309
|
: optionsOrPrompt;
|
|
73
310
|
const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt, } = options;
|
|
74
|
-
// Get tools if enabled
|
|
311
|
+
// Get combined tools (direct + MCP) if enabled
|
|
75
312
|
const tools = this.config.enableTools
|
|
76
|
-
?
|
|
313
|
+
? await this.getCombinedTools()
|
|
77
314
|
: {};
|
|
78
315
|
try {
|
|
79
316
|
const result = await streamText({
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import { createGoogleGenerativeAI } from "@ai-sdk/google";
|
|
2
2
|
import { streamText, generateText, Output, } from "ai";
|
|
3
3
|
import { logger } from "../utils/logger.js";
|
|
4
|
+
// CRITICAL: Setup environment variables early for AI SDK compatibility
|
|
5
|
+
// The AI SDK specifically looks for GOOGLE_GENERATIVE_AI_API_KEY
|
|
6
|
+
// We need to ensure this is set before any AI SDK operations
|
|
7
|
+
if (!process.env.GOOGLE_GENERATIVE_AI_API_KEY &&
|
|
8
|
+
process.env.GOOGLE_AI_API_KEY) {
|
|
9
|
+
process.env.GOOGLE_GENERATIVE_AI_API_KEY = process.env.GOOGLE_AI_API_KEY;
|
|
10
|
+
}
|
|
4
11
|
// Default system context
|
|
5
12
|
const DEFAULT_SYSTEM_CONTEXT = {
|
|
6
13
|
systemPrompt: "You are a helpful AI assistant.",
|
|
@@ -14,7 +21,8 @@ const getGoogleAIApiKey = () => {
|
|
|
14
21
|
}
|
|
15
22
|
// Ensure GOOGLE_GENERATIVE_AI_API_KEY is set for @ai-sdk/google compatibility
|
|
16
23
|
// The AI SDK specifically looks for this variable name
|
|
17
|
-
if (!process.env.GOOGLE_GENERATIVE_AI_API_KEY &&
|
|
24
|
+
if (!process.env.GOOGLE_GENERATIVE_AI_API_KEY &&
|
|
25
|
+
process.env.GOOGLE_AI_API_KEY) {
|
|
18
26
|
process.env.GOOGLE_GENERATIVE_AI_API_KEY = process.env.GOOGLE_AI_API_KEY;
|
|
19
27
|
}
|
|
20
28
|
return apiKey;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@juspay/neurolink",
|
|
3
|
-
"version": "1.11.
|
|
3
|
+
"version": "1.11.3",
|
|
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",
|
|
@@ -42,7 +42,52 @@
|
|
|
42
42
|
"lint": "prettier --check . && eslint .",
|
|
43
43
|
"format": "prettier --write .",
|
|
44
44
|
"changeset": "changeset",
|
|
45
|
-
"changeset:version": "changeset version && git add --all"
|
|
45
|
+
"changeset:version": "changeset version && git add --all",
|
|
46
|
+
"// ===== NEUROLINK DEVELOPER EXPERIENCE ENHANCEMENT 2.0 =====": "",
|
|
47
|
+
"// Environment & Setup (pnpm-first)": "",
|
|
48
|
+
"setup": "pnpm install && node tools/automation/environment-manager.js",
|
|
49
|
+
"setup:complete": "pnpm run setup && pnpm run project:organize && pnpm run env:validate",
|
|
50
|
+
"env:setup": "node tools/automation/environment-manager.js",
|
|
51
|
+
"env:validate": "node tools/automation/environment-manager.js --validate",
|
|
52
|
+
"env:backup": "node tools/automation/environment-manager.js --backup",
|
|
53
|
+
"env:list-backups": "node tools/automation/environment-manager.js --list-backups",
|
|
54
|
+
"// Project Management & Analysis": "",
|
|
55
|
+
"project:analyze": "node tools/automation/script-analyzer.js",
|
|
56
|
+
"project:cleanup": "node tools/automation/script-analyzer.js --execute",
|
|
57
|
+
"project:organize": "node tools/automation/project-organizer.js",
|
|
58
|
+
"project:health": "node tools/development/health-monitor.js",
|
|
59
|
+
"// Shell Script Conversion": "",
|
|
60
|
+
"convert:shell-scripts": "node tools/automation/shell-converter.js",
|
|
61
|
+
"convert:specific": "node tools/automation/shell-converter.js --specific",
|
|
62
|
+
"// Testing (Enhanced & Adaptive)": "",
|
|
63
|
+
"test:smart": "node tools/testing/adaptive-test-runner.js",
|
|
64
|
+
"test:providers": "node tools/testing/provider-validator.js",
|
|
65
|
+
"test:performance": "node tools/testing/performance-monitor.js",
|
|
66
|
+
"test:coverage": "vitest run --coverage",
|
|
67
|
+
"test:ci": "pnpm run test:smart && pnpm run test:coverage",
|
|
68
|
+
"// Content Generation (Cross-platform JS)": "",
|
|
69
|
+
"content:screenshots": "node tools/content/screenshot-automation.js",
|
|
70
|
+
"content:videos": "node tools/converted-scripts/generate-all-videos.js",
|
|
71
|
+
"content:cleanup": "node tools/converted-scripts/cleanup-hash-named-videos.js",
|
|
72
|
+
"content:all": "pnpm run content:screenshots && pnpm run content:videos",
|
|
73
|
+
"// Documentation Automation": "",
|
|
74
|
+
"docs:sync": "node tools/content/documentation-sync.js",
|
|
75
|
+
"docs:validate": "node tools/content/documentation-sync.js --validate",
|
|
76
|
+
"docs:generate": "pnpm run docs:sync && pnpm run content:screenshots",
|
|
77
|
+
"// Development & Monitoring": "",
|
|
78
|
+
"dev:full": "node tools/development/dev-server.js",
|
|
79
|
+
"dev:health": "node tools/development/health-monitor.js",
|
|
80
|
+
"dev:demo": "concurrently \"pnpm run dev\" \"node neurolink-demo/complete-enhanced-server.js\"",
|
|
81
|
+
"// Build & Deploy (Complete Pipeline)": "",
|
|
82
|
+
"build:complete": "node tools/automation/build-system.js",
|
|
83
|
+
"build:analyze": "node tools/development/dependency-analyzer.js",
|
|
84
|
+
"// Quality & Maintenance": "",
|
|
85
|
+
"quality:all": "pnpm run lint && pnpm run format && pnpm run test:ci",
|
|
86
|
+
"clean": "pnpm run content:cleanup && rm -rf dist .svelte-kit node_modules/.cache",
|
|
87
|
+
"reset": "pnpm run clean && pnpm install",
|
|
88
|
+
"audit": "pnpm audit && pnpm run build:analyze",
|
|
89
|
+
"// Release & Publishing": "",
|
|
90
|
+
"release": "pnpm run build:complete && pnpm run test:ci && changeset publish"
|
|
46
91
|
},
|
|
47
92
|
"files": [
|
|
48
93
|
"dist",
|