@juspay/neurolink 7.47.0 → 7.47.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 (48) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/core/baseProvider.d.ts +1 -1
  3. package/dist/core/baseProvider.js +3 -3
  4. package/dist/core/conversationMemoryManager.d.ts +1 -1
  5. package/dist/core/conversationMemoryManager.js +1 -1
  6. package/dist/core/redisConversationMemoryManager.d.ts +2 -2
  7. package/dist/core/redisConversationMemoryManager.js +15 -9
  8. package/dist/factories/providerRegistry.js +1 -1
  9. package/dist/lib/core/baseProvider.d.ts +1 -1
  10. package/dist/lib/core/baseProvider.js +3 -3
  11. package/dist/lib/core/conversationMemoryManager.d.ts +1 -1
  12. package/dist/lib/core/conversationMemoryManager.js +1 -1
  13. package/dist/lib/core/redisConversationMemoryManager.d.ts +2 -2
  14. package/dist/lib/core/redisConversationMemoryManager.js +15 -9
  15. package/dist/lib/factories/providerRegistry.js +1 -1
  16. package/dist/lib/neurolink.d.ts +6 -1
  17. package/dist/lib/neurolink.js +37 -33
  18. package/dist/lib/providers/anthropic.js +1 -1
  19. package/dist/lib/providers/anthropicBaseProvider.js +1 -1
  20. package/dist/lib/providers/azureOpenai.js +1 -1
  21. package/dist/lib/providers/googleAiStudio.js +1 -1
  22. package/dist/lib/providers/googleVertex.js +1 -1
  23. package/dist/lib/providers/huggingFace.js +1 -1
  24. package/dist/lib/providers/litellm.js +1 -1
  25. package/dist/lib/providers/mistral.js +1 -1
  26. package/dist/lib/providers/openAI.js +1 -1
  27. package/dist/lib/providers/openaiCompatible.js +1 -1
  28. package/dist/lib/utils/conversationMemory.d.ts +1 -1
  29. package/dist/lib/utils/conversationMemory.js +2 -2
  30. package/dist/lib/utils/conversationMemoryUtils.d.ts +1 -1
  31. package/dist/lib/utils/conversationMemoryUtils.js +2 -2
  32. package/dist/neurolink.d.ts +6 -1
  33. package/dist/neurolink.js +37 -33
  34. package/dist/providers/anthropic.js +1 -1
  35. package/dist/providers/anthropicBaseProvider.js +1 -1
  36. package/dist/providers/azureOpenai.js +1 -1
  37. package/dist/providers/googleAiStudio.js +1 -1
  38. package/dist/providers/googleVertex.js +1 -1
  39. package/dist/providers/huggingFace.js +1 -1
  40. package/dist/providers/litellm.js +1 -1
  41. package/dist/providers/mistral.js +1 -1
  42. package/dist/providers/openAI.js +1 -1
  43. package/dist/providers/openaiCompatible.js +1 -1
  44. package/dist/utils/conversationMemory.d.ts +1 -1
  45. package/dist/utils/conversationMemory.js +2 -2
  46. package/dist/utils/conversationMemoryUtils.d.ts +1 -1
  47. package/dist/utils/conversationMemoryUtils.js +2 -2
  48. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ ## [7.47.2](https://github.com/juspay/neurolink/compare/v7.47.1...v7.47.2) (2025-09-26)
