@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.
- package/CHANGELOG.md +6 -0
- package/dist/adapters/tts/googleTTSHandler.js +26 -1
- package/dist/adapters/video/vertexVideoHandler.js +23 -17
- package/dist/cli/commands/config.d.ts +3 -3
- package/dist/cli/commands/observability.d.ts +53 -0
- package/dist/cli/commands/observability.js +453 -0
- package/dist/cli/commands/telemetry.d.ts +63 -0
- package/dist/cli/commands/telemetry.js +689 -0
- package/dist/cli/factories/commandFactory.js +29 -15
- package/dist/cli/parser.js +6 -9
- package/dist/cli/utils/formatters.d.ts +13 -0
- package/dist/cli/utils/formatters.js +23 -0
- package/dist/constants/contextWindows.js +6 -0
- package/dist/constants/enums.d.ts +6 -0
- package/dist/constants/enums.js +8 -2
- package/dist/context/budgetChecker.js +75 -48
- package/dist/context/contextCompactor.js +135 -127
- package/dist/core/baseProvider.d.ts +5 -0
- package/dist/core/baseProvider.js +158 -102
- package/dist/core/conversationMemoryInitializer.js +7 -4
- package/dist/core/conversationMemoryManager.d.ts +2 -0
- package/dist/core/conversationMemoryManager.js +6 -2
- package/dist/core/modules/GenerationHandler.d.ts +2 -2
- package/dist/core/modules/GenerationHandler.js +12 -12
- package/dist/evaluation/ragasEvaluator.js +39 -19
- package/dist/evaluation/scoring.js +46 -20
- package/dist/features/ppt/presentationOrchestrator.js +23 -0
- package/dist/features/ppt/slideGenerator.js +13 -0
- package/dist/features/ppt/slideRenderers.d.ts +1 -1
- package/dist/features/ppt/slideRenderers.js +6 -4
- package/dist/features/ppt/slideTypeInference.d.ts +1 -1
- package/dist/features/ppt/slideTypeInference.js +75 -73
- package/dist/files/fileTools.d.ts +6 -6
- package/dist/index.d.ts +46 -12
- package/dist/index.js +79 -17
- package/dist/lib/adapters/tts/googleTTSHandler.js +26 -1
- package/dist/lib/adapters/video/vertexVideoHandler.js +23 -17
- package/dist/lib/constants/contextWindows.js +6 -0
- package/dist/lib/constants/enums.d.ts +6 -0
- package/dist/lib/constants/enums.js +8 -2
- package/dist/lib/context/budgetChecker.js +75 -48
- package/dist/lib/context/contextCompactor.js +135 -127
- package/dist/lib/core/baseProvider.d.ts +5 -0
- package/dist/lib/core/baseProvider.js +158 -102
- package/dist/lib/core/conversationMemoryInitializer.js +7 -4
- package/dist/lib/core/conversationMemoryManager.d.ts +2 -0
- package/dist/lib/core/conversationMemoryManager.js +6 -2
- package/dist/lib/core/modules/GenerationHandler.d.ts +2 -2
- package/dist/lib/core/modules/GenerationHandler.js +12 -12
- package/dist/lib/evaluation/ragasEvaluator.js +39 -19
- package/dist/lib/evaluation/scoring.js +46 -20
- package/dist/lib/features/ppt/presentationOrchestrator.js +23 -0
- package/dist/lib/features/ppt/slideGenerator.js +13 -0
- package/dist/lib/features/ppt/slideRenderers.d.ts +1 -1
- package/dist/lib/features/ppt/slideRenderers.js +6 -4
- package/dist/lib/features/ppt/slideTypeInference.d.ts +1 -1
- package/dist/lib/features/ppt/slideTypeInference.js +75 -73
- package/dist/lib/files/fileTools.d.ts +6 -6
- package/dist/lib/index.d.ts +46 -12
- package/dist/lib/index.js +79 -17
- package/dist/lib/mcp/httpRateLimiter.js +39 -12
- package/dist/lib/mcp/httpRetryHandler.js +22 -1
- package/dist/lib/mcp/mcpClientFactory.js +13 -15
- package/dist/lib/memory/memoryRetrievalTools.js +22 -0
- package/dist/lib/neurolink.d.ts +64 -72
- package/dist/lib/neurolink.js +984 -566
- package/dist/lib/observability/exporterRegistry.d.ts +152 -0
- package/dist/lib/observability/exporterRegistry.js +414 -0
- package/dist/lib/observability/exporters/arizeExporter.d.ts +32 -0
- package/dist/lib/observability/exporters/arizeExporter.js +139 -0
- package/dist/lib/observability/exporters/baseExporter.d.ts +117 -0
- package/dist/lib/observability/exporters/baseExporter.js +191 -0
- package/dist/lib/observability/exporters/braintrustExporter.d.ts +30 -0
- package/dist/lib/observability/exporters/braintrustExporter.js +155 -0
- package/dist/lib/observability/exporters/datadogExporter.d.ts +37 -0
- package/dist/lib/observability/exporters/datadogExporter.js +197 -0
- package/dist/lib/observability/exporters/index.d.ts +13 -0
- package/dist/lib/observability/exporters/index.js +14 -0
- package/dist/lib/observability/exporters/laminarExporter.d.ts +48 -0
- package/dist/lib/observability/exporters/laminarExporter.js +303 -0
- package/dist/lib/observability/exporters/langfuseExporter.d.ts +47 -0
- package/dist/lib/observability/exporters/langfuseExporter.js +200 -0
- package/dist/lib/observability/exporters/langsmithExporter.d.ts +26 -0
- package/dist/lib/observability/exporters/langsmithExporter.js +124 -0
- package/dist/lib/observability/exporters/otelExporter.d.ts +39 -0
- package/dist/lib/observability/exporters/otelExporter.js +165 -0
- package/dist/lib/observability/exporters/posthogExporter.d.ts +48 -0
- package/dist/lib/observability/exporters/posthogExporter.js +288 -0
- package/dist/lib/observability/exporters/sentryExporter.d.ts +32 -0
- package/dist/lib/observability/exporters/sentryExporter.js +166 -0
- package/dist/lib/observability/index.d.ts +25 -0
- package/dist/lib/observability/index.js +32 -0
- package/dist/lib/observability/metricsAggregator.d.ts +260 -0
- package/dist/lib/observability/metricsAggregator.js +553 -0
- package/dist/lib/observability/otelBridge.d.ts +49 -0
- package/dist/lib/observability/otelBridge.js +132 -0
- package/dist/lib/observability/retryPolicy.d.ts +192 -0
- package/dist/lib/observability/retryPolicy.js +384 -0
- package/dist/lib/observability/sampling/index.d.ts +4 -0
- package/dist/lib/observability/sampling/index.js +5 -0
- package/dist/lib/observability/sampling/samplers.d.ts +116 -0
- package/dist/lib/observability/sampling/samplers.js +217 -0
- package/dist/lib/observability/spanProcessor.d.ts +129 -0
- package/dist/lib/observability/spanProcessor.js +288 -0
- package/dist/lib/observability/tokenTracker.d.ts +156 -0
- package/dist/lib/observability/tokenTracker.js +414 -0
- package/dist/lib/observability/types/exporterTypes.d.ts +250 -0
- package/dist/lib/observability/types/exporterTypes.js +6 -0
- package/dist/lib/observability/types/index.d.ts +6 -0
- package/dist/lib/observability/types/index.js +5 -0
- package/dist/lib/observability/types/spanTypes.d.ts +244 -0
- package/dist/lib/observability/types/spanTypes.js +93 -0
- package/dist/lib/observability/utils/index.d.ts +4 -0
- package/dist/lib/observability/utils/index.js +5 -0
- package/dist/lib/observability/utils/spanSerializer.d.ts +115 -0
- package/dist/lib/observability/utils/spanSerializer.js +287 -0
- package/dist/lib/providers/amazonSagemaker.d.ts +5 -4
- package/dist/lib/providers/amazonSagemaker.js +3 -4
- package/dist/lib/providers/googleVertex.d.ts +7 -0
- package/dist/lib/providers/googleVertex.js +80 -2
- package/dist/lib/rag/pipeline/RAGPipeline.d.ts +0 -5
- package/dist/lib/rag/pipeline/RAGPipeline.js +122 -87
- package/dist/lib/rag/ragIntegration.js +30 -0
- package/dist/lib/rag/retrieval/hybridSearch.js +22 -0
- package/dist/lib/server/abstract/baseServerAdapter.js +51 -19
- package/dist/lib/server/middleware/common.js +44 -12
- package/dist/lib/services/server/ai/observability/instrumentation.d.ts +2 -2
- package/dist/lib/services/server/ai/observability/instrumentation.js +10 -5
- package/dist/lib/types/conversationMemoryInterface.d.ts +2 -0
- package/dist/lib/types/modelTypes.d.ts +18 -18
- package/dist/lib/types/providers.d.ts +5 -0
- package/dist/lib/utils/pricing.js +25 -1
- package/dist/lib/utils/ttsProcessor.js +74 -59
- package/dist/lib/workflow/config.d.ts +36 -36
- package/dist/lib/workflow/core/ensembleExecutor.js +10 -0
- package/dist/lib/workflow/core/judgeScorer.js +20 -2
- package/dist/lib/workflow/core/workflowRunner.js +34 -1
- package/dist/mcp/httpRateLimiter.js +39 -12
- package/dist/mcp/httpRetryHandler.js +22 -1
- package/dist/mcp/mcpClientFactory.js +13 -15
- package/dist/memory/memoryRetrievalTools.js +22 -0
- package/dist/neurolink.d.ts +64 -72
- package/dist/neurolink.js +984 -566
- package/dist/observability/FEATURE-STATUS.md +269 -0
- package/dist/observability/exporterRegistry.d.ts +152 -0
- package/dist/observability/exporterRegistry.js +413 -0
- package/dist/observability/exporters/arizeExporter.d.ts +32 -0
- package/dist/observability/exporters/arizeExporter.js +138 -0
- package/dist/observability/exporters/baseExporter.d.ts +117 -0
- package/dist/observability/exporters/baseExporter.js +190 -0
- package/dist/observability/exporters/braintrustExporter.d.ts +30 -0
- package/dist/observability/exporters/braintrustExporter.js +154 -0
- package/dist/observability/exporters/datadogExporter.d.ts +37 -0
- package/dist/observability/exporters/datadogExporter.js +196 -0
- package/dist/observability/exporters/index.d.ts +13 -0
- package/dist/observability/exporters/index.js +13 -0
- package/dist/observability/exporters/laminarExporter.d.ts +48 -0
- package/dist/observability/exporters/laminarExporter.js +302 -0
- package/dist/observability/exporters/langfuseExporter.d.ts +47 -0
- package/dist/observability/exporters/langfuseExporter.js +199 -0
- package/dist/observability/exporters/langsmithExporter.d.ts +26 -0
- package/dist/observability/exporters/langsmithExporter.js +123 -0
- package/dist/observability/exporters/otelExporter.d.ts +39 -0
- package/dist/observability/exporters/otelExporter.js +164 -0
- package/dist/observability/exporters/posthogExporter.d.ts +48 -0
- package/dist/observability/exporters/posthogExporter.js +287 -0
- package/dist/observability/exporters/sentryExporter.d.ts +32 -0
- package/dist/observability/exporters/sentryExporter.js +165 -0
- package/dist/observability/index.d.ts +25 -0
- package/dist/observability/index.js +31 -0
- package/dist/observability/metricsAggregator.d.ts +260 -0
- package/dist/observability/metricsAggregator.js +552 -0
- package/dist/observability/otelBridge.d.ts +49 -0
- package/dist/observability/otelBridge.js +131 -0
- package/dist/observability/retryPolicy.d.ts +192 -0
- package/dist/observability/retryPolicy.js +383 -0
- package/dist/observability/sampling/index.d.ts +4 -0
- package/dist/observability/sampling/index.js +4 -0
- package/dist/observability/sampling/samplers.d.ts +116 -0
- package/dist/observability/sampling/samplers.js +216 -0
- package/dist/observability/spanProcessor.d.ts +129 -0
- package/dist/observability/spanProcessor.js +287 -0
- package/dist/observability/tokenTracker.d.ts +156 -0
- package/dist/observability/tokenTracker.js +413 -0
- package/dist/observability/types/exporterTypes.d.ts +250 -0
- package/dist/observability/types/exporterTypes.js +5 -0
- package/dist/observability/types/index.d.ts +6 -0
- package/dist/observability/types/index.js +4 -0
- package/dist/observability/types/spanTypes.d.ts +244 -0
- package/dist/observability/types/spanTypes.js +92 -0
- package/dist/observability/utils/index.d.ts +4 -0
- package/dist/observability/utils/index.js +4 -0
- package/dist/observability/utils/spanSerializer.d.ts +115 -0
- package/dist/observability/utils/spanSerializer.js +286 -0
- package/dist/providers/amazonSagemaker.d.ts +5 -4
- package/dist/providers/amazonSagemaker.js +3 -4
- package/dist/providers/googleVertex.d.ts +7 -0
- package/dist/providers/googleVertex.js +80 -2
- package/dist/rag/pipeline/RAGPipeline.d.ts +0 -5
- package/dist/rag/pipeline/RAGPipeline.js +122 -87
- package/dist/rag/ragIntegration.js +30 -0
- package/dist/rag/retrieval/hybridSearch.js +22 -0
- package/dist/server/abstract/baseServerAdapter.js +51 -19
- package/dist/server/middleware/common.js +44 -12
- package/dist/services/server/ai/observability/instrumentation.d.ts +2 -2
- package/dist/services/server/ai/observability/instrumentation.js +10 -5
- package/dist/types/conversationMemoryInterface.d.ts +2 -0
- package/dist/types/providers.d.ts +5 -0
- package/dist/utils/pricing.js +25 -1
- package/dist/utils/ttsProcessor.js +74 -59
- package/dist/workflow/config.d.ts +52 -52
- package/dist/workflow/core/ensembleExecutor.js +10 -0
- package/dist/workflow/core/judgeScorer.js +20 -2
- package/dist/workflow/core/workflowRunner.js +34 -1
- 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 {};
|