@juspay/neurolink 9.24.0 → 9.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (215) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/adapters/tts/googleTTSHandler.js +26 -1
  3. package/dist/adapters/video/vertexVideoHandler.js +23 -17
  4. package/dist/cli/commands/config.d.ts +3 -3
  5. package/dist/cli/commands/observability.d.ts +53 -0
  6. package/dist/cli/commands/observability.js +453 -0
  7. package/dist/cli/commands/telemetry.d.ts +63 -0
  8. package/dist/cli/commands/telemetry.js +689 -0
  9. package/dist/cli/factories/commandFactory.js +29 -15
  10. package/dist/cli/parser.js +6 -9
  11. package/dist/cli/utils/formatters.d.ts +13 -0
  12. package/dist/cli/utils/formatters.js +23 -0
  13. package/dist/constants/contextWindows.js +6 -0
  14. package/dist/constants/enums.d.ts +6 -0
  15. package/dist/constants/enums.js +8 -2
  16. package/dist/context/budgetChecker.js +75 -48
  17. package/dist/context/contextCompactor.js +135 -127
  18. package/dist/core/baseProvider.d.ts +5 -0
  19. package/dist/core/baseProvider.js +158 -102
  20. package/dist/core/conversationMemoryInitializer.js +7 -4
  21. package/dist/core/conversationMemoryManager.d.ts +2 -0
  22. package/dist/core/conversationMemoryManager.js +6 -2
  23. package/dist/core/modules/GenerationHandler.d.ts +2 -2
  24. package/dist/core/modules/GenerationHandler.js +12 -12
  25. package/dist/evaluation/ragasEvaluator.js +39 -19
  26. package/dist/evaluation/scoring.js +46 -20
  27. package/dist/features/ppt/presentationOrchestrator.js +23 -0
  28. package/dist/features/ppt/slideGenerator.js +13 -0
  29. package/dist/features/ppt/slideRenderers.d.ts +1 -1
  30. package/dist/features/ppt/slideRenderers.js +6 -4
  31. package/dist/features/ppt/slideTypeInference.d.ts +1 -1
  32. package/dist/features/ppt/slideTypeInference.js +75 -73
  33. package/dist/files/fileTools.d.ts +6 -6
  34. package/dist/index.d.ts +46 -12
  35. package/dist/index.js +79 -17
  36. package/dist/lib/adapters/tts/googleTTSHandler.js +26 -1
  37. package/dist/lib/adapters/video/vertexVideoHandler.js +23 -17
  38. package/dist/lib/constants/contextWindows.js +6 -0
  39. package/dist/lib/constants/enums.d.ts +6 -0
  40. package/dist/lib/constants/enums.js +8 -2
  41. package/dist/lib/context/budgetChecker.js +75 -48
  42. package/dist/lib/context/contextCompactor.js +135 -127
  43. package/dist/lib/core/baseProvider.d.ts +5 -0
  44. package/dist/lib/core/baseProvider.js +158 -102
  45. package/dist/lib/core/conversationMemoryInitializer.js +7 -4
  46. package/dist/lib/core/conversationMemoryManager.d.ts +2 -0
  47. package/dist/lib/core/conversationMemoryManager.js +6 -2
  48. package/dist/lib/core/modules/GenerationHandler.d.ts +2 -2
  49. package/dist/lib/core/modules/GenerationHandler.js +12 -12
  50. package/dist/lib/evaluation/ragasEvaluator.js +39 -19
  51. package/dist/lib/evaluation/scoring.js +46 -20
  52. package/dist/lib/features/ppt/presentationOrchestrator.js +23 -0
  53. package/dist/lib/features/ppt/slideGenerator.js +13 -0
  54. package/dist/lib/features/ppt/slideRenderers.d.ts +1 -1
  55. package/dist/lib/features/ppt/slideRenderers.js +6 -4
  56. package/dist/lib/features/ppt/slideTypeInference.d.ts +1 -1
  57. package/dist/lib/features/ppt/slideTypeInference.js +75 -73
  58. package/dist/lib/files/fileTools.d.ts +6 -6
  59. package/dist/lib/index.d.ts +46 -12
  60. package/dist/lib/index.js +79 -17
  61. package/dist/lib/mcp/httpRateLimiter.js +39 -12
  62. package/dist/lib/mcp/httpRetryHandler.js +22 -1
  63. package/dist/lib/mcp/mcpClientFactory.js +13 -15
  64. package/dist/lib/memory/memoryRetrievalTools.js +22 -0
  65. package/dist/lib/neurolink.d.ts +64 -72
  66. package/dist/lib/neurolink.js +984 -566
  67. package/dist/lib/observability/exporterRegistry.d.ts +152 -0
  68. package/dist/lib/observability/exporterRegistry.js +414 -0
  69. package/dist/lib/observability/exporters/arizeExporter.d.ts +32 -0
  70. package/dist/lib/observability/exporters/arizeExporter.js +139 -0
  71. package/dist/lib/observability/exporters/baseExporter.d.ts +117 -0
  72. package/dist/lib/observability/exporters/baseExporter.js +191 -0
  73. package/dist/lib/observability/exporters/braintrustExporter.d.ts +30 -0
  74. package/dist/lib/observability/exporters/braintrustExporter.js +155 -0
  75. package/dist/lib/observability/exporters/datadogExporter.d.ts +37 -0
  76. package/dist/lib/observability/exporters/datadogExporter.js +197 -0
  77. package/dist/lib/observability/exporters/index.d.ts +13 -0
  78. package/dist/lib/observability/exporters/index.js +14 -0
  79. package/dist/lib/observability/exporters/laminarExporter.d.ts +48 -0
  80. package/dist/lib/observability/exporters/laminarExporter.js +303 -0
  81. package/dist/lib/observability/exporters/langfuseExporter.d.ts +47 -0
  82. package/dist/lib/observability/exporters/langfuseExporter.js +200 -0
  83. package/dist/lib/observability/exporters/langsmithExporter.d.ts +26 -0
  84. package/dist/lib/observability/exporters/langsmithExporter.js +124 -0
  85. package/dist/lib/observability/exporters/otelExporter.d.ts +39 -0
  86. package/dist/lib/observability/exporters/otelExporter.js +165 -0
  87. package/dist/lib/observability/exporters/posthogExporter.d.ts +48 -0
  88. package/dist/lib/observability/exporters/posthogExporter.js +288 -0
  89. package/dist/lib/observability/exporters/sentryExporter.d.ts +32 -0
  90. package/dist/lib/observability/exporters/sentryExporter.js +166 -0
  91. package/dist/lib/observability/index.d.ts +25 -0
  92. package/dist/lib/observability/index.js +32 -0
  93. package/dist/lib/observability/metricsAggregator.d.ts +260 -0
  94. package/dist/lib/observability/metricsAggregator.js +553 -0
  95. package/dist/lib/observability/otelBridge.d.ts +49 -0
  96. package/dist/lib/observability/otelBridge.js +132 -0
  97. package/dist/lib/observability/retryPolicy.d.ts +192 -0
  98. package/dist/lib/observability/retryPolicy.js +384 -0
  99. package/dist/lib/observability/sampling/index.d.ts +4 -0
  100. package/dist/lib/observability/sampling/index.js +5 -0
  101. package/dist/lib/observability/sampling/samplers.d.ts +116 -0
  102. package/dist/lib/observability/sampling/samplers.js +217 -0
  103. package/dist/lib/observability/spanProcessor.d.ts +129 -0
  104. package/dist/lib/observability/spanProcessor.js +288 -0
  105. package/dist/lib/observability/tokenTracker.d.ts +156 -0
  106. package/dist/lib/observability/tokenTracker.js +414 -0
  107. package/dist/lib/observability/types/exporterTypes.d.ts +250 -0
  108. package/dist/lib/observability/types/exporterTypes.js +6 -0
  109. package/dist/lib/observability/types/index.d.ts +6 -0
  110. package/dist/lib/observability/types/index.js +5 -0
  111. package/dist/lib/observability/types/spanTypes.d.ts +244 -0
  112. package/dist/lib/observability/types/spanTypes.js +93 -0
  113. package/dist/lib/observability/utils/index.d.ts +4 -0
  114. package/dist/lib/observability/utils/index.js +5 -0
  115. package/dist/lib/observability/utils/spanSerializer.d.ts +115 -0
  116. package/dist/lib/observability/utils/spanSerializer.js +287 -0
  117. package/dist/lib/providers/amazonSagemaker.d.ts +5 -4
  118. package/dist/lib/providers/amazonSagemaker.js +3 -4
  119. package/dist/lib/providers/googleVertex.d.ts +7 -0
  120. package/dist/lib/providers/googleVertex.js +80 -2
  121. package/dist/lib/rag/pipeline/RAGPipeline.d.ts +0 -5
  122. package/dist/lib/rag/pipeline/RAGPipeline.js +122 -87
  123. package/dist/lib/rag/ragIntegration.js +30 -0
  124. package/dist/lib/rag/retrieval/hybridSearch.js +22 -0
  125. package/dist/lib/server/abstract/baseServerAdapter.js +51 -19
  126. package/dist/lib/server/middleware/common.js +44 -12
  127. package/dist/lib/services/server/ai/observability/instrumentation.d.ts +2 -2
  128. package/dist/lib/services/server/ai/observability/instrumentation.js +10 -5
  129. package/dist/lib/types/conversationMemoryInterface.d.ts +2 -0
  130. package/dist/lib/types/modelTypes.d.ts +18 -18
  131. package/dist/lib/types/providers.d.ts +5 -0
  132. package/dist/lib/utils/pricing.js +25 -1
  133. package/dist/lib/utils/ttsProcessor.js +74 -59
  134. package/dist/lib/workflow/config.d.ts +36 -36
  135. package/dist/lib/workflow/core/ensembleExecutor.js +10 -0
  136. package/dist/lib/workflow/core/judgeScorer.js +20 -2
  137. package/dist/lib/workflow/core/workflowRunner.js +34 -1
  138. package/dist/mcp/httpRateLimiter.js +39 -12
  139. package/dist/mcp/httpRetryHandler.js +22 -1
  140. package/dist/mcp/mcpClientFactory.js +13 -15
  141. package/dist/memory/memoryRetrievalTools.js +22 -0
  142. package/dist/neurolink.d.ts +64 -72
  143. package/dist/neurolink.js +984 -566
  144. package/dist/observability/FEATURE-STATUS.md +269 -0
  145. package/dist/observability/exporterRegistry.d.ts +152 -0
  146. package/dist/observability/exporterRegistry.js +413 -0
  147. package/dist/observability/exporters/arizeExporter.d.ts +32 -0
  148. package/dist/observability/exporters/arizeExporter.js +138 -0
  149. package/dist/observability/exporters/baseExporter.d.ts +117 -0
  150. package/dist/observability/exporters/baseExporter.js +190 -0
  151. package/dist/observability/exporters/braintrustExporter.d.ts +30 -0
  152. package/dist/observability/exporters/braintrustExporter.js +154 -0
  153. package/dist/observability/exporters/datadogExporter.d.ts +37 -0
  154. package/dist/observability/exporters/datadogExporter.js +196 -0
  155. package/dist/observability/exporters/index.d.ts +13 -0
  156. package/dist/observability/exporters/index.js +13 -0
  157. package/dist/observability/exporters/laminarExporter.d.ts +48 -0
  158. package/dist/observability/exporters/laminarExporter.js +302 -0
  159. package/dist/observability/exporters/langfuseExporter.d.ts +47 -0
  160. package/dist/observability/exporters/langfuseExporter.js +199 -0
  161. package/dist/observability/exporters/langsmithExporter.d.ts +26 -0
  162. package/dist/observability/exporters/langsmithExporter.js +123 -0
  163. package/dist/observability/exporters/otelExporter.d.ts +39 -0
  164. package/dist/observability/exporters/otelExporter.js +164 -0
  165. package/dist/observability/exporters/posthogExporter.d.ts +48 -0
  166. package/dist/observability/exporters/posthogExporter.js +287 -0
  167. package/dist/observability/exporters/sentryExporter.d.ts +32 -0
  168. package/dist/observability/exporters/sentryExporter.js +165 -0
  169. package/dist/observability/index.d.ts +25 -0
  170. package/dist/observability/index.js +31 -0
  171. package/dist/observability/metricsAggregator.d.ts +260 -0
  172. package/dist/observability/metricsAggregator.js +552 -0
  173. package/dist/observability/otelBridge.d.ts +49 -0
  174. package/dist/observability/otelBridge.js +131 -0
  175. package/dist/observability/retryPolicy.d.ts +192 -0
  176. package/dist/observability/retryPolicy.js +383 -0
  177. package/dist/observability/sampling/index.d.ts +4 -0
  178. package/dist/observability/sampling/index.js +4 -0
  179. package/dist/observability/sampling/samplers.d.ts +116 -0
  180. package/dist/observability/sampling/samplers.js +216 -0
  181. package/dist/observability/spanProcessor.d.ts +129 -0
  182. package/dist/observability/spanProcessor.js +287 -0
  183. package/dist/observability/tokenTracker.d.ts +156 -0
  184. package/dist/observability/tokenTracker.js +413 -0
  185. package/dist/observability/types/exporterTypes.d.ts +250 -0
  186. package/dist/observability/types/exporterTypes.js +5 -0
  187. package/dist/observability/types/index.d.ts +6 -0
  188. package/dist/observability/types/index.js +4 -0
  189. package/dist/observability/types/spanTypes.d.ts +244 -0
  190. package/dist/observability/types/spanTypes.js +92 -0
  191. package/dist/observability/utils/index.d.ts +4 -0
  192. package/dist/observability/utils/index.js +4 -0
  193. package/dist/observability/utils/spanSerializer.d.ts +115 -0
  194. package/dist/observability/utils/spanSerializer.js +286 -0
  195. package/dist/providers/amazonSagemaker.d.ts +5 -4
  196. package/dist/providers/amazonSagemaker.js +3 -4
  197. package/dist/providers/googleVertex.d.ts +7 -0
  198. package/dist/providers/googleVertex.js +80 -2
  199. package/dist/rag/pipeline/RAGPipeline.d.ts +0 -5
  200. package/dist/rag/pipeline/RAGPipeline.js +122 -87
  201. package/dist/rag/ragIntegration.js +30 -0
  202. package/dist/rag/retrieval/hybridSearch.js +22 -0
  203. package/dist/server/abstract/baseServerAdapter.js +51 -19
  204. package/dist/server/middleware/common.js +44 -12
  205. package/dist/services/server/ai/observability/instrumentation.d.ts +2 -2
  206. package/dist/services/server/ai/observability/instrumentation.js +10 -5
  207. package/dist/types/conversationMemoryInterface.d.ts +2 -0
  208. package/dist/types/providers.d.ts +5 -0
  209. package/dist/utils/pricing.js +25 -1
  210. package/dist/utils/ttsProcessor.js +74 -59
  211. package/dist/workflow/config.d.ts +52 -52
  212. package/dist/workflow/core/ensembleExecutor.js +10 -0
  213. package/dist/workflow/core/judgeScorer.js +20 -2
  214. package/dist/workflow/core/workflowRunner.js +34 -1
  215. package/package.json +1 -1
