@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,329 @@
1
+ /**
2
+ * NeuroLink MCP Semaphore Manager
3
+ * Prevents race conditions in concurrent tool executions using a robust semaphore pattern
4
+ * Based on proven patterns from 1MCP reference implementation
5
+ */
6
+ /**
7
+ * Semaphore Manager for concurrent operation control
8
+ * Implements the proven semaphore pattern from 1MCP to prevent race conditions
9
+ */
10
+ export class SemaphoreManager {
11
+ locks = new Map();
12
+ queues = new Map();
13
+ stats = new Map();
14
+ globalStats = {
15
+ activeOperations: 0,
16
+ queuedOperations: 0,
17
+ totalOperations: 0,
18
+ totalWaitTime: 0,
19
+ averageWaitTime: 0,
20
+ peakQueueDepth: 0,
21
+ lastActivity: Date.now(),
22
+ };
23
+ /**
24
+ * Acquire a semaphore and execute an operation
25
+ * Ensures exclusive access to resources identified by the key
26
+ *
27
+ * @param key Unique identifier for the resource
28
+ * @param operation Async operation to execute with exclusive access
29
+ * @param context Optional execution context for enhanced tracking
30
+ * @returns Result of the operation with timing metrics
31
+ */
32
+ async acquire(key, operation, context) {
33
+ const startTime = Date.now();
34
+ let waitTime = 0;
35
+ let executionTime = 0;
36
+ let queueDepth = 0;
37
+ // Get or create queue for this key
38
+ const queue = this.queues.get(key) || [];
39
+ queueDepth = queue.length;
40
+ // Check if there's an active lock
41
+ const existingLock = this.locks.get(key);
42
+ if (existingLock) {
43
+ // Add to queue and wait
44
+ queueDepth++;
45
+ this.updateQueueDepth(key, queueDepth);
46
+ const waitPromise = new Promise((resolve, reject) => {
47
+ queue.push({ resolve, reject });
48
+ this.queues.set(key, queue);
49
+ });
50
+ if (process.env.NEUROLINK_DEBUG === "true") {
51
+ console.log(`[Semaphore] Operation waiting in queue for key: ${key} (depth: ${queueDepth})`);
52
+ }
53
+ // Wait for existing lock and our turn in queue
54
+ await existingLock;
55
+ await waitPromise;
56
+ waitTime = Date.now() - startTime;
57
+ }
58
+ // Create new lock for this operation
59
+ let lockResolve;
60
+ const lockPromise = new Promise((resolve) => {
61
+ lockResolve = resolve;
62
+ });
63
+ this.locks.set(key, lockPromise);
64
+ // Update statistics
65
+ this.incrementActiveOperations(key);
66
+ // Execute the operation
67
+ const executionStartTime = Date.now();
68
+ if (process.env.NEUROLINK_DEBUG === "true") {
69
+ console.log(`[Semaphore] Executing operation for key: ${key}`);
70
+ }
71
+ try {
72
+ const result = await operation();
73
+ executionTime = Math.max(1, Date.now() - executionStartTime); // Ensure at least 1ms
74
+ // Update statistics
75
+ this.updateStats(key, waitTime, executionTime);
76
+ if (process.env.NEUROLINK_DEBUG === "true") {
77
+ console.log(`[Semaphore] Operation completed successfully for key: ${key}`);
78
+ }
79
+ return {
80
+ success: true,
81
+ result,
82
+ waitTime,
83
+ executionTime,
84
+ queueDepth,
85
+ };
86
+ }
87
+ catch (error) {
88
+ executionTime = Math.max(1, Date.now() - executionStartTime); // Ensure at least 1ms
89
+ const errorObj = error instanceof Error ? error : new Error(String(error));
90
+ // Update statistics even for errors
91
+ this.updateStats(key, waitTime, executionTime);
92
+ if (process.env.NEUROLINK_DEBUG === "true") {
93
+ console.error(`[Semaphore] Operation failed for key: ${key}`, errorObj.message);
94
+ }
95
+ return {
96
+ success: false,
97
+ error: errorObj,
98
+ waitTime,
99
+ executionTime,
100
+ queueDepth,
101
+ };
102
+ }
103
+ finally {
104
+ // Release the lock
105
+ this.locks.delete(key);
106
+ if (lockResolve) {
107
+ lockResolve();
108
+ }
109
+ // Process queue
110
+ const queue = this.queues.get(key) || [];
111
+ if (queue.length > 0) {
112
+ const next = queue.shift();
113
+ if (queue.length === 0) {
114
+ this.queues.delete(key);
115
+ }
116
+ else {
117
+ this.queues.set(key, queue);
118
+ }
119
+ // Allow next operation to proceed
120
+ next.resolve();
121
+ }
122
+ // Update statistics
123
+ this.decrementActiveOperations(key);
124
+ if (process.env.NEUROLINK_DEBUG === "true") {
125
+ console.log(`[Semaphore] Released lock for key: ${key}`);
126
+ }
127
+ }
128
+ }
129
+ /**
130
+ * Try to acquire a semaphore without waiting
131
+ * Returns immediately if the resource is locked
132
+ *
133
+ * @param key Unique identifier for the resource
134
+ * @param operation Async operation to execute if lock is available
135
+ * @param context Optional execution context
136
+ * @returns Result of the operation or null if resource is locked
137
+ */
138
+ async tryAcquire(key, operation, context) {
139
+ // Check if there's an active lock or queue
140
+ if (this.locks.has(key) || (this.queues.get(key) || []).length > 0) {
141
+ if (process.env.NEUROLINK_DEBUG === "true") {
142
+ console.log(`[Semaphore] tryAcquire failed - resource locked: ${key}`);
143
+ }
144
+ return null;
145
+ }
146
+ // No lock, proceed with normal acquire
147
+ return this.acquire(key, operation, context);
148
+ }
149
+ /**
150
+ * Check if a resource is currently locked
151
+ *
152
+ * @param key Resource identifier
153
+ * @returns True if the resource is locked
154
+ */
155
+ isLocked(key) {
156
+ return this.locks.has(key);
157
+ }
158
+ /**
159
+ * Get the current queue depth for a resource
160
+ *
161
+ * @param key Resource identifier
162
+ * @returns Number of operations waiting for this resource
163
+ */
164
+ getQueueDepth(key) {
165
+ const queue = this.queues.get(key) || [];
166
+ const hasLock = this.locks.has(key);
167
+ return queue.length + (hasLock ? 1 : 0);
168
+ }
169
+ /**
170
+ * Get statistics for a specific resource or global stats
171
+ *
172
+ * @param key Optional resource identifier
173
+ * @returns Semaphore statistics
174
+ */
175
+ getStats(key) {
176
+ if (key) {
177
+ return (this.stats.get(key) || {
178
+ activeOperations: 0,
179
+ queuedOperations: 0,
180
+ totalOperations: 0,
181
+ totalWaitTime: 0,
182
+ averageWaitTime: 0,
183
+ peakQueueDepth: 0,
184
+ lastActivity: 0,
185
+ });
186
+ }
187
+ return { ...this.globalStats };
188
+ }
189
+ /**
190
+ * Clear all semaphores (use with caution)
191
+ * This will reject all pending operations
192
+ */
193
+ clearAll() {
194
+ console.warn("[Semaphore] Clearing all semaphores - pending operations will be rejected");
195
+ // Reject all queued operations
196
+ for (const [key, queue] of this.queues) {
197
+ for (const op of queue) {
198
+ op.reject(new Error("Semaphore cleared"));
199
+ }
200
+ }
201
+ // Clear all data structures
202
+ this.locks.clear();
203
+ this.queues.clear();
204
+ this.stats.clear();
205
+ // Reset global stats
206
+ this.globalStats = {
207
+ activeOperations: 0,
208
+ queuedOperations: 0,
209
+ totalOperations: this.globalStats.totalOperations,
210
+ totalWaitTime: this.globalStats.totalWaitTime,
211
+ averageWaitTime: this.globalStats.averageWaitTime,
212
+ peakQueueDepth: this.globalStats.peakQueueDepth,
213
+ lastActivity: Date.now(),
214
+ };
215
+ }
216
+ /**
217
+ * Update queue depth statistics
218
+ *
219
+ * @private
220
+ */
221
+ updateQueueDepth(key, depth) {
222
+ const keyStats = this.stats.get(key) || this.createEmptyStats();
223
+ if (depth > keyStats.peakQueueDepth) {
224
+ keyStats.peakQueueDepth = depth;
225
+ }
226
+ keyStats.queuedOperations = depth;
227
+ this.stats.set(key, keyStats);
228
+ // Update global stats
229
+ this.globalStats.queuedOperations = Array.from(this.stats.values()).reduce((total, stats) => total + stats.queuedOperations, 0);
230
+ // Update global peak
231
+ if (depth > this.globalStats.peakQueueDepth) {
232
+ this.globalStats.peakQueueDepth = depth;
233
+ }
234
+ }
235
+ /**
236
+ * Increment active operations counter
237
+ *
238
+ * @private
239
+ */
240
+ incrementActiveOperations(key) {
241
+ const keyStats = this.stats.get(key) || this.createEmptyStats();
242
+ keyStats.activeOperations++;
243
+ keyStats.totalOperations++;
244
+ keyStats.lastActivity = Date.now();
245
+ this.stats.set(key, keyStats);
246
+ this.globalStats.activeOperations++;
247
+ this.globalStats.totalOperations++;
248
+ this.globalStats.lastActivity = Date.now();
249
+ }
250
+ /**
251
+ * Decrement active operations counter
252
+ *
253
+ * @private
254
+ */
255
+ decrementActiveOperations(key) {
256
+ const keyStats = this.stats.get(key);
257
+ if (keyStats && keyStats.activeOperations > 0) {
258
+ keyStats.activeOperations--;
259
+ keyStats.lastActivity = Date.now();
260
+ }
261
+ if (this.globalStats.activeOperations > 0) {
262
+ this.globalStats.activeOperations--;
263
+ }
264
+ this.globalStats.lastActivity = Date.now();
265
+ }
266
+ /**
267
+ * Update timing statistics
268
+ *
269
+ * @private
270
+ */
271
+ updateStats(key, waitTime, executionTime) {
272
+ const keyStats = this.stats.get(key) || this.createEmptyStats();
273
+ keyStats.totalWaitTime += waitTime;
274
+ keyStats.averageWaitTime =
275
+ keyStats.totalOperations > 0
276
+ ? keyStats.totalWaitTime / keyStats.totalOperations
277
+ : 0;
278
+ keyStats.lastActivity = Date.now();
279
+ this.stats.set(key, keyStats);
280
+ // Update global stats
281
+ this.globalStats.totalWaitTime += waitTime;
282
+ this.globalStats.averageWaitTime =
283
+ this.globalStats.totalOperations > 0
284
+ ? this.globalStats.totalWaitTime / this.globalStats.totalOperations
285
+ : 0;
286
+ }
287
+ /**
288
+ * Create empty statistics object
289
+ *
290
+ * @private
291
+ */
292
+ createEmptyStats() {
293
+ return {
294
+ activeOperations: 0,
295
+ queuedOperations: 0,
296
+ totalOperations: 0,
297
+ totalWaitTime: 0,
298
+ averageWaitTime: 0,
299
+ peakQueueDepth: 0,
300
+ lastActivity: Date.now(),
301
+ };
302
+ }
303
+ }
304
+ /**
305
+ * Default semaphore manager instance
306
+ */
307
+ export const defaultSemaphoreManager = new SemaphoreManager();
308
+ /**
309
+ * Utility function to acquire semaphore with default manager
310
+ *
311
+ * @param key Resource identifier
312
+ * @param operation Operation to execute
313
+ * @param context Optional execution context
314
+ * @returns Operation result with metrics
315
+ */
316
+ export async function acquireSemaphore(key, operation, context) {
317
+ return defaultSemaphoreManager.acquire(key, operation, context);
318
+ }
319
+ /**
320
+ * Utility function to try acquiring semaphore without waiting
321
+ *
322
+ * @param key Resource identifier
323
+ * @param operation Operation to execute
324
+ * @param context Optional execution context
325
+ * @returns Operation result or null if locked
326
+ */
327
+ export async function tryAcquireSemaphore(key, operation, context) {
328
+ return defaultSemaphoreManager.tryAcquire(key, operation, context);
329
+ }
@@ -30,13 +30,13 @@ export declare const workflowToolSchemas: {
30
30
  includeAsyncTests: z.ZodDefault<z.ZodBoolean>;
31
31
  }, "strip", z.ZodTypeAny, {
32
32
  codeFunction: string;
33
- testTypes: ("integration" | "unit" | "edge-cases" | "performance" | "security")[];
33
+ testTypes: ("integration" | "unit" | "performance" | "edge-cases" | "security")[];
34
34
  framework: "jest" | "mocha" | "vitest" | "pytest" | "unittest" | "rspec";
35
35
  coverageTarget: number;
36
36
  includeAsyncTests: boolean;
37
37
  }, {
38
38
  codeFunction: string;
39
- testTypes?: ("integration" | "unit" | "edge-cases" | "performance" | "security")[] | undefined;
39
+ testTypes?: ("integration" | "unit" | "performance" | "edge-cases" | "security")[] | undefined;
40
40
  framework?: "jest" | "mocha" | "vitest" | "pytest" | "unittest" | "rspec" | undefined;
41
41
  coverageTarget?: number | undefined;
42
42
  includeAsyncTests?: boolean | undefined;
@@ -5,6 +5,7 @@
5
5
  import { z } from "zod";
6
6
  import { AIProviderFactory } from "../../../core/factory.js";
7
7
  import { getBestProviderSync as getBestProvider } from "../../../utils/providerUtils.js";
8
+ import { DEFAULT_MAX_TOKENS } from "../../../core/constants.js";
8
9
  // Tool-specific schemas with comprehensive validation
9
10
  const generateTestCasesSchema = z.object({
10
11
  codeFunction: z
@@ -145,7 +146,7 @@ Return ONLY a valid JSON object with this exact structure:
145
146
  Generate 3-5 comprehensive test cases covering the requested types.`;
146
147
  const result = await provider.generateText({
147
148
  prompt,
148
- maxTokens: 1200,
149
+ maxTokens: Math.floor(DEFAULT_MAX_TOKENS * 1.2),
149
150
  temperature: 0.3, // Lower temperature for more consistent structured output
150
151
  });
151
152
  if (!result || !result.text) {
@@ -251,7 +252,7 @@ Return ONLY a valid JSON object with this exact structure:
251
252
  Focus on real, actionable improvements based on the specified objectives.`;
252
253
  const result = await provider.generateText({
253
254
  prompt,
254
- maxTokens: 1000,
255
+ maxTokens: DEFAULT_MAX_TOKENS,
255
256
  temperature: 0.2, // Very low temperature for consistent refactoring
256
257
  });
257
258
  if (!result || !result.text) {
@@ -359,7 +360,7 @@ Return ONLY a valid JSON object with this exact structure:
359
360
  Focus on creating accurate, useful documentation that explains the code's purpose, parameters, return values, and usage patterns.`;
360
361
  const result = await provider.generateText({
361
362
  prompt,
362
- maxTokens: 1200,
363
+ maxTokens: Math.floor(DEFAULT_MAX_TOKENS * 1.2),
363
364
  temperature: 0.3, // Moderate temperature for creative but structured documentation
364
365
  });
365
366
  if (!result || !result.text) {
@@ -484,7 +485,7 @@ Return ONLY a valid JSON object with this exact structure:
484
485
  Provide thorough, actionable analysis focused on improving AI output quality.`;
485
486
  const result = await provider.generateText({
486
487
  prompt,
487
- maxTokens: 1000,
488
+ maxTokens: DEFAULT_MAX_TOKENS,
488
489
  temperature: 0.4, // Moderate temperature for analytical thinking
489
490
  });
490
491
  if (!result || !result.text) {
@@ -0,0 +1,186 @@
1
+ /**
2
+ * NeuroLink MCP Session Management System
3
+ * Enables continuous tool calling with persistent state across executions
4
+ * Based on patterns from Cline's session management implementation
5
+ */
6
+ import type { NeuroLinkExecutionContext, ToolResult } from "./factory.js";
7
+ import { type PersistenceOptions } from "./session-persistence.js";
8
+ /**
9
+ * Session state for orchestrator operations
10
+ */
11
+ export interface OrchestratorSession {
12
+ id: string;
13
+ context: NeuroLinkExecutionContext;
14
+ toolHistory: ToolResult[];
15
+ state: Map<string, any>;
16
+ metadata: {
17
+ userAgent?: string;
18
+ origin?: string;
19
+ tags?: string[];
20
+ };
21
+ createdAt: number;
22
+ lastActivity: number;
23
+ expiresAt: number;
24
+ }
25
+ /**
26
+ * Session creation options
27
+ */
28
+ export interface SessionOptions {
29
+ ttl?: number;
30
+ metadata?: {
31
+ userAgent?: string;
32
+ origin?: string;
33
+ tags?: string[];
34
+ };
35
+ }
36
+ /**
37
+ * Session statistics
38
+ */
39
+ export interface SessionStats {
40
+ activeSessions: number;
41
+ totalSessionsCreated: number;
42
+ totalSessionsExpired: number;
43
+ averageSessionDuration: number;
44
+ averageToolsPerSession: number;
45
+ peakConcurrentSessions: number;
46
+ lastCleanup: number;
47
+ }
48
+ /**
49
+ * Session Manager for maintaining state across tool executions
50
+ * Implements session lifecycle management with automatic cleanup
51
+ */
52
+ export declare class SessionManager {
53
+ private sessions;
54
+ private sessionCounter;
55
+ private stats;
56
+ private cleanupInterval;
57
+ private defaultTTL;
58
+ private cleanupIntervalMs;
59
+ private persistence;
60
+ private persistenceEnabled;
61
+ constructor(defaultTTL?: number, cleanupIntervalMs?: number, autoCleanup?: boolean, enablePersistence?: boolean);
62
+ /**
63
+ * Initialize session manager with persistence
64
+ */
65
+ initialize(persistenceOptions?: PersistenceOptions): Promise<void>;
66
+ /**
67
+ * Create a new session
68
+ *
69
+ * @param context Execution context for the session
70
+ * @param options Session configuration options
71
+ * @returns Created session
72
+ */
73
+ createSession(context: NeuroLinkExecutionContext, options?: SessionOptions): OrchestratorSession;
74
+ /**
75
+ * Get an existing session
76
+ *
77
+ * @param sessionId Session identifier
78
+ * @param extend Whether to extend the session's expiration
79
+ * @returns Session if found and not expired
80
+ */
81
+ getSession(sessionId: string, extend?: boolean): OrchestratorSession | null;
82
+ /**
83
+ * Update session with new tool result
84
+ *
85
+ * @param sessionId Session identifier
86
+ * @param toolResult Result from tool execution
87
+ * @returns Updated session or null if not found
88
+ */
89
+ updateSession(sessionId: string, toolResult: ToolResult): OrchestratorSession | null;
90
+ /**
91
+ * Set session state value
92
+ *
93
+ * @param sessionId Session identifier
94
+ * @param key State key
95
+ * @param value State value
96
+ * @returns Updated session or null if not found
97
+ */
98
+ setSessionState(sessionId: string, key: string, value: any): OrchestratorSession | null;
99
+ /**
100
+ * Get session state value
101
+ *
102
+ * @param sessionId Session identifier
103
+ * @param key State key
104
+ * @returns State value or undefined
105
+ */
106
+ getSessionState(sessionId: string, key: string): any;
107
+ /**
108
+ * Remove a session
109
+ *
110
+ * @param sessionId Session identifier
111
+ * @returns True if session was removed
112
+ */
113
+ removeSession(sessionId: string): boolean;
114
+ /**
115
+ * Clean up expired sessions
116
+ *
117
+ * @returns Number of sessions cleaned up
118
+ */
119
+ cleanup(): Promise<number>;
120
+ /**
121
+ * Get an existing session with async persistence loading
122
+ *
123
+ * @param sessionId Session identifier
124
+ * @param extend Whether to extend the session's expiration
125
+ * @returns Session if found and not expired, or null
126
+ */
127
+ getSessionAsync(sessionId: string, extend?: boolean): Promise<OrchestratorSession | null>;
128
+ /**
129
+ * Get all active sessions
130
+ *
131
+ * @returns Array of active sessions
132
+ */
133
+ getActiveSessions(): Promise<OrchestratorSession[]>;
134
+ /**
135
+ * Get session statistics
136
+ *
137
+ * @returns Session statistics
138
+ */
139
+ getStats(): SessionStats;
140
+ /**
141
+ * Clear all sessions
142
+ */
143
+ clearAll(): void;
144
+ /**
145
+ * Start automatic cleanup interval
146
+ *
147
+ * @private
148
+ */
149
+ private startAutoCleanup;
150
+ /**
151
+ * Stop automatic cleanup interval
152
+ */
153
+ stopAutoCleanup(): void;
154
+ /**
155
+ * Generate unique session ID
156
+ *
157
+ * @private
158
+ */
159
+ private generateSessionId;
160
+ /**
161
+ * Update statistics
162
+ *
163
+ * @private
164
+ */
165
+ private updateStats;
166
+ }
167
+ /**
168
+ * Default session manager instance
169
+ */
170
+ export declare const defaultSessionManager: SessionManager;
171
+ /**
172
+ * Utility function to create session with default manager
173
+ *
174
+ * @param context Execution context
175
+ * @param options Session options
176
+ * @returns Created session
177
+ */
178
+ export declare function createSession(context: NeuroLinkExecutionContext, options?: SessionOptions): Promise<OrchestratorSession>;
179
+ /**
180
+ * Utility function to get session with default manager
181
+ *
182
+ * @param sessionId Session identifier
183
+ * @param extend Whether to extend expiration
184
+ * @returns Session or null
185
+ */
186
+ export declare function getSession(sessionId: string, extend?: boolean): Promise<OrchestratorSession | null>;