@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
@@ -471,8 +471,8 @@ export type GenerateResult = {
471
471
  * });
472
472
  *
473
473
  * if (result.ppt) {
474
- * console.log(`Generated ${result.ppt.slides.length} slides`);
475
- * console.log(`Title: ${result.ppt.slides[0].title}`);
474
+ * console.log(`Generated ${result.ppt.totalSlides} slides`);
475
+ * console.log(`Saved at: ${result.ppt.filePath}`);
476
476
  * }
477
477
  * ```
478
478
  */
@@ -89,24 +89,24 @@ export declare const ModelConfigSchema: z.ZodObject<{
89
89
  releaseDate: z.ZodString;
90
90
  }, "strip", z.ZodTypeAny, {
91
91
  capabilities: string[];
92
- id: string;
93
- displayName: string;
94
- deprecated: boolean;
95
92
  pricing: {
96
93
  output: number;
97
94
  input: number;
98
95
  };
96
+ id: string;
97
+ displayName: string;
98
+ deprecated: boolean;
99
99
  contextWindow: number;
100
100
  releaseDate: string;
101
101
  }, {
102
102
  capabilities: string[];
103
- id: string;
104
- displayName: string;
105
- deprecated: boolean;
106
103
  pricing: {
107
104
  output: number;
108
105
  input: number;
109
106
  };
107
+ id: string;
108
+ displayName: string;
109
+ deprecated: boolean;
110
110
  contextWindow: number;
111
111
  releaseDate: string;
112
112
  }>;
@@ -135,24 +135,24 @@ export declare const ModelRegistrySchema: z.ZodObject<{
135
135
  releaseDate: z.ZodString;
136
136
  }, "strip", z.ZodTypeAny, {
137
137
  capabilities: string[];
138
- id: string;
139
- displayName: string;
140
- deprecated: boolean;
141
138
  pricing: {
142
139
  output: number;
143
140
  input: number;
144
141
  };
142
+ id: string;
143
+ displayName: string;
144
+ deprecated: boolean;
145
145
  contextWindow: number;
146
146
  releaseDate: string;
147
147
  }, {
148
148
  capabilities: string[];
149
- id: string;
150
- displayName: string;
151
- deprecated: boolean;
152
149
  pricing: {
153
150
  output: number;
154
151
  input: number;
155
152
  };
153
+ id: string;
154
+ displayName: string;
155
+ deprecated: boolean;
156
156
  contextWindow: number;
157
157
  releaseDate: string;
158
158
  }>>>;
@@ -162,13 +162,13 @@ export declare const ModelRegistrySchema: z.ZodObject<{
162
162
  version: string;
163
163
  models: Record<string, Record<string, {
164
164
  capabilities: string[];
165
- id: string;
166
- displayName: string;
167
- deprecated: boolean;
168
165
  pricing: {
169
166
  output: number;
170
167
  input: number;
171
168
  };
169
+ id: string;
170
+ displayName: string;
171
+ deprecated: boolean;
172
172
  contextWindow: number;
173
173
  releaseDate: string;
174
174
  }>>;
@@ -179,13 +179,13 @@ export declare const ModelRegistrySchema: z.ZodObject<{
179
179
  version: string;
180
180
  models: Record<string, Record<string, {
181
181
  capabilities: string[];
182
- id: string;
183
- displayName: string;
184
- deprecated: boolean;
185
182
  pricing: {
186
183
  output: number;
187
184
  input: number;
188
185
  };
186
+ id: string;
187
+ displayName: string;
188
+ deprecated: boolean;
189
189
  contextWindow: number;
190
190
  releaseDate: string;
191
191
  }>>;
@@ -335,6 +335,11 @@ export type AIProvider = {
335
335
  customTools: Map<string, unknown>;
336
336
  executeTool: (toolName: string, params: unknown) => Promise<unknown>;
337
337
  }, functionTag: string): void;
338
+ /** Trace context propagated from NeuroLink SDK for parent-child span hierarchy */
339
+ _traceContext?: {
340
+ traceId: string;
341
+ parentSpanId: string;
342
+ } | null;
338
343
  };
339
344
  /**
340
345
  * Provider attempt result for iteration tracking (converted from interface)
@@ -61,6 +61,12 @@ const PRICING = {
61
61
  },
62
62
  // Google (Gemini)
63
63
  google: {
64
+ "gemini-2.5-flash": { input: 0.15 / 1_000_000, output: 0.6 / 1_000_000 },
65
+ "gemini-2.5-pro": { input: 1.25 / 1_000_000, output: 10.0 / 1_000_000 },
66
+ "gemini-2.5-flash-lite": {
67
+ input: 0.075 / 1_000_000,
68
+ output: 0.3 / 1_000_000,
69
+ },
64
70
  "gemini-2.0-flash": { input: 0.1 / 1_000_000, output: 0.4 / 1_000_000 },
65
71
  "gemini-2.0-pro": { input: 1.25 / 1_000_000, output: 10.0 / 1_000_000 },
66
72
  "gemini-1.5-pro": { input: 1.25 / 1_000_000, output: 5.0 / 1_000_000 },
@@ -101,7 +107,25 @@ function findRates(provider, model) {
101
107
  // Longest-prefix match
102
108
  const sortedKeys = Object.keys(providerPricing).sort((a, b) => b.length - a.length);
103
109
  const key = sortedKeys.find((k) => model.startsWith(k));
104
- return key ? providerPricing[key] : undefined;
110
+ if (key) {
111
+ return providerPricing[key];
112
+ }
113
+ // Fallback: Vertex hosts both Claude and Gemini models.
114
+ // If no match found under "vertex", try "google" pricing for Gemini models.
115
+ if (normalizedProvider === "vertex" && model.startsWith("gemini")) {
116
+ const googlePricing = PRICING["google"];
117
+ if (googlePricing) {
118
+ if (googlePricing[model]) {
119
+ return googlePricing[model];
120
+ }
121
+ const googleKeys = Object.keys(googlePricing).sort((a, b) => b.length - a.length);
122
+ const googleKey = googleKeys.find((k) => model.startsWith(k));
123
+ if (googleKey) {
124
+ return googlePricing[googleKey];
125
+ }
126
+ }
127
+ }
128
+ return undefined;
105
129
  }
106
130
  /**
107
131
  * Calculate the dollar cost of a generate/stream call based on token usage.
@@ -9,6 +9,8 @@
9
9
  import { logger } from "./logger.js";
10
10
  import { ErrorCategory, ErrorSeverity } from "../constants/enums.js";
11
11
  import { NeuroLinkError } from "./errorHandling.js";
12
+ import { SpanSerializer, SpanType, SpanStatus, } from "../observability/index.js";
13
+ import { getMetricsAggregator } from "../observability/index.js";
12
14
  /**
13
15
  * TTS-specific error codes
14
16
  */
@@ -175,63 +177,70 @@ export class TTSProcessor {
175
177
  * ```
