@juspay/neurolink 9.23.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 +12 -0
- package/README.md +10 -13
- 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.d.ts +34 -0
- package/dist/cli/factories/commandFactory.js +321 -116
- 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/index.d.ts +1 -1
- package/dist/features/ppt/index.js +1 -1
- 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/index.d.ts +1 -1
- package/dist/lib/features/ppt/index.js +1 -1
- 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/cli.d.ts +18 -2
- package/dist/lib/types/conversationMemoryInterface.d.ts +2 -0
- package/dist/lib/types/generateTypes.d.ts +2 -2
- 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/cli.d.ts +18 -2
- package/dist/types/conversationMemoryInterface.d.ts +2 -0
- package/dist/types/generateTypes.d.ts +2 -2
- 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,190 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Abstract base class for all observability exporters
|
|
3
|
+
* Follows NeuroLink's factory pattern and Mastra's unified exporter interface
|
|
4
|
+
*/
|
|
5
|
+
import { logger } from "../../utils/logger.js";
|
|
6
|
+
/**
|
|
7
|
+
* Abstract base class for all observability exporters
|
|
8
|
+
* Provides common functionality: buffering, flush intervals, health checks, retry logic
|
|
9
|
+
*/
|
|
10
|
+
export class BaseExporter {
|
|
11
|
+
name;
|
|
12
|
+
config;
|
|
13
|
+
initialized = false;
|
|
14
|
+
buffer = [];
|
|
15
|
+
maxBufferSize;
|
|
16
|
+
retries;
|
|
17
|
+
flushInterval = null;
|
|
18
|
+
lastExportTime = 0;
|
|
19
|
+
constructor(name, config) {
|
|
20
|
+
this.name = name;
|
|
21
|
+
this.config = config;
|
|
22
|
+
this.maxBufferSize = config.maxBufferSize ?? 100;
|
|
23
|
+
this.retries = config.retries ?? 3;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Ping the exporter's backend to verify connectivity
|
|
27
|
+
* Override this in subclasses to provide backend-specific health check
|
|
28
|
+
*/
|
|
29
|
+
async ping() {
|
|
30
|
+
// Default implementation does nothing
|
|
31
|
+
// Subclasses should override this to make an actual API call
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Buffer a span for batch export
|
|
35
|
+
* Triggers flush if buffer is full
|
|
36
|
+
*/
|
|
37
|
+
bufferSpan(span) {
|
|
38
|
+
this.buffer.push(span);
|
|
39
|
+
if (this.buffer.length >= this.maxBufferSize) {
|
|
40
|
+
// Use void to explicitly ignore the promise
|
|
41
|
+
void this.flush();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Start automatic flush interval
|
|
46
|
+
* @param intervalMs - Interval in milliseconds between flushes
|
|
47
|
+
*/
|
|
48
|
+
startFlushInterval(intervalMs) {
|
|
49
|
+
if (this.flushInterval) {
|
|
50
|
+
clearInterval(this.flushInterval);
|
|
51
|
+
}
|
|
52
|
+
this.flushInterval = setInterval(() => {
|
|
53
|
+
this.flush().catch((error) => {
|
|
54
|
+
logger.warn(`[${this.name}] Periodic flush failed`, {
|
|
55
|
+
error: error instanceof Error ? error.message : String(error),
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
}, intervalMs);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Stop the automatic flush interval
|
|
62
|
+
*/
|
|
63
|
+
stopFlushInterval() {
|
|
64
|
+
if (this.flushInterval) {
|
|
65
|
+
clearInterval(this.flushInterval);
|
|
66
|
+
this.flushInterval = null;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Get exporter name
|
|
71
|
+
*/
|
|
72
|
+
getName() {
|
|
73
|
+
return this.name;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Check if exporter is initialized
|
|
77
|
+
*/
|
|
78
|
+
isInitialized() {
|
|
79
|
+
return this.initialized;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Get number of pending spans in buffer
|
|
83
|
+
*/
|
|
84
|
+
getPendingCount() {
|
|
85
|
+
return this.buffer.length;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Get last export timestamp
|
|
89
|
+
*/
|
|
90
|
+
getLastExportTime() {
|
|
91
|
+
return this.lastExportTime;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Create a standard export result for success
|
|
95
|
+
*/
|
|
96
|
+
createSuccessResult(exportedCount, durationMs) {
|
|
97
|
+
this.lastExportTime = Date.now();
|
|
98
|
+
return {
|
|
99
|
+
success: true,
|
|
100
|
+
exportedCount,
|
|
101
|
+
failedCount: 0,
|
|
102
|
+
durationMs,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Create a standard export result for failure
|
|
107
|
+
*/
|
|
108
|
+
createFailureResult(spanIds, error, durationMs, retryable = true) {
|
|
109
|
+
return {
|
|
110
|
+
success: false,
|
|
111
|
+
exportedCount: 0,
|
|
112
|
+
failedCount: spanIds.length,
|
|
113
|
+
errors: spanIds.map((spanId) => ({
|
|
114
|
+
spanId,
|
|
115
|
+
error,
|
|
116
|
+
retryable,
|
|
117
|
+
})),
|
|
118
|
+
durationMs,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Create a standard health status
|
|
123
|
+
*/
|
|
124
|
+
createHealthStatus(healthy, errors) {
|
|
125
|
+
return {
|
|
126
|
+
healthy,
|
|
127
|
+
name: this.name,
|
|
128
|
+
pendingSpans: this.buffer.length,
|
|
129
|
+
lastExportTime: this.lastExportTime || undefined,
|
|
130
|
+
errors,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Execute an operation with exponential backoff retry
|
|
135
|
+
* @param operation - The async operation to execute
|
|
136
|
+
* @param operationName - Name for logging purposes
|
|
137
|
+
* @returns The result of the operation
|
|
138
|
+
* @throws The last error if all retries fail
|
|
139
|
+
*/
|
|
140
|
+
async withRetry(operation, operationName) {
|
|
141
|
+
const maxRetries = this.retries;
|
|
142
|
+
const baseDelay = 1000;
|
|
143
|
+
let lastError;
|
|
144
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
145
|
+
try {
|
|
146
|
+
return await operation();
|
|
147
|
+
}
|
|
148
|
+
catch (error) {
|
|
149
|
+
lastError = error;
|
|
150
|
+
if (attempt < maxRetries) {
|
|
151
|
+
const delay = baseDelay * 2 ** attempt;
|
|
152
|
+
logger.warn(`[${this.name}] ${operationName} failed, retrying in ${delay}ms`, {
|
|
153
|
+
attempt: attempt + 1,
|
|
154
|
+
maxRetries,
|
|
155
|
+
error: lastError.message,
|
|
156
|
+
});
|
|
157
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
throw lastError;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* No-op exporter for when observability is disabled
|
|
166
|
+
* Provides zero-overhead behavior
|
|
167
|
+
*/
|
|
168
|
+
export class NoOpExporter extends BaseExporter {
|
|
169
|
+
constructor() {
|
|
170
|
+
super("noop", { enabled: false });
|
|
171
|
+
}
|
|
172
|
+
async initialize() {
|
|
173
|
+
this.initialized = true;
|
|
174
|
+
}
|
|
175
|
+
async exportSpan(_span) {
|
|
176
|
+
return this.createSuccessResult(0, 0);
|
|
177
|
+
}
|
|
178
|
+
async exportBatch(_spans) {
|
|
179
|
+
return this.createSuccessResult(0, 0);
|
|
180
|
+
}
|
|
181
|
+
async flush() {
|
|
182
|
+
// No-op
|
|
183
|
+
}
|
|
184
|
+
async shutdown() {
|
|
185
|
+
this.initialized = false;
|
|
186
|
+
}
|
|
187
|
+
async healthCheck() {
|
|
188
|
+
return this.createHealthStatus(true);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Braintrust Exporter
|
|
3
|
+
* Exports spans to Braintrust AI evaluation platform
|
|
4
|
+
*/
|
|
5
|
+
import type { BraintrustExporterConfig, ExporterHealthStatus, ExportResult, SpanData } from "../types/index.js";
|
|
6
|
+
import { BaseExporter } from "./baseExporter.js";
|
|
7
|
+
/**
|
|
8
|
+
* Braintrust exporter for AI evaluation and scoring
|
|
9
|
+
* Supports project logs and evaluation metrics
|
|
10
|
+
*/
|
|
11
|
+
export declare class BraintrustExporter extends BaseExporter {
|
|
12
|
+
private readonly apiKey;
|
|
13
|
+
private readonly projectName;
|
|
14
|
+
private readonly endpoint;
|
|
15
|
+
constructor(config: BraintrustExporterConfig);
|
|
16
|
+
initialize(): Promise<void>;
|
|
17
|
+
exportSpan(span: SpanData): Promise<ExportResult>;
|
|
18
|
+
exportBatch(spans: SpanData[]): Promise<ExportResult>;
|
|
19
|
+
flush(): Promise<void>;
|
|
20
|
+
shutdown(): Promise<void>;
|
|
21
|
+
healthCheck(): Promise<ExporterHealthStatus>;
|
|
22
|
+
/**
|
|
23
|
+
* Verify connectivity to Braintrust API
|
|
24
|
+
*/
|
|
25
|
+
protected ping(): Promise<void>;
|
|
26
|
+
/**
|
|
27
|
+
* Convert span to Braintrust log format
|
|
28
|
+
*/
|
|
29
|
+
private convertToBraintrustLog;
|
|
30
|
+
}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Braintrust Exporter
|
|
3
|
+
* Exports spans to Braintrust AI evaluation platform
|
|
4
|
+
*/
|
|
5
|
+
import { logger } from "../../utils/logger.js";
|
|
6
|
+
import { BaseExporter } from "./baseExporter.js";
|
|
7
|
+
/**
|
|
8
|
+
* Braintrust exporter for AI evaluation and scoring
|
|
9
|
+
* Supports project logs and evaluation metrics
|
|
10
|
+
*/
|
|
11
|
+
export class BraintrustExporter extends BaseExporter {
|
|
12
|
+
apiKey;
|
|
13
|
+
projectName;
|
|
14
|
+
endpoint;
|
|
15
|
+
constructor(config) {
|
|
16
|
+
super("braintrust", config);
|
|
17
|
+
this.apiKey = config.apiKey;
|
|
18
|
+
this.projectName = config.projectName;
|
|
19
|
+
this.endpoint = config.endpoint ?? "https://api.braintrust.dev";
|
|
20
|
+
}
|
|
21
|
+
async initialize() {
|
|
22
|
+
if (this.initialized) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
// Verify API key
|
|
26
|
+
try {
|
|
27
|
+
const response = await fetch(`${this.endpoint}/v1/project`, {
|
|
28
|
+
headers: { Authorization: `Bearer ${this.apiKey}` },
|
|
29
|
+
});
|
|
30
|
+
if (!response.ok) {
|
|
31
|
+
throw new Error(`Braintrust initialization failed: ${response.statusText}`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
logger.warn("[Braintrust] Could not verify API connection:", error instanceof Error ? error.message : error);
|
|
36
|
+
}
|
|
37
|
+
this.initialized = true;
|
|
38
|
+
this.startFlushInterval(this.config.flushIntervalMs ?? 5000);
|
|
39
|
+
}
|
|
40
|
+
async exportSpan(span) {
|
|
41
|
+
const startTime = Date.now();
|
|
42
|
+
try {
|
|
43
|
+
const log = this.convertToBraintrustLog(span);
|
|
44
|
+
const response = await fetch(`${this.endpoint}/v1/project_logs/${this.projectName}/insert`, {
|
|
45
|
+
method: "POST",
|
|
46
|
+
headers: {
|
|
47
|
+
"Content-Type": "application/json",
|
|
48
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
49
|
+
},
|
|
50
|
+
body: JSON.stringify({ events: [log] }),
|
|
51
|
+
});
|
|
52
|
+
if (!response.ok) {
|
|
53
|
+
throw new Error(`Export failed: ${response.statusText}`);
|
|
54
|
+
}
|
|
55
|
+
return this.createSuccessResult(1, Date.now() - startTime);
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
return this.createFailureResult([span.spanId], error instanceof Error ? error.message : String(error), Date.now() - startTime);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
async exportBatch(spans) {
|
|
62
|
+
const startTime = Date.now();
|
|
63
|
+
try {
|
|
64
|
+
const events = spans.map((s) => this.convertToBraintrustLog(s));
|
|
65
|
+
const response = await fetch(`${this.endpoint}/v1/project_logs/${this.projectName}/insert`, {
|
|
66
|
+
method: "POST",
|
|
67
|
+
headers: {
|
|
68
|
+
"Content-Type": "application/json",
|
|
69
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
70
|
+
},
|
|
71
|
+
body: JSON.stringify({ events }),
|
|
72
|
+
});
|
|
73
|
+
if (!response.ok) {
|
|
74
|
+
throw new Error(`Batch export failed: ${response.statusText}`);
|
|
75
|
+
}
|
|
76
|
+
return this.createSuccessResult(spans.length, Date.now() - startTime);
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
return this.createFailureResult(spans.map((s) => s.spanId), error instanceof Error ? error.message : String(error), Date.now() - startTime);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
async flush() {
|
|
83
|
+
if (this.buffer.length > 0) {
|
|
84
|
+
const spans = [...this.buffer];
|
|
85
|
+
this.buffer = [];
|
|
86
|
+
await this.exportBatch(spans);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
async shutdown() {
|
|
90
|
+
await this.flush();
|
|
91
|
+
this.stopFlushInterval();
|
|
92
|
+
this.initialized = false;
|
|
93
|
+
}
|
|
94
|
+
async healthCheck() {
|
|
95
|
+
try {
|
|
96
|
+
await this.withRetry(() => this.ping(), "health check");
|
|
97
|
+
return this.createHealthStatus(true);
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
return this.createHealthStatus(false, ["Health check failed"]);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Verify connectivity to Braintrust API
|
|
105
|
+
*/
|
|
106
|
+
async ping() {
|
|
107
|
+
const response = await fetch(`${this.endpoint}/v1/project`, {
|
|
108
|
+
headers: { Authorization: `Bearer ${this.apiKey}` },
|
|
109
|
+
});
|
|
110
|
+
if (!response.ok) {
|
|
111
|
+
throw new Error(`Braintrust API unreachable: ${response.status}`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Convert span to Braintrust log format
|
|
116
|
+
*/
|
|
117
|
+
convertToBraintrustLog(span) {
|
|
118
|
+
return {
|
|
119
|
+
project_name: this.projectName,
|
|
120
|
+
id: span.spanId,
|
|
121
|
+
span_id: span.spanId,
|
|
122
|
+
root_span_id: span.parentSpanId ? undefined : span.spanId,
|
|
123
|
+
span_parents: span.parentSpanId ? [span.parentSpanId] : [],
|
|
124
|
+
input: span.attributes["input"],
|
|
125
|
+
output: span.attributes["output"],
|
|
126
|
+
expected: span.attributes["expected"],
|
|
127
|
+
scores: span.attributes["scores"],
|
|
128
|
+
metadata: {
|
|
129
|
+
// Pick only safe, non-PII attributes for metadata (avoid leaking input/output)
|
|
130
|
+
...(span.attributes["ai.provider"] !== undefined && {
|
|
131
|
+
"ai.provider": span.attributes["ai.provider"],
|
|
132
|
+
}),
|
|
133
|
+
...(span.attributes["ai.model"] !== undefined && {
|
|
134
|
+
"ai.model": span.attributes["ai.model"],
|
|
135
|
+
}),
|
|
136
|
+
// Explicit fields placed after spread so they always win
|
|
137
|
+
provider: span.attributes["ai.provider"],
|
|
138
|
+
model: span.attributes["ai.model"],
|
|
139
|
+
type: span.type,
|
|
140
|
+
status: span.status,
|
|
141
|
+
statusMessage: span.statusMessage,
|
|
142
|
+
},
|
|
143
|
+
metrics: {
|
|
144
|
+
tokens: span.attributes["ai.tokens.total"],
|
|
145
|
+
prompt_tokens: span.attributes["ai.tokens.input"],
|
|
146
|
+
completion_tokens: span.attributes["ai.tokens.output"],
|
|
147
|
+
cost: span.attributes["ai.cost.total"],
|
|
148
|
+
duration_ms: span.durationMs,
|
|
149
|
+
},
|
|
150
|
+
created: span.startTime,
|
|
151
|
+
end_time: span.endTime,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Datadog Exporter
|
|
3
|
+
* Exports spans to Datadog APM platform
|
|
4
|
+
*/
|
|
5
|
+
import type { DatadogExporterConfig, ExporterHealthStatus, ExportResult, SpanData } from "../types/index.js";
|
|
6
|
+
import { BaseExporter } from "./baseExporter.js";
|
|
7
|
+
/**
|
|
8
|
+
* Datadog exporter for enterprise APM integration
|
|
9
|
+
* Supports trace correlation and AI-specific custom metrics
|
|
10
|
+
*/
|
|
11
|
+
export declare class DatadogExporter extends BaseExporter {
|
|
12
|
+
private readonly apiKey;
|
|
13
|
+
private readonly appKey?;
|
|
14
|
+
private readonly site;
|
|
15
|
+
private readonly service;
|
|
16
|
+
private readonly source;
|
|
17
|
+
private readonly logsEndpoint;
|
|
18
|
+
constructor(config: DatadogExporterConfig);
|
|
19
|
+
initialize(): Promise<void>;
|
|
20
|
+
exportSpan(span: SpanData): Promise<ExportResult>;
|
|
21
|
+
exportBatch(spans: SpanData[]): Promise<ExportResult>;
|
|
22
|
+
flush(): Promise<void>;
|
|
23
|
+
shutdown(): Promise<void>;
|
|
24
|
+
healthCheck(): Promise<ExporterHealthStatus>;
|
|
25
|
+
/**
|
|
26
|
+
* Verify connectivity to Datadog API
|
|
27
|
+
*/
|
|
28
|
+
protected ping(): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Convert span to Datadog log format with trace correlation
|
|
31
|
+
*/
|
|
32
|
+
private convertToDatadogLog;
|
|
33
|
+
/**
|
|
34
|
+
* Build Datadog tags from span attributes
|
|
35
|
+
*/
|
|
36
|
+
private buildTags;
|
|
37
|
+
}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Datadog Exporter
|
|
3
|
+
* Exports spans to Datadog APM platform
|
|
4
|
+
*/
|
|
5
|
+
import { logger } from "../../utils/logger.js";
|
|
6
|
+
import { SpanStatus } from "../types/spanTypes.js";
|
|
7
|
+
import { BaseExporter } from "./baseExporter.js";
|
|
8
|
+
/**
|
|
9
|
+
* Datadog exporter for enterprise APM integration
|
|
10
|
+
* Supports trace correlation and AI-specific custom metrics
|
|
11
|
+
*/
|
|
12
|
+
export class DatadogExporter extends BaseExporter {
|
|
13
|
+
apiKey;
|
|
14
|
+
appKey;
|
|
15
|
+
site;
|
|
16
|
+
service;
|
|
17
|
+
source;
|
|
18
|
+
logsEndpoint;
|
|
19
|
+
constructor(config) {
|
|
20
|
+
super("datadog", config);
|
|
21
|
+
this.apiKey = config.apiKey;
|
|
22
|
+
this.appKey = config.appKey;
|
|
23
|
+
this.site = config.site ?? "us1";
|
|
24
|
+
this.service = config.service ?? "neurolink";
|
|
25
|
+
this.source = config.source ?? "neurolink-ai";
|
|
26
|
+
const baseDomain = this.site === "us1" ? "datadoghq.com" : `${this.site}.datadoghq.com`;
|
|
27
|
+
this.logsEndpoint = `https://http-intake.logs.${baseDomain}/api/v2/logs`;
|
|
28
|
+
}
|
|
29
|
+
async initialize() {
|
|
30
|
+
if (this.initialized) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
// Validate API key
|
|
34
|
+
try {
|
|
35
|
+
const validateUrl = this.site === "us1"
|
|
36
|
+
? "https://api.datadoghq.com/api/v1/validate"
|
|
37
|
+
: `https://api.${this.site}.datadoghq.com/api/v1/validate`;
|
|
38
|
+
const response = await fetch(validateUrl, {
|
|
39
|
+
headers: {
|
|
40
|
+
"DD-API-KEY": this.apiKey,
|
|
41
|
+
...(this.appKey && { "DD-APPLICATION-KEY": this.appKey }),
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
if (!response.ok) {
|
|
45
|
+
throw new Error(`Datadog API key validation failed: ${response.statusText}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
// Allow initialization to proceed even if API is unreachable
|
|
50
|
+
logger.warn("[Datadog] Could not verify API connection:", error instanceof Error ? error.message : error);
|
|
51
|
+
}
|
|
52
|
+
this.initialized = true;
|
|
53
|
+
this.startFlushInterval(this.config.flushIntervalMs ?? 10000);
|
|
54
|
+
}
|
|
55
|
+
async exportSpan(span) {
|
|
56
|
+
const startTime = Date.now();
|
|
57
|
+
try {
|
|
58
|
+
const log = this.convertToDatadogLog(span);
|
|
59
|
+
const response = await fetch(this.logsEndpoint, {
|
|
60
|
+
method: "POST",
|
|
61
|
+
headers: {
|
|
62
|
+
"Content-Type": "application/json",
|
|
63
|
+
"DD-API-KEY": this.apiKey,
|
|
64
|
+
},
|
|
65
|
+
body: JSON.stringify([log]),
|
|
66
|
+
});
|
|
67
|
+
if (!response.ok) {
|
|
68
|
+
throw new Error(`Export failed: ${response.statusText}`);
|
|
69
|
+
}
|
|
70
|
+
return this.createSuccessResult(1, Date.now() - startTime);
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
return this.createFailureResult([span.spanId], error instanceof Error ? error.message : String(error), Date.now() - startTime);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
async exportBatch(spans) {
|
|
77
|
+
const startTime = Date.now();
|
|
78
|
+
try {
|
|
79
|
+
const logs = spans.map((s) => this.convertToDatadogLog(s));
|
|
80
|
+
const response = await fetch(this.logsEndpoint, {
|
|
81
|
+
method: "POST",
|
|
82
|
+
headers: {
|
|
83
|
+
"Content-Type": "application/json",
|
|
84
|
+
"DD-API-KEY": this.apiKey,
|
|
85
|
+
},
|
|
86
|
+
body: JSON.stringify(logs),
|
|
87
|
+
});
|
|
88
|
+
if (!response.ok) {
|
|
89
|
+
throw new Error(`Batch export failed: ${response.statusText}`);
|
|
90
|
+
}
|
|
91
|
+
return this.createSuccessResult(spans.length, Date.now() - startTime);
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
return this.createFailureResult(spans.map((s) => s.spanId), error instanceof Error ? error.message : String(error), Date.now() - startTime);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
async flush() {
|
|
98
|
+
if (this.buffer.length > 0) {
|
|
99
|
+
const spans = [...this.buffer];
|
|
100
|
+
this.buffer = [];
|
|
101
|
+
await this.exportBatch(spans);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
async shutdown() {
|
|
105
|
+
await this.flush();
|
|
106
|
+
this.stopFlushInterval();
|
|
107
|
+
this.initialized = false;
|
|
108
|
+
}
|
|
109
|
+
async healthCheck() {
|
|
110
|
+
try {
|
|
111
|
+
await this.withRetry(() => this.ping(), "health check");
|
|
112
|
+
return this.createHealthStatus(true);
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
return this.createHealthStatus(false, ["Health check failed"]);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Verify connectivity to Datadog API
|
|
120
|
+
*/
|
|
121
|
+
async ping() {
|
|
122
|
+
const validateUrl = this.site === "us1"
|
|
123
|
+
? "https://api.datadoghq.com/api/v1/validate"
|
|
124
|
+
: `https://api.${this.site}.datadoghq.com/api/v1/validate`;
|
|
125
|
+
const response = await fetch(validateUrl, {
|
|
126
|
+
headers: { "DD-API-KEY": this.apiKey },
|
|
127
|
+
});
|
|
128
|
+
if (!response.ok) {
|
|
129
|
+
throw new Error(`Datadog API validation failed: ${response.status}`);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Convert span to Datadog log format with trace correlation
|
|
134
|
+
*/
|
|
135
|
+
convertToDatadogLog(span) {
|
|
136
|
+
return {
|
|
137
|
+
ddsource: this.source,
|
|
138
|
+
ddtags: this.buildTags(span),
|
|
139
|
+
hostname: process.env.HOSTNAME || "unknown",
|
|
140
|
+
message: `${span.type}: ${span.name}`,
|
|
141
|
+
service: this.service,
|
|
142
|
+
status: span.status === SpanStatus.ERROR ? "error" : "info",
|
|
143
|
+
timestamp: new Date(span.startTime).getTime(),
|
|
144
|
+
// Trace correlation
|
|
145
|
+
dd: {
|
|
146
|
+
trace_id: span.traceId,
|
|
147
|
+
span_id: span.spanId,
|
|
148
|
+
},
|
|
149
|
+
// AI-specific attributes
|
|
150
|
+
ai: {
|
|
151
|
+
provider: span.attributes["ai.provider"],
|
|
152
|
+
model: span.attributes["ai.model"],
|
|
153
|
+
tokens: {
|
|
154
|
+
input: span.attributes["ai.tokens.input"],
|
|
155
|
+
output: span.attributes["ai.tokens.output"],
|
|
156
|
+
total: span.attributes["ai.tokens.total"],
|
|
157
|
+
},
|
|
158
|
+
cost: span.attributes["ai.cost.total"],
|
|
159
|
+
duration_ms: span.durationMs,
|
|
160
|
+
},
|
|
161
|
+
// User context
|
|
162
|
+
usr: {
|
|
163
|
+
id: span.attributes["user.id"],
|
|
164
|
+
session_id: span.attributes["session.id"],
|
|
165
|
+
},
|
|
166
|
+
// Error details
|
|
167
|
+
...(span.status === SpanStatus.ERROR && {
|
|
168
|
+
error: {
|
|
169
|
+
message: span.statusMessage,
|
|
170
|
+
type: span.attributes["error.type"],
|
|
171
|
+
stack: span.attributes["error.stack"],
|
|
172
|
+
},
|
|
173
|
+
}),
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Build Datadog tags from span attributes
|
|
178
|
+
*/
|
|
179
|
+
buildTags(span) {
|
|
180
|
+
const tags = [
|
|
181
|
+
`env:${this.config.environment ?? "production"}`,
|
|
182
|
+
`version:${this.config.version ?? "unknown"}`,
|
|
183
|
+
`span_type:${span.type}`,
|
|
184
|
+
];
|
|
185
|
+
if (span.attributes["ai.provider"]) {
|
|
186
|
+
tags.push(`ai_provider:${span.attributes["ai.provider"]}`);
|
|
187
|
+
}
|
|
188
|
+
if (span.attributes["ai.model"]) {
|
|
189
|
+
tags.push(`ai_model:${span.attributes["ai.model"]}`);
|
|
190
|
+
}
|
|
191
|
+
if (span.attributes["tool.name"]) {
|
|
192
|
+
tags.push(`tool:${span.attributes["tool.name"]}`);
|
|
193
|
+
}
|
|
194
|
+
return tags.join(",");
|
|
195
|
+
}
|
|
196
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Observability exporters exports
|
|
3
|
+
*/
|
|
4
|
+
export { ArizeExporter } from "./arizeExporter.js";
|
|
5
|
+
export { BaseExporter, NoOpExporter } from "./baseExporter.js";
|
|
6
|
+
export { BraintrustExporter } from "./braintrustExporter.js";
|
|
7
|
+
export { DatadogExporter } from "./datadogExporter.js";
|
|
8
|
+
export { LaminarExporter } from "./laminarExporter.js";
|
|
9
|
+
export { LangfuseExporter } from "./langfuseExporter.js";
|
|
10
|
+
export { LangSmithExporter } from "./langsmithExporter.js";
|
|
11
|
+
export { OtelExporter } from "./otelExporter.js";
|
|
12
|
+
export { PostHogExporter } from "./posthogExporter.js";
|
|
13
|
+
export { SentryExporter } from "./sentryExporter.js";
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Observability exporters exports
|
|
3
|
+
*/
|
|
4
|
+
export { ArizeExporter } from "./arizeExporter.js";
|
|
5
|
+
export { BaseExporter, NoOpExporter } from "./baseExporter.js";
|
|
6
|
+
export { BraintrustExporter } from "./braintrustExporter.js";
|
|
7
|
+
export { DatadogExporter } from "./datadogExporter.js";
|
|
8
|
+
export { LaminarExporter } from "./laminarExporter.js";
|
|
9
|
+
export { LangfuseExporter } from "./langfuseExporter.js";
|
|
10
|
+
export { LangSmithExporter } from "./langsmithExporter.js";
|
|
11
|
+
export { OtelExporter } from "./otelExporter.js";
|
|
12
|
+
export { PostHogExporter } from "./posthogExporter.js";
|
|
13
|
+
export { SentryExporter } from "./sentryExporter.js";
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Laminar Exporter
|
|
3
|
+
* Exports spans to Laminar LLM tracing platform
|
|
4
|
+
* @see https://docs.laminar.run/
|
|
5
|
+
*/
|
|
6
|
+
import type { ExporterHealthStatus, ExportResult, LaminarExporterConfig, SpanData } from "../types/index.js";
|
|
7
|
+
import { BaseExporter } from "./baseExporter.js";
|
|
8
|
+
/**
|
|
9
|
+
* Laminar exporter for LLM pipeline tracing and monitoring
|
|
10
|
+
* Supports detailed traces with input/output tracking
|
|
11
|
+
*/
|
|
12
|
+
export declare class LaminarExporter extends BaseExporter {
|
|
13
|
+
private readonly apiKey;
|
|
14
|
+
private readonly projectApiKey?;
|
|
15
|
+
private readonly baseUrl;
|
|
16
|
+
constructor(config: LaminarExporterConfig);
|
|
17
|
+
initialize(): Promise<void>;
|
|
18
|
+
/**
|
|
19
|
+
* Get authorization headers
|
|
20
|
+
*/
|
|
21
|
+
private getHeaders;
|
|
22
|
+
exportSpan(span: SpanData): Promise<ExportResult>;
|
|
23
|
+
exportBatch(spans: SpanData[]): Promise<ExportResult>;
|
|
24
|
+
flush(): Promise<void>;
|
|
25
|
+
shutdown(): Promise<void>;
|
|
26
|
+
healthCheck(): Promise<ExporterHealthStatus>;
|
|
27
|
+
/**
|
|
28
|
+
* Verify connectivity to Laminar API
|
|
29
|
+
*/
|
|
30
|
+
protected ping(): Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Convert span to Laminar trace format
|
|
33
|
+
*/
|
|
34
|
+
private convertToLaminarTrace;
|
|
35
|
+
/**
|
|
36
|
+
* Map NeuroLink span type to Laminar type
|
|
37
|
+
*/
|
|
38
|
+
private mapSpanTypeToLaminarType;
|
|
39
|
+
/**
|
|
40
|
+
* Map span status to Laminar status format
|
|
41
|
+
*/
|
|
42
|
+
private mapSpanStatus;
|
|
43
|
+
/**
|
|
44
|
+
* Extract additional metadata from span attributes
|
|
45
|
+
* Filters out standard attributes that are already handled
|
|
46
|
+
*/
|
|
47
|
+
private extractMetadata;
|
|
48
|
+
}
|