@sentry/core 10.46.0 → 10.48.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 (381) hide show
  1. package/build/cjs/api.js +1 -0
  2. package/build/cjs/api.js.map +1 -1
  3. package/build/cjs/attributes.js +43 -0
  4. package/build/cjs/attributes.js.map +1 -1
  5. package/build/cjs/client.js +13 -6
  6. package/build/cjs/client.js.map +1 -1
  7. package/build/cjs/currentScopes.js +33 -0
  8. package/build/cjs/currentScopes.js.map +1 -1
  9. package/build/cjs/envelope.js +4 -3
  10. package/build/cjs/envelope.js.map +1 -1
  11. package/build/cjs/index.js +50 -13
  12. package/build/cjs/index.js.map +1 -1
  13. package/build/cjs/integration.js +6 -0
  14. package/build/cjs/integration.js.map +1 -1
  15. package/build/cjs/integrations/express/index.js +206 -0
  16. package/build/cjs/integrations/express/index.js.map +1 -0
  17. package/build/cjs/integrations/express/patch-layer.js +251 -0
  18. package/build/cjs/integrations/express/patch-layer.js.map +1 -0
  19. package/build/cjs/integrations/express/request-layer-store.js +25 -0
  20. package/build/cjs/integrations/express/request-layer-store.js.map +1 -0
  21. package/build/cjs/integrations/express/set-sdk-processing-metadata.js +17 -0
  22. package/build/cjs/integrations/express/set-sdk-processing-metadata.js.map +1 -0
  23. package/build/cjs/integrations/express/types.js +17 -0
  24. package/build/cjs/integrations/express/types.js.map +1 -0
  25. package/build/cjs/integrations/express/utils.js +238 -0
  26. package/build/cjs/integrations/express/utils.js.map +1 -0
  27. package/build/cjs/integrations/mcp-server/correlation.js +5 -1
  28. package/build/cjs/integrations/mcp-server/correlation.js.map +1 -1
  29. package/build/cjs/integrations/mcp-server/handlers.js +18 -10
  30. package/build/cjs/integrations/mcp-server/handlers.js.map +1 -1
  31. package/build/cjs/integrations/mcp-server/index.js +2 -1
  32. package/build/cjs/integrations/mcp-server/index.js.map +1 -1
  33. package/build/cjs/integrations/mcp-server/transport.js +1 -1
  34. package/build/cjs/integrations/mcp-server/transport.js.map +1 -1
  35. package/build/cjs/integrations/mcp-server/validation.js +7 -5
  36. package/build/cjs/integrations/mcp-server/validation.js.map +1 -1
  37. package/build/cjs/integrations/spanStreaming.js +48 -0
  38. package/build/cjs/integrations/spanStreaming.js.map +1 -0
  39. package/build/cjs/integrations/supabase.js +1 -1
  40. package/build/cjs/integrations/supabase.js.map +1 -1
  41. package/build/cjs/semanticAttributes.js +35 -3
  42. package/build/cjs/semanticAttributes.js.map +1 -1
  43. package/build/cjs/tracing/ai/gen-ai-attributes.js +9 -79
  44. package/build/cjs/tracing/ai/gen-ai-attributes.js.map +1 -1
  45. package/build/cjs/tracing/ai/utils.js +50 -35
  46. package/build/cjs/tracing/ai/utils.js.map +1 -1
  47. package/build/cjs/tracing/anthropic-ai/constants.js +10 -10
  48. package/build/cjs/tracing/anthropic-ai/constants.js.map +1 -1
  49. package/build/cjs/tracing/anthropic-ai/index.js +18 -20
  50. package/build/cjs/tracing/anthropic-ai/index.js.map +1 -1
  51. package/build/cjs/tracing/anthropic-ai/streaming.js +2 -100
  52. package/build/cjs/tracing/anthropic-ai/streaming.js.map +1 -1
  53. package/build/cjs/tracing/anthropic-ai/utils.js +0 -9
  54. package/build/cjs/tracing/anthropic-ai/utils.js.map +1 -1
  55. package/build/cjs/tracing/dynamicSamplingContext.js +2 -1
  56. package/build/cjs/tracing/dynamicSamplingContext.js.map +1 -1
  57. package/build/cjs/tracing/google-genai/constants.js +9 -12
  58. package/build/cjs/tracing/google-genai/constants.js.map +1 -1
  59. package/build/cjs/tracing/google-genai/index.js +49 -27
  60. package/build/cjs/tracing/google-genai/index.js.map +1 -1
  61. package/build/cjs/tracing/google-genai/streaming.js +2 -23
  62. package/build/cjs/tracing/google-genai/streaming.js.map +1 -1
  63. package/build/cjs/tracing/google-genai/utils.js +0 -25
  64. package/build/cjs/tracing/google-genai/utils.js.map +1 -1
  65. package/build/cjs/tracing/langchain/embeddings.js +132 -0
  66. package/build/cjs/tracing/langchain/embeddings.js.map +1 -0
  67. package/build/cjs/tracing/langchain/index.js.map +1 -1
  68. package/build/cjs/tracing/openai/constants.js +7 -7
  69. package/build/cjs/tracing/openai/constants.js.map +1 -1
  70. package/build/cjs/tracing/openai/index.js +19 -37
  71. package/build/cjs/tracing/openai/index.js.map +1 -1
  72. package/build/cjs/tracing/openai/streaming.js +3 -34
  73. package/build/cjs/tracing/openai/streaming.js.map +1 -1
  74. package/build/cjs/tracing/openai/utils.js +78 -243
  75. package/build/cjs/tracing/openai/utils.js.map +1 -1
  76. package/build/cjs/tracing/sentryNonRecordingSpan.js +7 -0
  77. package/build/cjs/tracing/sentryNonRecordingSpan.js.map +1 -1
  78. package/build/cjs/tracing/sentrySpan.js +39 -0
  79. package/build/cjs/tracing/sentrySpan.js.map +1 -1
  80. package/build/cjs/tracing/spans/beforeSendSpan.js +43 -0
  81. package/build/cjs/tracing/spans/beforeSendSpan.js.map +1 -0
  82. package/build/cjs/tracing/spans/captureSpan.js +126 -0
  83. package/build/cjs/tracing/spans/captureSpan.js.map +1 -0
  84. package/build/cjs/tracing/spans/envelope.js +38 -0
  85. package/build/cjs/tracing/spans/envelope.js.map +1 -0
  86. package/build/cjs/tracing/spans/estimateSize.js +41 -0
  87. package/build/cjs/tracing/spans/estimateSize.js.map +1 -0
  88. package/build/cjs/tracing/spans/hasSpanStreamingEnabled.js +11 -0
  89. package/build/cjs/tracing/spans/hasSpanStreamingEnabled.js.map +1 -0
  90. package/build/cjs/tracing/spans/spanBuffer.js +158 -0
  91. package/build/cjs/tracing/spans/spanBuffer.js.map +1 -0
  92. package/build/cjs/tracing/trace.js +88 -13
  93. package/build/cjs/tracing/trace.js.map +1 -1
  94. package/build/cjs/tracing/vercel-ai/utils.js +1 -4
  95. package/build/cjs/tracing/vercel-ai/utils.js.map +1 -1
  96. package/build/cjs/utils/featureFlags.js +6 -0
  97. package/build/cjs/utils/featureFlags.js.map +1 -1
  98. package/build/cjs/utils/object.js +33 -0
  99. package/build/cjs/utils/object.js.map +1 -1
  100. package/build/cjs/utils/spanUtils.js +116 -13
  101. package/build/cjs/utils/spanUtils.js.map +1 -1
  102. package/build/cjs/utils/stacktrace.js +3 -1
  103. package/build/cjs/utils/stacktrace.js.map +1 -1
  104. package/build/cjs/utils/string.js +3 -0
  105. package/build/cjs/utils/string.js.map +1 -1
  106. package/build/cjs/utils/traceData.js +11 -0
  107. package/build/cjs/utils/traceData.js.map +1 -1
  108. package/build/cjs/utils/version.js +1 -1
  109. package/build/esm/api.js +1 -1
  110. package/build/esm/api.js.map +1 -1
  111. package/build/esm/attributes.js +43 -1
  112. package/build/esm/attributes.js.map +1 -1
  113. package/build/esm/client.js +8 -1
  114. package/build/esm/client.js.map +1 -1
  115. package/build/esm/currentScopes.js +31 -1
  116. package/build/esm/currentScopes.js.map +1 -1
  117. package/build/esm/envelope.js +2 -1
  118. package/build/esm/envelope.js.map +1 -1
  119. package/build/esm/index.js +13 -4
  120. package/build/esm/index.js.map +1 -1
  121. package/build/esm/integration.js +6 -0
  122. package/build/esm/integration.js.map +1 -1
  123. package/build/esm/integrations/express/index.js +202 -0
  124. package/build/esm/integrations/express/index.js.map +1 -0
  125. package/build/esm/integrations/express/patch-layer.js +249 -0
  126. package/build/esm/integrations/express/patch-layer.js.map +1 -0
  127. package/build/esm/integrations/express/request-layer-store.js +22 -0
  128. package/build/esm/integrations/express/request-layer-store.js.map +1 -0
  129. package/build/esm/integrations/express/set-sdk-processing-metadata.js +15 -0
  130. package/build/esm/integrations/express/set-sdk-processing-metadata.js.map +1 -0
  131. package/build/esm/integrations/express/types.js +10 -0
  132. package/build/esm/integrations/express/types.js.map +1 -0
  133. package/build/esm/integrations/express/utils.js +225 -0
  134. package/build/esm/integrations/express/utils.js.map +1 -0
  135. package/build/esm/integrations/mcp-server/correlation.js +5 -1
  136. package/build/esm/integrations/mcp-server/correlation.js.map +1 -1
  137. package/build/esm/integrations/mcp-server/handlers.js +18 -10
  138. package/build/esm/integrations/mcp-server/handlers.js.map +1 -1
  139. package/build/esm/integrations/mcp-server/index.js +2 -1
  140. package/build/esm/integrations/mcp-server/index.js.map +1 -1
  141. package/build/esm/integrations/mcp-server/transport.js +1 -1
  142. package/build/esm/integrations/mcp-server/transport.js.map +1 -1
  143. package/build/esm/integrations/mcp-server/validation.js +7 -5
  144. package/build/esm/integrations/mcp-server/validation.js.map +1 -1
  145. package/build/esm/integrations/spanStreaming.js +46 -0
  146. package/build/esm/integrations/spanStreaming.js.map +1 -0
  147. package/build/esm/integrations/supabase.js +1 -1
  148. package/build/esm/integrations/supabase.js.map +1 -1
  149. package/build/esm/package.json +1 -1
  150. package/build/esm/semanticAttributes.js +26 -4
  151. package/build/esm/semanticAttributes.js.map +1 -1
  152. package/build/esm/tracing/ai/gen-ai-attributes.js +8 -69
  153. package/build/esm/tracing/ai/gen-ai-attributes.js.map +1 -1
  154. package/build/esm/tracing/ai/utils.js +51 -35
  155. package/build/esm/tracing/ai/utils.js.map +1 -1
  156. package/build/esm/tracing/anthropic-ai/constants.js +10 -10
  157. package/build/esm/tracing/anthropic-ai/constants.js.map +1 -1
  158. package/build/esm/tracing/anthropic-ai/index.js +21 -23
  159. package/build/esm/tracing/anthropic-ai/index.js.map +1 -1
  160. package/build/esm/tracing/anthropic-ai/streaming.js +3 -101
  161. package/build/esm/tracing/anthropic-ai/streaming.js.map +1 -1
  162. package/build/esm/tracing/anthropic-ai/utils.js +1 -9
  163. package/build/esm/tracing/anthropic-ai/utils.js.map +1 -1
  164. package/build/esm/tracing/dynamicSamplingContext.js +2 -1
  165. package/build/esm/tracing/dynamicSamplingContext.js.map +1 -1
  166. package/build/esm/tracing/google-genai/constants.js +9 -10
  167. package/build/esm/tracing/google-genai/constants.js.map +1 -1
  168. package/build/esm/tracing/google-genai/index.js +53 -31
  169. package/build/esm/tracing/google-genai/index.js.map +1 -1
  170. package/build/esm/tracing/google-genai/streaming.js +2 -23
  171. package/build/esm/tracing/google-genai/streaming.js.map +1 -1
  172. package/build/esm/tracing/google-genai/utils.js +1 -24
  173. package/build/esm/tracing/google-genai/utils.js.map +1 -1
  174. package/build/esm/tracing/langchain/embeddings.js +129 -0
  175. package/build/esm/tracing/langchain/embeddings.js.map +1 -0
  176. package/build/esm/tracing/langchain/index.js.map +1 -1
  177. package/build/esm/tracing/openai/constants.js +7 -7
  178. package/build/esm/tracing/openai/constants.js.map +1 -1
  179. package/build/esm/tracing/openai/index.js +21 -39
  180. package/build/esm/tracing/openai/index.js.map +1 -1
  181. package/build/esm/tracing/openai/streaming.js +4 -35
  182. package/build/esm/tracing/openai/streaming.js.map +1 -1
  183. package/build/esm/tracing/openai/utils.js +79 -232
  184. package/build/esm/tracing/openai/utils.js.map +1 -1
  185. package/build/esm/tracing/sentryNonRecordingSpan.js +7 -0
  186. package/build/esm/tracing/sentryNonRecordingSpan.js.map +1 -1
  187. package/build/esm/tracing/sentrySpan.js +40 -1
  188. package/build/esm/tracing/sentrySpan.js.map +1 -1
  189. package/build/esm/tracing/spans/beforeSendSpan.js +40 -0
  190. package/build/esm/tracing/spans/beforeSendSpan.js.map +1 -0
  191. package/build/esm/tracing/spans/captureSpan.js +122 -0
  192. package/build/esm/tracing/spans/captureSpan.js.map +1 -0
  193. package/build/esm/tracing/spans/envelope.js +36 -0
  194. package/build/esm/tracing/spans/envelope.js.map +1 -0
  195. package/build/esm/tracing/spans/estimateSize.js +39 -0
  196. package/build/esm/tracing/spans/estimateSize.js.map +1 -0
  197. package/build/esm/tracing/spans/hasSpanStreamingEnabled.js +9 -0
  198. package/build/esm/tracing/spans/hasSpanStreamingEnabled.js.map +1 -0
  199. package/build/esm/tracing/spans/spanBuffer.js +156 -0
  200. package/build/esm/tracing/spans/spanBuffer.js.map +1 -0
  201. package/build/esm/tracing/trace.js +89 -14
  202. package/build/esm/tracing/trace.js.map +1 -1
  203. package/build/esm/tracing/vercel-ai/utils.js +2 -5
  204. package/build/esm/tracing/vercel-ai/utils.js.map +1 -1
  205. package/build/esm/utils/featureFlags.js +6 -0
  206. package/build/esm/utils/featureFlags.js.map +1 -1
  207. package/build/esm/utils/object.js +33 -1
  208. package/build/esm/utils/object.js.map +1 -1
  209. package/build/esm/utils/spanUtils.js +112 -14
  210. package/build/esm/utils/spanUtils.js.map +1 -1
  211. package/build/esm/utils/stacktrace.js +3 -1
  212. package/build/esm/utils/stacktrace.js.map +1 -1
  213. package/build/esm/utils/string.js +3 -0
  214. package/build/esm/utils/string.js.map +1 -1
  215. package/build/esm/utils/traceData.js +12 -1
  216. package/build/esm/utils/traceData.js.map +1 -1
  217. package/build/esm/utils/version.js +1 -1
  218. package/build/types/api.d.ts +1 -0
  219. package/build/types/api.d.ts.map +1 -1
  220. package/build/types/asyncContext/types.d.ts +3 -1
  221. package/build/types/asyncContext/types.d.ts.map +1 -1
  222. package/build/types/attributes.d.ts +5 -0
  223. package/build/types/attributes.d.ts.map +1 -1
  224. package/build/types/client.d.ts +35 -1
  225. package/build/types/client.d.ts.map +1 -1
  226. package/build/types/currentScopes.d.ts +20 -0
  227. package/build/types/currentScopes.d.ts.map +1 -1
  228. package/build/types/envelope.d.ts.map +1 -1
  229. package/build/types/index.d.ts +15 -6
  230. package/build/types/index.d.ts.map +1 -1
  231. package/build/types/integration.d.ts.map +1 -1
  232. package/build/types/integrations/express/index.d.ts +75 -0
  233. package/build/types/integrations/express/index.d.ts.map +1 -0
  234. package/build/types/integrations/express/patch-layer.d.ts +32 -0
  235. package/build/types/integrations/express/patch-layer.d.ts.map +1 -0
  236. package/build/types/integrations/express/request-layer-store.d.ts +32 -0
  237. package/build/types/integrations/express/request-layer-store.d.ts.map +1 -0
  238. package/build/types/integrations/express/set-sdk-processing-metadata.d.ts +35 -0
  239. package/build/types/integrations/express/set-sdk-processing-metadata.d.ts.map +1 -0
  240. package/build/types/integrations/express/types.d.ts +154 -0
  241. package/build/types/integrations/express/types.d.ts.map +1 -0
  242. package/build/types/integrations/express/utils.d.ts +93 -0
  243. package/build/types/integrations/express/utils.d.ts.map +1 -0
  244. package/build/types/integrations/mcp-server/correlation.d.ts +2 -1
  245. package/build/types/integrations/mcp-server/correlation.d.ts.map +1 -1
  246. package/build/types/integrations/mcp-server/handlers.d.ts +9 -4
  247. package/build/types/integrations/mcp-server/handlers.d.ts.map +1 -1
  248. package/build/types/integrations/mcp-server/index.d.ts +2 -1
  249. package/build/types/integrations/mcp-server/index.d.ts.map +1 -1
  250. package/build/types/integrations/mcp-server/types.d.ts +40 -7
  251. package/build/types/integrations/mcp-server/types.d.ts.map +1 -1
  252. package/build/types/integrations/mcp-server/validation.d.ts +4 -1
  253. package/build/types/integrations/mcp-server/validation.d.ts.map +1 -1
  254. package/build/types/integrations/spanStreaming.d.ts +2 -0
  255. package/build/types/integrations/spanStreaming.d.ts.map +1 -0
  256. package/build/types/semanticAttributes.d.ts +23 -3
  257. package/build/types/semanticAttributes.d.ts.map +1 -1
  258. package/build/types/tracing/ai/gen-ai-attributes.d.ts +6 -46
  259. package/build/types/tracing/ai/gen-ai-attributes.d.ts.map +1 -1
  260. package/build/types/tracing/ai/utils.d.ts +34 -9
  261. package/build/types/tracing/ai/utils.d.ts.map +1 -1
  262. package/build/types/tracing/anthropic-ai/constants.d.ts +24 -1
  263. package/build/types/tracing/anthropic-ai/constants.d.ts.map +1 -1
  264. package/build/types/tracing/anthropic-ai/index.d.ts.map +1 -1
  265. package/build/types/tracing/anthropic-ai/streaming.d.ts.map +1 -1
  266. package/build/types/tracing/anthropic-ai/types.d.ts +5 -2
  267. package/build/types/tracing/anthropic-ai/types.d.ts.map +1 -1
  268. package/build/types/tracing/anthropic-ai/utils.d.ts +1 -5
  269. package/build/types/tracing/anthropic-ai/utils.d.ts.map +1 -1
  270. package/build/types/tracing/dynamicSamplingContext.d.ts.map +1 -1
  271. package/build/types/tracing/google-genai/constants.d.ts +22 -3
  272. package/build/types/tracing/google-genai/constants.d.ts.map +1 -1
  273. package/build/types/tracing/google-genai/index.d.ts.map +1 -1
  274. package/build/types/tracing/google-genai/streaming.d.ts.map +1 -1
  275. package/build/types/tracing/google-genai/types.d.ts +6 -2
  276. package/build/types/tracing/google-genai/types.d.ts.map +1 -1
  277. package/build/types/tracing/google-genai/utils.d.ts +0 -9
  278. package/build/types/tracing/google-genai/utils.d.ts.map +1 -1
  279. package/build/types/tracing/index.d.ts +1 -0
  280. package/build/types/tracing/index.d.ts.map +1 -1
  281. package/build/types/tracing/langchain/embeddings.d.ts +27 -0
  282. package/build/types/tracing/langchain/embeddings.d.ts.map +1 -0
  283. package/build/types/tracing/langchain/index.d.ts +1 -0
  284. package/build/types/tracing/langchain/index.d.ts.map +1 -1
  285. package/build/types/tracing/openai/constants.d.ts +14 -1
  286. package/build/types/tracing/openai/constants.d.ts.map +1 -1
  287. package/build/types/tracing/openai/index.d.ts.map +1 -1
  288. package/build/types/tracing/openai/streaming.d.ts.map +1 -1
  289. package/build/types/tracing/openai/types.d.ts +5 -2
  290. package/build/types/tracing/openai/types.d.ts.map +1 -1
  291. package/build/types/tracing/openai/utils.d.ts +4 -63
  292. package/build/types/tracing/openai/utils.d.ts.map +1 -1
  293. package/build/types/tracing/sentryNonRecordingSpan.d.ts +12 -1
  294. package/build/types/tracing/sentryNonRecordingSpan.d.ts.map +1 -1
  295. package/build/types/tracing/sentrySpan.d.ts +10 -1
  296. package/build/types/tracing/sentrySpan.d.ts.map +1 -1
  297. package/build/types/tracing/spans/beforeSendSpan.d.ts +35 -0
  298. package/build/types/tracing/spans/beforeSendSpan.d.ts.map +1 -0
  299. package/build/types/tracing/spans/captureSpan.d.ts +26 -0
  300. package/build/types/tracing/spans/captureSpan.d.ts.map +1 -0
  301. package/build/types/tracing/spans/envelope.d.ts +8 -0
  302. package/build/types/tracing/spans/envelope.d.ts.map +1 -0
  303. package/build/types/tracing/spans/estimateSize.d.ts +12 -0
  304. package/build/types/tracing/spans/estimateSize.d.ts.map +1 -0
  305. package/build/types/tracing/spans/hasSpanStreamingEnabled.d.ts +6 -0
  306. package/build/types/tracing/spans/hasSpanStreamingEnabled.d.ts.map +1 -0
  307. package/build/types/tracing/spans/spanBuffer.d.ts +60 -0
  308. package/build/types/tracing/spans/spanBuffer.d.ts.map +1 -0
  309. package/build/types/tracing/trace.d.ts.map +1 -1
  310. package/build/types/tracing/vercel-ai/utils.d.ts.map +1 -1
  311. package/build/types/types-hoist/envelope.d.ts +22 -2
  312. package/build/types/types-hoist/envelope.d.ts.map +1 -1
  313. package/build/types/types-hoist/integration.d.ts +8 -0
  314. package/build/types/types-hoist/integration.d.ts.map +1 -1
  315. package/build/types/types-hoist/link.d.ts +2 -2
  316. package/build/types/types-hoist/link.d.ts.map +1 -1
  317. package/build/types/types-hoist/options.d.ts +26 -2
  318. package/build/types/types-hoist/options.d.ts.map +1 -1
  319. package/build/types/types-hoist/span.d.ts +35 -0
  320. package/build/types/types-hoist/span.d.ts.map +1 -1
  321. package/build/types/utils/featureFlags.d.ts.map +1 -1
  322. package/build/types/utils/object.d.ts +10 -0
  323. package/build/types/utils/object.d.ts.map +1 -1
  324. package/build/types/utils/spanUtils.d.ts +27 -2
  325. package/build/types/utils/spanUtils.d.ts.map +1 -1
  326. package/build/types/utils/stacktrace.d.ts.map +1 -1
  327. package/build/types/utils/string.d.ts +2 -2
  328. package/build/types/utils/string.d.ts.map +1 -1
  329. package/build/types/utils/traceData.d.ts +4 -0
  330. package/build/types/utils/traceData.d.ts.map +1 -1
  331. package/build/types-ts3.8/api.d.ts +1 -0
  332. package/build/types-ts3.8/asyncContext/types.d.ts +3 -1
  333. package/build/types-ts3.8/attributes.d.ts +5 -0
  334. package/build/types-ts3.8/client.d.ts +35 -1
  335. package/build/types-ts3.8/currentScopes.d.ts +20 -0
  336. package/build/types-ts3.8/index.d.ts +15 -6
  337. package/build/types-ts3.8/integrations/express/index.d.ts +75 -0
  338. package/build/types-ts3.8/integrations/express/patch-layer.d.ts +32 -0
  339. package/build/types-ts3.8/integrations/express/request-layer-store.d.ts +32 -0
  340. package/build/types-ts3.8/integrations/express/set-sdk-processing-metadata.d.ts +35 -0
  341. package/build/types-ts3.8/integrations/express/types.d.ts +154 -0
  342. package/build/types-ts3.8/integrations/express/utils.d.ts +96 -0
  343. package/build/types-ts3.8/integrations/mcp-server/correlation.d.ts +2 -1
  344. package/build/types-ts3.8/integrations/mcp-server/handlers.d.ts +9 -4
  345. package/build/types-ts3.8/integrations/mcp-server/index.d.ts +2 -1
  346. package/build/types-ts3.8/integrations/mcp-server/types.d.ts +40 -7
  347. package/build/types-ts3.8/integrations/mcp-server/validation.d.ts +4 -1
  348. package/build/types-ts3.8/integrations/spanStreaming.d.ts +2 -0
  349. package/build/types-ts3.8/semanticAttributes.d.ts +23 -3
  350. package/build/types-ts3.8/tracing/ai/gen-ai-attributes.d.ts +6 -46
  351. package/build/types-ts3.8/tracing/ai/utils.d.ts +34 -9
  352. package/build/types-ts3.8/tracing/anthropic-ai/constants.d.ts +24 -9
  353. package/build/types-ts3.8/tracing/anthropic-ai/types.d.ts +5 -2
  354. package/build/types-ts3.8/tracing/anthropic-ai/utils.d.ts +1 -5
  355. package/build/types-ts3.8/tracing/google-genai/constants.d.ts +22 -9
  356. package/build/types-ts3.8/tracing/google-genai/types.d.ts +6 -2
  357. package/build/types-ts3.8/tracing/google-genai/utils.d.ts +0 -9
  358. package/build/types-ts3.8/tracing/index.d.ts +1 -0
  359. package/build/types-ts3.8/tracing/langchain/embeddings.d.ts +27 -0
  360. package/build/types-ts3.8/tracing/langchain/index.d.ts +1 -0
  361. package/build/types-ts3.8/tracing/openai/constants.d.ts +14 -6
  362. package/build/types-ts3.8/tracing/openai/types.d.ts +5 -2
  363. package/build/types-ts3.8/tracing/openai/utils.d.ts +4 -63
  364. package/build/types-ts3.8/tracing/sentryNonRecordingSpan.d.ts +12 -1
  365. package/build/types-ts3.8/tracing/sentrySpan.d.ts +10 -1
  366. package/build/types-ts3.8/tracing/spans/beforeSendSpan.d.ts +35 -0
  367. package/build/types-ts3.8/tracing/spans/captureSpan.d.ts +26 -0
  368. package/build/types-ts3.8/tracing/spans/envelope.d.ts +8 -0
  369. package/build/types-ts3.8/tracing/spans/estimateSize.d.ts +12 -0
  370. package/build/types-ts3.8/tracing/spans/hasSpanStreamingEnabled.d.ts +6 -0
  371. package/build/types-ts3.8/tracing/spans/spanBuffer.d.ts +60 -0
  372. package/build/types-ts3.8/types-hoist/envelope.d.ts +22 -2
  373. package/build/types-ts3.8/types-hoist/integration.d.ts +8 -0
  374. package/build/types-ts3.8/types-hoist/link.d.ts +2 -2
  375. package/build/types-ts3.8/types-hoist/options.d.ts +26 -2
  376. package/build/types-ts3.8/types-hoist/span.d.ts +35 -0
  377. package/build/types-ts3.8/utils/object.d.ts +10 -0
  378. package/build/types-ts3.8/utils/spanUtils.d.ts +27 -2
  379. package/build/types-ts3.8/utils/string.d.ts +2 -2
  380. package/build/types-ts3.8/utils/traceData.d.ts +4 -0
  381. package/package.json +1 -1
