@juspay/neurolink 7.37.1 → 7.38.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 (46) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/core/baseProvider.d.ts +4 -0
  3. package/dist/core/baseProvider.js +40 -0
  4. package/dist/core/redisConversationMemoryManager.d.ts +98 -15
  5. package/dist/core/redisConversationMemoryManager.js +665 -203
  6. package/dist/lib/core/baseProvider.d.ts +4 -0
  7. package/dist/lib/core/baseProvider.js +40 -0
  8. package/dist/lib/core/redisConversationMemoryManager.d.ts +98 -15
  9. package/dist/lib/core/redisConversationMemoryManager.js +665 -203
  10. package/dist/lib/neurolink.d.ts +33 -1
  11. package/dist/lib/neurolink.js +64 -0
  12. package/dist/lib/providers/anthropic.js +8 -0
  13. package/dist/lib/providers/anthropicBaseProvider.js +8 -0
  14. package/dist/lib/providers/azureOpenai.js +8 -0
  15. package/dist/lib/providers/googleAiStudio.js +8 -0
  16. package/dist/lib/providers/googleVertex.js +10 -0
  17. package/dist/lib/providers/huggingFace.js +8 -0
  18. package/dist/lib/providers/litellm.js +8 -0
  19. package/dist/lib/providers/mistral.js +8 -0
  20. package/dist/lib/providers/openAI.js +10 -0
  21. package/dist/lib/providers/openaiCompatible.js +8 -0
  22. package/dist/lib/types/conversation.d.ts +52 -2
  23. package/dist/lib/utils/conversationMemory.js +3 -1
  24. package/dist/lib/utils/messageBuilder.d.ts +10 -2
  25. package/dist/lib/utils/messageBuilder.js +22 -1
  26. package/dist/lib/utils/redis.d.ts +10 -6
  27. package/dist/lib/utils/redis.js +71 -70
  28. package/dist/neurolink.d.ts +33 -1
  29. package/dist/neurolink.js +64 -0
  30. package/dist/providers/anthropic.js +8 -0
  31. package/dist/providers/anthropicBaseProvider.js +8 -0
  32. package/dist/providers/azureOpenai.js +8 -0
  33. package/dist/providers/googleAiStudio.js +8 -0
  34. package/dist/providers/googleVertex.js +10 -0
  35. package/dist/providers/huggingFace.js +8 -0
  36. package/dist/providers/litellm.js +8 -0
  37. package/dist/providers/mistral.js +8 -0
  38. package/dist/providers/openAI.js +10 -0
  39. package/dist/providers/openaiCompatible.js +8 -0
  40. package/dist/types/conversation.d.ts +52 -2
  41. package/dist/utils/conversationMemory.js +3 -1
  42. package/dist/utils/messageBuilder.d.ts +10 -2
  43. package/dist/utils/messageBuilder.js +22 -1
  44. package/dist/utils/redis.d.ts +10 -6
  45. package/dist/utils/redis.js +71 -70
  46. package/package.json +1 -1
