@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.
Files changed (225) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +10 -13
  3. package/dist/adapters/tts/googleTTSHandler.js +26 -1
  4. package/dist/adapters/video/vertexVideoHandler.js +23 -17
  5. package/dist/cli/commands/config.d.ts +3 -3
  6. package/dist/cli/commands/observability.d.ts +53 -0
  7. package/dist/cli/commands/observability.js +453 -0
  8. package/dist/cli/commands/telemetry.d.ts +63 -0
  9. package/dist/cli/commands/telemetry.js +689 -0
  10. package/dist/cli/factories/commandFactory.d.ts +34 -0
  11. package/dist/cli/factories/commandFactory.js +321 -116
  12. package/dist/cli/parser.js +6 -9
  13. package/dist/cli/utils/formatters.d.ts +13 -0
  14. package/dist/cli/utils/formatters.js +23 -0
  15. package/dist/constants/contextWindows.js +6 -0
  16. package/dist/constants/enums.d.ts +6 -0
  17. package/dist/constants/enums.js +8 -2
  18. package/dist/context/budgetChecker.js +75 -48
  19. package/dist/context/contextCompactor.js +135 -127
  20. package/dist/core/baseProvider.d.ts +5 -0
  21. package/dist/core/baseProvider.js +158 -102
  22. package/dist/core/conversationMemoryInitializer.js +7 -4
  23. package/dist/core/conversationMemoryManager.d.ts +2 -0
  24. package/dist/core/conversationMemoryManager.js +6 -2
  25. package/dist/core/modules/GenerationHandler.d.ts +2 -2
  26. package/dist/core/modules/GenerationHandler.js +12 -12
  27. package/dist/evaluation/ragasEvaluator.js +39 -19
  28. package/dist/evaluation/scoring.js +46 -20
  29. package/dist/features/ppt/index.d.ts +1 -1
  30. package/dist/features/ppt/index.js +1 -1
  31. package/dist/features/ppt/presentationOrchestrator.js +23 -0
  32. package/dist/features/ppt/slideGenerator.js +13 -0
  33. package/dist/features/ppt/slideRenderers.d.ts +1 -1
  34. package/dist/features/ppt/slideRenderers.js +6 -4
  35. package/dist/features/ppt/slideTypeInference.d.ts +1 -1
  36. package/dist/features/ppt/slideTypeInference.js +75 -73
  37. package/dist/files/fileTools.d.ts +6 -6
  38. package/dist/index.d.ts +46 -12
  39. package/dist/index.js +79 -17
  40. package/dist/lib/adapters/tts/googleTTSHandler.js +26 -1
  41. package/dist/lib/adapters/video/vertexVideoHandler.js +23 -17
  42. package/dist/lib/constants/contextWindows.js +6 -0
  43. package/dist/lib/constants/enums.d.ts +6 -0
  44. package/dist/lib/constants/enums.js +8 -2
  45. package/dist/lib/context/budgetChecker.js +75 -48
  46. package/dist/lib/context/contextCompactor.js +135 -127
  47. package/dist/lib/core/baseProvider.d.ts +5 -0
  48. package/dist/lib/core/baseProvider.js +158 -102
  49. package/dist/lib/core/conversationMemoryInitializer.js +7 -4
  50. package/dist/lib/core/conversationMemoryManager.d.ts +2 -0
  51. package/dist/lib/core/conversationMemoryManager.js +6 -2
  52. package/dist/lib/core/modules/GenerationHandler.d.ts +2 -2
  53. package/dist/lib/core/modules/GenerationHandler.js +12 -12
  54. package/dist/lib/evaluation/ragasEvaluator.js +39 -19
  55. package/dist/lib/evaluation/scoring.js +46 -20
  56. package/dist/lib/features/ppt/index.d.ts +1 -1
  57. package/dist/lib/features/ppt/index.js +1 -1
  58. package/dist/lib/features/ppt/presentationOrchestrator.js +23 -0
  59. package/dist/lib/features/ppt/slideGenerator.js +13 -0
  60. package/dist/lib/features/ppt/slideRenderers.d.ts +1 -1
  61. package/dist/lib/features/ppt/slideRenderers.js +6 -4
  62. package/dist/lib/features/ppt/slideTypeInference.d.ts +1 -1
  63. package/dist/lib/features/ppt/slideTypeInference.js +75 -73
  64. package/dist/lib/files/fileTools.d.ts +6 -6
  65. package/dist/lib/index.d.ts +46 -12
  66. package/dist/lib/index.js +79 -17
  67. package/dist/lib/mcp/httpRateLimiter.js +39 -12
  68. package/dist/lib/mcp/httpRetryHandler.js +22 -1
  69. package/dist/lib/mcp/mcpClientFactory.js +13 -15
  70. package/dist/lib/memory/memoryRetrievalTools.js +22 -0
  71. package/dist/lib/neurolink.d.ts +64 -72
  72. package/dist/lib/neurolink.js +984 -566
  73. package/dist/lib/observability/exporterRegistry.d.ts +152 -0
  74. package/dist/lib/observability/exporterRegistry.js +414 -0
  75. package/dist/lib/observability/exporters/arizeExporter.d.ts +32 -0
  76. package/dist/lib/observability/exporters/arizeExporter.js +139 -0
  77. package/dist/lib/observability/exporters/baseExporter.d.ts +117 -0
  78. package/dist/lib/observability/exporters/baseExporter.js +191 -0
  79. package/dist/lib/observability/exporters/braintrustExporter.d.ts +30 -0
  80. package/dist/lib/observability/exporters/braintrustExporter.js +155 -0
  81. package/dist/lib/observability/exporters/datadogExporter.d.ts +37 -0
  82. package/dist/lib/observability/exporters/datadogExporter.js +197 -0
  83. package/dist/lib/observability/exporters/index.d.ts +13 -0
  84. package/dist/lib/observability/exporters/index.js +14 -0
  85. package/dist/lib/observability/exporters/laminarExporter.d.ts +48 -0
  86. package/dist/lib/observability/exporters/laminarExporter.js +303 -0
  87. package/dist/lib/observability/exporters/langfuseExporter.d.ts +47 -0
  88. package/dist/lib/observability/exporters/langfuseExporter.js +200 -0
  89. package/dist/lib/observability/exporters/langsmithExporter.d.ts +26 -0
  90. package/dist/lib/observability/exporters/langsmithExporter.js +124 -0
  91. package/dist/lib/observability/exporters/otelExporter.d.ts +39 -0
  92. package/dist/lib/observability/exporters/otelExporter.js +165 -0
  93. package/dist/lib/observability/exporters/posthogExporter.d.ts +48 -0
  94. package/dist/lib/observability/exporters/posthogExporter.js +288 -0
  95. package/dist/lib/observability/exporters/sentryExporter.d.ts +32 -0
  96. package/dist/lib/observability/exporters/sentryExporter.js +166 -0
  97. package/dist/lib/observability/index.d.ts +25 -0
  98. package/dist/lib/observability/index.js +32 -0
  99. package/dist/lib/observability/metricsAggregator.d.ts +260 -0
  100. package/dist/lib/observability/metricsAggregator.js +553 -0
  101. package/dist/lib/observability/otelBridge.d.ts +49 -0
  102. package/dist/lib/observability/otelBridge.js +132 -0
  103. package/dist/lib/observability/retryPolicy.d.ts +192 -0
  104. package/dist/lib/observability/retryPolicy.js +384 -0
  105. package/dist/lib/observability/sampling/index.d.ts +4 -0
  106. package/dist/lib/observability/sampling/index.js +5 -0
  107. package/dist/lib/observability/sampling/samplers.d.ts +116 -0
  108. package/dist/lib/observability/sampling/samplers.js +217 -0
  109. package/dist/lib/observability/spanProcessor.d.ts +129 -0
  110. package/dist/lib/observability/spanProcessor.js +288 -0
  111. package/dist/lib/observability/tokenTracker.d.ts +156 -0
  112. package/dist/lib/observability/tokenTracker.js +414 -0
  113. package/dist/lib/observability/types/exporterTypes.d.ts +250 -0
  114. package/dist/lib/observability/types/exporterTypes.js +6 -0
  115. package/dist/lib/observability/types/index.d.ts +6 -0
  116. package/dist/lib/observability/types/index.js +5 -0
  117. package/dist/lib/observability/types/spanTypes.d.ts +244 -0
  118. package/dist/lib/observability/types/spanTypes.js +93 -0
  119. package/dist/lib/observability/utils/index.d.ts +4 -0
  120. package/dist/lib/observability/utils/index.js +5 -0
  121. package/dist/lib/observability/utils/spanSerializer.d.ts +115 -0
  122. package/dist/lib/observability/utils/spanSerializer.js +287 -0
  123. package/dist/lib/providers/amazonSagemaker.d.ts +5 -4
  124. package/dist/lib/providers/amazonSagemaker.js +3 -4
  125. package/dist/lib/providers/googleVertex.d.ts +7 -0
  126. package/dist/lib/providers/googleVertex.js +80 -2
  127. package/dist/lib/rag/pipeline/RAGPipeline.d.ts +0 -5
  128. package/dist/lib/rag/pipeline/RAGPipeline.js +122 -87
  129. package/dist/lib/rag/ragIntegration.js +30 -0
  130. package/dist/lib/rag/retrieval/hybridSearch.js +22 -0
  131. package/dist/lib/server/abstract/baseServerAdapter.js +51 -19
  132. package/dist/lib/server/middleware/common.js +44 -12
  133. package/dist/lib/services/server/ai/observability/instrumentation.d.ts +2 -2
  134. package/dist/lib/services/server/ai/observability/instrumentation.js +10 -5
  135. package/dist/lib/types/cli.d.ts +18 -2
  136. package/dist/lib/types/conversationMemoryInterface.d.ts +2 -0
  137. package/dist/lib/types/generateTypes.d.ts +2 -2
  138. package/dist/lib/types/modelTypes.d.ts +18 -18
  139. package/dist/lib/types/providers.d.ts +5 -0
  140. package/dist/lib/utils/pricing.js +25 -1
  141. package/dist/lib/utils/ttsProcessor.js +74 -59
  142. package/dist/lib/workflow/config.d.ts +36 -36
  143. package/dist/lib/workflow/core/ensembleExecutor.js +10 -0
  144. package/dist/lib/workflow/core/judgeScorer.js +20 -2
  145. package/dist/lib/workflow/core/workflowRunner.js +34 -1
  146. package/dist/mcp/httpRateLimiter.js +39 -12
  147. package/dist/mcp/httpRetryHandler.js +22 -1
  148. package/dist/mcp/mcpClientFactory.js +13 -15
  149. package/dist/memory/memoryRetrievalTools.js +22 -0
  150. package/dist/neurolink.d.ts +64 -72
  151. package/dist/neurolink.js +984 -566
  152. package/dist/observability/FEATURE-STATUS.md +269 -0
  153. package/dist/observability/exporterRegistry.d.ts +152 -0
  154. package/dist/observability/exporterRegistry.js +413 -0
  155. package/dist/observability/exporters/arizeExporter.d.ts +32 -0
  156. package/dist/observability/exporters/arizeExporter.js +138 -0
  157. package/dist/observability/exporters/baseExporter.d.ts +117 -0
  158. package/dist/observability/exporters/baseExporter.js +190 -0
  159. package/dist/observability/exporters/braintrustExporter.d.ts +30 -0
  160. package/dist/observability/exporters/braintrustExporter.js +154 -0
  161. package/dist/observability/exporters/datadogExporter.d.ts +37 -0
  162. package/dist/observability/exporters/datadogExporter.js +196 -0
  163. package/dist/observability/exporters/index.d.ts +13 -0
  164. package/dist/observability/exporters/index.js +13 -0
  165. package/dist/observability/exporters/laminarExporter.d.ts +48 -0
  166. package/dist/observability/exporters/laminarExporter.js +302 -0
  167. package/dist/observability/exporters/langfuseExporter.d.ts +47 -0
  168. package/dist/observability/exporters/langfuseExporter.js +199 -0
  169. package/dist/observability/exporters/langsmithExporter.d.ts +26 -0
  170. package/dist/observability/exporters/langsmithExporter.js +123 -0
  171. package/dist/observability/exporters/otelExporter.d.ts +39 -0
  172. package/dist/observability/exporters/otelExporter.js +164 -0
  173. package/dist/observability/exporters/posthogExporter.d.ts +48 -0
  174. package/dist/observability/exporters/posthogExporter.js +287 -0
  175. package/dist/observability/exporters/sentryExporter.d.ts +32 -0
  176. package/dist/observability/exporters/sentryExporter.js +165 -0
  177. package/dist/observability/index.d.ts +25 -0
  178. package/dist/observability/index.js +31 -0
  179. package/dist/observability/metricsAggregator.d.ts +260 -0
  180. package/dist/observability/metricsAggregator.js +552 -0
  181. package/dist/observability/otelBridge.d.ts +49 -0
  182. package/dist/observability/otelBridge.js +131 -0
  183. package/dist/observability/retryPolicy.d.ts +192 -0
  184. package/dist/observability/retryPolicy.js +383 -0
  185. package/dist/observability/sampling/index.d.ts +4 -0
  186. package/dist/observability/sampling/index.js +4 -0
  187. package/dist/observability/sampling/samplers.d.ts +116 -0
  188. package/dist/observability/sampling/samplers.js +216 -0
  189. package/dist/observability/spanProcessor.d.ts +129 -0
  190. package/dist/observability/spanProcessor.js +287 -0
  191. package/dist/observability/tokenTracker.d.ts +156 -0
  192. package/dist/observability/tokenTracker.js +413 -0
  193. package/dist/observability/types/exporterTypes.d.ts +250 -0
  194. package/dist/observability/types/exporterTypes.js +5 -0
  195. package/dist/observability/types/index.d.ts +6 -0
  196. package/dist/observability/types/index.js +4 -0
  197. package/dist/observability/types/spanTypes.d.ts +244 -0
  198. package/dist/observability/types/spanTypes.js +92 -0
  199. package/dist/observability/utils/index.d.ts +4 -0
  200. package/dist/observability/utils/index.js +4 -0
  201. package/dist/observability/utils/spanSerializer.d.ts +115 -0
  202. package/dist/observability/utils/spanSerializer.js +286 -0
  203. package/dist/providers/amazonSagemaker.d.ts +5 -4
  204. package/dist/providers/amazonSagemaker.js +3 -4
  205. package/dist/providers/googleVertex.d.ts +7 -0
  206. package/dist/providers/googleVertex.js +80 -2
  207. package/dist/rag/pipeline/RAGPipeline.d.ts +0 -5
  208. package/dist/rag/pipeline/RAGPipeline.js +122 -87
  209. package/dist/rag/ragIntegration.js +30 -0
  210. package/dist/rag/retrieval/hybridSearch.js +22 -0
  211. package/dist/server/abstract/baseServerAdapter.js +51 -19
  212. package/dist/server/middleware/common.js +44 -12
  213. package/dist/services/server/ai/observability/instrumentation.d.ts +2 -2
  214. package/dist/services/server/ai/observability/instrumentation.js +10 -5
  215. package/dist/types/cli.d.ts +18 -2
  216. package/dist/types/conversationMemoryInterface.d.ts +2 -0
  217. package/dist/types/generateTypes.d.ts +2 -2
  218. package/dist/types/providers.d.ts +5 -0
  219. package/dist/utils/pricing.js +25 -1
  220. package/dist/utils/ttsProcessor.js +74 -59
  221. package/dist/workflow/config.d.ts +52 -52
  222. package/dist/workflow/core/ensembleExecutor.js +10 -0
  223. package/dist/workflow/core/judgeScorer.js +20 -2
  224. package/dist/workflow/core/workflowRunner.js +34 -1
  225. package/package.json +1 -1