@@ -3,12 +3,14 @@ import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '../../semanticAttributes.js';
3
3
  import { SPAN_STATUS_ERROR } from '../spanstatus.js';
4
4
  import { startSpanManual, startSpan } from '../trace.js';
5
5
  import { handleCallbackErrors } from '../../utils/handleCallbackErrors.js';
6
- import { GEN_AI_OPERATION_NAME_ATTRIBUTE, GEN_AI_REQUEST_MODEL_ATTRIBUTE, GEN_AI_REQUEST_AVAILABLE_TOOLS_ATTRIBUTE, GEN_AI_SYSTEM_INSTRUCTIONS_ATTRIBUTE, GEN_AI_INPUT_MESSAGES_ATTRIBUTE, GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE, GEN_AI_RESPONSE_MODEL_ATTRIBUTE, GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE, GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE, GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE, GEN_AI_RESPONSE_TEXT_ATTRIBUTE, GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE, GEN_AI_SYSTEM_ATTRIBUTE, GEN_AI_REQUEST_TEMPERATURE_ATTRIBUTE, GEN_AI_REQUEST_TOP_P_ATTRIBUTE, GEN_AI_REQUEST_TOP_K_ATTRIBUTE, GEN_AI_REQUEST_MAX_TOKENS_ATTRIBUTE, GEN_AI_REQUEST_FREQUENCY_PENALTY_ATTRIBUTE, GEN_AI_REQUEST_PRESENCE_PENALTY_ATTRIBUTE } from '../ai/gen-ai-attributes.js';
6
+ import { GEN_AI_REQUEST_MODEL_ATTRIBUTE, GEN_AI_REQUEST_AVAILABLE_TOOLS_ATTRIBUTE, GEN_AI_EMBEDDINGS_INPUT_ATTRIBUTE, GEN_AI_SYSTEM_INSTRUCTIONS_ATTRIBUTE, GEN_AI_INPUT_MESSAGES_ATTRIBUTE, GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE, GEN_AI_RESPONSE_MODEL_ATTRIBUTE, GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE, GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE, GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE, GEN_AI_RESPONSE_TEXT_ATTRIBUTE, GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE, GEN_AI_OPERATION_NAME_ATTRIBUTE, GEN_AI_SYSTEM_ATTRIBUTE, GEN_AI_REQUEST_TEMPERATURE_ATTRIBUTE, GEN_AI_REQUEST_TOP_P_ATTRIBUTE, GEN_AI_REQUEST_TOP_K_ATTRIBUTE, GEN_AI_REQUEST_MAX_TOKENS_ATTRIBUTE, GEN_AI_REQUEST_FREQUENCY_PENALTY_ATTRIBUTE, GEN_AI_REQUEST_PRESENCE_PENALTY_ATTRIBUTE } from '../ai/gen-ai-attributes.js';
7
7
  import { truncateGenAiMessages } from '../ai/messageTruncation.js';
