@juspay/neurolink 2.1.0 → 3.0.1

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 (43) hide show
  1. package/CHANGELOG.md +36 -9
  2. package/README.md +17 -39
  3. package/dist/cli/index.js +40 -18
  4. package/dist/lib/mcp/plugins/filesystem-mcp.d.ts +1 -1
  5. package/dist/lib/neurolink.d.ts +2 -0
  6. package/dist/lib/neurolink.js +5 -3
  7. package/dist/lib/providers/agent-enhanced-provider.js +61 -53
  8. package/dist/lib/providers/amazonBedrock.js +11 -7
  9. package/dist/lib/providers/anthropic.js +13 -11
  10. package/dist/lib/providers/azureOpenAI.js +10 -10
  11. package/dist/lib/providers/googleAIStudio.js +14 -7
  12. package/dist/lib/providers/googleVertexAI.js +14 -7
  13. package/dist/lib/providers/huggingFace.js +11 -7
  14. package/dist/lib/providers/mistralAI.js +11 -7
  15. package/dist/lib/providers/ollama.js +12 -4
  16. package/dist/lib/providers/openAI.js +11 -7
  17. package/dist/lib/providers/timeout-wrapper.d.ts +2 -2
  18. package/dist/lib/providers/timeout-wrapper.js +3 -3
  19. package/dist/lib/proxy/proxy-fetch.d.ts +18 -0
  20. package/dist/lib/proxy/proxy-fetch.js +64 -0
  21. package/dist/lib/utils/timeout.d.ts +4 -4
  22. package/dist/lib/utils/timeout.js +42 -34
  23. package/dist/mcp/plugins/filesystem-mcp.d.ts +1 -1
  24. package/dist/mcp/plugins/filesystem-mcp.js +1 -1
  25. package/dist/neurolink.d.ts +2 -0
  26. package/dist/neurolink.js +5 -3
  27. package/dist/providers/agent-enhanced-provider.js +61 -53
  28. package/dist/providers/amazonBedrock.js +11 -7
  29. package/dist/providers/anthropic.js +13 -11
  30. package/dist/providers/azureOpenAI.js +10 -10
  31. package/dist/providers/googleAIStudio.js +14 -7
  32. package/dist/providers/googleVertexAI.js +14 -7
  33. package/dist/providers/huggingFace.js +11 -7
  34. package/dist/providers/mistralAI.js +11 -7
  35. package/dist/providers/ollama.js +12 -4
  36. package/dist/providers/openAI.js +11 -7
  37. package/dist/providers/timeout-wrapper.d.ts +2 -2
  38. package/dist/providers/timeout-wrapper.js +3 -3
  39. package/dist/proxy/proxy-fetch.d.ts +18 -0
  40. package/dist/proxy/proxy-fetch.js +64 -0
  41. package/dist/utils/timeout.d.ts +4 -4
  42. package/dist/utils/timeout.js +42 -34
  43. package/package.json +2 -1
@@ -23,7 +23,8 @@ async function getCreateVertexAnthropic() {
23
23
  }
24
24
  import { streamText, generateText, Output, } from "ai";
25
25
  import { logger } from "../utils/logger.js";
26
- import { createTimeoutController, TimeoutError, getDefaultTimeout } from "../utils/timeout.js";
26
+ import { createTimeoutController, TimeoutError, getDefaultTimeout, } from "../utils/timeout.js";
27
+ import { createProxyFetch } from "../proxy/proxy-fetch.js";
27
28
  // Default system context
