@juspay/neurolink 9.10.0 → 9.11.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 (174) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/adapters/video/videoAnalyzer.d.ts +3 -3
  3. package/dist/adapters/video/videoAnalyzer.js +39 -25
  4. package/dist/agent/directTools.d.ts +3 -3
  5. package/dist/cli/commands/config.d.ts +9 -9
  6. package/dist/cli/loop/optionsSchema.d.ts +1 -1
  7. package/dist/constants/contextWindows.d.ts +6 -3
  8. package/dist/constants/contextWindows.js +30 -3
  9. package/dist/constants/index.d.ts +3 -3
  10. package/dist/constants/retry.d.ts +4 -4
  11. package/dist/constants/retry.js +1 -1
  12. package/dist/context/contextCompactor.d.ts +1 -1
  13. package/dist/context/contextCompactor.js +59 -1
  14. package/dist/context/summarizationEngine.d.ts +2 -2
  15. package/dist/context/summarizationEngine.js +44 -18
  16. package/dist/context/toolOutputLimits.d.ts +22 -13
  17. package/dist/context/toolOutputLimits.js +58 -64
  18. package/dist/core/baseProvider.d.ts +11 -2
  19. package/dist/core/baseProvider.js +30 -1
  20. package/dist/core/conversationMemoryManager.d.ts +13 -1
  21. package/dist/core/conversationMemoryManager.js +36 -5
  22. package/dist/core/modules/GenerationHandler.d.ts +6 -0
  23. package/dist/core/modules/GenerationHandler.js +192 -7
  24. package/dist/core/modules/MessageBuilder.js +42 -4
  25. package/dist/core/modules/TelemetryHandler.js +4 -1
  26. package/dist/core/redisConversationMemoryManager.d.ts +19 -3
  27. package/dist/core/redisConversationMemoryManager.js +253 -58
  28. package/dist/index.d.ts +2 -0
  29. package/dist/index.js +3 -0
  30. package/dist/lib/adapters/video/videoAnalyzer.d.ts +3 -3
  31. package/dist/lib/adapters/video/videoAnalyzer.js +39 -25
  32. package/dist/lib/agent/directTools.d.ts +7 -7
  33. package/dist/lib/constants/contextWindows.d.ts +6 -3
  34. package/dist/lib/constants/contextWindows.js +30 -3
  35. package/dist/lib/constants/index.d.ts +3 -3
  36. package/dist/lib/constants/retry.d.ts +4 -4
  37. package/dist/lib/constants/retry.js +1 -1
  38. package/dist/lib/context/contextCompactor.d.ts +1 -1
  39. package/dist/lib/context/contextCompactor.js +59 -1
  40. package/dist/lib/context/summarizationEngine.d.ts +2 -2
  41. package/dist/lib/context/summarizationEngine.js +44 -18
  42. package/dist/lib/context/toolOutputLimits.d.ts +22 -13
  43. package/dist/lib/context/toolOutputLimits.js +58 -64
  44. package/dist/lib/core/baseProvider.d.ts +11 -2
  45. package/dist/lib/core/baseProvider.js +30 -1
  46. package/dist/lib/core/conversationMemoryManager.d.ts +13 -1
  47. package/dist/lib/core/conversationMemoryManager.js +36 -5
  48. package/dist/lib/core/modules/GenerationHandler.d.ts +6 -0
  49. package/dist/lib/core/modules/GenerationHandler.js +192 -7
  50. package/dist/lib/core/modules/MessageBuilder.js +42 -4
  51. package/dist/lib/core/modules/TelemetryHandler.js +4 -1
  52. package/dist/lib/core/redisConversationMemoryManager.d.ts +19 -3
  53. package/dist/lib/core/redisConversationMemoryManager.js +253 -58
  54. package/dist/lib/files/fileTools.d.ts +3 -3
  55. package/dist/lib/index.d.ts +2 -0
  56. package/dist/lib/index.js +3 -0
  57. package/dist/lib/mcp/externalServerManager.js +36 -1
  58. package/dist/lib/memory/memoryRetrievalTools.d.ts +166 -0
  59. package/dist/lib/memory/memoryRetrievalTools.js +145 -0
  60. package/dist/lib/neurolink.d.ts +35 -1
  61. package/dist/lib/neurolink.js +471 -16
  62. package/dist/lib/providers/amazonBedrock.d.ts +1 -1
  63. package/dist/lib/providers/amazonBedrock.js +78 -45
  64. package/dist/lib/providers/amazonSagemaker.d.ts +1 -1
  65. package/dist/lib/providers/amazonSagemaker.js +1 -1
  66. package/dist/lib/providers/anthropic.d.ts +1 -1
  67. package/dist/lib/providers/anthropic.js +7 -7
  68. package/dist/lib/providers/anthropicBaseProvider.d.ts +1 -1
  69. package/dist/lib/providers/anthropicBaseProvider.js +7 -6
  70. package/dist/lib/providers/azureOpenai.d.ts +1 -1
  71. package/dist/lib/providers/azureOpenai.js +1 -1
  72. package/dist/lib/providers/googleAiStudio.d.ts +1 -1
  73. package/dist/lib/providers/googleAiStudio.js +5 -5
  74. package/dist/lib/providers/googleVertex.d.ts +1 -1
  75. package/dist/lib/providers/googleVertex.js +74 -17
  76. package/dist/lib/providers/huggingFace.d.ts +1 -1
  77. package/dist/lib/providers/huggingFace.js +1 -1
  78. package/dist/lib/providers/litellm.d.ts +1 -1
  79. package/dist/lib/providers/litellm.js +18 -16
  80. package/dist/lib/providers/mistral.d.ts +1 -1
  81. package/dist/lib/providers/mistral.js +1 -1
  82. package/dist/lib/providers/ollama.d.ts +1 -1
  83. package/dist/lib/providers/ollama.js +8 -7
  84. package/dist/lib/providers/openAI.d.ts +1 -1
  85. package/dist/lib/providers/openAI.js +6 -6
  86. package/dist/lib/providers/openRouter.d.ts +1 -1
  87. package/dist/lib/providers/openRouter.js +6 -2
  88. package/dist/lib/providers/openaiCompatible.d.ts +1 -1
  89. package/dist/lib/providers/openaiCompatible.js +1 -1
  90. package/dist/lib/proxy/proxyFetch.js +291 -65
  91. package/dist/lib/server/utils/validation.d.ts +4 -4
  92. package/dist/lib/services/server/ai/observability/instrumentation.js +12 -3
  93. package/dist/lib/telemetry/telemetryService.d.ts +2 -1
  94. package/dist/lib/telemetry/telemetryService.js +8 -1
  95. package/dist/lib/types/contextTypes.d.ts +26 -2
  96. package/dist/lib/types/conversation.d.ts +72 -40
  97. package/dist/lib/types/conversationMemoryInterface.d.ts +5 -1
  98. package/dist/lib/types/generateTypes.d.ts +26 -0
  99. package/dist/lib/types/modelTypes.d.ts +2 -2
  100. package/dist/lib/types/multimodal.d.ts +2 -0
  101. package/dist/lib/types/observability.d.ts +10 -0
  102. package/dist/lib/types/sdkTypes.d.ts +1 -1
  103. package/dist/lib/utils/conversationMemory.d.ts +4 -3
  104. package/dist/lib/utils/conversationMemory.js +44 -6
  105. package/dist/lib/utils/errorHandling.d.ts +5 -0
  106. package/dist/lib/utils/errorHandling.js +7 -2
  107. package/dist/lib/utils/logger.d.ts +8 -0
  108. package/dist/lib/utils/logger.js +56 -1
  109. package/dist/lib/utils/messageBuilder.js +74 -4
  110. package/dist/lib/utils/redis.js +6 -1
  111. package/dist/lib/utils/tokenEstimation.d.ts +2 -2
  112. package/dist/lib/utils/tokenEstimation.js +16 -1
  113. package/dist/lib/utils/videoAnalysisProcessor.d.ts +2 -1
  114. package/dist/lib/utils/videoAnalysisProcessor.js +7 -2
  115. package/dist/lib/workflow/config.d.ts +110 -110
  116. package/dist/mcp/externalServerManager.js +36 -1
  117. package/dist/memory/memoryRetrievalTools.d.ts +166 -0
  118. package/dist/memory/memoryRetrievalTools.js +144 -0
  119. package/dist/neurolink.d.ts +35 -1
  120. package/dist/neurolink.js +471 -16
  121. package/dist/providers/amazonBedrock.d.ts +1 -1
  122. package/dist/providers/amazonBedrock.js +78 -45
  123. package/dist/providers/amazonSagemaker.d.ts +1 -1
  124. package/dist/providers/amazonSagemaker.js +1 -1
  125. package/dist/providers/anthropic.d.ts +1 -1
  126. package/dist/providers/anthropic.js +7 -7
  127. package/dist/providers/anthropicBaseProvider.d.ts +1 -1
  128. package/dist/providers/anthropicBaseProvider.js +7 -6
  129. package/dist/providers/azureOpenai.d.ts +1 -1
  130. package/dist/providers/azureOpenai.js +1 -1
  131. package/dist/providers/googleAiStudio.d.ts +1 -1
  132. package/dist/providers/googleAiStudio.js +5 -5
  133. package/dist/providers/googleVertex.d.ts +1 -1
  134. package/dist/providers/googleVertex.js +74 -17
  135. package/dist/providers/huggingFace.d.ts +1 -1
  136. package/dist/providers/huggingFace.js +1 -1
  137. package/dist/providers/litellm.d.ts +1 -1
  138. package/dist/providers/litellm.js +18 -16
  139. package/dist/providers/mistral.d.ts +1 -1
  140. package/dist/providers/mistral.js +1 -1
  141. package/dist/providers/ollama.d.ts +1 -1
  142. package/dist/providers/ollama.js +8 -7
  143. package/dist/providers/openAI.d.ts +1 -1
  144. package/dist/providers/openAI.js +6 -6
  145. package/dist/providers/openRouter.d.ts +1 -1
  146. package/dist/providers/openRouter.js +6 -2
  147. package/dist/providers/openaiCompatible.d.ts +1 -1
  148. package/dist/providers/openaiCompatible.js +1 -1
  149. package/dist/proxy/proxyFetch.js +291 -65
  150. package/dist/services/server/ai/observability/instrumentation.js +12 -3
  151. package/dist/telemetry/telemetryService.d.ts +2 -1
  152. package/dist/telemetry/telemetryService.js +8 -1
  153. package/dist/types/contextTypes.d.ts +26 -2
  154. package/dist/types/conversation.d.ts +72 -40
  155. package/dist/types/conversationMemoryInterface.d.ts +5 -1
  156. package/dist/types/generateTypes.d.ts +26 -0
  157. package/dist/types/modelTypes.d.ts +10 -10
  158. package/dist/types/multimodal.d.ts +2 -0
  159. package/dist/types/observability.d.ts +10 -0
  160. package/dist/types/sdkTypes.d.ts +1 -1
  161. package/dist/utils/conversationMemory.d.ts +4 -3
  162. package/dist/utils/conversationMemory.js +44 -6
  163. package/dist/utils/errorHandling.d.ts +5 -0
  164. package/dist/utils/errorHandling.js +7 -2
  165. package/dist/utils/logger.d.ts +8 -0
  166. package/dist/utils/logger.js +56 -1
  167. package/dist/utils/messageBuilder.js +74 -4
  168. package/dist/utils/redis.js +6 -1
  169. package/dist/utils/tokenEstimation.d.ts +2 -2
  170. package/dist/utils/tokenEstimation.js +16 -1
  171. package/dist/utils/videoAnalysisProcessor.d.ts +2 -1
  172. package/dist/utils/videoAnalysisProcessor.js +7 -2
  173. package/dist/workflow/config.d.ts +12 -12
  174. package/package.json +1 -1
