@juspay/neurolink 12.59.0 → 13.0.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 (146) hide show
  1. package/CHANGELOG.md +3 -3
  2. package/dist/auth/anthropicOAuth.js +3 -3
  3. package/dist/auth/middleware/AuthMiddleware.d.ts +1 -1
  4. package/dist/auth/sessionManager.js +4 -4
  5. package/dist/auth/tokenStore.js +4 -4
  6. package/dist/browser/neurolink.min.js +474 -473
  7. package/dist/cli/commands/observability.d.ts +1 -6
  8. package/dist/cli/commands/observability.js +0 -106
  9. package/dist/cli/commands/proxy.js +9 -18
  10. package/dist/cli/commands/telemetry.d.ts +3 -13
  11. package/dist/cli/commands/telemetry.js +7 -354
  12. package/dist/cli/loop/session.js +1 -1
  13. package/dist/client/httpClient.js +1 -1
  14. package/dist/client/sseClient.js +1 -1
  15. package/dist/client/streamingClient.js +2 -2
  16. package/dist/client/wsClient.js +1 -1
  17. package/dist/constants/langfuse.d.ts +25 -0
  18. package/dist/constants/langfuse.js +38 -0
  19. package/dist/constants/telemetry.d.ts +20 -0
  20. package/dist/constants/telemetry.js +34 -0
  21. package/dist/core/baseProvider.d.ts +2 -1
  22. package/dist/core/baseProvider.js +4 -11
  23. package/dist/core/conversationMemoryManager.js +5 -8
  24. package/dist/core/factory.js +1 -1
  25. package/dist/core/geminiLoopAdapter.d.ts +8 -1
  26. package/dist/core/geminiLoopAdapter.js +25 -1
  27. package/dist/core/loopEngine.js +69 -40
  28. package/dist/core/modules/MessageBuilder.js +2 -2
  29. package/dist/core/modules/StreamHandler.js +2 -2
  30. package/dist/core/modules/TelemetryHandler.d.ts +2 -18
  31. package/dist/core/modules/TelemetryHandler.js +1 -66
  32. package/dist/core/modules/ToolsManager.js +40 -31
  33. package/dist/core/nativeGenerateLoop.js +78 -8
  34. package/dist/core/redisConversationMemoryManager.js +8 -15
  35. package/dist/core/toolExecutionGuards.js +1 -13
  36. package/dist/index.d.ts +5 -12
  37. package/dist/index.js +5 -37
  38. package/dist/mcp/batching/requestBatcher.js +1 -1
  39. package/dist/mcp/externalServerManager.js +3 -21
  40. package/dist/mcp/toolDiscoveryService.js +4 -16
  41. package/dist/mcp/toolRegistry.js +2 -5
  42. package/dist/memory/memoryRetrievalTools.js +1 -1
  43. package/dist/neurolink.d.ts +16 -27
  44. package/dist/neurolink.js +788 -792
  45. package/dist/observability/exporterSpanProcessor.d.ts +50 -0
  46. package/dist/observability/exporterSpanProcessor.js +181 -0
  47. package/dist/observability/exporters/langfuseExporter.d.ts +13 -34
  48. package/dist/observability/exporters/langfuseExporter.js +101 -154
  49. package/dist/observability/index.d.ts +1 -0
  50. package/dist/observability/index.js +1 -0
  51. package/dist/observability/langfuseMasking.d.ts +8 -0
  52. package/dist/observability/langfuseMasking.js +47 -0
  53. package/dist/observability/otlpEncoding.d.ts +20 -0
  54. package/dist/observability/otlpEncoding.js +85 -0
  55. package/dist/providers/amazonBedrock/client.js +142 -176
  56. package/dist/providers/amazonBedrock/loopAdapter.js +14 -1
  57. package/dist/providers/amazonSagemaker.js +118 -80
  58. package/dist/providers/anthropic/client.js +3 -52
  59. package/dist/providers/anthropic/loopAdapter.js +24 -1
  60. package/dist/providers/anthropic/rateLimitCapture.js +9 -12
  61. package/dist/providers/googleAiStudio/client.d.ts +4 -5
  62. package/dist/providers/googleAiStudio/client.js +38 -40
  63. package/dist/providers/googleVertex/client.d.ts +2 -7
  64. package/dist/providers/googleVertex/client.js +282 -378
  65. package/dist/providers/googleVertex/constants.js +2 -2
  66. package/dist/providers/litellm/client.d.ts +2 -9
  67. package/dist/providers/litellm/client.js +1 -63
  68. package/dist/providers/openAI/client.d.ts +1 -8
  69. package/dist/providers/openAI/client.js +0 -65
  70. package/dist/providers/openaiChatCompletionsBase.d.ts +1 -0
  71. package/dist/providers/openaiChatCompletionsBase.js +61 -4
  72. package/dist/providers/replicate.js +22 -4
  73. package/dist/proxy/codexUsage.js +7 -0
  74. package/dist/proxy/proxyFetch.js +19 -25
  75. package/dist/proxy/proxyTracer.d.ts +14 -7
  76. package/dist/proxy/proxyTracer.js +129 -83
  77. package/dist/proxy/proxyTranslationEngine.js +0 -1
  78. package/dist/proxy/requestLogger.d.ts +1 -1
  79. package/dist/proxy/requestLogger.js +39 -45
  80. package/dist/server/middleware/auth.d.ts +5 -1
  81. package/dist/server/middleware/auth.js +10 -3
  82. package/dist/server/middleware/common.js +1 -1
  83. package/dist/server/routes/agentRoutes.js +4 -4
  84. package/dist/server/routes/claudeProxyRoutes.js +99 -196
  85. package/dist/server/routes/codexProxyRoutes.js +621 -591
  86. package/dist/server/routes/healthRoutes.js +6 -6
  87. package/dist/server/routes/mcpRoutes.js +7 -7
  88. package/dist/server/routes/memoryRoutes.js +7 -7
  89. package/dist/server/routes/openApiRoutes.js +3 -3
  90. package/dist/server/routes/toolRoutes.js +5 -5
  91. package/dist/server/routes/transcribeRoutes.js +1 -1
  92. package/dist/server/utils/validation.d.ts +3 -3
  93. package/dist/services/server/ai/observability/instrumentation.d.ts +34 -201
  94. package/dist/services/server/ai/observability/instrumentation.js +220 -1267
  95. package/dist/services/server/ai/observability/langfuseSetup.d.ts +14 -0
  96. package/dist/services/server/ai/observability/langfuseSetup.js +55 -0
  97. package/dist/services/server/ai/observability/otlpSetup.d.ts +16 -0
  98. package/dist/services/server/ai/observability/otlpSetup.js +58 -0
  99. package/dist/session/globalSessionState.js +0 -11
  100. package/dist/telemetry/attributes.d.ts +23 -46
  101. package/dist/telemetry/attributes.js +76 -162
  102. package/dist/telemetry/chatMessages.d.ts +13 -0
  103. package/dist/telemetry/chatMessages.js +59 -0
  104. package/dist/telemetry/index.d.ts +5 -19
  105. package/dist/telemetry/index.js +5 -26
  106. package/dist/telemetry/observation.d.ts +37 -0
  107. package/dist/telemetry/observation.js +112 -0
  108. package/dist/telemetry/observationNames.d.ts +18 -0
  109. package/dist/telemetry/observationNames.js +24 -0
  110. package/dist/telemetry/spanSanitizer.d.ts +39 -0
  111. package/dist/telemetry/spanSanitizer.js +92 -0
  112. package/dist/telemetry/spanSerialization.d.ts +13 -0
  113. package/dist/telemetry/spanSerialization.js +46 -0
  114. package/dist/telemetry/tracers.d.ts +37 -18
  115. package/dist/telemetry/tracers.js +97 -19
  116. package/dist/telemetry/withSpan.d.ts +47 -25
  117. package/dist/telemetry/withSpan.js +158 -71
  118. package/dist/types/cli.d.ts +0 -11
  119. package/dist/types/decision.d.ts +3 -0
  120. package/dist/types/exporter.d.ts +54 -0
  121. package/dist/types/exporter.js +0 -4
  122. package/dist/types/generate.d.ts +4 -1
  123. package/dist/types/isolatedAgent.d.ts +5 -4
  124. package/dist/types/loopEngine.d.ts +18 -28
  125. package/dist/types/observability.d.ts +127 -160
  126. package/dist/types/providers.d.ts +15 -0
  127. package/dist/types/proxy.d.ts +41 -2
  128. package/dist/types/server.d.ts +9 -5
  129. package/dist/utils/anthropicTraceSanitizer.d.ts +2 -2
  130. package/dist/utils/anthropicTraceSanitizer.js +3 -1
  131. package/dist/utils/conversationMemory.js +4 -4
  132. package/dist/utils/fileDetector.js +1 -1
  133. package/dist/utils/messageBuilder.js +1 -1
  134. package/dist/utils/noOutputSentinel.d.ts +4 -16
  135. package/dist/utils/noOutputSentinel.js +12 -28
  136. package/dist/utils/providerRetry.js +4 -4
  137. package/dist/voice/livekit/brain.js +1 -1
  138. package/dist/voice/livekit/realtimeMemory.d.ts +1 -1
  139. package/dist/voice/livekit/realtimeMemory.js +66 -1
  140. package/dist/voice/livekit/realtimeVoiceAgent.js +1 -1
  141. package/docs-site/static/search-index.json +42 -64
  142. package/package.json +5 -4
  143. package/dist/telemetry/telemetryService.d.ts +0 -79
  144. package/dist/telemetry/telemetryService.js +0 -572
  145. package/dist/utils/observabilityHelpers.d.ts +0 -27
  146. package/dist/utils/observabilityHelpers.js +0 -47