@@ -0,0 +1,413 @@
1
+ /**
2
+ * Token Usage Tracker
3
+ * Aggregates token usage and cost across spans
4
+ */
5
+ /**
6
+ * Built-in model pricing database (approximate, subject to change)
7
+ */
8
+ const MODEL_PRICING = {
9
+ // OpenAI
10
+ "gpt-4o": {
11
+ inputPricePerMillion: 2.5,
12
+ outputPricePerMillion: 10.0,
13
+ cachedInputPricePerMillion: 1.25,
14
+ },
15
+ "gpt-4o-mini": {
16
+ inputPricePerMillion: 0.15,
17
+ outputPricePerMillion: 0.6,
18
+ cachedInputPricePerMillion: 0.075,
19
+ },
20
+ o1: {
21
+ inputPricePerMillion: 15.0,
22
+ outputPricePerMillion: 60.0,
23
+ cachedInputPricePerMillion: 7.5,
24
+ },
25
+ "o1-mini": {
26
+ inputPricePerMillion: 3.0,
27
+ outputPricePerMillion: 12.0,
28
+ cachedInputPricePerMillion: 1.5,
29
+ },
30
+ // Anthropic
31
+ "claude-sonnet-4-20250514": {
32
+ inputPricePerMillion: 3.0,
33
+ outputPricePerMillion: 15.0,
34
+ cachedInputPricePerMillion: 0.3,
35
+ },
36
+ "claude-3-5-sonnet-20241022": {
37
+ inputPricePerMillion: 3.0,
38
+ outputPricePerMillion: 15.0,
39
+ cachedInputPricePerMillion: 0.3,
40
+ },
41
+ "claude-3-5-haiku-20241022": {
42
+ inputPricePerMillion: 0.8,
43
+ outputPricePerMillion: 4.0,
44
+ cachedInputPricePerMillion: 0.08,
45
+ },
46
+ // Google
47
+ "gemini-2.5-flash": {
48
+ inputPricePerMillion: 0.15,
49
+ outputPricePerMillion: 0.6,
50
+ },
51
+ "gemini-2.5-pro": {
52
+ inputPricePerMillion: 1.25,
53
+ outputPricePerMillion: 10.0,
54
+ },
55
+ "gemini-2.0-flash-exp": {
56
+ inputPricePerMillion: 0.15,
57
+ outputPricePerMillion: 0.6,
58
+ },
59
+ // Mistral
60
+ "mistral-large-latest": {
61
+ inputPricePerMillion: 2.0,
62
+ outputPricePerMillion: 6.0,
63
+ },
64
+ "mistral-small-latest": {
65
+ inputPricePerMillion: 0.2,
66
+ outputPricePerMillion: 0.6,
67
+ },
68
+ };
69
+ /**
70
+ * Token tracker for aggregating usage across spans
71
+ */
72
+ export class TokenTracker {
73
+ stats = {
74
+ totalInputTokens: 0,
75
+ totalOutputTokens: 0,
76
+ totalTokens: 0,
77
+ cacheReadTokens: 0,
78
+ cacheCreationTokens: 0,
79
+ reasoningTokens: 0,
80
+ totalCost: 0,
81
+ byProvider: new Map(),
82
+ byModel: new Map(),
83
+ bySpanType: new Map(),
84
+ };
85
+ customPricing = new Map();
86
+ /**
87
+ * Set custom pricing for a single model
88
+ * @param modelName - The model name (e.g., "gpt-4o", "claude-3-5-sonnet")
89
+ * @param pricing - The pricing information
90
+ */
91
+ setModelPricing(modelName, pricing) {
92
+ this.customPricing.set(modelName, pricing);
93
+ }
94
+ /**
95
+ * Update pricing for an existing model (alias for setModelPricing)
96
+ * @param model - The model name
97
+ * @param pricing - The new pricing information
98
+ */
99
+ updatePricing(model, pricing) {
100
+ this.customPricing.set(model, pricing);
101
+ }
102
+ /**
103
+ * Load pricing configuration from a config object
104
+ * Useful for loading pricing from environment or config files
105
+ * @param config - Record of model names to pricing information
106
+ */
107
+ loadPricingFromConfig(config) {
108
+ for (const [model, pricing] of Object.entries(config)) {
109
+ this.customPricing.set(model, pricing);
110
+ }
111
+ }
112
+ /**
113
+ * Get pricing for a specific model
114
+ * @param model - The model name
115
+ * @returns The pricing information or undefined if not found
116
+ */
117
+ getModelPricing(model) {
118
+ return this.customPricing.get(model) ?? MODEL_PRICING[model];
119
+ }
120
+ /**
121
+ * Get all available model pricing (custom + built-in)
122
+ * @returns Record of all model pricing
123
+ */
124
+ getAllPricing() {
125
+ const allPricing = { ...MODEL_PRICING };
126
+ // Custom pricing takes precedence
127
+ const customPricingEntries = Array.from(this.customPricing.entries());
128
+ for (const [model, pricing] of customPricingEntries) {
129
+ allPricing[model] = pricing;
130
+ }
131
+ return allPricing;
132
+ }
133
+ /**
134
+ * Remove custom pricing for a model (falls back to built-in)
135
+ * @param model - The model name to remove custom pricing for
136
+ */
137
+ removeCustomPricing(model) {
138
+ return this.customPricing.delete(model);
139
+ }
140
+ /**
141
+ * Track token usage from a span
142
+ */
143
+ trackSpan(span) {
144
+ const attrs = span.attributes;
145
+ const inputTokens = attrs["ai.tokens.input"] ?? 0;
146
+ const outputTokens = attrs["ai.tokens.output"] ?? 0;
147
+ const totalTokens = attrs["ai.tokens.total"] ?? inputTokens + outputTokens;
148
+ const cacheRead = attrs["ai.tokens.cache_read"] ?? 0;
149
+ const cacheCreation = attrs["ai.tokens.cache_creation"] ?? 0;
150
+ const reasoning = attrs["ai.tokens.reasoning"] ?? 0;
151
+ const cost = attrs["ai.cost.total"] ??
152
+ this.calculateCost(attrs, inputTokens, outputTokens, cacheRead);
153
+ // Update totals
154
+ this.stats.totalInputTokens += inputTokens;
155
+ this.stats.totalOutputTokens += outputTokens;
156
+ this.stats.totalTokens += totalTokens;
157
+ this.stats.cacheReadTokens += cacheRead;
158
+ this.stats.cacheCreationTokens += cacheCreation;
159
+ this.stats.reasoningTokens += reasoning;
160
+ this.stats.totalCost += cost;
161
+ // Update by provider
162
+ const provider = attrs["ai.provider"];
163
+ if (provider) {
164
+ const existing = this.stats.byProvider.get(provider) ?? {
165
+ provider,
166
+ inputTokens: 0,
167
+ outputTokens: 0,
168
+ totalTokens: 0,
169
+ cost: 0,
170
+ requestCount: 0,
171
+ };
172
+ existing.inputTokens += inputTokens;
173
+ existing.outputTokens += outputTokens;
174
+ existing.totalTokens += totalTokens;
175
+ existing.cost += cost;
176
+ existing.requestCount += 1;
177
+ this.stats.byProvider.set(provider, existing);
178
+ }
179
+ // Update by model
180
+ const model = attrs["ai.model"];
181
+ if (model) {
182
+ const existing = this.stats.byModel.get(model) ?? {
183
+ model,
184
+ provider: provider ?? "unknown",
185
+ inputTokens: 0,
186
+ outputTokens: 0,
187
+ totalTokens: 0,
188
+ cost: 0,
189
+ requestCount: 0,
190
+ avgTokensPerRequest: 0,
191
+ };
192
+ existing.inputTokens += inputTokens;
193
+ existing.outputTokens += outputTokens;
194
+ existing.totalTokens += totalTokens;
195
+ existing.cost += cost;
196
+ existing.requestCount += 1;
197
+ existing.avgTokensPerRequest =
198
+ existing.totalTokens / existing.requestCount;
199
+ this.stats.byModel.set(model, existing);
200
+ }
201
+ // Update by span type
202
+ const currentTypeTotal = this.stats.bySpanType.get(span.type) ?? 0;
203
+ this.stats.bySpanType.set(span.type, currentTypeTotal + totalTokens);
204
+ }
205
+ /**
206
+ * Calculate cost from token counts and provider/model
207
+ */
208
+ calculateCost(attrs, inputTokens, outputTokens, cacheReadTokens = 0) {
209
+ const model = attrs["ai.model"];
210
+ if (!model) {
211
+ return 0;
212
+ }
213
+ // Check custom pricing first, then fall back to built-in
214
+ const pricing = this.customPricing.get(model) ?? MODEL_PRICING[model];
215
+ if (!pricing) {
216
+ return 0;
217
+ }
218
+ const regularInputTokens = inputTokens - cacheReadTokens;
219
+ const regularCost = (regularInputTokens / 1_000_000) * pricing.inputPricePerMillion;
220
+ const cachedCost = (cacheReadTokens / 1_000_000) *
221
+ (pricing.cachedInputPricePerMillion ?? pricing.inputPricePerMillion);
222
+ const outputCost = (outputTokens / 1_000_000) * pricing.outputPricePerMillion;
223
+ return regularCost + cachedCost + outputCost;
224
+ }
225
+ /**
226
+ * Track token usage from a simple usage object
227
+ * This is a convenience method for tracking usage without a full span
228
+ * @param usage - Token usage data
229
+ */
230
+ trackUsage(usage) {
231
+ const inputTokens = usage.promptTokens ?? 0;
232
+ const outputTokens = usage.completionTokens ?? 0;
233
+ const totalTokens = usage.totalTokens ?? inputTokens + outputTokens;
234
+ // Update totals
235
+ this.stats.totalInputTokens += inputTokens;
236
+ this.stats.totalOutputTokens += outputTokens;
237
+ this.stats.totalTokens += totalTokens;
238
+ // Calculate cost if model is provided
239
+ let cost = 0;
240
+ if (usage.model) {
241
+ const pricing = this.customPricing.get(usage.model) ?? MODEL_PRICING[usage.model];
242
+ if (pricing) {
243
+ cost =
244
+ (inputTokens / 1_000_000) * pricing.inputPricePerMillion +
245
+ (outputTokens / 1_000_000) * pricing.outputPricePerMillion;
246
+ }
247
+ }
248
+ this.stats.totalCost += cost;
249
+ // Update by provider if provided
250
+ if (usage.provider) {
251
+ const existing = this.stats.byProvider.get(usage.provider) ?? {
252
+ provider: usage.provider,
253
+ inputTokens: 0,
254
+ outputTokens: 0,
255
+ totalTokens: 0,
256
+ cost: 0,
257
+ requestCount: 0,
258
+ };
259
+ existing.inputTokens += inputTokens;
260
+ existing.outputTokens += outputTokens;
261
+ existing.totalTokens += totalTokens;
262
+ existing.cost += cost;
263
+ existing.requestCount += 1;
264
+ this.stats.byProvider.set(usage.provider, existing);
265
+ }
266
+ // Update by model if provided
267
+ if (usage.model) {
268
+ const existing = this.stats.byModel.get(usage.model) ?? {
269
+ model: usage.model,
270
+ provider: usage.provider ?? "unknown",
271
+ inputTokens: 0,
272
+ outputTokens: 0,
273
+ totalTokens: 0,
274
+ cost: 0,
275
+ requestCount: 0,
276
+ avgTokensPerRequest: 0,
277
+ };
278
+ existing.inputTokens += inputTokens;
279
+ existing.outputTokens += outputTokens;
280
+ existing.totalTokens += totalTokens;
281
+ existing.cost += cost;
282
+ existing.requestCount += 1;
283
+ existing.avgTokensPerRequest =
284
+ existing.totalTokens / existing.requestCount;
285
+ this.stats.byModel.set(usage.model, existing);
286
+ }
287
+ }
288
+ /**
289
+ * Get current stats
290
+ */
291
+ getStats() {
292
+ return { ...this.stats };
293
+ }
294
+ /**
295
+ * Get stats for a specific time window of spans
296
+ */
297
+ getStatsForWindow(spans) {
298
+ const tracker = new TokenTracker();
299
+ // Copy custom pricing so windowed calculations use the same rates
300
+ for (const [model, pricing] of this.customPricing) {
301
+ tracker.setModelPricing(model, pricing);
302
+ }
303
+ for (const span of spans) {
304
+ tracker.trackSpan(span);
305
+ }
306
+ return tracker.getStats();
307
+ }
308
+ /**
309
+ * Reset all stats
310
+ */
311
+ reset() {
312
+ this.stats = {
313
+ totalInputTokens: 0,
314
+ totalOutputTokens: 0,
315
+ totalTokens: 0,
316
+ cacheReadTokens: 0,
317
+ cacheCreationTokens: 0,
318
+ reasoningTokens: 0,
319
+ totalCost: 0,
320
+ byProvider: new Map(),
321
+ byModel: new Map(),
322
+ bySpanType: new Map(),
323
+ };
324
+ }
325
+ /**
326
+ * Export stats as JSON
327
+ */
328
+ toJSON() {
329
+ return {
330
+ totalInputTokens: this.stats.totalInputTokens,
331
+ totalOutputTokens: this.stats.totalOutputTokens,
332
+ totalTokens: this.stats.totalTokens,
333
+ cacheReadTokens: this.stats.cacheReadTokens,
334
+ cacheCreationTokens: this.stats.cacheCreationTokens,
335
+ reasoningTokens: this.stats.reasoningTokens,
336
+ totalCost: this.stats.totalCost,
337
+ byProvider: Object.fromEntries(this.stats.byProvider),
338
+ byModel: Object.fromEntries(this.stats.byModel),
339
+ bySpanType: Object.fromEntries(this.stats.bySpanType),
340
+ };
341
+ }
342
+ /**
343
+ * Format cost as currency string
344
+ */
345
+ formatCost(cost, currency = "USD") {
346
+ return new Intl.NumberFormat("en-US", {
347
+ style: "currency",
348
+ currency,
349
+ minimumFractionDigits: 4,
350
+ }).format(cost);
351
+ }
352
+ /**
353
+ * Get a summary string of current stats
354
+ */
355
+ getSummary() {
356
+ const stats = this.stats;
357
+ return [
358
+ `Token Usage Summary:`,
359
+ ` Input tokens: ${stats.totalInputTokens.toLocaleString()}`,
360
+ ` Output tokens: ${stats.totalOutputTokens.toLocaleString()}`,
361
+ ` Total tokens: ${stats.totalTokens.toLocaleString()}`,
362
+ ` Total cost: ${this.formatCost(stats.totalCost)}`,
363
+ stats.cacheReadTokens > 0
364
+ ? ` Cache read tokens: ${stats.cacheReadTokens.toLocaleString()}`
365
+ : "",
366
+ stats.reasoningTokens > 0
367
+ ? ` Reasoning tokens: ${stats.reasoningTokens.toLocaleString()}`
368
+ : "",
369
+ ]
370
+ .filter(Boolean)
371
+ .join("\n");
372
+ }
373
+ }
374
+ /**
375
+ * Enrich span with token usage attributes
376
+ */
377
+ export function enrichSpanWithTokenUsage(span, usage) {
378
+ return {
379
+ ...span,
380
+ attributes: {
381
+ ...span.attributes,
382
+ "ai.tokens.input": usage.promptTokens ?? 0,
383
+ "ai.tokens.output": usage.completionTokens ?? 0,
384
+ "ai.tokens.total": usage.totalTokens ??
385
+ (usage.promptTokens ?? 0) + (usage.completionTokens ?? 0),
386
+ "ai.tokens.cache_creation": usage.cacheCreationTokens,
387
+ "ai.tokens.cache_read": usage.cacheReadTokens,
388
+ "ai.tokens.reasoning": usage.reasoningTokens,
389
+ },
390
+ };
391
+ }
392
+ /**
393
+ * Global token tracker instance (singleton pattern from main)
394
+ */
395
+ let globalTokenTracker = null;
396
+ /**
397
+ * Get the global token tracker instance
398
+ */
399
+ export function getTokenTracker() {
400
+ if (!globalTokenTracker) {
401
+ globalTokenTracker = new TokenTracker();
402
+ }
403
+ return globalTokenTracker;
404
+ }
405
+ /**
406
+ * Reset the global token tracker (for testing)
407
+ */
408
+ export function resetTokenTracker() {
409
+ if (globalTokenTracker) {
410
+ globalTokenTracker.reset();
411
+ }
412
+ globalTokenTracker = null;
413
+ }
@@ -0,0 +1,250 @@
1
+ /**
2
+ * Exporter configuration types
3
+ * Following NeuroLink's type conventions
4
+ */
5
+ /**
6
+ * Base configuration for all exporters
7
+ */
8
+ export type ExporterConfig = {
9
+ /** Whether the exporter is enabled */
10
+ enabled: boolean;
11
+ /** Maximum spans to buffer before auto-flush */
12
+ maxBufferSize?: number;
13
+ /** Flush interval in milliseconds */
14
+ flushIntervalMs?: number;
15
+ /** Request timeout in milliseconds */
16
+ timeoutMs?: number;
17
+ /** Number of retry attempts */
18
+ retries?: number;
19
+ /** Custom headers for HTTP requests */
20
+ headers?: Record<string, string>;
21
+ /** Environment name (dev, staging, prod) */
22
+ environment?: string;
23
+ /** Service/application version */
24
+ version?: string;
25
+ };
26
+ /**
27
+ * Export error details
28
+ */
29
+ export type ExportError = {
30
+ spanId: string;
31
+ error: string;
32
+ retryable: boolean;
33
+ };
34
+ /**
35
+ * Export result with status and metadata
36
+ */
37
+ export type ExportResult = {
38
+ success: boolean;
39
+ exportedCount: number;
40
+ failedCount: number;
41
+ errors?: ExportError[];
42
+ durationMs: number;
43
+ };
44
+ /**
45
+ * Exporter health status
46
+ */
47
+ export type ExporterHealthStatus = {
48
+ healthy: boolean;
49
+ name: string;
50
+ latencyMs?: number;
51
+ lastExportTime?: number;
52
+ pendingSpans: number;
53
+ errors?: string[];
54
+ };
55
+ /**
56
+ * Langfuse exporter configuration
57
+ */
58
+ export type LangfuseExporterConfig = ExporterConfig & {
59
+ publicKey: string;
60
+ /**
61
+ * @sensitive
62
+ * WARNING: This is a sensitive credential. Handle securely.
63
+ */
64
+ secretKey: string;
65
+ baseUrl?: string;
66
+ release?: string;
67
+ };
68
+ /**
69
+ * LangSmith exporter configuration
70
+ */
71
+ export type LangSmithExporterConfig = ExporterConfig & {
72
+ /**
73
+ * @sensitive
74
+ * WARNING: This is a sensitive credential. Handle securely.
75
+ */
76
+ apiKey: string;
77
+ projectName?: string;
78
+ endpoint?: string;
79
+ };
80
+ /**
81
+ * Datadog exporter configuration
82
+ */
83
+ export type DatadogExporterConfig = ExporterConfig & {
84
+ /**
85
+ * @sensitive
86
+ * WARNING: This is a sensitive credential. Handle securely.
87
+ */
88
+ apiKey: string;
89
+ appKey?: string;
90
+ /** Datadog site: us1, us3, us5, eu1, ap1 */
91
+ site?: string;
92
+ service?: string;
93
+ source?: string;
94
+ };
95
+ /**
96
+ * Sentry exporter configuration
97
+ */
98
+ export type SentryExporterConfig = ExporterConfig & {
99
+ /**
100
+ * @sensitive
101
+ * WARNING: This is a sensitive credential. Handle securely.
102
+ */
103
+ dsn: string;
104
+ tracesSampleRate?: number;
105
+ profilesSampleRate?: number;
106
+ release?: string;
107
+ };
108
+ /**
109
+ * Braintrust exporter configuration
110
+ */
111
+ export type BraintrustExporterConfig = ExporterConfig & {
112
+ /**
113
+ * @sensitive
114
+ * WARNING: This is a sensitive credential. Handle securely.
115
+ */
116
+ apiKey: string;
117
+ projectName: string;
118
+ endpoint?: string;
119
+ };
120
+ /**
121
+ * Arize exporter configuration
122
+ */
123
+ export type ArizeExporterConfig = ExporterConfig & {
124
+ /**
125
+ * @sensitive
126
+ * WARNING: This is a sensitive credential. Handle securely.
127
+ */
128
+ spaceKey: string;
129
+ /**
130
+ * @sensitive
131
+ * WARNING: This is a sensitive credential. Handle securely.
132
+ */
133
+ apiKey: string;
134
+ modelId?: string;
135
+ modelVersion?: string;
136
+ };
137
+ /**
138
+ * PostHog exporter configuration
139
+ */
140
+ export type PostHogExporterConfig = ExporterConfig & {
141
+ /**
142
+ * @sensitive
143
+ * WARNING: This is a sensitive credential. Handle securely.
144
+ */
145
+ apiKey: string;
146
+ host?: string;
147
+ personalApiKey?: string;
148
+ };
149
+ /**
150
+ * Laminar exporter configuration
151
+ */
152
+ export type LaminarExporterConfig = ExporterConfig & {
153
+ /**
154
+ * @sensitive
155
+ * WARNING: This is a sensitive credential. Handle securely.
156
+ */
157
+ apiKey: string;
158
+ projectApiKey?: string;
159
+ baseUrl?: string;
160
+ };
161
+ /**
162
+ * OpenTelemetry protocol types
163
+ */
164
+ export type OtelProtocol = "http" | "grpc" | "zipkin";
165
+ /**
166
+ * OpenTelemetry exporter configuration
167
+ */
168
+ export type OtelExporterConfig = ExporterConfig & {
169
+ endpoint: string;
170
+ protocol?: OtelProtocol;
171
+ serviceName?: string;
172
+ serviceVersion?: string;
173
+ resourceAttributes?: Record<string, string>;
174
+ compression?: "gzip" | "none";
175
+ };
176
+ /**
177
+ * Exporter plugin interface for custom exporters
178
+ */
179
+ export type ExporterPlugin = {
180
+ name: string;
181
+ version: string;
182
+ create(config: ExporterConfig): unknown;
183
+ };
184
+ /**
185
+ * Extended observability configuration for NeuroLink SDK
186
+ */
187
+ export type ExtendedObservabilityConfig = {
188
+ /** Langfuse configuration */
189
+ langfuse?: LangfuseExporterConfig;
190
+ /** LangSmith configuration */
191
+ langsmith?: LangSmithExporterConfig;
192
+ /** Datadog configuration */
193
+ datadog?: DatadogExporterConfig;
194
+ /** Sentry configuration */
195
+ sentry?: SentryExporterConfig;
196
+ /** Braintrust configuration */
197
+ braintrust?: BraintrustExporterConfig;
198
+ /** Arize configuration */
199
+ arize?: ArizeExporterConfig;
200
+ /** PostHog configuration */
201
+ posthog?: PostHogExporterConfig;
202
+ /** Laminar configuration */
203
+ laminar?: LaminarExporterConfig;
204
+ /** OpenTelemetry configuration */
205
+ openTelemetry?: OtelExporterConfig;
206
+ /** Sampling configuration */
207
+ sampling?: SamplerConfig;
208
+ };
209
+ /**
210
+ * Sampler configuration — discriminated union keyed on `type`.
211
+ * Each variant carries only the fields relevant to that sampler.
212
+ */
213
+ export type SamplerConfig = {
214
+ type: "always";
215
+ } | {
216
+ type: "never";
217
+ } | {
218
+ type: "ratio";
219
+ ratio: number;
220
+ } | {
221
+ type: "trace-id-ratio";
222
+ ratio: number;
223
+ } | {
224
+ type: "attribute-based";
225
+ rules: SamplingRule[];
226
+ defaultRatio?: number;
227
+ } | {
228
+ type: "priority";
229
+ rules: SamplingRule[];
230
+ defaultRatio?: number;
231
+ } | {
232
+ type: "error-only";
233
+ } | {
234
+ type: "custom";
235
+ rules?: SamplingRule[];
236
+ defaultRatio?: number;
237
+ };
238
+ /**
239
+ * Sampling rule definition
240
+ */
241
+ export type SamplingRule = {
242
+ /** Rule name for identification */
243
+ name: string;
244
+ /** Conditions that must match (AND logic) */
245
+ conditions: Record<string, unknown>;
246
+ /** Whether to sample if conditions match */
247
+ sample: boolean;
248
+ /** Optional priority (higher = evaluated first) */
249
+ priority?: number;
250
+ };
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Exporter configuration types
3
+ * Following NeuroLink's type conventions
4
+ */
5
+ export {};
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Observability types exports
3
+ */
4
+ export type { ArizeExporterConfig, BraintrustExporterConfig, DatadogExporterConfig, ExportError, ExporterConfig, ExporterHealthStatus, ExporterPlugin, ExportResult, ExtendedObservabilityConfig, LaminarExporterConfig, LangfuseExporterConfig, LangSmithExporterConfig, OtelExporterConfig, OtelProtocol, PostHogExporterConfig, SamplerConfig, SamplingRule, SentryExporterConfig, } from "./exporterTypes.js";
5
+ export { AGENT_ATTRIBUTES, GENAI_ATTRIBUTES, type LangfuseSpan, type LangSmithRun, type OtelSpan, type SpanAttributes, type SpanData, type SpanEvent, type SpanLink, SpanStatus, SpanType, } from "./spanTypes.js";
6
+ export type { TraceView } from "../metricsAggregator.js";
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Observability types exports
3
+ */
4
+ export { AGENT_ATTRIBUTES, GENAI_ATTRIBUTES, SpanStatus, SpanType, } from "./spanTypes.js";