@juspay/neurolink 7.29.1 → 7.29.2

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 (59) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/cli/commands/config.d.ts +3 -3
  3. package/dist/cli/commands/mcp.js +25 -0
  4. package/dist/cli/factories/commandFactory.d.ts +1 -0
  5. package/dist/cli/factories/commandFactory.js +115 -21
  6. package/dist/cli/index.js +8 -0
  7. package/dist/core/factory.js +77 -4
  8. package/dist/factories/providerFactory.js +3 -0
  9. package/dist/factories/providerRegistry.js +2 -2
  10. package/dist/lib/core/factory.js +77 -4
  11. package/dist/lib/factories/providerFactory.js +3 -0
  12. package/dist/lib/factories/providerRegistry.js +2 -2
  13. package/dist/lib/mcp/externalServerManager.js +13 -14
  14. package/dist/lib/mcp/flexibleToolValidator.d.ts +50 -0
  15. package/dist/lib/mcp/flexibleToolValidator.js +161 -0
  16. package/dist/lib/mcp/toolRegistry.d.ts +2 -2
  17. package/dist/lib/mcp/toolRegistry.js +25 -50
  18. package/dist/lib/neurolink.d.ts +2 -0
  19. package/dist/lib/neurolink.js +137 -69
  20. package/dist/lib/providers/amazonBedrock.d.ts +47 -6
  21. package/dist/lib/providers/amazonBedrock.js +282 -23
  22. package/dist/lib/providers/aws/credentialProvider.d.ts +58 -0
  23. package/dist/lib/providers/aws/credentialProvider.js +267 -0
  24. package/dist/lib/providers/aws/credentialTester.d.ts +49 -0
  25. package/dist/lib/providers/aws/credentialTester.js +394 -0
  26. package/dist/lib/proxy/awsProxyIntegration.d.ts +23 -0
  27. package/dist/lib/proxy/awsProxyIntegration.js +285 -0
  28. package/dist/lib/proxy/proxyFetch.d.ts +9 -5
  29. package/dist/lib/proxy/proxyFetch.js +232 -98
  30. package/dist/lib/proxy/utils/noProxyUtils.d.ts +39 -0
  31. package/dist/lib/proxy/utils/noProxyUtils.js +149 -0
  32. package/dist/lib/types/providers.d.ts +43 -0
  33. package/dist/lib/utils/providerConfig.d.ts +1 -0
  34. package/dist/lib/utils/providerConfig.js +2 -1
  35. package/dist/lib/utils/providerHealth.js +123 -5
  36. package/dist/mcp/externalServerManager.js +13 -14
  37. package/dist/mcp/flexibleToolValidator.d.ts +50 -0
  38. package/dist/mcp/flexibleToolValidator.js +161 -0
  39. package/dist/mcp/toolRegistry.d.ts +2 -2
  40. package/dist/mcp/toolRegistry.js +25 -50
  41. package/dist/neurolink.d.ts +2 -0
  42. package/dist/neurolink.js +137 -69
  43. package/dist/providers/amazonBedrock.d.ts +47 -6
  44. package/dist/providers/amazonBedrock.js +282 -23
  45. package/dist/providers/aws/credentialProvider.d.ts +58 -0
  46. package/dist/providers/aws/credentialProvider.js +267 -0
  47. package/dist/providers/aws/credentialTester.d.ts +49 -0
  48. package/dist/providers/aws/credentialTester.js +394 -0
  49. package/dist/proxy/awsProxyIntegration.d.ts +23 -0
  50. package/dist/proxy/awsProxyIntegration.js +285 -0
  51. package/dist/proxy/proxyFetch.d.ts +9 -5
  52. package/dist/proxy/proxyFetch.js +232 -98
  53. package/dist/proxy/utils/noProxyUtils.d.ts +39 -0
  54. package/dist/proxy/utils/noProxyUtils.js +149 -0
  55. package/dist/types/providers.d.ts +43 -0
  56. package/dist/utils/providerConfig.d.ts +1 -0
  57. package/dist/utils/providerConfig.js +2 -1
  58. package/dist/utils/providerHealth.js +123 -5
  59. package/package.json +5 -1
@@ -24,6 +24,7 @@ import { ProviderRegistry } from "./factories/providerRegistry.js";
24
24
  import { createCustomToolServerInfo, detectCategory, } from "./utils/mcpDefaults.js";
