@juspay/neurolink 13.4.10 → 13.5.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 (145) hide show
  1. package/CHANGELOG.md +2 -3
  2. package/README.md +3 -2
  3. package/dist/adapters/video/videoAnalyzer.d.ts +1 -0
  4. package/dist/adapters/video/videoAnalyzer.js +4 -0
  5. package/dist/autoresearch/index.d.ts +1 -0
  6. package/dist/autoresearch/index.js +4 -0
  7. package/dist/autoresearch/worker.js +4 -0
  8. package/dist/browser/neurolink.min.js +466 -466
  9. package/dist/cli/commands/decide.js +25 -5
  10. package/dist/cli/commands/observability.js +11 -4
  11. package/dist/cli/commands/telemetry.js +36 -6
  12. package/dist/cli/utils/formatters.d.ts +17 -0
  13. package/dist/cli/utils/formatters.js +39 -0
  14. package/dist/constants/langfuse.d.ts +17 -1
  15. package/dist/constants/langfuse.js +23 -1
  16. package/dist/constants/telemetry.d.ts +6 -0
  17. package/dist/constants/telemetry.js +6 -0
  18. package/dist/core/baseProvider.js +2 -0
  19. package/dist/core/geminiLoopAdapter.js +19 -0
  20. package/dist/core/loopEngine.js +10 -7
  21. package/dist/core/modules/StreamHandler.js +5 -4
  22. package/dist/core/modules/TelemetryHandler.d.ts +5 -1
  23. package/dist/core/modules/TelemetryHandler.js +16 -0
  24. package/dist/core/modules/ToolsManager.js +3 -0
  25. package/dist/core/nativeGenerateLoop.js +1 -1
  26. package/dist/evaluation/index.d.ts +1 -0
  27. package/dist/evaluation/index.js +4 -0
  28. package/dist/evaluation/ragasEvaluator.js +1 -0
  29. package/dist/factories/providerDescriptors.d.ts +4 -3
  30. package/dist/factories/providerDescriptors.js +6 -4
  31. package/dist/index.d.ts +1 -1
  32. package/dist/index.js +1 -1
  33. package/dist/mcp/externalServerManager.js +6 -2
  34. package/dist/mcp/toolRegistry.js +3 -0
  35. package/dist/neurolink.d.ts +20 -10
  36. package/dist/neurolink.js +134 -65
  37. package/dist/observability/FEATURE-STATUS.md +0 -4
  38. package/dist/observability/exporterRegistry.d.ts +6 -1
  39. package/dist/observability/exporterRegistry.js +18 -0
  40. package/dist/observability/exporterSpanProcessor.d.ts +20 -6
  41. package/dist/observability/exporterSpanProcessor.js +166 -34
  42. package/dist/observability/exporters/baseExporter.d.ts +22 -3
  43. package/dist/observability/exporters/baseExporter.js +87 -5
  44. package/dist/observability/exporters/langfuseExporter.d.ts +29 -3
  45. package/dist/observability/exporters/langfuseExporter.js +251 -41
  46. package/dist/observability/langfuseMasking.d.ts +1 -1
  47. package/dist/observability/langfuseMasking.js +1 -1
  48. package/dist/observability/otlpEncoding.d.ts +18 -5
  49. package/dist/observability/otlpEncoding.js +69 -12
  50. package/dist/observability/utils/spanSerializer.d.ts +3 -2
  51. package/dist/observability/utils/spanSerializer.js +5 -3
  52. package/dist/processors/base/BaseFileProcessor.d.ts +1 -0
  53. package/dist/processors/base/BaseFileProcessor.js +4 -0
  54. package/dist/processors/index.d.ts +1 -0
  55. package/dist/processors/index.js +4 -0
  56. package/dist/processors/registry/ProcessorRegistry.d.ts +1 -0
  57. package/dist/processors/registry/ProcessorRegistry.js +5 -0
  58. package/dist/providers/amazonBedrock/client.js +7 -5
  59. package/dist/providers/amazonSagemaker.js +32 -12
  60. package/dist/providers/anthropic/client.js +1 -0
  61. package/dist/providers/anthropic/loopAdapter.js +7 -3
  62. package/dist/providers/catalog/provider-catalog.schema.json +64 -3
  63. package/dist/providers/catalog/schema.js +81 -1
  64. package/dist/providers/catalog/xor.json +30 -10
  65. package/dist/providers/configuredDecision.d.ts +8 -1
  66. package/dist/providers/configuredDecision.js +22 -0
  67. package/dist/providers/decide/dialects/openaiDecisions.js +8 -0
  68. package/dist/providers/decide/dialects/systemOne.js +28 -2
  69. package/dist/providers/decide/guards.d.ts +6 -0
  70. package/dist/providers/decide/guards.js +22 -0
  71. package/dist/providers/googleAiStudio/client.js +2 -0
  72. package/dist/providers/googleVertex/client.d.ts +6 -5
  73. package/dist/providers/googleVertex/client.js +46 -19
  74. package/dist/providers/openaiChatCompletionsBase.js +4 -4
  75. package/dist/providers/systemOneDecision.d.ts +30 -7
  76. package/dist/providers/systemOneDecision.js +71 -14
  77. package/dist/proxy/codexUsage.js +59 -2
  78. package/dist/proxy/proxyTracer.d.ts +25 -1
  79. package/dist/proxy/proxyTracer.js +146 -22
  80. package/dist/proxy/proxyTranslationEngine.js +4 -2
  81. package/dist/proxy/sseInterceptor.js +6 -4
  82. package/dist/rag/chunkers/BaseChunker.js +1 -0
  83. package/dist/rag/index.d.ts +1 -0
  84. package/dist/rag/index.js +4 -0
  85. package/dist/rag/ragIntegration.js +1 -0
  86. package/dist/rag/reranker/reranker.js +2 -0
  87. package/dist/rag/retrieval/vectorQueryTool.js +1 -0
  88. package/dist/server/routes/codexProxyRoutes.js +3 -1
  89. package/dist/server/utils/validation.d.ts +3 -3
  90. package/dist/services/server/ai/observability/instrumentation.d.ts +8 -7
  91. package/dist/services/server/ai/observability/instrumentation.js +217 -47
  92. package/dist/services/server/ai/observability/langfuseSetup.d.ts +19 -1
  93. package/dist/services/server/ai/observability/langfuseSetup.js +62 -4
  94. package/dist/services/server/ai/observability/otlpSetup.d.ts +12 -2
  95. package/dist/services/server/ai/observability/otlpSetup.js +55 -4
  96. package/dist/telemetry/aiMetrics.d.ts +56 -0
  97. package/dist/telemetry/aiMetrics.js +229 -0
  98. package/dist/telemetry/attributes.d.ts +24 -1
  99. package/dist/telemetry/attributes.js +94 -9
  100. package/dist/telemetry/chatMessages.d.ts +6 -0
  101. package/dist/telemetry/chatMessages.js +37 -0
  102. package/dist/telemetry/index.d.ts +1 -1
  103. package/dist/telemetry/index.js +1 -1
  104. package/dist/telemetry/observation.d.ts +5 -5
  105. package/dist/telemetry/observation.js +128 -39
  106. package/dist/telemetry/spanSanitizer.d.ts +2 -2
  107. package/dist/telemetry/spanSanitizer.js +76 -8
  108. package/dist/telemetry/telemetryStarter.d.ts +16 -0
  109. package/dist/telemetry/telemetryStarter.js +28 -0
  110. package/dist/telemetry/traceContext.d.ts +3 -3
  111. package/dist/telemetry/traceContext.js +3 -3
  112. package/dist/telemetry/tracers.d.ts +13 -1
  113. package/dist/telemetry/tracers.js +49 -10
  114. package/dist/telemetry/withSpan.d.ts +19 -3
  115. package/dist/telemetry/withSpan.js +149 -20
  116. package/dist/types/cli.d.ts +2 -0
  117. package/dist/types/decision.d.ts +117 -10
  118. package/dist/types/exporter.d.ts +98 -3
  119. package/dist/types/livekit.d.ts +16 -1
  120. package/dist/types/loopEngine.d.ts +16 -1
  121. package/dist/types/observability.d.ts +38 -5
  122. package/dist/types/providerCatalog.d.ts +12 -1
  123. package/dist/types/providers.d.ts +2 -0
  124. package/dist/types/proxy.d.ts +2 -0
  125. package/dist/types/span.d.ts +26 -0
  126. package/dist/utils/decisionAnswers.d.ts +7 -1
  127. package/dist/utils/decisionAnswers.js +43 -2
  128. package/dist/utils/decisionLimits.d.ts +13 -1
  129. package/dist/utils/decisionLimits.js +52 -1
  130. package/dist/utils/decisionMedia.d.ts +4 -2
  131. package/dist/utils/decisionMedia.js +216 -14
  132. package/dist/utils/timeout.js +4 -2
  133. package/dist/voice/livekit/realtimeMcpTools.js +11 -2
  134. package/dist/voice/livekit/realtimeMemory.d.ts +20 -2
  135. package/dist/voice/livekit/realtimeMemory.js +139 -46
  136. package/dist/voice/livekit/realtimeVoiceAgent.js +20 -8
  137. package/dist/voice/livekit/turnRecorder.js +22 -9
  138. package/dist/workflow/core/ensembleExecutor.js +2 -0
  139. package/dist/workflow/core/judgeScorer.js +1 -0
  140. package/dist/workflow/core/responseConditioner.js +1 -0
  141. package/dist/workflow/core/workflowRunner.js +6 -1
  142. package/dist/workflow/index.d.ts +1 -0
  143. package/dist/workflow/index.js +4 -0
  144. package/docs-site/static/search-index.json +56 -48
  145. package/package.json +21 -2
