@juspay/neurolink 7.34.0 → 7.36.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 (57) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +64 -7
  3. package/dist/adapters/providerImageAdapter.d.ts +56 -0
  4. package/dist/adapters/providerImageAdapter.js +257 -0
  5. package/dist/cli/commands/config.d.ts +20 -20
  6. package/dist/cli/commands/setup-anthropic.d.ts +16 -0
  7. package/dist/cli/commands/setup-anthropic.js +414 -0
  8. package/dist/cli/commands/setup-azure.d.ts +17 -0
  9. package/dist/cli/commands/setup-azure.js +415 -0
  10. package/dist/cli/commands/setup-bedrock.d.ts +13 -0
  11. package/dist/cli/commands/setup-bedrock.js +487 -0
  12. package/dist/cli/commands/setup-gcp.d.ts +18 -0
  13. package/dist/cli/commands/setup-gcp.js +569 -0
  14. package/dist/cli/commands/setup-google-ai.d.ts +16 -0
  15. package/dist/cli/commands/setup-google-ai.js +369 -0
  16. package/dist/cli/commands/setup-huggingface.d.ts +8 -0
  17. package/dist/cli/commands/setup-huggingface.js +200 -0
  18. package/dist/cli/commands/setup-mistral.d.ts +8 -0
  19. package/dist/cli/commands/setup-mistral.js +233 -0
  20. package/dist/cli/commands/setup-openai.d.ts +16 -0
  21. package/dist/cli/commands/setup-openai.js +402 -0
  22. package/dist/cli/commands/setup.d.ts +19 -0
  23. package/dist/cli/commands/setup.js +539 -0
  24. package/dist/cli/factories/commandFactory.d.ts +5 -0
  25. package/dist/cli/factories/commandFactory.js +67 -3
  26. package/dist/cli/factories/setupCommandFactory.d.ts +18 -0
  27. package/dist/cli/factories/setupCommandFactory.js +137 -0
  28. package/dist/cli/parser.js +4 -1
  29. package/dist/cli/utils/envManager.d.ts +3 -2
  30. package/dist/cli/utils/envManager.js +18 -4
  31. package/dist/core/baseProvider.js +99 -45
  32. package/dist/core/types.d.ts +3 -0
  33. package/dist/lib/adapters/providerImageAdapter.d.ts +56 -0
  34. package/dist/lib/adapters/providerImageAdapter.js +257 -0
  35. package/dist/lib/core/baseProvider.js +99 -45
  36. package/dist/lib/core/types.d.ts +3 -0
  37. package/dist/lib/neurolink.js +8 -3
  38. package/dist/lib/types/content.d.ts +78 -0
  39. package/dist/lib/types/content.js +5 -0
  40. package/dist/lib/types/conversation.d.ts +19 -0
  41. package/dist/lib/types/generateTypes.d.ts +4 -1
  42. package/dist/lib/types/streamTypes.d.ts +6 -3
  43. package/dist/lib/utils/imageProcessor.d.ts +84 -0
  44. package/dist/lib/utils/imageProcessor.js +362 -0
  45. package/dist/lib/utils/messageBuilder.d.ts +8 -1
  46. package/dist/lib/utils/messageBuilder.js +279 -0
  47. package/dist/neurolink.js +8 -3
  48. package/dist/types/content.d.ts +78 -0
  49. package/dist/types/content.js +5 -0
  50. package/dist/types/conversation.d.ts +19 -0
  51. package/dist/types/generateTypes.d.ts +4 -1
  52. package/dist/types/streamTypes.d.ts +6 -3
  53. package/dist/utils/imageProcessor.d.ts +84 -0
  54. package/dist/utils/imageProcessor.js +362 -0
  55. package/dist/utils/messageBuilder.d.ts +8 -1
  56. package/dist/utils/messageBuilder.js +279 -0
  57. package/package.json +1 -1