25
25
  // Factory processing imports
26
26
  import { processFactoryOptions, enhanceTextGenerationOptions, validateFactoryConfig, processStreamingFactoryOptions, createCleanStreamOptions, } from "./utils/factoryProcessing.js";
27
+ // Tool detection and execution imports
27
28
  // Transformation utilities
28
29
  import { transformToolExecutions, transformToolExecutionsForMCP, transformAvailableTools, transformToolsForMCP, transformToolsToExpectedFormat, transformToolsToDescriptions, extractToolNames, transformParamsForLogging, optimizeToolForCollection, } from "./utils/transformationUtils.js";
29
30
  // Enhanced error handling imports
@@ -54,14 +55,21 @@ export class NeuroLink {
54
55
  * @param toolName - Name of the tool
55
56
  * @param startTime - Timestamp when tool execution started
56
57
  * @param success - Whether the tool execution was successful
58
+ * @param result - The result of the tool execution (optional)
59
+ * @param error - The error if execution failed (optional)
57
60
  */
58
- emitToolEndEvent(toolName, startTime, success) {
61
+ emitToolEndEvent(toolName, startTime, success, result, error) {
62
+ // Emit tool end event (NeuroLink format - enhanced with result/error)
59
63
  this.emitter.emit("tool:end", {
60
64
  toolName,
61
65
  responseTime: Date.now() - startTime,
62
66
  success,
63
67
  timestamp: Date.now(),
68
+ result: result, // Enhanced: include actual result
69
+ error: error, // Enhanced: include error if present
64
70
  });
71
+ // ADD: Bedrock-compatible tool:end event (positional parameters)
72
+ this.emitter.emit("tool:end", toolName, success ? result : error);
65
73
  }
66
74
  // Conversation memory support
67
75
  conversationMemory;
@@ -816,11 +824,15 @@ export class NeuroLink {
816
824
  options.input.text = this.contextManager.getContextForPrompt("user", options.input.text);
817
825
  }
818
826
  const startTime = Date.now();
819
- // Emit generation start event
827
+ // Emit generation start event (NeuroLink format - keep existing)
820
828
  this.emitter.emit("generation:start", {
821
829
  provider: options.provider || "auto",
822
830
  timestamp: startTime,
823
831
  });
832
+ // ADD: Bedrock-compatible response:start event
833
+ this.emitter.emit("response:start");
834
+ // ADD: Bedrock-compatible message event
835
+ this.emitter.emit("message", `Starting ${options.provider || "auto"} text generation...`);
824
836
  // Process factory configuration
825
837
  const factoryResult = processFactoryOptions(options);
826
838
  // Validate factory configuration if present
@@ -863,13 +875,18 @@ export class NeuroLink {
863
875
  }
864
876
  // Use redesigned generation logic
865
877
  const textResult = await this.generateTextInternal(textOptions);
866
- // Emit generation completion event
878
+ // Emit generation completion event (NeuroLink format - enhanced with content)
867
879
  this.emitter.emit("generation:end", {
868
880
  provider: textResult.provider,
869
881
  responseTime: Date.now() - startTime,
870
882
  toolsUsed: textResult.toolsUsed,
871
883
  timestamp: Date.now(),
884
+ result: textResult, // Enhanced: include full result
872
885
  });
886
+ // ADD: Bedrock-compatible response:end event with content
887
+ this.emitter.emit("response:end", textResult.content || "");
888
+ // ADD: Bedrock-compatible message event
889
+ this.emitter.emit("message", `Generation completed in ${Date.now() - startTime}ms`);
873
890
  // Convert back to GenerateResult
874
891
  const generateResult = {
875
892
  content: textResult.content,
@@ -1002,6 +1019,10 @@ export class NeuroLink {
1002
1019
  promptLength: options.prompt?.length || 0,
1003
1020
  hasConversationMemory: !!this.conversationMemory,
1004
1021
  });
1022
+ // ADD: Bedrock-compatible response:start event for generateTextInternal
1023
+ this.emitter.emit("response:start");
1024
+ // ADD: Bedrock-compatible message event for generateTextInternal
1025
+ this.emitter.emit("message", `Starting ${options.provider || "auto"} text generation (internal)...`);
1005
1026
  try {
1006
1027
  // 🚀 EXHAUSTIVE LOGGING POINT G002: CONVERSATION MEMORY INITIALIZATION
1007
1028
  const conversationMemoryStartTime = process.hrtime.bigint();
@@ -1148,6 +1169,8 @@ export class NeuroLink {
1148
1169
  });
1149
1170
  // Store conversation turn
1150
1171
  await storeConversationTurn(this.conversationMemory, options, mcpResult);
1172
+ // ADD: Bedrock-compatible response:end event for MCP success path
1173
+ this.emitter.emit("response:end", mcpResult.content || "");
1151
1174
  return mcpResult;
1152
1175
  }
1153
1176
  else {
@@ -1164,6 +1187,8 @@ export class NeuroLink {
1164
1187
  logger.debug(`[${functionTag}] Found tool executions but no content, continuing with result`);
1165
1188
  // Store conversation turn even with empty content if tools executed
1166
1189
  await storeConversationTurn(this.conversationMemory, options, mcpResult);
1190
+ // ADD: Bedrock-compatible response:end event for MCP tool execution success path
1191
+ this.emitter.emit("response:end", mcpResult.content || "");
1167
1192
  return mcpResult;
1168
1193
  }
1169
1194
  }
@@ -1188,12 +1213,20 @@ export class NeuroLink {
1188
1213
  logger.debug(`[${functionTag}] Direct generation successful`);
1189
1214
  // Store conversation turn
1190
1215
  await storeConversationTurn(this.conversationMemory, options, directResult);
1216
+ // ADD: Bedrock-compatible response:end event for generateTextInternal
1217
+ this.emitter.emit("response:end", directResult.content || "");
1218
+ // ADD: Bedrock-compatible message event for generateTextInternal completion
1219
+ this.emitter.emit("message", `Text generation completed successfully`);
1191
1220
  return directResult;
1192
1221
  }
1193
1222
  catch (error) {
1194
1223
  logger.error(`[${functionTag}] All generation methods failed`, {
1195
1224
  error: error instanceof Error ? error.message : String(error),
1196
1225
  });
1226
+ // ADD: Bedrock-compatible response:end event for error path (empty content)
1227
+ this.emitter.emit("response:end", "");
1228
+ // ADD: Centralized error event emission
1229
+ this.emitter.emit("error", error instanceof Error ? error : new Error(String(error)));
1197
1230
  throw error;
1198
1231
  }
1199
1232
  }
