@juspay/neurolink 3.0.1 → 4.1.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 (232) hide show
  1. package/CHANGELOG.md +66 -6
  2. package/README.md +318 -27
  3. package/dist/agent/direct-tools.d.ts +6 -6
  4. package/dist/chat/client-utils.d.ts +92 -0
  5. package/dist/chat/client-utils.js +298 -0
  6. package/dist/chat/index.d.ts +27 -0
  7. package/dist/chat/index.js +41 -0
  8. package/dist/chat/session-storage.d.ts +77 -0
  9. package/dist/chat/session-storage.js +233 -0
  10. package/dist/chat/session.d.ts +95 -0
  11. package/dist/chat/session.js +257 -0
  12. package/dist/chat/sse-handler.d.ts +49 -0
  13. package/dist/chat/sse-handler.js +266 -0
  14. package/dist/chat/types.d.ts +73 -0
  15. package/dist/chat/types.js +5 -0
  16. package/dist/chat/websocket-chat-handler.d.ts +36 -0
  17. package/dist/chat/websocket-chat-handler.js +262 -0
  18. package/dist/cli/commands/config.js +12 -12
  19. package/dist/cli/commands/mcp.js +3 -4
  20. package/dist/cli/index.d.ts +0 -7
  21. package/dist/cli/index.js +247 -28
  22. package/dist/config/configManager.d.ts +60 -0
  23. package/dist/config/configManager.js +300 -0
  24. package/dist/config/types.d.ts +136 -0
  25. package/dist/config/types.js +43 -0
  26. package/dist/core/analytics.d.ts +23 -0
  27. package/dist/core/analytics.js +131 -0
  28. package/dist/core/constants.d.ts +41 -0
  29. package/dist/core/constants.js +50 -0
  30. package/dist/core/defaults.d.ts +18 -0
  31. package/dist/core/defaults.js +29 -0
  32. package/dist/core/evaluation-config.d.ts +29 -0
  33. package/dist/core/evaluation-config.js +144 -0
  34. package/dist/core/evaluation-providers.d.ts +30 -0
  35. package/dist/core/evaluation-providers.js +187 -0
  36. package/dist/core/evaluation.d.ts +117 -0
  37. package/dist/core/evaluation.js +528 -0
  38. package/dist/core/factory.js +33 -25
  39. package/dist/core/types.d.ts +165 -6
  40. package/dist/core/types.js +3 -4
  41. package/dist/index.d.ts +9 -4
  42. package/dist/index.js +25 -4
  43. package/dist/lib/agent/direct-tools.d.ts +6 -6
  44. package/dist/lib/chat/client-utils.d.ts +92 -0
  45. package/dist/lib/chat/client-utils.js +298 -0
  46. package/dist/lib/chat/index.d.ts +27 -0
  47. package/dist/lib/chat/index.js +41 -0
  48. package/dist/lib/chat/session-storage.d.ts +77 -0
  49. package/dist/lib/chat/session-storage.js +233 -0
  50. package/dist/lib/chat/session.d.ts +95 -0
  51. package/dist/lib/chat/session.js +257 -0
  52. package/dist/lib/chat/sse-handler.d.ts +49 -0
  53. package/dist/lib/chat/sse-handler.js +266 -0
  54. package/dist/lib/chat/types.d.ts +73 -0
  55. package/dist/lib/chat/types.js +5 -0
  56. package/dist/lib/chat/websocket-chat-handler.d.ts +36 -0
  57. package/dist/lib/chat/websocket-chat-handler.js +262 -0
  58. package/dist/lib/config/configManager.d.ts +60 -0
  59. package/dist/lib/config/configManager.js +300 -0
  60. package/dist/lib/config/types.d.ts +136 -0
  61. package/dist/lib/config/types.js +43 -0
  62. package/dist/lib/core/analytics.d.ts +23 -0
  63. package/dist/lib/core/analytics.js +131 -0
  64. package/dist/lib/core/constants.d.ts +41 -0
  65. package/dist/lib/core/constants.js +50 -0
  66. package/dist/lib/core/defaults.d.ts +18 -0
  67. package/dist/lib/core/defaults.js +29 -0
  68. package/dist/lib/core/evaluation-config.d.ts +29 -0
  69. package/dist/lib/core/evaluation-config.js +144 -0
  70. package/dist/lib/core/evaluation-providers.d.ts +30 -0
  71. package/dist/lib/core/evaluation-providers.js +187 -0
  72. package/dist/lib/core/evaluation.d.ts +117 -0
  73. package/dist/lib/core/evaluation.js +528 -0
  74. package/dist/lib/core/factory.js +33 -26
  75. package/dist/lib/core/types.d.ts +165 -6
  76. package/dist/lib/core/types.js +3 -4
  77. package/dist/lib/index.d.ts +9 -4
  78. package/dist/lib/index.js +25 -4
  79. package/dist/lib/mcp/contracts/mcpContract.d.ts +118 -0
  80. package/dist/lib/mcp/contracts/mcpContract.js +5 -0
  81. package/dist/lib/mcp/dynamic-chain-executor.d.ts +201 -0
  82. package/dist/lib/mcp/dynamic-chain-executor.js +489 -0
  83. package/dist/lib/mcp/dynamic-orchestrator.d.ts +109 -0
  84. package/dist/lib/mcp/dynamic-orchestrator.js +351 -0
  85. package/dist/lib/mcp/error-manager.d.ts +254 -0
  86. package/dist/lib/mcp/error-manager.js +501 -0
  87. package/dist/lib/mcp/error-recovery.d.ts +158 -0
  88. package/dist/lib/mcp/error-recovery.js +405 -0
  89. package/dist/lib/mcp/function-calling.js +11 -3
  90. package/dist/lib/mcp/health-monitor.d.ts +256 -0
  91. package/dist/lib/mcp/health-monitor.js +621 -0
  92. package/dist/lib/mcp/logging.js +5 -0
  93. package/dist/lib/mcp/neurolink-mcp-client.js +2 -1
  94. package/dist/lib/mcp/orchestrator.d.ts +136 -5
  95. package/dist/lib/mcp/orchestrator.js +332 -16
  96. package/dist/lib/mcp/registry.d.ts +71 -16
  97. package/dist/lib/mcp/registry.js +104 -6
  98. package/dist/lib/mcp/semaphore-manager.d.ts +137 -0
  99. package/dist/lib/mcp/semaphore-manager.js +329 -0
  100. package/dist/lib/mcp/servers/ai-providers/ai-workflow-tools.d.ts +2 -2
  101. package/dist/lib/mcp/servers/ai-providers/ai-workflow-tools.js +5 -4
  102. package/dist/lib/mcp/session-manager.d.ts +186 -0
  103. package/dist/lib/mcp/session-manager.js +400 -0
  104. package/dist/lib/mcp/session-persistence.d.ts +93 -0
  105. package/dist/lib/mcp/session-persistence.js +298 -0
  106. package/dist/lib/mcp/tool-integration.js +1 -1
  107. package/dist/lib/mcp/tool-registry.d.ts +55 -34
  108. package/dist/lib/mcp/tool-registry.js +111 -97
  109. package/dist/lib/mcp/transport-manager.d.ts +153 -0
  110. package/dist/lib/mcp/transport-manager.js +330 -0
  111. package/dist/lib/mcp/unified-mcp.js +6 -1
  112. package/dist/lib/mcp/unified-registry.d.ts +54 -5
  113. package/dist/lib/mcp/unified-registry.js +139 -6
  114. package/dist/lib/neurolink.d.ts +101 -0
  115. package/dist/lib/neurolink.js +147 -1
  116. package/dist/lib/providers/agent-enhanced-provider.d.ts +11 -2
  117. package/dist/lib/providers/agent-enhanced-provider.js +86 -15
  118. package/dist/lib/providers/amazonBedrock.d.ts +9 -1
  119. package/dist/lib/providers/amazonBedrock.js +26 -2
  120. package/dist/lib/providers/analytics-helper.d.ts +53 -0
  121. package/dist/lib/providers/analytics-helper.js +151 -0
  122. package/dist/lib/providers/anthropic.d.ts +11 -1
  123. package/dist/lib/providers/anthropic.js +29 -4
  124. package/dist/lib/providers/azureOpenAI.d.ts +3 -1
  125. package/dist/lib/providers/azureOpenAI.js +28 -4
  126. package/dist/lib/providers/function-calling-provider.d.ts +9 -1
  127. package/dist/lib/providers/function-calling-provider.js +14 -1
  128. package/dist/lib/providers/googleAIStudio.d.ts +15 -1
  129. package/dist/lib/providers/googleAIStudio.js +32 -2
  130. package/dist/lib/providers/googleVertexAI.d.ts +9 -1
  131. package/dist/lib/providers/googleVertexAI.js +31 -2
  132. package/dist/lib/providers/huggingFace.d.ts +3 -1
  133. package/dist/lib/providers/huggingFace.js +26 -3
  134. package/dist/lib/providers/mcp-provider.d.ts +9 -1
  135. package/dist/lib/providers/mcp-provider.js +12 -0
  136. package/dist/lib/providers/mistralAI.d.ts +3 -1
  137. package/dist/lib/providers/mistralAI.js +25 -2
  138. package/dist/lib/providers/ollama.d.ts +3 -1
  139. package/dist/lib/providers/ollama.js +27 -4
  140. package/dist/lib/providers/openAI.d.ts +15 -1
  141. package/dist/lib/providers/openAI.js +32 -2
  142. package/dist/lib/proxy/proxy-fetch.js +8 -7
  143. package/dist/lib/services/streaming/streaming-manager.d.ts +29 -0
  144. package/dist/lib/services/streaming/streaming-manager.js +244 -0
  145. package/dist/lib/services/types.d.ts +155 -0
  146. package/dist/lib/services/types.js +2 -0
  147. package/dist/lib/services/websocket/websocket-server.d.ts +34 -0
  148. package/dist/lib/services/websocket/websocket-server.js +304 -0
  149. package/dist/lib/telemetry/index.d.ts +15 -0
  150. package/dist/lib/telemetry/index.js +22 -0
  151. package/dist/lib/telemetry/telemetry-service.d.ts +47 -0
  152. package/dist/lib/telemetry/telemetry-service.js +259 -0
  153. package/dist/lib/utils/streaming-utils.d.ts +67 -0
  154. package/dist/lib/utils/streaming-utils.js +201 -0
  155. package/dist/mcp/contracts/mcpContract.d.ts +118 -0
  156. package/dist/mcp/contracts/mcpContract.js +5 -0
  157. package/dist/mcp/dynamic-chain-executor.d.ts +201 -0
  158. package/dist/mcp/dynamic-chain-executor.js +489 -0
  159. package/dist/mcp/dynamic-orchestrator.d.ts +109 -0
  160. package/dist/mcp/dynamic-orchestrator.js +351 -0
  161. package/dist/mcp/error-manager.d.ts +254 -0
  162. package/dist/mcp/error-manager.js +501 -0
  163. package/dist/mcp/error-recovery.d.ts +158 -0
  164. package/dist/mcp/error-recovery.js +405 -0
  165. package/dist/mcp/function-calling.js +11 -3
  166. package/dist/mcp/health-monitor.d.ts +256 -0
  167. package/dist/mcp/health-monitor.js +621 -0
  168. package/dist/mcp/logging.js +5 -0
  169. package/dist/mcp/neurolink-mcp-client.js +2 -1
  170. package/dist/mcp/orchestrator.d.ts +136 -5
  171. package/dist/mcp/orchestrator.js +332 -16
  172. package/dist/mcp/plugins/core/neurolink-mcp.json +15 -15
  173. package/dist/mcp/registry.d.ts +71 -16
  174. package/dist/mcp/registry.js +104 -6
  175. package/dist/mcp/semaphore-manager.d.ts +137 -0
  176. package/dist/mcp/semaphore-manager.js +329 -0
  177. package/dist/mcp/servers/ai-providers/ai-workflow-tools.d.ts +2 -2
  178. package/dist/mcp/servers/ai-providers/ai-workflow-tools.js +5 -4
  179. package/dist/mcp/session-manager.d.ts +186 -0
  180. package/dist/mcp/session-manager.js +400 -0
  181. package/dist/mcp/session-persistence.d.ts +93 -0
  182. package/dist/mcp/session-persistence.js +299 -0
  183. package/dist/mcp/tool-integration.js +1 -1
  184. package/dist/mcp/tool-registry.d.ts +55 -34
  185. package/dist/mcp/tool-registry.js +111 -97
  186. package/dist/mcp/transport-manager.d.ts +153 -0
  187. package/dist/mcp/transport-manager.js +331 -0
  188. package/dist/mcp/unified-mcp.js +6 -1
  189. package/dist/mcp/unified-registry.d.ts +54 -5
  190. package/dist/mcp/unified-registry.js +139 -6
  191. package/dist/neurolink.d.ts +101 -0
  192. package/dist/neurolink.js +147 -1
  193. package/dist/providers/agent-enhanced-provider.d.ts +11 -2
  194. package/dist/providers/agent-enhanced-provider.js +86 -15
  195. package/dist/providers/amazonBedrock.d.ts +9 -1
  196. package/dist/providers/amazonBedrock.js +26 -2
  197. package/dist/providers/analytics-helper.d.ts +53 -0
  198. package/dist/providers/analytics-helper.js +151 -0
  199. package/dist/providers/anthropic.d.ts +11 -1
  200. package/dist/providers/anthropic.js +29 -4
  201. package/dist/providers/azureOpenAI.d.ts +3 -1
  202. package/dist/providers/azureOpenAI.js +29 -4
  203. package/dist/providers/function-calling-provider.d.ts +9 -1
  204. package/dist/providers/function-calling-provider.js +14 -1
  205. package/dist/providers/googleAIStudio.d.ts +15 -1
  206. package/dist/providers/googleAIStudio.js +32 -2
  207. package/dist/providers/googleVertexAI.d.ts +9 -1
  208. package/dist/providers/googleVertexAI.js +31 -2
  209. package/dist/providers/huggingFace.d.ts +3 -1
  210. package/dist/providers/huggingFace.js +26 -3
  211. package/dist/providers/mcp-provider.d.ts +9 -1
  212. package/dist/providers/mcp-provider.js +12 -0
  213. package/dist/providers/mistralAI.d.ts +3 -1
  214. package/dist/providers/mistralAI.js +25 -2
  215. package/dist/providers/ollama.d.ts +3 -1
  216. package/dist/providers/ollama.js +27 -4
  217. package/dist/providers/openAI.d.ts +15 -1
  218. package/dist/providers/openAI.js +33 -2
  219. package/dist/proxy/proxy-fetch.js +8 -7
  220. package/dist/services/streaming/streaming-manager.d.ts +29 -0
  221. package/dist/services/streaming/streaming-manager.js +244 -0
  222. package/dist/services/types.d.ts +155 -0
  223. package/dist/services/types.js +2 -0
  224. package/dist/services/websocket/websocket-server.d.ts +34 -0
  225. package/dist/services/websocket/websocket-server.js +304 -0
  226. package/dist/telemetry/index.d.ts +15 -0
  227. package/dist/telemetry/index.js +22 -0
  228. package/dist/telemetry/telemetry-service.d.ts +47 -0
  229. package/dist/telemetry/telemetry-service.js +261 -0
  230. package/dist/utils/streaming-utils.d.ts +67 -0
  231. package/dist/utils/streaming-utils.js +201 -0
  232. package/package.json +245 -228