@@ -0,0 +1,286 @@
1
+ /**
2
+ * Utility class for span creation and serialization
3
+ * Handles conversion between NeuroLink's span format and platform-specific formats
4
+ */
5
+ import { randomBytes } from "node:crypto";
6
+ import { SpanStatus, SpanType, } from "../types/index.js";
7
+ /**
8
+ * Utility class for span creation and serialization
9
+ */
10
+ export class SpanSerializer {
11
+ /**
12
+ * Create a new span with generated IDs
13
+ */
14
+ static createSpan(type, name, attributes = {}, parentSpanId, traceId) {
15
+ return {
16
+ spanId: randomBytes(8).toString("hex"),
17
+ traceId: traceId ?? randomBytes(16).toString("hex"),
18
+ parentSpanId,
19
+ type,
20
+ name,
21
+ startTime: new Date().toISOString(),
22
+ status: SpanStatus.UNSET,
23
+ attributes: attributes,
24
+ events: [],
25
+ links: [],
26
+ };
27
+ }
28
+ /**
29
+ * End a span with status
30
+ */
31
+ static endSpan(span, status = SpanStatus.OK, statusMessage) {
32
+ const endTime = new Date();
33
+ const startTime = new Date(span.startTime);
34
+ return {
35
+ ...span,
36
+ endTime: endTime.toISOString(),
37
+ durationMs: endTime.getTime() - startTime.getTime(),
38
+ status,
39
+ statusMessage,
40
+ };
41
+ }
42
+ /**
43
+ * Add event to span
44
+ */
45
+ static addEvent(span, name, attributes) {
46
+ const event = {
47
+ name,
48
+ timestamp: new Date().toISOString(),
49
+ attributes,
50
+ };
51
+ return {
52
+ ...span,
53
+ events: [...span.events, event],
54
+ };
55
+ }
56
+ /**
57
+ * Update span attributes
58
+ */
59
+ static updateAttributes(span, attributes) {
60
+ return {
61
+ ...span,
62
+ attributes: {
63
+ ...span.attributes,
64
+ ...attributes,
65
+ },
66
+ };
67
+ }
68
+ /**
69
+ * Serialize span to JSON for export
70
+ */
71
+ static toJSON(span) {
72
+ return JSON.stringify(span, null, 2);
73
+ }
74
+ /**
75
+ * Instance method to serialize a span object to JSON string
76
+ * @param span - The span data to serialize (can be partial span data)
77
+ * @returns JSON string representation of the span
78
+ */
79
+ serialize(span) {
80
+ return JSON.stringify(span, null, 2);
81
+ }
82
+ /**
83
+ * Instance method to deserialize a JSON string to span data
84
+ * @param json - The JSON string to parse
85
+ * @returns Parsed span data
86
+ */
87
+ deserialize(json) {
88
+ return JSON.parse(json);
89
+ }
90
+ /**
91
+ * Parse span from JSON
92
+ */
93
+ static fromJSON(json) {
94
+ return JSON.parse(json);
95
+ }
96
+ /**
97
+ * Serialize span for Langfuse format
98
+ */
99
+ static toLangfuseFormat(span) {
100
+ return {
101
+ id: span.spanId,
102
+ traceId: span.traceId,
103
+ parentObservationId: span.parentSpanId,
104
+ name: span.name,
105
+ startTime: span.startTime,
106
+ endTime: span.endTime,
107
+ metadata: { ...span.attributes },
108
+ level: span.status === SpanStatus.ERROR ? "ERROR" : "DEFAULT",
109
+ statusMessage: span.statusMessage,
110
+ input: span.attributes["input"],
111
+ output: span.attributes["output"],
112
+ usage: span.attributes["ai.tokens.total"] !== undefined
113
+ ? {
114
+ promptTokens: span.attributes["ai.tokens.input"],
115
+ completionTokens: span.attributes["ai.tokens.output"],
116
+ totalTokens: span.attributes["ai.tokens.total"],
117
+ }
118
+ : undefined,
119
+ };
120
+ }
121
+ /**
122
+ * Serialize span for LangSmith format
123
+ */
124
+ static toLangSmithFormat(span) {
125
+ return {
126
+ id: span.spanId,
127
+ trace_id: span.traceId,
128
+ parent_run_id: span.parentSpanId,
129
+ name: span.name,
130
+ run_type: SpanSerializer.mapSpanTypeToLangSmithRunType(span.type),
131
+ start_time: span.startTime,
132
+ end_time: span.endTime,
133
+ extra: { ...span.attributes },
134
+ error: span.status === SpanStatus.ERROR ? span.statusMessage : undefined,
135
+ inputs: span.attributes["input"],
136
+ outputs: span.attributes["output"],
137
+ tags: SpanSerializer.extractTags(span.attributes),
138
+ };
139
+ }
140
+ /**
141
+ * Serialize span for OpenTelemetry format
142
+ */
143
+ static toOtelFormat(span) {
144
+ return {
145
+ traceId: span.traceId,
146
+ spanId: span.spanId,
147
+ parentSpanId: span.parentSpanId,
148
+ name: span.name,
149
+ kind: 1, // SPAN_KIND_INTERNAL
150
+ startTimeUnixNano: new Date(span.startTime).getTime() * 1_000_000,
151
+ endTimeUnixNano: span.endTime
152
+ ? new Date(span.endTime).getTime() * 1_000_000
153
+ : undefined,
154
+ attributes: Object.entries(span.attributes)
155
+ .filter(([, value]) => value !== undefined)
156
+ .map(([key, value]) => ({
157
+ key,
158
+ value: SpanSerializer.toOtelAttributeValue(value),
159
+ })),
160
+ status: {
161
+ code: span.status,
162
+ message: span.statusMessage,
163
+ },
164
+ events: span.events.map((e) => ({
165
+ name: e.name,
166
+ timeUnixNano: new Date(e.timestamp).getTime() * 1_000_000,
167
+ attributes: e.attributes
168
+ ? Object.entries(e.attributes).map(([k, v]) => ({
169
+ key: k,
170
+ value: SpanSerializer.toOtelAttributeValue(v),
171
+ }))
172
+ : [],
173
+ })),
174
+ };
175
+ }
176
+ /**
177
+ * Convert value to OTel attribute value format
178
+ */
179
+ static toOtelAttributeValue(value) {
180
+ if (typeof value === "string") {
181
+ return { stringValue: value };
182
+ }
183
+ if (typeof value === "number") {
184
+ return Number.isInteger(value)
185
+ ? { intValue: value }
186
+ : { stringValue: String(value) };
187
+ }
188
+ if (typeof value === "boolean") {
189
+ return { boolValue: value };
190
+ }
191
+ return { stringValue: JSON.stringify(value) };
192
+ }
193
+ /**
194
+ * Map NeuroLink span type to LangSmith run type
195
+ */
196
+ static mapSpanTypeToLangSmithRunType(type) {
197
+ const mapping = {
198
+ [SpanType.AGENT_RUN]: "chain",
199
+ [SpanType.WORKFLOW_STEP]: "chain",
200
+ [SpanType.TOOL_CALL]: "tool",
201
+ [SpanType.MODEL_GENERATION]: "llm",
202
+ [SpanType.EMBEDDING]: "embedding",
203
+ [SpanType.RETRIEVAL]: "retriever",
204
+ [SpanType.MEMORY]: "chain",
205
+ [SpanType.CONTEXT_COMPACTION]: "chain",
206
+ [SpanType.RAG]: "retriever",
207
+ [SpanType.EVALUATION]: "chain",
208
+ [SpanType.MCP_TRANSPORT]: "tool",
209
+ [SpanType.MEDIA_GENERATION]: "llm",
210
+ [SpanType.PPT_GENERATION]: "chain",
211
+ [SpanType.WORKFLOW]: "chain",
212
+ [SpanType.TTS]: "chain",
213
+ [SpanType.SERVER_REQUEST]: "chain",
214
+ [SpanType.CUSTOM]: "chain",
215
+ };
216
+ return mapping[type] || "chain";
217
+ }
218
+ /**
219
+ * Extract tags from span attributes for LangSmith
220
+ */
221
+ static extractTags(attributes) {
222
+ const tags = [];
223
+ if (attributes["ai.provider"]) {
224
+ tags.push(`provider:${attributes["ai.provider"]}`);
225
+ }
226
+ if (attributes["ai.model"]) {
227
+ tags.push(`model:${attributes["ai.model"]}`);
228
+ }
229
+ if (attributes["deployment.environment"]) {
230
+ tags.push(`env:${attributes["deployment.environment"]}`);
231
+ }
232
+ if (attributes["tool.name"]) {
233
+ tags.push(`tool:${attributes["tool.name"]}`);
234
+ }
235
+ return tags;
236
+ }
237
+ /**
238
+ * Create a generation span with AI-specific attributes
239
+ */
240
+ static createGenerationSpan(params) {
241
+ return SpanSerializer.createSpan(SpanType.MODEL_GENERATION, params.name ?? `gen_ai.${params.provider}.chat`, {
242
+ "ai.provider": params.provider,
243
+ "ai.model": params.model,
244
+ "ai.temperature": params.temperature,
245
+ "ai.max_tokens": params.maxTokens,
246
+ input: params.input,
247
+ "user.id": params.userId,
248
+ "session.id": params.sessionId,
249
+ }, params.parentSpanId, params.traceId);
250
+ }
251
+ /**
252
+ * Create a tool call span
253
+ */
254
+ static createToolCallSpan(params) {
255
+ return SpanSerializer.createSpan(SpanType.TOOL_CALL, `tool.${params.toolName}`, {
256
+ "tool.name": params.toolName,
257
+ "tool.server": params.server,
258
+ input: params.input,
259
+ }, params.parentSpanId, params.traceId);
260
+ }
261
+ /**
262
+ * Enrich span with token usage
263
+ */
264
+ static enrichWithTokenUsage(span, usage) {
265
+ return SpanSerializer.updateAttributes(span, {
266
+ "ai.tokens.input": usage.promptTokens ?? 0,
267
+ "ai.tokens.output": usage.completionTokens ?? 0,
268
+ "ai.tokens.total": usage.totalTokens ??
269
+ (usage.promptTokens ?? 0) + (usage.completionTokens ?? 0),
270
+ "ai.tokens.cache_creation": usage.cacheCreationTokens,
271
+ "ai.tokens.cache_read": usage.cacheReadTokens,
272
+ "ai.tokens.reasoning": usage.reasoningTokens,
273
+ });
274
+ }
275
+ /**
276
+ * Enrich span with cost information
277
+ */
278
+ static enrichWithCost(span, cost) {
279
+ return SpanSerializer.updateAttributes(span, {
280
+ "ai.cost.input": cost.inputCost,
281
+ "ai.cost.output": cost.outputCost,
282
+ "ai.cost.total": cost.totalCost,
283
+ "ai.cost.currency": cost.currency ?? "USD",
284
+ });
285
+ }
286
+ }
@@ -4,11 +4,12 @@
4
4
  * This module provides a simplified SageMaker provider that extends BaseProvider