@@ -23,7 +23,7 @@ import { createRealtimeLlm, requireXaiApiKey } from "./realtimeModel.js";
23
23
  import { readCallContextFromRoom } from "./roomContext.js";
24
24
  import { attachRealtimeEventBridge } from "./realtimeEventBridge.js";
25
25
  import { buildRealtimeMcpTools } from "./realtimeMcpTools.js";
26
- import { setUpRealtimeCallMemory } from "./realtimeMemory.js";
26
+ import { setUpRealtimeCallMemory, setUpRealtimeCallTracing, } from "./realtimeMemory.js";
27
27
  const realtimeLogEventSchema = z.object({
28
28
  level: z.enum(["debug", "info", "warn", "error"]),
29
29
  message: z.string(),
@@ -219,6 +219,18 @@ export function defineRealtimeVoiceAgent(config = {}) {
219
219
  model: cfg.model,
220
220
  backend: cfg.backend,
221
221
  });
222
+ // Tracing does not depend on memory: a call without it is still traced.
223
+ const recorder = memory?.recorder ??
224
+ setUpRealtimeCallTracing(ctx, {
225
+ model: cfg.model,
226
+ backend: cfg.backend,
227
+ ...(memoryConfig?.settleMs !== undefined
228
+ ? { settleMs: memoryConfig.settleMs }
229
+ : {}),
230
+ ...(memoryConfig?.flushBudgetMs !== undefined
231
+ ? { flushBudgetMs: memoryConfig.flushBudgetMs }
232
+ : {}),
233
+ });
222
234
  await installRealtimeJobLifecycle(ctx, cfg);
223
235
  const { voice } = await import("@livekit/agents");
224
236
  const realtimeLlm = await createRealtimeLlm(cfg);
@@ -249,10 +261,10 @@ export function defineRealtimeVoiceAgent(config = {}) {
249
261
  xContext,
250
262
  publishEvent: bridge.publishEvent,
251
263
  requestConfirmation: bridge.requestConfirmation,
252
- ...(memory
264
+ ...(recorder
253
265
  ? {
254
- onToolStart: (call) => memory.recorder.toolStart(call),
255
- onToolEnd: (call) => memory.recorder.toolEnd(call),
266
+ onToolStart: (call) => recorder.toolStart(call),
267
+ onToolEnd: (call) => recorder.toolEnd(call),
256
268
  }
257
269
  : {}),
258
270
  });
@@ -319,7 +331,7 @@ export function defineRealtimeVoiceAgent(config = {}) {
319
331
  });