@@ -44,7 +44,7 @@ export declare class AmazonBedrockProvider extends BaseProvider {
44
44
  * Uses ListFoundationModels API to validate connectivity and permissions
45
45
  */
46
46
  checkBedrockHealth(): Promise<void>;
47
- handleProviderError(error: unknown): Error;
47
+ formatProviderError(error: unknown): Error;
48
48
  /**
49
49
  * Generate embeddings for text using Amazon Bedrock embedding models
50
50
  * Uses the native AWS SDK InvokeModel command for Titan embeddings
@@ -4,6 +4,7 @@ import path from "path";
4
4
  import { createAnalytics } from "../core/analytics.js";
5
5
  import { BaseProvider } from "../core/baseProvider.js";
6
6
  import { DEFAULT_MAX_STEPS } from "../core/constants.js";
7
+ import { AuthenticationError, ProviderError } from "../types/errors.js";
7
8
  import { isAbortError } from "../utils/errorHandling.js";
8
9
  import { logger } from "../utils/logger.js";
9
10
  import { buildMultimodalMessagesArray } from "../utils/messageBuilder.js";
@@ -224,57 +225,66 @@ export class AmazonBedrockProvider extends BaseProvider {
224
225
  logger.debug(`[AmazonBedrockProvider] Calling Bedrock with ${this.conversationHistory.length} messages and ${toolConfig?.tools?.length || 0} tools`);
225
226
  // Create command and attempt API call
226
227
  const command = new ConverseCommand(commandInput);
227
- logger.info(`⏳ [AmazonBedrockProvider] Sending ConverseCommand to Bedrock...`);
228
+ logger.debug("[Observability] Bedrock API request", {
229
+ model: commandInput.modelId,
230
+ region: region,
231
+ messageCount: commandInput.messages?.length || 0,
232
+ toolCount: commandInput.toolConfig?.tools?.length || 0,
233
+ maxTokens: commandInput.inferenceConfig?.maxTokens,
234
+ });
228
235
  const apiCallStartTime = Date.now();
229
236
  const response = await this.bedrockClient.send(command);
230
237
  const apiCallDuration = Date.now() - apiCallStartTime;
231
- logger.info(`✅ [AmazonBedrockProvider] Bedrock API call successful!`);
232
- logger.info(`⏱️ [AmazonBedrockProvider] API call duration: ${apiCallDuration}ms`);
233
- logger.info(`📊 [AmazonBedrockProvider] Response metadata:`);
234
- logger.info(` - Stop reason: ${response.stopReason}`);
235
- logger.info(` - Usage tokens: ${JSON.stringify(response.usage || {})}`);
236
- logger.info(` - Metrics: ${JSON.stringify(response.metrics || {})}`);
238
+ logger.debug("[Observability] Bedrock API response", {
239
+ model: commandInput.modelId,
240
+ durationMs: apiCallDuration,
241
+ hasContent: !!response.output?.message?.content?.length,
242
+ stopReason: response.stopReason,
243
+ usage: response.usage
244
+ ? {
245
+ inputTokens: response.usage.inputTokens,
246
+ outputTokens: response.usage.outputTokens,
247
+ totalTokens: (response.usage.inputTokens || 0) +
248
+ (response.usage.outputTokens || 0),
249
+ }
250
+ : undefined,
251
+ });
252
+ logger.info(`[AmazonBedrockProvider] Bedrock API call successful`);
253
+ logger.info(`[AmazonBedrockProvider] API call duration: ${apiCallDuration}ms`);
237
254
  const totalDuration = Date.now() - startTime;
238
- logger.info(`🎯 [AmazonBedrockProvider] Total callBedrock duration: ${totalDuration}ms`);
255
+ logger.info(`[AmazonBedrockProvider] Total callBedrock duration: ${totalDuration}ms`);
239
256
  return response;
240
257
  }
241
258
  catch (error) {
242
259
  const errorDuration = Date.now() - startTime;
243
- logger.error(`❌ [AmazonBedrockProvider] Bedrock API call failed after ${errorDuration}ms`);
244
- logger.error(`🔍 [AmazonBedrockProvider] Error details:`);
260
+ // Extract AWS metadata for structured logging
261
+ const awsError = error && typeof error === "object"
262
+ ? error
263
+ : null;
264
+ const metadata = awsError?.$metadata && typeof awsError.$metadata === "object"
265
+ ? awsError.$metadata
266
+ : null;
267
+ logger.debug("[Observability] Bedrock API request failed", {
268
+ model: this.modelName || this.getDefaultModel(),
269
+ durationMs: errorDuration,
270
+ error: error instanceof Error ? error.message : String(error),
271
+ errorName: error instanceof Error ? error.name : undefined,
272
+ httpStatus: metadata?.httpStatusCode,
273
+ awsRequestId: metadata?.requestId,
274
+ awsErrorCode: awsError?.Code,
275
+ });
276
+ logger.error(`[AmazonBedrockProvider] Bedrock API call failed after ${errorDuration}ms`);
245
277
  if (error instanceof Error) {
246
- logger.error(` - Error name: ${error.name}`);
247
- logger.error(` - Error message: ${error.message}`);
248
- logger.error(` - Error stack: ${error.stack}`);
278
+ logger.error(`[AmazonBedrockProvider] Error: ${error.name} - ${error.message}`);
249
279
  }
250
- // Log AWS SDK specific error details
251
- if (error && typeof error === "object") {
252
- const awsError = error;
253
- if (awsError.$metadata && typeof awsError.$metadata === "object") {
254
- const metadata = awsError.$metadata;
255
- logger.error(`🏭 [AmazonBedrockProvider] AWS SDK metadata:`);
256
- logger.error(` - HTTP status: ${metadata.httpStatusCode}`);
257
- logger.error(` - Request ID: ${metadata.requestId}`);
258
- logger.error(` - Attempts: ${metadata.attempts}`);
259
- logger.error(` - Total retry delay: ${metadata.totalRetryDelay}`);
260
- }
261
- if (awsError.Code) {
262
- logger.error(` - AWS Error Code: ${awsError.Code}`);
263
- }
264
- if (awsError.Type) {
265
- logger.error(` - AWS Error Type: ${awsError.Type}`);
266
- }
267
- if (awsError.Fault) {
268
- logger.error(` - AWS Fault: ${awsError.Fault}`);
269
- }
280
+ if (metadata) {
281
+ logger.error(`[AmazonBedrockProvider] AWS SDK metadata`, {
282
+ httpStatus: metadata.httpStatusCode,
283
+ requestId: metadata.requestId,
284
+ attempts: metadata.attempts,
285
+ totalRetryDelay: metadata.totalRetryDelay,
286
+ });
270
287
  }
271
- // Log environment details for debugging
272
- logger.error(`🌍 [AmazonBedrockProvider] Environment diagnostics:`);
273
- logger.error(` - AWS_REGION: ${process.env.AWS_REGION || "not set"}`);
274
- logger.error(` - AWS_PROFILE: ${process.env.AWS_PROFILE || "not set"}`);
275
- logger.error(` - AWS_ACCESS_KEY_ID: ${process.env.AWS_ACCESS_KEY_ID ? "set" : "not set"}`);
276
- logger.error(` - AWS_SECRET_ACCESS_KEY: ${process.env.AWS_SECRET_ACCESS_KEY ? "set" : "not set"}`);
277
- logger.error(` - AWS_SESSION_TOKEN: ${process.env.AWS_SESSION_TOKEN ? "set" : "not set"}`);
278
288
  throw error;
279
289
  }
280
290
  }
@@ -733,6 +743,10 @@ export class AmazonBedrockProvider extends BaseProvider {
733
743
  // Fallback to generate method and convert to streaming format
734
744
  const generateResult = await this.generate({
735
745
  prompt: options.input.text,
746
+ input: options.input,
747
+ maxTokens: options.maxTokens,
748
+ temperature: options.temperature,
749
+ systemPrompt: options.systemPrompt,
736
750
  });
737
751
  if (!generateResult) {
738
752
  throw new Error("Generate method returned null result");
@@ -793,8 +807,18 @@ export class AmazonBedrockProvider extends BaseProvider {
793
807
  logger.debug("🟦 [TRACE] streamingConversationLoop - testing first streaming call");
794
808
  const commandInput = await this.prepareStreamCommand(options);
795
809
  const command = new ConverseStreamCommand(commandInput);
810
+ logger.debug("[Observability] Bedrock streaming API request", {
811
+ model: commandInput.modelId,
812
+ messageCount: commandInput.messages?.length || 0,
813
+ toolCount: commandInput.toolConfig?.tools?.length || 0,
814
+ });
815
+ const streamStartTime = Date.now();
796
816
  const response = await this.bedrockClient.send(command);
797
- logger.debug("🟦 [TRACE] streamingConversationLoop - first streaming call SUCCESS");
817
+ logger.debug("[Observability] Bedrock streaming API connection established", {
818
+ model: commandInput.modelId,
819
+ durationMs: Date.now() - streamStartTime,
820
+ hasStream: !!response.stream,
821
+ });
798
822
  // Process the first response immediately to avoid waste
799
823
  const stream = new ReadableStream({
800
824
  start: async (controller) => {
@@ -925,7 +949,16 @@ export class AmazonBedrockProvider extends BaseProvider {
925
949
  }
926
950
  async processStreamResponse(commandInput, controller) {
927
951
  const command = new ConverseStreamCommand(commandInput);
952
+ logger.debug("[Observability] Bedrock streaming API request (continuation)", {
953
+ model: commandInput.modelId,
954
+ messageCount: commandInput.messages?.length || 0,
955
+ });
956
+ const iterationStartTime = Date.now();
928
957
  const response = await this.bedrockClient.send(command);
958
+ logger.debug("[Observability] Bedrock streaming API connection established (continuation)", {
959
+ model: commandInput.modelId,
960
+ durationMs: Date.now() - iterationStartTime,
961
+ });
929
962
  if (!response.stream) {
930
963
  throw new Error("No stream returned from Bedrock");
931
964
  }
@@ -1176,16 +1209,16 @@ export class AmazonBedrockProvider extends BaseProvider {
1176
1209
  }
1177
1210
  }
1178
1211
  }
1179
- handleProviderError(error) {
1212
+ formatProviderError(error) {
1180
1213
  // Handle AWS SDK specific errors
1181
1214
  const message = error instanceof Error ? error.message : String(error);
1182
1215
  if (message.includes("AccessDeniedException")) {
1183
- return new Error("AWS Bedrock access denied. Check your credentials and permissions.");
1216
+ return new AuthenticationError("AWS Bedrock access denied. Check your credentials and permissions.", this.providerName);
1184
1217
  }
1185
1218
  if (message.includes("ValidationException")) {
1186
- return new Error(`AWS Bedrock validation error: ${message}`);
1219
+ return new ProviderError(`Validation error: ${message}`, this.providerName);
1187
1220
  }
1188
- return new Error(`AWS Bedrock error: ${message}`);
1221
+ return new ProviderError(`AWS Bedrock error: ${message}`, this.providerName);
1189
1222
  }
1190
1223
  /**
1191
1224
  * Generate embeddings for text using Amazon Bedrock embedding models
@@ -21,7 +21,7 @@ export declare class AmazonSageMakerProvider extends BaseProvider {
21
21
  protected getDefaultModel(): string;
22
22
  protected getAISDKModel(): LanguageModelV1;
23
23
  protected executeStream(_options: StreamOptions, _analysisSchema?: ZodType<unknown, ZodTypeDef, unknown> | Schema<unknown>): Promise<StreamResult>;
24
- protected handleProviderError(error: unknown): Error;
24
+ protected formatProviderError(error: unknown): Error;
25
25
  /**
26
26
  * Get SageMaker-specific provider information
27
27
  */
@@ -64,7 +64,7 @@ export class AmazonSageMakerProvider extends BaseProvider {
64
64
  throw this.handleProviderError(error);
65
65
  }
66
66
  }