5
5
  * and integrates with the NeuroLink ecosystem using existing patterns.
6
6
  */
7
+ import type { LanguageModelV1, Schema } from "ai";
7
8
  import type { ZodType, ZodTypeDef } from "zod";
8
- import type { Schema, LanguageModelV1 } from "ai";
9
- import { AIProviderName } from "../constants/enums.js";
10
- import type { StreamOptions, StreamResult } from "../types/streamTypes.js";
9
+ import type { AIProviderName } from "../constants/enums.js";
11
10
  import { BaseProvider } from "../core/baseProvider.js";
11
+ import type { NeuroLink } from "../neurolink.js";
12
+ import type { StreamOptions, StreamResult } from "../types/streamTypes.js";
12
13
  /**
13
14
  * Amazon SageMaker Provider extending BaseProvider
14
15
  */
@@ -16,7 +17,7 @@ export declare class AmazonSageMakerProvider extends BaseProvider {
16
17
  private sagemakerModel;
17
18
  private sagemakerConfig;
18
19
  private modelConfig;
19
- constructor(modelName?: string, endpointName?: string, region?: string);
20
+ constructor(modelName?: string, endpointName?: string, region?: string, neurolink?: NeuroLink);
20
21
  protected getProviderName(): AIProviderName;
21
22
  protected getDefaultModel(): string;
22
23
  protected getAISDKModel(): LanguageModelV1;
@@ -4,11 +4,10 @@
4
4
  * This module provides a simplified SageMaker provider that extends BaseProvider
5
5
  * and integrates with the NeuroLink ecosystem using existing patterns.
6
6
  */
7
- import { AIProviderName } from "../constants/enums.js";
8
7
  import { BaseProvider } from "../core/baseProvider.js";
9
8
  import { logger } from "../utils/logger.js";
10
9
  // SageMaker-specific imports
11
- import { getSageMakerConfig, getSageMakerModelConfig, getDefaultSageMakerEndpoint, getSageMakerModel, } from "./sagemaker/config.js";
10
+ import { getDefaultSageMakerEndpoint, getSageMakerConfig, getSageMakerModel, getSageMakerModelConfig, } from "./sagemaker/config.js";
12
11
  import { handleSageMakerError, SageMakerError } from "./sagemaker/errors.js";
13
12
  import { SageMakerLanguageModel } from "./sagemaker/language-model.js";
14
13
  /**
@@ -18,8 +17,8 @@ export class AmazonSageMakerProvider extends BaseProvider {
18
17
  sagemakerModel;
19
18
  sagemakerConfig;
20
19
  modelConfig;
21
- constructor(modelName, endpointName, region) {
22
- super(modelName, "sagemaker");
20
+ constructor(modelName, endpointName, region, neurolink) {
21
+ super(modelName, "sagemaker", neurolink);
23
22
  try {
24
23
  // Load and validate configuration
25
24
  this.sagemakerConfig = getSageMakerConfig(region);
@@ -130,6 +130,13 @@ export declare class GoogleVertexProvider extends BaseProvider {
130
130
  * Shared by both stream and generate native Gemini 3 paths.
131
131
  */
132
132
  private buildNativeContentParts;
133
+ /**
134
+ * Convert conversationMessages from NeuroLink's ChatMessage format into
135
+ * the @google/genai contents format and prepend them before the current
136
+ * user message. This gives the native Gemini 3 path multi-turn context
137
+ * that was previously dropped (only the current prompt was sent).
138
+ */
139
+ private prependConversationHistory;
133
140
  /**
134
141
  * Execute stream using native @google/genai SDK for Gemini 3 models on Vertex AI
135
142
  * This bypasses @ai-sdk/google-vertex to properly handle thought_signature
@@ -1140,6 +1140,33 @@ export class GoogleVertexProvider extends BaseProvider {
1140
1140
  },
1141
1141
  ];
1142
1142
  }
1143
+ /**
1144
+ * Convert conversationMessages from NeuroLink's ChatMessage format into
1145
+ * the @google/genai contents format and prepend them before the current
1146
+ * user message. This gives the native Gemini 3 path multi-turn context
1147
+ * that was previously dropped (only the current prompt was sent).
1148
+ */
1149
+ prependConversationHistory(currentContents, conversationMessages) {
1150
+ if (!conversationMessages || conversationMessages.length === 0) {
1151
+ return currentContents;
1152
+ }
1153
+ const history = [];
1154
+ for (const msg of conversationMessages) {
1155
+ // @google/genai only accepts "user" and "model" roles in contents.
1156
+ // Skip system messages (handled via config.systemInstruction).
1157
+ // Map "assistant" → "model" (Gemini convention).
1158
+ const role = msg.role === "assistant" ? "model" : msg.role;
1159
+ if (role !== "user" && role !== "model") {
1160
+ continue;
1161
+ }
1162
+ if (!msg.content || msg.content.trim().length === 0) {
1163
+ continue;
1164
+ }
1165
+ history.push({ role, parts: [{ text: msg.content }] });
1166
+ }
1167
+ // Prepend history before current user message
1168
+ return [...history, ...currentContents];
1169
+ }
1143
1170
  // ── Shared Gemini 3 helpers are now in ./googleNativeGemini3.ts ──
1144
1171
  /**
1145
1172
  * Execute stream using native @google/genai SDK for Gemini 3 models on Vertex AI
@@ -1192,6 +1219,13 @@ export class GoogleVertexProvider extends BaseProvider {
1192
1219
  }
1193
1220
  // Build config
1194
1221
  const config = buildNativeConfig(options, toolsConfig);
1222
+ // Global endpoint rejects systemInstruction for Gemini 3.x —
1223
+ // move it into a prefixed user message (same fix as generate path)
1224
+ let streamSystemPreamble;
1225
+ if (effectiveLocation === "global" && config.systemInstruction) {
1226
+ streamSystemPreamble = config.systemInstruction;
1227
+ delete config.systemInstruction;
1228
+ }
1195
1229
  // Add JSON output format support for native SDK stream
1196
1230
  if (streamOptions.output?.format === "json" || streamOptions.schema) {
1197
1231
  config.responseMimeType = "application/json";
@@ -1212,7 +1246,26 @@ export class GoogleVertexProvider extends BaseProvider {
1212
1246
  const timeoutController = createTimeoutController(timeout, this.providerName, "stream");
1213
1247
  const composedSignal = composeAbortSignals(options.abortSignal, timeoutController?.controller.signal);
1214
1248
  const maxSteps = computeMaxStepsShared(options.maxSteps);
1215
- const currentContents = [...contents];
1249
+ // Inject conversation history so the native path has multi-turn context
1250
+ let currentContents = this.prependConversationHistory([...contents], options.conversationMessages);
1251
+ // Prepend system prompt as a user message for the global endpoint
1252
+ if (streamSystemPreamble) {
1253
+ currentContents = [
1254
+ {
1255
+ role: "user",
1256
+ parts: [
1257
+ { text: `[System Instructions]\n${streamSystemPreamble}` },
1258
+ ],
1259
+ },
1260
+ {
1261
+ role: "model",
1262
+ parts: [
1263
+ { text: "Understood. I will follow these instructions." },
1264
+ ],
1265
+ },
1266
+ ...currentContents,
1267
+ ];
1268
+ }
1216
1269
  let finalText = "";
1217
1270
  let lastStepText = "";
1218
1271
  let totalInputTokens = 0;
@@ -1355,6 +1408,14 @@ export class GoogleVertexProvider extends BaseProvider {
1355
1408
  }
1356
1409
  // Build config
1357
1410
  const config = buildNativeConfig(options, toolsConfig);
1411
+ // Global endpoint rejects systemInstruction for Gemini 3.x, returning
1412
+ // "Please use a valid role: user, model." Move it into a prefixed
1413
+ // user message so the model still receives the system context.
1414
+ let systemPreamble;
1415
+ if (effectiveLocation === "global" && config.systemInstruction) {
1416
+ systemPreamble = config.systemInstruction;
1417
+ delete config.systemInstruction;
1418
+ }
1358
1419
  // Note: Schema/JSON output for Gemini 3 native SDK is complex due to $ref resolution issues
1359
1420
  // For now, schemas are handled via the AI SDK fallback path, not native SDK
1360
1421
  // TODO: Implement proper $ref resolution for complex nested schemas
@@ -1363,7 +1424,24 @@ export class GoogleVertexProvider extends BaseProvider {
1363
1424
  const timeoutController = createTimeoutController(timeout, this.providerName, "generate");
1364
1425
  const composedSignal = composeAbortSignals(options.abortSignal, timeoutController?.controller.signal);
1365
1426
  const maxSteps = computeMaxStepsShared(options.maxSteps);
1366
- const currentContents = [...contents];
1427
+ // Inject conversation history so the native path has multi-turn context
1428
+ let currentContents = this.prependConversationHistory([...contents], options.conversationMessages);
1429
+ // Prepend system prompt as a user message for the global endpoint
1430
+ if (systemPreamble) {
1431
+ currentContents = [
1432
+ {
1433
+ role: "user",
1434
+ parts: [{ text: `[System Instructions]\n${systemPreamble}` }],
1435
+ },
1436
+ {
1437
+ role: "model",
1438
+ parts: [
1439
+ { text: "Understood. I will follow these instructions." },
1440
+ ],
1441
+ },
1442
+ ...currentContents,
1443
+ ];
1444
+ }
1367
1445
  let finalText = "";
1368
1446
  let lastStepText = "";
1369
1447
  let totalInputTokens = 0;
@@ -34,11 +34,6 @@ export type { IngestOptions } from "../../types/ragTypes.js";
34
34
  export type { QueryOptions } from "../../types/ragTypes.js";
35
35
  export type { RAGResponse } from "../../types/ragTypes.js";
36
36
  export type { PipelineStats } from "../../types/ragTypes.js";
37
- /**
38
- * RAG Pipeline Orchestrator
39
- *
40
- * Complete end-to-end pipeline for Retrieval-Augmented Generation.
41
- */
42
37
  export declare class RAGPipeline {
43
38
  private id;
44
39
  private config;