@@ -0,0 +1,415 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Azure OpenAI Setup Command
4
+ *
5
+ * Setup for Azure OpenAI integration:
6
+ * - AZURE_OPENAI_API_KEY (required)
7
+ * - AZURE_OPENAI_ENDPOINT (required)
8
+ * - AZURE_OPENAI_MODEL (optional)
9
+ *
10
+ * Follows the same UX patterns as other setup commands
11
+ */
12
+ import inquirer from "inquirer";
13
+ import chalk from "chalk";
14
+ import ora from "ora";
15
+ import { logger } from "../../lib/utils/logger.js";
16
+ import { updateEnvFile as updateEnvFileShared, displayEnvUpdateSummary, } from "../utils/envManager.js";
17
+ export async function handleAzureSetup(argv) {
18
+ try {
19
+ const options = {
20
+ checkOnly: argv.check || false,
21
+ interactive: !argv.nonInteractive,
22
+ };
23
+ logger.always(chalk.blue("🔍 Checking Azure OpenAI configuration..."));
24
+ // Step 1: Check for existing configuration
25
+ const hasApiKey = !!process.env.AZURE_OPENAI_API_KEY;
26
+ const hasEndpoint = !!process.env.AZURE_OPENAI_ENDPOINT;
27
+ const hasModel = !!process.env.AZURE_OPENAI_MODEL;
28
+ // Display current status
29
+ displayCurrentStatus(hasApiKey, hasEndpoint, hasModel);
30
+ // Check-only mode - show status and exit
31
+ if (options.checkOnly) {
32
+ if (hasApiKey && hasEndpoint) {
33
+ logger.always(chalk.green("✅ Azure OpenAI setup complete"));
34
+ const apiKey = process.env.AZURE_OPENAI_API_KEY;
35
+ if (apiKey) {
36
+ logger.always(` API Key: ${maskCredential(apiKey)}`);
37
+ }
38
+ logger.always(` Endpoint: ${process.env.AZURE_OPENAI_ENDPOINT}`);
39
+ if (hasModel) {
40
+ logger.always(` Model: ${process.env.AZURE_OPENAI_MODEL}`);
41
+ }
42
+ else {
43
+ logger.always(" Model: (using deployment default)");
44
+ }
45
+ }
46
+ else {
47
+ logger.always(chalk.yellow("⚠️ Azure OpenAI setup incomplete"));
48
+ }
49
+ return;
50
+ }
51
+ const config = {};
52
+ // Step 2: Handle existing configuration
53
+ if (hasApiKey && hasEndpoint) {
54
+ logger.always(chalk.green("✅ Azure OpenAI credentials found in environment"));
55
+ const apiKey = process.env.AZURE_OPENAI_API_KEY;
56
+ if (apiKey) {
57
+ logger.always(` API Key: ${maskCredential(apiKey)}`);
58
+ }
59
+ logger.always(` Endpoint: ${process.env.AZURE_OPENAI_ENDPOINT}`);
60
+ if (hasModel) {
61
+ logger.always(` Model: ${process.env.AZURE_OPENAI_MODEL}`);
62
+ }
63
+ else {
64
+ logger.always(" Model: (using deployment default)");
65
+ }
66
+ if (options.interactive) {
67
+ const { reconfigure } = await inquirer.prompt([
68
+ {
69
+ type: "confirm",
70
+ name: "reconfigure",
71
+ message: "Azure OpenAI is already configured. Do you want to reconfigure?",
72
+ default: false,
73
+ },
74
+ ]);
75
+ if (!reconfigure) {
76
+ // Still offer model selection if no model is set
77
+ if (!hasModel) {
78
+ const { wantsCustomModel } = await inquirer.prompt([
79
+ {
80
+ type: "confirm",
81
+ name: "wantsCustomModel",
82
+ message: "Do you want to specify an Azure OpenAI model? (optional)",
83
+ default: false,
84
+ },
85
+ ]);
86
+ if (wantsCustomModel) {
87
+ config.model = await promptForModel();
88
+ }
89
+ }
90
+ else {
91
+ // Offer to change existing model
92
+ const { wantsChangeModel } = await inquirer.prompt([
93
+ {
94
+ type: "confirm",
95
+ name: "wantsChangeModel",
96
+ message: `Do you want to change the Azure OpenAI model? (current: ${process.env.AZURE_OPENAI_MODEL})`,
97
+ default: false,
98
+ },
99
+ ]);
100
+ if (wantsChangeModel) {
101
+ config.model = await promptForModel();
102
+ }
103
+ }
104
+ if (config.model) {
105
+ await updateEnvFileWithConfig(config);
106
+ logger.always(chalk.green("✅ Model configuration updated!"));
107
+ logger.always(` AZURE_OPENAI_MODEL=${config.model}`);
108
+ }
109
+ else {
110
+ logger.always(chalk.blue("👍 Keeping existing configuration."));
111
+ }
112
+ // Show usage example
113
+ showUsageExample();
114
+ return;
115
+ }
116
+ else {
117
+ // User chose to reconfigure - mark this for proper handling
118
+ logger.always(chalk.blue("📝 Reconfiguring Azure OpenAI setup..."));
119
+ config.isReconfiguring = true;
120
+ }
121
+ }
122
+ else {
123
+ // Non-interactive mode - just use existing credentials
124
+ logger.always(chalk.green("✅ Setup complete! Using existing Azure OpenAI configuration."));
125
+ return;
126
+ }
127
+ }
128
+ // Step 3: Interactive setup for missing or reconfiguring credentials
129
+ if (options.interactive) {
130
+ const isReconfiguring = config.isReconfiguring === true;
131
+ // Handle API key setup/reconfiguration
132
+ if (!hasApiKey || isReconfiguring) {
133
+ if (!hasApiKey) {
134
+ // No API key exists - prompt for it
135
+ logger.always("");
136
+ logger.always(chalk.yellow("📋 To get your Azure OpenAI credentials:"));
137
+ logger.always("1. Visit: https://portal.azure.com/");
138
+ logger.always("2. Navigate to your Azure OpenAI resource");
139
+ logger.always("3. Go to 'Keys and Endpoint' section");
140
+ logger.always("4. Copy the API key and endpoint URL");
141
+ logger.always("");
142
+ }
143
+ else if (isReconfiguring) {
144
+ // Ask if they want to change the API key
145
+ const apiKey = process.env.AZURE_OPENAI_API_KEY;
146
+ const { wantsChangeApiKey } = await inquirer.prompt([
147
+ {
148
+ type: "confirm",
149
+ name: "wantsChangeApiKey",
150
+ message: `Do you want to change the Azure OpenAI API key? (current: ${apiKey ? maskCredential(apiKey) : "****"})`,
151
+ default: false,
152
+ },
153
+ ]);
154
+ if (!wantsChangeApiKey) {
155
+ config.apiKey = undefined; // Don't update the API key
156
+ }
157
+ }
158
+ if (!hasApiKey || (isReconfiguring && config.apiKey !== undefined)) {
159
+ const { apiKey } = await inquirer.prompt([
160
+ {
161
+ type: "password",
162
+ name: "apiKey",
163
+ message: isReconfiguring
164
+ ? "Enter your new Azure OpenAI API key:"
165
+ : "Enter your Azure OpenAI API key:",
166
+ validate: validateApiKey,
167
+ },
168
+ ]);
169
+ config.apiKey = apiKey.trim();
170
+ }
171
+ }
172
+ // Handle endpoint setup/reconfiguration
173
+ if (!hasEndpoint || isReconfiguring) {
174
+ if (isReconfiguring && hasEndpoint) {
175
+ const { wantsChangeEndpoint } = await inquirer.prompt([
176
+ {
177
+ type: "confirm",
178
+ name: "wantsChangeEndpoint",
179
+ message: `Do you want to change the Azure OpenAI endpoint? (current: ${process.env.AZURE_OPENAI_ENDPOINT})`,
180
+ default: false,
181
+ },
182
+ ]);
183
+ if (!wantsChangeEndpoint) {
184
+ config.endpoint = undefined; // Don't update the endpoint
185
+ }
186
+ }
187
+ if (!hasEndpoint ||
188
+ (isReconfiguring && config.endpoint !== undefined)) {
189
+ const { endpoint } = await inquirer.prompt([
190
+ {
191
+ type: "input",
192
+ name: "endpoint",
193
+ message: isReconfiguring
194
+ ? "Enter your new Azure OpenAI endpoint URL:"
195
+ : "Enter your Azure OpenAI endpoint URL:",
196
+ validate: validateEndpoint,
197
+ },
198
+ ]);
199
+ config.endpoint = endpoint.trim();
200
+ }
201
+ }
202
+ // Prompt for model selection
203
+ const { wantsCustomModel } = await inquirer.prompt([
204
+ {
205
+ type: "confirm",
206
+ name: "wantsCustomModel",
207
+ message: hasModel
208
+ ? `Do you want to change the Azure OpenAI model? (current: ${process.env.AZURE_OPENAI_MODEL})`
209
+ : "Do you want to specify an Azure OpenAI model? (optional)",
210
+ default: false,
211
+ },
212
+ ]);
213
+ if (wantsCustomModel) {
214
+ config.model = await promptForModel();
215
+ }
216
+ }
217
+ else {
218
+ // Non-interactive mode
219
+ logger.always(chalk.yellow("⚠️ Non-interactive mode: setup incomplete"));
220
+ logger.always(chalk.yellow("💡 Run without --non-interactive to configure Azure OpenAI"));
221
+ return;
222
+ }
223
+ // Step 4: Update .env file
224
+ if (config.apiKey || config.endpoint || config.model) {
225
+ await updateEnvFileWithConfig(config);
226
+ logger.always(chalk.green("✅ Azure OpenAI setup complete!"));
227
+ if (config.apiKey) {
228
+ logger.always(` API Key: ${maskCredential(config.apiKey)}`);
229
+ }
230
+ if (config.endpoint) {
231
+ logger.always(` Endpoint: ${config.endpoint}`);
232
+ }
233
+ if (config.model) {
234
+ logger.always(` Model: ${config.model}`);
235
+ }
236
+ // Show usage example
237
+ showUsageExample();
238
+ }
239
+ else if (options.interactive && !options.checkOnly) {
240
+ logger.always(chalk.green("✅ Setup complete!"));
241
+ showUsageExample();
242
+ }
243
+ }
244
+ catch (error) {
245
+ logger.error(chalk.red("❌ Azure OpenAI setup failed:"));
246
+ logger.error(chalk.red(error instanceof Error ? error.message : "Unknown error"));
247
+ process.exit(1);
248
+ }
249
+ }
250
+ /**
251
+ * Display current configuration status
252
+ */
253
+ function displayCurrentStatus(hasApiKey, hasEndpoint, hasModel) {
254
+ if (hasApiKey) {
255
+ logger.always(chalk.green("✔ AZURE_OPENAI_API_KEY found in environment"));
256
+ }
257
+ else {
258
+ logger.always(chalk.red("✘ AZURE_OPENAI_API_KEY not found"));
259
+ }
260
+ if (hasEndpoint) {
261
+ logger.always(chalk.green(`✔ AZURE_OPENAI_ENDPOINT found: ${process.env.AZURE_OPENAI_ENDPOINT}`));
262
+ }
263
+ else {
264
+ logger.always(chalk.red("✘ AZURE_OPENAI_ENDPOINT not found"));
265
+ }
266
+ if (hasModel) {
267
+ logger.always(chalk.green(`✔ AZURE_OPENAI_MODEL found: ${process.env.AZURE_OPENAI_MODEL}`));
268
+ }
269
+ else {
270
+ logger.always(chalk.yellow("⚠ AZURE_OPENAI_MODEL not set (will use deployment default)"));
271
+ }
272
+ }
273
+ /**
274
+ * Validate Azure OpenAI API key format
275
+ */
276
+ function validateApiKey(input) {
277
+ if (!input.trim()) {
278
+ return "Azure OpenAI API key is required";
279
+ }
280
+ const trimmed = input.trim();
281
+ if (trimmed.length < 20) {
282
+ return "Azure OpenAI API key seems too short";
283
+ }
284
+ // Azure OpenAI keys are typically 32 character hex strings
285
+ if (!/^[a-f0-9]{32}$/i.test(trimmed)) {
286
+ return "Azure OpenAI API key should be a 32-character hexadecimal string";
287
+ }
288
+ return true;
289
+ }
290
+ /**
291
+ * Validate Azure OpenAI endpoint URL
292
+ */
293
+ function validateEndpoint(input) {
294
+ if (!input.trim()) {
295
+ return "Azure OpenAI endpoint URL is required";
296
+ }
297
+ const trimmed = input.trim();
298
+ try {
299
+ const url = new URL(trimmed);
300
+ if (!url.hostname.includes("openai.azure.com")) {
301
+ return "Endpoint should be an Azure OpenAI URL (*.openai.azure.com)";
302
+ }
303
+ return true;
304
+ }
305
+ catch {
306
+ return "Invalid URL format. Should be like: https://your-resource.openai.azure.com/";
307
+ }
308
+ }
309
+ /**
310
+ * Prompt user for model selection
311
+ */
312
+ async function promptForModel() {
313
+ const { modelChoice } = await inquirer.prompt([
314
+ {
315
+ type: "list",
316
+ name: "modelChoice",
317
+ message: "Select an Azure OpenAI model:",
318
+ choices: [
319
+ {
320
+ name: "gpt-4o (Latest multimodal model)",
321
+ value: "gpt-4o",
322
+ },
323
+ {
324
+ name: "gpt-4o-mini (Cost-effective)",
325
+ value: "gpt-4o-mini",
326
+ },
327
+ {
328
+ name: "gpt-4-turbo (Previous generation)",
329
+ value: "gpt-4-turbo",
330
+ },
331
+ {
332
+ name: "gpt-35-turbo (Legacy, most cost-effective)",
333
+ value: "gpt-35-turbo",
334
+ },
335
+ {
336
+ name: "Custom deployment name (enter manually)",
337
+ value: "custom",
338
+ },
339
+ ],
340
+ },
341
+ ]);
342
+ if (modelChoice === "custom") {
343
+ const { customModel } = await inquirer.prompt([
344
+ {
345
+ type: "input",
346
+ name: "customModel",
347
+ message: "Enter your Azure OpenAI deployment name:",
348
+ validate: (input) => {
349
+ if (!input.trim()) {
350
+ return "Deployment name is required";
351
+ }
352
+ // Basic validation - Azure deployment names are alphanumeric with hyphens
353
+ const trimmed = input.trim();
354
+ if (!/^[a-z0-9-]+$/i.test(trimmed)) {
355
+ return "Deployment name should contain only letters, numbers, and hyphens";
356
+ }
357
+ return true;
358
+ },
359
+ },
360
+ ]);
361
+ return customModel.trim();
362
+ }
363
+ return modelChoice;
364
+ }
365
+ /**
366
+ * Update .env file with Azure OpenAI configuration using shared utilities
367
+ */
368
+ async function updateEnvFileWithConfig(config) {
369
+ const spinner = ora("💾 Updating .env file...").start();
370
+ try {
371
+ // Prepare environment variables for the shared utility
372
+ const newVars = {};
373
+ if (config.apiKey) {
374
+ newVars.AZURE_OPENAI_API_KEY = config.apiKey;
375
+ }
376
+ if (config.endpoint) {
377
+ newVars.AZURE_OPENAI_ENDPOINT = config.endpoint;
378
+ }
379
+ if (config.model) {
380
+ newVars.AZURE_OPENAI_MODEL = config.model;
381
+ }
382
+ // Use shared envManager utility with backup enabled
383
+ const result = updateEnvFileShared(newVars, ".env", true);
384
+ spinner.succeed(chalk.green("✔ .env file updated successfully"));
385
+ // Display summary using shared utility
386
+ displayEnvUpdateSummary(result, false);
387
+ }
388
+ catch (error) {
389
+ spinner.fail(chalk.red("❌ Failed to update .env file"));
390
+ logger.error(chalk.red(`Error: ${error instanceof Error ? error.message : "Unknown error"}`));
391
+ throw error;
392
+ }
393
+ }
394
+ /**
395
+ * Mask API key for display
396
+ */
397
+ function maskCredential(credential) {
398
+ if (!credential || credential.length < 8) {
399
+ return "****";
400
+ }
401
+ const start = credential.slice(0, 4);
402
+ const end = credential.slice(-4);
403
+ const middle = "*".repeat(Math.max(4, credential.length - 8));
404
+ return `${start}${middle}${end}`;
405
+ }
406
+ /**
407
+ * Show usage example
408
+ */
409
+ function showUsageExample() {
410
+ logger.always("");
411
+ logger.always(chalk.green("🚀 You can now use Azure OpenAI with the NeuroLink CLI:"));
412
+ logger.always(chalk.cyan(" pnpm cli generate 'Hello from Azure OpenAI!' --provider azure"));
413
+ logger.always(chalk.cyan(" pnpm cli generate 'Explain quantum computing' --provider azure"));
414
+ logger.always(chalk.cyan(" pnpm cli generate 'Analyze this data' --provider azure --enable-analytics"));
415
+ }
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * AWS Bedrock Setup Command for New Developers
4
+ *
5
+ * Checks for AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY
6
+ * Auto-detects AWS CLI configuration, prompts for missing config, updates .env safely
7
+ */
8
+ interface BedrockSetupArgv {
9
+ check?: boolean;
10
+ nonInteractive?: boolean;
11
+ }
12
+ export declare function handleBedrockSetup(argv: BedrockSetupArgv): Promise<void>;
13
+ export {};