67
- handleProviderError(error) {
67
+ formatProviderError(error) {
68
68
  if (error instanceof SageMakerError) {
69
69
  return error;
70
70
  }
@@ -16,7 +16,7 @@ export declare class AnthropicProvider extends BaseProvider {
16
16
  * Returns the Vercel AI SDK model instance for Anthropic
17
17
  */
18
18
  getAISDKModel(): LanguageModelV1;
19
- handleProviderError(error: unknown): Error;
19
+ protected formatProviderError(error: unknown): Error;
20
20
  protected executeStream(options: StreamOptions, _analysisSchema?: ValidationSchema): Promise<StreamResult>;
21
21
  isAvailable(): Promise<boolean>;
22
22
  getModel(): LanguageModelV1;
@@ -49,9 +49,9 @@ export class AnthropicProvider extends BaseProvider {
49
49
  getAISDKModel() {
50
50
  return this.model;
51
51
  }
52
- handleProviderError(error) {
52
+ formatProviderError(error) {
53
53
  if (error instanceof TimeoutError) {
54
- throw new NetworkError(`Request timed out after ${error.timeout}ms`, this.providerName);
54
+ return new NetworkError(`Request timed out after ${error.timeout}ms`, this.providerName);
55
55
  }
56
56
  const errorRecord = error;
57
57
  const message = typeof errorRecord?.message === "string"
@@ -59,28 +59,28 @@ export class AnthropicProvider extends BaseProvider {
59
59
  : "Unknown error";
60
60
  if (message.includes("API_KEY_INVALID") ||
61
61
  message.includes("Invalid API key")) {
62
- throw new AuthenticationError("Invalid Anthropic API key. Please check your ANTHROPIC_API_KEY environment variable.", this.providerName);
62
+ return new AuthenticationError("Invalid Anthropic API key. Please check your ANTHROPIC_API_KEY environment variable.", this.providerName);
63
63
  }
64
64
  if (message.includes("rate limit") ||
65
65
  message.includes("too_many_requests") ||
66
66
  message.includes("429")) {
67
- throw new RateLimitError("Anthropic rate limit exceeded. Please try again later.", this.providerName);
67
+ return new RateLimitError("Anthropic rate limit exceeded. Please try again later.", this.providerName);
68
68
  }
69
69
  if (message.includes("ECONNRESET") ||
70
70
  message.includes("ENOTFOUND") ||
71
71
  message.includes("ECONNREFUSED") ||
72
72
  message.includes("network") ||
73
73
  message.includes("connection")) {
74
- throw new NetworkError(`Connection error: ${message}`, this.providerName);
74
+ return new NetworkError(`Connection error: ${message}`, this.providerName);
75
75
  }
76
76
  if (message.includes("500") ||
77
77
  message.includes("502") ||
78
78
  message.includes("503") ||
79
79
  message.includes("504") ||
80
80
  message.includes("server error")) {
81
- throw new ProviderError(`Server error: ${message}`, this.providerName);
81
+ return new ProviderError(`Server error: ${message}`, this.providerName);
82
82
  }
83
- throw new ProviderError(`Anthropic error: ${message}`, this.providerName);
83
+ return new ProviderError(`Anthropic error: ${message}`, this.providerName);
84
84
  }
85
85
  // executeGenerate removed - BaseProvider handles all generation with tools
86
86
  async executeStream(options, _analysisSchema) {
@@ -16,7 +16,7 @@ export declare class AnthropicProviderV2 extends BaseProvider {
16
16
  * Returns the Vercel AI SDK model instance for Anthropic
17
17
  */
18
18
  protected getAISDKModel(): LanguageModelV1;
19
- protected handleProviderError(error: unknown): Error;
19
+ protected formatProviderError(error: unknown): Error;
20
20
  private getApiKey;
21
21
  protected executeStream(options: StreamOptions, _analysisSchema?: ZodType<unknown, ZodTypeDef, unknown> | Schema<unknown>): Promise<StreamResult>;
22
22
  }
@@ -2,6 +2,7 @@ import { createAnthropic } from "@ai-sdk/anthropic";
2
2
  import { streamText } from "ai";
3
3
  import { AIProviderName, AnthropicModels } from "../constants/enums.js";
4
4
  import { BaseProvider } from "../core/baseProvider.js";
5
+ import { AuthenticationError, NetworkError, ProviderError, RateLimitError, } from "../types/errors.js";
5
6
  import { logger } from "../utils/logger.js";
6
7
  import { composeAbortSignals, createTimeoutController, TimeoutError, } from "../utils/timeout.js";
7
8
  import { validateApiKey, createAnthropicBaseConfig, } from "../utils/providerConfig.js";
@@ -35,21 +36,21 @@ export class AnthropicProviderV2 extends BaseProvider {
35
36
  const anthropic = createAnthropic({ apiKey });
36
37
  return anthropic(this.modelName);
37
38
  }
38
- handleProviderError(error) {
39
+ formatProviderError(error) {
39
40
  if (error instanceof TimeoutError) {
40
- return new Error(`Anthropic request timed out: ${error.message}`);
41
+ return new NetworkError(`Request timed out: ${error.message}`, this.providerName);
41
42
  }
42
43
  const errorWithStatus = error;
43
44
  if (errorWithStatus?.status === 401) {
44
- return new Error("Invalid Anthropic API key. Please check your ANTHROPIC_API_KEY environment variable.");
45
+ return new AuthenticationError("Invalid Anthropic API key. Please check your ANTHROPIC_API_KEY environment variable.", this.providerName);
45
46
  }
46
47
  if (errorWithStatus?.status === 429) {
47
- return new Error("Anthropic rate limit exceeded. Please try again later.");
48
+ return new RateLimitError("Anthropic rate limit exceeded. Please try again later.", this.providerName);
48
49
  }
49
50
  if (errorWithStatus?.status === 400) {
50
- return new Error(`Anthropic bad request: ${errorWithStatus?.message || "Invalid request parameters"}`);
51
+ return new ProviderError(`Bad request: ${errorWithStatus?.message || "Invalid request parameters"}`, this.providerName);
51
52
  }
52
- return new Error(`Anthropic error: ${errorWithStatus?.message || String(error) || "Unknown error"}`);
53
+ return new ProviderError(`Anthropic error: ${errorWithStatus?.message || String(error) || "Unknown error"}`, this.providerName);
53
54
  }
54
55
  // Configuration helper - now using consolidated utility
55
56
  getApiKey() {
@@ -15,7 +15,7 @@ export declare class AzureOpenAIProvider extends BaseProvider {
15
15
  * Returns the Vercel AI SDK model instance for Azure OpenAI
16
16
  */
17
17
  getAISDKModel(): LanguageModelV1;
18
- handleProviderError(error: unknown): Error;
18
+ protected formatProviderError(error: unknown): Error;
19
19
  protected executeStream(options: StreamOptions, _analysisSchema?: unknown): Promise<StreamResult>;
20
20
  }
21
21
  export default AzureOpenAIProvider;
@@ -62,7 +62,7 @@ export class AzureOpenAIProvider extends BaseProvider {
62
62
  getAISDKModel() {
63
63
  return this.azureProvider(this.deployment);
64
64
  }
65
- handleProviderError(error) {
65
+ formatProviderError(error) {
66
66
  if (error instanceof TimeoutError) {
67
67
  return new Error(`Azure OpenAI request timed out: ${error.message}`);
68
68
  }
@@ -43,7 +43,7 @@ export declare class GoogleAIStudioProvider extends BaseProvider {
43
43
  * 🔧 PHASE 2: Return AI SDK model instance for tool calling
44
44
  */
45
45
  getAISDKModel(): LanguageModelV1;
46
- handleProviderError(error: unknown): Error;
46
+ protected formatProviderError(error: unknown): Error;
47
47
  /**
48
48
  * Overrides the BaseProvider's image generation method to implement it for Google AI.
49
49
  * This method calls the Google AI API to generate an image from a prompt.
@@ -91,21 +91,21 @@ export class GoogleAIStudioProvider extends BaseProvider {
91
91
  const google = createGoogleGenerativeAI({ apiKey });
92
92
  return google(this.modelName);
93
93
  }
94
- handleProviderError(error) {
94
+ formatProviderError(error) {
95
95
  if (error instanceof TimeoutError) {
96
- throw new NetworkError(error.message, this.providerName);
96
+ return new NetworkError(error.message, this.providerName);
97
97
  }
98
98
  const errorRecord = error;
99
99
  const message = typeof errorRecord?.message === "string"
100
100
  ? errorRecord.message
101
101
  : "Unknown error";
102
102
  if (message.includes("API_KEY_INVALID")) {
103
- throw new AuthenticationError("Invalid Google AI API key. Please check your GOOGLE_AI_API_KEY environment variable.", this.providerName);
103
+ return new AuthenticationError("Invalid Google AI API key. Please check your GOOGLE_AI_API_KEY environment variable.", this.providerName);
104
104
  }
105
105
  if (message.includes("RATE_LIMIT_EXCEEDED")) {
106
- throw new RateLimitError("Google AI rate limit exceeded. Please try again later.", this.providerName);
106
+ return new RateLimitError("Google AI rate limit exceeded. Please try again later.", this.providerName);
107
107
  }
108
- throw new ProviderError(`Google AI error: ${message}`, this.providerName);
108
+ return new ProviderError(`Google AI error: ${message}`, this.providerName);
109
109
  }
110
110
  /**
111
111
  * Overrides the BaseProvider's image generation method to implement it for Google AI.
@@ -130,7 +130,7 @@ export declare class GoogleVertexProvider extends BaseProvider {
130
130
  * Override generate to route Gemini 3 models with tools to native SDK
131
131
  */
132
132
  generate(optionsOrPrompt: TextGenerationOptions | string): Promise<EnhancedGenerateResult | null>;
133
- protected handleProviderError(error: unknown): Error;
133
+ protected formatProviderError(error: unknown): Error;
134
134
  /**
135
135
  * Memory-safe cache management for model configurations
136
136
  * Implements LRU eviction to prevent memory leaks in long-running processes
@@ -10,7 +10,7 @@ import { BaseProvider } from "../core/baseProvider.js";
10
10
  import { DEFAULT_MAX_STEPS, GLOBAL_LOCATION_MODELS, } from "../core/constants.js";
11
11
  import { ModelConfigurationManager } from "../core/modelConfiguration.js";
12
12
  import { createProxyFetch } from "../proxy/proxyFetch.js";
13
- import { AuthenticationError, ProviderError } from "../types/errors.js";
13
+ import { AuthenticationError, NetworkError, ProviderError, RateLimitError, InvalidModelError, } from "../types/errors.js";
14
14
  import { ERROR_CODES, NeuroLinkError } from "../utils/errorHandling.js";
15
15
  import { FileDetector } from "../utils/fileDetector.js";
16
16
  import { logger } from "../utils/logger.js";
@@ -20,6 +20,16 @@ import { convertZodToJsonSchema, inlineJsonSchema, } from "../utils/schemaConver
20
20
  import { composeAbortSignals, createTimeoutController, TimeoutError, } from "../utils/timeout.js";
21
21
  import { buildNativeToolDeclarations, buildNativeConfig, computeMaxSteps as computeMaxStepsShared, collectStreamChunks, extractTextFromParts, executeNativeToolCalls, handleMaxStepsTermination, pushModelResponseToHistory, } from "./googleNativeGemini3.js";
22
22
  // Import proper types for multimodal message handling
23
+ // Keep-alive note: Node.js native fetch and undici (used by createProxyFetch)
24
+ // handle HTTP keep-alive internally. The fetchWithRetry wrapper in proxyFetch.ts
25
+ // provides retry protection for transient ECONNRESET/ETIMEDOUT errors.
26
+ //
27
+ // Auth isolation note: @ai-sdk/google-vertex resolves auth tokens (via
28
+ // generateAuthToken → google-auth-library) BEFORE applying the user AbortSignal
29
+ // to the main API call. Auth token refresh uses gaxios internally, not our
30
+ // custom fetch, so it is inherently isolated from user cancellation signals.
31
+ // The image generation path (getImageGenerationAccessToken) has an additional
32
+ // explicit 15s timeout per attempt for direct REST API calls.
23
33
  // Enhanced Anthropic support with direct imports
24
34
  // Using the dual provider architecture from Vercel AI SDK
25
35
  const hasAnthropicSupport = () => {
@@ -1315,29 +1325,44 @@ export class GoogleVertexProvider extends BaseProvider {
1315
1325
  // Fall back to BaseProvider implementation
1316
1326
  return super.generate(optionsOrPrompt);
1317
1327
  }
1318
- handleProviderError(error) {
1328
+ formatProviderError(error) {
1329
+ // Pass through AbortError as-is so callers can detect cancellation
1319
1330
  const errorRecord = error;
1331
+ if (typeof errorRecord?.name === "string" &&
1332
+ errorRecord.name === "AbortError") {
1333
+ return error;
1334
+ }
1320
1335
  if (typeof errorRecord?.name === "string" &&
1321
1336
  errorRecord.name === "TimeoutError") {
1322
- return new TimeoutError(`Google Vertex AI request timed out. Consider increasing timeout or using a lighter model.`, this.defaultTimeout);
1337
+ return new NetworkError(`Google Vertex AI request timed out. Consider increasing timeout or using a lighter model.`, this.providerName);
1323
1338
  }
1324
1339
  const message = typeof errorRecord?.message === "string"
1325
1340
  ? errorRecord.message
1326
1341
  : "Unknown error occurred";
1342
+ const code = typeof errorRecord?.code === "string" ? errorRecord.code : undefined;
1343
+ if (code === "ECONNRESET" ||
1344
+ code === "ENOTFOUND" ||
1345
+ code === "ECONNREFUSED" ||
1346
+ message.includes("ECONNRESET") ||
1347
+ message.includes("ENOTFOUND") ||
1348
+ message.includes("ECONNREFUSED") ||
1349
+ message.includes("connect ETIMEDOUT")) {
1350
+ return new NetworkError(`Google Vertex AI network error: ${message}`, this.providerName);
1351
+ }
1327
1352
  if (message.includes("PERMISSION_DENIED")) {
1328
- return new Error(`❌ Google Vertex AI Permission Denied\n\nYour Google Cloud credentials don't have permission to access Vertex AI.\n\nRequired Steps:\n1. Ensure your service account has Vertex AI User role\n2. Check if Vertex AI API is enabled in your project\n3. Verify your project ID is correct\n4. Confirm your location/region has Vertex AI available`);
1353
+ return new AuthenticationError(`❌ Google Vertex AI Permission Denied\n\nYour Google Cloud credentials don't have permission to access Vertex AI.\n\nRequired Steps:\n1. Ensure your service account has Vertex AI User role\n2. Check if Vertex AI API is enabled in your project\n3. Verify your project ID is correct\n4. Confirm your location/region has Vertex AI available`, this.providerName);
1329
1354
  }
1330
1355
  if (message.includes("NOT_FOUND")) {
1331
1356
  const modelSuggestions = this.getModelSuggestions(this.modelName);
1332
- return new Error(`❌ Google Vertex AI Model Not Found\n\n${message}\n\nModel '${this.modelName}' is not available.\n\nSuggested alternatives:\n${modelSuggestions}\n\nTroubleshooting:\n1. Check model name spelling and format\n2. Verify model is available in your region (${this.location})\n3. Ensure your project has access to the model\n4. For Claude models, enable Anthropic integration in Google Cloud Console`);
1357
+ return new InvalidModelError(`❌ Google Vertex AI Model Not Found\n\n${message}\n\nModel '${this.modelName}' is not available.\n\nSuggested alternatives:\n${modelSuggestions}\n\nTroubleshooting:\n1. Check model name spelling and format\n2. Verify model is available in your region (${this.location})\n3. Ensure your project has access to the model\n4. For Claude models, enable Anthropic integration in Google Cloud Console`, this.providerName);
1333
1358
  }
1334
1359
  if (message.includes("QUOTA_EXCEEDED")) {
1335
- return new Error(`❌ Google Vertex AI Quota Exceeded\n\n${message}\n\nSolutions:\n1. Check your Vertex AI quotas in Google Cloud Console\n2. Request quota increase if needed\n3. Try a different model or reduce request frequency\n4. Consider using a different region`);
1360
+ return new RateLimitError(`❌ Google Vertex AI Quota Exceeded\n\n${message}\n\nSolutions:\n1. Check your Vertex AI quotas in Google Cloud Console\n2. Request quota increase if needed\n3. Try a different model or reduce request frequency\n4. Consider using a different region`, this.providerName);
1336
1361
  }
1337
1362
  if (message.includes("INVALID_ARGUMENT")) {
1338
- return new Error(`❌ Google Vertex AI Invalid Request\n\n${message}\n\nCheck:\n1. Request parameters are within model limits\n2. Input text is properly formatted\n3. Temperature and other settings are valid\n4. Model supports your request type`);
1363
+ return new ProviderError(`❌ Google Vertex AI Invalid Request\n\n${message}\n\nCheck:\n1. Request parameters are within model limits\n2. Input text is properly formatted\n3. Temperature and other settings are valid\n4. Model supports your request type`, this.providerName);
1339
1364
  }
1340
- return new Error(`❌ Google Vertex AI Provider Error\n\n${message}\n\nTroubleshooting:\n1. Check Google Cloud credentials and permissions\n2. Verify project ID and location settings\n3. Ensure Vertex AI API is enabled\n4. Check network connectivity`);
1365
+ return new ProviderError(`❌ Google Vertex AI Provider Error\n\n${message}\n\nTroubleshooting:\n1. Check Google Cloud credentials and permissions\n2. Verify project ID and location settings\n3. Ensure Vertex AI API is enabled\n4. Check network connectivity`, this.providerName);
1341
1366
  }
1342
1367
  /**
1343
1368
  * Memory-safe cache management for model configurations
@@ -2048,20 +2073,52 @@ export class GoogleVertexProvider extends BaseProvider {
2048
2073
  * Obtain a Google Auth access token for Vertex AI REST API calls.
2049
2074
  */
2050
2075
  async getImageGenerationAccessToken() {
2076
+ const maxRetries = 3;
2077
+ const baseDelay = 500;
2078
+ const authTimeoutMs = 15000;
2051
2079
  const { GoogleAuth } = await import("google-auth-library");
2052
2080
  // Priority: GOOGLE_APPLICATION_CREDENTIALS_NEUROLINK > GOOGLE_APPLICATION_CREDENTIALS
2053
2081
  const credentialsPath = process.env.GOOGLE_APPLICATION_CREDENTIALS_NEUROLINK ||
2054
2082
  process.env.GOOGLE_APPLICATION_CREDENTIALS;
2055
- const auth = new GoogleAuth({
2056
- ...(credentialsPath && { keyFilename: credentialsPath }),
2057
- scopes: ["https://www.googleapis.com/auth/cloud-platform"],
2058
- });
2059
- const client = await auth.getClient();
2060
- const accessToken = await client.getAccessToken();
2061
- if (!accessToken.token) {
2062
- throw new AuthenticationError("Failed to obtain access token from Google Auth", this.providerName);
2083
+ for (let attempt = 1; attempt <= maxRetries; attempt++) {
2084
+ // Enforce per-attempt timeout with AbortController
2085
+ const controller = new AbortController();
2086
+ const authTimer = setTimeout(() => {
2087
+ controller.abort();
2088
+ logger.warn(`[GoogleVertexProvider] Auth token refresh exceeded ${authTimeoutMs}ms timeout (attempt ${attempt}/${maxRetries})`);
2089
+ }, authTimeoutMs);
2090
+ try {
2091
+ const auth = new GoogleAuth({
2092
+ ...(credentialsPath && { keyFilename: credentialsPath }),
2093
+ scopes: ["https://www.googleapis.com/auth/cloud-platform"],
2094
+ });
2095
+ const client = await auth.getClient();
2096
+ const accessToken = await client.getAccessToken();
2097
+ if (!accessToken.token) {
2098
+ throw new AuthenticationError("Failed to obtain access token from Google Auth", this.providerName);
2099
+ }
2100
+ return accessToken.token;
2101
+ }
2102
+ catch (error) {
2103
+ const err = error;
2104
+ const isRetryable = controller.signal.aborted ||
2105
+ err?.code === "ECONNRESET" ||
2106
+ err?.code === "ETIMEDOUT" ||
2107
+ err?.code === "ENOTFOUND" ||
2108
+ err?.message?.includes("socket hang up") ||
2109
+ err?.message?.includes("network socket disconnected");
2110
+ if (!isRetryable || attempt === maxRetries) {
2111
+ throw error;
2112
+ }
2113
+ const delay = baseDelay * Math.pow(2, attempt - 1);
2114
+ logger.warn(`[GoogleVertexProvider] Auth token transient error (${err?.code || err?.message}), retrying in ${delay}ms (attempt ${attempt}/${maxRetries})`);
2115
+ await new Promise((r) => setTimeout(r, delay));
2116
+ }
2117
+ finally {
2118
+ clearTimeout(authTimer);
2119
+ }
2063
2120
  }
2064
- return accessToken.token;
2121
+ throw new AuthenticationError("Failed to obtain access token after retries", this.providerName);
2065
2122
  }
2066
2123
  /**
2067
2124
  * Build request parts for image generation from prompt, PDFs, and images.
@@ -68,7 +68,7 @@ export declare class HuggingFaceProvider extends BaseProvider {
68
68
  /**
69
69
  * Enhanced error handling with HuggingFace-specific guidance
70
70
  */
71
- handleProviderError(error: unknown): Error;
71
+ formatProviderError(error: unknown): Error;
72
72
  getProviderName(): AIProviderName;
73
73
  getDefaultModel(): string;
74
74
  /**
@@ -265,7 +265,7 @@ Available tools will be provided in the function calling format. Use them when t
265
265
  /**
266
266
  * Enhanced error handling with HuggingFace-specific guidance
267
267
  */
268
- handleProviderError(error) {
268
+ formatProviderError(error) {
269
269
  if (error instanceof TimeoutError) {
270
270
  return new Error(`HuggingFace request timed out: ${error.message}`);
271
271
  }
@@ -19,7 +19,7 @@ export declare class LiteLLMProvider extends BaseProvider {
19
19
  * Returns the Vercel AI SDK model instance for LiteLLM
20
20
  */
21
21
  protected getAISDKModel(): LanguageModelV1;
22
- handleProviderError(error: unknown): Error;
22
+ formatProviderError(error: unknown): Error;
23
23
  /**
24
24
  * LiteLLM supports tools for compatible models
25
25
  */