320
332
  }
321
333
  bridge.publishEvent("text", { delta: chunk });
322
- memory?.recorder.assistantDelta(chunk);
334
+ recorder?.assistantDelta(chunk);
323
335
  }
324
336
  }
325
337
  }
@@ -358,7 +370,7 @@ export function defineRealtimeVoiceAgent(config = {}) {
358
370
  text: ev.transcript,
359
371
  final: ev.isFinal,
360
372
  });
361
- memory?.recorder.userTranscript({
373
+ recorder?.userTranscript({
362
374
  text: ev.transcript,
363
375
  final: ev.isFinal,
364
376
  });
@@ -379,7 +391,7 @@ export function defineRealtimeVoiceAgent(config = {}) {
379
391
  // The id the stored messages carry, so a client can merge its live
380
392
  // copy of the turn with history instead of showing it twice.
381
393
  bridge.publishEvent("done", memory ? { turnId: ev.item.id } : {});
382
- memory?.recorder.assistantMessage({
394
+ recorder?.assistantMessage({
383
395
  id: ev.item.id,
384
396
  text: ev.item.textContent,
385
397
  interrupted: ev.item.interrupted,
@@ -398,7 +410,7 @@ export function defineRealtimeVoiceAgent(config = {}) {
398
410
  bridge.publishEvent("status", { state: "listening" });
399
411
  if (cfg.greeting.trim().length > 0) {
400
412
  logger.info("realtime.session.greeting", { ms: sinceConnect() });
401
- memory?.recorder.expectGreeting();
413
+ recorder?.expectGreeting();
402
414
  session.generateReply({ instructions: cfg.greeting });
403
415
  }
404
416
  }
@@ -102,6 +102,18 @@ async function writeWithRetry(record, context) {
102
102
  /* a failure sink must never break the call */
103
103
  }
104
104
  }
105
+ /** The stored form of a closed exchange. */
106
+ function turnRecord(exchange) {
107
+ return {
108
+ turnId: exchange.turnId,
109
+ userMessage: exchange.user,
110
+ aiResponse: exchange.assistant,
111
+ interrupted: exchange.interrupted,
112
+ callEnded: exchange.callEnded,
113
+ startTime: new Date(exchange.startedAt),
114
+ ...(exchange.events.length > 0 ? { events: exchange.events } : {}),
115
+ };
116
+ }
105
117
  /** Create a recorder for one call. */
106
118
  export function createVoiceTurnRecorder(options) {
107
119
  const settleMs = options.settleMs ?? DEFAULT_SETTLE_MS;
@@ -165,15 +177,14 @@ export function createVoiceTurnRecorder(options) {
165
177
  });
166
178
  }
167
179
  function finishExchange(exchange) {
168
- enqueue({
169
- turnId: exchange.turnId,
170
- userMessage: exchange.user,
171
- aiResponse: exchange.assistant,
172
- interrupted: exchange.interrupted,
173
- callEnded: exchange.callEnded,
174
- startTime: new Date(exchange.startedAt),
175
- ...(exchange.events.length > 0 ? { events: exchange.events } : {}),
176
- });
180
+ const record = turnRecord(exchange);
181
+ try {
182
+ options.onClosed?.(record);
183
+ }
184
+ catch {
185
+ /* an observer of closed exchanges must never break the call */
186
+ }
187
+ enqueue(record);
177
188
  }
178
189
  function syntheticTurnId() {
179
190
  syntheticTurns += 1;
@@ -297,6 +308,7 @@ export function createVoiceTurnRecorder(options) {
297
308
  open.events.push(nextEvent("tool:start", {
298
309
  tool: call.name,
299
310
  toolName: call.name,
311
+ ...(call.callId !== undefined ? { callId: call.callId } : {}),
300
312
  ...(call.args !== undefined
301
313
  ? { args: boundedPayload(call.args) }
302
314
  : {}),
@@ -309,6 +321,7 @@ export function createVoiceTurnRecorder(options) {
309
321
  open.events.push(nextEvent("tool:end", {
310
322
  tool: call.name,
311
323
  toolName: call.name,
324
+ ...(call.callId !== undefined ? { callId: call.callId } : {}),
312
325
  success: call.error === undefined,
313
326
  ...(call.error !== undefined
314
327
  ? { error: boundedText(call.error) }
@@ -23,6 +23,7 @@ export async function executeEnsemble(options) {
23
23
  return withSpan({
24
24
  name: "neurolink.workflow.ensemble.execute",
25
25
  tracer: tracers.workflow,
26
+ observationType: "span",
26
27
  attributes: {
27
28
  "workflow.model_count": options.models.length,
28
29
  "workflow.parallelism": options.executionConfig?.parallelism ?? 10,
@@ -318,6 +319,7 @@ export async function executeModelGroups(groups, prompt, _executionConfig, syste
318
319
  return withSpan({
319
320
  name: "neurolink.workflow.layers.execute",
320
321
  tracer: tracers.workflow,
322
+ observationType: "span",
321
323
  attributes: {
322
324
  "workflow.group_count": groups.length,
323
325
  "workflow.total_models": groups.reduce((n, g) => n + g.models.length, 0),
@@ -23,6 +23,7 @@ export async function scoreEnsemble(options) {
23
23
  return withSpan({
24
24
  name: "neurolink.workflow.judge.score",
25
25
  tracer: tracers.workflow,
26
+ observationType: "span",
26
27
  attributes: {
27
28
  "workflow.judges_count": options.judges.length,
28
29
  "workflow.responses_count": options.responses.length,
@@ -23,6 +23,7 @@ export async function conditionResponse(options) {
23
23
  return withSpan({
24
24
  name: "neurolink.workflow.response.condition",
25
25
  tracer: tracers.workflow,
26
+ observationType: "span",
26
27
  attributes: {
27
28
  "workflow.conditioning.enabled": Boolean(options.config?.useConfidence),
28
29
  "workflow.conditioning.has_synthesis_model": Boolean(options.config?.synthesisModel),
@@ -14,6 +14,7 @@
14
14
  import { SpanStatusCode } from "@opentelemetry/api";
15
15
  import { logger } from "../../utils/logger.js";
16
16
  import { SpanSerializer, SpanType, SpanStatus, getMetricsAggregator, } from "../../observability/index.js";
17
+ import { observe } from "../../telemetry/observation.js";
17
18
  import { withSpan } from "../../telemetry/withSpan.js";
18
19
  import { tracers } from "../../telemetry/tracers.js";
19
20
  import { getModelGroups, PLACEHOLDER_MODEL, PLACEHOLDER_PROVIDER, usesModelGroups, } from "../config.js";
@@ -51,6 +52,7 @@ export async function runWorkflow(config, options) {
51
52
  return withSpan({
52
53
  name: "neurolink.workflow.run",
53
54
  tracer: tracers.sdk,
55
+ observationType: "span",
54
56
  attributes: {
55
57
  "workflow.name": config.name,
56
58
  "workflow.type": config.type,
@@ -486,7 +488,10 @@ export async function* runWorkflowWithStreaming(config, options) {
486
488
  "workflow.type": config.type,
487
489
  "workflow.id": config.id ?? "unknown",
488
490
  },
489
- }, (otelSpan) => runWorkflowStreamingInner(config, options, otelSpan));
491
+ }, (otelSpan) => {
492
+ observe(otelSpan, "span", {});
493
+ return runWorkflowStreamingInner(config, options, otelSpan);
494
+ });
490
495
  yield* generator;
491
496
  }
492
497
  async function* runWorkflowStreamingInner(config, options, otelSpan) {
@@ -1,3 +1,4 @@
1
+ import "../services/server/ai/observability/instrumentation.js";
1
2
  export { createWorkflowConfig, DEFAULT_EXECUTION_CONFIG, DEFAULT_JUDGE_CONFIG, getAllModels, getModelGroups, usesModelGroups, WorkflowConfigSchema, } from "./config.js";
2
3
  export { clearRegistry, getRegistryStats, getWorkflow, listWorkflows, registerWorkflow, unregisterWorkflow, } from "./core/workflowRegistry.js";
3
4
  export { runWorkflow } from "./core/workflowRunner.js";
@@ -1,3 +1,7 @@
1
+ // Imported on its own, this entry starts tracing at its first span, as the
2
+ // main entry does. The import sits here rather than in the shared tracers so
3
+ // that the client entry stays free of the OpenTelemetry Node SDK.
4
+ import "../services/server/ai/observability/instrumentation.js";
1
5
  // ============================================================================
2
6
  // CORE FUNCTIONS
3
7
  // ============================================================================