@juspay/neurolink 2.0.0 → 3.0.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 (50) hide show
  1. package/CHANGELOG.md +34 -7
  2. package/README.md +38 -34
  3. package/dist/cli/commands/config.d.ts +6 -6
  4. package/dist/cli/index.js +46 -35
  5. package/dist/core/types.d.ts +2 -0
  6. package/dist/lib/core/types.d.ts +2 -0
  7. package/dist/lib/mcp/plugins/filesystem-mcp.d.ts +1 -1
  8. package/dist/lib/neurolink.d.ts +2 -0
  9. package/dist/lib/neurolink.js +23 -2
  10. package/dist/lib/providers/agent-enhanced-provider.d.ts +1 -0
  11. package/dist/lib/providers/agent-enhanced-provider.js +115 -51
  12. package/dist/lib/providers/amazonBedrock.js +74 -24
  13. package/dist/lib/providers/anthropic.js +80 -16
  14. package/dist/lib/providers/azureOpenAI.js +77 -15
  15. package/dist/lib/providers/googleAIStudio.js +77 -26
  16. package/dist/lib/providers/googleVertexAI.js +77 -24
  17. package/dist/lib/providers/huggingFace.js +74 -26
  18. package/dist/lib/providers/mistralAI.js +74 -26
  19. package/dist/lib/providers/ollama.d.ts +1 -1
  20. package/dist/lib/providers/ollama.js +32 -10
  21. package/dist/lib/providers/openAI.js +71 -23
  22. package/dist/lib/providers/timeout-wrapper.d.ts +40 -0
  23. package/dist/lib/providers/timeout-wrapper.js +100 -0
  24. package/dist/lib/proxy/proxy-fetch.d.ts +18 -0
  25. package/dist/lib/proxy/proxy-fetch.js +64 -0
  26. package/dist/lib/utils/timeout.d.ts +69 -0
  27. package/dist/lib/utils/timeout.js +138 -0
  28. package/dist/mcp/plugins/filesystem-mcp.d.ts +1 -1
  29. package/dist/mcp/plugins/filesystem-mcp.js +1 -1
  30. package/dist/neurolink.d.ts +2 -0
  31. package/dist/neurolink.js +23 -2
  32. package/dist/providers/agent-enhanced-provider.d.ts +1 -0
  33. package/dist/providers/agent-enhanced-provider.js +115 -51
  34. package/dist/providers/amazonBedrock.js +74 -24
  35. package/dist/providers/anthropic.js +80 -16
  36. package/dist/providers/azureOpenAI.js +77 -15
  37. package/dist/providers/googleAIStudio.js +77 -26
  38. package/dist/providers/googleVertexAI.js +77 -24
  39. package/dist/providers/huggingFace.js +74 -26
  40. package/dist/providers/mistralAI.js +74 -26
  41. package/dist/providers/ollama.d.ts +1 -1
  42. package/dist/providers/ollama.js +32 -10
  43. package/dist/providers/openAI.js +71 -23
  44. package/dist/providers/timeout-wrapper.d.ts +40 -0
  45. package/dist/providers/timeout-wrapper.js +100 -0
  46. package/dist/proxy/proxy-fetch.d.ts +18 -0
  47. package/dist/proxy/proxy-fetch.js +64 -0
  48. package/dist/utils/timeout.d.ts +69 -0
  49. package/dist/utils/timeout.js +138 -0
  50. package/package.json +2 -1
package/CHANGELOG.md CHANGED
@@ -1,28 +1,55 @@
1
- # [2.0.0](https://github.com/juspay/neurolink/compare/v1.11.3...v2.0.0) (2025-06-28)
1
+ # [3.0.0](https://github.com/juspay/neurolink/compare/v2.1.0...v3.0.0) (2025-07-01)
2
2
 
3
3
 
4
4
  ### Features
5
5
 