@@ -0,0 +1,299 @@
1
+ /**
2
+ * NeuroLink Session Persistence Layer
3
+ * Provides file-based persistence for sessions with atomic writes and recovery
4
+ */
5
+ import fs from "fs/promises";
6
+ import path from "path";
7
+ import crypto from "crypto";
8
+ import { existsSync } from "fs";
9
+ /**
10
+ * Session Persistence Manager
11
+ * Handles saving and loading sessions to/from disk with recovery mechanisms
12
+ */
13
+ export class SessionPersistence {
14
+ directory;
15
+ snapshotInterval;
16
+ retentionPeriod;
17
+ enableChecksum;
18
+ maxRetries;
19
+ snapshotTimer = null;
20
+ sessionMap;
21
+ constructor(sessionMap, options = {}) {
22
+ this.sessionMap = sessionMap;
23
+ this.directory = options.directory || ".neurolink/sessions";
24
+ this.snapshotInterval = options.snapshotInterval || 30000; // 30 seconds
25
+ this.retentionPeriod = options.retentionPeriod || 86400000; // 24 hours
26
+ this.enableChecksum = options.enableChecksum ?? true;
27
+ this.maxRetries = options.maxRetries || 3;
28
+ }
29
+ /**
30
+ * Initialize persistence layer
31
+ */
32
+ async initialize() {
33
+ // Create sessions directory if it doesn't exist
34
+ await this.ensureDirectory();
35
+ // Load existing sessions
36
+ await this.loadSessions();
37
+ // Start snapshot timer
38
+ this.startSnapshotTimer();
39
+ if (process.env.NEUROLINK_DEBUG === "true") {
40
+ console.log(`[SessionPersistence] Initialized with directory: ${this.directory}`);
41
+ }
42
+ }
43
+ /**
44
+ * Ensure sessions directory exists
45
+ */
46
+ async ensureDirectory() {
47
+ await fs.mkdir(this.directory, { recursive: true });
48
+ }
49
+ /**
50
+ * Calculate checksum for data integrity
51
+ */
52
+ calculateChecksum(data) {
53
+ return crypto.createHash("sha256").update(data).digest("hex");
54
+ }
55
+ /**
56
+ * Serialize session to JSON with metadata
57
+ */
58
+ serializeSession(session) {
59
+ // Convert Map to array for JSON serialization
60
+ const sessionData = {
61
+ ...session,
62
+ state: Array.from(session.state.entries()),
63
+ };
64
+ let fileData = {
65
+ session: sessionData,
66
+ checksum: "",
67
+ version: "1.0",
68
+ lastSaved: Date.now(),
69
+ };
70
+ if (this.enableChecksum) {
71
+ // First serialization without checksum
72
+ const tempJsonData = JSON.stringify(fileData, null, 2);
73
+ // Calculate checksum based on the first serialization
74
+ fileData.checksum = this.calculateChecksum(tempJsonData);
75
+ }
76
+ // Final serialization with checksum included
77
+ return JSON.stringify(fileData, null, 2);
78
+ }
79
+ /**
80
+ * Deserialize session from JSON
81
+ */
82
+ deserializeSession(data) {
83
+ try {
84
+ const fileData = JSON.parse(data);
85
+ // Verify checksum if enabled
86
+ if (this.enableChecksum && fileData.checksum) {
87
+ const tempData = { ...fileData, checksum: "" };
88
+ const expectedChecksum = this.calculateChecksum(JSON.stringify(tempData, null, 2));
89
+ if (fileData.checksum !== expectedChecksum) {
90
+ console.error("[SessionPersistence] Checksum mismatch, session corrupted");
91
+ return null;
92
+ }
93
+ }
94
+ // Convert state array back to Map
95
+ const session = fileData.session;
96
+ session.state = new Map(session.state);
97
+ return session;
98
+ }
99
+ catch (error) {
100
+ console.error("[SessionPersistence] Failed to deserialize session:", error);
101
+ return null;
102
+ }
103
+ }
104
+ /**
105
+ * Save single session with atomic write
106
+ */
107
+ async saveSession(sessionId, session) {
108
+ const filename = `${sessionId}.json`;
109
+ const filepath = path.join(this.directory, filename);
110
+ const tempPath = `${filepath}.tmp`;
111
+ let retries = 0;
112
+ while (retries < this.maxRetries) {
113
+ try {
114
+ // Serialize session
115
+ const data = this.serializeSession(session);
116
+ // Write to temporary file first (atomic write pattern)
117
+ await fs.writeFile(tempPath, data, "utf8");
118
+ // Rename temp file to final location (atomic operation)
119
+ await fs.rename(tempPath, filepath);
120
+ if (process.env.NEUROLINK_DEBUG === "true") {
121
+ console.log(`[SessionPersistence] Saved session ${sessionId}`);
122
+ }
123
+ return true;
124
+ }
125
+ catch (error) {
126
+ retries++;
127
+ console.error(`[SessionPersistence] Failed to save session (attempt ${retries}):`, error);
128
+ // Clean up temp file if it exists
129
+ try {
130
+ await fs.unlink(tempPath);
131
+ }
132
+ catch {
133
+ // Ignore errors when cleaning up temp file
134
+ }
135
+ if (retries < this.maxRetries) {
136
+ // Exponential backoff
137
+ await new Promise((resolve) => setTimeout(resolve, Math.pow(2, retries) * 100));
138
+ }
139
+ }
140
+ }
141
+ return false;
142
+ }
143
+ /**
144
+ * Load single session from disk
145
+ */
146
+ async loadSession(sessionId) {
147
+ const filename = `${sessionId}.json`;
148
+ const filepath = path.join(this.directory, filename);
149
+ try {
150
+ const data = await fs.readFile(filepath, "utf8");
151
+ return this.deserializeSession(data);
152
+ }
153
+ catch (error) {
154
+ if (error.code !== "ENOENT") {
155
+ console.error(`[SessionPersistence] Failed to load session ${sessionId}:`, error);
156
+ }
157
+ return null;
158
+ }
159
+ }
160
+ /**
161
+ * Load all sessions from disk on startup
162
+ */
163
+ async loadSessions() {
164
+ try {
165
+ const files = await fs.readdir(this.directory);
166
+ const sessionFiles = files.filter((f) => f.endsWith(".json"));
167
+ let loaded = 0;
168
+ let expired = 0;
169
+ for (const file of sessionFiles) {
170
+ const sessionId = file.replace(".json", "");
171
+ const session = await this.loadSession(sessionId);
172
+ if (session) {
173
+ // Check if session is expired
174
+ if (session.expiresAt < Date.now()) {
175
+ expired++;
176
+ // Clean up expired session file
177
+ await this.deleteSession(sessionId);
178
+ }
179
+ else {
180
+ // Restore to memory
181
+ this.sessionMap.set(sessionId, session);
182
+ loaded++;
183
+ }
184
+ }
185
+ }
186
+ console.log(`[SessionPersistence] Loaded ${loaded} sessions, cleaned ${expired} expired sessions`);
187
+ }
188
+ catch (error) {
189
+ console.error("[SessionPersistence] Failed to load sessions:", error);
190
+ }
191
+ }
192
+ /**
193
+ * Save all active sessions (snapshot)
194
+ */
195
+ async saveAllSessions() {
196
+ const sessions = Array.from(this.sessionMap.entries());
197
+ // Filter out expired sessions and create save promises
198
+ const savePromises = sessions
199
+ .filter(([_, session]) => session.expiresAt >= Date.now())
200
+ .map(async ([sessionId, session]) => {
201
+ return (await this.saveSession(sessionId, session)) ? 1 : 0;
202
+ });
203
+ // Execute all save operations concurrently
204
+ const results = await Promise.all(savePromises);
205
+ const saved = results.reduce((sum, result) => sum + result, 0);
206
+ if (process.env.NEUROLINK_DEBUG === "true") {
207
+ console.log(`[SessionPersistence] Snapshot: saved ${saved}/${sessions.length} sessions`);
208
+ }
209
+ }
210
+ /**
211
+ * Delete session file
212
+ */
213
+ async deleteSession(sessionId) {
214
+ const filename = `${sessionId}.json`;
215
+ const filepath = path.join(this.directory, filename);
216
+ try {
217
+ await fs.unlink(filepath);
218
+ // Keep memory and disk state in sync
219
+ this.sessionMap.delete(sessionId);
220
+ }
221
+ catch (error) {
222
+ if (error.code !== "ENOENT") {
223
+ console.error(`[SessionPersistence] Failed to delete session ${sessionId}:`, error);
224
+ }
225
+ }
226
+ }
227
+ /**
228
+ * Clean up old session files
229
+ */
230
+ async cleanupOldSessions() {
231
+ try {
232
+ const files = await fs.readdir(this.directory);
233
+ const now = Date.now();
234
+ let cleaned = 0;
235
+ for (const file of files) {
236
+ if (!file.endsWith(".json")) {
237
+ continue;
238
+ }
239
+ const filepath = path.join(this.directory, file);
240
+ const stats = await fs.stat(filepath);
241
+ // Remove files older than retention period
242
+ if (now - stats.mtimeMs > this.retentionPeriod) {
243
+ await fs.unlink(filepath);
244
+ cleaned++;
245
+ }
246
+ }
247
+ if (cleaned > 0) {
248
+ console.log(`[SessionPersistence] Cleaned up ${cleaned} old session files`);
249
+ }
250
+ }
251
+ catch (error) {
252
+ console.error("[SessionPersistence] Cleanup failed:", error);
253
+ }
254
+ }
255
+ /**
256
+ * Start periodic snapshot timer
257
+ */
258
+ startSnapshotTimer() {
259
+ if (this.snapshotTimer) {
260
+ clearInterval(this.snapshotTimer);
261
+ }
262
+ this.snapshotTimer = setInterval(async () => {
263
+ await this.saveAllSessions();
264
+ await this.cleanupOldSessions();
265
+ }, this.snapshotInterval);
266
+ }
267
+ /**
268
+ * Stop snapshot timer
269
+ */
270
+ stopSnapshotTimer() {
271
+ if (this.snapshotTimer) {
272
+ clearInterval(this.snapshotTimer);
273
+ this.snapshotTimer = null;
274
+ }
275
+ }
276
+ /**
277
+ * Shutdown persistence layer
278
+ */
279
+ async shutdown() {
280
+ this.stopSnapshotTimer();
281
+ // Final snapshot before shutdown
282
+ await this.saveAllSessions();
283
+ console.log("[SessionPersistence] Shutdown complete");
284
+ }
285
+ }
286
+ /**
287
+ * Default session persistence instance
288
+ */
289
+ export let defaultSessionPersistence = null;
290
+ /**
291
+ * Initialize default session persistence
292
+ */
293
+ export async function initializeSessionPersistence(sessionMap, options) {
294
+ if (!defaultSessionPersistence) {
295
+ defaultSessionPersistence = new SessionPersistence(sessionMap, options);
296
+ await defaultSessionPersistence.initialize();
297
+ }
298
+ return defaultSessionPersistence;
299
+ }
@@ -93,7 +93,7 @@ export class MCPToolIntegration {
93
93
  results.push({
94
94
  name: toolInfo.name,
95
95
  description: toolInfo.description || "No description available",
96
- serverId: toolInfo.server || "unknown",
96
+ serverId: toolInfo.serverId || "unknown",
97
97
  relevance,
98
98
  });
99
99
  }