@@ -28,7 +28,7 @@ export function createHealthRoutes(basePath = "/api") {
28
28
  {
29
29
  method: "GET",
30
30
  path: `${basePath}/health`,
31
- handler: tracedHealthHandler("neurolink.http.health.check", `${basePath}/health`, async () => {
31
+ handler: tracedHealthHandler("http.health.check", `${basePath}/health`, async () => {
32
32
  return {
33
33
  status: "ok",
34
34
  timestamp: new Date().toISOString(),
@@ -42,7 +42,7 @@ export function createHealthRoutes(basePath = "/api") {
42
42
  {
43
43
  method: "GET",
44
44
  path: `${basePath}/health/live`,
45
- handler: tracedHealthHandler("neurolink.http.health.live", `${basePath}/health/live`, async () => {
45
+ handler: tracedHealthHandler("http.health.live", `${basePath}/health/live`, async () => {
46
46
  // Liveness probe - just checks if the server is running
47
47
  return {
48
48
  status: "alive",
@@ -56,7 +56,7 @@ export function createHealthRoutes(basePath = "/api") {
56
56
  method: "GET",
57
57
  path: `${basePath}/health/ready`,
58
58
  handler: (ctx) => withSpan({
59
- name: "neurolink.http.health.ready",
59
+ name: "http.health.ready",
60
60
  tracer: tracers.http,
61
61
  attributes: {
62
62
  "http.route": `${basePath}/health/ready`,
@@ -99,7 +99,7 @@ export function createHealthRoutes(basePath = "/api") {
99
99
  method: "GET",
100
100
  path: `${basePath}/health/startup`,
101
101
  handler: (ctx) => withSpan({
102
- name: "neurolink.http.health.startup",
102
+ name: "http.health.startup",
103
103
  tracer: tracers.http,
104
104
  attributes: {
105
105
  "http.route": `${basePath}/health/startup`,
@@ -126,7 +126,7 @@ export function createHealthRoutes(basePath = "/api") {
126
126
  method: "GET",
127
127
  path: `${basePath}/health/detailed`,
128
128
  handler: (ctx) => withSpan({
129
- name: "neurolink.http.health.detailed",
129
+ name: "http.health.detailed",
130
130
  tracer: tracers.http,
131
131
  attributes: {
132
132
  "http.route": `${basePath}/health/detailed`,
@@ -217,7 +217,7 @@ export function createHealthRoutes(basePath = "/api") {
217
217
  {
218
218
  method: "GET",
219
219
  path: `${basePath}/version`,
220
- handler: tracedHealthHandler("neurolink.http.version", `${basePath}/version`, async () => {
220
+ handler: tracedHealthHandler("http.version", `${basePath}/version`, async () => {
221
221
  return {
222
222
  name: "@juspay/neurolink",
223
223
  version: process.env.npm_package_version || "unknown",
@@ -324,49 +324,49 @@ export function createMCPRoutes(basePath = "/api") {
324
324
  {
325
325
  method: "GET",
326
326
  path: `${basePath}/mcp/servers`,
327
- handler: tracedMcpHandler("neurolink.http.mcp.listServers", `${basePath}/mcp/servers`, handleListServers),
327
+ handler: tracedMcpHandler("http.mcp.listServers", `${basePath}/mcp/servers`, handleListServers),
328
328
  description: "List all MCP servers",
329
329
  tags: ["mcp"],
330
330
  },
331
331
  {
332
332
  method: "GET",
333
333
  path: `${basePath}/mcp/servers/:name`,
334
- handler: tracedMcpHandler("neurolink.http.mcp.getServer", `${basePath}/mcp/servers/:name`, handleGetServer),
334
+ handler: tracedMcpHandler("http.mcp.getServer", `${basePath}/mcp/servers/:name`, handleGetServer),
335
335
  description: "Get MCP server status",
336
336
  tags: ["mcp"],
337
337
  },
338
338
  {
339
339
  method: "POST",
340
340
  path: `${basePath}/mcp/servers/:name/reconnect`,
341
- handler: tracedMcpHandler("neurolink.http.mcp.reconnectServer", `${basePath}/mcp/servers/:name/reconnect`, handleReconnectServer),
341
+ handler: tracedMcpHandler("http.mcp.reconnectServer", `${basePath}/mcp/servers/:name/reconnect`, handleReconnectServer),
342
342
  description: "Reconnect to an MCP server",
343
343
  tags: ["mcp"],
344
344
  },
345
345
  {
346
346
  method: "DELETE",
347
347
  path: `${basePath}/mcp/servers/:name`,
348
- handler: tracedMcpHandler("neurolink.http.mcp.removeServer", `${basePath}/mcp/servers/:name`, handleRemoveServer),
348
+ handler: tracedMcpHandler("http.mcp.removeServer", `${basePath}/mcp/servers/:name`, handleRemoveServer),
349
349
  description: "Remove an MCP server",
350
350
  tags: ["mcp"],
351
351
  },
352
352
  {
353
353
  method: "GET",
354
354
  path: `${basePath}/mcp/servers/:name/tools`,
355
- handler: tracedMcpHandler("neurolink.http.mcp.listServerTools", `${basePath}/mcp/servers/:name/tools`, handleListServerTools),
355
+ handler: tracedMcpHandler("http.mcp.listServerTools", `${basePath}/mcp/servers/:name/tools`, handleListServerTools),
356
356
  description: "List tools from a specific MCP server",
357
357
  tags: ["mcp", "tools"],
358
358
  },
359
359
  {
360
360
  method: "POST",
361
361
  path: `${basePath}/mcp/servers/:name/tools/:toolName/execute`,
362
- handler: tracedMcpHandler("neurolink.http.mcp.executeTool", `${basePath}/mcp/servers/:name/tools/:toolName/execute`, handleExecuteTool),
362
+ handler: tracedMcpHandler("http.mcp.executeTool", `${basePath}/mcp/servers/:name/tools/:toolName/execute`, handleExecuteTool),
363
363
  description: "Execute a tool from a specific MCP server",
364
364
  tags: ["mcp", "tools"],
365
365
  },
366
366
  {
367
367
  method: "GET",
368
368
  path: `${basePath}/mcp/health`,
369
- handler: tracedMcpHandler("neurolink.http.mcp.health", `${basePath}/mcp/health`, handleMCPHealth),
369
+ handler: tracedMcpHandler("http.mcp.health", `${basePath}/mcp/health`, handleMCPHealth),
370
370
  description: "Health check for all MCP servers",
371
371
  tags: ["mcp", "health"],
372
372
  },
@@ -312,7 +312,7 @@ export function createMemoryRoutes(basePath = "/api") {
312
312
  {
313
313
  method: "GET",
314
314
  path: `${basePath}/memory/sessions/:id/messages`,
315
- handler: tracedMemoryHandler("neurolink.http.memory.getSessionMessages", `${basePath}/memory/sessions/:id/messages`, handleGetSessionMessages),
315
+ handler: tracedMemoryHandler("http.memory.getSessionMessages", `${basePath}/memory/sessions/:id/messages`, handleGetSessionMessages),
316
316
  description: "Get messages for a session",
317
317
  tags: ["memory"],
318
318
  },
@@ -320,7 +320,7 @@ export function createMemoryRoutes(basePath = "/api") {
320
320
  {
321
321
  method: "GET",
322
322
  path: `${basePath}/memory/sessions/:id`,
323
- handler: tracedMemoryHandler("neurolink.http.memory.getSession", `${basePath}/memory/sessions/:id`, handleGetSession),
323
+ handler: tracedMemoryHandler("http.memory.getSession", `${basePath}/memory/sessions/:id`, handleGetSession),
324
324
  description: "Get session by ID",
325
325
  tags: ["memory"],
326
326
  },
@@ -328,35 +328,35 @@ export function createMemoryRoutes(basePath = "/api") {
328
328
  {
329
329
  method: "GET",
330
330
  path: `${basePath}/memory/sessions`,
331
- handler: tracedMemoryHandler("neurolink.http.memory.listSessions", `${basePath}/memory/sessions`, handleListSessions),
331
+ handler: tracedMemoryHandler("http.memory.listSessions", `${basePath}/memory/sessions`, handleListSessions),
332
332
  description: "List all conversation sessions",
333
333
  tags: ["memory"],
334
334
  },
335
335
  {
336
336
  method: "GET",
337
337
  path: `${basePath}/memory/stats`,
338
- handler: tracedMemoryHandler("neurolink.http.memory.stats", `${basePath}/memory/stats`, handleGetStats),
338
+ handler: tracedMemoryHandler("http.memory.stats", `${basePath}/memory/stats`, handleGetStats),
339
339
  description: "Get memory statistics",
340
340
  tags: ["memory"],
341
341
  },
342
342
  {
343
343
  method: "DELETE",
344
344
  path: `${basePath}/memory/sessions/:sessionId`,
345
- handler: tracedMemoryHandler("neurolink.http.memory.clearSession", `${basePath}/memory/sessions/:sessionId`, handleClearSession),
345
+ handler: tracedMemoryHandler("http.memory.clearSession", `${basePath}/memory/sessions/:sessionId`, handleClearSession),
346
346
  description: "Clear a conversation session",
347
347
  tags: ["memory"],
348
348
  },
349
349
  {
350
350
  method: "DELETE",
351
351
  path: `${basePath}/memory/sessions`,
352
- handler: tracedMemoryHandler("neurolink.http.memory.clearAllSessions", `${basePath}/memory/sessions`, handleClearAllSessions),
352
+ handler: tracedMemoryHandler("http.memory.clearAllSessions", `${basePath}/memory/sessions`, handleClearAllSessions),
353
353
  description: "Clear all conversation sessions",
354
354
  tags: ["memory"],
355
355
  },
356
356
  {
357
357
  method: "GET",
358
358
  path: `${basePath}/memory/health`,
359
- handler: tracedMemoryHandler("neurolink.http.memory.health", `${basePath}/memory/health`, handleMemoryHealth),
359
+ handler: tracedMemoryHandler("http.memory.health", `${basePath}/memory/health`, handleMemoryHealth),
360
360
  description: "Check memory system health",
361
361
  tags: ["memory", "health"],
362
362
  },
@@ -47,7 +47,7 @@ export function createOpenApiRoutes(basePath = "/api", getRoutes) {
47
47
  method: "GET",
48
48
  path: `${basePath}/openapi.json`,
49
49
  handler: async () => withSpan({
50
- name: "neurolink.http.openapi.json",
50
+ name: "http.openapi.json",
51
51
  tracer: tracers.http,
52
52
  attributes: {
53
53
  "http.route": `${basePath}/openapi.json`,
@@ -76,7 +76,7 @@ export function createOpenApiRoutes(basePath = "/api", getRoutes) {
76
76
  method: "GET",
77
77
  path: `${basePath}/openapi.yaml`,
78
78
  handler: async () => withSpan({
79
- name: "neurolink.http.openapi.yaml",
79
+ name: "http.openapi.yaml",
80
80
  tracer: tracers.http,
81
81
  attributes: {
82
82
  "http.route": `${basePath}/openapi.yaml`,
@@ -109,7 +109,7 @@ export function createOpenApiRoutes(basePath = "/api", getRoutes) {
109
109
  method: "GET",
110
110
  path: `${basePath}/docs`,
111
111
  handler: async () => withSpan({
112
- name: "neurolink.http.openapi.docs",
112
+ name: "http.openapi.docs",
113
113
  tracer: tracers.http,
114
114
  attributes: {
115
115
  "http.route": `${basePath}/docs`,
@@ -23,7 +23,7 @@ export function createToolRoutes(basePath = "/api") {
23
23
  method: "GET",
24
24
  path: `${basePath}/tools`,
25
25
  handler: async (ctx) => withSpan({
26
- name: "neurolink.http.tools.list",
26
+ name: "http.tools.list",
27
27
  tracer: tracers.http,
28
28
  attributes: { "http.route": `${basePath}/tools` },
29
29
  }, async (span) => {
@@ -47,7 +47,7 @@ export function createToolRoutes(basePath = "/api") {
47
47
  method: "GET",
48
48
  path: `${basePath}/tools/search`,
49
49
  handler: async (ctx) => withSpan({
50
- name: "neurolink.http.tools.search",
50
+ name: "http.tools.search",
51
51
  tracer: tracers.http,
52
52
  attributes: {
53
53
  "http.route": `${basePath}/tools/search`,
@@ -96,7 +96,7 @@ export function createToolRoutes(basePath = "/api") {
96
96
  }
97
97
  const request = validation.data;
98
98
  return withSpan({
99
- name: "neurolink.http.tools.execute",
99
+ name: "http.tools.execute",
100
100
  tracer: tracers.http,
101
101
  attributes: {
102
102
  "http.route": `${basePath}/tools/execute`,
@@ -170,7 +170,7 @@ export function createToolRoutes(basePath = "/api") {
170
170
  }
171
171
  const args = bodyValidation.data;
172
172
  return withSpan({
173
- name: "neurolink.http.tools.executeByName",
173
+ name: "http.tools.executeByName",
174
174
  tracer: tracers.http,
175
175
  attributes: {
176
176
  "http.route": `${basePath}/tools/:name/execute`,
@@ -237,7 +237,7 @@ export function createToolRoutes(basePath = "/api") {
237
237
  }
238
238
  const { name } = paramValidation.data;
239
239
  return withSpan({
240
- name: "neurolink.http.tools.get",
240
+ name: "http.tools.get",
241
241
  tracer: tracers.http,
242
242
  attributes: {
243
243
  "http.route": `${basePath}/tools/:name`,
@@ -223,7 +223,7 @@ function classifyError(error) {
223
223
  }
224
224
  async function runTranscription(ctx, route, options) {
225
225
  return withSpan({
226
- name: "neurolink.http.transcribe",
226
+ name: "http.transcribe",
227
227
  tracer: tracers.http,
228
228
  attributes: {
229
229
  "http.route": route,
@@ -192,8 +192,8 @@ export declare const TranscribeConfigSchema: z.ZodObject<{
192
192
  correction: z.ZodOptional<z.ZodObject<{
193
193
  enabled: z.ZodOptional<z.ZodBoolean>;
194
194
  guard: z.ZodOptional<z.ZodEnum<{
195
- none: "none";
196
195
  decide: "decide";
196
+ none: "none";
197
197
  }>>;
198
198
  decideTimeoutMs: z.ZodOptional<z.ZodNumber>;
199
199
  rewrite: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<false>, z.ZodObject<{
@@ -242,8 +242,8 @@ export declare const TranscribeRequestSchema: z.ZodObject<{
242
242
  correction: z.ZodOptional<z.ZodObject<{
243
243
  enabled: z.ZodOptional<z.ZodBoolean>;
244
244
  guard: z.ZodOptional<z.ZodEnum<{
245
- none: "none";
246
245
  decide: "decide";
246
+ none: "none";
247
247
  }>>;
248
248
  decideTimeoutMs: z.ZodOptional<z.ZodNumber>;
249
249
  rewrite: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<false>, z.ZodObject<{
@@ -308,8 +308,8 @@ export declare const TranscribeStreamConfigSchema: z.ZodObject<{
308
308
  correction: z.ZodOptional<z.ZodObject<{
309
309
  enabled: z.ZodOptional<z.ZodBoolean>;
310
310
  guard: z.ZodOptional<z.ZodEnum<{
311
- none: "none";
312
311
  decide: "decide";
312
+ none: "none";
313
313
  }>>;
314
314
  decideTimeoutMs: z.ZodOptional<z.ZodNumber>;
315
315
  rewrite: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<false>, z.ZodObject<{
@@ -1,229 +1,62 @@
1
+ import { type Context } from "@opentelemetry/api";
2
+ import type { NeurolinkTraceContext, ObservabilityConfig, SpanContent } from "../../../../types/index.js";
1
3
  /**
2
- * OpenTelemetry Instrumentation for Langfuse v4
3
- *
4
- * Configures OpenTelemetry TracerProvider with LangfuseSpanProcessor to capture
5
- * traces from Vercel AI SDK's experimental_telemetry feature.
6
- *
7
- * Flow: Vercel AI SDK → OpenTelemetry Spans → LangfuseSpanProcessor → Langfuse Platform
4
+ * @description Starts NeuroLink's tracing once per process, synchronously. Every span created through the shared tracers calls it first, so direct provider calls without a NeuroLink instance are traced too. Langfuse is enabled unless `config.langfuse` is `false`, when an options object is given or `LANGFUSE_PUBLIC_KEY` and `LANGFUSE_SECRET_KEY` are set; an OTLP exporter is added when `OTEL_EXPORTER_OTLP_ENDPOINT` is set. When the host already registered a TracerProvider no provider is created; the Langfuse exporter, if configured, is registered on the shared exporter registry and the host adds `createExporterSpanProcessor()` to its provider. The first call that finds tracing configured decides the setup and a later `config` is ignored; calls made before anything is configured start nothing, so a later config or environment can still start tracing, unless `langfuse: false` was passed. After `shutdownOpenTelemetry` it does nothing.
5
+ * @param config {ObservabilityConfig | undefined} - Observability options, honoured only when this is the first call.
6
+ * @returns {void} Nothing; a failed setup is logged and recorded in `getLangfuseHealthStatus`.
8
7
  */
9
- import { trace, type Span as ApiSpan } from "@opentelemetry/api";
10
- import type { LoggerProvider } from "@opentelemetry/sdk-logs";
11
- import type { SpanProcessor } from "@opentelemetry/sdk-trace-base";
12
- import type { NodeTracerProvider } from "@opentelemetry/sdk-trace-node";
13
- import type { LangfuseConfig, LangfuseContext } from "../../../../types/index.js";
8
+ export declare function ensureTelemetry(config?: ObservabilityConfig): void;
14
9
  /**
15
- * True when a span is an internal NeuroLink wrapper that should NOT be sent to
16
- * Langfuse. Internal wrappers carry the `langfuse.internal: true` attribute.
17
- *
18
- * Exposed so host apps that bring their own `LangfuseSpanProcessor` (e.g.
19
- * `skipLangfuseSpanProcessor: true`, or manual registration on an existing
20
- * TracerProvider) can apply the same filter and avoid duplicate observations.
10
+ * @description Registers a holder of the process-wide telemetry and starts it if needed. Pair every call with `releaseTelemetry`.
11
+ * @param config {ObservabilityConfig | undefined} - Observability options forwarded to `ensureTelemetry`.
12
+ * @returns {void} Nothing.
21
13
  */
22
- export declare function isLangfuseInternalSpan(span: {
23
- attributes?: Record<string, unknown>;
24
- }): boolean;
14
+ export declare function acquireTelemetry(config?: ObservabilityConfig): void;
25
15
  /**
26
- * Drop-in `shouldExportSpan` predicate for a `LangfuseSpanProcessor` that
27
- * filters out NeuroLink internal wrapper spans.
28
- *
29
- * Usage in host apps:
30
- * ```ts
31
- * import { langfuseShouldExportSpan } from "@juspay/neurolink";
32
- * new LangfuseSpanProcessor({ ..., shouldExportSpan: langfuseShouldExportSpan });
33
- * ```
16
+ * @description Releases one holder registered by `acquireTelemetry` and flushes pending spans. The provider stays registered for the process so cached tracers keep working and later instances reuse it.
17
+ * @returns {Promise<void>} Resolves when pending spans are flushed.
18
+ * @throws {Error} When any provider fails to flush.
34
19
  */
35
- export declare function langfuseShouldExportSpan({ otelSpan, }: {
36
- otelSpan: {
37
- attributes?: Record<string, unknown>;
38
- };
39
- }): boolean;
20
+ export declare function releaseTelemetry(): Promise<void>;
40
21
  /**
41
- * Initialize OpenTelemetry once and let concurrent callers share the work.
42
- *
43
- * NeuroLink constructors intentionally start this asynchronously. Keeping the
44
- * in-flight promise here lets another constructor join it and lets an immediate
45
- * flush or shutdown wait for the same initialization before touching providers.
46
- */
47
- export declare function initializeOpenTelemetry(config: LangfuseConfig): Promise<void>;
48
- /**
49
- * Flush all pending spans to Langfuse
22
+ * @description Exports pending spans and metrics from the providers NeuroLink owns and flushes its Langfuse exporter. A host provider is never flushed.
23
+ * @returns {Promise<void>} Resolves when every owned provider has flushed.
24
+ * @throws {Error} When any provider fails to flush.
50
25
  */
51
26
  export declare function flushOpenTelemetry(): Promise<void>;
52
27
  /**
53
- * Shutdown OpenTelemetry and Langfuse span processor
54
- *
55
- * Concurrent callers share one in-flight teardown, the same way concurrent
56
- * initializers share one in-flight `initializeOpenTelemetry`: a second
57
- * shutdown call joins the first instead of tearing down the same provider
58
- * instances a second time.
28
+ * @description Terminally shuts down the providers NeuroLink owns once no `acquireTelemetry` holder remains; while holders remain it only flushes. Telemetry cannot be restarted in this process afterwards. A host provider is never shut down; with one, only NeuroLink's Langfuse exporter is shut down and unregistered.
29
+ * @returns {Promise<void>} Resolves when telemetry is flushed or shut down.
59
30
  */
60
31
  export declare function shutdownOpenTelemetry(): Promise<void>;
61
32
  /**
62
- * Get the Langfuse span processor
63
- */
64
- export declare function getLangfuseSpanProcessor(): SpanProcessor | null;
65
- /**
66
- * Get the tracer provider
67
- */
68
- export declare function getTracerProvider(): NodeTracerProvider | null;
69
- /**
70
- * Get the logger provider for emitting OTLP log records.
71
- * Returns null if OTLP is not configured or LoggerProvider was not created.
72
- */
73
- export declare function getLoggerProvider(): LoggerProvider | null;
74
- /**
75
- * Check if OpenTelemetry is initialized
33
+ * @description Reports whether NeuroLink's tracing is active, either on its own provider or alongside a host provider.
34
+ * @returns {boolean} `true` once `ensureTelemetry` has set tracing up.
76
35
  */
77
36
  export declare function isOpenTelemetryInitialized(): boolean;
78
37
  /**
79
- * Get health status for Langfuse observability
80
- *
81
- * @returns Health status object with initialization and configuration details
38
+ * @description Summarizes the Langfuse export state for health checks.
39
+ * @returns {{ isHealthy: boolean; initialized: boolean; hasProcessor: boolean; usingExternalProvider: boolean; error?: string }} `isHealthy` and `hasProcessor` are `true` only while a Langfuse exporter is registered, on NeuroLink's own provider or beside a host provider (where it still needs `createExporterSpanProcessor()` on the host provider to receive spans); `error` carries the message of a failed initialization.
82
40
  */
83
41
  export declare function getLangfuseHealthStatus(): {
84
42
  isHealthy: boolean;
85
43
  initialized: boolean;
86
- credentialsValid: boolean;
87
- enabled: boolean;
88
44
  hasProcessor: boolean;
89
45
  usingExternalProvider: boolean;
90
- config?: {
91
- baseUrl: string;
92
- environment: string;
93
- release: string;
94
- };
46
+ error?: string;
95
47
  };
96
48
  /**
97
- * Set user and session context for Langfuse spans in the current async context
98
- *
99
- * Merges the provided context with existing AsyncLocalStorage context. If a callback is provided,
100
- * the context is scoped to that callback execution and returns the callback's result.
101
- * Without a callback, the context applies to the current execution context and its children.
102
- *
103
- * Uses AsyncLocalStorage to properly scope context per request, avoiding race conditions
104
- * in concurrent scenarios.
105
- *
106
- * @param context - Object containing context fields to merge with existing context
107
- * @param callback - Optional callback to run within the context scope. If omitted, context applies to current execution
108
- * @returns The callback's return value if provided, otherwise void
109
- *
110
- * @example
111
- * // With callback - returns the result
112
- * const result = await setLangfuseContext({ userId: "user123" }, async () => {
113
- * return await generateText({ model: "gpt-4", prompt: "Hello" });
114
- * });
115
- *
116
- * @example
117
- * // Without callback - sets context for current execution
118
- * await setLangfuseContext({ sessionId: "session456", traceName: "chat-completion" });
119
- */
120
- export declare function setLangfuseContext<T = void>(context: {
121
- userId?: string | null;
122
- sessionId?: string | null;
123
- conversationId?: string | null;
124
- requestId?: string | null;
125
- traceName?: string | null;
126
- metadata?: Record<string, unknown> | null;
127
- /** Langfuse trace tags, set on the trace's root span */
128
- tags?: string[] | null;
129
- /** Explicit operation name (overrides auto-detection) */
130
- operationName?: string | null;
131
- /** Override global autoDetectOperationName for this context */
132
- autoDetectOperationName?: boolean;
133
- /** Custom attributes to set on all spans within this context */
134
- customAttributes?: Record<string, string | number | boolean>;
135
- }, callback?: () => T | Promise<T>): Promise<T | void>;
136
- /**
137
- * Get the current Langfuse context from AsyncLocalStorage
138
- *
139
- * Returns the current context including userId, sessionId, conversationId,
140
- * requestId, traceName, and metadata. Returns undefined if no context is set.
141
- *
142
- * @returns The current LangfuseContext or undefined
143
- *
144
- * @example
145
- * const context = getLangfuseContext();
146
- * console.log(context?.userId, context?.sessionId);
147
- */
148
- export declare function getLangfuseContext(): LangfuseContext | undefined;
149
- /**
150
- * Fill a span's Langfuse identity when the caller's context would otherwise
151
- * fall back to "guest". Identity (user.id / session.id) is set additively —
152
- * only fields ambient context didn't already provide, so a host's own context
153
- * is never overridden. trace.name (the title) is rescued only when no ambient
154
- * name source exists AND this span is the trace root, mirroring
155
- * ContextEnricher.onStart so a host wrapper span isn't relabelled.
156
- */
157
- export declare function stampGuestRescueIdentity(span: ApiSpan, callContext: unknown, isRootSpan: boolean): void;
158
- /**
159
- * Capture the current Langfuse AsyncLocalStorage context and return a wrapper
160
- * that re-enters that context when executing the provided callback.
161
- *
162
- * This is essential for preserving trace context across async boundaries that
163
- * break the automatic ALS propagation chain, such as `setImmediate()`,
164
- * `setTimeout()`, or event-emitter callbacks. Without this, spans created
165
- * inside those callbacks become orphaned traces in Langfuse.
166
- *
167
- * **How it works:**
168
- * 1. Captures the current ALS store at call time (synchronously).
169
- * 2. Returns an async function that, when invoked, re-enters the captured
170
- * context via `contextStorage.run()` before executing the callback.
171
- * 3. If no context exists at capture time, the callback runs without
172
- * ALS wrapping (no-op passthrough).
173
- *
174
- * @param fn - The async function to execute within the captured context
175
- * @returns A new async function that preserves the Langfuse ALS context
176
- *
177
- * @example
178
- * // Before (broken — setImmediate loses ALS context):
179
- * setImmediate(async () => {
180
- * await this.checkAndSummarize(session, threshold);
181
- * });
182
- *
183
- * // After (fixed — context is captured and re-entered):
184
- * const wrappedFn = runWithCurrentLangfuseContext(async () => {
185
- * await this.checkAndSummarize(session, threshold);
186
- * });
187
- * setImmediate(wrappedFn);
49
+ * @description Reads the full trace metadata that `setLangfuseContext` stored on a context.
50
+ * @param ctx {Context} - Context to read, normally the active one.
51
+ * @returns {Record<string, SpanContent>} Metadata set by enclosing `setLangfuseContext` calls, inner keys winning; empty when none was set.
188
52
  */
189
- export declare function runWithCurrentLangfuseContext<T>(fn: () => Promise<T>): () => Promise<T>;
53
+ export declare function traceMetadataFromContext(ctx: Context): Record<string, SpanContent>;
190
54
  /**
191
- * Get an OpenTelemetry Tracer for creating custom spans
192
- *
193
- * This allows applications to create their own spans that will be
194
- * processed by the same span processors (ContextEnricher + LangfuseSpanProcessor).
195
- *
196
- * @param name - Tracer name, defaults to "neurolink"
197
- * @param version - Tracer version, optional
198
- * @returns OpenTelemetry Tracer instance
199
- *
55
+ * @description Runs `fn` with trace attributes propagated to every span it creates. `conversationId` and `requestId` become metadata; empty values are dropped. Metadata values of up to 200 characters once stringified are on every observation; longer values and arrays are recorded in full on the trace only, written by the trace root.
56
+ * @param params {NeurolinkTraceContext} - User, session, trace name, tags and metadata for the trace.
57
+ * @param fn {() => T} - Work to run inside the propagated context.
58
+ * @returns {T} Whatever `fn` returns.
200
59
  * @example
201
- * const tracer = getTracer("my-app");
202
- * const span = tracer.startSpan("custom-operation");
203
- * try {
204
- * // ... do work
205
- * } finally {
206
- * span.end();
207
- * }
208
- */
209
- export declare function getTracer(name?: string, version?: string): ReturnType<typeof trace.getTracer>;
210
- /**
211
- * Create a new ContextEnricher span processor
212
- * Use this when useExternalTracerProvider is true to add to your own TracerProvider
213
- *
214
- * @returns A new ContextEnricher instance
215
- */
216
- export declare function createContextEnricher(): SpanProcessor;
217
- /**
218
- * Get all span processors that NeuroLink would use
219
- * Convenience function that returns [ContextEnricher, LangfuseSpanProcessor]
220
- *
221
- * @returns Array of span processors, or empty array if not initialized
222
- */
223
- export declare function getSpanProcessors(): SpanProcessor[];
224
- /**
225
- * Check if using external TracerProvider mode
226
- *
227
- * @returns true if operating in external TracerProvider mode
60
+ * await setLangfuseContext({ userId: "u1", sessionId: "s1" }, () => neurolink.generate({ input: { text: "hi" } }));
228
61
  */
229
- export declare function isUsingExternalTracerProvider(): boolean;
62
+ export declare function setLangfuseContext<T>(params: NeurolinkTraceContext, fn: () => T): T;