@juspay/neurolink 9.24.0 → 9.25.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 (215) hide show
  1. package/CHANGELOG.md +6 -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 +158 -102
  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 +158 -102
  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 +984 -566
  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 +200 -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 +553 -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 +288 -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/spanSerializer.d.ts +115 -0
  116. package/dist/lib/observability/utils/spanSerializer.js +287 -0
  117. package/dist/lib/providers/amazonSagemaker.d.ts +5 -4
  118. package/dist/lib/providers/amazonSagemaker.js +3 -4
  119. package/dist/lib/providers/googleVertex.d.ts +7 -0
  120. package/dist/lib/providers/googleVertex.js +80 -2
  121. package/dist/lib/rag/pipeline/RAGPipeline.d.ts +0 -5
  122. package/dist/lib/rag/pipeline/RAGPipeline.js +122 -87
  123. package/dist/lib/rag/ragIntegration.js +30 -0
  124. package/dist/lib/rag/retrieval/hybridSearch.js +22 -0
  125. package/dist/lib/server/abstract/baseServerAdapter.js +51 -19
  126. package/dist/lib/server/middleware/common.js +44 -12
  127. package/dist/lib/services/server/ai/observability/instrumentation.d.ts +2 -2
  128. package/dist/lib/services/server/ai/observability/instrumentation.js +10 -5
  129. package/dist/lib/types/conversationMemoryInterface.d.ts +2 -0
  130. package/dist/lib/types/modelTypes.d.ts +18 -18
  131. package/dist/lib/types/providers.d.ts +5 -0
  132. package/dist/lib/utils/pricing.js +25 -1
  133. package/dist/lib/utils/ttsProcessor.js +74 -59
  134. package/dist/lib/workflow/config.d.ts +36 -36
  135. package/dist/lib/workflow/core/ensembleExecutor.js +10 -0
  136. package/dist/lib/workflow/core/judgeScorer.js +20 -2
  137. package/dist/lib/workflow/core/workflowRunner.js +34 -1
  138. package/dist/mcp/httpRateLimiter.js +39 -12
  139. package/dist/mcp/httpRetryHandler.js +22 -1
  140. package/dist/mcp/mcpClientFactory.js +13 -15
  141. package/dist/memory/memoryRetrievalTools.js +22 -0
  142. package/dist/neurolink.d.ts +64 -72
  143. package/dist/neurolink.js +984 -566
  144. package/dist/observability/FEATURE-STATUS.md +269 -0
  145. package/dist/observability/exporterRegistry.d.ts +152 -0
  146. package/dist/observability/exporterRegistry.js +413 -0
  147. package/dist/observability/exporters/arizeExporter.d.ts +32 -0
  148. package/dist/observability/exporters/arizeExporter.js +138 -0
  149. package/dist/observability/exporters/baseExporter.d.ts +117 -0
  150. package/dist/observability/exporters/baseExporter.js +190 -0
  151. package/dist/observability/exporters/braintrustExporter.d.ts +30 -0
  152. package/dist/observability/exporters/braintrustExporter.js +154 -0
  153. package/dist/observability/exporters/datadogExporter.d.ts +37 -0
  154. package/dist/observability/exporters/datadogExporter.js +196 -0
  155. package/dist/observability/exporters/index.d.ts +13 -0
  156. package/dist/observability/exporters/index.js +13 -0
  157. package/dist/observability/exporters/laminarExporter.d.ts +48 -0
  158. package/dist/observability/exporters/laminarExporter.js +302 -0
  159. package/dist/observability/exporters/langfuseExporter.d.ts +47 -0
  160. package/dist/observability/exporters/langfuseExporter.js +199 -0
  161. package/dist/observability/exporters/langsmithExporter.d.ts +26 -0
  162. package/dist/observability/exporters/langsmithExporter.js +123 -0
  163. package/dist/observability/exporters/otelExporter.d.ts +39 -0
  164. package/dist/observability/exporters/otelExporter.js +164 -0
  165. package/dist/observability/exporters/posthogExporter.d.ts +48 -0
  166. package/dist/observability/exporters/posthogExporter.js +287 -0
  167. package/dist/observability/exporters/sentryExporter.d.ts +32 -0
  168. package/dist/observability/exporters/sentryExporter.js +165 -0
  169. package/dist/observability/index.d.ts +25 -0
  170. package/dist/observability/index.js +31 -0
  171. package/dist/observability/metricsAggregator.d.ts +260 -0
  172. package/dist/observability/metricsAggregator.js +552 -0
  173. package/dist/observability/otelBridge.d.ts +49 -0
  174. package/dist/observability/otelBridge.js +131 -0
  175. package/dist/observability/retryPolicy.d.ts +192 -0
  176. package/dist/observability/retryPolicy.js +383 -0
  177. package/dist/observability/sampling/index.d.ts +4 -0
  178. package/dist/observability/sampling/index.js +4 -0
  179. package/dist/observability/sampling/samplers.d.ts +116 -0
  180. package/dist/observability/sampling/samplers.js +216 -0
  181. package/dist/observability/spanProcessor.d.ts +129 -0
  182. package/dist/observability/spanProcessor.js +287 -0
  183. package/dist/observability/tokenTracker.d.ts +156 -0
  184. package/dist/observability/tokenTracker.js +413 -0
  185. package/dist/observability/types/exporterTypes.d.ts +250 -0
  186. package/dist/observability/types/exporterTypes.js +5 -0
  187. package/dist/observability/types/index.d.ts +6 -0
  188. package/dist/observability/types/index.js +4 -0
  189. package/dist/observability/types/spanTypes.d.ts +244 -0
  190. package/dist/observability/types/spanTypes.js +92 -0
  191. package/dist/observability/utils/index.d.ts +4 -0
  192. package/dist/observability/utils/index.js +4 -0
  193. package/dist/observability/utils/spanSerializer.d.ts +115 -0
  194. package/dist/observability/utils/spanSerializer.js +286 -0
  195. package/dist/providers/amazonSagemaker.d.ts +5 -4
  196. package/dist/providers/amazonSagemaker.js +3 -4
  197. package/dist/providers/googleVertex.d.ts +7 -0
  198. package/dist/providers/googleVertex.js +80 -2
  199. package/dist/rag/pipeline/RAGPipeline.d.ts +0 -5
  200. package/dist/rag/pipeline/RAGPipeline.js +122 -87
  201. package/dist/rag/ragIntegration.js +30 -0
  202. package/dist/rag/retrieval/hybridSearch.js +22 -0
  203. package/dist/server/abstract/baseServerAdapter.js +51 -19
  204. package/dist/server/middleware/common.js +44 -12
  205. package/dist/services/server/ai/observability/instrumentation.d.ts +2 -2
  206. package/dist/services/server/ai/observability/instrumentation.js +10 -5
  207. package/dist/types/conversationMemoryInterface.d.ts +2 -0
  208. package/dist/types/providers.d.ts +5 -0
  209. package/dist/utils/pricing.js +25 -1
  210. package/dist/utils/ttsProcessor.js +74 -59
  211. package/dist/workflow/config.d.ts +52 -52
  212. package/dist/workflow/core/ensembleExecutor.js +10 -0
  213. package/dist/workflow/core/judgeScorer.js +20 -2
  214. package/dist/workflow/core/workflowRunner.js +34 -1
  215. package/package.json +1 -1
