@juspay/neurolink 1.2.3 → 1.3.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 +108 -0
- package/README.md +213 -1138
- package/dist/cli/commands/config.d.ts +373 -0
- package/dist/cli/commands/config.js +532 -0
- package/dist/cli/commands/mcp.d.ts +7 -0
- package/dist/cli/commands/mcp.js +434 -0
- package/dist/cli/index.d.ts +9 -0
- package/dist/cli/index.js +451 -169
- package/dist/core/factory.js +10 -2
- package/dist/core/types.d.ts +3 -1
- package/dist/core/types.js +2 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/mcp/context-manager.d.ts +164 -0
- package/dist/mcp/context-manager.js +273 -0
- package/dist/mcp/factory.d.ts +144 -0
- package/dist/mcp/factory.js +141 -0
- package/dist/mcp/orchestrator.d.ts +170 -0
- package/dist/mcp/orchestrator.js +372 -0
- package/dist/mcp/registry.d.ts +188 -0
- package/dist/mcp/registry.js +373 -0
- package/dist/mcp/servers/ai-providers/ai-core-server.d.ts +10 -0
- package/dist/mcp/servers/ai-providers/ai-core-server.js +280 -0
- package/dist/neurolink.d.ts +2 -2
- package/dist/neurolink.js +1 -1
- package/dist/providers/anthropic.d.ts +34 -0
- package/dist/providers/anthropic.js +307 -0
- package/dist/providers/azureOpenAI.d.ts +37 -0
- package/dist/providers/azureOpenAI.js +338 -0
- package/dist/providers/index.d.ts +4 -0
- package/dist/providers/index.js +5 -1
- package/dist/utils/providerUtils.js +8 -2
- package/package.json +163 -97
|
@@ -0,0 +1,532 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* NeuroLink CLI Configuration Management
|
|
4
|
+
*
|
|
5
|
+
* Enhanced configuration system with interactive setup,
|
|
6
|
+
* multi-profile support, and smart validation.
|
|
7
|
+
*/
|
|
8
|
+
import inquirer from 'inquirer';
|
|
9
|
+
import fs from 'fs';
|
|
10
|
+
import path from 'path';
|
|
11
|
+
import os from 'os';
|
|
12
|
+
import chalk from 'chalk';
|
|
13
|
+
import { z } from 'zod';
|
|
14
|
+
// Configuration schema for validation
|
|
15
|
+
const ConfigSchema = z.object({
|
|
16
|
+
defaultProvider: z.enum(['auto', 'openai', 'bedrock', 'vertex', 'anthropic', 'azure', 'huggingface']).default('auto'),
|
|
17
|
+
providers: z.object({
|
|
18
|
+
openai: z.object({
|
|
19
|
+
apiKey: z.string().optional(),
|
|
20
|
+
model: z.string().default('gpt-4'),
|
|
21
|
+
baseURL: z.string().optional()
|
|
22
|
+
}).optional(),
|
|
23
|
+
bedrock: z.object({
|
|
24
|
+
region: z.string().optional(),
|
|
25
|
+
accessKeyId: z.string().optional(),
|
|
26
|
+
secretAccessKey: z.string().optional(),
|
|
27
|
+
sessionToken: z.string().optional(),
|
|
28
|
+
model: z.string().default('arn:aws:bedrock:us-east-2:225681119357:inference-profile/us.anthropic.claude-3-7-sonnet-20250219-v1:0')
|
|
29
|
+
}).optional(),
|
|
30
|
+
vertex: z.object({
|
|
31
|
+
projectId: z.string().optional(),
|
|
32
|
+
location: z.string().default('us-east5'),
|
|
33
|
+
credentials: z.string().optional(),
|
|
34
|
+
serviceAccountKey: z.string().optional(),
|
|
35
|
+
clientEmail: z.string().optional(),
|
|
36
|
+
privateKey: z.string().optional(),
|
|
37
|
+
model: z.string().default('gemini-1.5-pro')
|
|
38
|
+
}).optional(),
|
|
39
|
+
anthropic: z.object({
|
|
40
|
+
apiKey: z.string().optional(),
|
|
41
|
+
model: z.string().default('claude-3-5-sonnet-20241022')
|
|
42
|
+
}).optional(),
|
|
43
|
+
azure: z.object({
|
|
44
|
+
apiKey: z.string().optional(),
|
|
45
|
+
endpoint: z.string().optional(),
|
|
46
|
+
deploymentId: z.string().optional(),
|
|
47
|
+
model: z.string().default('gpt-4')
|
|
48
|
+
}).optional(),
|
|
49
|
+
huggingface: z.object({
|
|
50
|
+
apiKey: z.string().optional(),
|
|
51
|
+
model: z.string().default('microsoft/DialoGPT-large')
|
|
52
|
+
}).optional()
|
|
53
|
+
}).default({}),
|
|
54
|
+
profiles: z.record(z.string(), z.any()).default({}),
|
|
55
|
+
preferences: z.object({
|
|
56
|
+
outputFormat: z.enum(['text', 'json', 'yaml']).default('text'),
|
|
57
|
+
temperature: z.number().min(0).max(2).default(0.7),
|
|
58
|
+
maxTokens: z.number().min(1).max(4000).default(500),
|
|
59
|
+
enableLogging: z.boolean().default(false),
|
|
60
|
+
enableCaching: z.boolean().default(true),
|
|
61
|
+
cacheStrategy: z.enum(['memory', 'file', 'redis']).default('memory')
|
|
62
|
+
}).default({})
|
|
63
|
+
});
|
|
64
|
+
export class ConfigManager {
|
|
65
|
+
configDir;
|
|
66
|
+
configFile;
|
|
67
|
+
config;
|
|
68
|
+
constructor() {
|
|
69
|
+
this.configDir = path.join(os.homedir(), '.neurolink');
|
|
70
|
+
this.configFile = path.join(this.configDir, 'config.json');
|
|
71
|
+
this.config = this.loadConfig();
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Load configuration from file or create default
|
|
75
|
+
*/
|
|
76
|
+
loadConfig() {
|
|
77
|
+
try {
|
|
78
|
+
if (fs.existsSync(this.configFile)) {
|
|
79
|
+
const configData = JSON.parse(fs.readFileSync(this.configFile, 'utf8'));
|
|
80
|
+
return ConfigSchema.parse(configData);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
console.warn(chalk.yellow(`⚠️ Invalid config file: ${error instanceof Error ? error.message : 'Unknown error'}`));
|
|
85
|
+
}
|
|
86
|
+
return ConfigSchema.parse({});
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Save configuration to file
|
|
90
|
+
*/
|
|
91
|
+
saveConfig() {
|
|
92
|
+
try {
|
|
93
|
+
// Ensure config directory exists
|
|
94
|
+
if (!fs.existsSync(this.configDir)) {
|
|
95
|
+
fs.mkdirSync(this.configDir, { recursive: true });
|
|
96
|
+
}
|
|
97
|
+
// Validate before saving
|
|
98
|
+
const validatedConfig = ConfigSchema.parse(this.config);
|
|
99
|
+
fs.writeFileSync(this.configFile, JSON.stringify(validatedConfig, null, 2));
|
|
100
|
+
console.log(chalk.green(`✅ Configuration saved to ${this.configFile}`));
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
console.error(chalk.red(`❌ Failed to save config: ${error instanceof Error ? error.message : 'Unknown error'}`));
|
|
104
|
+
process.exit(1);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Interactive configuration setup
|
|
109
|
+
*/
|
|
110
|
+
async initInteractive() {
|
|
111
|
+
console.log(chalk.blue('🧠 NeuroLink Configuration Setup\n'));
|
|
112
|
+
try {
|
|
113
|
+
// Basic preferences
|
|
114
|
+
const preferences = await inquirer.prompt([
|
|
115
|
+
{
|
|
116
|
+
type: 'list',
|
|
117
|
+
name: 'defaultProvider',
|
|
118
|
+
message: 'Select your default AI provider:',
|
|
119
|
+
choices: [
|
|
120
|
+
{ name: 'Auto (recommended) - Automatically select best available', value: 'auto' },
|
|
121
|
+
{ name: 'OpenAI - GPT models', value: 'openai' },
|
|
122
|
+
{ name: 'Amazon Bedrock - Claude, Llama, Titan', value: 'bedrock' },
|
|
123
|
+
{ name: 'Google Vertex AI - Gemini models', value: 'vertex' },
|
|
124
|
+
{ name: 'Anthropic - Claude models (direct)', value: 'anthropic' },
|
|
125
|
+
{ name: 'Azure OpenAI - Enterprise GPT', value: 'azure' },
|
|
126
|
+
{ name: 'Hugging Face - Open source models', value: 'huggingface' }
|
|
127
|
+
],
|
|
128
|
+
default: this.config.defaultProvider
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
type: 'list',
|
|
132
|
+
name: 'outputFormat',
|
|
133
|
+
message: 'Preferred output format:',
|
|
134
|
+
choices: ['text', 'json', 'yaml'],
|
|
135
|
+
default: this.config.preferences.outputFormat
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
type: 'number',
|
|
139
|
+
name: 'temperature',
|
|
140
|
+
message: 'Default creativity level (0.0 = focused, 1.0 = creative):',
|
|
141
|
+
default: this.config.preferences.temperature,
|
|
142
|
+
validate: (value) => value >= 0 && value <= 2
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
type: 'confirm',
|
|
146
|
+
name: 'setupProviders',
|
|
147
|
+
message: 'Would you like to configure provider credentials now?',
|
|
148
|
+
default: true
|
|
149
|
+
}
|
|
150
|
+
]);
|
|
151
|
+
// Update config with preferences
|
|
152
|
+
this.config.defaultProvider = preferences.defaultProvider;
|
|
153
|
+
this.config.preferences.outputFormat = preferences.outputFormat;
|
|
154
|
+
this.config.preferences.temperature = preferences.temperature;
|
|
155
|
+
// Setup providers if requested
|
|
156
|
+
if (preferences.setupProviders) {
|
|
157
|
+
await this.setupProviders();
|
|
158
|
+
}
|
|
159
|
+
this.saveConfig();
|
|
160
|
+
console.log(chalk.green('\n✅ Configuration setup complete!'));
|
|
161
|
+
console.log(chalk.blue('💡 You can modify settings anytime with: neurolink config edit'));
|
|
162
|
+
console.log(chalk.blue('💡 Test your setup with: neurolink status'));
|
|
163
|
+
}
|
|
164
|
+
catch (error) {
|
|
165
|
+
if (error instanceof Error && error.message === 'User force closed the prompt with 0 null') {
|
|
166
|
+
console.log(chalk.yellow('\n⚠️ Setup cancelled by user'));
|
|
167
|
+
process.exit(0);
|
|
168
|
+
}
|
|
169
|
+
throw error;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Setup individual providers
|
|
174
|
+
*/
|
|
175
|
+
async setupProviders() {
|
|
176
|
+
const { selectedProviders } = await inquirer.prompt([
|
|
177
|
+
{
|
|
178
|
+
type: 'checkbox',
|
|
179
|
+
name: 'selectedProviders',
|
|
180
|
+
message: 'Select providers to configure:',
|
|
181
|
+
choices: [
|
|
182
|
+
{ name: 'OpenAI (GPT-4, GPT-3.5)', value: 'openai' },
|
|
183
|
+
{ name: 'Amazon Bedrock (Claude, Llama)', value: 'bedrock' },
|
|
184
|
+
{ name: 'Google Vertex AI (Gemini)', value: 'vertex' },
|
|
185
|
+
{ name: 'Anthropic Direct (Claude)', value: 'anthropic' },
|
|
186
|
+
{ name: 'Azure OpenAI (Enterprise)', value: 'azure' },
|
|
187
|
+
{ name: 'Hugging Face (Open Source)', value: 'huggingface' }
|
|
188
|
+
]
|
|
189
|
+
}
|
|
190
|
+
]);
|
|
191
|
+
for (const provider of selectedProviders) {
|
|
192
|
+
await this.setupProvider(provider);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Setup individual provider
|
|
197
|
+
*/
|
|
198
|
+
async setupProvider(provider) {
|
|
199
|
+
console.log(chalk.blue(`\n🔧 Configuring ${provider.toUpperCase()}`));
|
|
200
|
+
switch (provider) {
|
|
201
|
+
case 'openai':
|
|
202
|
+
await this.setupOpenAI();
|
|
203
|
+
break;
|
|
204
|
+
case 'bedrock':
|
|
205
|
+
await this.setupBedrock();
|
|
206
|
+
break;
|
|
207
|
+
case 'vertex':
|
|
208
|
+
await this.setupVertex();
|
|
209
|
+
break;
|
|
210
|
+
case 'anthropic':
|
|
211
|
+
await this.setupAnthropic();
|
|
212
|
+
break;
|
|
213
|
+
case 'azure':
|
|
214
|
+
await this.setupAzure();
|
|
215
|
+
break;
|
|
216
|
+
case 'huggingface':
|
|
217
|
+
await this.setupHuggingFace();
|
|
218
|
+
break;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* OpenAI provider setup
|
|
223
|
+
*/
|
|
224
|
+
async setupOpenAI() {
|
|
225
|
+
const answers = await inquirer.prompt([
|
|
226
|
+
{
|
|
227
|
+
type: 'password',
|
|
228
|
+
name: 'apiKey',
|
|
229
|
+
message: 'OpenAI API Key (sk-...):',
|
|
230
|
+
validate: (value) => value.startsWith('sk-') || 'API key should start with "sk-"'
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
type: 'list',
|
|
234
|
+
name: 'model',
|
|
235
|
+
message: 'Default model:',
|
|
236
|
+
choices: ['gpt-4', 'gpt-4-turbo', 'gpt-3.5-turbo'],
|
|
237
|
+
default: 'gpt-4'
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
type: 'input',
|
|
241
|
+
name: 'baseURL',
|
|
242
|
+
message: 'Custom base URL (optional):',
|
|
243
|
+
default: ''
|
|
244
|
+
}
|
|
245
|
+
]);
|
|
246
|
+
this.config.providers.openai = {
|
|
247
|
+
apiKey: answers.apiKey,
|
|
248
|
+
model: answers.model,
|
|
249
|
+
...(answers.baseURL && { baseURL: answers.baseURL })
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Amazon Bedrock provider setup
|
|
254
|
+
*/
|
|
255
|
+
async setupBedrock() {
|
|
256
|
+
const answers = await inquirer.prompt([
|
|
257
|
+
{
|
|
258
|
+
type: 'input',
|
|
259
|
+
name: 'region',
|
|
260
|
+
message: 'AWS Region:',
|
|
261
|
+
default: 'us-east-1'
|
|
262
|
+
},
|
|
263
|
+
{
|
|
264
|
+
type: 'input',
|
|
265
|
+
name: 'accessKeyId',
|
|
266
|
+
message: 'AWS Access Key ID (optional if using IAM roles):'
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
type: 'password',
|
|
270
|
+
name: 'secretAccessKey',
|
|
271
|
+
message: 'AWS Secret Access Key (optional if using IAM roles):'
|
|
272
|
+
},
|
|
273
|
+
{
|
|
274
|
+
type: 'password',
|
|
275
|
+
name: 'sessionToken',
|
|
276
|
+
message: 'AWS Session Token (optional):'
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
type: 'input',
|
|
280
|
+
name: 'model',
|
|
281
|
+
message: 'Model ARN:',
|
|
282
|
+
default: 'arn:aws:bedrock:us-east-2:225681119357:inference-profile/us.anthropic.claude-3-7-sonnet-20250219-v1:0'
|
|
283
|
+
}
|
|
284
|
+
]);
|
|
285
|
+
this.config.providers.bedrock = {
|
|
286
|
+
region: answers.region,
|
|
287
|
+
...(answers.accessKeyId && { accessKeyId: answers.accessKeyId }),
|
|
288
|
+
...(answers.secretAccessKey && { secretAccessKey: answers.secretAccessKey }),
|
|
289
|
+
...(answers.sessionToken && { sessionToken: answers.sessionToken }),
|
|
290
|
+
model: answers.model
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Google Vertex AI provider setup
|
|
295
|
+
*/
|
|
296
|
+
async setupVertex() {
|
|
297
|
+
const { authMethod } = await inquirer.prompt([
|
|
298
|
+
{
|
|
299
|
+
type: 'list',
|
|
300
|
+
name: 'authMethod',
|
|
301
|
+
message: 'Authentication method:',
|
|
302
|
+
choices: [
|
|
303
|
+
{ name: 'Service Account File', value: 'file' },
|
|
304
|
+
{ name: 'Service Account JSON String', value: 'json' },
|
|
305
|
+
{ name: 'Individual Environment Variables', value: 'env' }
|
|
306
|
+
]
|
|
307
|
+
}
|
|
308
|
+
]);
|
|
309
|
+
const commonAnswers = await inquirer.prompt([
|
|
310
|
+
{
|
|
311
|
+
type: 'input',
|
|
312
|
+
name: 'projectId',
|
|
313
|
+
message: 'Google Cloud Project ID:',
|
|
314
|
+
validate: (value) => value.length > 0 || 'Project ID is required'
|
|
315
|
+
},
|
|
316
|
+
{
|
|
317
|
+
type: 'input',
|
|
318
|
+
name: 'location',
|
|
319
|
+
message: 'Vertex AI Location:',
|
|
320
|
+
default: 'us-east5'
|
|
321
|
+
},
|
|
322
|
+
{
|
|
323
|
+
type: 'list',
|
|
324
|
+
name: 'model',
|
|
325
|
+
message: 'Default model:',
|
|
326
|
+
choices: ['gemini-1.5-pro', 'gemini-1.5-flash', 'gemini-pro'],
|
|
327
|
+
default: 'gemini-1.5-pro'
|
|
328
|
+
}
|
|
329
|
+
]);
|
|
330
|
+
let authConfig = {};
|
|
331
|
+
switch (authMethod) {
|
|
332
|
+
case 'file':
|
|
333
|
+
const fileAnswers = await inquirer.prompt([
|
|
334
|
+
{
|
|
335
|
+
type: 'input',
|
|
336
|
+
name: 'credentials',
|
|
337
|
+
message: 'Path to service account JSON file:',
|
|
338
|
+
validate: (value) => fs.existsSync(value) || 'File does not exist'
|
|
339
|
+
}
|
|
340
|
+
]);
|
|
341
|
+
authConfig = { credentials: fileAnswers.credentials };
|
|
342
|
+
break;
|
|
343
|
+
case 'json':
|
|
344
|
+
const jsonAnswers = await inquirer.prompt([
|
|
345
|
+
{
|
|
346
|
+
type: 'input',
|
|
347
|
+
name: 'serviceAccountKey',
|
|
348
|
+
message: 'Service account JSON string:',
|
|
349
|
+
validate: (value) => {
|
|
350
|
+
try {
|
|
351
|
+
JSON.parse(value);
|
|
352
|
+
return true;
|
|
353
|
+
}
|
|
354
|
+
catch {
|
|
355
|
+
return 'Invalid JSON';
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
]);
|
|
360
|
+
authConfig = { serviceAccountKey: jsonAnswers.serviceAccountKey };
|
|
361
|
+
break;
|
|
362
|
+
case 'env':
|
|
363
|
+
const envAnswers = await inquirer.prompt([
|
|
364
|
+
{
|
|
365
|
+
type: 'input',
|
|
366
|
+
name: 'clientEmail',
|
|
367
|
+
message: 'Service account email:',
|
|
368
|
+
validate: (value) => value.includes('@') || 'Invalid email format'
|
|
369
|
+
},
|
|
370
|
+
{
|
|
371
|
+
type: 'password',
|
|
372
|
+
name: 'privateKey',
|
|
373
|
+
message: 'Private key:'
|
|
374
|
+
}
|
|
375
|
+
]);
|
|
376
|
+
authConfig = {
|
|
377
|
+
clientEmail: envAnswers.clientEmail,
|
|
378
|
+
privateKey: envAnswers.privateKey
|
|
379
|
+
};
|
|
380
|
+
break;
|
|
381
|
+
}
|
|
382
|
+
this.config.providers.vertex = {
|
|
383
|
+
projectId: commonAnswers.projectId,
|
|
384
|
+
location: commonAnswers.location,
|
|
385
|
+
model: commonAnswers.model,
|
|
386
|
+
...authConfig
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
390
|
+
* Anthropic provider setup
|
|
391
|
+
*/
|
|
392
|
+
async setupAnthropic() {
|
|
393
|
+
const answers = await inquirer.prompt([
|
|
394
|
+
{
|
|
395
|
+
type: 'password',
|
|
396
|
+
name: 'apiKey',
|
|
397
|
+
message: 'Anthropic API Key:',
|
|
398
|
+
validate: (value) => value.length > 0 || 'API key is required'
|
|
399
|
+
},
|
|
400
|
+
{
|
|
401
|
+
type: 'list',
|
|
402
|
+
name: 'model',
|
|
403
|
+
message: 'Default model:',
|
|
404
|
+
choices: [
|
|
405
|
+
'claude-3-5-sonnet-20241022',
|
|
406
|
+
'claude-3-5-haiku-20241022',
|
|
407
|
+
'claude-3-opus-20240229'
|
|
408
|
+
],
|
|
409
|
+
default: 'claude-3-5-sonnet-20241022'
|
|
410
|
+
}
|
|
411
|
+
]);
|
|
412
|
+
this.config.providers.anthropic = answers;
|
|
413
|
+
}
|
|
414
|
+
/**
|
|
415
|
+
* Azure OpenAI provider setup
|
|
416
|
+
*/
|
|
417
|
+
async setupAzure() {
|
|
418
|
+
const answers = await inquirer.prompt([
|
|
419
|
+
{
|
|
420
|
+
type: 'password',
|
|
421
|
+
name: 'apiKey',
|
|
422
|
+
message: 'Azure OpenAI API Key:'
|
|
423
|
+
},
|
|
424
|
+
{
|
|
425
|
+
type: 'input',
|
|
426
|
+
name: 'endpoint',
|
|
427
|
+
message: 'Azure OpenAI Endpoint:',
|
|
428
|
+
validate: (value) => value.startsWith('https://') || 'Endpoint should start with https://'
|
|
429
|
+
},
|
|
430
|
+
{
|
|
431
|
+
type: 'input',
|
|
432
|
+
name: 'deploymentId',
|
|
433
|
+
message: 'Deployment ID:'
|
|
434
|
+
},
|
|
435
|
+
{
|
|
436
|
+
type: 'list',
|
|
437
|
+
name: 'model',
|
|
438
|
+
message: 'Model:',
|
|
439
|
+
choices: ['gpt-4', 'gpt-4-turbo', 'gpt-35-turbo'],
|
|
440
|
+
default: 'gpt-4'
|
|
441
|
+
}
|
|
442
|
+
]);
|
|
443
|
+
this.config.providers.azure = answers;
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* Hugging Face provider setup
|
|
447
|
+
*/
|
|
448
|
+
async setupHuggingFace() {
|
|
449
|
+
const answers = await inquirer.prompt([
|
|
450
|
+
{
|
|
451
|
+
type: 'password',
|
|
452
|
+
name: 'apiKey',
|
|
453
|
+
message: 'Hugging Face API Key:'
|
|
454
|
+
},
|
|
455
|
+
{
|
|
456
|
+
type: 'input',
|
|
457
|
+
name: 'model',
|
|
458
|
+
message: 'Model name:',
|
|
459
|
+
default: 'microsoft/DialoGPT-large'
|
|
460
|
+
}
|
|
461
|
+
]);
|
|
462
|
+
this.config.providers.huggingface = answers;
|
|
463
|
+
}
|
|
464
|
+
/**
|
|
465
|
+
* Get current configuration
|
|
466
|
+
*/
|
|
467
|
+
getConfig() {
|
|
468
|
+
return this.config;
|
|
469
|
+
}
|
|
470
|
+
/**
|
|
471
|
+
* Update configuration
|
|
472
|
+
*/
|
|
473
|
+
updateConfig(updates) {
|
|
474
|
+
this.config = { ...this.config, ...updates };
|
|
475
|
+
this.saveConfig();
|
|
476
|
+
}
|
|
477
|
+
/**
|
|
478
|
+
* Show current configuration
|
|
479
|
+
*/
|
|
480
|
+
showConfig() {
|
|
481
|
+
console.log(chalk.blue('📋 Current NeuroLink Configuration\n'));
|
|
482
|
+
console.log(chalk.cyan('General Settings:'));
|
|
483
|
+
console.log(` Default Provider: ${chalk.white(this.config.defaultProvider)}`);
|
|
484
|
+
console.log(` Output Format: ${chalk.white(this.config.preferences.outputFormat)}`);
|
|
485
|
+
console.log(` Temperature: ${chalk.white(this.config.preferences.temperature)}`);
|
|
486
|
+
console.log(` Max Tokens: ${chalk.white(this.config.preferences.maxTokens)}`);
|
|
487
|
+
console.log(chalk.cyan('\nConfigured Providers:'));
|
|
488
|
+
Object.entries(this.config.providers).forEach(([name, config]) => {
|
|
489
|
+
if (config && Object.keys(config).length > 0) {
|
|
490
|
+
console.log(` ${chalk.green('✅')} ${name.toUpperCase()}`);
|
|
491
|
+
if ('model' in config) {
|
|
492
|
+
console.log(` Model: ${chalk.white(config.model)}`);
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
});
|
|
496
|
+
console.log(chalk.cyan('\nConfiguration File:'));
|
|
497
|
+
console.log(` Location: ${chalk.white(this.configFile)}`);
|
|
498
|
+
}
|
|
499
|
+
/**
|
|
500
|
+
* Validate configuration
|
|
501
|
+
*/
|
|
502
|
+
validateConfig() {
|
|
503
|
+
const errors = [];
|
|
504
|
+
try {
|
|
505
|
+
ConfigSchema.parse(this.config);
|
|
506
|
+
}
|
|
507
|
+
catch (error) {
|
|
508
|
+
if (error instanceof z.ZodError) {
|
|
509
|
+
errors.push(...error.errors.map(e => `${e.path.join('.')}: ${e.message}`));
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
// Check for at least one configured provider
|
|
513
|
+
const hasProvider = Object.values(this.config.providers).some(provider => provider && Object.keys(provider).length > 0);
|
|
514
|
+
if (!hasProvider) {
|
|
515
|
+
errors.push('No providers configured. Run "neurolink config init" to set up providers.');
|
|
516
|
+
}
|
|
517
|
+
return {
|
|
518
|
+
valid: errors.length === 0,
|
|
519
|
+
errors
|
|
520
|
+
};
|
|
521
|
+
}
|
|
522
|
+
/**
|
|
523
|
+
* Reset configuration to defaults
|
|
524
|
+
*/
|
|
525
|
+
resetConfig() {
|
|
526
|
+
this.config = ConfigSchema.parse({});
|
|
527
|
+
this.saveConfig();
|
|
528
|
+
console.log(chalk.green('✅ Configuration reset to defaults'));
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
// Export for use in other CLI commands
|
|
532
|
+
export const configManager = new ConfigManager();
|