@juspay/neurolink 9.24.0 → 9.25.1

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 (219) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/adapters/tts/googleTTSHandler.js +26 -1
  3. package/dist/adapters/video/vertexVideoHandler.js +23 -17
  4. package/dist/cli/commands/config.d.ts +3 -3
  5. package/dist/cli/commands/observability.d.ts +53 -0
  6. package/dist/cli/commands/observability.js +453 -0
  7. package/dist/cli/commands/telemetry.d.ts +63 -0
  8. package/dist/cli/commands/telemetry.js +689 -0
  9. package/dist/cli/factories/commandFactory.js +29 -15
  10. package/dist/cli/parser.js +6 -9
  11. package/dist/cli/utils/formatters.d.ts +13 -0
  12. package/dist/cli/utils/formatters.js +23 -0
  13. package/dist/constants/contextWindows.js +6 -0
  14. package/dist/constants/enums.d.ts +6 -0
  15. package/dist/constants/enums.js +8 -2
  16. package/dist/context/budgetChecker.js +75 -48
  17. package/dist/context/contextCompactor.js +135 -127
  18. package/dist/core/baseProvider.d.ts +5 -0
  19. package/dist/core/baseProvider.js +117 -110
  20. package/dist/core/conversationMemoryInitializer.js +7 -4
  21. package/dist/core/conversationMemoryManager.d.ts +2 -0
  22. package/dist/core/conversationMemoryManager.js +6 -2
  23. package/dist/core/modules/GenerationHandler.d.ts +2 -2
  24. package/dist/core/modules/GenerationHandler.js +12 -12
  25. package/dist/evaluation/ragasEvaluator.js +39 -19
  26. package/dist/evaluation/scoring.js +46 -20
  27. package/dist/features/ppt/presentationOrchestrator.js +23 -0
  28. package/dist/features/ppt/slideGenerator.js +13 -0
  29. package/dist/features/ppt/slideRenderers.d.ts +1 -1
  30. package/dist/features/ppt/slideRenderers.js +6 -4
  31. package/dist/features/ppt/slideTypeInference.d.ts +1 -1
  32. package/dist/features/ppt/slideTypeInference.js +75 -73
  33. package/dist/files/fileTools.d.ts +6 -6
  34. package/dist/index.d.ts +46 -12
  35. package/dist/index.js +79 -17
  36. package/dist/lib/adapters/tts/googleTTSHandler.js +26 -1
  37. package/dist/lib/adapters/video/vertexVideoHandler.js +23 -17
  38. package/dist/lib/constants/contextWindows.js +6 -0
  39. package/dist/lib/constants/enums.d.ts +6 -0
  40. package/dist/lib/constants/enums.js +8 -2
  41. package/dist/lib/context/budgetChecker.js +75 -48
  42. package/dist/lib/context/contextCompactor.js +135 -127
  43. package/dist/lib/core/baseProvider.d.ts +5 -0
  44. package/dist/lib/core/baseProvider.js +117 -110
  45. package/dist/lib/core/conversationMemoryInitializer.js +7 -4
  46. package/dist/lib/core/conversationMemoryManager.d.ts +2 -0
  47. package/dist/lib/core/conversationMemoryManager.js +6 -2
  48. package/dist/lib/core/modules/GenerationHandler.d.ts +2 -2
  49. package/dist/lib/core/modules/GenerationHandler.js +12 -12
  50. package/dist/lib/evaluation/ragasEvaluator.js +39 -19
  51. package/dist/lib/evaluation/scoring.js +46 -20
  52. package/dist/lib/features/ppt/presentationOrchestrator.js +23 -0
  53. package/dist/lib/features/ppt/slideGenerator.js +13 -0
  54. package/dist/lib/features/ppt/slideRenderers.d.ts +1 -1
  55. package/dist/lib/features/ppt/slideRenderers.js +6 -4
  56. package/dist/lib/features/ppt/slideTypeInference.d.ts +1 -1
  57. package/dist/lib/features/ppt/slideTypeInference.js +75 -73
  58. package/dist/lib/files/fileTools.d.ts +6 -6
  59. package/dist/lib/index.d.ts +46 -12
  60. package/dist/lib/index.js +79 -17
  61. package/dist/lib/mcp/httpRateLimiter.js +39 -12
  62. package/dist/lib/mcp/httpRetryHandler.js +22 -1
  63. package/dist/lib/mcp/mcpClientFactory.js +13 -15
  64. package/dist/lib/memory/memoryRetrievalTools.js +22 -0
  65. package/dist/lib/neurolink.d.ts +64 -72
  66. package/dist/lib/neurolink.js +1007 -564
  67. package/dist/lib/observability/exporterRegistry.d.ts +152 -0
  68. package/dist/lib/observability/exporterRegistry.js +414 -0
  69. package/dist/lib/observability/exporters/arizeExporter.d.ts +32 -0
  70. package/dist/lib/observability/exporters/arizeExporter.js +139 -0
  71. package/dist/lib/observability/exporters/baseExporter.d.ts +117 -0
  72. package/dist/lib/observability/exporters/baseExporter.js +191 -0
  73. package/dist/lib/observability/exporters/braintrustExporter.d.ts +30 -0
  74. package/dist/lib/observability/exporters/braintrustExporter.js +155 -0
  75. package/dist/lib/observability/exporters/datadogExporter.d.ts +37 -0
  76. package/dist/lib/observability/exporters/datadogExporter.js +197 -0
  77. package/dist/lib/observability/exporters/index.d.ts +13 -0
  78. package/dist/lib/observability/exporters/index.js +14 -0
  79. package/dist/lib/observability/exporters/laminarExporter.d.ts +48 -0
  80. package/dist/lib/observability/exporters/laminarExporter.js +303 -0
  81. package/dist/lib/observability/exporters/langfuseExporter.d.ts +47 -0
  82. package/dist/lib/observability/exporters/langfuseExporter.js +204 -0
  83. package/dist/lib/observability/exporters/langsmithExporter.d.ts +26 -0
  84. package/dist/lib/observability/exporters/langsmithExporter.js +124 -0
  85. package/dist/lib/observability/exporters/otelExporter.d.ts +39 -0
  86. package/dist/lib/observability/exporters/otelExporter.js +165 -0
  87. package/dist/lib/observability/exporters/posthogExporter.d.ts +48 -0
  88. package/dist/lib/observability/exporters/posthogExporter.js +288 -0
  89. package/dist/lib/observability/exporters/sentryExporter.d.ts +32 -0
  90. package/dist/lib/observability/exporters/sentryExporter.js +166 -0
  91. package/dist/lib/observability/index.d.ts +25 -0
  92. package/dist/lib/observability/index.js +32 -0
  93. package/dist/lib/observability/metricsAggregator.d.ts +260 -0
  94. package/dist/lib/observability/metricsAggregator.js +557 -0
  95. package/dist/lib/observability/otelBridge.d.ts +49 -0
  96. package/dist/lib/observability/otelBridge.js +132 -0
  97. package/dist/lib/observability/retryPolicy.d.ts +192 -0
  98. package/dist/lib/observability/retryPolicy.js +384 -0
  99. package/dist/lib/observability/sampling/index.d.ts +4 -0
  100. package/dist/lib/observability/sampling/index.js +5 -0
  101. package/dist/lib/observability/sampling/samplers.d.ts +116 -0
  102. package/dist/lib/observability/sampling/samplers.js +217 -0
  103. package/dist/lib/observability/spanProcessor.d.ts +129 -0
  104. package/dist/lib/observability/spanProcessor.js +304 -0
  105. package/dist/lib/observability/tokenTracker.d.ts +156 -0
  106. package/dist/lib/observability/tokenTracker.js +414 -0
  107. package/dist/lib/observability/types/exporterTypes.d.ts +250 -0
  108. package/dist/lib/observability/types/exporterTypes.js +6 -0
  109. package/dist/lib/observability/types/index.d.ts +6 -0
  110. package/dist/lib/observability/types/index.js +5 -0
  111. package/dist/lib/observability/types/spanTypes.d.ts +244 -0
  112. package/dist/lib/observability/types/spanTypes.js +93 -0
  113. package/dist/lib/observability/utils/index.d.ts +4 -0
  114. package/dist/lib/observability/utils/index.js +5 -0
  115. package/dist/lib/observability/utils/safeMetadata.d.ts +10 -0
  116. package/dist/lib/observability/utils/safeMetadata.js +26 -0
  117. package/dist/lib/observability/utils/spanSerializer.d.ts +115 -0
  118. package/dist/lib/observability/utils/spanSerializer.js +291 -0
  119. package/dist/lib/providers/amazonSagemaker.d.ts +5 -4
  120. package/dist/lib/providers/amazonSagemaker.js +3 -4
  121. package/dist/lib/providers/googleVertex.d.ts +7 -0
  122. package/dist/lib/providers/googleVertex.js +76 -2
  123. package/dist/lib/rag/pipeline/RAGPipeline.d.ts +0 -5
  124. package/dist/lib/rag/pipeline/RAGPipeline.js +122 -87
  125. package/dist/lib/rag/ragIntegration.js +30 -0
  126. package/dist/lib/rag/retrieval/hybridSearch.js +22 -0
  127. package/dist/lib/server/abstract/baseServerAdapter.js +51 -19
  128. package/dist/lib/server/middleware/common.js +44 -12
  129. package/dist/lib/services/server/ai/observability/instrumentation.d.ts +2 -2
  130. package/dist/lib/services/server/ai/observability/instrumentation.js +10 -5
  131. package/dist/lib/types/conversationMemoryInterface.d.ts +2 -0
  132. package/dist/lib/types/modelTypes.d.ts +18 -18
  133. package/dist/lib/types/providers.d.ts +5 -0
  134. package/dist/lib/utils/pricing.js +25 -1
  135. package/dist/lib/utils/ttsProcessor.js +74 -59
  136. package/dist/lib/workflow/config.d.ts +36 -36
  137. package/dist/lib/workflow/core/ensembleExecutor.js +10 -0
  138. package/dist/lib/workflow/core/judgeScorer.js +20 -2
  139. package/dist/lib/workflow/core/workflowRunner.js +34 -1
  140. package/dist/mcp/httpRateLimiter.js +39 -12
  141. package/dist/mcp/httpRetryHandler.js +22 -1
  142. package/dist/mcp/mcpClientFactory.js +13 -15
  143. package/dist/memory/memoryRetrievalTools.js +22 -0
  144. package/dist/neurolink.d.ts +64 -72
  145. package/dist/neurolink.js +1007 -564
  146. package/dist/observability/FEATURE-STATUS.md +269 -0
  147. package/dist/observability/exporterRegistry.d.ts +152 -0
  148. package/dist/observability/exporterRegistry.js +413 -0
  149. package/dist/observability/exporters/arizeExporter.d.ts +32 -0
  150. package/dist/observability/exporters/arizeExporter.js +138 -0
  151. package/dist/observability/exporters/baseExporter.d.ts +117 -0
  152. package/dist/observability/exporters/baseExporter.js +190 -0
  153. package/dist/observability/exporters/braintrustExporter.d.ts +30 -0
  154. package/dist/observability/exporters/braintrustExporter.js +154 -0
  155. package/dist/observability/exporters/datadogExporter.d.ts +37 -0
  156. package/dist/observability/exporters/datadogExporter.js +196 -0
  157. package/dist/observability/exporters/index.d.ts +13 -0
  158. package/dist/observability/exporters/index.js +13 -0
  159. package/dist/observability/exporters/laminarExporter.d.ts +48 -0
  160. package/dist/observability/exporters/laminarExporter.js +302 -0
  161. package/dist/observability/exporters/langfuseExporter.d.ts +47 -0
  162. package/dist/observability/exporters/langfuseExporter.js +203 -0
  163. package/dist/observability/exporters/langsmithExporter.d.ts +26 -0
  164. package/dist/observability/exporters/langsmithExporter.js +123 -0
  165. package/dist/observability/exporters/otelExporter.d.ts +39 -0
  166. package/dist/observability/exporters/otelExporter.js +164 -0
  167. package/dist/observability/exporters/posthogExporter.d.ts +48 -0
  168. package/dist/observability/exporters/posthogExporter.js +287 -0
  169. package/dist/observability/exporters/sentryExporter.d.ts +32 -0
  170. package/dist/observability/exporters/sentryExporter.js +165 -0
  171. package/dist/observability/index.d.ts +25 -0
  172. package/dist/observability/index.js +31 -0
  173. package/dist/observability/metricsAggregator.d.ts +260 -0
  174. package/dist/observability/metricsAggregator.js +556 -0
  175. package/dist/observability/otelBridge.d.ts +49 -0
  176. package/dist/observability/otelBridge.js +131 -0
  177. package/dist/observability/retryPolicy.d.ts +192 -0
  178. package/dist/observability/retryPolicy.js +383 -0
  179. package/dist/observability/sampling/index.d.ts +4 -0
  180. package/dist/observability/sampling/index.js +4 -0
  181. package/dist/observability/sampling/samplers.d.ts +116 -0
  182. package/dist/observability/sampling/samplers.js +216 -0
  183. package/dist/observability/spanProcessor.d.ts +129 -0
  184. package/dist/observability/spanProcessor.js +303 -0
  185. package/dist/observability/tokenTracker.d.ts +156 -0
  186. package/dist/observability/tokenTracker.js +413 -0
  187. package/dist/observability/types/exporterTypes.d.ts +250 -0
  188. package/dist/observability/types/exporterTypes.js +5 -0
  189. package/dist/observability/types/index.d.ts +6 -0
  190. package/dist/observability/types/index.js +4 -0
  191. package/dist/observability/types/spanTypes.d.ts +244 -0
  192. package/dist/observability/types/spanTypes.js +92 -0
  193. package/dist/observability/utils/index.d.ts +4 -0
  194. package/dist/observability/utils/index.js +4 -0
  195. package/dist/observability/utils/safeMetadata.d.ts +10 -0
  196. package/dist/observability/utils/safeMetadata.js +25 -0
  197. package/dist/observability/utils/spanSerializer.d.ts +115 -0
  198. package/dist/observability/utils/spanSerializer.js +290 -0
  199. package/dist/providers/amazonSagemaker.d.ts +5 -4
  200. package/dist/providers/amazonSagemaker.js +3 -4
  201. package/dist/providers/googleVertex.d.ts +7 -0
  202. package/dist/providers/googleVertex.js +76 -2
  203. package/dist/rag/pipeline/RAGPipeline.d.ts +0 -5
  204. package/dist/rag/pipeline/RAGPipeline.js +122 -87
  205. package/dist/rag/ragIntegration.js +30 -0
  206. package/dist/rag/retrieval/hybridSearch.js +22 -0
  207. package/dist/server/abstract/baseServerAdapter.js +51 -19
  208. package/dist/server/middleware/common.js +44 -12
  209. package/dist/services/server/ai/observability/instrumentation.d.ts +2 -2
  210. package/dist/services/server/ai/observability/instrumentation.js +10 -5
  211. package/dist/types/conversationMemoryInterface.d.ts +2 -0
  212. package/dist/types/providers.d.ts +5 -0
  213. package/dist/utils/pricing.js +25 -1
  214. package/dist/utils/ttsProcessor.js +74 -59
  215. package/dist/workflow/config.d.ts +52 -52
  216. package/dist/workflow/core/ensembleExecutor.js +10 -0
  217. package/dist/workflow/core/judgeScorer.js +20 -2
  218. package/dist/workflow/core/workflowRunner.js +34 -1
  219. package/package.json +1 -1