@@ -0,0 +1,453 @@
1
+ #!/usr/bin/env node
2
+ /* eslint-disable no-console, curly */
3
+ /**
4
+ * NeuroLink CLI Observability Commands
5
+ *
6
+ * Commands for monitoring and managing observability features:
7
+ * - status: Show telemetry status
8
+ * - metrics: Show metrics summary
9
+ * - exporters: List configured exporters
10
+ * - costs: Show cost breakdown
11
+ */
12
+ import chalk from "chalk";
13
+ import ora from "ora";
14
+ import { logger } from "../../lib/utils/logger.js";
15
+ import { NeuroLink } from "../../lib/neurolink.js";
16
+ import { formatRow, formatCost } from "../utils/formatters.js";
17
+ /**
18
+ * Observability Command Factory
19
+ */
20
+ export class ObservabilityCommandFactory {
21
+ /**
22
+ * Create the observability command group
23
+ */
24
+ static createObservabilityCommands() {
25
+ return {
26
+ command: "observability <subcommand>",
27
+ aliases: ["obs", "otel"],
28
+ describe: "Observability and telemetry management",
29
+ builder: (yargs) => {
30
+ return yargs
31
+ .command(ObservabilityCommandFactory.createStatusCommand())
32
+ .command(ObservabilityCommandFactory.createMetricsCommand())
33
+ .command(ObservabilityCommandFactory.createExportersCommand())
34
+ .command(ObservabilityCommandFactory.createCostsCommand())
35
+ .demandCommand(1, "Please specify a subcommand")
36
+ .strict();
37
+ },
38
+ handler: () => {
39
+ // This handler is not called directly due to demandCommand
40
+ },
41
+ };
42
+ }
43
+ /**
44
+ * Create the status subcommand
45
+ */
46
+ static createStatusCommand() {
47
+ return {
48
+ command: "status",
49
+ describe: "Show telemetry and observability status",
50
+ builder: (yargs) => {
51
+ return yargs
52
+ .option("format", {
53
+ alias: "f",
54
+ type: "string",
55
+ choices: ["text", "json", "table"],
56
+ default: "text",
57
+ describe: "Output format",
58
+ })
59
+ .option("quiet", {
60
+ alias: "q",
61
+ type: "boolean",
62
+ default: false,
63
+ describe: "Minimal output",
64
+ });
65
+ },
66
+ handler: async (args) => {
67
+ const spinner = args.quiet
68
+ ? null
69
+ : ora("Checking observability status...").start();
70
+ try {
71
+ const neurolink = new NeuroLink();
72
+ const status = neurolink.getTelemetryStatus();
73
+ if (spinner)
74
+ spinner.succeed("Status retrieved");
75
+ if (args.format === "json") {
76
+ console.log(JSON.stringify(status, null, 2));
77
+ }
78
+ else {
79
+ console.log("");
80
+ console.log(chalk.bold.cyan("=== Observability Status ==="));
81
+ console.log("");
82
+ // Telemetry enabled status
83
+ const enabledIcon = status.enabled
84
+ ? chalk.green("ON")
85
+ : chalk.red("OFF");
86
+ console.log(formatRow("Telemetry:", enabledIcon));
87
+ // Langfuse status
88
+ if (status.langfuse) {
89
+ console.log("");
90
+ console.log(chalk.bold("Langfuse:"));
91
+ const lfStatus = status.langfuse.enabled
92
+ ? chalk.green("Enabled")
93
+ : chalk.gray("Disabled");
94
+ console.log(formatRow(" Status:", lfStatus));
95
+ if (status.langfuse.baseUrl) {
96
+ console.log(formatRow(" URL:", status.langfuse.baseUrl));
97
+ }
98
+ if (status.langfuse.environment) {
99
+ console.log(formatRow(" Environment:", status.langfuse.environment));
100
+ }
101
+ }
102
+ // OpenTelemetry status
103
+ if (status.openTelemetry) {
104
+ console.log("");
105
+ console.log(chalk.bold("OpenTelemetry:"));
106
+ const otelStatus = status.openTelemetry.enabled
107
+ ? chalk.green("Enabled")
108
+ : chalk.gray("Disabled");
109
+ console.log(formatRow(" Status:", otelStatus));
110
+ if (status.openTelemetry.endpoint) {
111
+ console.log(formatRow(" Endpoint:", status.openTelemetry.endpoint));
112
+ }
113
+ if (status.openTelemetry.serviceName) {
114
+ console.log(formatRow(" Service:", status.openTelemetry.serviceName));
115
+ }
116
+ }
117
+ // Exporters summary
118
+ if (status.exporters && status.exporters.length > 0) {
119
+ console.log("");
120
+ console.log(chalk.bold("Active Exporters:"));
121
+ for (const exporter of status.exporters) {
122
+ const exporterStatus = exporter.healthy
123
+ ? chalk.green("Healthy")
124
+ : chalk.red("Unhealthy");
125
+ console.log(formatRow(` ${exporter.name}:`, exporterStatus));
126
+ }
127
+ }
128
+ console.log("");
129
+ }
130
+ }
131
+ catch (error) {
132
+ if (spinner)
133
+ spinner.fail("Failed to get status");
134
+ logger.error("Error:", error instanceof Error ? error.message : String(error));
135
+ process.exit(1);
136
+ }
137
+ },
138
+ };
139
+ }
140
+ /**
141
+ * Create the metrics subcommand
142
+ */
143
+ static createMetricsCommand() {
144
+ return {
145
+ command: "metrics",
146
+ describe: "Show metrics summary",
147
+ builder: (yargs) => {
148
+ return yargs
149
+ .option("format", {
150
+ alias: "f",
151
+ type: "string",
152
+ choices: ["text", "json", "table"],
153
+ default: "text",
154
+ describe: "Output format",
155
+ })
156
+ .option("detailed", {
157
+ alias: "d",
158
+ type: "boolean",
159
+ default: false,
160
+ describe: "Show detailed metrics including percentiles",
161
+ })
162
+ .option("quiet", {
163
+ alias: "q",
164
+ type: "boolean",
165
+ default: false,
166
+ describe: "Minimal output",
167
+ });
168
+ },
169
+ handler: async (args) => {
170
+ const spinner = args.quiet ? null : ora("Gathering metrics...").start();
171
+ try {
172
+ const neurolink = new NeuroLink();
173
+ const metrics = neurolink.getMetrics();
174
+ if (spinner)
175
+ spinner.succeed("Metrics retrieved");
176
+ if (args.format === "json") {
177
+ console.log(JSON.stringify(metrics, null, 2));
178
+ }
179
+ else {
180
+ console.log("");
181
+ console.log(chalk.bold.cyan("=== Metrics Summary ==="));
182
+ console.log("");
183
+ // Request statistics
184
+ console.log(chalk.bold("Request Statistics:"));
185
+ console.log(formatRow(" Total requests:", metrics.totalSpans.toLocaleString()));
186
+ console.log(formatRow(" Successful:", metrics.successfulSpans.toLocaleString()));
187
+ console.log(formatRow(" Failed:", metrics.failedSpans.toLocaleString()));
188
+ console.log(formatRow(" Success rate:", `${(metrics.successRate * 100).toFixed(2)}%`));
189
+ // Latency statistics
190
+ if (metrics.latency && metrics.latency.count > 0) {
191
+ console.log("");
192
+ console.log(chalk.bold("Latency (ms):"));
193
+ console.log(formatRow(" Min:", metrics.latency.min.toFixed(2)));
194
+ console.log(formatRow(" Max:", metrics.latency.max.toFixed(2)));
195
+ console.log(formatRow(" Mean:", metrics.latency.mean.toFixed(2)));
196
+ console.log(formatRow(" P50:", metrics.latency.p50.toFixed(2)));
197
+ console.log(formatRow(" P95:", metrics.latency.p95.toFixed(2)));
198
+ console.log(formatRow(" P99:", metrics.latency.p99.toFixed(2)));
199
+ if (args.detailed) {
200
+ console.log(formatRow(" P75:", metrics.latency.p75.toFixed(2)));
201
+ console.log(formatRow(" P90:", metrics.latency.p90.toFixed(2)));
202
+ console.log(formatRow(" Std Dev:", metrics.latency.stdDev.toFixed(2)));
203
+ }
204
+ }
205
+ // Token statistics
206
+ if (metrics.tokens) {
207
+ console.log("");
208
+ console.log(chalk.bold("Token Usage:"));
209
+ console.log(formatRow(" Input tokens:", metrics.tokens.totalInputTokens.toLocaleString()));
210
+ console.log(formatRow(" Output tokens:", metrics.tokens.totalOutputTokens.toLocaleString()));
211
+ console.log(formatRow(" Total tokens:", metrics.tokens.totalTokens.toLocaleString()));
212
+ if (args.detailed &&
213
+ metrics.tokens.cacheReadTokens &&
214
+ metrics.tokens.cacheReadTokens > 0) {
215
+ console.log(formatRow(" Cache read:", metrics.tokens.cacheReadTokens.toLocaleString()));
216
+ }
217
+ if (args.detailed &&
218
+ metrics.tokens.reasoningTokens &&
219
+ metrics.tokens.reasoningTokens > 0) {
220
+ console.log(formatRow(" Reasoning:", metrics.tokens.reasoningTokens.toLocaleString()));
221
+ }
222
+ }
223
+ // Cost
224
+ if (metrics.totalCost !== undefined && metrics.totalCost > 0) {
225
+ console.log("");
226
+ console.log(chalk.bold("Cost:"));
227
+ console.log(formatRow(" Total:", formatCost(metrics.totalCost)));
228
+ }
229
+ // Tracking duration
230
+ if (metrics.trackingDurationMs) {
231
+ const durationSec = metrics.trackingDurationMs / 1000;
232
+ const throughput = metrics.totalSpans > 0 ? metrics.totalSpans / durationSec : 0;
233
+ console.log("");
234
+ console.log(chalk.gray(`Tracking: ${durationSec.toFixed(1)}s (${throughput.toFixed(2)} req/s)`));
235
+ }
236
+ console.log("");
237
+ }
238
+ }
239
+ catch (error) {
240
+ if (spinner)
241
+ spinner.fail("Failed to get metrics");
242
+ logger.error("Error:", error instanceof Error ? error.message : String(error));
243
+ process.exit(1);
244
+ }
245
+ },
246
+ };
247
+ }
248
+ /**
249
+ * Create the exporters subcommand
250
+ */
251
+ static createExportersCommand() {
252
+ return {
253
+ command: "exporters",
254
+ aliases: ["exp"],
255
+ describe: "List configured exporters",
256
+ builder: (yargs) => {
257
+ return yargs
258
+ .option("format", {
259
+ alias: "f",
260
+ type: "string",
261
+ choices: ["text", "json", "table"],
262
+ default: "text",
263
+ describe: "Output format",
264
+ })
265
+ .option("quiet", {
266
+ alias: "q",
267
+ type: "boolean",
268
+ default: false,
269
+ describe: "Minimal output",
270
+ });
271
+ },
272
+ handler: async (args) => {
273
+ const spinner = args.quiet
274
+ ? null
275
+ : ora("Checking exporters...").start();
276
+ try {
277
+ const neurolink = new NeuroLink();
278
+ const status = neurolink.getTelemetryStatus();
279
+ if (spinner)
280
+ spinner.succeed("Exporters retrieved");
281
+ const exporters = status.exporters ?? [];
282
+ if (args.format === "json") {
283
+ console.log(JSON.stringify(exporters, null, 2));
284
+ }
285
+ else {
286
+ console.log("");
287
+ console.log(chalk.bold.cyan("=== Configured Exporters ==="));
288
+ console.log("");
289
+ if (exporters.length === 0) {
290
+ console.log(chalk.gray("No exporters configured."));
291
+ console.log("");
292
+ console.log("Available exporters:");
293
+ console.log(" - Langfuse (langfuse)");
294
+ console.log(" - LangSmith (langsmith)");
295
+ console.log(" - OpenTelemetry (otel)");
296
+ console.log(" - Datadog (datadog)");
297
+ console.log(" - Sentry (sentry)");
298
+ console.log(" - Braintrust (braintrust)");
299
+ console.log(" - Arize (arize)");
300
+ console.log(" - PostHog (posthog)");
301
+ console.log(" - Laminar (laminar)");
302
+ }
303
+ else {
304
+ for (const exporter of exporters) {
305
+ const healthIcon = exporter.healthy
306
+ ? chalk.green("[OK]")
307
+ : chalk.red("[ERROR]");
308
+ console.log(`${healthIcon} ${chalk.bold(exporter.name)}`);
309
+ if (exporter.latencyMs !== undefined) {
310
+ console.log(formatRow(" Latency:", `${exporter.latencyMs.toFixed(2)}ms`));
311
+ }
312
+ if (exporter.pendingSpans !== undefined) {
313
+ console.log(formatRow(" Pending spans:", exporter.pendingSpans.toLocaleString()));
314
+ }
315
+ if (exporter.lastExportTime) {
316
+ const lastExport = new Date(exporter.lastExportTime);
317
+ console.log(formatRow(" Last export:", lastExport.toISOString()));
318
+ }
319
+ if (exporter.errors && exporter.errors.length > 0) {
320
+ console.log(chalk.yellow(" Errors:"));
321
+ for (const error of exporter.errors.slice(0, 3)) {
322
+ console.log(chalk.red(` - ${error}`));
323
+ }
324
+ }
325
+ console.log("");
326
+ }
327
+ }
328
+ }
329
+ }
330
+ catch (error) {
331
+ if (spinner)
332
+ spinner.fail("Failed to get exporters");
333
+ logger.error("Error:", error instanceof Error ? error.message : String(error));
334
+ process.exit(1);
335
+ }
336
+ },
337
+ };
338
+ }
339
+ /**
340
+ * Create the costs subcommand
341
+ */
342
+ static createCostsCommand() {
343
+ return {
344
+ command: "costs",
345
+ aliases: ["cost"],
346
+ describe: "Show cost breakdown",
347
+ builder: (yargs) => {
348
+ return yargs
349
+ .option("format", {
350
+ alias: "f",
351
+ type: "string",
352
+ choices: ["text", "json", "table"],
353
+ default: "text",
354
+ describe: "Output format",
355
+ })
356
+ .option("by-model", {
357
+ alias: "m",
358
+ type: "boolean",
359
+ default: true,
360
+ describe: "Show cost breakdown by model",
361
+ })
362
+ .option("by-provider", {
363
+ alias: "p",
364
+ type: "boolean",
365
+ default: true,
366
+ describe: "Show cost breakdown by provider",
367
+ })
368
+ .option("quiet", {
369
+ alias: "q",
370
+ type: "boolean",
371
+ default: false,
372
+ describe: "Minimal output",
373
+ });
374
+ },
375
+ handler: async (args) => {
376
+ const spinner = args.quiet ? null : ora("Calculating costs...").start();
377
+ try {
378
+ const neurolink = new NeuroLink();
379
+ const metrics = neurolink.getMetrics();
380
+ if (spinner)
381
+ spinner.succeed("Costs calculated");
382
+ if (args.format === "json") {
383
+ const jsonOutput = {
384
+ totalCost: metrics.totalCost,
385
+ };
386
+ if (args.byProvider !== false) {
387
+ jsonOutput.costByProvider = metrics.costByProvider;
388
+ }
389
+ if (args.byModel !== false) {
390
+ jsonOutput.costByModel = metrics.costByModel;
391
+ }
392
+ console.log(JSON.stringify(jsonOutput, null, 2));
393
+ }
394
+ else {
395
+ console.log("");
396
+ console.log(chalk.bold.cyan("=== Cost Breakdown ==="));
397
+ console.log("");
398
+ // Total cost
399
+ console.log(chalk.bold(`Total Cost: ${formatCost(metrics.totalCost ?? 0)}`));
400
+ // Cost by provider
401
+ if (args.byProvider !== false &&
402
+ metrics.costByProvider &&
403
+ metrics.costByProvider.length > 0) {
404
+ console.log("");
405
+ console.log(chalk.bold("By Provider:"));
406
+ // Sort by cost descending
407
+ const sortedProviders = [...metrics.costByProvider].sort((a, b) => b.totalCost - a.totalCost);
408
+ for (const provider of sortedProviders) {
409
+ const costStr = formatCost(provider.totalCost);
410
+ const avgCost = formatCost(provider.avgCostPerRequest);
411
+ console.log(` ${chalk.cyan(provider.provider.padEnd(15))} ${costStr}`);
412
+ console.log(chalk.gray(` ${provider.requestCount} requests, avg ${avgCost}/req`));
413
+ }
414
+ }
415
+ // Cost by model
416
+ if (args.byModel !== false &&
417
+ metrics.costByModel &&
418
+ metrics.costByModel.length > 0) {
419
+ console.log("");
420
+ console.log(chalk.bold("By Model:"));
421
+ // Sort by cost descending
422
+ const sortedModels = [...metrics.costByModel].sort((a, b) => b.totalCost - a.totalCost);
423
+ for (const model of sortedModels) {
424
+ const costStr = formatCost(model.totalCost);
425
+ const avgCost = formatCost(model.avgCostPerRequest);
426
+ console.log(` ${chalk.cyan(model.model)}`);
427
+ console.log(` Cost: ${costStr}`);
428
+ console.log(chalk.gray(` ${model.requestCount} requests, avg ${avgCost}/req`));
429
+ console.log(chalk.gray(` ${model.inputTokens.toLocaleString()} input, ${model.outputTokens.toLocaleString()} output tokens`));
430
+ }
431
+ }
432
+ // No cost data
433
+ if ((!metrics.costByProvider ||
434
+ metrics.costByProvider.length === 0) &&
435
+ (!metrics.costByModel || metrics.costByModel.length === 0)) {
436
+ console.log("");
437
+ console.log(chalk.gray("No cost data available."));
438
+ console.log(chalk.gray("Cost tracking is recorded when observability is enabled."));
439
+ }
440
+ console.log("");
441
+ }
442
+ }
443
+ catch (error) {
444
+ if (spinner)
445
+ spinner.fail("Failed to get costs");
446
+ logger.error("Error:", error instanceof Error ? error.message : String(error));
447
+ process.exit(1);
448
+ }
449
+ },
450
+ };
451
+ }
452
+ }
453
+ //# sourceMappingURL=observability.js.map
@@ -0,0 +1,63 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * NeuroLink CLI Telemetry Commands
4
+ *
5
+ * Commands for managing telemetry and observability exporters:
6
+ * - status: Show exporter status
7
+ * - configure: Configure an exporter
8
+ * - list-exporters: List configured exporters
9
+ * - flush: Flush pending spans
10
+ * - stats: Show token/cost stats
11
+ */
12
+ import type { CommandModule } from "yargs";
13
+ /**
14
+ * Telemetry command arguments
15
+ */
16
+ type TelemetryCommandArgs = {
17
+ format?: "text" | "json" | "table";
18
+ quiet?: boolean;
19
+ };
20
+ type StatusArgs = TelemetryCommandArgs;
21
+ type ConfigureArgs = TelemetryCommandArgs & {
22
+ exporter: string;
23
+ config: string;
24
+ };
25
+ type ListExportersArgs = TelemetryCommandArgs;
26
+ type FlushArgs = TelemetryCommandArgs & {
27
+ timeout?: number;
28
+ };
29
+ type StatsArgs = TelemetryCommandArgs & {
30
+ detailed?: boolean;
31
+ byModel?: boolean;
32
+ byProvider?: boolean;
33
+ };
34
+ /**
35
+ * Telemetry Command Factory
36
+ */
37
+ export declare class TelemetryCommandFactory {
38
+ /**
39
+ * Create the telemetry command group
40
+ */
41
+ static createTelemetryCommands(): CommandModule<object, object>;
42
+ /**
43
+ * Create the status subcommand
44
+ */
45
+ static createStatusCommand(): CommandModule<object, StatusArgs>;
46
+ /**
47
+ * Create the configure subcommand
48
+ */
49
+ static createConfigureCommand(): CommandModule<object, ConfigureArgs>;
50
+ /**
51
+ * Create the list-exporters subcommand
52
+ */
53
+ static createListExportersCommand(): CommandModule<object, ListExportersArgs>;
54
+ /**
55
+ * Create the flush subcommand
56
+ */
57
+ static createFlushCommand(): CommandModule<object, FlushArgs>;
58
+ /**
59
+ * Create the stats subcommand
60
+ */
61
+ static createStatsCommand(): CommandModule<object, StatsArgs>;
62
+ }
63
+ export {};