28
29
  const DEFAULT_SYSTEM_CONTEXT = {
29
30
  systemPrompt: "You are a helpful AI assistant.",
@@ -146,9 +147,11 @@ const createVertexSettings = async () => {
146
147
  const functionTag = "createVertexSettings";
147
148
  // Setup authentication first
148
149
  await setupGoogleAuth();
150
+ const proxyFetch = createProxyFetch();
149
151
  const baseSettings = {
150
152
  project: getGCPVertexBreezeProjectId(),
151
153
  location: getGCPVertexBreezeLocation(),
154
+ fetch: proxyFetch,
152
155
  };
153
156
  // Method 1: Principal Account Authentication (file path) - Recommended for production
154
157
  if (hasPrincipalAccountAuth()) {
@@ -286,7 +289,7 @@ export class GoogleVertexAI {
286
289
  const options = typeof optionsOrPrompt === "string"
287
290
  ? { prompt: optionsOrPrompt }
288
291
  : optionsOrPrompt;
289
- const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt = DEFAULT_SYSTEM_CONTEXT.systemPrompt, schema, timeout = getDefaultTimeout(provider, 'stream'), } = options;
292
+ const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt = DEFAULT_SYSTEM_CONTEXT.systemPrompt, schema, timeout = getDefaultTimeout(provider, "stream"), } = options;
290
293
  // Use schema from options or fallback parameter
291
294
  const finalSchema = schema || analysisSchema;
292
295
  logger.debug(`[${functionTag}] Stream request started`, {
@@ -301,7 +304,7 @@ export class GoogleVertexAI {
301
304
  });
302
305
  const model = await this.getModel();
303
306
  // Create timeout controller if timeout is specified
304
- const timeoutController = createTimeoutController(timeout, provider, 'stream');
307
+ const timeoutController = createTimeoutController(timeout, provider, "stream");
305
308
  const streamOptions = {
306
309
  model: model,
307
310
  prompt: prompt,
@@ -309,7 +312,9 @@ export class GoogleVertexAI {
309
312
  temperature,
310
313
  maxTokens,
311
314
  // Add abort signal if available
312
- ...(timeoutController && { abortSignal: timeoutController.controller.signal }),
315
+ ...(timeoutController && {
316
+ abortSignal: timeoutController.controller.signal,
317
+ }),
313
318
  onError: (event) => {
314
319
  const error = event.error;
315
320
  const errorMessage = error instanceof Error ? error.message : String(error);
@@ -392,7 +397,7 @@ export class GoogleVertexAI {
392
397
  const options = typeof optionsOrPrompt === "string"
393
398
  ? { prompt: optionsOrPrompt }
394
399
  : optionsOrPrompt;
395
- const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt = DEFAULT_SYSTEM_CONTEXT.systemPrompt, schema, timeout = getDefaultTimeout(provider, 'generate'), } = options;
400
+ const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt = DEFAULT_SYSTEM_CONTEXT.systemPrompt, schema, timeout = getDefaultTimeout(provider, "generate"), } = options;
396
401
  // Use schema from options or fallback parameter
397
402
  const finalSchema = schema || analysisSchema;
398
403
  logger.debug(`[${functionTag}] Generate request started`, {
@@ -406,7 +411,7 @@ export class GoogleVertexAI {
406
411
  });
407
412
  const model = await this.getModel();
408
413
  // Create timeout controller if timeout is specified
409
- const timeoutController = createTimeoutController(timeout, provider, 'generate');
414
+ const timeoutController = createTimeoutController(timeout, provider, "generate");
410
415
  const generateOptions = {
411
416
  model: model,
412
417
  prompt: prompt,
@@ -414,7 +419,9 @@ export class GoogleVertexAI {
414
419
  temperature,
415
420
  maxTokens,
416
421
  // Add abort signal if available
417
- ...(timeoutController && { abortSignal: timeoutController.controller.signal }),
422
+ ...(timeoutController && {
423
+ abortSignal: timeoutController.controller.signal,
424
+ }),
418
425
  };
419
426
  if (finalSchema) {
420
427
  generateOptions.experimental_output = Output.object({
@@ -1,7 +1,7 @@
1
1
  import { HfInference } from "@huggingface/inference";
2
2
  import { streamText, generateText, Output, } from "ai";
3
3
  import { logger } from "../utils/logger.js";
4
- import { createTimeoutController, TimeoutError, getDefaultTimeout } from "../utils/timeout.js";
4
+ import { createTimeoutController, TimeoutError, getDefaultTimeout, } from "../utils/timeout.js";
5
5
  // Default system context
6
6
  const DEFAULT_SYSTEM_CONTEXT = {
7
7
  systemPrompt: "You are a helpful AI assistant.",
@@ -229,7 +229,7 @@ export class HuggingFace {
229
229
  const options = typeof optionsOrPrompt === "string"
230
230
  ? { prompt: optionsOrPrompt }
231
231
  : optionsOrPrompt;
232
- const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt = DEFAULT_SYSTEM_CONTEXT.systemPrompt, schema, timeout = getDefaultTimeout(provider, 'stream'), } = options;
232
+ const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt = DEFAULT_SYSTEM_CONTEXT.systemPrompt, schema, timeout = getDefaultTimeout(provider, "stream"), } = options;
233
233
  // Use schema from options or fallback parameter
234
234
  const finalSchema = schema || analysisSchema;
235
235
  logger.debug(`[${functionTag}] Stream request started`, {
@@ -243,7 +243,7 @@ export class HuggingFace {
243
243
  });
244
244
  const model = this.getModel();
245
245
  // Create timeout controller if timeout is specified
246
- const timeoutController = createTimeoutController(timeout, provider, 'stream');
246
+ const timeoutController = createTimeoutController(timeout, provider, "stream");
247
247
  const streamOptions = {
248
248
  model: model,
249
249
  prompt: prompt,
@@ -251,7 +251,9 @@ export class HuggingFace {
251
251
  temperature,
252
252
  maxTokens,
253
253
  // Add abort signal if available
254
- ...(timeoutController && { abortSignal: timeoutController.controller.signal }),
254
+ ...(timeoutController && {
255
+ abortSignal: timeoutController.controller.signal,
256
+ }),
255
257
  onError: (event) => {
256
258
  const error = event.error;
257
259
  const errorMessage = error instanceof Error ? error.message : String(error);
@@ -335,7 +337,7 @@ export class HuggingFace {
335
337
  const options = typeof optionsOrPrompt === "string"
336
338
  ? { prompt: optionsOrPrompt }
337
339
  : optionsOrPrompt;
338
- const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt = DEFAULT_SYSTEM_CONTEXT.systemPrompt, schema, timeout = getDefaultTimeout(provider, 'generate'), } = options;
340
+ const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt = DEFAULT_SYSTEM_CONTEXT.systemPrompt, schema, timeout = getDefaultTimeout(provider, "generate"), } = options;
339
341
  // Use schema from options or fallback parameter
340
342
  const finalSchema = schema || analysisSchema;
341
343
  logger.debug(`[${functionTag}] Generate request started`, {
@@ -348,7 +350,7 @@ export class HuggingFace {
348
350
  });
349
351
  const model = this.getModel();
350
352
  // Create timeout controller if timeout is specified
351
- const timeoutController = createTimeoutController(timeout, provider, 'generate');
353
+ const timeoutController = createTimeoutController(timeout, provider, "generate");
352
354
  const generateOptions = {
353
355
  model: model,
354
356
  prompt: prompt,
@@ -356,7 +358,9 @@ export class HuggingFace {
356
358
  temperature,
357
359
  maxTokens,
358
360
  // Add abort signal if available
359
- ...(timeoutController && { abortSignal: timeoutController.controller.signal }),
361
+ ...(timeoutController && {
362
+ abortSignal: timeoutController.controller.signal,
363
+ }),
360
364
  };
361
365
  if (finalSchema) {
362
366
  generateOptions.experimental_output = Output.object({
@@ -1,7 +1,7 @@
1
1
  import { createMistral } from "@ai-sdk/mistral";
2
2
  import { streamText, generateText, Output, } from "ai";
3
3
  import { logger } from "../utils/logger.js";
4
- import { createTimeoutController, TimeoutError, getDefaultTimeout } from "../utils/timeout.js";
4
+ import { createTimeoutController, TimeoutError, getDefaultTimeout, } from "../utils/timeout.js";
5
5
  // Default system context
6
6
  const DEFAULT_SYSTEM_CONTEXT = {
7
7
  systemPrompt: "You are a helpful AI assistant.",
@@ -89,7 +89,7 @@ export class MistralAI {
89
89
  const options = typeof optionsOrPrompt === "string"
90
90
  ? { prompt: optionsOrPrompt }
91
91
  : optionsOrPrompt;
92
- const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt = DEFAULT_SYSTEM_CONTEXT.systemPrompt, schema, timeout = getDefaultTimeout(provider, 'stream'), } = options;
92
+ const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt = DEFAULT_SYSTEM_CONTEXT.systemPrompt, schema, timeout = getDefaultTimeout(provider, "stream"), } = options;
93
93
  // Use schema from options or fallback parameter
94
94
  const finalSchema = schema || analysisSchema;
95
95
  logger.debug(`[${functionTag}] Stream request started`, {
@@ -103,7 +103,7 @@ export class MistralAI {
103
103
  });
104
104
  const model = this.getModel();
105
105
  // Create timeout controller if timeout is specified
106
- const timeoutController = createTimeoutController(timeout, provider, 'stream');
106
+ const timeoutController = createTimeoutController(timeout, provider, "stream");
107
107
  const streamOptions = {
108
108
  model: model,
109
109
  prompt: prompt,
@@ -111,7 +111,9 @@ export class MistralAI {
111
111
  temperature,
112
112
  maxTokens,
113
113
  // Add abort signal if available
114
- ...(timeoutController && { abortSignal: timeoutController.controller.signal }),
114
+ ...(timeoutController && {
115
+ abortSignal: timeoutController.controller.signal,
116
+ }),
115
117
  onError: (event) => {
116
118
  const error = event.error;
117
119
  const errorMessage = error instanceof Error ? error.message : String(error);
@@ -195,7 +197,7 @@ export class MistralAI {
195
197
  const options = typeof optionsOrPrompt === "string"
196
198
  ? { prompt: optionsOrPrompt }
197
199
  : optionsOrPrompt;
198
- const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt = DEFAULT_SYSTEM_CONTEXT.systemPrompt, schema, timeout = getDefaultTimeout(provider, 'generate'), } = options;
200
+ const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt = DEFAULT_SYSTEM_CONTEXT.systemPrompt, schema, timeout = getDefaultTimeout(provider, "generate"), } = options;
199
201
  // Use schema from options or fallback parameter
200
202
  const finalSchema = schema || analysisSchema;
201
203
  logger.debug(`[${functionTag}] Generate request started`, {
@@ -208,7 +210,7 @@ export class MistralAI {
208
210
  });
209
211
  const model = this.getModel();
210
212
  // Create timeout controller if timeout is specified
211
- const timeoutController = createTimeoutController(timeout, provider, 'generate');
213
+ const timeoutController = createTimeoutController(timeout, provider, "generate");
212
214
  const generateOptions = {
213
215
  model: model,
214
216
  prompt: prompt,
@@ -216,7 +218,9 @@ export class MistralAI {
216
218
  temperature,
217
219
  maxTokens,
218
220
  // Add abort signal if available
219
- ...(timeoutController && { abortSignal: timeoutController.controller.signal }),
221
+ ...(timeoutController && {
222
+ abortSignal: timeoutController.controller.signal,
223
+ }),
220
224
  };
221
225
  if (finalSchema) {
222
226
  generateOptions.experimental_output = Output.object({
@@ -281,8 +281,12 @@ export class Ollama {
281
281
  this.baseUrl = process.env.OLLAMA_BASE_URL || "http://localhost:11434";
282
282
  this.modelName = modelName || process.env.OLLAMA_MODEL || "llama2";
283
283
  // Use environment variable for backward compatibility, but convert to format used by other providers
284
- const envTimeout = process.env.OLLAMA_TIMEOUT ? parseInt(process.env.OLLAMA_TIMEOUT) : undefined;
285
- this.defaultTimeout = envTimeout || parseInt(getDefaultTimeout('ollama', 'generate').replace(/[^\d]/g, ''));
284
+ const envTimeout = process.env.OLLAMA_TIMEOUT
285
+ ? parseInt(process.env.OLLAMA_TIMEOUT)
286
+ : undefined;
287
+ this.defaultTimeout =
288
+ envTimeout ||
289
+ parseInt(getDefaultTimeout("ollama", "generate").replace(/[^\d]/g, ""));
286
290
  logger.debug("[Ollama] Initialized", {
287
291
  baseUrl: this.baseUrl,
288
292
  modelName: this.modelName,
@@ -397,7 +401,9 @@ export class Ollama {
397
401
  const finalSchema = schema || analysisSchema;
398
402
  // Convert timeout to milliseconds if provided as string
399
403
  const timeoutMs = timeout
400
- ? (typeof timeout === 'string' ? parseInt(getDefaultTimeout('ollama', 'generate').replace(/[^\d]/g, '')) : timeout)
404
+ ? typeof timeout === "string"
405
+ ? parseInt(getDefaultTimeout("ollama", "generate").replace(/[^\d]/g, ""))
406
+ : timeout
401
407
  : this.defaultTimeout;
402
408
  logger.debug(`[${functionTag}] Generate request started`, {
403
409
  provider,
@@ -460,7 +466,9 @@ export class Ollama {
460
466
  const finalSchema = schema || analysisSchema;
461
467
  // Convert timeout to milliseconds if provided as string
462
468
  const timeoutMs = timeout
463
- ? (typeof timeout === 'string' ? parseInt(getDefaultTimeout('ollama', 'stream').replace(/[^\d]/g, '')) : timeout)
469
+ ? typeof timeout === "string"
470
+ ? parseInt(getDefaultTimeout("ollama", "stream").replace(/[^\d]/g, ""))
471
+ : timeout
464
472
  : this.defaultTimeout;
465
473
  logger.debug(`[${functionTag}] Stream request started`, {
466
474
  provider,
@@ -1,7 +1,7 @@
1
1
  import { openai } from "@ai-sdk/openai";
2
2
  import { streamText, generateText, Output, } from "ai";
3
3
  import { logger } from "../utils/logger.js";
4
- import { createTimeoutController, getDefaultTimeout, TimeoutError } from "../utils/timeout.js";
4
+ import { createTimeoutController, getDefaultTimeout, TimeoutError, } from "../utils/timeout.js";
5
5
  // Default system context
6
6
  const DEFAULT_SYSTEM_CONTEXT = {
7
7
  systemPrompt: "You are a helpful AI assistant.",
@@ -60,7 +60,7 @@ export class OpenAI {
60
60
  const options = typeof optionsOrPrompt === "string"
61
61
  ? { prompt: optionsOrPrompt }
62
62
  : optionsOrPrompt;
63
- const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt = DEFAULT_SYSTEM_CONTEXT.systemPrompt, schema, timeout = getDefaultTimeout(provider, 'stream'), } = options;
63
+ const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt = DEFAULT_SYSTEM_CONTEXT.systemPrompt, schema, timeout = getDefaultTimeout(provider, "stream"), } = options;
64
64
  // Use schema from options or fallback parameter
65
65
  const finalSchema = schema || analysisSchema;
66
66
  logger.debug(`[${functionTag}] Stream text started`, {
@@ -72,7 +72,7 @@ export class OpenAI {
72
72
  timeout,
73
73
  });
74
74
  // Create timeout controller if timeout is specified
75
- const timeoutController = createTimeoutController(timeout, provider, 'stream');
75
+ const timeoutController = createTimeoutController(timeout, provider, "stream");
76
76
  const streamOptions = {
77
77
  model: this.model,
78
78
  prompt: prompt,
@@ -80,7 +80,9 @@ export class OpenAI {
80
80
  temperature,
81
81
  maxTokens,
82
82
  // Add abort signal if available
83
- ...(timeoutController && { abortSignal: timeoutController.controller.signal }),
83
+ ...(timeoutController && {
84
+ abortSignal: timeoutController.controller.signal,
85
+ }),
84
86
  onError: (event) => {
85
87
  const error = event.error;
86
88
  const errorMessage = error instanceof Error ? error.message : String(error);
@@ -155,7 +157,7 @@ export class OpenAI {
155
157
  const options = typeof optionsOrPrompt === "string"
156
158
  ? { prompt: optionsOrPrompt }
157
159
  : optionsOrPrompt;
158
- const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt = DEFAULT_SYSTEM_CONTEXT.systemPrompt, schema, timeout = getDefaultTimeout(provider, 'generate'), } = options;
160
+ const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt = DEFAULT_SYSTEM_CONTEXT.systemPrompt, schema, timeout = getDefaultTimeout(provider, "generate"), } = options;
159
161
  // Use schema from options or fallback parameter
160
162
  const finalSchema = schema || analysisSchema;
161
163
  logger.debug(`[${functionTag}] Generate text started`, {
@@ -167,7 +169,7 @@ export class OpenAI {
167
169
  timeout,
168
170
  });
169
171
  // Create timeout controller if timeout is specified
170
- const timeoutController = createTimeoutController(timeout, provider, 'generate');
172
+ const timeoutController = createTimeoutController(timeout, provider, "generate");
171
173
  const generateOptions = {
172
174
  model: this.model,
173
175
  prompt: prompt,
@@ -175,7 +177,9 @@ export class OpenAI {
175
177
  temperature,
176
178
  maxTokens,
177
179
  // Add abort signal if available
178
- ...(timeoutController && { abortSignal: timeoutController.controller.signal }),
180
+ ...(timeoutController && {
181
+ abortSignal: timeoutController.controller.signal,
182
+ }),
179
183
  };
180
184
  if (finalSchema) {
181
185
  generateOptions.experimental_output = Output.object({
@@ -11,7 +11,7 @@
11
11
  * @param operation - Operation type (generate or stream)
12
12
  * @returns The result of the promise or throws TimeoutError
13
13
  */
14
- export declare function withTimeout<T>(promise: Promise<T>, timeout: number | string | undefined, provider: string, operation: 'generate' | 'stream'): Promise<T>;
14
+ export declare function withTimeout<T>(promise: Promise<T>, timeout: number | string | undefined, provider: string, operation: "generate" | "stream"): Promise<T>;
15
15
  /**
16
16
  * Wrap a streaming async generator with timeout
17
17
  * @param generator - The async generator to wrap
@@ -27,7 +27,7 @@ export declare function withStreamingTimeout<T>(generator: AsyncGenerator<T>, ti
27
27
  * @param operation - Operation type
28
28
  * @returns AbortController and cleanup function
29
29
  */
30
- export declare function createTimeoutController(timeout: number | string | undefined, provider: string, operation: 'generate' | 'stream'): {
30
+ export declare function createTimeoutController(timeout: number | string | undefined, provider: string, operation: "generate" | "stream"): {
31
31
  controller: AbortController;
32
32
  cleanup: () => void;
33
33
  timeoutMs: number;
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Provides a consistent way to add timeout functionality to any async operation.
5
5
  */
6
- import { parseTimeout, TimeoutError, createTimeoutPromise } from '../utils/timeout.js';
6
+ import { parseTimeout, TimeoutError, createTimeoutPromise, } from "../utils/timeout.js";
7
7
  /**
8
8
  * Wrap an async operation with a timeout
9
9
  * @param promise - The promise to wrap
@@ -40,7 +40,7 @@ export async function* withStreamingTimeout(generator, timeout, provider) {
40
40
  for await (const chunk of generator) {
41
41
  // Check if we've exceeded the timeout
42
42
  if (Date.now() - startTime > timeoutMs) {
43
- throw new TimeoutError(`${provider} streaming operation timed out after ${timeout}`, timeoutMs, provider, 'stream');
43
+ throw new TimeoutError(`${provider} streaming operation timed out after ${timeout}`, timeoutMs, provider, "stream");
44
44
  }
45
45
  yield chunk;
46
46
  }
@@ -84,7 +84,7 @@ export function mergeAbortSignals(signals) {
84
84
  // Listen to all signals and abort when any fires
85
85
  for (const signal of signals) {
86
86
  if (signal && !signal.aborted) {
87
- signal.addEventListener('abort', () => {
87
+ signal.addEventListener("abort", () => {
88
88
  if (!controller.signal.aborted) {
89
89
  controller.abort(signal.reason);
90
90
  }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Proxy-aware fetch implementation for AI SDK providers
3
+ * Implements the proven Vercel AI SDK proxy pattern using undici
4
+ */
5
+ /**
6
+ * Create a proxy-aware fetch function
7
+ * This implements the community-validated approach for Vercel AI SDK
8
+ */
9
+ export declare function createProxyFetch(): typeof fetch;
10
+ /**
11
+ * Get proxy status information
12
+ */
13
+ export declare function getProxyStatus(): {
14
+ enabled: boolean;
15
+ httpProxy: string | null;
16
+ httpsProxy: string | null;
17
+ method: string;
18
+ };
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Proxy-aware fetch implementation for AI SDK providers
3
+ * Implements the proven Vercel AI SDK proxy pattern using undici
4
+ */
5
+ /**
6
+ * Create a proxy-aware fetch function
7
+ * This implements the community-validated approach for Vercel AI SDK
8
+ */
9
+ export function createProxyFetch() {
10
+ const httpsProxy = process.env.HTTPS_PROXY || process.env.https_proxy;
11
+ const httpProxy = process.env.HTTP_PROXY || process.env.http_proxy;
12
+ // If no proxy configured, return standard fetch
13
+ if (!httpsProxy && !httpProxy) {
14
+ console.log("[Proxy Fetch] No proxy environment variables found - using standard fetch");
15
+ return fetch;
16
+ }
17
+ console.log(`[Proxy Fetch] Configuring proxy with undici ProxyAgent:`);
18
+ console.log(`[Proxy Fetch] HTTP_PROXY: ${httpProxy || "not set"}`);
19
+ console.log(`[Proxy Fetch] HTTPS_PROXY: ${httpsProxy || "not set"}`);
20
+ // Return proxy-aware fetch function
21
+ return async (input, init) => {
22
+ try {
23
+ // Dynamic import undici to avoid build issues
24
+ const undici = await import("undici");
25
+ const { ProxyAgent } = undici;
26
+ const url = typeof input === "string"
27
+ ? new URL(input)
28
+ : input instanceof URL
29
+ ? input
30
+ : new URL(input.url);
31
+ const proxyUrl = url.protocol === "https:" ? httpsProxy : httpProxy;
32
+ if (proxyUrl) {
33
+ console.log(`[Proxy Fetch] Creating ProxyAgent for ${url.hostname} via ${proxyUrl}`);
34
+ // Create ProxyAgent
35
+ const dispatcher = new ProxyAgent(proxyUrl);
36
+ // Use undici fetch with dispatcher
37
+ const response = await undici.fetch(input, {
38
+ ...init,
39
+ dispatcher: dispatcher,
40
+ });
41
+ console.log(`[Proxy Fetch] ✅ Request proxied successfully to ${url.hostname}`);
42
+ return response; // Type assertion to avoid complex type issues
43
+ }
44
+ }
45
+ catch (error) {
46
+ console.warn(`[Proxy Fetch] Proxy failed (${error.message}), falling back to direct connection`);
47
+ }
48
+ // Fallback to standard fetch
49
+ return fetch(input, init);
50
+ };
51
+ }
52
+ /**
53
+ * Get proxy status information
54
+ */
55
+ export function getProxyStatus() {
56
+ const httpsProxy = process.env.HTTPS_PROXY || process.env.https_proxy;
57
+ const httpProxy = process.env.HTTP_PROXY || process.env.http_proxy;
58
+ return {
59
+ enabled: !!(httpsProxy || httpProxy),
60
+ httpProxy: httpProxy || null,
61
+ httpsProxy: httpsProxy || null,
62
+ method: "undici-proxy-agent",
63
+ };
64
+ }
@@ -39,7 +39,7 @@ export declare const DEFAULT_TIMEOUTS: {
39
39
  vertex: string;
40
40
  anthropic: string;
41
41
  azure: string;
42
- 'google-ai': string;
42
+ "google-ai": string;
43
43
  huggingface: string;
44
44
  ollama: string;
45
45
  mistral: string;
@@ -57,7 +57,7 @@ export declare const DEFAULT_TIMEOUTS: {
57
57
  * @param operation - Operation type (generate or stream)
58
58
  * @returns Default timeout string
59
59
  */
60
- export declare function getDefaultTimeout(provider: string, operation?: 'generate' | 'stream'): string;
60
+ export declare function getDefaultTimeout(provider: string, operation?: "generate" | "stream"): string;
61
61
  /**
62
62
  * Create a timeout promise that rejects after specified duration
63
63
  * @param timeout - Timeout duration
@@ -65,5 +65,5 @@ export declare function getDefaultTimeout(provider: string, operation?: 'generat
65
65
  * @param operation - Operation type for error message
66
66
  * @returns Promise that rejects with TimeoutError
67
67
  */
68
- export declare function createTimeoutPromise(timeout: number | string | undefined, provider: string, operation: 'generate' | 'stream'): Promise<never> | null;
69
- export { createTimeoutController } from '../providers/timeout-wrapper.js';
68
+ export declare function createTimeoutPromise(timeout: number | string | undefined, provider: string, operation: "generate" | "stream"): Promise<never> | null;
69
+ export { createTimeoutController } from "../providers/timeout-wrapper.js";
@@ -16,9 +16,9 @@ export class TimeoutError extends Error {
16
16
  this.timeout = timeout;
17
17
  this.provider = provider;
18
18
  this.operation = operation;
19
- this.name = 'TimeoutError';
19
+ this.name = "TimeoutError";
20
20
  // Maintains proper stack trace for where error was thrown
21
- if (typeof Error.captureStackTrace === 'function') {
21
+ if (typeof Error.captureStackTrace === "function") {
22
22
  Error.captureStackTrace(this, TimeoutError);
23
23
  }
24
24
  }
@@ -37,15 +37,16 @@ export class TimeoutError extends Error {
37
37
  * - parseTimeout(undefined) => undefined
38
38
  */
39
39
  export function parseTimeout(timeout) {
40
- if (timeout === undefined)
40
+ if (timeout === undefined) {
41
41
  return undefined;
42
- if (typeof timeout === 'number') {
42
+ }
43
+ if (typeof timeout === "number") {
43
44
  if (timeout <= 0) {
44
45
  throw new Error(`Timeout must be positive, got: ${timeout}`);
45
46
  }
46
47
  return timeout; // Assume milliseconds
47
48
  }
48
- if (typeof timeout === 'string') {
49
+ if (typeof timeout === "string") {
49
50
  // Match number (including decimals) followed by optional unit
50
51
  const match = timeout.match(/^(\d+(?:\.\d+)?)(ms|s|m|h)?$/);
51
52
  if (!match) {
@@ -55,13 +56,18 @@ export function parseTimeout(timeout) {
55
56
  if (value <= 0) {
56
57
  throw new Error(`Timeout must be positive, got: ${value}`);
57
58
  }
58
- const unit = match[2] || 'ms';
59
+ const unit = match[2] || "ms";
59
60
  switch (unit) {
60
- case 'ms': return value;
61
- case 's': return value * 1000;
62
- case 'm': return value * 60 * 1000;
63
- case 'h': return value * 60 * 60 * 1000;
64
- default: return value; // Should never reach here due to regex
61
+ case "ms":
62
+ return value;
63
+ case "s":
64
+ return value * 1000;
65
+ case "m":
66
+ return value * 60 * 1000;
67
+ case "h":
68
+ return value * 60 * 60 * 1000;
69
+ default:
70
+ return value; // Should never reach here due to regex
65
71
  }
66
72
  }
67
73
  throw new Error(`Invalid timeout type: ${typeof timeout}`);
@@ -70,25 +76,25 @@ export function parseTimeout(timeout) {
70
76
  * Default timeout configurations for different providers and operations
71
77
  */
72
78
  export const DEFAULT_TIMEOUTS = {
73
- global: '30s', // Default for all providers
74
- streaming: '2m', // Longer timeout for streaming operations
79
+ global: "30s", // Default for all providers
80
+ streaming: "2m", // Longer timeout for streaming operations
75
81
  providers: {
76
- openai: '30s', // OpenAI typically responds quickly
77
- bedrock: '45s', // AWS can be slower, especially for cold starts
78
- vertex: '60s', // Google Cloud can be slower
79
- anthropic: '30s', // Direct Anthropic API is fast
80
- azure: '30s', // Azure OpenAI similar to OpenAI
81
- 'google-ai': '30s', // Google AI Studio is fast
82
- huggingface: '2m', // Open source models vary significantly
83
- ollama: '5m', // Local models need more time, especially large ones
84
- mistral: '45s' // Mistral AI moderate speed
82
+ openai: "30s", // OpenAI typically responds quickly
83
+ bedrock: "45s", // AWS can be slower, especially for cold starts
84
+ vertex: "60s", // Google Cloud can be slower
85
+ anthropic: "30s", // Direct Anthropic API is fast
86
+ azure: "30s", // Azure OpenAI similar to OpenAI
87
+ "google-ai": "30s", // Google AI Studio is fast
88
+ huggingface: "2m", // Open source models vary significantly
89
+ ollama: "5m", // Local models need more time, especially large ones
90
+ mistral: "45s", // Mistral AI moderate speed
85
91
  },
86
92
  tools: {
87
- default: '10s', // Default timeout for MCP tool execution
88
- filesystem: '5s', // File operations should be quick
89
- network: '30s', // Network requests might take longer
90
- computation: '2m' // Heavy computation tools need more time
91
- }
93
+ default: "10s", // Default timeout for MCP tool execution
94
+ filesystem: "5s", // File operations should be quick
95
+ network: "30s", // Network requests might take longer
96
+ computation: "2m", // Heavy computation tools need more time
97
+ },
92
98
  };
93
99
  /**
94
100
  * Get default timeout for a specific provider
@@ -96,13 +102,12 @@ export const DEFAULT_TIMEOUTS = {
96
102
  * @param operation - Operation type (generate or stream)
97
103
  * @returns Default timeout string
98
104
  */
99
- export function getDefaultTimeout(provider, operation = 'generate') {
100
- if (operation === 'stream') {
105
+ export function getDefaultTimeout(provider, operation = "generate") {
106
+ if (operation === "stream") {
101
107
  return DEFAULT_TIMEOUTS.streaming;
102
108
  }
103
- const providerKey = provider.toLowerCase().replace('_', '-');
104
- return DEFAULT_TIMEOUTS.providers[providerKey]
105
- || DEFAULT_TIMEOUTS.global;
109
+ const providerKey = provider.toLowerCase().replace("_", "-");
110
+ return (DEFAULT_TIMEOUTS.providers[providerKey] || DEFAULT_TIMEOUTS.global);
106
111
  }
107
112
  /**
108
113
  * Create a timeout promise that rejects after specified duration
@@ -121,10 +126,13 @@ export function createTimeoutPromise(timeout, provider, operation) {
121
126
  reject(new TimeoutError(`${provider} ${operation} operation timed out after ${timeout}`, timeoutMs, provider, operation));
122
127
  }, timeoutMs);
123
128
  // Unref the timer so it doesn't keep the process alive (Node.js only)
124
- if (typeof timer === 'object' && timer && 'unref' in timer && typeof timer.unref === 'function') {
129
+ if (typeof timer === "object" &&
130
+ timer &&
131
+ "unref" in timer &&
132
+ typeof timer.unref === "function") {
125
133
  timer.unref();
126
134
  }
127
135
  });
128
136
  }
129
137
  // Re-export createTimeoutController from timeout-wrapper for convenience
130
- export { createTimeoutController } from '../providers/timeout-wrapper.js';
138
+ export { createTimeoutController } from "../providers/timeout-wrapper.js";
@@ -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
  */
@@ -4,7 +4,7 @@
4
4
  * Based on research document recommendations
5
5
  */
6
6
  import path from "path";
7
- import { MCP, MCPMetadata, ExecutionContext, MCPCategory, } from "../contracts/mcp-contract.js";
7
+ import { MCP, MCPCategory, } from "../contracts/mcp-contract.js";
8
8
  /**
9
9
  * Enhanced FileSystem MCP Plugin
10
10
  */
@@ -8,6 +8,7 @@ import type { AIProviderName } from "./core/types.js";
8
8
  export interface TextGenerationOptions {
9
9
  prompt: string;
10
10
  provider?: "openai" | "bedrock" | "vertex" | "anthropic" | "azure" | "google-ai" | "huggingface" | "ollama" | "mistral" | "auto";
11
+ model?: string;
11
12
  temperature?: number;
12
13
  maxTokens?: number;
13
14
  systemPrompt?: string;
@@ -18,6 +19,7 @@ export interface TextGenerationOptions {
18
19
  export interface StreamTextOptions {
19
20
  prompt: string;
20
21
  provider?: "openai" | "bedrock" | "vertex" | "anthropic" | "azure" | "google-ai" | "huggingface" | "ollama" | "mistral" | "auto";
22
+ model?: string;
21
23
  temperature?: number;
22
24
  maxTokens?: number;
23
25
  systemPrompt?: string;