@@ -4,6 +4,8 @@
4
4
  * Provides fault tolerance and prevents server overload
5
5
  */
6
6
  import { mcpLogger } from "../utils/logger.js";
7
+ import { SpanSerializer, SpanType, SpanStatus, } from "../observability/index.js";
8
+ import { getMetricsAggregator } from "../observability/index.js";
7
9
  /**
8
10
  * Default rate limit configuration
9
11
  * Provides sensible defaults for most MCP HTTP transport use cases
@@ -71,19 +73,44 @@ export class HTTPRateLimiter {
71
73
  * @throws Error if the wait queue is too long
72
74
  */
73
75
  async acquire() {
74
- // First, try to acquire without waiting
75
- if (this.tryAcquire()) {
76
- return;
77
- }
78
- // Add to wait queue
79
- return new Promise((resolve, reject) => {
80
- this.waitQueue.push({ resolve, reject });
81
- mcpLogger.debug(`[HTTPRateLimiter] Request queued, queue length: ${this.waitQueue.length}`);
82
- // Start processing the queue if not already processing
83
- if (!this.processingQueue) {
84
- this.processQueue();
85
- }
76
+ const span = SpanSerializer.createSpan(SpanType.MCP_TRANSPORT, "mcp.rateLimit", {
77
+ "mcp.transport": "http",
78
+ "mcp.operation": "rateLimit",
79
+ "mcp.rateLimit.tokensAvailable": this.tokens,
80
+ "mcp.rateLimit.maxBurst": this.config.maxBurst,
86
81
  });
82
+ const startTime = Date.now();
83
+ try {
84
+ // First, try to acquire without waiting
85
+ if (this.tryAcquire()) {
86
+ span.durationMs = Date.now() - startTime;
87
+ span.attributes["mcp.rateLimit.waited"] = false;
88
+ const endedSpan = SpanSerializer.endSpan(span, SpanStatus.OK);
89
+ getMetricsAggregator().recordSpan(endedSpan);
90
+ return;
91
+ }
92
+ // Add to wait queue
93
+ await new Promise((resolve, reject) => {
94
+ this.waitQueue.push({ resolve, reject });
95
+ mcpLogger.debug(`[HTTPRateLimiter] Request queued, queue length: ${this.waitQueue.length}`);
96
+ // Start processing the queue if not already processing
97
+ if (!this.processingQueue) {
98
+ this.processQueue();
99
+ }
100
+ });
101
+ span.durationMs = Date.now() - startTime;
102
+ span.attributes["mcp.rateLimit.waited"] = true;
103
+ const endedSpan = SpanSerializer.endSpan(span, SpanStatus.OK);
104
+ getMetricsAggregator().recordSpan(endedSpan);
105
+ }
106
+ catch (error) {
107
+ span.durationMs = Date.now() - startTime;
108
+ const endedSpan = SpanSerializer.endSpan(span, SpanStatus.ERROR);
109
+ endedSpan.statusMessage =
110
+ error instanceof Error ? error.message : String(error);
111
+ getMetricsAggregator().recordSpan(endedSpan);
112
+ throw error;
113
+ }
87
114
  }
88
115
  /**
89
116
  * Process the wait queue, granting tokens as they become available
@@ -7,6 +7,8 @@
7
7
  import { isAbortError } from "../utils/errorHandling.js";
8
8
  import { calculateBackoffDelay } from "../utils/retryHandler.js";
9
9
  import { logger } from "../utils/logger.js";
10
+ import { SpanSerializer, SpanType, SpanStatus, } from "../observability/index.js";
11
+ import { getMetricsAggregator } from "../observability/index.js";
10
12
  /**
11
13
  * Default HTTP retry configuration
12
14
  */
@@ -129,10 +131,23 @@ export async function withHTTPRetry(operation, config = {}) {
129
131
  ...DEFAULT_HTTP_RETRY_CONFIG,
130
132
  ...config,
131
133
  };
134
+ const span = SpanSerializer.createSpan(SpanType.MCP_TRANSPORT, "mcp.retry", {
135
+ "mcp.transport": "http",
136
+ "mcp.operation": "retry",
137
+ "mcp.maxAttempts": mergedConfig.maxAttempts,
138
+ });
139
+ const startTime = Date.now();
132
140
  let lastError;
141
+ let actualAttempts = 0;
133
142
  for (let attempt = 1; attempt <= mergedConfig.maxAttempts; attempt++) {
143
+ actualAttempts = attempt;
134
144
  try {
135
- return await operation();
145
+ const result = await operation();
146
+ span.durationMs = Date.now() - startTime;
147
+ span.attributes["mcp.retryAttempt"] = attempt;
148
+ const endedSpan = SpanSerializer.endSpan(span, SpanStatus.OK);
149
+ getMetricsAggregator().recordSpan(endedSpan);
150
+ return result;
136
151
  }
137
152
  catch (error) {
138
153
  lastError = error;
@@ -153,5 +168,11 @@ export async function withHTTPRetry(operation, config = {}) {
153
168
  await sleep(delay);
154
169
  }
155
170
  }
171
+ span.durationMs = Date.now() - startTime;
172
+ span.attributes["mcp.retryAttempt"] = actualAttempts;
173
+ const endedSpan = SpanSerializer.endSpan(span, SpanStatus.ERROR);
174
+ endedSpan.statusMessage =
175
+ lastError instanceof Error ? lastError.message : String(lastError);
176
+ getMetricsAggregator().recordSpan(endedSpan);
156
177
  throw lastError;
157
178
  }
@@ -15,8 +15,8 @@ import { globalCircuitBreakerManager } from "./mcpCircuitBreaker.js";
15
15
  import { withHTTPRetry, DEFAULT_HTTP_RETRY_CONFIG, } from "./httpRetryHandler.js";
16
16
  import { globalRateLimiterManager } from "./httpRateLimiter.js";
17
17
  import { NeuroLinkOAuthProvider, InMemoryTokenStorage } from "./auth/index.js";
18
- import { tracers } from "../telemetry/tracers.js";
19
- import { SpanStatusCode } from "@opentelemetry/api";
18
+ import { SpanSerializer, SpanType, SpanStatus, } from "../observability/index.js";
19
+ import { getMetricsAggregator } from "../observability/index.js";
20
20
  /**
21
21
  * MCPClientFactory
22
22
  * Factory class for creating MCP clients with different transports
@@ -38,12 +38,10 @@ export class MCPClientFactory {
38
38
  */
39
39
  static async createClient(config, timeout = 10000) {
40
40
  const startTime = Date.now();
41
- const span = tracers.mcp.startSpan("neurolink.mcp.client.create", {
42
- attributes: {
43
- "mcp.server_id": config.id,
44
- "mcp.transport": config.transport,
45
- "mcp.timeout_ms": timeout,
46
- },
41
+ const obsSpan = SpanSerializer.createSpan(SpanType.MCP_TRANSPORT, "mcp.connect", {
42
+ "mcp.transport": config.transport,
43
+ "mcp.operation": "connect",
44
+ "mcp.server_id": config.id,
47
45
  });
48
46
  try {
49
47
  mcpLogger.info(`[MCPClientFactory] Creating client for ${config.id}`, {
@@ -103,7 +101,9 @@ export class MCPClientFactory {
103
101
  duration: Date.now() - startTime,
104
102
  capabilities: result.capabilities,
105
103
  });
106
- span.setStatus({ code: SpanStatusCode.OK });
104
+ obsSpan.durationMs = Date.now() - startTime;
105
+ const endedObsSpan = SpanSerializer.endSpan(obsSpan, SpanStatus.OK);
106
+ getMetricsAggregator().recordSpan(endedObsSpan);
107
107
  return {
108
108
  ...result,
109
109
  success: true,
@@ -113,18 +113,16 @@ export class MCPClientFactory {
113
113
  catch (error) {
114
114
  const errorMessage = error instanceof Error ? error.message : String(error);
115
115
  mcpLogger.error(`[MCPClientFactory] Failed to create client for ${config.id}:`, error);
116
- // NLK-GAP-004 fix: Record both exception AND error status on span
117
- span.recordException(error instanceof Error ? error : new Error(errorMessage));
118
- span.setStatus({ code: SpanStatusCode.ERROR, message: errorMessage });
116
+ obsSpan.durationMs = Date.now() - startTime;
117
+ const endedObsSpan = SpanSerializer.endSpan(obsSpan, SpanStatus.ERROR);
118
+ endedObsSpan.statusMessage = errorMessage;
119
+ getMetricsAggregator().recordSpan(endedObsSpan);
119
120
  return {
120
121
  success: false,
121
122
  error: errorMessage,
122
123
  duration: Date.now() - startTime,
123
124
  };
124
125
  }
125
- finally {
126
- span.end();
127
- }
128
126
  }
129
127
  /**
130
128
  * Internal client creation logic
@@ -9,6 +9,8 @@
9
9
  import { tool } from "ai";
10
10
  import { z } from "zod";
11
11
  import { logger } from "../utils/logger.js";
12
+ import { SpanSerializer, SpanType, SpanStatus, } from "../observability/index.js";
13
+ import { getMetricsAggregator } from "../observability/index.js";
12
14
  /** Maximum characters returned per retrieval request */
13
15
  const DEFAULT_RETRIEVAL_LIMIT = 50_000;
14
16
  /** Hard maximum for user/LLM-supplied limit to prevent massive tool outputs */
@@ -62,9 +64,18 @@ export function createMemoryRetrievalTools(memoryManager) {
62
64
  "Returns matching lines with line numbers."),
63
65
  }),
64
66
  execute: async (args) => {
67
+ const span = SpanSerializer.createSpan(SpanType.MEMORY, "memory.retrieve", {
68
+ "memory.operation": "retrieve",
69
+ "memory.store": "redis",
70
+ "memory.query": args.search || args.messageId || `lastN:${args.lastN ?? "all"}`,
71
+ });
72
+ const startTime = Date.now();
65
73
  try {
66
74
  const conversation = await memoryManager.getSessionRaw(args.sessionId);
67
75
  if (!conversation) {
76
+ span.durationMs = Date.now() - startTime;
77
+ const endedSpan = SpanSerializer.endSpan(span, SpanStatus.OK);
78
+ getMetricsAggregator().recordSpan(endedSpan);
68
79
  return { error: "Session not found", sessionId: args.sessionId };
69
80
  }
70
81
  let messages = conversation.messages;
@@ -72,6 +83,9 @@ export function createMemoryRetrievalTools(memoryManager) {
72
83
  if (args.messageId) {
73
84
  const msg = messages.find((m) => m.id === args.messageId);
74
85
  if (!msg) {
86
+ span.durationMs = Date.now() - startTime;
87
+ const endedSpan = SpanSerializer.endSpan(span, SpanStatus.OK);
88
+ getMetricsAggregator().recordSpan(endedSpan);
75
89
  return { error: "Message not found", messageId: args.messageId };
76
90
  }
77
91
  messages = [msg];
@@ -130,9 +144,17 @@ export function createMemoryRetrievalTools(memoryManager) {
130
144
  hasMore: end < content.length,
131
145
  };
132
146
  });
147
+ span.durationMs = Date.now() - startTime;
148
+ const endedSpan = SpanSerializer.endSpan(span, SpanStatus.OK);
149
+ getMetricsAggregator().recordSpan(endedSpan);
133
150
  return { messages: results, totalMessages: results.length };
134
151
  }
135
152
  catch (error) {
153
+ span.durationMs = Date.now() - startTime;
154
+ const endedSpan = SpanSerializer.endSpan(span, SpanStatus.ERROR);
155
+ endedSpan.statusMessage =
156
+ error instanceof Error ? error.message : String(error);
157
+ getMetricsAggregator().recordSpan(endedSpan);
136
158
  logger.error("[MemoryRetrievalTools] Error retrieving context", {
137
159
  error: error instanceof Error ? error.message : String(error),
138
160
  });
@@ -10,6 +10,8 @@ import { ConversationMemoryManager } from "./core/conversationMemoryManager.js";
10
10
  import type { RedisConversationMemoryManager } from "./core/redisConversationMemoryManager.js";
11
11
  import { ExternalServerManager } from "./mcp/externalServerManager.js";
12
12
  import { MCPToolRegistry } from "./mcp/toolRegistry.js";
13
+ import type { MetricsSummary, TraceView } from "./observability/metricsAggregator.js";
14
+ import type { SpanData } from "./observability/types/spanTypes.js";
13
15
  import type { JsonObject, NeuroLinkEvents, TypedEventEmitter } from "./types/common.js";
14
16
  import type { NeurolinkConstructorConfig } from "./types/configTypes.js";
15
17
  import type { ChatMessage } from "./types/conversation.js";
@@ -21,78 +23,6 @@ import type { ObservabilityConfig } from "./types/observability.js";
21
23
  import type { StreamOptions, StreamResult } from "./types/streamTypes.js";
22
24
  import type { ToolExecutionContext, ToolExecutionSummary, ToolInfo } from "./types/tools.js";
23
25
  import type { BatchOperationResult } from "./types/typeAliases.js";
24
- /**
25
- * NeuroLink - Universal AI Development Platform
26
- *
27
- * Main SDK class providing unified access to 14+ AI providers with enterprise features:
28
- * - Multi-provider support (OpenAI, Anthropic, Google AI Studio, Google Vertex, AWS Bedrock, etc.)
29
- * - MCP (Model Context Protocol) tool integration with 58+ external servers
30
- * - Human-in-the-Loop (HITL) security workflows for regulated industries
31
- * - Redis-based conversation memory and persistence
32
- * - Enterprise middleware system for monitoring and control
33
- * - Automatic provider fallback and retry logic
34
- * - Streaming with real-time token delivery
35
- * - Multimodal support (text, images, PDFs, CSV)
36
- *
37
- * @category Core
38
- *
39
- * @example Basic usage
40
- * ```typescript
41
- * import { NeuroLink } from '@juspay/neurolink';
42
- *
43
- * const neurolink = new NeuroLink();
44
- *
45
- * const result = await neurolink.generate({
46
- * input: { text: 'Explain quantum computing' },
47
- * provider: 'vertex',
48
- * model: 'gemini-3-flash'
49
- * });
50
- *
51
- * console.log(result.content);
52
- * ```
53
- *
54
- * @example With HITL security
55
- * ```typescript
56
- * const neurolink = new NeuroLink({
57
- * hitl: {
58
- * enabled: true,
59
- * requireApproval: ['writeFile', 'executeCode'],
60
- * confidenceThreshold: 0.85
61
- * }
62
- * });
63
- * ```
64
- *
65
- * @example With Redis memory
66
- * ```typescript
67
- * const neurolink = new NeuroLink({
68
- * conversationMemory: {
69
- * enabled: true,
70
- * redis: {
71
- * url: 'redis://localhost:6379'
72
- * }
73
- * }
74
- * });
75
- * ```
76
- *
77
- * @example With MCP tools
78
- * ```typescript
79
- * const neurolink = new NeuroLink();
80
- *
81
- * // Discover available tools
82
- * const tools = await neurolink.getAvailableTools();
83
- *
84
- * // Use tools in generation
85
- * const result = await neurolink.generate({
86
- * input: { text: 'Read the README.md file' },
87
- * tools: ['readFile']
88
- * });
89
- * ```
90
- *
91
- * @see {@link GenerateOptions} for generation options
92
- * @see {@link StreamOptions} for streaming options
93
- * @see {@link NeurolinkConstructorConfig} for configuration options
94
- * @since 1.0.0
95
- */
96
26
  export declare class NeuroLink {
97
27
  private mcpInitialized;
98
28
  private mcpInitPromise;
@@ -203,6 +133,13 @@ export declare class NeuroLink {
203
133
  * @throws {Error} When HITL configuration is invalid (if enabled)
204
134
  */
205
135
  private observabilityConfig?;
136
+ private metricsAggregator;
137
+ /**
138
+ * Per-request metrics trace context backed by AsyncLocalStorage.
139
+ * Safe for concurrent requests on the same SDK instance.
140
+ * Context is set via metricsTraceContextStorage.run() in generate/stream.
141
+ */
142
+ private get _metricsTraceContext();
206
143
  constructor(config?: NeurolinkConstructorConfig);
207
144
  /**
208
145
  * Initialize provider registry with security settings
@@ -385,6 +322,56 @@ export declare class NeuroLink {
385
322
  * Centralized utility to avoid duplication across providers
386
323
  */
387
324
  isTelemetryEnabled(): boolean;
325
+ /**
326
+ * Get comprehensive telemetry status including Langfuse, OTel, and exporter health
327
+ */
328
+ getTelemetryStatus(): {
329
+ enabled: boolean;
330
+ langfuse?: {
331
+ enabled: boolean;
332
+ baseUrl?: string;
333
+ environment?: string;
334
+ };
335
+ openTelemetry?: {
336
+ enabled: boolean;
337
+ endpoint?: string;
338
+ serviceName?: string;
339
+ };
340
+ exporters?: Array<{
341
+ name: string;
342
+ enabled: boolean;
343
+ healthy: boolean;
344
+ pendingSpans: number;
345
+ lastExportTime?: string;
346
+ latencyMs?: number;
347
+ errors?: string[];
348
+ }>;
349
+ };
350
+ /**
351
+ * Get aggregated observability metrics (latency, tokens, cost, success rate)
352
+ */
353
+ getMetrics(): MetricsSummary;
354
+ /**
355
+ * Get all recorded spans
356
+ */
357
+ getSpans(): SpanData[];
358
+ /**
359
+ * Get traces (spans grouped by traceId with parent-child hierarchy)
360
+ */
361
+ getTraces(): TraceView[];
362
+ /**
363
+ * Reset all collected metrics and spans
364
+ */
365
+ resetMetrics(): void;
366
+ /**
367
+ * Record a span for metrics tracking
368
+ */
369
+ recordMetricsSpan(span: SpanData): void;
370
+ /**
371
+ * Record a memory operation span to both instance and global metrics aggregators.
372
+ * This ensures memory spans are visible via sdk.getSpans() and getMetricsAggregator().getSpans().
373
+ */
374
+ private recordMemorySpan;
388
375
  /**
389
376
  * Public method to initialize Langfuse observability
390
377
  * This method can be called externally to ensure Langfuse is properly initialized
@@ -394,6 +381,11 @@ export declare class NeuroLink {
394
381
  * Gracefully shutdown NeuroLink and all MCP connections
395
382
  */
396
383
  shutdown(): Promise<void>;
384
+ /**
385
+ * Initialize event listeners that feed span data to MetricsAggregator.
386
+ * Listens to generation:end, stream:complete, and tool:end events.
387
+ */
388
+ private initializeMetricsListeners;
397
389
  /**
398
390
  * Generate AI response with comprehensive feature support.
399
391
  *