@@ -1299,6 +1332,9 @@ export class NeuroLink {
1299
1332
  // Create provider and generate
1300
1333
  const provider = await AIProviderFactory.createProvider(providerName, options.model, !options.disableTools, // Pass disableTools as inverse of enableMCP
1301
1334
  this);
1335
+ // ADD: Emit connection events for all providers (Bedrock-compatible)
1336
+ this.emitter.emit("connected");
1337
+ this.emitter.emit("message", `${providerName} provider initialized successfully`);
1302
1338
  // Enable tool execution for the provider using BaseProvider method
1303
1339
  provider.setupToolExecutor({
1304
1340
  customTools: this.getCustomTools(),
@@ -1393,6 +1429,9 @@ export class NeuroLink {
1393
1429
  const conversationMessages = await getConversationMessages(this.conversationMemory, options);
1394
1430
  const provider = await AIProviderFactory.createProvider(providerName, options.model, !options.disableTools, // Pass disableTools as inverse of enableMCP
1395
1431
  this);
1432
+ // ADD: Emit connection events for successful provider creation (Bedrock-compatible)
1433
+ this.emitter.emit("connected");
1434
+ this.emitter.emit("message", `${providerName} provider initialized successfully`);
1396
1435
  // Enable tool execution for direct provider generation using BaseProvider method
1397
1436
  provider.setupToolExecutor({
1398
1437
  customTools: this.getCustomTools(),
@@ -1454,7 +1493,7 @@ export class NeuroLink {
1454
1493
  * Execute tools if available through centralized registry
1455
1494
  * Simplified approach without domain detection - relies on tool registry
1456
1495
  */
1457
- async detectAndExecuteTools(prompt, domainType) {
1496
+ async detectAndExecuteTools(prompt, _domainType) {
1458
1497
  const functionTag = "NeuroLink.detectAndExecuteTools";
1459
1498
  try {
1460
1499
  // Simplified: Just return original prompt without complex detection
@@ -1669,7 +1708,7 @@ export class NeuroLink {
1669
1708
  global.gc();
1670
1709
  return process.memoryUsage();
1671
1710
  }
1672
- catch (e) {
1711
+ catch (_e) {
1673
1712
  return null;
1674
1713
  }
1675
1714
  })()
@@ -1807,11 +1846,15 @@ export class NeuroLink {
1807
1846
  cpuAfterValidation: process.cpuUsage(),
1808
1847
  message: "EXHAUSTIVE validation success - proceeding with stream processing",
1809
1848
  });
1810
- // Emit stream start event
1849
+ // Emit stream start event (NeuroLink format - keep existing)
1811
1850
  this.emitter.emit("stream:start", {
1812
1851
  provider: options.provider || "auto",
1813
1852
  timestamp: startTime,
1814
1853
  });
1854
+ // ADD: Bedrock-compatible response:start event
1855
+ this.emitter.emit("response:start");
1856
+ // ADD: Bedrock-compatible message event
1857
+ this.emitter.emit("message", `Starting ${options.provider || "auto"} stream generation...`);
1815
1858
  // Process factory configuration for streaming
1816
1859
  const factoryResult = processFactoryOptions(options);
1817
1860
  const streamingResult = processStreamingFactoryOptions(options);
@@ -1903,6 +1946,8 @@ export class NeuroLink {
1903
1946
  // Ensure chunk has content property and it's a string
1904
1947
  if (typeof chunk.content === "string") {
1905
1948
  accumulatedContent += chunk.content;
1949
+ // ADD: Bedrock-compatible response:chunk event
1950
+ self.emitter.emit("response:chunk", chunk.content);
1906
1951
  }
1907
1952
  else if (chunk.content === undefined ||
1908
1953
  chunk.content === null) {
@@ -1914,6 +1959,8 @@ export class NeuroLink {
1914
1959
  const stringContent = String(chunk.content || "");
1915
1960
  processedChunk = { ...chunk, content: stringContent };
1916
1961
  accumulatedContent += stringContent;
1962
+ // ADD: Bedrock-compatible response:chunk event
1963
+ self.emitter.emit("response:chunk", stringContent);
1917
1964
  }
1918
1965
  }
1919
1966
  else if (chunk === null || chunk === undefined) {
@@ -1950,11 +1997,16 @@ export class NeuroLink {
1950
1997
  responseTime,
1951
1998
  provider: providerName,
1952
1999
  });
1953
- // Emit stream completion event
2000
+ // Emit stream completion event (NeuroLink format - enhanced with content)
1954
2001
  this.emitter.emit("stream:end", {
1955
2002
  provider: providerName,
1956
2003
  responseTime,
2004
+ result: { content: accumulatedContent }, // Enhanced: include accumulated content
1957
2005
  });
2006
+ // ADD: Bedrock-compatible response:end event with full response
2007
+ this.emitter.emit("response:end", accumulatedContent);
2008
+ // ADD: Bedrock-compatible message event
2009
+ this.emitter.emit("message", `Stream completed in ${responseTime}ms (${accumulatedContent.length} chars)`);
1958
2010
  // Convert to StreamResult format - Include analytics and evaluation from provider
1959
2011
  return {
1960
2012
  stream: processedStream,
@@ -1983,6 +2035,8 @@ export class NeuroLink {
1983
2035
  };
1984
2036
  }
1985
2037
  catch (error) {
2038
+ // ADD: Error event emission for MCP streaming failure
2039
+ this.emitter.emit("error", error instanceof Error ? error : new Error(String(error)));
1986
2040
  // Fall back to regular streaming if MCP fails
1987
2041
  mcpLogger.warn(`[${functionTag}] MCP streaming failed, falling back to regular`, {
1988
2042
  error: error instanceof Error ? error.message : String(error),
@@ -2018,6 +2072,8 @@ export class NeuroLink {
2018
2072
  for await (const chunk of streamResult.stream) {
2019
2073
  if (chunk && typeof chunk.content === "string") {
2020
2074
  fallbackAccumulatedContent += chunk.content;
2075
+ // ADD: Bedrock-compatible response:chunk event for fallback
2076
+ self.emitter.emit("response:chunk", chunk.content);
2021
2077
  }
2022
2078
  yield chunk; // Preserve original streaming behavior
2023
2079
  }
@@ -2045,12 +2101,17 @@ export class NeuroLink {
2045
2101
  }
2046
2102
  })(this);
2047
2103
  const responseTime = Date.now() - startTime;
2048
- // Emit stream completion event for fallback
2104
+ // Emit stream completion event for fallback (NeuroLink format - enhanced with content)
2049
2105
  this.emitter.emit("stream:end", {
2050
2106
  provider: providerName,
2051
2107
  responseTime,
2052
2108
  fallback: true,
2109
+ result: { content: fallbackAccumulatedContent }, // Enhanced: include accumulated content
2053
2110
  });
2111
+ // ADD: Bedrock-compatible response:end event with full response
2112
+ this.emitter.emit("response:end", fallbackAccumulatedContent);
2113
+ // ADD: Bedrock-compatible message event
2114
+ this.emitter.emit("message", `Fallback stream completed in ${responseTime}ms (${fallbackAccumulatedContent.length} chars)`);
2054
2115
  return {
2055
2116
  stream: fallbackProcessedStream,
2056
2117
  provider: providerName,
@@ -2271,7 +2332,7 @@ export class NeuroLink {
2271
2332
  timestamp: Date.now(),
2272
2333
  });
2273
2334
  try {
2274
- // --- Start: Added Validation Logic ---
2335
+ // --- Start: Enhanced Validation Logic with FlexibleToolValidator ---
2275
2336
  if (!name || typeof name !== "string") {
2276
2337
  throw new Error("Invalid tool name");
2277
2338
  }
@@ -2281,55 +2342,36 @@ export class NeuroLink {
2281
2342
  if (typeof tool.execute !== "function") {
2282
2343
  throw new Error(`Tool '${name}' must have an execute method.`);
2283
2344
  }
2284
- // --- End: Added Validation Logic ---
2285
- // Import validation functions synchronously - they are pure functions
2286
- let validateTool;
2287
- let isToolNameAvailable;
2288
- let suggestToolNames;
2345
+ // Use FlexibleToolValidator for consistent validation across SDK and toolRegistry
2289
2346
  try {
2290
- // Try ES module import first
2291
- const toolRegistrationModule = require("./sdk/toolRegistration.js");
2292
- ({ validateTool, isToolNameAvailable, suggestToolNames } =
2293
- toolRegistrationModule);
2347
+ const flexibleValidatorModule = require("./mcp/flexibleToolValidator.js");
2348
+ const FlexibleToolValidator = flexibleValidatorModule.FlexibleToolValidator;
2349
+ // Use the same validation logic as toolRegistry (static method)
2350
+ const validationResult = FlexibleToolValidator.validateToolName(name);
2351
+ if (!validationResult.isValid) {
2352
+ throw new Error(`Tool validation failed: ${validationResult.error}`);
2353
+ }
2294
2354
  }
2295
2355
  catch (error) {
2296
- // Fallback: skip validation if import fails (graceful degradation)
2297
- logger.warn("Tool validation module not available, skipping advanced validation", {
2356
+ // If FlexibleToolValidator import fails, use basic safety checks
2357
+ logger.warn("FlexibleToolValidator not available, using basic validation", {
2298
2358
  error: error instanceof Error ? error.message : String(error),
2299
2359
  });
2300
- // Create minimal validation functions
2301
- validateTool = () => { }; // No-op
2302
- isToolNameAvailable = () => true; // Allow all names
2303
- suggestToolNames = () => ["alternative_tool"];
2304
- }
2305
- // Check if tool name is available (not reserved)
2306
- if (!isToolNameAvailable(name)) {
2307
- const suggestions = suggestToolNames(name);
2308
- throw new Error(`Tool name '${name}' is not available (reserved or invalid format). ` +
2309
- `Suggested alternatives: ${suggestions.slice(0, 3).join(", ")}`);
2310
- }
2311
- // Create a simplified tool object for validation
2312
- const toolForValidation = {
2313
- description: tool.description || "",
2314
- execute: async (params) => {
2315
- if (tool.execute) {
2316
- const result = await tool.execute(params);
2317
- return result;
2318
- }
2319
- return "";
2320
- },
2321
- parameters: tool.inputSchema,
2322
- metadata: {
2323
- category: "custom",
2324
- },
2325
- };
2326
- // Use comprehensive validation logic
2327
- try {
2328
- validateTool(name, toolForValidation);
2329
- }
2330
- catch (error) {
2331
- throw new Error(`Tool registration failed: ${error instanceof Error ? error.message : String(error)}`);
2360
+ // Basic safety checks to prevent obvious issues
2361
+ if (name.trim() === "") {
2362
+ throw new Error("Tool name cannot be empty");
2363
+ }
2364
+ if (name.length > 100) {
2365
+ throw new Error("Tool name is too long (maximum 100 characters)");
2366
+ }
2367
+ // eslint-disable-next-line no-control-regex
2368
+ if (/[\x00-\x1F\x7F]/.test(name)) {
2369
+ throw new Error("Tool name contains invalid control characters");
2370
+ }
2332
2371
  }
2372
+ // --- End: Enhanced Validation Logic ---
2373
+ // Tool object validation is now handled by FlexibleToolValidator above
2374
+ // Proceed with tool registration since validation passed
2333
2375
  // SMART DEFAULTS: Use utility to eliminate boilerplate creation
2334
2376
  const mcpServerInfo = createCustomToolServerInfo(name, tool);
2335
2377
  // Register with toolRegistry using MCPServerInfo directly
@@ -2489,11 +2531,14 @@ export class NeuroLink {
2489
2531
  : params,
2490
2532
  hasExternalManager: !!this.externalServerManager,
2491
2533
  });
2492
- // Emit tool start event
2534
+ // Emit tool start event (NeuroLink format - keep existing)
2493
2535
  this.emitter.emit("tool:start", {
2494
2536
  toolName,
2495
2537
  timestamp: executionStartTime,
2538
+ input: params, // Enhanced: add input parameters
2496
2539
  });
2540
+ // ADD: Bedrock-compatible tool:start event (positional parameters)
2541
+ this.emitter.emit("tool:start", toolName, params);
2497
2542
  // Set default options
2498
2543
  const finalOptions = {
2499
2544
  timeout: options?.timeout || 30000, // 30 second default timeout
@@ -2519,13 +2564,15 @@ export class NeuroLink {
2519
2564
  });
2520
2565
  }
2521
2566
  const metrics = this.toolExecutionMetrics.get(toolName);
2522
- metrics.totalExecutions++;
2567
+ if (metrics) {
2568
+ metrics.totalExecutions++;
2569
+ }
2523
2570
  try {
2524
2571
  mcpLogger.debug(`[${functionTag}] Executing tool: ${toolName}`, {
2525
2572
  toolName,
2526
2573
  params,
2527
2574
  options: finalOptions,
2528
- circuitBreakerState: circuitBreaker.getState(),
2575
+ circuitBreakerState: circuitBreaker?.getState(),
2529
2576
  });
2530
2577
  // Execute with circuit breaker, timeout, and retry logic
2531
2578
  const result = await circuitBreaker.execute(async () => {
@@ -2546,12 +2593,14 @@ export class NeuroLink {
2546
2593
  });
2547
2594
  // Update success metrics
2548
2595
  const executionTime = Date.now() - executionStartTime;
2549
- metrics.successfulExecutions++;
2550
- metrics.lastExecutionTime = executionTime;
2551
- metrics.averageExecutionTime =
2552
- (metrics.averageExecutionTime * (metrics.successfulExecutions - 1) +
2553
- executionTime) /
2554
- metrics.successfulExecutions;
2596
+ if (metrics) {
2597
+ metrics.successfulExecutions++;
2598
+ metrics.lastExecutionTime = executionTime;
2599
+ metrics.averageExecutionTime =
2600
+ (metrics.averageExecutionTime * (metrics.successfulExecutions - 1) +
2601
+ executionTime) /
2602
+ metrics.successfulExecutions;
2603
+ }
2555
2604
  // Track memory usage
2556
2605
  const endMemory = MemoryManager.getMemoryUsageMB();
2557
2606
  const memoryDelta = endMemory.heapUsed - startMemory.heapUsed;
@@ -2566,15 +2615,17 @@ export class NeuroLink {
2566
2615
  toolName,
2567
2616
  executionTime,
2568
2617
  memoryDelta,
2569
- circuitBreakerState: circuitBreaker.getState(),
2618
+ circuitBreakerState: circuitBreaker?.getState(),
2570
2619
  });
2571
2620
  // Emit tool end event using the helper method
2572
- this.emitToolEndEvent(toolName, executionStartTime, true);
2621
+ this.emitToolEndEvent(toolName, executionStartTime, true, result);
2573
2622
  return result;
2574
2623
  }
2575
2624
  catch (error) {
2576
2625
  // Update failure metrics
2577
- metrics.failedExecutions++;
2626
+ if (metrics) {
2627
+ metrics.failedExecutions++;
2628
+ }
2578
2629
  const executionTime = Date.now() - executionStartTime;
2579
2630
  // Create structured error
2580
2631
  let structuredError;
@@ -2605,8 +2656,10 @@ export class NeuroLink {
2605
2656
  else {
2606
2657
  structuredError = ErrorFactory.toolExecutionFailed(toolName, new Error(String(error)));
2607
2658
  }
2659
+ // ADD: Centralized error event emission
2660
+ this.emitter.emit("error", structuredError);
2608
2661
  // Emit tool end event using the helper method
2609
- this.emitToolEndEvent(toolName, executionStartTime, false);
2662
+ this.emitToolEndEvent(toolName, executionStartTime, false, undefined, structuredError);
2610
2663
  // Add execution context to structured error
2611
2664
  structuredError = new NeuroLinkError({
2612
2665
  ...structuredError,
@@ -2615,8 +2668,8 @@ export class NeuroLink {
2615
2668
  executionTime,
2616
2669
  params,
2617
2670
  options: finalOptions,
2618
- circuitBreakerState: circuitBreaker.getState(),
2619
- circuitBreakerFailures: circuitBreaker.getFailureCount(),
2671
+ circuitBreakerState: circuitBreaker?.getState(),
2672
+ circuitBreakerFailures: circuitBreaker?.getFailureCount(),
2620
2673
  metrics: { ...metrics },
2621
2674
  },
2622
2675
  });
@@ -2667,9 +2720,21 @@ export class NeuroLink {
2667
2720
  userId: "neurolink-user",
2668
2721
  };
2669
2722
  const result = (await toolRegistry.executeTool(toolName, params, context));
2723
+ // ADD: Check if result indicates a failure and emit error event
2724
+ if (result &&
2725
+ typeof result === "object" &&
2726
+ "success" in result &&
2727
+ result.success === false) {
2728
+ const errorMessage = result.error || "Tool execution failed";
2729
+ const errorToEmit = new Error(errorMessage);
2730
+ this.emitter.emit("error", errorToEmit);
2731
+ }
2670
2732
  return result;
2671
2733
  }
2672
2734
  catch (error) {
2735
+ // ADD: Emergency error event emission (fallback)
2736
+ const errorToEmit = error instanceof Error ? error : new Error(String(error));
2737
+ this.emitter.emit("error", errorToEmit);
2673
2738
  // Check if tool was not found
2674
2739
  if (error instanceof Error && error.message.includes("not found")) {
2675
2740
  const availableTools = await this.getAllAvailableTools();
@@ -2841,6 +2906,9 @@ export class NeuroLink {
2841
2906
  }
2842
2907
  const { AIProviderFactory } = await import("./core/factory.js");
2843
2908
  const { hasProviderEnvVars } = await import("./utils/providerUtils.js");
2909
+ // Keep references to prevent unused variable warnings
2910
+ void AIProviderFactory;
2911
+ void hasProviderEnvVars;
2844
2912
  const providers = [
2845
2913
  "openai",
2846
2914
  "bedrock",
@@ -3103,7 +3171,7 @@ export class NeuroLink {
3103
3171
  const inMemoryServers = this.getInMemoryServers();
3104
3172
  if (inMemoryServers.has(serverId)) {
3105
3173
  const serverInfo = inMemoryServers.get(serverId);
3106
- return !!(serverInfo.tools && serverInfo.tools.length > 0);
3174
+ return !!(serverInfo?.tools && serverInfo.tools.length > 0);
3107
3175
  }
3108
3176
  // Test external MCP servers
3109
3177
  const externalServer = this.externalServerManager.getServer(serverId);
@@ -3610,7 +3678,7 @@ export class NeuroLink {
3610
3678
  * Convert JSON Schema to AI SDK compatible format
3611
3679
  * For now, we'll skip schema validation and let the AI SDK handle parameters dynamically
3612
3680
  */
3613
- convertJSONSchemaToAISDKFormat(inputSchema) {
3681
+ convertJSONSchemaToAISDKFormat(_inputSchema) {
3614
3682
  // The simplest approach: don't provide parameters schema
3615
3683
  // This lets the AI SDK handle the tool without schema validation
3616
3684
  // Tools will still work, they just won't have strict parameter validation
@@ -3,29 +3,70 @@ import { type LanguageModelV1 } from "ai";
3
3
  import type { AIProviderName } from "../core/types.js";
4
4
  import type { StreamOptions, StreamResult } from "../types/streamTypes.js";
5
5
  import { BaseProvider } from "../core/baseProvider.js";
6
+ import { AWSCredentialProvider } from "./aws/credentialProvider.js";
7
+ import { BedrockRuntimeClient } from "@aws-sdk/client-bedrock-runtime";
8
+ import type { AWSCredentialConfig } from "../types/providers.js";
9
+ import type { NeuroLink } from "../neurolink.js";
6
10
  /**
7
- * Amazon Bedrock Provider v2 - BaseProvider Implementation
11
+ * Amazon Bedrock Provider v3 - Enhanced Authentication Implementation
8
12
  *
9
- * PHASE 3.3: Simple BaseProvider wrap around existing @ai-sdk/amazon-bedrock implementation
13
+ * BEDROCK-MCP-CONNECTOR COMPATIBILITY: Complete AWS SDK credential chain support
10
14
  *
11
15
  * Features:
12
16
  * - Extends BaseProvider for shared functionality
13
- * - Preserves existing AWS credential configuration
14
- * - Maintains inference profile ARN support
15
- * - Uses pre-initialized Bedrock instance for efficiency
17
+ * - AWS SDK v3 defaultProvider credential chain (9 sources)
18
+ * - Dual access: AI SDK + Direct AWS SDK BedrockRuntimeClient
19
+ * - Full backward compatibility with existing configurations
16
20
  * - Enhanced error handling with setup guidance
21
+ * - Bedrock-MCP-Connector compatible authentication patterns
17
22
  */
18
23
  export declare class AmazonBedrockProvider extends BaseProvider {
24
+ private awsCredentialProvider;
25
+ private bedrockClient;
19
26
  private bedrock;
20
27
  private model;
21
- constructor(modelName?: string);
28
+ constructor(modelName?: string, credentialConfig?: AWSCredentialConfig, neurolink?: NeuroLink);
29
+ /**
30
+ * Legacy AWS configuration for backward compatibility
31
+ */
32
+ private createLegacyAWSConfig;
22
33
  protected getProviderName(): AIProviderName;
23
34
  protected getDefaultModel(): string;
24
35
  /**
25
36
  * Returns the Vercel AI SDK model instance for AWS Bedrock
26
37
  */
27
38
  protected getAISDKModel(): LanguageModelV1;
39
+ /**
40
+ * Get AWS SDK BedrockRuntimeClient for direct access (Bedrock-MCP-Connector compatibility)
41
+ * This provides the same direct AWS SDK access that Bedrock-MCP-Connector uses
42
+ */
43
+ getBedrockClient(): BedrockRuntimeClient;
44
+ /**
45
+ * Get AWS SDK BedrockRuntimeClient with proxy support ensured
46
+ * Use this method when proxy support is critical for the operation
47
+ */
48
+ getBedrockClientWithProxy(): Promise<BedrockRuntimeClient>;
49
+ /**
50
+ * Get AWS credential provider for advanced credential management
51
+ */
52
+ getCredentialProvider(): AWSCredentialProvider;
53
+ /**
54
+ * Ensure proxy support is configured for AWS SDK client if needed
55
+ */
56
+ private ensureProxySupport;
57
+ /**
58
+ * Test AWS credentials and Bedrock connectivity
59
+ * Useful for debugging authentication issues
60
+ */
61
+ testConnectivity(): Promise<{
62
+ credentialsValid: boolean;
63
+ bedrockAccessible: boolean;
64
+ credentialSource: string;
65
+ error?: string;
66
+ responseTime?: number;
67
+ }>;
28
68
  protected executeStream(options: StreamOptions, _analysisSchema?: ZodUnknownSchema): Promise<StreamResult>;
69
+ protected handleStreamError(error: unknown): Error;
29
70
  protected handleProviderError(error: unknown): Error;
30
71
  }
31
72
  export default AmazonBedrockProvider;