@@ -1,40 +1,38 @@
1
1
  /**
2
2
  * MCP Tool Registry - Extended Registry with Tool Management
3
+ * Updated to match industry standard camelCase interfaces
3
4
  */
4
- import type { ExecutionContext } from "./contracts/mcp-contract.js";
5
+ import type { ExecutionContext, ToolInfo } from "./contracts/mcpContract.js";
5
6
  import type { ToolResult } from "./factory.js";
6
7
  import { MCPRegistry } from "./registry.js";
7
- export interface ToolInfo {
8
- id: string;
9
- name: string;
10
- description?: string;
11
- inputSchema?: any;
12
- outputSchema?: any;
13
- serverId: string;
14
- source: "manual" | "auto" | "default";
15
- isImplemented?: boolean;
16
- server?: string;
17
- }
18
8
  export type ToolExecutionResult = ToolResult;
9
+ /**
10
+ * Tool execution options
11
+ */
12
+ export interface ToolExecutionOptions {
13
+ timeout?: number;
14
+ retries?: number;
15
+ context?: ExecutionContext;
16
+ preferredSource?: string;
17
+ fallbackEnabled?: boolean;
18
+ validateBeforeExecution?: boolean;
19
+ timeoutMs?: number;
20
+ }
19
21
  export declare class MCPToolRegistry extends MCPRegistry {
20
22
  private tools;
21
23
  private toolExecutionStats;
22
24
  /**
23
- * Register a server with its tools
24
- */
25
- registerServer(serverId: string, serverInfo: any): Promise<void>;
26
- /**
27
- * Unregister a server and its tools
25
+ * Register a server with its tools (updated signature)
28
26
  */
29
- unregisterServer(serverId: string): Promise<void>;
27
+ registerServer(serverId: string, serverConfig?: unknown, context?: ExecutionContext): Promise<void>;
30
28
  /**
31
- * Execute a tool
29
+ * Execute a tool with enhanced context
32
30
  */
33
- executeTool(toolName: string, args: any, context: ExecutionContext): Promise<ToolExecutionResult>;
31
+ executeTool<T = unknown>(toolName: string, args?: unknown, context?: ExecutionContext): Promise<T>;
34
32
  /**
35
- * List all available tools
33
+ * List all available tools (updated signature)
36
34
  */
37
- listTools(): Promise<ToolInfo[]>;
35
+ listTools(context?: ExecutionContext): Promise<ToolInfo[]>;
38
36
  /**
39
37
  * Get tool information
40
38
  */
@@ -44,23 +42,46 @@ export declare class MCPToolRegistry extends MCPRegistry {
44
42
  */
45
43
  private updateStats;
46
44
  /**
47
- * Get tool execution statistics
45
+ * Get execution statistics
48
46
  */
49
- getToolStats(toolName?: string): any;
47
+ getExecutionStats(): Record<string, {
48
+ count: number;
49
+ averageTime: number;
50
+ totalTime: number;
51
+ }>;
50
52
  /**
51
- * Get tool execution statistics
53
+ * Clear execution statistics
52
54
  */
53
- getStats(): Promise<any>;
55
+ clearStats(): void;
54
56
  /**
55
- * Clear all tools and stats
57
+ * Get tools by category
56
58
  */
57
- clear(): void;
59
+ getToolsByCategory(category: string): ToolInfo[];
60
+ /**
61
+ * Check if tool exists
62
+ */
63
+ hasTool(toolName: string): boolean;
64
+ /**
65
+ * Remove a tool
66
+ */
67
+ removeTool(toolName: string): boolean;
68
+ /**
69
+ * Get tool count
70
+ */
71
+ getToolCount(): number;
72
+ /**
73
+ * Get statistics (alias for getExecutionStats)
74
+ */
75
+ getStats(): Record<string, {
76
+ count: number;
77
+ averageTime: number;
78
+ totalTime: number;
79
+ }>;
80
+ /**
81
+ * Unregister a server
82
+ */
83
+ unregisterServer(serverId: string): boolean;
58
84
  }
59
85
  export declare const toolRegistry: MCPToolRegistry;
60
86
  export declare const defaultToolRegistry: MCPToolRegistry;
61
- export interface ToolExecutionOptions {
62
- preferredSource?: string;
63
- fallbackEnabled?: boolean;
64
- validateBeforeExecution?: boolean;
65
- timeoutMs?: number;
66
- }
87
+ export type { ToolInfo } from "./contracts/mcpContract.js";
@@ -1,5 +1,6 @@
1
1
  /**
2
2
  * MCP Tool Registry - Extended Registry with Tool Management
3
+ * Updated to match industry standard camelCase interfaces
3
4
  */
4
5
  import { MCPRegistry } from "./registry.js";
5
6
  import { registryLogger } from "./logging.js";
@@ -7,91 +8,74 @@ export class MCPToolRegistry extends MCPRegistry {
7
8
  tools = new Map();
8
9
  toolExecutionStats = new Map();
9
10
  /**
10
- * Register a server with its tools
11
+ * Register a server with its tools (updated signature)
11
12
  */
12
- async registerServer(serverId, serverInfo) {
13
+ async registerServer(serverId, serverConfig, context) {
13
14
  registryLogger.info(`Registering server: ${serverId}`);
15
+ // Convert to DiscoveredMcp format for compatibility
16
+ const plugin = {
17
+ metadata: {
18
+ name: serverId,
19
+ description: typeof serverConfig === "object" && serverConfig
20
+ ? serverConfig.description || "No description"
21
+ : "No description",
22
+ },
23
+ tools: typeof serverConfig === "object" && serverConfig
24
+ ? serverConfig.tools
25
+ : {},
26
+ configuration: typeof serverConfig === "object" && serverConfig
27
+ ? serverConfig
28
+ : {},
29
+ };
30
+ // Call the parent register method
31
+ this.register(plugin);
14
32
  // Extract tools from server info if available
15
- if (serverInfo.tools) {
16
- for (const [toolName, toolDef] of Object.entries(serverInfo.tools)) {
17
- const toolId = `${serverId}.${toolName}`;
18
- this.tools.set(toolId, {
19
- id: toolId,
20
- name: toolName,
21
- description: toolDef.description,
22
- inputSchema: toolDef.inputSchema,
23
- outputSchema: toolDef.outputSchema,
24
- serverId,
25
- server: serverId, // Backward compatibility alias
26
- source: "manual",
27
- isImplemented: true,
28
- });
29
- }
30
- }
31
- }
32
- /**
33
- * Unregister a server and its tools
34
- */
35
- async unregisterServer(serverId) {
36
- registryLogger.info(`Unregistering server: ${serverId}`);
37
- // Remove all tools for this server
38
- for (const [toolId, toolInfo] of this.tools) {
39
- if (toolInfo.serverId === serverId) {
40
- this.tools.delete(toolId);
41
- this.toolExecutionStats.delete(toolId);
42
- }
33
+ const tools = plugin.tools || {};
34
+ for (const [toolName, toolDef] of Object.entries(tools)) {
35
+ const toolId = `${serverId}.${toolName}`;
36
+ this.tools.set(toolId, {
37
+ name: toolName,
38
+ description: toolDef?.description,
39
+ inputSchema: toolDef?.inputSchema,
40
+ outputSchema: toolDef?.outputSchema,
41
+ serverId,
42
+ category: toolDef?.category || "general",
43
+ });
43
44
  }
44
45
  }
45
46
  /**
46
- * Execute a tool
47
+ * Execute a tool with enhanced context
47
48
  */
48
49
  async executeTool(toolName, args, context) {
49
50
  const startTime = Date.now();
50
51
  try {
51
- const toolInfo = this.getToolInfo(toolName);
52
- if (!toolInfo) {
53
- throw new Error(`Tool not found: ${toolName}`);
54
- }
55
52
  registryLogger.info(`Executing tool: ${toolName}`);
56
- // Get the plugin that provides this tool
57
- const plugin = this.get(toolInfo.serverId);
58
- if (!plugin) {
59
- throw new Error(`Plugin not found for tool: ${toolName}`);
60
- }
61
- // Execute through the plugin (stub implementation)
62
- const result = {
63
- success: true,
64
- data: `Tool ${toolInfo.name} executed with args: ${JSON.stringify(args)}`,
53
+ // Create execution context if not provided
54
+ const execContext = {
55
+ sessionId: context?.sessionId || crypto.randomUUID(),
56
+ userId: context?.userId,
57
+ ...context,
65
58
  };
66
- const executionTime = Date.now() - startTime;
67
- this.updateStats(toolName, executionTime);
68
- return {
69
- success: true,
70
- data: result,
71
- metadata: {
72
- toolName,
73
- executionTime,
74
- timestamp: Date.now(),
75
- },
59
+ // Mock execution for now
60
+ const result = {
61
+ result: `Mock execution of ${toolName}`,
62
+ args,
63
+ context: execContext,
76
64
  };
65
+ // Update statistics
66
+ const duration = Date.now() - startTime;
67
+ this.updateStats(toolName, duration);
68
+ return result;
77
69
  }
78
70
  catch (error) {
79
71
  registryLogger.error(`Tool execution failed: ${toolName}`, error);
80
- return {
81
- success: false,
82
- error: error instanceof Error ? error : new Error(String(error)),
83
- metadata: {
84
- toolName,
85
- executionTime: Date.now() - startTime,
86
- timestamp: Date.now(),
87
- },
88
- };
72
+ throw error;
89
73
  }
90
74
  }
91
75
  /**
92
- * List all available tools
76
+ * List all available tools (updated signature)
93
77
  */
94
- async listTools() {
78
+ async listTools(context) {
95
79
  return Array.from(this.tools.values());
96
80
  }
97
81
  /**
@@ -108,53 +92,83 @@ export class MCPToolRegistry extends MCPRegistry {
108
92
  count: 0,
109
93
  totalTime: 0,
110
94
  };
111
- stats.count++;
95
+ stats.count += 1;
112
96
  stats.totalTime += executionTime;
113
97
  this.toolExecutionStats.set(toolName, stats);
114
98
  }
115
99
  /**
116
- * Get tool execution statistics
100
+ * Get execution statistics
117
101
  */
118
- getToolStats(toolName) {
119
- if (toolName) {
120
- const stats = this.toolExecutionStats.get(toolName);
121
- return stats
122
- ? {
123
- ...stats,
124
- averageTime: stats.totalTime / stats.count,
125
- }
126
- : null;
127
- }
128
- // Return all stats
129
- const allStats = {};
130
- for (const [tool, stats] of this.toolExecutionStats) {
131
- allStats[tool] = {
132
- ...stats,
102
+ getExecutionStats() {
103
+ const result = {};
104
+ for (const [toolName, stats] of this.toolExecutionStats.entries()) {
105
+ result[toolName] = {
106
+ count: stats.count,
107
+ totalTime: stats.totalTime,
133
108
  averageTime: stats.totalTime / stats.count,
134
109
  };
135
110
  }
136
- return allStats;
111
+ return result;
137
112
  }
138
113
  /**
139
- * Get tool execution statistics
114
+ * Clear execution statistics
140
115
  */
141
- async getStats() {
142
- const tools = await this.listTools();
143
- return {
144
- totalTools: tools.length,
145
- totalExecutions: Array.from(this.toolExecutionStats.values()).reduce((acc, stats) => acc + stats.count, 0),
146
- };
116
+ clearStats() {
117
+ this.toolExecutionStats.clear();
147
118
  }
148
119
  /**
149
- * Clear all tools and stats
120
+ * Get tools by category
150
121
  */
151
- clear() {
152
- super.clear();
153
- this.tools.clear();
154
- this.toolExecutionStats.clear();
122
+ getToolsByCategory(category) {
123
+ return Array.from(this.tools.values()).filter((tool) => tool.category === category);
124
+ }
125
+ /**
126
+ * Check if tool exists
127
+ */
128
+ hasTool(toolName) {
129
+ return this.tools.has(toolName);
130
+ }
131
+ /**
132
+ * Remove a tool
133
+ */
134
+ removeTool(toolName) {
135
+ const removed = this.tools.delete(toolName);
136
+ if (removed) {
137
+ this.toolExecutionStats.delete(toolName);
138
+ registryLogger.info(`Removed tool: ${toolName}`);
139
+ }
140
+ return removed;
141
+ }
142
+ /**
143
+ * Get tool count
144
+ */
145
+ getToolCount() {
146
+ return this.tools.size;
147
+ }
148
+ /**
149
+ * Get statistics (alias for getExecutionStats)
150
+ */
151
+ getStats() {
152
+ return this.getExecutionStats();
153
+ }
154
+ /**
155
+ * Unregister a server
156
+ */
157
+ unregisterServer(serverId) {
158
+ // Remove all tools for this server
159
+ const removedTools = [];
160
+ for (const [toolId, tool] of this.tools.entries()) {
161
+ if (tool.serverId === serverId) {
162
+ this.tools.delete(toolId);
163
+ removedTools.push(toolId);
164
+ }
165
+ }
166
+ // Remove from parent registry
167
+ const removed = this.unregister(serverId);
168
+ registryLogger.info(`Unregistered server ${serverId}, removed ${removedTools.length} tools`);
169
+ return removed;
155
170
  }
156
171
  }
157
- // Export singleton instance
172
+ // Create default instance
158
173
  export const toolRegistry = new MCPToolRegistry();
159
- // Additional exports for backward compatibility
160
174
  export const defaultToolRegistry = toolRegistry;