@@ -224,6 +224,10 @@ export declare abstract class BaseProvider implements AIProvider {
224
224
  * Get timeout value in milliseconds
225
225
  */
226
226
  getTimeout(options: TextGenerationOptions | StreamOptions): number;
227
+ /**
228
+ * Check if tool executions should be stored and handle storage
229
+ */
230
+ protected handleToolExecutionStorage(toolCalls: unknown[], toolResults: unknown[], options: TextGenerationOptions | StreamOptions): Promise<void>;
227
231
  /**
228
232
  * Utility method to chunk large prompts into smaller pieces
229
233
  * @param prompt The prompt to chunk
@@ -297,6 +297,16 @@ export class BaseProvider {
297
297
  toolChoice: shouldUseTools ? "auto" : "none",
298
298
  temperature: options.temperature,
299
299
  maxTokens: options.maxTokens,
300
+ onStepFinish: ({ toolCalls, toolResults }) => {
301
+ logger.info("Tool execution completed", { toolResults, toolCalls });
302
+ // Handle tool execution storage
303
+ this.handleToolExecutionStorage(toolCalls, toolResults, options).catch((error) => {
304
+ logger.warn("[BaseProvider] Failed to store tool executions", {
305
+ provider: this.providerName,
306
+ error: error instanceof Error ? error.message : String(error),
307
+ });
308
+ });
309
+ },
300
310
  });
301
311
  }
302
312
  /**
@@ -1470,6 +1480,36 @@ export class BaseProvider {
1470
1480
  }
1471
1481
  return this.defaultTimeout;
1472
1482
  }
1483
+ /**
1484
+ * Check if tool executions should be stored and handle storage
1485
+ */
1486
+ async handleToolExecutionStorage(toolCalls, toolResults, options) {
1487
+ // Check if tools are not empty
1488
+ const hasToolData = (toolCalls && toolCalls.length > 0) ||
1489
+ (toolResults && toolResults.length > 0);
1490
+ // Check if NeuroLink instance is available and has tool execution storage
1491
+ const hasStorageAvailable = this.neurolink?.isToolExecutionStorageAvailable();
1492
+ // Early return if storage is not available or no tool data
1493
+ if (!hasStorageAvailable || !hasToolData || !this.neurolink) {
1494
+ return;
1495
+ }
1496
+ const sessionId = options.context?.sessionId ||
1497
+ options.sessionId ||
1498
+ `session-${Date.now()}`;
1499
+ const userId = options.context?.userId ||
1500
+ options.userId;
1501
+ try {
1502
+ await this.neurolink.storeToolExecutions(sessionId, userId, toolCalls, toolResults);
1503
+ }
1504
+ catch (error) {
1505
+ logger.warn("[BaseProvider] Failed to store tool executions", {
1506
+ provider: this.providerName,
1507
+ sessionId,
1508
+ error: error instanceof Error ? error.message : String(error),
1509
+ });
1510
+ // Don't throw - tool storage failures shouldn't break generation
1511
+ }
1512
+ }
1473
1513
  /**
1474
1514
  * Utility method to chunk large prompts into smaller pieces
1475
1515
  * @param prompt The prompt to chunk
@@ -2,21 +2,65 @@
2
2
  * Redis Conversation Memory Manager for NeuroLink
3
3
  * Redis-based implementation of conversation storage with same interface as ConversationMemoryManager
4
4
  */
5
- import type { ConversationMemoryConfig, SessionMemory, ConversationMemoryStats, ChatMessage, RedisStorageConfig } from "../types/conversation.js";
6
- /**
7
- * Redis-based implementation of the ConversationMemoryManager
8
- * Uses the same interface but stores data in Redis
9
- */
5
+ import type { ConversationMemoryConfig, ConversationMemoryStats, ChatMessage, RedisStorageConfig, SessionMetadata, RedisConversationObject } from "../types/conversation.js";
10
6
  export declare class RedisConversationMemoryManager {
11
7
  config: ConversationMemoryConfig;
12
8
  private isInitialized;
13
9
  private redisConfig;
14
10
  private redisClient;
11
+ /**
12
+ * Temporary storage for tool execution data to prevent race conditions
13
+ * Key format: "${sessionId}:${userId}"
14
+ */
15
+ private pendingToolExecutions;
16
+ /**
17
+ * Track sessions currently generating titles to prevent race conditions
18
+ * Key format: "${sessionId}:${userId}"
19
+ */
20
+ private titleGenerationInProgress;
15
21
  constructor(config: ConversationMemoryConfig, redisConfig?: RedisStorageConfig);
16
22
  /**
17
23
  * Initialize the memory manager with Redis connection
18
24
  */
19
25
  initialize(): Promise<void>;
26
+ /**
27
+ * Get all sessions for a specific user
28
+ */
29
+ getUserSessions(userId: string): Promise<string[]>;
30
+ /**
31
+ * Add a session to user's session set (private method)
32
+ */
33
+ private addUserSession;
34
+ /**
35
+ * Remove a session from user's session set (private method)
36
+ */
37
+ private removeUserSession;
38
+ /**
39
+ * Generate next message ID for a conversation
40
+ */
41
+ private generateMessageId;
42
+ /**
43
+ * Generate current timestamp in ISO format
44
+ */
45
+ private generateTimestamp;
46
+ /**
47
+ * Generate a unique conversation ID using UUID v4
48
+ */
49
+ private generateUniqueId;
50
+ /**
51
+ * Store tool execution data for a session (temporarily to avoid race conditions)
52
+ */
53
+ storeToolExecution(sessionId: string, userId: string | undefined, toolCalls: Array<{
54
+ toolCallId?: string;
55
+ toolName?: string;
56
+ args?: Record<string, unknown>;
57
+ [key: string]: unknown;
58
+ }>, toolResults: Array<{
59
+ toolCallId?: string;
60
+ result?: unknown;
61
+ error?: string;
62
+ [key: string]: unknown;
63
+ }>): Promise<void>;
20
64
  /**
21
65
  * Store a conversation turn for a session
22
66
  */
@@ -24,11 +68,41 @@ export declare class RedisConversationMemoryManager {
24
68
  /**
25
69
  * Build context messages for AI prompt injection
26
70
  */
27
- buildContextMessages(sessionId: string): Promise<ChatMessage[]>;
71
+ buildContextMessages(sessionId: string, userId?: string): Promise<ChatMessage[]>;
72
+ /**
73
+ * Get session metadata for a specific user session (optimized for listing)
74
+ * Fetches only essential metadata without heavy message arrays
75
+ *
76
+ * @param userId The user identifier
77
+ * @param sessionId The session identifier
78
+ * @returns Session metadata or null if session doesn't exist
79
+ */
80
+ getUserSessionMetadata(userId: string, sessionId: string): Promise<SessionMetadata | null>;
81
+ /**
82
+ * Get conversation history for a specific user session
83
+ *
84
+ * @param userId The user identifier
85
+ * @param sessionId The session identifier
86
+ * @returns Array of chat messages or null if session doesn't exist
87
+ */
88
+ getUserSessionHistory(userId: string, sessionId: string): Promise<ChatMessage[] | null>;
89
+ /**
90
+ * Get the complete conversation object for a specific user session
91
+ *
92
+ * This method returns the full conversation object including title, metadata,
93
+ * timestamps, and all chat messages. Unlike getUserSessionHistory() which returns
94
+ * only the messages array, this method provides the complete conversation context.
95
+ *
96
+ * @param userId The user identifier who owns the session
97
+ * @param sessionId The unique session identifier
98
+ * @returns Complete conversation object with all data, or null if session doesn't exist
99
+ */
100
+ getUserSessionObject(userId: string, sessionId: string): Promise<RedisConversationObject | null>;
28
101
  /**
29
- * Get session data
102
+ * Generate a conversation title from the first user message
103
+ * Uses AI to create a concise, descriptive title (5-8 words)
30
104
  */
31
- getSession(sessionId: string): Promise<SessionMemory | undefined>;
105
+ generateConversationTitle(userMessage: string): Promise<string>;
32
106
  /**
33
107
  * Create summary system message
34
108
  */
@@ -44,23 +118,32 @@ export declare class RedisConversationMemoryManager {
44
118
  /**
45
119
  * Clear a specific session
46
120
  */
47
- clearSession(sessionId: string): Promise<boolean>;
121
+ clearSession(sessionId: string, userId?: string): Promise<boolean>;
48
122
  /**
49
123
  * Clear all sessions
50
124
  */
51
125
  clearAllSessions(): Promise<void>;
52
126
  /**
53
- * Summarize messages for a session
127
+ * Ensure Redis client is initialized
54
128
  */
55
- private _summarizeMessages;
129
+ private ensureInitialized;
56
130
  /**
57
- * Create summarization prompt
131
+ * Get session metadata for all sessions of a user (optimized for listing)
132
+ * Returns only essential metadata without heavy message arrays
133
+ *
134
+ * @param userId The user identifier
135
+ * @returns Array of session metadata objects
58
136
  */
59
- private _createSummarizationPrompt;
137
+ getUserAllSessionsHistory(userId: string): Promise<SessionMetadata[]>;
60
138
  /**
61
- * Ensure Redis client is initialized
139
+ * Clean up stale pending tool execution data
140
+ * Removes data older than 5 minutes to prevent memory leaks
62
141
  */
63
- private ensureInitialized;
142
+ private cleanupStalePendingData;
143
+ /**
144
+ * Flush pending tool execution data for a session and merge into conversation
145
+ */
146
+ private flushPendingToolData;
64
147
  /**
65
148
  * Enforce session limit
66
149
  *