2
+
3
+ ### Bug Fixes
4
+
5
+ - **(timestamp):** Incorrect timestamps being stored in redis ([2d66232](https://github.com/juspay/neurolink/commit/2d6623275bc4c1f5986957d476ddcf3933ba61e4))
6
+
7
+ ## [7.47.1](https://github.com/juspay/neurolink/compare/v7.47.0...v7.47.1) (2025-09-26)
8
+
9
+ ### Bug Fixes
10
+
11
+ - **(tools):** Unregistered tools getting called ([45fd67a](https://github.com/juspay/neurolink/commit/45fd67af418b5e458ce6a261a7891234a8d489b8))
12
+
1
13
  ## [7.47.0](https://github.com/juspay/neurolink/compare/v7.46.0...v7.47.0) (2025-09-25)
2
14
 
3
15
  ### Features
@@ -227,7 +227,7 @@ export declare abstract class BaseProvider implements AIProvider {
227
227
  /**
228
228
  * Check if tool executions should be stored and handle storage
229
229
  */
230
- protected handleToolExecutionStorage(toolCalls: unknown[], toolResults: unknown[], options: TextGenerationOptions | StreamOptions): Promise<void>;
230
+ protected handleToolExecutionStorage(toolCalls: unknown[], toolResults: unknown[], options: TextGenerationOptions | StreamOptions, currentTime: Date): Promise<void>;
231
231
  /**
232
232
  * Utility method to chunk large prompts into smaller pieces
233
233
  * @param prompt The prompt to chunk
@@ -300,7 +300,7 @@ export class BaseProvider {
300
300
  onStepFinish: ({ toolCalls, toolResults }) => {
301
301
  logger.info("Tool execution completed", { toolResults, toolCalls });
302
302
  // Handle tool execution storage
303
- this.handleToolExecutionStorage(toolCalls, toolResults, options).catch((error) => {
303
+ this.handleToolExecutionStorage(toolCalls, toolResults, options, new Date()).catch((error) => {
304
304
  logger.warn("[BaseProvider] Failed to store tool executions", {
305
305
  provider: this.providerName,
306
306
  error: error instanceof Error ? error.message : String(error),
@@ -1499,7 +1499,7 @@ export class BaseProvider {
1499
1499
  /**
1500
1500
  * Check if tool executions should be stored and handle storage
1501
1501
  */
1502
- async handleToolExecutionStorage(toolCalls, toolResults, options) {
1502
+ async handleToolExecutionStorage(toolCalls, toolResults, options, currentTime) {
1503
1503
  // Check if tools are not empty
1504
1504
  const hasToolData = (toolCalls && toolCalls.length > 0) ||
1505
1505
  (toolResults && toolResults.length > 0);
@@ -1515,7 +1515,7 @@ export class BaseProvider {
1515
1515
  const userId = options.context?.userId ||
1516
1516
  options.userId;
1517
1517
  try {
1518
- await this.neurolink.storeToolExecutions(sessionId, userId, toolCalls, toolResults);
1518
+ await this.neurolink.storeToolExecutions(sessionId, userId, toolCalls, toolResults, currentTime);
1519
1519
  }
1520
1520
  catch (error) {
1521
1521
  logger.warn("[BaseProvider] Failed to store tool executions", {
@@ -16,7 +16,7 @@ export declare class ConversationMemoryManager {
16
16
  * Store a conversation turn for a session
17
17
  * ULTRA-OPTIMIZED: Direct ChatMessage[] storage with zero conversion overhead
18
18
  */
19
- storeConversationTurn(sessionId: string, userId: string | undefined, userMessage: string, aiResponse: string): Promise<void>;
19
+ storeConversationTurn(sessionId: string, userId: string | undefined, userMessage: string, aiResponse: string, _startTimeStamp: Date | undefined): Promise<void>;
20
20
  /**
21
21
  * Build context messages for AI prompt injection (ULTRA-OPTIMIZED)
22
22
  * Returns pre-stored message array with zero conversion overhead
@@ -36,7 +36,7 @@ export class ConversationMemoryManager {
36
36
  * Store a conversation turn for a session
37
37
  * ULTRA-OPTIMIZED: Direct ChatMessage[] storage with zero conversion overhead
38
38
  */
39
- async storeConversationTurn(sessionId, userId, userMessage, aiResponse) {
39
+ async storeConversationTurn(sessionId, userId, userMessage, aiResponse, _startTimeStamp) {
40
40
  await this.ensureInitialized();
41
41
  try {
42
42
  // Get or create session
@@ -60,11 +60,11 @@ export declare class RedisConversationMemoryManager {
60
60
  result?: unknown;
61
61
  error?: string;
62
62
  [key: string]: unknown;
63
- }>): Promise<void>;
63
+ }>, currentTime?: Date): Promise<void>;
64
64
  /**
65
65
  * Store a conversation turn for a session
66
66
  */
67
- storeConversationTurn(sessionId: string, userId: string | undefined, userMessage: string, aiResponse: string): Promise<void>;
67
+ storeConversationTurn(sessionId: string, userId: string | undefined, userMessage: string, aiResponse: string, startTimeStamp: Date | undefined): Promise<void>;
68
68
  /**
69
69
  * Build context messages for AI prompt injection
70
70
  */
@@ -156,7 +156,7 @@ export class RedisConversationMemoryManager {
156
156
  /**
157
157
  * Store tool execution data for a session (temporarily to avoid race conditions)
158
158
  */
159
- async storeToolExecution(sessionId, userId, toolCalls, toolResults) {
159
+ async storeToolExecution(sessionId, userId, toolCalls, toolResults, currentTime) {
160
160
  logger.debug("[RedisConversationMemoryManager] Storing tool execution temporarily", {
161
161
  sessionId,
162
162
  userId,
@@ -168,8 +168,14 @@ export class RedisConversationMemoryManager {
168
168
  const pendingKey = `${sessionId}:${normalizedUserId}`;
169
169
  // Store tool execution data temporarily to prevent race conditions
170
170
  const pendingData = {
171
- toolCalls: toolCalls || [],
172
- toolResults: toolResults || [],
171
+ toolCalls: (toolCalls || []).map((call) => ({
172
+ ...call,
173
+ timestamp: currentTime,
174
+ })),
175
+ toolResults: (toolResults || []).map((result) => ({
176
+ ...result,
177
+ timestamp: currentTime,
178
+ })),
173
179
  timestamp: Date.now(),
174
180
  };
175
181
  // Check if there's existing pending data and merge
@@ -214,7 +220,7 @@ export class RedisConversationMemoryManager {
214
220
  /**
215
221
  * Store a conversation turn for a session
216
222
  */
217
- async storeConversationTurn(sessionId, userId, userMessage, aiResponse) {
223
+ async storeConversationTurn(sessionId, userId, userMessage, aiResponse, startTimeStamp) {
218
224
  logger.debug("[RedisConversationMemoryManager] Storing conversation turn", {
219
225
  sessionId,
220
226
  userId,
@@ -294,8 +300,8 @@ export class RedisConversationMemoryManager {
294
300
  title: "New Conversation", // Temporary title until generated
295
301
  sessionId,
296
302
  userId: normalizedUserId,
297
- createdAt: currentTime,
298
- updatedAt: currentTime,
303
+ createdAt: startTimeStamp?.toISOString() || currentTime,
304
+ updatedAt: startTimeStamp?.toISOString() || currentTime,
299
305
  messages: [],
300
306
  };
301
307
  }
@@ -312,7 +318,7 @@ export class RedisConversationMemoryManager {
312
318
  // Add new messages to conversation history with new format
313
319
  const userMsg = {
314
320
  id: this.generateMessageId(conversation),
315
- timestamp: this.generateTimestamp(),
321
+ timestamp: startTimeStamp?.toISOString() || this.generateTimestamp(),
316
322
  role: "user",
317
323
  content: userMessage,
318
324
  };
@@ -868,7 +874,7 @@ User message: "${userMessage}`;
868
874
  toolCallMap.set(toolCallId, toolName);
869
875
  const toolCallMessage = {
870
876
  id: this.generateMessageId(conversation),
871
- timestamp: this.generateTimestamp(),
877
+ timestamp: toolCall.timestamp?.toISOString() || this.generateTimestamp(),
872
878
  role: "tool_call",
873
879
  content: "", // Can be empty for tool calls
874
880
  tool: toolName,
@@ -885,7 +891,7 @@ User message: "${userMessage}`;
885
891
  const toolName = toolCallMap.get(toolCallId) || "unknown";
886
892
  const toolResultMessage = {
887
893
  id: this.generateMessageId(conversation),
888
- timestamp: this.generateTimestamp(),
894
+ timestamp: toolResult.timestamp?.toISOString() || this.generateTimestamp(),
889
895
  role: "tool_result",
890
896
  content: "", // Can be empty for tool results
891
897
  tool: toolName, // Now correctly extracted from tool call mapping
@@ -87,7 +87,7 @@ export class ProviderRegistry {
87
87
  // Register Amazon SageMaker provider
88
88
  ProviderFactory.registerProvider(AIProviderName.SAGEMAKER, async (modelName, _providerName, _sdk, region) => {
89
89
  const { AmazonSageMakerProvider } = await import("../providers/amazonSagemaker.js");
90
- return new AmazonSageMakerProvider(modelName, region);
90
+ return new AmazonSageMakerProvider(modelName, undefined, region);
91
91
  }, process.env.SAGEMAKER_MODEL || "sagemaker-model", ["sagemaker", "aws-sagemaker"]);
92
92
  logger.debug("All providers registered successfully");
93
93
  this.registered = true;
@@ -227,7 +227,7 @@ export declare abstract class BaseProvider implements AIProvider {
227
227
  /**
228
228
  * Check if tool executions should be stored and handle storage
229
229
  */
230
- protected handleToolExecutionStorage(toolCalls: unknown[], toolResults: unknown[], options: TextGenerationOptions | StreamOptions): Promise<void>;
230
+ protected handleToolExecutionStorage(toolCalls: unknown[], toolResults: unknown[], options: TextGenerationOptions | StreamOptions, currentTime: Date): Promise<void>;
231
231
  /**
232
232
  * Utility method to chunk large prompts into smaller pieces
233
233
  * @param prompt The prompt to chunk
@@ -300,7 +300,7 @@ export class BaseProvider {
300
300
  onStepFinish: ({ toolCalls, toolResults }) => {
301
301
  logger.info("Tool execution completed", { toolResults, toolCalls });
302
302
  // Handle tool execution storage
303
- this.handleToolExecutionStorage(toolCalls, toolResults, options).catch((error) => {
303
+ this.handleToolExecutionStorage(toolCalls, toolResults, options, new Date()).catch((error) => {
304
304
  logger.warn("[BaseProvider] Failed to store tool executions", {
305
305
  provider: this.providerName,
306
306
  error: error instanceof Error ? error.message : String(error),
@@ -1499,7 +1499,7 @@ export class BaseProvider {
1499
1499
  /**
1500
1500
  * Check if tool executions should be stored and handle storage
1501
1501
  */
1502
- async handleToolExecutionStorage(toolCalls, toolResults, options) {
1502
+ async handleToolExecutionStorage(toolCalls, toolResults, options, currentTime) {
1503
1503
  // Check if tools are not empty
1504
1504
  const hasToolData = (toolCalls && toolCalls.length > 0) ||
1505
1505
  (toolResults && toolResults.length > 0);
@@ -1515,7 +1515,7 @@ export class BaseProvider {
1515
1515
  const userId = options.context?.userId ||
1516
1516
  options.userId;
1517
1517
  try {
1518
- await this.neurolink.storeToolExecutions(sessionId, userId, toolCalls, toolResults);
1518
+ await this.neurolink.storeToolExecutions(sessionId, userId, toolCalls, toolResults, currentTime);
1519
1519
  }
1520
1520
  catch (error) {
1521
1521
  logger.warn("[BaseProvider] Failed to store tool executions", {
@@ -16,7 +16,7 @@ export declare class ConversationMemoryManager {
16
16
  * Store a conversation turn for a session
17
17
  * ULTRA-OPTIMIZED: Direct ChatMessage[] storage with zero conversion overhead
18
18
  */
19
- storeConversationTurn(sessionId: string, userId: string | undefined, userMessage: string, aiResponse: string): Promise<void>;
19
+ storeConversationTurn(sessionId: string, userId: string | undefined, userMessage: string, aiResponse: string, _startTimeStamp: Date | undefined): Promise<void>;
20
20
  /**
21
21
  * Build context messages for AI prompt injection (ULTRA-OPTIMIZED)
22
22
  * Returns pre-stored message array with zero conversion overhead
@@ -36,7 +36,7 @@ export class ConversationMemoryManager {
36
36
  * Store a conversation turn for a session
37
37
  * ULTRA-OPTIMIZED: Direct ChatMessage[] storage with zero conversion overhead
38
38
  */
39
- async storeConversationTurn(sessionId, userId, userMessage, aiResponse) {
39
+ async storeConversationTurn(sessionId, userId, userMessage, aiResponse, _startTimeStamp) {
40
40
  await this.ensureInitialized();
41
41
  try {
42
42
  // Get or create session
@@ -60,11 +60,11 @@ export declare class RedisConversationMemoryManager {
60
60
  result?: unknown;
61
61
  error?: string;
62
62
  [key: string]: unknown;
63
- }>): Promise<void>;
63
+ }>, currentTime?: Date): Promise<void>;
64
64
  /**
65
65
  * Store a conversation turn for a session
66
66
  */
67
- storeConversationTurn(sessionId: string, userId: string | undefined, userMessage: string, aiResponse: string): Promise<void>;
67
+ storeConversationTurn(sessionId: string, userId: string | undefined, userMessage: string, aiResponse: string, startTimeStamp: Date | undefined): Promise<void>;
68
68
  /**
69
69
  * Build context messages for AI prompt injection
70
70
  */
@@ -156,7 +156,7 @@ export class RedisConversationMemoryManager {
156
156
  /**
157
157
  * Store tool execution data for a session (temporarily to avoid race conditions)
158
158
  */
159
- async storeToolExecution(sessionId, userId, toolCalls, toolResults) {
159
+ async storeToolExecution(sessionId, userId, toolCalls, toolResults, currentTime) {
160
160
  logger.debug("[RedisConversationMemoryManager] Storing tool execution temporarily", {
161
161
  sessionId,
162
162
  userId,
@@ -168,8 +168,14 @@ export class RedisConversationMemoryManager {
168
168
  const pendingKey = `${sessionId}:${normalizedUserId}`;
169
169
  // Store tool execution data temporarily to prevent race conditions
170
170
  const pendingData = {
171
- toolCalls: toolCalls || [],
172
- toolResults: toolResults || [],
171
+ toolCalls: (toolCalls || []).map((call) => ({
172
+ ...call,
173
+ timestamp: currentTime,
174
+ })),
175
+ toolResults: (toolResults || []).map((result) => ({
176
+ ...result,
177
+ timestamp: currentTime,
178
+ })),
173
179
  timestamp: Date.now(),
174
180
  };
175
181
  // Check if there's existing pending data and merge
@@ -214,7 +220,7 @@ export class RedisConversationMemoryManager {
214
220
  /**
215
221
  * Store a conversation turn for a session
216
222
  */
217
- async storeConversationTurn(sessionId, userId, userMessage, aiResponse) {
223
+ async storeConversationTurn(sessionId, userId, userMessage, aiResponse, startTimeStamp) {
218
224
  logger.debug("[RedisConversationMemoryManager] Storing conversation turn", {
219
225
  sessionId,
220
226
  userId,
@@ -294,8 +300,8 @@ export class RedisConversationMemoryManager {
294
300
  title: "New Conversation", // Temporary title until generated
295
301
  sessionId,
296
302
  userId: normalizedUserId,
297
- createdAt: currentTime,
298
- updatedAt: currentTime,
303
+ createdAt: startTimeStamp?.toISOString() || currentTime,
304
+ updatedAt: startTimeStamp?.toISOString() || currentTime,
299
305
  messages: [],
300
306
  };
301
307
  }
@@ -312,7 +318,7 @@ export class RedisConversationMemoryManager {
312
318
  // Add new messages to conversation history with new format
313
319
  const userMsg = {
314
320
  id: this.generateMessageId(conversation),
315
- timestamp: this.generateTimestamp(),
321
+ timestamp: startTimeStamp?.toISOString() || this.generateTimestamp(),
316
322
  role: "user",
317
323
  content: userMessage,
318
324
  };
@@ -868,7 +874,7 @@ User message: "${userMessage}`;
868
874
  toolCallMap.set(toolCallId, toolName);
869
875
  const toolCallMessage = {
870
876
  id: this.generateMessageId(conversation),
871
- timestamp: this.generateTimestamp(),
877
+ timestamp: toolCall.timestamp?.toISOString() || this.generateTimestamp(),
872
878
  role: "tool_call",
873
879
  content: "", // Can be empty for tool calls
874
880
  tool: toolName,
@@ -885,7 +891,7 @@ User message: "${userMessage}`;
885
891
  const toolName = toolCallMap.get(toolCallId) || "unknown";
886
892
  const toolResultMessage = {
887
893
  id: this.generateMessageId(conversation),
888
- timestamp: this.generateTimestamp(),
894
+ timestamp: toolResult.timestamp?.toISOString() || this.generateTimestamp(),
889
895
  role: "tool_result",
890
896
  content: "", // Can be empty for tool results
891
897
  tool: toolName, // Now correctly extracted from tool call mapping
@@ -87,7 +87,7 @@ export class ProviderRegistry {
87
87
  // Register Amazon SageMaker provider
88
88
  ProviderFactory.registerProvider(AIProviderName.SAGEMAKER, async (modelName, _providerName, _sdk, region) => {
89
89
  const { AmazonSageMakerProvider } = await import("../providers/amazonSagemaker.js");
90
- return new AmazonSageMakerProvider(modelName, region);
90
+ return new AmazonSageMakerProvider(modelName, undefined, region);
91
91
  }, process.env.SAGEMAKER_MODEL || "sagemaker-model", ["sagemaker", "aws-sagemaker"]);
92
92
  logger.debug("All providers registered successfully");
93
93
  this.registered = true;
@@ -6,6 +6,7 @@
6
6
  * Uses real MCP infrastructure for tool discovery and execution.
7
7
  */
8
8
  import type { TextGenerationOptions, TextGenerationResult } from "./types/index.js";
9
+ import { MCPToolRegistry } from "./mcp/toolRegistry.js";
9
10
  import type { GenerateOptions, GenerateResult } from "./types/generateTypes.js";
10
11
  import type { StreamOptions, StreamResult } from "./types/streamTypes.js";
11
12
  import type { MCPServerInfo, MCPExecutableTool } from "./types/mcpTypes.js";
@@ -46,6 +47,7 @@ export interface MCPStatus {
46
47
  export declare class NeuroLink {
47
48
  private mcpInitialized;
48
49
  private emitter;
50
+ private toolRegistry;
49
51
  private autoDiscoveredServerInfos;
50
52
  private externalServerManager;
51
53
  private toolCache;
@@ -99,6 +101,7 @@ export declare class NeuroLink {
99
101
  * @param config.hitl.dangerousActions - Keywords that trigger confirmation (default: ['delete', 'remove', 'drop'])
100
102
  * @param config.hitl.timeout - Confirmation timeout in milliseconds (default: 30000)
101
103
  * @param config.hitl.allowArgumentModification - Allow users to modify tool parameters (default: true)
104
+ * @param config.toolRegistry - Optional tool registry instance for advanced use cases (default: new MCPToolRegistry())
102
105
  *
103
106
  * @example
104
107
  * ```typescript
@@ -139,6 +142,7 @@ export declare class NeuroLink {
139
142
  conversationMemory?: Partial<ConversationMemoryConfig>;
140
143
  enableOrchestration?: boolean;
141
144
  hitl?: HITLConfig;
145
+ toolRegistry?: MCPToolRegistry;
142
146
  });
143
147
  /**
144
148
  * Initialize provider registry with security settings
@@ -919,6 +923,7 @@ export declare class NeuroLink {
919
923
  * @param userId - User identifier (optional)
920
924
  * @param toolCalls - Array of tool calls
921
925
  * @param toolResults - Array of tool results
926
+ * @param currentTime - Date when the tool execution occurred (optional)
922
927
  * @returns Promise resolving when storage is complete
923
928
  */
924
929
  storeToolExecutions(sessionId: string, userId: string | undefined, toolCalls: Array<{
@@ -931,7 +936,7 @@ export declare class NeuroLink {
931
936
  result?: unknown;
932
937
  error?: string;
933
938
  [key: string]: unknown;
934
- }>): Promise<void>;
939
+ }>, currentTime?: Date): Promise<void>;
935
940
  /**
936
941
  * Check if tool execution storage is available
937
942
  * @returns boolean indicating if Redis storage is configured and available