@juspay/neurolink 7.33.4 → 7.35.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.
- package/CHANGELOG.md +15 -0
- package/README.md +101 -7
- package/dist/cli/commands/setup-anthropic.d.ts +16 -0
- package/dist/cli/commands/setup-anthropic.js +414 -0
- package/dist/cli/commands/setup-azure.d.ts +17 -0
- package/dist/cli/commands/setup-azure.js +415 -0
- package/dist/cli/commands/setup-bedrock.d.ts +13 -0
- package/dist/cli/commands/setup-bedrock.js +487 -0
- package/dist/cli/commands/setup-gcp.d.ts +18 -0
- package/dist/cli/commands/setup-gcp.js +569 -0
- package/dist/cli/commands/setup-google-ai.d.ts +16 -0
- package/dist/cli/commands/setup-google-ai.js +369 -0
- package/dist/cli/commands/setup-huggingface.d.ts +8 -0
- package/dist/cli/commands/setup-huggingface.js +200 -0
- package/dist/cli/commands/setup-mistral.d.ts +8 -0
- package/dist/cli/commands/setup-mistral.js +233 -0
- package/dist/cli/commands/setup-openai.d.ts +16 -0
- package/dist/cli/commands/setup-openai.js +402 -0
- package/dist/cli/commands/setup.d.ts +19 -0
- package/dist/cli/commands/setup.js +539 -0
- package/dist/cli/errorHandler.d.ts +1 -0
- package/dist/cli/errorHandler.js +28 -0
- package/dist/cli/factories/commandFactory.d.ts +27 -0
- package/dist/cli/factories/commandFactory.js +416 -60
- package/dist/cli/factories/ollamaCommandFactory.js +7 -1
- package/dist/cli/factories/setupCommandFactory.d.ts +18 -0
- package/dist/cli/factories/setupCommandFactory.js +137 -0
- package/dist/cli/index.d.ts +1 -1
- package/dist/cli/index.js +9 -164
- package/dist/cli/loop/optionsSchema.d.ts +15 -0
- package/dist/cli/loop/optionsSchema.js +59 -0
- package/dist/cli/loop/session.d.ts +15 -0
- package/dist/cli/loop/session.js +252 -0
- package/dist/cli/parser.d.ts +1 -0
- package/dist/cli/parser.js +161 -0
- package/dist/cli/utils/envManager.d.ts +3 -2
- package/dist/cli/utils/envManager.js +18 -4
- package/dist/cli/utils/ollamaUtils.js +6 -0
- package/dist/config/{conversationMemoryConfig.d.ts → conversationMemory.d.ts} +1 -1
- package/dist/core/baseProvider.js +17 -3
- package/dist/core/conversationMemoryFactory.d.ts +23 -0
- package/dist/core/conversationMemoryFactory.js +144 -0
- package/dist/core/conversationMemoryInitializer.d.ts +14 -0
- package/dist/core/conversationMemoryInitializer.js +127 -0
- package/dist/core/conversationMemoryManager.d.ts +3 -2
- package/dist/core/conversationMemoryManager.js +4 -3
- package/dist/core/redisConversationMemoryManager.d.ts +73 -0
- package/dist/core/redisConversationMemoryManager.js +483 -0
- package/dist/core/types.d.ts +1 -1
- package/dist/lib/config/{conversationMemoryConfig.d.ts → conversationMemory.d.ts} +1 -1
- package/dist/lib/core/baseProvider.js +17 -3
- package/dist/lib/core/conversationMemoryFactory.d.ts +23 -0
- package/dist/lib/core/conversationMemoryFactory.js +144 -0
- package/dist/lib/core/conversationMemoryInitializer.d.ts +14 -0
- package/dist/lib/core/conversationMemoryInitializer.js +127 -0
- package/dist/lib/core/conversationMemoryManager.d.ts +3 -2
- package/dist/lib/core/conversationMemoryManager.js +4 -3
- package/dist/lib/core/redisConversationMemoryManager.d.ts +73 -0
- package/dist/lib/core/redisConversationMemoryManager.js +483 -0
- package/dist/lib/core/types.d.ts +1 -1
- package/dist/lib/neurolink.d.ts +15 -9
- package/dist/lib/neurolink.js +218 -67
- package/dist/lib/providers/amazonBedrock.d.ts +4 -4
- package/dist/lib/providers/anthropic.d.ts +4 -4
- package/dist/lib/providers/azureOpenai.d.ts +4 -4
- package/dist/lib/providers/googleAiStudio.d.ts +4 -4
- package/dist/lib/providers/googleAiStudio.js +1 -1
- package/dist/lib/providers/huggingFace.d.ts +4 -4
- package/dist/lib/providers/litellm.d.ts +1 -1
- package/dist/lib/providers/mistral.d.ts +4 -4
- package/dist/lib/providers/mistral.js +2 -2
- package/dist/lib/providers/openAI.d.ts +4 -4
- package/dist/lib/session/globalSessionState.d.ts +27 -0
- package/dist/lib/session/globalSessionState.js +77 -0
- package/dist/lib/types/{conversationTypes.d.ts → conversation.d.ts} +32 -0
- package/dist/lib/types/generateTypes.d.ts +1 -1
- package/dist/lib/types/streamTypes.d.ts +1 -1
- package/dist/lib/utils/conversationMemory.d.ts +22 -0
- package/dist/lib/utils/conversationMemory.js +121 -0
- package/dist/lib/utils/conversationMemoryUtils.d.ts +1 -1
- package/dist/lib/utils/conversationMemoryUtils.js +2 -2
- package/dist/lib/utils/messageBuilder.d.ts +1 -1
- package/dist/lib/utils/messageBuilder.js +1 -1
- package/dist/lib/utils/redis.d.ts +42 -0
- package/dist/lib/utils/redis.js +263 -0
- package/dist/neurolink.d.ts +15 -9
- package/dist/neurolink.js +218 -67
- package/dist/providers/amazonBedrock.d.ts +4 -4
- package/dist/providers/anthropic.d.ts +4 -4
- package/dist/providers/azureOpenai.d.ts +4 -4
- package/dist/providers/googleAiStudio.d.ts +4 -4
- package/dist/providers/googleAiStudio.js +1 -1
- package/dist/providers/huggingFace.d.ts +4 -4
- package/dist/providers/litellm.d.ts +1 -1
- package/dist/providers/mistral.d.ts +4 -4
- package/dist/providers/mistral.js +2 -2
- package/dist/providers/openAI.d.ts +4 -4
- package/dist/session/globalSessionState.d.ts +27 -0
- package/dist/session/globalSessionState.js +77 -0
- package/dist/types/{conversationTypes.d.ts → conversation.d.ts} +32 -0
- package/dist/types/generateTypes.d.ts +1 -1
- package/dist/types/streamTypes.d.ts +1 -1
- package/dist/utils/conversationMemory.d.ts +22 -0
- package/dist/utils/conversationMemory.js +121 -0
- package/dist/utils/conversationMemoryUtils.d.ts +1 -1
- package/dist/utils/conversationMemoryUtils.js +2 -2
- package/dist/utils/messageBuilder.d.ts +1 -1
- package/dist/utils/messageBuilder.js +1 -1
- package/dist/utils/redis.d.ts +42 -0
- package/dist/utils/redis.js +263 -0
- package/package.json +3 -1
- /package/dist/config/{conversationMemoryConfig.js → conversationMemory.js} +0 -0
- /package/dist/lib/config/{conversationMemoryConfig.js → conversationMemory.js} +0 -0
- /package/dist/lib/types/{conversationTypes.js → conversation.js} +0 -0
- /package/dist/types/{conversationTypes.js → conversation.js} +0 -0
@@ -0,0 +1,263 @@
|
|
1
|
+
/**
|
2
|
+
* Redis Utilities for NeuroLink
|
3
|
+
* Helper functions for Redis storage operations
|
4
|
+
*/
|
5
|
+
import { createClient } from "redis";
|
6
|
+
import { logger } from "./logger.js";
|
7
|
+
// Redis client type
|
8
|
+
/**
|
9
|
+
* Creates a Redis client with the provided configuration
|
10
|
+
*/
|
11
|
+
export async function createRedisClient(config) {
|
12
|
+
const url = `redis://${config.host}:${config.port}/${config.db}`;
|
13
|
+
// Create client options
|
14
|
+
const clientOptions = {
|
15
|
+
url,
|
16
|
+
socket: {
|
17
|
+
connectTimeout: config.connectionOptions?.connectTimeout,
|
18
|
+
reconnectStrategy: (retries) => {
|
19
|
+
if (retries > (config.connectionOptions?.maxRetriesPerRequest || 3)) {
|
20
|
+
logger.error("Redis connection retries exhausted");
|
21
|
+
return new Error("Redis connection retries exhausted");
|
22
|
+
}
|
23
|
+
const delay = Math.min((config.connectionOptions?.retryDelayOnFailover || 100) *
|
24
|
+
Math.pow(2, retries), 10000);
|
25
|
+
return delay;
|
26
|
+
},
|
27
|
+
},
|
28
|
+
};
|
29
|
+
if (config.password) {
|
30
|
+
clientOptions.password = config.password;
|
31
|
+
}
|
32
|
+
// Create client with secured options
|
33
|
+
const client = createClient(clientOptions);
|
34
|
+
client.on("error", (err) => {
|
35
|
+
const sanitizedMessage = err.message.replace(/redis:\/\/.*?@/g, "redis://[redacted]@");
|
36
|
+
logger.error("Redis client error", { error: sanitizedMessage });
|
37
|
+
});
|
38
|
+
client.on("connect", () => {
|
39
|
+
logger.debug("Redis client connected", {
|
40
|
+
host: config.host,
|
41
|
+
port: config.port,
|
42
|
+
db: config.db,
|
43
|
+
});
|
44
|
+
});
|
45
|
+
client.on("reconnecting", () => {
|
46
|
+
logger.debug("Redis client reconnecting");
|
47
|
+
});
|
48
|
+
if (!client.isOpen) {
|
49
|
+
await client.connect();
|
50
|
+
}
|
51
|
+
return client;
|
52
|
+
}
|
53
|
+
/**
|
54
|
+
* Generates a Redis key for session messages
|
55
|
+
*/
|
56
|
+
export function getSessionKey(config, sessionId) {
|
57
|
+
const key = `${config.keyPrefix}${sessionId}`;
|
58
|
+
logger.debug("[redisUtils] Generated session key", {
|
59
|
+
sessionId,
|
60
|
+
keyPrefix: config.keyPrefix,
|
61
|
+
fullKey: key,
|
62
|
+
});
|
63
|
+
return key;
|
64
|
+
}
|
65
|
+
/**
|
66
|
+
* Serializes messages for Redis storage
|
67
|
+
*/
|
68
|
+
export function serializeMessages(messages) {
|
69
|
+
try {
|
70
|
+
logger.debug("[redisUtils] Serializing messages", {
|
71
|
+
messageCount: messages.length,
|
72
|
+
messageTypes: messages.map((m) => m.role),
|
73
|
+
firstMessage: messages.length > 0
|
74
|
+
? {
|
75
|
+
role: messages[0].role,
|
76
|
+
contentLength: messages[0].content.length,
|
77
|
+
contentPreview: messages[0].content.substring(0, 50),
|
78
|
+
}
|
79
|
+
: null,
|
80
|
+
lastMessage: messages.length > 0
|
81
|
+
? {
|
82
|
+
role: messages[messages.length - 1].role,
|
83
|
+
contentLength: messages[messages.length - 1].content.length,
|
84
|
+
contentPreview: messages[messages.length - 1].content.substring(0, 50),
|
85
|
+
}
|
86
|
+
: null,
|
87
|
+
});
|
88
|
+
const serialized = JSON.stringify(messages);
|
89
|
+
logger.debug("[redisUtils] Messages serialized successfully", {
|
90
|
+
serializedLength: serialized.length,
|
91
|
+
messageCount: messages.length,
|
92
|
+
});
|
93
|
+
return serialized;
|
94
|
+
}
|
95
|
+
catch (error) {
|
96
|
+
logger.error("[redisUtils] Failed to serialize messages", {
|
97
|
+
error: error instanceof Error ? error.message : String(error),
|
98
|
+
stack: error instanceof Error ? error.stack : undefined,
|
99
|
+
messageCount: messages.length,
|
100
|
+
});
|
101
|
+
throw error;
|
102
|
+
}
|
103
|
+
}
|
104
|
+
/**
|
105
|
+
* Deserializes messages from Redis storage
|
106
|
+
*/
|
107
|
+
export function deserializeMessages(data) {
|
108
|
+
if (!data) {
|
109
|
+
logger.debug("[redisUtils] No data to deserialize, returning empty array");
|
110
|
+
return [];
|
111
|
+
}
|
112
|
+
try {
|
113
|
+
logger.debug("[redisUtils] Deserializing messages", {
|
114
|
+
dataLength: data.length,
|
115
|
+
dataPreview: data.substring(0, 100) + (data.length > 100 ? "..." : ""),
|
116
|
+
});
|
117
|
+
// Parse as unknown first, then validate before casting
|
118
|
+
const parsedData = JSON.parse(data);
|
119
|
+
// Check if the parsed data is an array
|
120
|
+
if (!Array.isArray(parsedData)) {
|
121
|
+
logger.warn("[redisUtils] Deserialized data is not an array", {
|
122
|
+
type: typeof parsedData,
|
123
|
+
preview: JSON.stringify(parsedData).substring(0, 100),
|
124
|
+
});
|
125
|
+
return [];
|
126
|
+
}
|
127
|
+
// Validate each item in the array has the correct ChatMessage structure
|
128
|
+
const isValid = parsedData.every((m) => typeof m === "object" &&
|
129
|
+
m !== null &&
|
130
|
+
"role" in m &&
|
131
|
+
"content" in m &&
|
132
|
+
typeof m.role === "string" &&
|
133
|
+
typeof m.content === "string" &&
|
134
|
+
(m.role === "user" || m.role === "assistant" || m.role === "system"));
|
135
|
+
if (!isValid) {
|
136
|
+
logger.warn("[redisUtils] Deserialized data has unexpected structure", {
|
137
|
+
isArray: true,
|
138
|
+
firstItem: parsedData.length > 0 ? JSON.stringify(parsedData[0]) : null,
|
139
|
+
});
|
140
|
+
return [];
|
141
|
+
}
|
142
|
+
// Now that we've validated, we can safely cast
|
143
|
+
const messages = parsedData;
|
144
|
+
logger.debug("[redisUtils] Messages deserialized successfully", {
|
145
|
+
messageCount: messages.length,
|
146
|
+
messageTypes: messages.map((m) => m.role),
|
147
|
+
firstMessage: messages.length > 0
|
148
|
+
? {
|
149
|
+
role: messages[0].role,
|
150
|
+
contentLength: messages[0].content.length,
|
151
|
+
contentPreview: messages[0].content.substring(0, 50),
|
152
|
+
}
|
153
|
+
: null,
|
154
|
+
lastMessage: messages.length > 0
|
155
|
+
? {
|
156
|
+
role: messages[messages.length - 1].role,
|
157
|
+
contentLength: messages[messages.length - 1].content.length,
|
158
|
+
contentPreview: messages[messages.length - 1].content.substring(0, 50),
|
159
|
+
}
|
160
|
+
: null,
|
161
|
+
});
|
162
|
+
logger.debug("[deserializeMessages] completed");
|
163
|
+
return messages;
|
164
|
+
}
|
165
|
+
catch (error) {
|
166
|
+
logger.error("[redisUtils] Failed to deserialize messages", {
|
167
|
+
error: error instanceof Error ? error.message : String(error),
|
168
|
+
stack: error instanceof Error ? error.stack : undefined,
|
169
|
+
dataLength: data.length,
|
170
|
+
dataPreview: "[REDACTED]", // Prevent exposure of potentially sensitive data
|
171
|
+
});
|
172
|
+
return [];
|
173
|
+
}
|
174
|
+
}
|
175
|
+
/**
|
176
|
+
* Checks if Redis client is healthy
|
177
|
+
*/
|
178
|
+
export async function isRedisHealthy(client) {
|
179
|
+
try {
|
180
|
+
const pong = await client.ping();
|
181
|
+
return pong === "PONG";
|
182
|
+
}
|
183
|
+
catch (error) {
|
184
|
+
logger.error("Redis health check failed", { error });
|
185
|
+
return false;
|
186
|
+
}
|
187
|
+
}
|
188
|
+
/**
|
189
|
+
* Scan Redis keys matching a pattern without blocking the server
|
190
|
+
* This is a non-blocking alternative to the KEYS command
|
191
|
+
*
|
192
|
+
* @param client Redis client
|
193
|
+
* @param pattern Pattern to match keys (e.g. "prefix:*")
|
194
|
+
* @param batchSize Number of keys to scan in each iteration (default: 100)
|
195
|
+
* @returns Array of keys matching the pattern
|
196
|
+
*/
|
197
|
+
export async function scanKeys(client, pattern, batchSize = 100) {
|
198
|
+
logger.debug("[redisUtils] Starting SCAN operation", {
|
199
|
+
pattern,
|
200
|
+
batchSize,
|
201
|
+
});
|
202
|
+
const allKeys = [];
|
203
|
+
let cursor = "0";
|
204
|
+
let iterations = 0;
|
205
|
+
let totalScanned = 0;
|
206
|
+
try {
|
207
|
+
do {
|
208
|
+
iterations++;
|
209
|
+
// Use SCAN instead of KEYS to avoid blocking the server
|
210
|
+
const result = await client.scan(cursor, {
|
211
|
+
MATCH: pattern,
|
212
|
+
COUNT: batchSize,
|
213
|
+
});
|
214
|
+
// Extract cursor and keys from result
|
215
|
+
cursor = result.cursor;
|
216
|
+
const keys = result.keys || [];
|
217
|
+
// Add keys to result array
|
218
|
+
allKeys.push(...keys);
|
219
|
+
totalScanned += keys.length;
|
220
|
+
logger.debug("[redisUtils] SCAN iteration completed", {
|
221
|
+
iteration: iterations,
|
222
|
+
currentCursor: cursor,
|
223
|
+
keysInBatch: keys.length,
|
224
|
+
totalKeysFound: allKeys.length,
|
225
|
+
});
|
226
|
+
} while (cursor !== "0"); // Continue until cursor is 0
|
227
|
+
logger.info("[redisUtils] SCAN operation completed", {
|
228
|
+
pattern,
|
229
|
+
totalIterations: iterations,
|
230
|
+
totalKeysFound: allKeys.length,
|
231
|
+
totalScanned,
|
232
|
+
});
|
233
|
+
return allKeys;
|
234
|
+
}
|
235
|
+
catch (error) {
|
236
|
+
logger.error("[redisUtils] Error during SCAN operation", {
|
237
|
+
pattern,
|
238
|
+
error: error instanceof Error ? error.message : String(error),
|
239
|
+
stack: error instanceof Error ? error.stack : undefined,
|
240
|
+
});
|
241
|
+
throw error;
|
242
|
+
}
|
243
|
+
}
|
244
|
+
/**
|
245
|
+
* Get normalized Redis configuration with defaults
|
246
|
+
*/
|
247
|
+
export function getNormalizedConfig(config) {
|
248
|
+
return {
|
249
|
+
host: config.host || "localhost",
|
250
|
+
port: config.port || 6379,
|
251
|
+
password: config.password || "",
|
252
|
+
db: config.db || 0,
|
253
|
+
keyPrefix: config.keyPrefix || "neurolink:conversation:",
|
254
|
+
ttl: config.ttl || 86400,
|
255
|
+
connectionOptions: {
|
256
|
+
connectTimeout: 30000,
|
257
|
+
lazyConnect: true,
|
258
|
+
retryDelayOnFailover: 100,
|
259
|
+
maxRetriesPerRequest: 3,
|
260
|
+
...config.connectionOptions,
|
261
|
+
},
|
262
|
+
};
|
263
|
+
}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@juspay/neurolink",
|
3
|
-
"version": "7.
|
3
|
+
"version": "7.35.0",
|
4
4
|
"description": "Universal AI Development Platform with working MCP integration, multi-provider support, and professional CLI. Built-in tools operational, 58+ external MCP servers discoverable. Connect to filesystem, GitHub, database operations, and more. Build, test, and deploy AI applications with 9 major providers: OpenAI, Anthropic, Google AI, AWS Bedrock, Azure, Hugging Face, Ollama, and Mistral AI.",
|
5
5
|
"author": {
|
6
6
|
"name": "Juspay Technologies",
|
@@ -175,10 +175,12 @@
|
|
175
175
|
"dotenv": "^16.5.0",
|
176
176
|
"inquirer": "^9.2.15",
|
177
177
|
"mathjs": "^14.5.3",
|
178
|
+
"nanoid": "^5.1.5",
|
178
179
|
"ollama-ai-provider": "^1.2.0",
|
179
180
|
"ora": "^7.0.1",
|
180
181
|
"p-limit": "^6.2.0",
|
181
182
|
"reconnecting-eventsource": "^1.6.4",
|
183
|
+
"redis": "^5.8.2",
|
182
184
|
"undici": "^6.6.2",
|
183
185
|
"uuid": "^11.1.0",
|
184
186
|
"ws": "^8.18.3",
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|