176
178
  */
177
179
  static async synthesize(text, provider, options) {
178
- // Trim the text once at the start
179
- const trimmedText = text.trim();
180
- // 1. Text validation: reject empty text
181
- if (!trimmedText) {
182
- logger.error("[TTSProcessor] Text is required for synthesis");
183
- throw new TTSError({
184
- code: TTS_ERROR_CODES.EMPTY_TEXT,
185
- message: "Text is required for TTS synthesis",
186
- severity: ErrorSeverity.LOW,
187
- retriable: false,
188
- context: { provider },
189
- });
190
- }
191
- // 2. Handler lookup and error if provider not supported
192
- const handler = this.getHandler(provider);
193
- if (!handler) {
194
- logger.error(`[TTSProcessor] Provider "${provider}" is not registered`);
195
- throw new TTSError({
196
- code: TTS_ERROR_CODES.PROVIDER_NOT_SUPPORTED,
197
- message: `TTS provider "${provider}" is not supported. Use TTSProcessor.registerHandler() to register it.`,
198
- severity: ErrorSeverity.HIGH,
199
- retriable: false,
200
- context: {
201
- provider,
202
- availableProviders: Array.from(this.handlers.keys()),
203
- },
204
- });
205
- }
206
- // 3. Text validation: reject text exceeding provider-specific max length
207
- const maxTextLength = handler.maxTextLength ?? this.DEFAULT_MAX_TEXT_LENGTH;
208
- if (trimmedText.length > maxTextLength) {
209
- logger.error(`[TTSProcessor] Text exceeds maximum length of ${maxTextLength} characters for provider "${provider}"`);
210
- throw new TTSError({
211
- code: TTS_ERROR_CODES.TEXT_TOO_LONG,
212
- message: `Text length (${trimmedText.length}) exceeds maximum allowed length (${maxTextLength} characters) for provider "${provider}"`,
213
- severity: ErrorSeverity.MEDIUM,
214
- retriable: false,
215
- context: {
216
- provider,
217
- textLength: trimmedText.length,
218
- maxLength: maxTextLength,
219
- },
220
- });
221
- }
222
- // 4. Configuration check
223
- if (!handler.isConfigured()) {
224
- logger.warn(`[TTSProcessor] Provider "${provider}" is not properly configured`);
225
- throw new TTSError({
226
- code: TTS_ERROR_CODES.PROVIDER_NOT_CONFIGURED,
227
- message: `TTS provider "${provider}" is not configured. Please set the required API keys.`,
228
- category: ErrorCategory.CONFIGURATION,
229
- severity: ErrorSeverity.HIGH,
230
- retriable: false,
231
- context: { provider },
232
- });
233
- }
180
+ // Create span early so preflight failures are captured
181
+ const span = SpanSerializer.createSpan(SpanType.TTS, "tts.synthesize", {
182
+ "tts.operation": "synthesize",
183
+ "tts.provider": provider,
184
+ "tts.voice": options.voice,
185
+ "tts.format": options.format,
186
+ });
234
187
  try {
188
+ // Trim the text once at the start
189
+ const trimmedText = text.trim();
190
+ // 1. Text validation: reject empty text
191
+ if (!trimmedText) {
192
+ logger.error("[TTSProcessor] Text is required for synthesis");
193
+ throw new TTSError({
194
+ code: TTS_ERROR_CODES.EMPTY_TEXT,
195
+ message: "Text is required for TTS synthesis",
196
+ severity: ErrorSeverity.LOW,
197
+ retriable: false,
198
+ context: { provider },
199
+ });
200
+ }
201
+ // 2. Handler lookup and error if provider not supported
202
+ const handler = this.getHandler(provider);
203
+ if (!handler) {
204
+ logger.error(`[TTSProcessor] Provider "${provider}" is not registered`);
205
+ throw new TTSError({
206
+ code: TTS_ERROR_CODES.PROVIDER_NOT_SUPPORTED,
207
+ message: `TTS provider "${provider}" is not supported. Use TTSProcessor.registerHandler() to register it.`,
208
+ severity: ErrorSeverity.HIGH,
209
+ retriable: false,
210
+ context: {
211
+ provider,
212
+ availableProviders: Array.from(this.handlers.keys()),
213
+ },
214
+ });
215
+ }
216
+ // 3. Text validation: reject text exceeding provider-specific max length
217
+ const maxTextLength = handler.maxTextLength ?? this.DEFAULT_MAX_TEXT_LENGTH;
218
+ if (trimmedText.length > maxTextLength) {
219
+ logger.error(`[TTSProcessor] Text exceeds maximum length of ${maxTextLength} characters for provider "${provider}"`);
220
+ throw new TTSError({
221
+ code: TTS_ERROR_CODES.TEXT_TOO_LONG,
222
+ message: `Text length (${trimmedText.length}) exceeds maximum allowed length (${maxTextLength} characters) for provider "${provider}"`,
223
+ severity: ErrorSeverity.MEDIUM,
224
+ retriable: false,
225
+ context: {
226
+ provider,
227
+ textLength: trimmedText.length,
228
+ maxLength: maxTextLength,
229
+ },
230
+ });
231
+ }
232
+ // 4. Configuration check
233
+ if (!handler.isConfigured()) {
234
+ logger.warn(`[TTSProcessor] Provider "${provider}" is not properly configured`);
235
+ throw new TTSError({
236
+ code: TTS_ERROR_CODES.PROVIDER_NOT_CONFIGURED,
237
+ message: `TTS provider "${provider}" is not configured. Please set the required API keys.`,
238
+ category: ErrorCategory.CONFIGURATION,
239
+ severity: ErrorSeverity.HIGH,
240
+ retriable: false,
241
+ context: { provider },
242
+ });
243
+ }
235
244
  logger.debug(`[TTSProcessor] Starting synthesis with provider: ${provider}`);
236
245
  // 5. Call handler.synthesize() - providers handle their own timeouts
237
246
  const result = await handler.synthesize(trimmedText, options);
@@ -241,11 +250,17 @@ export class TTSProcessor {
241
250
  voice: result.voice ?? options.voice,
242
251
  };
243
252
  logger.info(`[TTSProcessor] Successfully synthesized ${result.size} bytes of audio`);
244
- // 7. Returns TTSResult with buffer, format, metadata
253
+ // 7. Record successful span
254
+ const endedSpan = SpanSerializer.endSpan(span, SpanStatus.OK);
255
+ getMetricsAggregator().recordSpan(endedSpan);
256
+ // 8. Returns TTSResult with buffer, format, metadata
245
257
  return enrichedResult;
246
258
  }
247
259
  catch (err) {
248
- // 8. Comprehensive error handling
260
+ // Record error span
261
+ const endedSpan = SpanSerializer.endSpan(span, SpanStatus.ERROR, err instanceof Error ? err.message : String(err));
262
+ getMetricsAggregator().recordSpan(endedSpan);
263
+ // 9. Comprehensive error handling
249
264
  // Re-throw TTSError as-is
250
265
  if (err instanceof TTSError) {
251
266
  throw err;
@@ -261,7 +276,7 @@ export class TTSProcessor {
261
276
  retriable: true,
262
277
  context: {
263
278
  provider,
264
- textLength: trimmedText.length,
279
+ textLength: text.trim().length,
265
280
  options,
266
281
  },
267
282
  originalError: err instanceof Error ? err : undefined,