6
- * **cli:** add command variations and stream agent support ([5fc4c26](https://github.com/juspay/neurolink/commit/5fc4c26b23bd189be52272521bdd2ca40dd55837))
6
+ * **proxy:** add comprehensive enterprise proxy support across all providers ([9668e67](https://github.com/juspay/neurolink/commit/9668e67dfaa27831ba85d45fdf5b7739de902b28))
7
7
 
8
8
 
9
9
  ### BREAKING CHANGES
10
10
 
11
- * **cli:** 'generate-text' command is deprecated and will be removed in v2.0
11
+ * **proxy:** None - fully backward compatible
12
12
 
13
- ## [1.11.3](https://github.com/juspay/neurolink/compare/v1.11.2...v1.11.3) (2025-06-22)
13
+ Files modified:
14
+ - docs/ENTERPRISE-PROXY-SETUP.md (NEW) - Comprehensive enterprise proxy guide
15
+ - docs/PROVIDER-CONFIGURATION.md - Added proxy configuration section
16
+ - docs/CLI-GUIDE.md - Added proxy environment variables documentation
17
+ - docs/ENVIRONMENT-VARIABLES.md - Added proxy configuration examples
18
+ - docs/TROUBLESHOOTING.md - Added proxy troubleshooting procedures
19
+ - .env.example - Added proxy environment variables
20
+ - memory-bank/ - Updated with proxy implementation milestone
21
+ - .clinerules - Added proxy success patterns
22
+ - CHANGELOG.md - Added v2.2.0 proxy support entry
23
+ - package.json - Updated description with enterprise features
24
+ - README.md - Removed outdated content
25
+
26
+ # [2.1.0](https://github.com/juspay/neurolink/compare/v2.0.0...v2.1.0) (2025-06-29)
27
+
28
+ ### Features
29
+
30
+ - **timeout:** add comprehensive timeout support for all AI providers ([8610f4a](https://github.com/juspay/neurolink/commit/8610f4ade418345b0395ab72af6e675f6eec6f93))
31
+
32
+ # [2.0.0](https://github.com/juspay/neurolink/compare/v1.11.3...v2.0.0) (2025-06-28)
14
33
 
34
+ ### Features
35
+
36
+ - **cli:** add command variations and stream agent support ([5fc4c26](https://github.com/juspay/neurolink/commit/5fc4c26b23bd189be52272521bdd2ca40dd55837))
37
+
38
+ ### BREAKING CHANGES
39
+
40
+ - **cli:** 'generate-text' command is deprecated and will be removed in v2.0
41
+
42
+ ## [1.11.3](https://github.com/juspay/neurolink/compare/v1.11.2...v1.11.3) (2025-06-22)
15
43
 
16
44
  ### Bug Fixes
17
45
 
18
- * resolve MCP external tools returning raw JSON instead of human-readable responses ([921a12b](https://github.com/juspay/neurolink/commit/921a12b5b31ca96bbfe3f1db05001ddb84470e14))
46
+ - resolve MCP external tools returning raw JSON instead of human-readable responses ([921a12b](https://github.com/juspay/neurolink/commit/921a12b5b31ca96bbfe3f1db05001ddb84470e14))
19
47
 
20
48
  ## [1.11.2](https://github.com/juspay/neurolink/compare/v1.11.1...v1.11.2) (2025-06-22)
21
49
 
22
-
23
50
  ### Bug Fixes
24
51
 
25
- * **ci:** refactor auto-converted Node.js scripts ([4088888](https://github.com/juspay/neurolink/commit/408888863f8223e64269423412f5c79a35ddfe36))
52
+ - **ci:** refactor auto-converted Node.js scripts ([4088888](https://github.com/juspay/neurolink/commit/408888863f8223e64269423412f5c79a35ddfe36))
26
53
 
27
54
  ## [1.11.1](https://github.com/juspay/neurolink/compare/v1.11.0...v1.11.1) (2025-06-21)
28
55
 
package/README.md CHANGED
@@ -11,28 +11,6 @@
11
11
 
12
12
  **NeuroLink** unifies OpenAI, Bedrock, Vertex AI, Google AI Studio, Anthropic, Azure OpenAI, Hugging Face, Ollama, and Mistral AI with intelligent fallback and streaming support. Available as both a **programmatic SDK** and **professional CLI tool**. Extracted from production use at Juspay.
13
13
 
14
- ## 🔥 **Latest Breakthrough: Full MCP Tool Integration Operational** (June 21, 2025)
15
-
16
- **MAJOR SUCCESS**: All blocking TypeScript compilation errors resolved + Complete CLI MCP integration achieved!
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`/`gen` and `agent-generate` commands use full MCP capabilities
22
- ✅ **Backward Compatible**: Tools enabled by default with opt-out flag for traditional usage
23
-
24
- ```bash
25
- # NEW: AI can now access your filesystem and execute tools (use preferred commands)
26
- npx @juspay/neurolink generate "List files in this directory" --provider google-ai
27
-
28
- # Alternative shorter command
29
- npx @juspay/neurolink gen "List files in this directory" --provider google-ai
30
-
31
- # ⚠️ DEPRECATED: generate-text will be removed in v2.0 (use 'generate' or 'gen' instead)
32
- # This command shows a deprecation warning and is kept for backward compatibility only
33
- npx @juspay/neurolink generate-text "List files in this directory" --provider google-ai
34
- ```
35
-
36
14
  ## 🚀 Quick Start
37
15
 
38
16
  ### Install & Run (2 minutes)
@@ -61,6 +39,7 @@ import { createBestAIProvider } from "@juspay/neurolink";
61
39
  const provider = createBestAIProvider();
62
40
  const result = await provider.generateText({
63
41
  prompt: "Write a haiku about programming",
42
+ timeout: "30s", // Optional: Set custom timeout (default: 30s)
64
43
  });
65
44
 
66
45
  console.log(result.text);
@@ -100,14 +79,14 @@ npx @juspay/neurolink status
100
79
 
101
80
  ## 🛠️ MCP Integration Status (v1.11.1) ✅ **PRODUCTION READY**
102
81
 
103
- | Component | Status | Description |
104
- | ------------------- | ------------------ | --------------------------------------------------- |
105
- | Built-in Tools | ✅ **Working** | Time tool, utilities - fully functional |
106
- | External Discovery | ✅ **Working** | 58+ MCP servers auto-discovered from all AI tools |
107
- | Tool Execution | ✅ **Working** | Real-time AI tool calling with built-in tools |
82
+ | Component | Status | Description |
83
+ | ------------------- | ------------------ | ---------------------------------------------------------- |
84
+ | Built-in Tools | ✅ **Working** | Time tool, utilities - fully functional |
85
+ | External Discovery | ✅ **Working** | 58+ MCP servers auto-discovered from all AI tools |
86
+ | Tool Execution | ✅ **Working** | Real-time AI tool calling with built-in tools |
108
87
  | **External Tools** | ✅ **SOLVED** | **Two-step tool calling fixed - human-readable responses** |
109
- | **CLI Integration** | ✅ **READY** | **Production-ready AI assistant with external tools** |
110
- | External Activation | 🔧 **Development** | Discovery complete, activation protocol in progress |
88
+ | **CLI Integration** | ✅ **READY** | **Production-ready AI assistant with external tools** |
89
+ | External Activation | 🔧 **Development** | Discovery complete, activation protocol in progress |
111
90
 
112
91
  ### ✅ Quick MCP Test (v1.7.1)
113
92
 
@@ -182,36 +161,61 @@ npx @juspay/neurolink gen "What time is it?"
182
161
  # Disable tools for training-data-only responses
183
162
  npx @juspay/neurolink generate "What time is it?" --disable-tools
184
163
 
164
+ # With custom timeout for complex prompts
165
+ npx @juspay/neurolink generate "Explain quantum computing in detail" --timeout 1m
166
+
185
167
  # Real-time streaming with agent support (default)
186
168
  npx @juspay/neurolink stream "What time is it?"
187
169
 
188
170
  # Streaming without tools (traditional mode)
189
171
  npx @juspay/neurolink stream "Tell me a story" --disable-tools
190
172
 
173
+ # Streaming with extended timeout
174
+ npx @juspay/neurolink stream "Write a long story" --timeout 5m
175
+
191
176
  # Provider diagnostics
192
177
  npx @juspay/neurolink status --verbose
193
178
 
194
179
  # Batch processing
195
180
  echo -e "Write a haiku\nExplain gravity" > prompts.txt
196
181
  npx @juspay/neurolink batch prompts.txt --output results.json
182
+
183
+ # Batch with custom timeout per request
184
+ npx @juspay/neurolink batch prompts.txt --timeout 45s --output results.json
197
185
  ```
198
186
 
199
187
  ### SDK Integration
200
188
 
201
189
  ```typescript
202
- // SvelteKit API route
190
+ // SvelteKit API route with timeout handling
203
191
  export const POST: RequestHandler = async ({ request }) => {
204
192
  const { message } = await request.json();
205
193
  const provider = createBestAIProvider();
206
- const result = await provider.streamText({ prompt: message });
207
- return new Response(result.toReadableStream());
194
+
195
+ try {
196
+ const result = await provider.streamText({
197
+ prompt: message,
198
+ timeout: "2m", // 2 minutes for streaming
199
+ });
200
+ return new Response(result.toReadableStream());
201
+ } catch (error) {
202
+ if (error.name === "TimeoutError") {
203
+ return new Response("Request timed out", { status: 408 });
204
+ }
205
+ throw error;
206
+ }
208
207
  };
209
208
 
210
- // Next.js API route
209
+ // Next.js API route with timeout
211
210
  export async function POST(request: NextRequest) {
212
211
  const { prompt } = await request.json();
213
212
  const provider = createBestAIProvider();
214
- const result = await provider.generateText({ prompt });
213
+
214
+ const result = await provider.generateText({
215
+ prompt,
216
+ timeout: process.env.AI_TIMEOUT || "30s", // Configurable timeout
217
+ });
218
+
215
219
  return NextResponse.json({ text: result.text });
216
220
  }
217
221
  ```
@@ -117,12 +117,12 @@ declare const ConfigSchema: z.ZodObject<{
117
117
  model: z.ZodDefault<z.ZodString>;
118
118
  timeout: z.ZodDefault<z.ZodNumber>;
119
119
  }, "strip", z.ZodTypeAny, {
120
- model: string;
121
120
  timeout: number;
121
+ model: string;
122
122
  baseUrl: string;
123
123
  }, {
124
- model?: string | undefined;
125
124
  timeout?: number | undefined;
125
+ model?: string | undefined;
126
126
  baseUrl?: string | undefined;
127
127
  }>>;
128
128
  mistral: z.ZodOptional<z.ZodObject<{
@@ -176,8 +176,8 @@ declare const ConfigSchema: z.ZodObject<{
176
176
  apiKey?: string | undefined;
177
177
  } | undefined;
178
178
  ollama?: {
179
- model: string;
180
179
  timeout: number;
180
+ model: string;
181
181
  baseUrl: string;
182
182
  } | undefined;
183
183
  mistral?: {
@@ -225,8 +225,8 @@ declare const ConfigSchema: z.ZodObject<{
225
225
  apiKey?: string | undefined;
226
226
  } | undefined;
227
227
  ollama?: {
228
- model?: string | undefined;
229
228
  timeout?: number | undefined;
229
+ model?: string | undefined;
230
230
  baseUrl?: string | undefined;
231
231
  } | undefined;
232
232
  mistral?: {
@@ -299,8 +299,8 @@ declare const ConfigSchema: z.ZodObject<{
299
299
  apiKey?: string | undefined;
300
300
  } | undefined;
301
301
  ollama?: {
302
- model: string;
303
302
  timeout: number;
303
+ model: string;
304
304
  baseUrl: string;
305
305
  } | undefined;
306
306
  mistral?: {
@@ -360,8 +360,8 @@ declare const ConfigSchema: z.ZodObject<{
360
360
  apiKey?: string | undefined;
361
361
  } | undefined;
362
362
  ollama?: {
363
- model?: string | undefined;
364
363
  timeout?: number | undefined;
364
+ model?: string | undefined;
365
365
  baseUrl?: string | undefined;
366
366
  } | undefined;
367
367
  mistral?: {
package/dist/cli/index.js CHANGED
@@ -253,9 +253,9 @@ const cli = yargs(args)
253
253
  description: "Enable debug mode with verbose output",
254
254
  }) // Kept for potential specific debug logic
255
255
  .option("timeout", {
256
- type: "number",
257
- default: 30000,
258
- description: "Timeout for the request in milliseconds",
256
+ type: "string",
257
+ default: "30s",
258
+ description: "Timeout for the request (e.g., 30s, 2m, 1h, 5000)",
259
259
  })
260
260
  .option("disable-tools", {
261
261
  type: "boolean",
@@ -268,7 +268,7 @@ const cli = yargs(args)
268
268
  .example('$0 generate-text "Hello world" --disable-tools', "Use without tool integration"), async (argv) => {
269
269
  // Check if generate-text was used specifically (for deprecation warning)
270
270
  const usedCommand = argv._[0];
271
- if (usedCommand === 'generate-text' && !argv.quiet) {
271
+ if (usedCommand === "generate-text" && !argv.quiet) {
272
272
  console.warn(chalk.yellow('⚠️ Warning: "generate-text" is deprecated. Use "generate" or "gen" instead for multimodal support.'));
273
273
  }
274
274
  let originalConsole = {};
@@ -285,9 +285,8 @@ const cli = yargs(args)
285
285
  ? null
286
286
  : ora("🤖 Generating text...").start();
287
287
  try {
288
- const timeoutPromise = new Promise((_, reject) => {
289
- setTimeout(() => reject(new Error(`Request timeout (${argv.timeout}ms)`)), argv.timeout);
290
- });
288
+ // The SDK will handle the timeout internally, so we don't need this wrapper anymore
289
+ // Just pass the timeout to the SDK
291
290
  // Use AgentEnhancedProvider when tools are enabled, otherwise use standard SDK
292
291
  let generatePromise;
293
292
  if (argv.disableTools === true) {
@@ -300,6 +299,7 @@ const cli = yargs(args)
300
299
  temperature: argv.temperature,
301
300
  maxTokens: argv.maxTokens,
302
301
  systemPrompt: argv.system,
302
+ timeout: argv.timeout,
303
303
  });
304
304
  }
305
305
  else {
@@ -323,10 +323,7 @@ const cli = yargs(args)
323
323
  });
324
324
  generatePromise = agentProvider.generateText(argv.prompt);
325
325
  }
326
- const result = (await Promise.race([
327
- generatePromise,
328
- timeoutPromise,
329
- ]));
326
+ const result = await generatePromise;
330
327
  if (argv.format === "json" && originalConsole.log) {
331
328
  Object.assign(console, originalConsole);
332
329
  }
@@ -334,20 +331,26 @@ const cli = yargs(args)
334
331
  spinner.succeed(chalk.green("✅ Text generated successfully!"));
335
332
  }
336
333
  // Handle both AgentEnhancedProvider (AI SDK) and standard NeuroLink SDK responses
337
- const responseText = result.text || result.content || "";
338
- const responseUsage = result.usage || {
339
- promptTokens: 0,
340
- completionTokens: 0,
341
- totalTokens: 0,
342
- };
334
+ const responseText = result
335
+ ? result.text || result.content || ""
336
+ : "";
337
+ const responseUsage = result
338
+ ? result.usage || {
339
+ promptTokens: 0,
340
+ completionTokens: 0,
341
+ totalTokens: 0,
342
+ }
343
+ : { promptTokens: 0, completionTokens: 0, totalTokens: 0 };
343
344
  if (argv.format === "json") {
344
345
  const jsonOutput = {
345
346
  content: responseText,
346
- provider: result.provider || argv.provider,
347
+ provider: result
348
+ ? result.provider || argv.provider
349
+ : argv.provider,
347
350
  usage: responseUsage,
348
- responseTime: result.responseTime || 0,
349
- toolCalls: result.toolCalls || [],
350
- toolResults: result.toolResults || [],
351
+ responseTime: result ? result.responseTime || 0 : 0,
352
+ toolCalls: result ? result.toolCalls || [] : [],
353
+ toolResults: result ? result.toolResults || [] : [],
351
354
  };
352
355
  process.stdout.write(JSON.stringify(jsonOutput, null, 2) + "\n");
353
356
  }
@@ -357,7 +360,9 @@ const cli = yargs(args)
357
360
  console.log("\n" + responseText + "\n");
358
361
  }
359
362
  // Show tool calls if any
360
- if (result.toolCalls && result.toolCalls.length > 0) {
363
+ if (result &&
364
+ result.toolCalls &&
365
+ result.toolCalls.length > 0) {
361
366
  console.log(chalk.blue("🔧 Tools Called:"));
362
367
  for (const toolCall of result.toolCalls) {
363
368
  console.log(`- ${toolCall.toolName}`);
@@ -366,7 +371,9 @@ const cli = yargs(args)
366
371
  console.log();
367
372
  }
368
373
  // Show tool results if any
369
- if (result.toolResults && result.toolResults.length > 0) {
374
+ if (result &&
375
+ result.toolResults &&
376
+ result.toolResults.length > 0) {
370
377
  console.log(chalk.blue("📋 Tool Results:"));
371
378
  for (const toolResult of result.toolResults) {
372
379
  console.log(`- ${toolResult.toolCallId}`);
@@ -375,9 +382,11 @@ const cli = yargs(args)
375
382
  console.log();
376
383
  }
377
384
  console.log(JSON.stringify({
378
- provider: result.provider || argv.provider,
385
+ provider: result
386
+ ? result.provider || argv.provider
387
+ : argv.provider,
379
388
  usage: responseUsage,
380
- responseTime: result.responseTime || 0,
389
+ responseTime: result ? result.responseTime || 0 : 0,
381
390
  }, null, 2));
382
391
  if (responseUsage.totalTokens) {
383
392
  console.log(chalk.blue(`ℹ️ ${responseUsage.totalTokens} tokens used`));
@@ -436,6 +445,11 @@ const cli = yargs(args)
436
445
  type: "number",
437
446
  default: 0.7,
438
447
  description: "Creativity level",
448
+ })
449
+ .option("timeout", {
450
+ type: "string",
451
+ default: "2m",
452
+ description: "Timeout for streaming (e.g., 30s, 2m, 1h)",
439
453
  })
440
454
  .option("debug", {
441
455
  type: "boolean",
@@ -468,6 +482,7 @@ const cli = yargs(args)
468
482
  ? undefined
469
483
  : argv.provider,
470
484
  temperature: argv.temperature,
485
+ timeout: argv.timeout,
471
486
  });
472
487
  }
473
488
  else {
@@ -498,7 +513,7 @@ const cli = yargs(args)
498
513
  const DELAY_MS = 50;
499
514
  for (let i = 0; i < text.length; i += CHUNK_SIZE) {
500
515
  process.stdout.write(text.slice(i, i + CHUNK_SIZE));
501
- await new Promise(resolve => setTimeout(resolve, DELAY_MS)); // Small delay
516
+ await new Promise((resolve) => setTimeout(resolve, DELAY_MS)); // Small delay
502
517
  }
503
518
  if (!argv.quiet) {
504
519
  process.stdout.write("\n");
@@ -552,9 +567,9 @@ const cli = yargs(args)
552
567
  description: "AI provider to use",
553
568
  })
554
569
  .option("timeout", {
555
- type: "number",
556
- default: 30000,
557
- description: "Timeout for each request in milliseconds",
570
+ type: "string",
571
+ default: "30s",
572
+ description: "Timeout for each request (e.g., 30s, 2m, 1h)",
558
573
  })
559
574
  .option("temperature", {
560
575
  type: "number",
@@ -607,8 +622,7 @@ const cli = yargs(args)
607
622
  spinner.text = `Processing ${i + 1}/${prompts.length}: ${prompts[i].substring(0, 30)}...`;
608
623
  }
609
624
  try {
610
- const timeoutPromise = new Promise((_, reject) => setTimeout(() => reject(new Error("Request timeout")), argv.timeout));
611
- const generatePromise = sdk.generateText({
625
+ const result = await sdk.generateText({
612
626
  prompt: prompts[i],
613
627
  provider: argv.provider === "auto"
614
628
  ? undefined
@@ -616,11 +630,8 @@ const cli = yargs(args)
616
630
  temperature: argv.temperature,
617
631
  maxTokens: argv.maxTokens,
618
632
  systemPrompt: argv.system,
633
+ timeout: argv.timeout,
619
634
  });
620
- const result = (await Promise.race([
621
- generatePromise,
622
- timeoutPromise,
623
- ]));
624
635
  results.push({ prompt: prompts[i], response: result.content });
625
636
  if (spinner) {
626
637
  spinner.render();
@@ -80,6 +80,7 @@ export interface TextGenerationOptions {
80
80
  systemPrompt?: string;
81
81
  schema?: ZodType<unknown, ZodTypeDef, unknown> | Schema<unknown>;
82
82
  tools?: Record<string, Tool>;
83
+ timeout?: number | string;
83
84
  }
84
85
  /**
85
86
  * Stream text options interface
@@ -92,6 +93,7 @@ export interface StreamTextOptions {
92
93
  systemPrompt?: string;
93
94
  schema?: ZodType<unknown, ZodTypeDef, unknown> | Schema<unknown>;
94
95
  tools?: Record<string, Tool>;
96
+ timeout?: number | string;
95
97
  }
96
98
  /**
97
99
  * AI Provider interface with flexible parameter support
@@ -80,6 +80,7 @@ export interface TextGenerationOptions {
80
80
  systemPrompt?: string;
81
81
  schema?: ZodType<unknown, ZodTypeDef, unknown> | Schema<unknown>;
82
82
  tools?: Record<string, Tool>;
83
+ timeout?: number | string;
83
84
  }
84
85
  /**
85
86
  * Stream text options interface
@@ -92,6 +93,7 @@ export interface StreamTextOptions {
92
93
  systemPrompt?: string;
93
94
  schema?: ZodType<unknown, ZodTypeDef, unknown> | Schema<unknown>;
94
95
  tools?: Record<string, Tool>;
96
+ timeout?: number | string;
95
97
  }
96
98
  /**
97
99
  * AI Provider interface with flexible parameter support
@@ -3,7 +3,7 @@
3
3
  * Implements the new MCP contract with security sandbox
4
4
  * Based on research document recommendations
5
5
  */
6
- import { MCP, MCPMetadata, ExecutionContext } from "../contracts/mcp-contract.js";
6
+ import { MCP, type MCPMetadata, type ExecutionContext } from "../contracts/mcp-contract.js";
7
7
  /**
8
8
  * FileSystem MCP Configuration
9
9
  */
@@ -12,6 +12,7 @@ export interface TextGenerationOptions {
12
12
  maxTokens?: number;
13
13
  systemPrompt?: string;
14
14
  schema?: any;
15
+ timeout?: number | string;
15
16
  disableTools?: boolean;
16
17
  }
17
18
  export interface StreamTextOptions {
@@ -20,6 +21,7 @@ export interface StreamTextOptions {
20
21
  temperature?: number;
21
22
  maxTokens?: number;
22
23
  systemPrompt?: string;
24
+ timeout?: number | string;
23
25
  }
24
26
  export interface TextGenerationResult {
25
27
  content: string;
@@ -11,6 +11,7 @@ import { toolRegistry } from "./mcp/tool-registry.js";
11
11
  import { unifiedRegistry } from "./mcp/unified-registry.js";
12
12
  import { logger } from "./utils/logger.js";
13
13
  import { getBestProvider } from "./utils/providerUtils-fixed.js";
14
+ import { TimeoutError } from "./utils/timeout.js";
14
15
  export class NeuroLink {
15
16
  mcpInitialized = false;
16
17
  contextManager;
@@ -32,10 +33,9 @@ export class NeuroLink {
32
33
  const mcpInitPromise = Promise.race([
33
34
  this.doIsolatedMCPInitialization(),
34
35
  new Promise((_, reject) => {
35
- const timer = setTimeout(() => {
36
+ setTimeout(() => {
36
37
  reject(new Error("MCP initialization timeout after 3s"));
37
38
  }, initTimeout);
38
- timer.unref(); // Don't keep process alive
39
39
  }),
40
40
  ]);
41
41
  await mcpInitPromise;
@@ -134,6 +134,7 @@ export class NeuroLink {
134
134
  temperature: options.temperature,
135
135
  maxTokens: options.maxTokens,
136
136
  systemPrompt: enhancedSystemPrompt,
137
+ timeout: options.timeout,
137
138
  }, options.schema);
138
139
  if (!result) {
139
140
  throw new Error("No response received from AI provider");
@@ -222,6 +223,7 @@ export class NeuroLink {
222
223
  temperature: options.temperature,
223
224
  maxTokens: options.maxTokens,
224
225
  systemPrompt: options.systemPrompt,
226
+ timeout: options.timeout,
225
227
  }, options.schema);
226
228
  if (!result) {
227
229
  throw new Error("No response received from AI provider");
@@ -252,9 +254,18 @@ export class NeuroLink {
252
254
  catch (error) {
253
255
  const errorMessage = error instanceof Error ? error.message : String(error);
254
256
  lastError = error instanceof Error ? error : new Error(errorMessage);
257
+ // Special handling for timeout errors
258
+ if (error instanceof TimeoutError) {
259
+ logger.warn(`[${functionTag}] Provider timed out`, {
260
+ provider: providerName,
261
+ timeout: error.timeout,
262
+ operation: error.operation,
263
+ });
264
+ }
255
265
  logger.debug(`[${functionTag}] Provider failed, trying next`, {
256
266
  provider: providerName,
257
267
  error: errorMessage,
268
+ isTimeout: error instanceof TimeoutError,
258
269
  remainingProviders: tryProviders.slice(tryProviders.indexOf(providerName) + 1),
259
270
  });
260
271
  // Continue to next provider
@@ -338,6 +349,7 @@ Note: Tool integration is currently in development. Please provide helpful respo
338
349
  temperature: options.temperature,
339
350
  maxTokens: options.maxTokens,
340
351
  systemPrompt: options.systemPrompt,
352
+ timeout: options.timeout,
341
353
  });
342
354
  if (!result) {
343
355
  throw new Error("No stream response received from AI provider");
@@ -358,9 +370,18 @@ Note: Tool integration is currently in development. Please provide helpful respo
358
370
  catch (error) {
359
371
  const errorMessage = error instanceof Error ? error.message : String(error);
360
372
  lastError = error instanceof Error ? error : new Error(errorMessage);
373
+ // Special handling for timeout errors
374
+ if (error instanceof TimeoutError) {
375
+ logger.warn(`[${functionTag}] Provider timed out`, {
376
+ provider: providerName,
377
+ timeout: error.timeout,
378
+ operation: error.operation,
379
+ });
380
+ }
361
381
  logger.debug(`[${functionTag}] Provider failed, trying next`, {
362
382
  provider: providerName,
363
383
  error: errorMessage,
384
+ isTimeout: error instanceof TimeoutError,
364
385
  remainingProviders: tryProviders.slice(tryProviders.indexOf(providerName) + 1),
365
386
  });
366
387
  // Continue to next provider
@@ -15,6 +15,7 @@ interface AgentConfig {
15
15
  enableTools?: boolean;
16
16
  enableMCP?: boolean;
17
17
  mcpInitTimeoutMs?: number;
18
+ toolExecutionTimeout?: number | string;
18
19
  mcpDiscoveryOptions?: {
19
20
  searchPaths?: string[];
20
21
  configFiles?: string[];