8
- import { resolveAIRecordingOptions, buildMethodPath, getFinalOperationName, getSpanOperation, extractSystemInstructions } from '../ai/utils.js';
9
- import { CHATS_CREATE_METHOD, CHAT_PATH, GOOGLE_GENAI_SYSTEM_NAME } from './constants.js';
8
+ import { resolveAIRecordingOptions, buildMethodPath, extractSystemInstructions } from '../ai/utils.js';
9
+ import { GOOGLE_GENAI_METHOD_REGISTRY, GOOGLE_GENAI_SYSTEM_NAME } from './constants.js';
10
10
  import { instrumentStream } from './streaming.js';
11
- import { shouldInstrument, isStreamingMethod, contentUnionToMessages } from './utils.js';
11
+ import { contentUnionToMessages } from './utils.js';
12
+
13
+ /* eslint-disable max-lines */
12
14
 
13
15
  /**
14
16
  * Extract model from parameters or chat context object
@@ -70,13 +72,13 @@ function extractConfigAttributes(config) {
70
72
  * Builds the base attributes for span creation including system info, model, and config
71
73
  */
72
74
  function extractRequestAttributes(
73
- methodPath,
75
+ operationName,
74
76
  params,
75
77
  context,
76
78
  ) {
77
79
  const attributes = {
78
80
  [GEN_AI_SYSTEM_ATTRIBUTE]: GOOGLE_GENAI_SYSTEM_NAME,
79
- [GEN_AI_OPERATION_NAME_ATTRIBUTE]: getFinalOperationName(methodPath),
81
+ [GEN_AI_OPERATION_NAME_ATTRIBUTE]: operationName,
80
82
  [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ai.google_genai',
81
83
  };
82
84
 
@@ -108,7 +110,18 @@ function extractRequestAttributes(
108
110
  * This is only recorded if recordInputs is true.
109
111
  * Handles different parameter formats for different Google GenAI methods.
110
112
  */
111
- function addPrivateRequestAttributes(span, params) {
113
+ function addPrivateRequestAttributes(span, params, isEmbeddings) {
114
+ if (isEmbeddings) {
115
+ const contents = params.contents;
116
+ if (contents != null) {
117
+ span.setAttribute(
118
+ GEN_AI_EMBEDDINGS_INPUT_ATTRIBUTE,
119
+ typeof contents === 'string' ? contents : JSON.stringify(contents),
120
+ );
121
+ }
122
+ return;
123
+ }
124
+
112
125
  const messages = [];
113
126
 
114
127
  // config.systemInstruction: ContentUnion
@@ -223,31 +236,32 @@ function addResponseAttributes(span, response, recordOutputs) {
223
236
  function instrumentMethod(
224
237
  originalMethod,
225
238
  methodPath,
239
+ instrumentedMethod,
226
240
  context,
227
241
  options,
228
242
  ) {
229
- const isSyncCreate = methodPath === CHATS_CREATE_METHOD;
243
+ const isEmbeddings = instrumentedMethod.operation === 'embeddings';
230
244
 
231
245
  return new Proxy(originalMethod, {
232
246
  apply(target, _, args) {
247
+ const operationName = instrumentedMethod.operation || 'unknown';
233
248
  const params = args[0] ;
234
- const requestAttributes = extractRequestAttributes(methodPath, params, context);
249
+ const requestAttributes = extractRequestAttributes(operationName, params, context);
235
250
  const model = requestAttributes[GEN_AI_REQUEST_MODEL_ATTRIBUTE] ?? 'unknown';
236
- const operationName = getFinalOperationName(methodPath);
237
251
 
238
252
  // Check if this is a streaming method
239
- if (isStreamingMethod(methodPath)) {
253
+ if (instrumentedMethod.streaming) {
240
254
  // Use startSpanManual for streaming methods to control span lifecycle
241
255
  return startSpanManual(
242
256
  {
243
257
  name: `${operationName} ${model}`,
244
- op: getSpanOperation(methodPath),
258
+ op: `gen_ai.${operationName}`,
245
259
  attributes: requestAttributes,
246
260
  },
247
261
  async (span) => {
248
262
  try {
249
263
  if (options.recordInputs && params) {
250
- addPrivateRequestAttributes(span, params);
264
+ addPrivateRequestAttributes(span, params, isEmbeddings);
251
265
  }
252
266
  const stream = await target.apply(context, args);
253
267
  return instrumentStream(stream, span, Boolean(options.recordOutputs)) ;
@@ -269,13 +283,13 @@ function instrumentMethod(
269
283
  // Single span for both sync and async operations
270
284
  return startSpan(
271
285
  {
272
- name: isSyncCreate ? `${operationName} ${model} create` : `${operationName} ${model}`,
273
- op: getSpanOperation(methodPath),
286
+ name: `${operationName} ${model}`,
287
+ op: `gen_ai.${operationName}`,
274
288
  attributes: requestAttributes,
275
289
  },
276
290
  (span) => {
277
291
  if (options.recordInputs && params) {
278
- addPrivateRequestAttributes(span, params);
292
+ addPrivateRequestAttributes(span, params, isEmbeddings);
279
293
  }
280
294
 
281
295
  return handleCallbackErrors(
@@ -287,8 +301,8 @@ function instrumentMethod(
287
301
  },
288
302
  () => {},
289
303
  result => {
290
- // Only add response attributes for content-producing methods, not for chats.create
291
- if (!isSyncCreate) {
304
+ // Only add response attributes for content-producing methods, not for embeddings
305
+ if (!isEmbeddings) {
292
306
  addResponseAttributes(span, result, options.recordOutputs);
293
307
  }
294
308
  },
@@ -309,21 +323,29 @@ function createDeepProxy(target, currentPath = '', options) {
309
323
  const value = Reflect.get(t, prop, receiver);
310
324
  const methodPath = buildMethodPath(currentPath, String(prop));
311
325
 
312
- if (typeof value === 'function' && shouldInstrument(methodPath)) {
313
- // Special case: chats.create is synchronous but needs both instrumentation AND result proxying
314
- if (methodPath === CHATS_CREATE_METHOD) {
315
- const instrumentedMethod = instrumentMethod(value , methodPath, t, options);
316
- return function instrumentedAndProxiedCreate(...args) {
317
- const result = instrumentedMethod(...args);
318
- // If the result is an object (like a chat instance), proxy it too
319
- if (result && typeof result === 'object') {
320
- return createDeepProxy(result, CHAT_PATH, options);
321
- }
322
- return result;
323
- };
326
+ const instrumentedMethod =
327
+ GOOGLE_GENAI_METHOD_REGISTRY[methodPath ];
328
+ if (typeof value === 'function' && instrumentedMethod) {
329
+ // If an operation is specified, we need to instrument the method itself
330
+ const wrappedMethod = instrumentedMethod.operation
331
+ ? instrumentMethod(value , methodPath, instrumentedMethod, t, options)
332
+ : value.bind(t);
333
+
334
+ if (!instrumentedMethod.proxyResultPath) {
335
+ return wrappedMethod;
324
336
  }
325
337
 
326
- return instrumentMethod(value , methodPath, t, options);
338
+ // If a proxyResultPath is specified, we need to proxy the result of the method.
339
+ // Note: This currently only properly handles synchronous methods. For async methods,
340
+ // the Promise itself would be proxied instead of the resolved value. Currently we
341
+ // don't have a case where this is needed, so I'll keep it simple for now.
342
+ return function (...args) {
343
+ const result = wrappedMethod(...args);
344
+ if (result && typeof result === 'object') {
345
+ return createDeepProxy(result , instrumentedMethod.proxyResultPath, options);
346
+ }
347
+ return result;
348
+ };
327
349
  }
328
350
 
329
351
  if (typeof value === 'function') {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../../src/tracing/google-genai/index.ts"],"sourcesContent":["import { captureException } from '../../exports';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '../../semanticAttributes';\nimport { SPAN_STATUS_ERROR } from '../../tracing';\nimport { startSpan, startSpanManual } from '../../tracing/trace';\nimport type { Span, SpanAttributeValue } from '../../types-hoist/span';\nimport { handleCallbackErrors } from '../../utils/handleCallbackErrors';\nimport {\n GEN_AI_INPUT_MESSAGES_ATTRIBUTE,\n GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE,\n GEN_AI_OPERATION_NAME_ATTRIBUTE,\n GEN_AI_REQUEST_AVAILABLE_TOOLS_ATTRIBUTE,\n GEN_AI_REQUEST_FREQUENCY_PENALTY_ATTRIBUTE,\n GEN_AI_REQUEST_MAX_TOKENS_ATTRIBUTE,\n GEN_AI_REQUEST_MODEL_ATTRIBUTE,\n GEN_AI_REQUEST_PRESENCE_PENALTY_ATTRIBUTE,\n GEN_AI_REQUEST_TEMPERATURE_ATTRIBUTE,\n GEN_AI_REQUEST_TOP_K_ATTRIBUTE,\n GEN_AI_REQUEST_TOP_P_ATTRIBUTE,\n GEN_AI_RESPONSE_MODEL_ATTRIBUTE,\n GEN_AI_RESPONSE_TEXT_ATTRIBUTE,\n GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE,\n GEN_AI_SYSTEM_ATTRIBUTE,\n GEN_AI_SYSTEM_INSTRUCTIONS_ATTRIBUTE,\n GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE,\n GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE,\n GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE,\n} from '../ai/gen-ai-attributes';\nimport { truncateGenAiMessages } from '../ai/messageTruncation';\nimport {\n buildMethodPath,\n extractSystemInstructions,\n getFinalOperationName,\n getSpanOperation,\n resolveAIRecordingOptions,\n} from '../ai/utils';\nimport { CHAT_PATH, CHATS_CREATE_METHOD, GOOGLE_GENAI_SYSTEM_NAME } from './constants';\nimport { instrumentStream } from './streaming';\nimport type {\n Candidate,\n ContentPart,\n GoogleGenAIIstrumentedMethod,\n GoogleGenAIOptions,\n GoogleGenAIResponse,\n} from './types';\nimport type { ContentListUnion, ContentUnion, Message, PartListUnion } from './utils';\nimport { contentUnionToMessages, isStreamingMethod, shouldInstrument } from './utils';\n\n/**\n * Extract model from parameters or chat context object\n * For chat instances, the model is available on the chat object as 'model' (older versions) or 'modelVersion' (newer versions)\n */\nexport function extractModel(params: Record<string, unknown>, context?: unknown): string {\n if ('model' in params && typeof params.model === 'string') {\n return params.model;\n }\n\n // Try to get model from chat context object (chat instance has model property)\n if (context && typeof context === 'object') {\n const contextObj = context as Record<string, unknown>;\n\n // Check for 'model' property (older versions, and streaming)\n if ('model' in contextObj && typeof contextObj.model === 'string') {\n return contextObj.model;\n }\n\n // Check for 'modelVersion' property (newer versions)\n if ('modelVersion' in contextObj && typeof contextObj.modelVersion === 'string') {\n return contextObj.modelVersion;\n }\n }\n\n return 'unknown';\n}\n\n/**\n * Extract generation config parameters\n */\nfunction extractConfigAttributes(config: Record<string, unknown>): Record<string, SpanAttributeValue> {\n const attributes: Record<string, SpanAttributeValue> = {};\n\n if ('temperature' in config && typeof config.temperature === 'number') {\n attributes[GEN_AI_REQUEST_TEMPERATURE_ATTRIBUTE] = config.temperature;\n }\n if ('topP' in config && typeof config.topP === 'number') {\n attributes[GEN_AI_REQUEST_TOP_P_ATTRIBUTE] = config.topP;\n }\n if ('topK' in config && typeof config.topK === 'number') {\n attributes[GEN_AI_REQUEST_TOP_K_ATTRIBUTE] = config.topK;\n }\n if ('maxOutputTokens' in config && typeof config.maxOutputTokens === 'number') {\n attributes[GEN_AI_REQUEST_MAX_TOKENS_ATTRIBUTE] = config.maxOutputTokens;\n }\n if ('frequencyPenalty' in config && typeof config.frequencyPenalty === 'number') {\n attributes[GEN_AI_REQUEST_FREQUENCY_PENALTY_ATTRIBUTE] = config.frequencyPenalty;\n }\n if ('presencePenalty' in config && typeof config.presencePenalty === 'number') {\n attributes[GEN_AI_REQUEST_PRESENCE_PENALTY_ATTRIBUTE] = config.presencePenalty;\n }\n\n return attributes;\n}\n\n/**\n * Extract request attributes from method arguments\n * Builds the base attributes for span creation including system info, model, and config\n */\nfunction extractRequestAttributes(\n methodPath: string,\n params?: Record<string, unknown>,\n context?: unknown,\n): Record<string, SpanAttributeValue> {\n const attributes: Record<string, SpanAttributeValue> = {\n [GEN_AI_SYSTEM_ATTRIBUTE]: GOOGLE_GENAI_SYSTEM_NAME,\n [GEN_AI_OPERATION_NAME_ATTRIBUTE]: getFinalOperationName(methodPath),\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ai.google_genai',\n };\n\n if (params) {\n attributes[GEN_AI_REQUEST_MODEL_ATTRIBUTE] = extractModel(params, context);\n\n // Extract generation config parameters\n if ('config' in params && typeof params.config === 'object' && params.config) {\n const config = params.config as Record<string, unknown>;\n Object.assign(attributes, extractConfigAttributes(config));\n\n // Extract available tools from config\n if ('tools' in config && Array.isArray(config.tools)) {\n const functionDeclarations = config.tools.flatMap(\n (tool: { functionDeclarations: unknown[] }) => tool.functionDeclarations,\n );\n attributes[GEN_AI_REQUEST_AVAILABLE_TOOLS_ATTRIBUTE] = JSON.stringify(functionDeclarations);\n }\n }\n } else {\n attributes[GEN_AI_REQUEST_MODEL_ATTRIBUTE] = extractModel({}, context);\n }\n\n return attributes;\n}\n\n/**\n * Add private request attributes to spans.\n * This is only recorded if recordInputs is true.\n * Handles different parameter formats for different Google GenAI methods.\n */\nfunction addPrivateRequestAttributes(span: Span, params: Record<string, unknown>): void {\n const messages: Message[] = [];\n\n // config.systemInstruction: ContentUnion\n if (\n 'config' in params &&\n params.config &&\n typeof params.config === 'object' &&\n 'systemInstruction' in params.config &&\n params.config.systemInstruction\n ) {\n messages.push(...contentUnionToMessages(params.config.systemInstruction as ContentUnion, 'system'));\n }\n\n // For chats.create: history contains the conversation history\n if ('history' in params) {\n messages.push(...contentUnionToMessages(params.history as PartListUnion, 'user'));\n }\n\n // For models.generateContent: ContentListUnion\n if ('contents' in params) {\n messages.push(...contentUnionToMessages(params.contents as ContentListUnion, 'user'));\n }\n\n // For chat.sendMessage: message can be PartListUnion\n if ('message' in params) {\n messages.push(...contentUnionToMessages(params.message as PartListUnion, 'user'));\n }\n\n if (Array.isArray(messages) && messages.length) {\n const { systemInstructions, filteredMessages } = extractSystemInstructions(messages);\n\n if (systemInstructions) {\n span.setAttribute(GEN_AI_SYSTEM_INSTRUCTIONS_ATTRIBUTE, systemInstructions);\n }\n\n const filteredLength = Array.isArray(filteredMessages) ? filteredMessages.length : 0;\n span.setAttributes({\n [GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE]: filteredLength,\n [GEN_AI_INPUT_MESSAGES_ATTRIBUTE]: JSON.stringify(truncateGenAiMessages(filteredMessages as unknown[])),\n });\n }\n}\n\n/**\n * Add response attributes from the Google GenAI response\n * @see https://github.com/googleapis/js-genai/blob/v1.19.0/src/types.ts#L2313\n */\nfunction addResponseAttributes(span: Span, response: GoogleGenAIResponse, recordOutputs?: boolean): void {\n if (!response || typeof response !== 'object') return;\n\n if (response.modelVersion) {\n span.setAttribute(GEN_AI_RESPONSE_MODEL_ATTRIBUTE, response.modelVersion);\n }\n\n // Add usage metadata if present\n if (response.usageMetadata && typeof response.usageMetadata === 'object') {\n const usage = response.usageMetadata;\n if (typeof usage.promptTokenCount === 'number') {\n span.setAttributes({\n [GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE]: usage.promptTokenCount,\n });\n }\n if (typeof usage.candidatesTokenCount === 'number') {\n span.setAttributes({\n [GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE]: usage.candidatesTokenCount,\n });\n }\n if (typeof usage.totalTokenCount === 'number') {\n span.setAttributes({\n [GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE]: usage.totalTokenCount,\n });\n }\n }\n\n // Add response text if recordOutputs is enabled\n if (recordOutputs && Array.isArray(response.candidates) && response.candidates.length > 0) {\n const responseTexts = response.candidates\n .map((candidate: Candidate) => {\n if (candidate.content?.parts && Array.isArray(candidate.content.parts)) {\n return candidate.content.parts\n .map((part: ContentPart) => (typeof part.text === 'string' ? part.text : ''))\n .filter((text: string) => text.length > 0)\n .join('');\n }\n return '';\n })\n .filter((text: string) => text.length > 0);\n\n if (responseTexts.length > 0) {\n span.setAttributes({\n [GEN_AI_RESPONSE_TEXT_ATTRIBUTE]: responseTexts.join(''),\n });\n }\n }\n\n // Add tool calls if recordOutputs is enabled\n if (recordOutputs && response.functionCalls) {\n const functionCalls = response.functionCalls;\n if (Array.isArray(functionCalls) && functionCalls.length > 0) {\n span.setAttributes({\n [GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE]: JSON.stringify(functionCalls),\n });\n }\n }\n}\n\n/**\n * Instrument any async or synchronous genai method with Sentry spans\n * Handles operations like models.generateContent and chat.sendMessage and chats.create\n * @see https://docs.sentry.io/platforms/javascript/guides/node/tracing/instrumentation/ai-agents-module/#manual-instrumentation\n */\nfunction instrumentMethod<T extends unknown[], R>(\n originalMethod: (...args: T) => R | Promise<R>,\n methodPath: GoogleGenAIIstrumentedMethod,\n context: unknown,\n options: GoogleGenAIOptions,\n): (...args: T) => R | Promise<R> {\n const isSyncCreate = methodPath === CHATS_CREATE_METHOD;\n\n return new Proxy(originalMethod, {\n apply(target, _, args: T): R | Promise<R> {\n const params = args[0] as Record<string, unknown> | undefined;\n const requestAttributes = extractRequestAttributes(methodPath, params, context);\n const model = requestAttributes[GEN_AI_REQUEST_MODEL_ATTRIBUTE] ?? 'unknown';\n const operationName = getFinalOperationName(methodPath);\n\n // Check if this is a streaming method\n if (isStreamingMethod(methodPath)) {\n // Use startSpanManual for streaming methods to control span lifecycle\n return startSpanManual(\n {\n name: `${operationName} ${model}`,\n op: getSpanOperation(methodPath),\n attributes: requestAttributes,\n },\n async (span: Span) => {\n try {\n if (options.recordInputs && params) {\n addPrivateRequestAttributes(span, params);\n }\n const stream = await target.apply(context, args);\n return instrumentStream(stream, span, Boolean(options.recordOutputs)) as R;\n } catch (error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureException(error, {\n mechanism: {\n handled: false,\n type: 'auto.ai.google_genai',\n data: { function: methodPath },\n },\n });\n span.end();\n throw error;\n }\n },\n );\n }\n // Single span for both sync and async operations\n return startSpan(\n {\n name: isSyncCreate ? `${operationName} ${model} create` : `${operationName} ${model}`,\n op: getSpanOperation(methodPath),\n attributes: requestAttributes,\n },\n (span: Span) => {\n if (options.recordInputs && params) {\n addPrivateRequestAttributes(span, params);\n }\n\n return handleCallbackErrors(\n () => target.apply(context, args),\n error => {\n captureException(error, {\n mechanism: { handled: false, type: 'auto.ai.google_genai', data: { function: methodPath } },\n });\n },\n () => {},\n result => {\n // Only add response attributes for content-producing methods, not for chats.create\n if (!isSyncCreate) {\n addResponseAttributes(span, result, options.recordOutputs);\n }\n },\n );\n },\n );\n },\n }) as (...args: T) => R | Promise<R>;\n}\n\n/**\n * Create a deep proxy for Google GenAI client instrumentation\n * Recursively instruments methods and handles special cases like chats.create\n */\nfunction createDeepProxy<T extends object>(target: T, currentPath = '', options: GoogleGenAIOptions): T {\n return new Proxy(target, {\n get: (t, prop, receiver) => {\n const value = Reflect.get(t, prop, receiver);\n const methodPath = buildMethodPath(currentPath, String(prop));\n\n if (typeof value === 'function' && shouldInstrument(methodPath)) {\n // Special case: chats.create is synchronous but needs both instrumentation AND result proxying\n if (methodPath === CHATS_CREATE_METHOD) {\n const instrumentedMethod = instrumentMethod(value as (...args: unknown[]) => unknown, methodPath, t, options);\n return function instrumentedAndProxiedCreate(...args: unknown[]): unknown {\n const result = instrumentedMethod(...args);\n // If the result is an object (like a chat instance), proxy it too\n if (result && typeof result === 'object') {\n return createDeepProxy(result, CHAT_PATH, options);\n }\n return result;\n };\n }\n\n return instrumentMethod(value as (...args: unknown[]) => Promise<unknown>, methodPath, t, options);\n }\n\n if (typeof value === 'function') {\n // Bind non-instrumented functions to preserve the original `this` context\n return value.bind(t);\n }\n\n if (value && typeof value === 'object') {\n return createDeepProxy(value, methodPath, options);\n }\n\n return value;\n },\n });\n}\n\n/**\n * Instrument a Google GenAI client with Sentry tracing\n * Can be used across Node.js, Cloudflare Workers, and Vercel Edge\n *\n * @template T - The type of the client that extends client object\n * @param client - The Google GenAI client to instrument\n * @param options - Optional configuration for recording inputs and outputs\n * @returns The instrumented client with the same type as the input\n *\n * @example\n * ```typescript\n * import { GoogleGenAI } from '@google/genai';\n * import { instrumentGoogleGenAIClient } from '@sentry/core';\n *\n * const genAI = new GoogleGenAI({ apiKey: process.env.GOOGLE_GENAI_API_KEY });\n * const instrumentedClient = instrumentGoogleGenAIClient(genAI);\n *\n * // Now both chats.create and sendMessage will be instrumented\n * const chat = instrumentedClient.chats.create({ model: 'gemini-1.5-pro' });\n * const response = await chat.sendMessage({ message: 'Hello' });\n * ```\n */\nexport function instrumentGoogleGenAIClient<T extends object>(client: T, options?: GoogleGenAIOptions): T {\n return createDeepProxy(client, '', resolveAIRecordingOptions(options));\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../../../src/tracing/google-genai/index.ts"],"sourcesContent":["/* eslint-disable max-lines */\nimport { captureException } from '../../exports';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '../../semanticAttributes';\nimport { SPAN_STATUS_ERROR } from '../../tracing';\nimport { startSpan, startSpanManual } from '../../tracing/trace';\nimport type { Span, SpanAttributeValue } from '../../types-hoist/span';\nimport { handleCallbackErrors } from '../../utils/handleCallbackErrors';\nimport {\n GEN_AI_EMBEDDINGS_INPUT_ATTRIBUTE,\n GEN_AI_INPUT_MESSAGES_ATTRIBUTE,\n GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE,\n GEN_AI_OPERATION_NAME_ATTRIBUTE,\n GEN_AI_REQUEST_AVAILABLE_TOOLS_ATTRIBUTE,\n GEN_AI_REQUEST_FREQUENCY_PENALTY_ATTRIBUTE,\n GEN_AI_REQUEST_MAX_TOKENS_ATTRIBUTE,\n GEN_AI_REQUEST_MODEL_ATTRIBUTE,\n GEN_AI_REQUEST_PRESENCE_PENALTY_ATTRIBUTE,\n GEN_AI_REQUEST_TEMPERATURE_ATTRIBUTE,\n GEN_AI_REQUEST_TOP_K_ATTRIBUTE,\n GEN_AI_REQUEST_TOP_P_ATTRIBUTE,\n GEN_AI_RESPONSE_MODEL_ATTRIBUTE,\n GEN_AI_RESPONSE_TEXT_ATTRIBUTE,\n GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE,\n GEN_AI_SYSTEM_ATTRIBUTE,\n GEN_AI_SYSTEM_INSTRUCTIONS_ATTRIBUTE,\n GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE,\n GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE,\n GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE,\n} from '../ai/gen-ai-attributes';\nimport { truncateGenAiMessages } from '../ai/messageTruncation';\nimport type { InstrumentedMethodEntry } from '../ai/utils';\nimport { buildMethodPath, extractSystemInstructions, resolveAIRecordingOptions } from '../ai/utils';\nimport { GOOGLE_GENAI_METHOD_REGISTRY, GOOGLE_GENAI_SYSTEM_NAME } from './constants';\nimport { instrumentStream } from './streaming';\nimport type { Candidate, ContentPart, GoogleGenAIOptions, GoogleGenAIResponse } from './types';\nimport type { ContentListUnion, ContentUnion, Message, PartListUnion } from './utils';\nimport { contentUnionToMessages } from './utils';\n\n/**\n * Extract model from parameters or chat context object\n * For chat instances, the model is available on the chat object as 'model' (older versions) or 'modelVersion' (newer versions)\n */\nexport function extractModel(params: Record<string, unknown>, context?: unknown): string {\n if ('model' in params && typeof params.model === 'string') {\n return params.model;\n }\n\n // Try to get model from chat context object (chat instance has model property)\n if (context && typeof context === 'object') {\n const contextObj = context as Record<string, unknown>;\n\n // Check for 'model' property (older versions, and streaming)\n if ('model' in contextObj && typeof contextObj.model === 'string') {\n return contextObj.model;\n }\n\n // Check for 'modelVersion' property (newer versions)\n if ('modelVersion' in contextObj && typeof contextObj.modelVersion === 'string') {\n return contextObj.modelVersion;\n }\n }\n\n return 'unknown';\n}\n\n/**\n * Extract generation config parameters\n */\nfunction extractConfigAttributes(config: Record<string, unknown>): Record<string, SpanAttributeValue> {\n const attributes: Record<string, SpanAttributeValue> = {};\n\n if ('temperature' in config && typeof config.temperature === 'number') {\n attributes[GEN_AI_REQUEST_TEMPERATURE_ATTRIBUTE] = config.temperature;\n }\n if ('topP' in config && typeof config.topP === 'number') {\n attributes[GEN_AI_REQUEST_TOP_P_ATTRIBUTE] = config.topP;\n }\n if ('topK' in config && typeof config.topK === 'number') {\n attributes[GEN_AI_REQUEST_TOP_K_ATTRIBUTE] = config.topK;\n }\n if ('maxOutputTokens' in config && typeof config.maxOutputTokens === 'number') {\n attributes[GEN_AI_REQUEST_MAX_TOKENS_ATTRIBUTE] = config.maxOutputTokens;\n }\n if ('frequencyPenalty' in config && typeof config.frequencyPenalty === 'number') {\n attributes[GEN_AI_REQUEST_FREQUENCY_PENALTY_ATTRIBUTE] = config.frequencyPenalty;\n }\n if ('presencePenalty' in config && typeof config.presencePenalty === 'number') {\n attributes[GEN_AI_REQUEST_PRESENCE_PENALTY_ATTRIBUTE] = config.presencePenalty;\n }\n\n return attributes;\n}\n\n/**\n * Extract request attributes from method arguments\n * Builds the base attributes for span creation including system info, model, and config\n */\nfunction extractRequestAttributes(\n operationName: string,\n params?: Record<string, unknown>,\n context?: unknown,\n): Record<string, SpanAttributeValue> {\n const attributes: Record<string, SpanAttributeValue> = {\n [GEN_AI_SYSTEM_ATTRIBUTE]: GOOGLE_GENAI_SYSTEM_NAME,\n [GEN_AI_OPERATION_NAME_ATTRIBUTE]: operationName,\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ai.google_genai',\n };\n\n if (params) {\n attributes[GEN_AI_REQUEST_MODEL_ATTRIBUTE] = extractModel(params, context);\n\n // Extract generation config parameters\n if ('config' in params && typeof params.config === 'object' && params.config) {\n const config = params.config as Record<string, unknown>;\n Object.assign(attributes, extractConfigAttributes(config));\n\n // Extract available tools from config\n if ('tools' in config && Array.isArray(config.tools)) {\n const functionDeclarations = config.tools.flatMap(\n (tool: { functionDeclarations: unknown[] }) => tool.functionDeclarations,\n );\n attributes[GEN_AI_REQUEST_AVAILABLE_TOOLS_ATTRIBUTE] = JSON.stringify(functionDeclarations);\n }\n }\n } else {\n attributes[GEN_AI_REQUEST_MODEL_ATTRIBUTE] = extractModel({}, context);\n }\n\n return attributes;\n}\n\n/**\n * Add private request attributes to spans.\n * This is only recorded if recordInputs is true.\n * Handles different parameter formats for different Google GenAI methods.\n */\nfunction addPrivateRequestAttributes(span: Span, params: Record<string, unknown>, isEmbeddings: boolean): void {\n if (isEmbeddings) {\n const contents = params.contents;\n if (contents != null) {\n span.setAttribute(\n GEN_AI_EMBEDDINGS_INPUT_ATTRIBUTE,\n typeof contents === 'string' ? contents : JSON.stringify(contents),\n );\n }\n return;\n }\n\n const messages: Message[] = [];\n\n // config.systemInstruction: ContentUnion\n if (\n 'config' in params &&\n params.config &&\n typeof params.config === 'object' &&\n 'systemInstruction' in params.config &&\n params.config.systemInstruction\n ) {\n messages.push(...contentUnionToMessages(params.config.systemInstruction as ContentUnion, 'system'));\n }\n\n // For chats.create: history contains the conversation history\n if ('history' in params) {\n messages.push(...contentUnionToMessages(params.history as PartListUnion, 'user'));\n }\n\n // For models.generateContent: ContentListUnion\n if ('contents' in params) {\n messages.push(...contentUnionToMessages(params.contents as ContentListUnion, 'user'));\n }\n\n // For chat.sendMessage: message can be PartListUnion\n if ('message' in params) {\n messages.push(...contentUnionToMessages(params.message as PartListUnion, 'user'));\n }\n\n if (Array.isArray(messages) && messages.length) {\n const { systemInstructions, filteredMessages } = extractSystemInstructions(messages);\n\n if (systemInstructions) {\n span.setAttribute(GEN_AI_SYSTEM_INSTRUCTIONS_ATTRIBUTE, systemInstructions);\n }\n\n const filteredLength = Array.isArray(filteredMessages) ? filteredMessages.length : 0;\n span.setAttributes({\n [GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE]: filteredLength,\n [GEN_AI_INPUT_MESSAGES_ATTRIBUTE]: JSON.stringify(truncateGenAiMessages(filteredMessages as unknown[])),\n });\n }\n}\n\n/**\n * Add response attributes from the Google GenAI response\n * @see https://github.com/googleapis/js-genai/blob/v1.19.0/src/types.ts#L2313\n */\nfunction addResponseAttributes(span: Span, response: GoogleGenAIResponse, recordOutputs?: boolean): void {\n if (!response || typeof response !== 'object') return;\n\n if (response.modelVersion) {\n span.setAttribute(GEN_AI_RESPONSE_MODEL_ATTRIBUTE, response.modelVersion);\n }\n\n // Add usage metadata if present\n if (response.usageMetadata && typeof response.usageMetadata === 'object') {\n const usage = response.usageMetadata;\n if (typeof usage.promptTokenCount === 'number') {\n span.setAttributes({\n [GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE]: usage.promptTokenCount,\n });\n }\n if (typeof usage.candidatesTokenCount === 'number') {\n span.setAttributes({\n [GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE]: usage.candidatesTokenCount,\n });\n }\n if (typeof usage.totalTokenCount === 'number') {\n span.setAttributes({\n [GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE]: usage.totalTokenCount,\n });\n }\n }\n\n // Add response text if recordOutputs is enabled\n if (recordOutputs && Array.isArray(response.candidates) && response.candidates.length > 0) {\n const responseTexts = response.candidates\n .map((candidate: Candidate) => {\n if (candidate.content?.parts && Array.isArray(candidate.content.parts)) {\n return candidate.content.parts\n .map((part: ContentPart) => (typeof part.text === 'string' ? part.text : ''))\n .filter((text: string) => text.length > 0)\n .join('');\n }\n return '';\n })\n .filter((text: string) => text.length > 0);\n\n if (responseTexts.length > 0) {\n span.setAttributes({\n [GEN_AI_RESPONSE_TEXT_ATTRIBUTE]: responseTexts.join(''),\n });\n }\n }\n\n // Add tool calls if recordOutputs is enabled\n if (recordOutputs && response.functionCalls) {\n const functionCalls = response.functionCalls;\n if (Array.isArray(functionCalls) && functionCalls.length > 0) {\n span.setAttributes({\n [GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE]: JSON.stringify(functionCalls),\n });\n }\n }\n}\n\n/**\n * Instrument any async or synchronous genai method with Sentry spans\n * Handles operations like models.generateContent and chat.sendMessage and chats.create\n * @see https://docs.sentry.io/platforms/javascript/guides/node/tracing/instrumentation/ai-agents-module/#manual-instrumentation\n */\nfunction instrumentMethod<T extends unknown[], R>(\n originalMethod: (...args: T) => R | Promise<R>,\n methodPath: string,\n instrumentedMethod: InstrumentedMethodEntry,\n context: unknown,\n options: GoogleGenAIOptions,\n): (...args: T) => R | Promise<R> {\n const isEmbeddings = instrumentedMethod.operation === 'embeddings';\n\n return new Proxy(originalMethod, {\n apply(target, _, args: T): R | Promise<R> {\n const operationName = instrumentedMethod.operation || 'unknown';\n const params = args[0] as Record<string, unknown> | undefined;\n const requestAttributes = extractRequestAttributes(operationName, params, context);\n const model = requestAttributes[GEN_AI_REQUEST_MODEL_ATTRIBUTE] ?? 'unknown';\n\n // Check if this is a streaming method\n if (instrumentedMethod.streaming) {\n // Use startSpanManual for streaming methods to control span lifecycle\n return startSpanManual(\n {\n name: `${operationName} ${model}`,\n op: `gen_ai.${operationName}`,\n attributes: requestAttributes,\n },\n async (span: Span) => {\n try {\n if (options.recordInputs && params) {\n addPrivateRequestAttributes(span, params, isEmbeddings);\n }\n const stream = await target.apply(context, args);\n return instrumentStream(stream, span, Boolean(options.recordOutputs)) as R;\n } catch (error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureException(error, {\n mechanism: {\n handled: false,\n type: 'auto.ai.google_genai',\n data: { function: methodPath },\n },\n });\n span.end();\n throw error;\n }\n },\n );\n }\n // Single span for both sync and async operations\n return startSpan(\n {\n name: `${operationName} ${model}`,\n op: `gen_ai.${operationName}`,\n attributes: requestAttributes,\n },\n (span: Span) => {\n if (options.recordInputs && params) {\n addPrivateRequestAttributes(span, params, isEmbeddings);\n }\n\n return handleCallbackErrors(\n () => target.apply(context, args),\n error => {\n captureException(error, {\n mechanism: { handled: false, type: 'auto.ai.google_genai', data: { function: methodPath } },\n });\n },\n () => {},\n result => {\n // Only add response attributes for content-producing methods, not for embeddings\n if (!isEmbeddings) {\n addResponseAttributes(span, result, options.recordOutputs);\n }\n },\n );\n },\n );\n },\n }) as (...args: T) => R | Promise<R>;\n}\n\n/**\n * Create a deep proxy for Google GenAI client instrumentation\n * Recursively instruments methods and handles special cases like chats.create\n */\nfunction createDeepProxy<T extends object>(target: T, currentPath = '', options: GoogleGenAIOptions): T {\n return new Proxy(target, {\n get: (t, prop, receiver) => {\n const value = Reflect.get(t, prop, receiver);\n const methodPath = buildMethodPath(currentPath, String(prop));\n\n const instrumentedMethod: InstrumentedMethodEntry | undefined =\n GOOGLE_GENAI_METHOD_REGISTRY[methodPath as keyof typeof GOOGLE_GENAI_METHOD_REGISTRY];\n if (typeof value === 'function' && instrumentedMethod) {\n // If an operation is specified, we need to instrument the method itself\n const wrappedMethod = instrumentedMethod.operation\n ? instrumentMethod(value as (...args: unknown[]) => unknown, methodPath, instrumentedMethod, t, options)\n : value.bind(t);\n\n if (!instrumentedMethod.proxyResultPath) {\n return wrappedMethod;\n }\n\n // If a proxyResultPath is specified, we need to proxy the result of the method.\n // Note: This currently only properly handles synchronous methods. For async methods,\n // the Promise itself would be proxied instead of the resolved value. Currently we\n // don't have a case where this is needed, so I'll keep it simple for now.\n return function (...args: unknown[]): unknown {\n const result = wrappedMethod(...args);\n if (result && typeof result === 'object') {\n return createDeepProxy(result as object, instrumentedMethod.proxyResultPath, options);\n }\n return result;\n };\n }\n\n if (typeof value === 'function') {\n // Bind non-instrumented functions to preserve the original `this` context\n return value.bind(t);\n }\n\n if (value && typeof value === 'object') {\n return createDeepProxy(value, methodPath, options);\n }\n\n return value;\n },\n });\n}\n\n/**\n * Instrument a Google GenAI client with Sentry tracing\n * Can be used across Node.js, Cloudflare Workers, and Vercel Edge\n *\n * @template T - The type of the client that extends client object\n * @param client - The Google GenAI client to instrument\n * @param options - Optional configuration for recording inputs and outputs\n * @returns The instrumented client with the same type as the input\n *\n * @example\n * ```typescript\n * import { GoogleGenAI } from '@google/genai';\n * import { instrumentGoogleGenAIClient } from '@sentry/core';\n *\n * const genAI = new GoogleGenAI({ apiKey: process.env.GOOGLE_GENAI_API_KEY });\n * const instrumentedClient = instrumentGoogleGenAIClient(genAI);\n *\n * // Now both chats.create and sendMessage will be instrumented\n * const chat = instrumentedClient.chats.create({ model: 'gemini-1.5-pro' });\n * const response = await chat.sendMessage({ message: 'Hello' });\n * ```\n */\nexport function instrumentGoogleGenAIClient<T extends object>(client: T, options?: GoogleGenAIOptions): T {\n return createDeepProxy(client, '', resolveAIRecordingOptions(options));\n}\n"],"names":[],"mappings":";;;;;;;;;;;;AAAA;;AAsCA;AACA;AACA;AACA;AACO,SAAS,YAAY,CAAC,MAAM,EAA2B,OAAO,EAAoB;AACzF,EAAE,IAAI,OAAA,IAAW,MAAA,IAAU,OAAO,MAAM,CAAC,KAAA,KAAU,QAAQ,EAAE;AAC7D,IAAI,OAAO,MAAM,CAAC,KAAK;AACvB,EAAE;;AAEF;AACA,EAAE,IAAI,OAAA,IAAW,OAAO,OAAA,KAAY,QAAQ,EAAE;AAC9C,IAAI,MAAM,UAAA,GAAa,OAAA;;AAEvB;AACA,IAAI,IAAI,OAAA,IAAW,UAAA,IAAc,OAAO,UAAU,CAAC,KAAA,KAAU,QAAQ,EAAE;AACvE,MAAM,OAAO,UAAU,CAAC,KAAK;AAC7B,IAAI;;AAEJ;AACA,IAAI,IAAI,cAAA,IAAkB,UAAA,IAAc,OAAO,UAAU,CAAC,YAAA,KAAiB,QAAQ,EAAE;AACrF,MAAM,OAAO,UAAU,CAAC,YAAY;AACpC,IAAI;AACJ,EAAE;;AAEF,EAAE,OAAO,SAAS;AAClB;;AAEA;AACA;AACA;AACA,SAAS,uBAAuB,CAAC,MAAM,EAA+D;AACtG,EAAE,MAAM,UAAU,GAAuC,EAAE;;AAE3D,EAAE,IAAI,aAAA,IAAiB,MAAA,IAAU,OAAO,MAAM,CAAC,WAAA,KAAgB,QAAQ,EAAE;AACzE,IAAI,UAAU,CAAC,oCAAoC,IAAI,MAAM,CAAC,WAAW;AACzE,EAAE;AACF,EAAE,IAAI,MAAA,IAAU,MAAA,IAAU,OAAO,MAAM,CAAC,IAAA,KAAS,QAAQ,EAAE;AAC3D,IAAI,UAAU,CAAC,8BAA8B,IAAI,MAAM,CAAC,IAAI;AAC5D,EAAE;AACF,EAAE,IAAI,MAAA,IAAU,MAAA,IAAU,OAAO,MAAM,CAAC,IAAA,KAAS,QAAQ,EAAE;AAC3D,IAAI,UAAU,CAAC,8BAA8B,IAAI,MAAM,CAAC,IAAI;AAC5D,EAAE;AACF,EAAE,IAAI,iBAAA,IAAqB,MAAA,IAAU,OAAO,MAAM,CAAC,eAAA,KAAoB,QAAQ,EAAE;AACjF,IAAI,UAAU,CAAC,mCAAmC,IAAI,MAAM,CAAC,eAAe;AAC5E,EAAE;AACF,EAAE,IAAI,kBAAA,IAAsB,MAAA,IAAU,OAAO,MAAM,CAAC,gBAAA,KAAqB,QAAQ,EAAE;AACnF,IAAI,UAAU,CAAC,0CAA0C,IAAI,MAAM,CAAC,gBAAgB;AACpF,EAAE;AACF,EAAE,IAAI,iBAAA,IAAqB,MAAA,IAAU,OAAO,MAAM,CAAC,eAAA,KAAoB,QAAQ,EAAE;AACjF,IAAI,UAAU,CAAC,yCAAyC,IAAI,MAAM,CAAC,eAAe;AAClF,EAAE;;AAEF,EAAE,OAAO,UAAU;AACnB;;AAEA;AACA;AACA;AACA;AACA,SAAS,wBAAwB;AACjC,EAAE,aAAa;AACf,EAAE,MAAM;AACR,EAAE,OAAO;AACT,EAAsC;AACtC,EAAE,MAAM,UAAU,GAAuC;AACzD,IAAI,CAAC,uBAAuB,GAAG,wBAAwB;AACvD,IAAI,CAAC,+BAA+B,GAAG,aAAa;AACpD,IAAI,CAAC,gCAAgC,GAAG,sBAAsB;AAC9D,GAAG;;AAEH,EAAE,IAAI,MAAM,EAAE;AACd,IAAI,UAAU,CAAC,8BAA8B,CAAA,GAAI,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC;;AAE9E;AACA,IAAI,IAAI,QAAA,IAAY,MAAA,IAAU,OAAO,MAAM,CAAC,MAAA,KAAW,QAAA,IAAY,MAAM,CAAC,MAAM,EAAE;AAClF,MAAM,MAAM,MAAA,GAAS,MAAM,CAAC,MAAA;AAC5B,MAAM,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,uBAAuB,CAAC,MAAM,CAAC,CAAC;;AAEhE;AACA,MAAM,IAAI,OAAA,IAAW,UAAU,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;AAC5D,QAAQ,MAAM,oBAAA,GAAuB,MAAM,CAAC,KAAK,CAAC,OAAO;AACzD,UAAU,CAAC,IAAI,KAA0C,IAAI,CAAC,oBAAoB;AAClF,SAAS;AACT,QAAQ,UAAU,CAAC,wCAAwC,CAAA,GAAI,IAAI,CAAC,SAAS,CAAC,oBAAoB,CAAC;AACnG,MAAM;AACN,IAAI;AACJ,EAAE,OAAO;AACT,IAAI,UAAU,CAAC,8BAA8B,CAAA,GAAI,YAAY,CAAC,EAAE,EAAE,OAAO,CAAC;AAC1E,EAAE;;AAEF,EAAE,OAAO,UAAU;AACnB;;AAEA;AACA;AACA;AACA;AACA;AACA,SAAS,2BAA2B,CAAC,IAAI,EAAQ,MAAM,EAA2B,YAAY,EAAiB;AAC/G,EAAE,IAAI,YAAY,EAAE;AACpB,IAAI,MAAM,QAAA,GAAW,MAAM,CAAC,QAAQ;AACpC,IAAI,IAAI,QAAA,IAAY,IAAI,EAAE;AAC1B,MAAM,IAAI,CAAC,YAAY;AACvB,QAAQ,iCAAiC;AACzC,QAAQ,OAAO,QAAA,KAAa,QAAA,GAAW,QAAA,GAAW,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC;AAC1E,OAAO;AACP,IAAI;AACJ,IAAI;AACJ,EAAE;;AAEF,EAAE,MAAM,QAAQ,GAAc,EAAE;;AAEhC;AACA,EAAE;AACF,IAAI,QAAA,IAAY,MAAA;AAChB,IAAI,MAAM,CAAC,MAAA;AACX,IAAI,OAAO,MAAM,CAAC,MAAA,KAAW,QAAA;AAC7B,IAAI,mBAAA,IAAuB,MAAM,CAAC,MAAA;AAClC,IAAI,MAAM,CAAC,MAAM,CAAC;AAClB,IAAI;AACJ,IAAI,QAAQ,CAAC,IAAI,CAAC,GAAG,sBAAsB,CAAC,MAAM,CAAC,MAAM,CAAC,iBAAA,GAAmC,QAAQ,CAAC,CAAC;AACvG,EAAE;;AAEF;AACA,EAAE,IAAI,SAAA,IAAa,MAAM,EAAE;AAC3B,IAAI,QAAQ,CAAC,IAAI,CAAC,GAAG,sBAAsB,CAAC,MAAM,CAAC,OAAA,GAA0B,MAAM,CAAC,CAAC;AACrF,EAAE;;AAEF;AACA,EAAE,IAAI,UAAA,IAAc,MAAM,EAAE;AAC5B,IAAI,QAAQ,CAAC,IAAI,CAAC,GAAG,sBAAsB,CAAC,MAAM,CAAC,QAAA,GAA8B,MAAM,CAAC,CAAC;AACzF,EAAE;;AAEF;AACA,EAAE,IAAI,SAAA,IAAa,MAAM,EAAE;AAC3B,IAAI,QAAQ,CAAC,IAAI,CAAC,GAAG,sBAAsB,CAAC,MAAM,CAAC,OAAA,GAA0B,MAAM,CAAC,CAAC;AACrF,EAAE;;AAEF,EAAE,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAA,IAAK,QAAQ,CAAC,MAAM,EAAE;AAClD,IAAI,MAAM,EAAE,kBAAkB,EAAE,gBAAA,KAAqB,yBAAyB,CAAC,QAAQ,CAAC;;AAExF,IAAI,IAAI,kBAAkB,EAAE;AAC5B,MAAM,IAAI,CAAC,YAAY,CAAC,oCAAoC,EAAE,kBAAkB,CAAC;AACjF,IAAI;;AAEJ,IAAI,MAAM,cAAA,GAAiB,KAAK,CAAC,OAAO,CAAC,gBAAgB,CAAA,GAAI,gBAAgB,CAAC,MAAA,GAAS,CAAC;AACxF,IAAI,IAAI,CAAC,aAAa,CAAC;AACvB,MAAM,CAAC,+CAA+C,GAAG,cAAc;AACvE,MAAM,CAAC,+BAA+B,GAAG,IAAI,CAAC,SAAS,CAAC,qBAAqB,CAAC,gBAAA,EAA8B,CAAC;AAC7G,KAAK,CAAC;AACN,EAAE;AACF;;AAEA;AACA;AACA;AACA;AACA,SAAS,qBAAqB,CAAC,IAAI,EAAQ,QAAQ,EAAuB,aAAa,EAAkB;AACzG,EAAE,IAAI,CAAC,QAAA,IAAY,OAAO,QAAA,KAAa,QAAQ,EAAE;;AAEjD,EAAE,IAAI,QAAQ,CAAC,YAAY,EAAE;AAC7B,IAAI,IAAI,CAAC,YAAY,CAAC,+BAA+B,EAAE,QAAQ,CAAC,YAAY,CAAC;AAC7E,EAAE;;AAEF;AACA,EAAE,IAAI,QAAQ,CAAC,aAAA,IAAiB,OAAO,QAAQ,CAAC,aAAA,KAAkB,QAAQ,EAAE;AAC5E,IAAI,MAAM,KAAA,GAAQ,QAAQ,CAAC,aAAa;AACxC,IAAI,IAAI,OAAO,KAAK,CAAC,gBAAA,KAAqB,QAAQ,EAAE;AACpD,MAAM,IAAI,CAAC,aAAa,CAAC;AACzB,QAAQ,CAAC,mCAAmC,GAAG,KAAK,CAAC,gBAAgB;AACrE,OAAO,CAAC;AACR,IAAI;AACJ,IAAI,IAAI,OAAO,KAAK,CAAC,oBAAA,KAAyB,QAAQ,EAAE;AACxD,MAAM,IAAI,CAAC,aAAa,CAAC;AACzB,QAAQ,CAAC,oCAAoC,GAAG,KAAK,CAAC,oBAAoB;AAC1E,OAAO,CAAC;AACR,IAAI;AACJ,IAAI,IAAI,OAAO,KAAK,CAAC,eAAA,KAAoB,QAAQ,EAAE;AACnD,MAAM,IAAI,CAAC,aAAa,CAAC;AACzB,QAAQ,CAAC,mCAAmC,GAAG,KAAK,CAAC,eAAe;AACpE,OAAO,CAAC;AACR,IAAI;AACJ,EAAE;;AAEF;AACA,EAAE,IAAI,aAAA,IAAiB,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAA,IAAK,QAAQ,CAAC,UAAU,CAAC,MAAA,GAAS,CAAC,EAAE;AAC7F,IAAI,MAAM,aAAA,GAAgB,QAAQ,CAAC;AACnC,OAAO,GAAG,CAAC,CAAC,SAAS,KAAgB;AACrC,QAAQ,IAAI,SAAS,CAAC,OAAO,EAAE,SAAS,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;AAChF,UAAU,OAAO,SAAS,CAAC,OAAO,CAAC;AACnC,aAAa,GAAG,CAAC,CAAC,IAAI,MAAmB,OAAO,IAAI,CAAC,IAAA,KAAS,WAAW,IAAI,CAAC,IAAA,GAAO,EAAE,CAAC;AACxF,aAAa,MAAM,CAAC,CAAC,IAAI,KAAa,IAAI,CAAC,MAAA,GAAS,CAAC;AACrD,aAAa,IAAI,CAAC,EAAE,CAAC;AACrB,QAAQ;AACR,QAAQ,OAAO,EAAE;AACjB,MAAM,CAAC;AACP,OAAO,MAAM,CAAC,CAAC,IAAI,KAAa,IAAI,CAAC,MAAA,GAAS,CAAC,CAAC;;AAEhD,IAAI,IAAI,aAAa,CAAC,MAAA,GAAS,CAAC,EAAE;AAClC,MAAM,IAAI,CAAC,aAAa,CAAC;AACzB,QAAQ,CAAC,8BAA8B,GAAG,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;AAChE,OAAO,CAAC;AACR,IAAI;AACJ,EAAE;;AAEF;AACA,EAAE,IAAI,aAAA,IAAiB,QAAQ,CAAC,aAAa,EAAE;AAC/C,IAAI,MAAM,aAAA,GAAgB,QAAQ,CAAC,aAAa;AAChD,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,aAAa,CAAA,IAAK,aAAa,CAAC,MAAA,GAAS,CAAC,EAAE;AAClE,MAAM,IAAI,CAAC,aAAa,CAAC;AACzB,QAAQ,CAAC,oCAAoC,GAAG,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC;AAC7E,OAAO,CAAC;AACR,IAAI;AACJ,EAAE;AACF;;AAEA;AACA;AACA;AACA;AACA;AACA,SAAS,gBAAgB;AACzB,EAAE,cAAc;AAChB,EAAE,UAAU;AACZ,EAAE,kBAAkB;AACpB,EAAE,OAAO;AACT,EAAE,OAAO;AACT,EAAkC;AAClC,EAAE,MAAM,YAAA,GAAe,kBAAkB,CAAC,SAAA,KAAc,YAAY;;AAEpE,EAAE,OAAO,IAAI,KAAK,CAAC,cAAc,EAAE;AACnC,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,IAAI,EAAqB;AAC9C,MAAM,MAAM,aAAA,GAAgB,kBAAkB,CAAC,SAAA,IAAa,SAAS;AACrE,MAAM,MAAM,MAAA,GAAS,IAAI,CAAC,CAAC,CAAA;AAC3B,MAAM,MAAM,iBAAA,GAAoB,wBAAwB,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,CAAC;AACxF,MAAM,MAAM,QAAQ,iBAAiB,CAAC,8BAA8B,CAAA,IAAK,SAAS;;AAElF;AACA,MAAM,IAAI,kBAAkB,CAAC,SAAS,EAAE;AACxC;AACA,QAAQ,OAAO,eAAe;AAC9B,UAAU;AACV,YAAY,IAAI,EAAE,CAAC,EAAA,aAAA,CAAA,CAAA,EAAA,KAAA,CAAA,CAAA;AACA,YAAA,EAAA,EAAA,CAAA,OAAA,EAAA,aAAA,CAAA,CAAA;AACA,YAAA,UAAA,EAAA,iBAAA;AACA,WAAA;AACA,UAAA,OAAA,IAAA,KAAA;AACA,YAAA,IAAA;AACA,cAAA,IAAA,OAAA,CAAA,YAAA,IAAA,MAAA,EAAA;AACA,gBAAA,2BAAA,CAAA,IAAA,EAAA,MAAA,EAAA,YAAA,CAAA;AACA,cAAA;AACA,cAAA,MAAA,MAAA,GAAA,MAAA,MAAA,CAAA,KAAA,CAAA,OAAA,EAAA,IAAA,CAAA;AACA,cAAA,OAAA,gBAAA,CAAA,MAAA,EAAA,IAAA,EAAA,OAAA,CAAA,OAAA,CAAA,aAAA,CAAA,CAAA;AACA,YAAA,CAAA,CAAA,OAAA,KAAA,EAAA;AACA,cAAA,IAAA,CAAA,SAAA,CAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,gBAAA,EAAA,CAAA;AACA,cAAA,gBAAA,CAAA,KAAA,EAAA;AACA,gBAAA,SAAA,EAAA;AACA,kBAAA,OAAA,EAAA,KAAA;AACA,kBAAA,IAAA,EAAA,sBAAA;AACA,kBAAA,IAAA,EAAA,EAAA,QAAA,EAAA,UAAA,EAAA;AACA,iBAAA;AACA,eAAA,CAAA;AACA,cAAA,IAAA,CAAA,GAAA,EAAA;AACA,cAAA,MAAA,KAAA;AACA,YAAA;AACA,UAAA,CAAA;AACA,SAAA;AACA,MAAA;AACA;AACA,MAAA,OAAA,SAAA;AACA,QAAA;AACA,UAAA,IAAA,EAAA,CAAA,EAAA,aAAA,CAAA,CAAA,EAAA,KAAA,CAAA,CAAA;AACA,UAAA,EAAA,EAAA,CAAA,OAAA,EAAA,aAAA,CAAA,CAAA;AACA,UAAA,UAAA,EAAA,iBAAA;AACA,SAAA;AACA,QAAA,CAAA,IAAA,KAAA;AACA,UAAA,IAAA,OAAA,CAAA,YAAA,IAAA,MAAA,EAAA;AACA,YAAA,2BAAA,CAAA,IAAA,EAAA,MAAA,EAAA,YAAA,CAAA;AACA,UAAA;;AAEA,UAAA,OAAA,oBAAA;AACA,YAAA,MAAA,MAAA,CAAA,KAAA,CAAA,OAAA,EAAA,IAAA,CAAA;AACA,YAAA,KAAA,IAAA;AACA,cAAA,gBAAA,CAAA,KAAA,EAAA;AACA,gBAAA,SAAA,EAAA,EAAA,OAAA,EAAA,KAAA,EAAA,IAAA,EAAA,sBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,UAAA,EAAA,EAAA;AACA,eAAA,CAAA;AACA,YAAA,CAAA;AACA,YAAA,MAAA,CAAA,CAAA;AACA,YAAA,MAAA,IAAA;AACA;AACA,cAAA,IAAA,CAAA,YAAA,EAAA;AACA,gBAAA,qBAAA,CAAA,IAAA,EAAA,MAAA,EAAA,OAAA,CAAA,aAAA,CAAA;AACA,cAAA;AACA,YAAA,CAAA;AACA,WAAA;AACA,QAAA,CAAA;AACA,OAAA;AACA,IAAA,CAAA;AACA,GAAA,CAAA;AACA;;AAEA;AACA;AACA;AACA;AACA,SAAA,eAAA,CAAA,MAAA,EAAA,WAAA,GAAA,EAAA,EAAA,OAAA,EAAA;AACA,EAAA,OAAA,IAAA,KAAA,CAAA,MAAA,EAAA;AACA,IAAA,GAAA,EAAA,CAAA,CAAA,EAAA,IAAA,EAAA,QAAA,KAAA;AACA,MAAA,MAAA,KAAA,GAAA,OAAA,CAAA,GAAA,CAAA,CAAA,EAAA,IAAA,EAAA,QAAA,CAAA;AACA,MAAA,MAAA,UAAA,GAAA,eAAA,CAAA,WAAA,EAAA,MAAA,CAAA,IAAA,CAAA,CAAA;;AAEA,MAAA,MAAA,kBAAA;AACA,QAAA,4BAAA,CAAA,UAAA,EAAA;AACA,MAAA,IAAA,OAAA,KAAA,KAAA,UAAA,IAAA,kBAAA,EAAA;AACA;AACA,QAAA,MAAA,aAAA,GAAA,kBAAA,CAAA;AACA,YAAA,gBAAA,CAAA,KAAA,GAAA,UAAA,EAAA,kBAAA,EAAA,CAAA,EAAA,OAAA;AACA,YAAA,KAAA,CAAA,IAAA,CAAA,CAAA,CAAA;;AAEA,QAAA,IAAA,CAAA,kBAAA,CAAA,eAAA,EAAA;AACA,UAAA,OAAA,aAAA;AACA,QAAA;;AAEA;AACA;AACA;AACA;AACA,QAAA,OAAA,UAAA,GAAA,IAAA,EAAA;AACA,UAAA,MAAA,MAAA,GAAA,aAAA,CAAA,GAAA,IAAA,CAAA;AACA,UAAA,IAAA,MAAA,IAAA,OAAA,MAAA,KAAA,QAAA,EAAA;AACA,YAAA,OAAA,eAAA,CAAA,MAAA,GAAA,kBAAA,CAAA,eAAA,EAAA,OAAA,CAAA;AACA,UAAA;AACA,UAAA,OAAA,MAAA;AACA,QAAA,CAAA;AACA,MAAA;;AAEA,MAAA,IAAA,OAAA,KAAA,KAAA,UAAA,EAAA;AACA;AACA,QAAA,OAAA,KAAA,CAAA,IAAA,CAAA,CAAA,CAAA;AACA,MAAA;;AAEA,MAAA,IAAA,KAAA,IAAA,OAAA,KAAA,KAAA,QAAA,EAAA;AACA,QAAA,OAAA,eAAA,CAAA,KAAA,EAAA,UAAA,EAAA,OAAA,CAAA;AACA,MAAA;;AAEA,MAAA,OAAA,KAAA;AACA,IAAA,CAAA;AACA,GAAA,CAAA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAA,2BAAA,CAAA,MAAA,EAAA,OAAA,EAAA;AACA,EAAA,OAAA,eAAA,CAAA,MAAA,EAAA,EAAA,EAAA,yBAAA,CAAA,OAAA,CAAA,CAAA;AACA;;;;"}
@@ -1,6 +1,6 @@
1
1
  import { captureException } from '../../exports.js';
2
2
  import { SPAN_STATUS_ERROR } from '../spanstatus.js';
3
- import { GEN_AI_RESPONSE_STREAMING_ATTRIBUTE, GEN_AI_RESPONSE_ID_ATTRIBUTE, GEN_AI_RESPONSE_MODEL_ATTRIBUTE, GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE, GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE, GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE, GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE, GEN_AI_RESPONSE_TEXT_ATTRIBUTE, GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE } from '../ai/gen-ai-attributes.js';
3
+ import { endStreamSpan } from '../ai/utils.js';
4
4
 
5
5
  /**
6
6
  * State object used to accumulate information from a stream of Google GenAI events.
@@ -107,28 +107,7 @@ async function* instrumentStream(
107
107
  yield chunk;
108
108
  }
109
109
  } finally {
110
- const attrs = {
111
- [GEN_AI_RESPONSE_STREAMING_ATTRIBUTE]: true,
112
- };
113
-
114
- if (state.responseId) attrs[GEN_AI_RESPONSE_ID_ATTRIBUTE] = state.responseId;
115
- if (state.responseModel) attrs[GEN_AI_RESPONSE_MODEL_ATTRIBUTE] = state.responseModel;
116
- if (state.promptTokens !== undefined) attrs[GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE] = state.promptTokens;
117
- if (state.completionTokens !== undefined) attrs[GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE] = state.completionTokens;
118
- if (state.totalTokens !== undefined) attrs[GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE] = state.totalTokens;
119
-
120
- if (state.finishReasons.length) {
121
- attrs[GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE] = JSON.stringify(state.finishReasons);
122
- }
123
- if (recordOutputs && state.responseTexts.length) {
124
- attrs[GEN_AI_RESPONSE_TEXT_ATTRIBUTE] = state.responseTexts.join('');
125
- }
126
- if (recordOutputs && state.toolCalls.length) {
127
- attrs[GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE] = JSON.stringify(state.toolCalls);
128
- }
129
-
130
- span.setAttributes(attrs);
131
- span.end();
110
+ endStreamSpan(span, state, recordOutputs);
132
111
  }
133
112
  }
134
113
 
@@ -1 +1 @@
1
- {"version":3,"file":"streaming.js","sources":["../../../../src/tracing/google-genai/streaming.ts"],"sourcesContent":["import { captureException } from '../../exports';\nimport { SPAN_STATUS_ERROR } from '../../tracing';\nimport type { Span, SpanAttributeValue } from '../../types-hoist/span';\nimport {\n GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE,\n GEN_AI_RESPONSE_ID_ATTRIBUTE,\n GEN_AI_RESPONSE_MODEL_ATTRIBUTE,\n GEN_AI_RESPONSE_STREAMING_ATTRIBUTE,\n GEN_AI_RESPONSE_TEXT_ATTRIBUTE,\n GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE,\n GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE,\n GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE,\n GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE,\n} from '../ai/gen-ai-attributes';\nimport type { GoogleGenAIResponse } from './types';\n\n/**\n * State object used to accumulate information from a stream of Google GenAI events.\n */\ninterface StreamingState {\n /** Collected response text fragments (for output recording). */\n responseTexts: string[];\n /** Reasons for finishing the response, as reported by the API. */\n finishReasons: string[];\n /** The response ID. */\n responseId?: string;\n /** The model name. */\n responseModel?: string;\n /** Number of prompt/input tokens used. */\n promptTokens?: number;\n /** Number of completion/output tokens used. */\n completionTokens?: number;\n /** Number of total tokens used. */\n totalTokens?: number;\n /** Accumulated tool calls (finalized) */\n toolCalls: Array<Record<string, unknown>>;\n}\n\n/**\n * Checks if a response chunk contains an error\n * @param chunk - The response chunk to check\n * @param span - The span to update if error is found\n * @returns Whether an error occurred\n */\nfunction isErrorChunk(chunk: GoogleGenAIResponse, span: Span): boolean {\n const feedback = chunk?.promptFeedback;\n if (feedback?.blockReason) {\n const message = feedback.blockReasonMessage ?? feedback.blockReason;\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureException(`Content blocked: ${message}`, {\n mechanism: { handled: false, type: 'auto.ai.google_genai' },\n });\n return true;\n }\n return false;\n}\n\n/**\n * Processes response metadata from a chunk\n * @param chunk - The response chunk to process\n * @param state - The state of the streaming process\n */\nfunction handleResponseMetadata(chunk: GoogleGenAIResponse, state: StreamingState): void {\n if (typeof chunk.responseId === 'string') state.responseId = chunk.responseId;\n if (typeof chunk.modelVersion === 'string') state.responseModel = chunk.modelVersion;\n\n const usage = chunk.usageMetadata;\n if (usage) {\n if (typeof usage.promptTokenCount === 'number') state.promptTokens = usage.promptTokenCount;\n if (typeof usage.candidatesTokenCount === 'number') state.completionTokens = usage.candidatesTokenCount;\n if (typeof usage.totalTokenCount === 'number') state.totalTokens = usage.totalTokenCount;\n }\n}\n\n/**\n * Processes candidate content from a response chunk\n * @param chunk - The response chunk to process\n * @param state - The state of the streaming process\n * @param recordOutputs - Whether to record outputs\n */\nfunction handleCandidateContent(chunk: GoogleGenAIResponse, state: StreamingState, recordOutputs: boolean): void {\n if (Array.isArray(chunk.functionCalls)) {\n state.toolCalls.push(...chunk.functionCalls);\n }\n\n for (const candidate of chunk.candidates ?? []) {\n if (candidate?.finishReason && !state.finishReasons.includes(candidate.finishReason)) {\n state.finishReasons.push(candidate.finishReason);\n }\n\n for (const part of candidate?.content?.parts ?? []) {\n if (recordOutputs && part.text) state.responseTexts.push(part.text);\n if (part.functionCall) {\n state.toolCalls.push({\n type: 'function',\n id: part.functionCall.id,\n name: part.functionCall.name,\n arguments: part.functionCall.args,\n });\n }\n }\n }\n}\n\n/**\n * Processes a single chunk from the Google GenAI stream\n * @param chunk - The chunk to process\n * @param state - The state of the streaming process\n * @param recordOutputs - Whether to record outputs\n * @param span - The span to update\n */\nfunction processChunk(chunk: GoogleGenAIResponse, state: StreamingState, recordOutputs: boolean, span: Span): void {\n if (!chunk || isErrorChunk(chunk, span)) return;\n handleResponseMetadata(chunk, state);\n handleCandidateContent(chunk, state, recordOutputs);\n}\n\n/**\n * Instruments an async iterable stream of Google GenAI response chunks, updates the span with\n * streaming attributes and (optionally) the aggregated output text, and yields\n * each chunk from the input stream unchanged.\n */\nexport async function* instrumentStream(\n stream: AsyncIterable<GoogleGenAIResponse>,\n span: Span,\n recordOutputs: boolean,\n): AsyncGenerator<GoogleGenAIResponse, void, unknown> {\n const state: StreamingState = {\n responseTexts: [],\n finishReasons: [],\n toolCalls: [],\n };\n\n try {\n for await (const chunk of stream) {\n processChunk(chunk, state, recordOutputs, span);\n yield chunk;\n }\n } finally {\n const attrs: Record<string, SpanAttributeValue> = {\n [GEN_AI_RESPONSE_STREAMING_ATTRIBUTE]: true,\n };\n\n if (state.responseId) attrs[GEN_AI_RESPONSE_ID_ATTRIBUTE] = state.responseId;\n if (state.responseModel) attrs[GEN_AI_RESPONSE_MODEL_ATTRIBUTE] = state.responseModel;\n if (state.promptTokens !== undefined) attrs[GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE] = state.promptTokens;\n if (state.completionTokens !== undefined) attrs[GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE] = state.completionTokens;\n if (state.totalTokens !== undefined) attrs[GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE] = state.totalTokens;\n\n if (state.finishReasons.length) {\n attrs[GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE] = JSON.stringify(state.finishReasons);\n }\n if (recordOutputs && state.responseTexts.length) {\n attrs[GEN_AI_RESPONSE_TEXT_ATTRIBUTE] = state.responseTexts.join('');\n }\n if (recordOutputs && state.toolCalls.length) {\n attrs[GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE] = JSON.stringify(state.toolCalls);\n }\n\n span.setAttributes(attrs);\n span.end();\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"streaming.js","sources":["../../../../src/tracing/google-genai/streaming.ts"],"sourcesContent":["import { captureException } from '../../exports';\nimport { SPAN_STATUS_ERROR } from '../../tracing';\nimport type { Span } from '../../types-hoist/span';\nimport { endStreamSpan } from '../ai/utils';\nimport type { GoogleGenAIResponse } from './types';\n\n/**\n * State object used to accumulate information from a stream of Google GenAI events.\n */\ninterface StreamingState {\n /** Collected response text fragments (for output recording). */\n responseTexts: string[];\n /** Reasons for finishing the response, as reported by the API. */\n finishReasons: string[];\n /** The response ID. */\n responseId?: string;\n /** The model name. */\n responseModel?: string;\n /** Number of prompt/input tokens used. */\n promptTokens?: number;\n /** Number of completion/output tokens used. */\n completionTokens?: number;\n /** Number of total tokens used. */\n totalTokens?: number;\n /** Accumulated tool calls (finalized) */\n toolCalls: Array<Record<string, unknown>>;\n}\n\n/**\n * Checks if a response chunk contains an error\n * @param chunk - The response chunk to check\n * @param span - The span to update if error is found\n * @returns Whether an error occurred\n */\nfunction isErrorChunk(chunk: GoogleGenAIResponse, span: Span): boolean {\n const feedback = chunk?.promptFeedback;\n if (feedback?.blockReason) {\n const message = feedback.blockReasonMessage ?? feedback.blockReason;\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureException(`Content blocked: ${message}`, {\n mechanism: { handled: false, type: 'auto.ai.google_genai' },\n });\n return true;\n }\n return false;\n}\n\n/**\n * Processes response metadata from a chunk\n * @param chunk - The response chunk to process\n * @param state - The state of the streaming process\n */\nfunction handleResponseMetadata(chunk: GoogleGenAIResponse, state: StreamingState): void {\n if (typeof chunk.responseId === 'string') state.responseId = chunk.responseId;\n if (typeof chunk.modelVersion === 'string') state.responseModel = chunk.modelVersion;\n\n const usage = chunk.usageMetadata;\n if (usage) {\n if (typeof usage.promptTokenCount === 'number') state.promptTokens = usage.promptTokenCount;\n if (typeof usage.candidatesTokenCount === 'number') state.completionTokens = usage.candidatesTokenCount;\n if (typeof usage.totalTokenCount === 'number') state.totalTokens = usage.totalTokenCount;\n }\n}\n\n/**\n * Processes candidate content from a response chunk\n * @param chunk - The response chunk to process\n * @param state - The state of the streaming process\n * @param recordOutputs - Whether to record outputs\n */\nfunction handleCandidateContent(chunk: GoogleGenAIResponse, state: StreamingState, recordOutputs: boolean): void {\n if (Array.isArray(chunk.functionCalls)) {\n state.toolCalls.push(...chunk.functionCalls);\n }\n\n for (const candidate of chunk.candidates ?? []) {\n if (candidate?.finishReason && !state.finishReasons.includes(candidate.finishReason)) {\n state.finishReasons.push(candidate.finishReason);\n }\n\n for (const part of candidate?.content?.parts ?? []) {\n if (recordOutputs && part.text) state.responseTexts.push(part.text);\n if (part.functionCall) {\n state.toolCalls.push({\n type: 'function',\n id: part.functionCall.id,\n name: part.functionCall.name,\n arguments: part.functionCall.args,\n });\n }\n }\n }\n}\n\n/**\n * Processes a single chunk from the Google GenAI stream\n * @param chunk - The chunk to process\n * @param state - The state of the streaming process\n * @param recordOutputs - Whether to record outputs\n * @param span - The span to update\n */\nfunction processChunk(chunk: GoogleGenAIResponse, state: StreamingState, recordOutputs: boolean, span: Span): void {\n if (!chunk || isErrorChunk(chunk, span)) return;\n handleResponseMetadata(chunk, state);\n handleCandidateContent(chunk, state, recordOutputs);\n}\n\n/**\n * Instruments an async iterable stream of Google GenAI response chunks, updates the span with\n * streaming attributes and (optionally) the aggregated output text, and yields\n * each chunk from the input stream unchanged.\n */\nexport async function* instrumentStream(\n stream: AsyncIterable<GoogleGenAIResponse>,\n span: Span,\n recordOutputs: boolean,\n): AsyncGenerator<GoogleGenAIResponse, void, unknown> {\n const state: StreamingState = {\n responseTexts: [],\n finishReasons: [],\n toolCalls: [],\n };\n\n try {\n for await (const chunk of stream) {\n processChunk(chunk, state, recordOutputs, span);\n yield chunk;\n }\n } finally {\n endStreamSpan(span, state, recordOutputs);\n }\n}\n"],"names":[],"mappings":"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"}
@@ -1,26 +1,3 @@
1
- import { GOOGLE_GENAI_INSTRUMENTED_METHODS } from './constants.js';
2
-
3
- /**
4
- * Check if a method path should be instrumented
5
- */
6
- function shouldInstrument(methodPath) {
7
- // Check for exact matches first (like 'models.generateContent')
8
- if (GOOGLE_GENAI_INSTRUMENTED_METHODS.includes(methodPath )) {
9
- return true;
10
- }
11
-
12
- // Check for method name matches (like 'sendMessage' from chat instances)
13
- const methodName = methodPath.split('.').pop();
14
- return GOOGLE_GENAI_INSTRUMENTED_METHODS.includes(methodName );
15
- }
16
-
17
- /**
18
- * Check if a method is a streaming method
19
- */
20
- function isStreamingMethod(methodPath) {
21
- return methodPath.includes('Stream');
22
- }
23
-
24
1
  // Copied from https://googleapis.github.io/js-genai/release_docs/index.html
25
2
 
26
3
  /**
@@ -43,5 +20,5 @@ function contentUnionToMessages(content, role = 'user') {
43
20
  return [{ role, content }];
44
21
  }
45
22
 
46
- export { contentUnionToMessages, isStreamingMethod, shouldInstrument };
23
+ export { contentUnionToMessages };
47
24
  //# sourceMappingURL=utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sources":["../../../../src/tracing/google-genai/utils.ts"],"sourcesContent":["import { GOOGLE_GENAI_INSTRUMENTED_METHODS } from './constants';\nimport type { GoogleGenAIIstrumentedMethod } from './types';\n\n/**\n * Check if a method path should be instrumented\n */\nexport function shouldInstrument(methodPath: string): methodPath is GoogleGenAIIstrumentedMethod {\n // Check for exact matches first (like 'models.generateContent')\n if (GOOGLE_GENAI_INSTRUMENTED_METHODS.includes(methodPath as GoogleGenAIIstrumentedMethod)) {\n return true;\n }\n\n // Check for method name matches (like 'sendMessage' from chat instances)\n const methodName = methodPath.split('.').pop();\n return GOOGLE_GENAI_INSTRUMENTED_METHODS.includes(methodName as GoogleGenAIIstrumentedMethod);\n}\n\n/**\n * Check if a method is a streaming method\n */\nexport function isStreamingMethod(methodPath: string): boolean {\n return methodPath.includes('Stream');\n}\n\n// Copied from https://googleapis.github.io/js-genai/release_docs/index.html\nexport type ContentListUnion = Content | Content[] | PartListUnion;\nexport type ContentUnion = Content | PartUnion[] | PartUnion;\nexport type Content = {\n parts?: Part[];\n role?: string;\n};\nexport type PartUnion = Part | string;\nexport type Part = Record<string, unknown> & {\n inlineData?: {\n data?: string;\n displayName?: string;\n mimeType?: string;\n };\n text?: string;\n};\nexport type PartListUnion = PartUnion[] | PartUnion;\n\n// our consistent span message shape\nexport type Message = Record<string, unknown> & {\n role: string;\n content?: PartListUnion;\n parts?: PartListUnion;\n};\n\n/**\n *\n */\nexport function contentUnionToMessages(content: ContentListUnion, role = 'user'): Message[] {\n if (typeof content === 'string') {\n return [{ role, content }];\n }\n if (Array.isArray(content)) {\n return content.flatMap(content => contentUnionToMessages(content, role));\n }\n if (typeof content !== 'object' || !content) return [];\n if ('role' in content && typeof content.role === 'string') {\n return [content as Message];\n }\n if ('parts' in content) {\n return [{ ...content, role } as Message];\n }\n return [{ role, content }];\n}\n"],"names":[],"mappings":";;AAGA;AACA;AACA;AACO,SAAS,gBAAgB,CAAC,UAAU,EAAsD;AACjG;AACA,EAAE,IAAI,iCAAiC,CAAC,QAAQ,CAAC,UAAA,EAA2C,EAAE;AAC9F,IAAI,OAAO,IAAI;AACf,EAAE;;AAEF;AACA,EAAE,MAAM,UAAA,GAAa,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE;AAChD,EAAE,OAAO,iCAAiC,CAAC,QAAQ,CAAC,YAA2C;AAC/F;;AAEA;AACA;AACA;AACO,SAAS,iBAAiB,CAAC,UAAU,EAAmB;AAC/D,EAAE,OAAO,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC;AACtC;;AAEA;;AAyBA;AACA;AACA;AACO,SAAS,sBAAsB,CAAC,OAAO,EAAoB,IAAA,GAAO,MAAM,EAAa;AAC5F,EAAE,IAAI,OAAO,OAAA,KAAY,QAAQ,EAAE;AACnC,IAAI,OAAO,CAAC,EAAE,IAAI,EAAE,OAAA,EAAS,CAAC;AAC9B,EAAE;AACF,EAAE,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE;AAC9B,IAAI,OAAO,OAAO,CAAC,OAAO,CAAC,OAAA,IAAW,sBAAsB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;AAC5E,EAAE;AACF,EAAE,IAAI,OAAO,OAAA,KAAY,QAAA,IAAY,CAAC,OAAO,EAAE,OAAO,EAAE;AACxD,EAAE,IAAI,MAAA,IAAU,OAAA,IAAW,OAAO,OAAO,CAAC,IAAA,KAAS,QAAQ,EAAE;AAC7D,IAAI,OAAO,CAAC,OAAA,EAAmB;AAC/B,EAAE;AACF,EAAE,IAAI,OAAA,IAAW,OAAO,EAAE;AAC1B,IAAI,OAAO,CAAC,EAAE,GAAG,OAAO,EAAE,IAAA,IAAkB;AAC5C,EAAE;AACF,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,OAAA,EAAS,CAAC;AAC5B;;;;"}
1
+ {"version":3,"file":"utils.js","sources":["../../../../src/tracing/google-genai/utils.ts"],"sourcesContent":["// Copied from https://googleapis.github.io/js-genai/release_docs/index.html\nexport type ContentListUnion = Content | Content[] | PartListUnion;\nexport type ContentUnion = Content | PartUnion[] | PartUnion;\nexport type Content = {\n parts?: Part[];\n role?: string;\n};\nexport type PartUnion = Part | string;\nexport type Part = Record<string, unknown> & {\n inlineData?: {\n data?: string;\n displayName?: string;\n mimeType?: string;\n };\n text?: string;\n};\nexport type PartListUnion = PartUnion[] | PartUnion;\n\n// our consistent span message shape\nexport type Message = Record<string, unknown> & {\n role: string;\n content?: PartListUnion;\n parts?: PartListUnion;\n};\n\n/**\n *\n */\nexport function contentUnionToMessages(content: ContentListUnion, role = 'user'): Message[] {\n if (typeof content === 'string') {\n return [{ role, content }];\n }\n if (Array.isArray(content)) {\n return content.flatMap(content => contentUnionToMessages(content, role));\n }\n if (typeof content !== 'object' || !content) return [];\n if ('role' in content && typeof content.role === 'string') {\n return [content as Message];\n }\n if ('parts' in content) {\n return [{ ...content, role } as Message];\n }\n return [{ role, content }];\n}\n"],"names":[],"mappings":"AAAA;;AAyBA;AACA;AACA;AACO,SAAS,sBAAsB,CAAC,OAAO,EAAoB,IAAA,GAAO,MAAM,EAAa;AAC5F,EAAE,IAAI,OAAO,OAAA,KAAY,QAAQ,EAAE;AACnC,IAAI,OAAO,CAAC,EAAE,IAAI,EAAE,OAAA,EAAS,CAAC;AAC9B,EAAE;AACF,EAAE,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE;AAC9B,IAAI,OAAO,OAAO,CAAC,OAAO,CAAC,OAAA,IAAW,sBAAsB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;AAC5E,EAAE;AACF,EAAE,IAAI,OAAO,OAAA,KAAY,QAAA,IAAY,CAAC,OAAO,EAAE,OAAO,EAAE;AACxD,EAAE,IAAI,MAAA,IAAU,OAAA,IAAW,OAAO,OAAO,CAAC,IAAA,KAAS,QAAQ,EAAE;AAC7D,IAAI,OAAO,CAAC,OAAA,EAAmB;AAC/B,EAAE;AACF,EAAE,IAAI,OAAA,IAAW,OAAO,EAAE;AAC1B,IAAI,OAAO,CAAC,EAAE,GAAG,OAAO,EAAE,IAAA,IAAkB;AAC5C,EAAE;AACF,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,OAAA,EAAS,CAAC;AAC5B;;;;"}
@@ -0,0 +1,129 @@
1
+ import { captureException } from '../../exports.js';
2
+ import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '../../semanticAttributes.js';
3
+ import { startSpan } from '../trace.js';
4
+ import { GEN_AI_EMBEDDINGS_INPUT_ATTRIBUTE, GEN_AI_EMBEDDINGS_OPERATION_ATTRIBUTE, GEN_AI_REQUEST_MODEL_ATTRIBUTE, GEN_AI_SYSTEM_ATTRIBUTE, GEN_AI_REQUEST_DIMENSIONS_ATTRIBUTE, GEN_AI_REQUEST_ENCODING_FORMAT_ATTRIBUTE, GEN_AI_OPERATION_NAME_ATTRIBUTE } from '../ai/gen-ai-attributes.js';
5
+ import { resolveAIRecordingOptions } from '../ai/utils.js';
6
+ import { LANGCHAIN_ORIGIN } from './constants.js';
7
+
8
+ /**
9
+ * Infers the AI provider system name from the embedding class instance.
10
+ */
11
+ function inferSystemFromInstance(instance) {
12
+ const name = (instance.constructor )?.name ?? '';
13
+ if (name.includes('OpenAI')) return 'openai';
14
+ if (name.includes('Google')) return 'google_genai';
15
+ if (name.includes('Mistral')) return 'mistralai';
16
+ if (name.includes('Vertex')) return 'google_vertexai';
17
+ if (name.includes('Bedrock')) return 'aws_bedrock';
18
+ if (name.includes('Ollama')) return 'ollama';
19
+ if (name.includes('Cloudflare')) return 'cloudflare';
20
+ if (name.includes('Cohere')) return 'cohere';
21
+ return 'langchain';
22
+ }
23
+
24
+ /**
25
+ * Extracts span attributes from a LangChain embedding class instance.
26
+ */
27
+ function extractEmbeddingAttributes(instance) {
28
+ const embeddingsInstance = (instance ?? {}) ;
29
+
30
+ const attributes = {
31
+ [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: LANGCHAIN_ORIGIN,
32
+ [SEMANTIC_ATTRIBUTE_SENTRY_OP]: GEN_AI_EMBEDDINGS_OPERATION_ATTRIBUTE,
33
+ [GEN_AI_OPERATION_NAME_ATTRIBUTE]: 'embeddings',
34
+ [GEN_AI_REQUEST_MODEL_ATTRIBUTE]: embeddingsInstance.model ?? 'unknown',
35
+ };
36
+
37
+ attributes[GEN_AI_SYSTEM_ATTRIBUTE] = inferSystemFromInstance(embeddingsInstance);
38
+ if ('dimensions' in embeddingsInstance) {
39
+ attributes[GEN_AI_REQUEST_DIMENSIONS_ATTRIBUTE] = embeddingsInstance.dimensions;
40
+ }
41
+ if ('encodingFormat' in embeddingsInstance) {
42
+ attributes[GEN_AI_REQUEST_ENCODING_FORMAT_ATTRIBUTE] = embeddingsInstance.encodingFormat;
43
+ }
44
+
45
+ return attributes;
46
+ }
47
+
48
+ /**
49
+ * Wraps a LangChain embedding method (embedQuery or embedDocuments) to create Sentry spans.
50
+ *
51
+ * Used internally by the Node.js auto-instrumentation to patch embedding class prototypes.
52
+ */
53
+ function instrumentEmbeddingMethod(
54
+ originalMethod,
55
+ options = {},
56
+ ) {
57
+ const { recordInputs } = resolveAIRecordingOptions(options);
58
+
59
+ return new Proxy(originalMethod, {
60
+ apply(target, thisArg, args) {
61
+ const attributes = extractEmbeddingAttributes(thisArg);
62
+ const modelName = attributes[GEN_AI_REQUEST_MODEL_ATTRIBUTE] || 'unknown';
63
+
64
+ if (recordInputs) {
65
+ const input = args[0];
66
+ if (input != null) {
67
+ attributes[GEN_AI_EMBEDDINGS_INPUT_ATTRIBUTE] = typeof input === 'string' ? input : JSON.stringify(input);
68
+ }
69
+ }
70
+
71
+ return startSpan(
72
+ {
73
+ name: `embeddings ${modelName}`,
74
+ op: GEN_AI_EMBEDDINGS_OPERATION_ATTRIBUTE,
75
+ attributes: attributes ,
76
+ },
77
+ () => {
78
+ return Reflect.apply(target, thisArg, args).then(undefined, error => {
79
+ captureException(error, {
80
+ mechanism: { handled: false, type: 'auto.ai.langchain' },
81
+ });
82
+ throw error;
83
+ });
84
+ },
85
+ );
86
+ },
87
+ }) ;
88
+ }
89
+
90
+ /**
91
+ * Wraps a LangChain embeddings instance to create Sentry spans for `embedQuery` and `embedDocuments` calls.
92
+ *
93
+ * Use this in non-Node runtimes (Cloudflare, browser, etc.) where auto-instrumentation is not available.
94
+ *
95
+ * @example
96
+ * ```javascript
97
+ * import * as Sentry from '@sentry/cloudflare';
98
+ * import { OpenAIEmbeddings } from '@langchain/openai';
99
+ *
100
+ * const embeddings = Sentry.instrumentLangChainEmbeddings(
101
+ * new OpenAIEmbeddings({ model: 'text-embedding-3-small' })
102
+ * );
103
+ *
104
+ * await embeddings.embedQuery('Hello world');
105
+ * await embeddings.embedDocuments(['doc1', 'doc2']);
106
+ * ```
107
+ */
108
+ function instrumentLangChainEmbeddings(instance, options) {
109
+ const embeddingsInstance = instance ;
110
+
111
+ if (typeof embeddingsInstance.embedQuery === 'function') {
112
+ embeddingsInstance.embedQuery = instrumentEmbeddingMethod(
113
+ embeddingsInstance.embedQuery ,
114
+ options,
115
+ );
116
+ }
117
+
118
+ if (typeof embeddingsInstance.embedDocuments === 'function') {
119
+ embeddingsInstance.embedDocuments = instrumentEmbeddingMethod(
120
+ embeddingsInstance.embedDocuments ,
121
+ options,
122
+ );
123
+ }
124
+
125
+ return instance;
126
+ }
127
+
128
+ export { instrumentEmbeddingMethod, instrumentLangChainEmbeddings };
129
+ //# sourceMappingURL=embeddings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embeddings.js","sources":["../../../../src/tracing/langchain/embeddings.ts"],"sourcesContent":["import { captureException } from '../../exports';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '../../semanticAttributes';\nimport { startSpan } from '../../tracing/trace';\nimport type { SpanAttributeValue } from '../../types-hoist/span';\nimport {\n GEN_AI_EMBEDDINGS_OPERATION_ATTRIBUTE,\n GEN_AI_EMBEDDINGS_INPUT_ATTRIBUTE,\n GEN_AI_OPERATION_NAME_ATTRIBUTE,\n GEN_AI_REQUEST_DIMENSIONS_ATTRIBUTE,\n GEN_AI_REQUEST_ENCODING_FORMAT_ATTRIBUTE,\n GEN_AI_REQUEST_MODEL_ATTRIBUTE,\n GEN_AI_SYSTEM_ATTRIBUTE,\n} from '../ai/gen-ai-attributes';\nimport { resolveAIRecordingOptions } from '../ai/utils';\nimport { LANGCHAIN_ORIGIN } from './constants';\nimport type { LangChainOptions } from './types';\n\n/**\n * Infers the AI provider system name from the embedding class instance.\n */\nfunction inferSystemFromInstance(instance: Record<string, unknown>): string {\n const name = (instance.constructor as { name?: string })?.name ?? '';\n if (name.includes('OpenAI')) return 'openai';\n if (name.includes('Google')) return 'google_genai';\n if (name.includes('Mistral')) return 'mistralai';\n if (name.includes('Vertex')) return 'google_vertexai';\n if (name.includes('Bedrock')) return 'aws_bedrock';\n if (name.includes('Ollama')) return 'ollama';\n if (name.includes('Cloudflare')) return 'cloudflare';\n if (name.includes('Cohere')) return 'cohere';\n return 'langchain';\n}\n\n/**\n * Extracts span attributes from a LangChain embedding class instance.\n */\nfunction extractEmbeddingAttributes(instance: unknown): Record<string, unknown> {\n const embeddingsInstance = (instance ?? {}) as Record<string, unknown>;\n\n const attributes: Record<string, unknown> = {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: LANGCHAIN_ORIGIN,\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: GEN_AI_EMBEDDINGS_OPERATION_ATTRIBUTE,\n [GEN_AI_OPERATION_NAME_ATTRIBUTE]: 'embeddings',\n [GEN_AI_REQUEST_MODEL_ATTRIBUTE]: embeddingsInstance.model ?? 'unknown',\n };\n\n attributes[GEN_AI_SYSTEM_ATTRIBUTE] = inferSystemFromInstance(embeddingsInstance);\n if ('dimensions' in embeddingsInstance) {\n attributes[GEN_AI_REQUEST_DIMENSIONS_ATTRIBUTE] = embeddingsInstance.dimensions;\n }\n if ('encodingFormat' in embeddingsInstance) {\n attributes[GEN_AI_REQUEST_ENCODING_FORMAT_ATTRIBUTE] = embeddingsInstance.encodingFormat;\n }\n\n return attributes;\n}\n\n/**\n * Wraps a LangChain embedding method (embedQuery or embedDocuments) to create Sentry spans.\n *\n * Used internally by the Node.js auto-instrumentation to patch embedding class prototypes.\n */\nexport function instrumentEmbeddingMethod(\n originalMethod: (...args: unknown[]) => Promise<unknown>,\n options: LangChainOptions = {},\n): (...args: unknown[]) => Promise<unknown> {\n const { recordInputs } = resolveAIRecordingOptions(options);\n\n return new Proxy(originalMethod, {\n apply(target, thisArg, args: unknown[]): Promise<unknown> {\n const attributes = extractEmbeddingAttributes(thisArg);\n const modelName = attributes[GEN_AI_REQUEST_MODEL_ATTRIBUTE] || 'unknown';\n\n if (recordInputs) {\n const input = args[0];\n if (input != null) {\n attributes[GEN_AI_EMBEDDINGS_INPUT_ATTRIBUTE] = typeof input === 'string' ? input : JSON.stringify(input);\n }\n }\n\n return startSpan(\n {\n name: `embeddings ${modelName}`,\n op: GEN_AI_EMBEDDINGS_OPERATION_ATTRIBUTE,\n attributes: attributes as Record<string, SpanAttributeValue>,\n },\n () => {\n return Reflect.apply(target, thisArg, args).then(undefined, error => {\n captureException(error, {\n mechanism: { handled: false, type: 'auto.ai.langchain' },\n });\n throw error;\n });\n },\n );\n },\n }) as (...args: unknown[]) => Promise<unknown>;\n}\n\n/**\n * Wraps a LangChain embeddings instance to create Sentry spans for `embedQuery` and `embedDocuments` calls.\n *\n * Use this in non-Node runtimes (Cloudflare, browser, etc.) where auto-instrumentation is not available.\n *\n * @example\n * ```javascript\n * import * as Sentry from '@sentry/cloudflare';\n * import { OpenAIEmbeddings } from '@langchain/openai';\n *\n * const embeddings = Sentry.instrumentLangChainEmbeddings(\n * new OpenAIEmbeddings({ model: 'text-embedding-3-small' })\n * );\n *\n * await embeddings.embedQuery('Hello world');\n * await embeddings.embedDocuments(['doc1', 'doc2']);\n * ```\n */\nexport function instrumentLangChainEmbeddings<T extends object>(instance: T, options?: LangChainOptions): T {\n const embeddingsInstance = instance as Record<string, unknown>;\n\n if (typeof embeddingsInstance.embedQuery === 'function') {\n embeddingsInstance.embedQuery = instrumentEmbeddingMethod(\n embeddingsInstance.embedQuery as (...args: unknown[]) => Promise<unknown>,\n options,\n );\n }\n\n if (typeof embeddingsInstance.embedDocuments === 'function') {\n embeddingsInstance.embedDocuments = instrumentEmbeddingMethod(\n embeddingsInstance.embedDocuments as (...args: unknown[]) => Promise<unknown>,\n options,\n );\n }\n\n return instance;\n}\n"],"names":[],"mappings":"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"}