@sentry/core 10.50.0 → 10.52.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 (347) hide show
  1. package/build/cjs/client.js +33 -5
  2. package/build/cjs/client.js.map +1 -1
  3. package/build/cjs/envelope.js +4 -1
  4. package/build/cjs/envelope.js.map +1 -1
  5. package/build/cjs/fetch.js +7 -4
  6. package/build/cjs/fetch.js.map +1 -1
  7. package/build/cjs/index.js +37 -13
  8. package/build/cjs/index.js.map +1 -1
  9. package/build/cjs/instrument/console.js +3 -1
  10. package/build/cjs/instrument/console.js.map +1 -1
  11. package/build/cjs/instrument/fetch.js +6 -2
  12. package/build/cjs/instrument/fetch.js.map +1 -1
  13. package/build/cjs/instrument/handlers.js +11 -1
  14. package/build/cjs/instrument/handlers.js.map +1 -1
  15. package/build/cjs/integrations/console.js +3 -1
  16. package/build/cjs/integrations/console.js.map +1 -1
  17. package/build/cjs/integrations/express/index.js +2 -4
  18. package/build/cjs/integrations/express/index.js.map +1 -1
  19. package/build/cjs/integrations/express/utils.js +0 -7
  20. package/build/cjs/integrations/express/utils.js.map +1 -1
  21. package/build/cjs/integrations/extraerrordata.js +2 -2
  22. package/build/cjs/integrations/extraerrordata.js.map +1 -1
  23. package/build/cjs/integrations/http/add-outgoing-request-breadcrumb.js +43 -0
  24. package/build/cjs/integrations/http/add-outgoing-request-breadcrumb.js.map +1 -0
  25. package/build/cjs/integrations/http/client-patch.js +113 -0
  26. package/build/cjs/integrations/http/client-patch.js.map +1 -0
  27. package/build/cjs/integrations/http/client-subscriptions.js +166 -0
  28. package/build/cjs/integrations/http/client-subscriptions.js.map +1 -0
  29. package/build/cjs/integrations/http/constants.js +10 -0
  30. package/build/cjs/integrations/http/constants.js.map +1 -0
  31. package/build/cjs/integrations/http/double-wrap-warning.js +29 -0
  32. package/build/cjs/integrations/http/double-wrap-warning.js.map +1 -0
  33. package/build/cjs/integrations/http/get-outgoing-span-data.js +88 -0
  34. package/build/cjs/integrations/http/get-outgoing-span-data.js.map +1 -0
  35. package/build/cjs/integrations/http/get-request-url.js +54 -0
  36. package/build/cjs/integrations/http/get-request-url.js.map +1 -0
  37. package/build/cjs/integrations/http/inject-trace-propagation-headers.js +81 -0
  38. package/build/cjs/integrations/http/inject-trace-propagation-headers.js.map +1 -0
  39. package/build/cjs/integrations/postgresjs.js +10 -1
  40. package/build/cjs/integrations/postgresjs.js.map +1 -1
  41. package/build/cjs/integrations/requestdata.js +92 -6
  42. package/build/cjs/integrations/requestdata.js.map +1 -1
  43. package/build/cjs/integrations/supabase.js +39 -12
  44. package/build/cjs/integrations/supabase.js.map +1 -1
  45. package/build/cjs/logs/console-integration.js +3 -1
  46. package/build/cjs/logs/console-integration.js.map +1 -1
  47. package/build/cjs/logs/envelope.js +12 -2
  48. package/build/cjs/logs/envelope.js.map +1 -1
  49. package/build/cjs/logs/internal.js +7 -1
  50. package/build/cjs/logs/internal.js.map +1 -1
  51. package/build/cjs/metrics/envelope.js +15 -2
  52. package/build/cjs/metrics/envelope.js.map +1 -1
  53. package/build/cjs/metrics/internal.js +7 -1
  54. package/build/cjs/metrics/internal.js.map +1 -1
  55. package/build/cjs/server-runtime-client.js +20 -2
  56. package/build/cjs/server-runtime-client.js.map +1 -1
  57. package/build/cjs/tracing/ai/gen-ai-attributes.js +6 -0
  58. package/build/cjs/tracing/ai/gen-ai-attributes.js.map +1 -1
  59. package/build/cjs/tracing/idleSpan.js +7 -1
  60. package/build/cjs/tracing/idleSpan.js.map +1 -1
  61. package/build/cjs/tracing/langchain/index.js +43 -8
  62. package/build/cjs/tracing/langchain/index.js.map +1 -1
  63. package/build/cjs/tracing/langchain/utils.js +44 -10
  64. package/build/cjs/tracing/langchain/utils.js.map +1 -1
  65. package/build/cjs/tracing/langgraph/index.js +105 -2
  66. package/build/cjs/tracing/langgraph/index.js.map +1 -1
  67. package/build/cjs/tracing/langgraph/utils.js +168 -0
  68. package/build/cjs/tracing/langgraph/utils.js.map +1 -1
  69. package/build/cjs/tracing/spans/captureSpan.js +169 -9
  70. package/build/cjs/tracing/spans/captureSpan.js.map +1 -1
  71. package/build/cjs/tracing/spans/envelope.js +13 -3
  72. package/build/cjs/tracing/spans/envelope.js.map +1 -1
  73. package/build/cjs/tracing/trace.js +2 -0
  74. package/build/cjs/tracing/trace.js.map +1 -1
  75. package/build/cjs/tracing/vercel-ai/constants.js +8 -0
  76. package/build/cjs/tracing/vercel-ai/constants.js.map +1 -1
  77. package/build/cjs/tracing/vercel-ai/index.js +93 -14
  78. package/build/cjs/tracing/vercel-ai/index.js.map +1 -1
  79. package/build/cjs/trpc.js +2 -3
  80. package/build/cjs/trpc.js.map +1 -1
  81. package/build/cjs/utils/baggage.js +73 -0
  82. package/build/cjs/utils/baggage.js.map +1 -1
  83. package/build/cjs/utils/chain-and-copy-promiselike.js +1 -0
  84. package/build/cjs/utils/chain-and-copy-promiselike.js.map +1 -1
  85. package/build/cjs/utils/get-default-export.js +32 -0
  86. package/build/cjs/utils/get-default-export.js.map +1 -0
  87. package/build/cjs/utils/isSentryRequestUrl.js +9 -1
  88. package/build/cjs/utils/isSentryRequestUrl.js.map +1 -1
  89. package/build/cjs/utils/normalizationHints.js +38 -0
  90. package/build/cjs/utils/normalizationHints.js.map +1 -0
  91. package/build/cjs/utils/normalize.js +7 -11
  92. package/build/cjs/utils/normalize.js.map +1 -1
  93. package/build/cjs/utils/object.js +1 -1
  94. package/build/cjs/utils/object.js.map +1 -1
  95. package/build/cjs/utils/request.js +192 -12
  96. package/build/cjs/utils/request.js.map +1 -1
  97. package/build/cjs/utils/should-ignore-span.js +27 -8
  98. package/build/cjs/utils/should-ignore-span.js.map +1 -1
  99. package/build/cjs/utils/spanUtils.js +1 -1
  100. package/build/cjs/utils/spanUtils.js.map +1 -1
  101. package/build/cjs/utils/version.js +1 -1
  102. package/build/esm/client.js +33 -5
  103. package/build/esm/client.js.map +1 -1
  104. package/build/esm/envelope.js +4 -1
  105. package/build/esm/envelope.js.map +1 -1
  106. package/build/esm/fetch.js +7 -4
  107. package/build/esm/fetch.js.map +1 -1
  108. package/build/esm/index.js +11 -5
  109. package/build/esm/index.js.map +1 -1
  110. package/build/esm/instrument/console.js +3 -1
  111. package/build/esm/instrument/console.js.map +1 -1
  112. package/build/esm/instrument/fetch.js +6 -2
  113. package/build/esm/instrument/fetch.js.map +1 -1
  114. package/build/esm/instrument/handlers.js +11 -1
  115. package/build/esm/instrument/handlers.js.map +1 -1
  116. package/build/esm/integrations/console.js +3 -1
  117. package/build/esm/integrations/console.js.map +1 -1
  118. package/build/esm/integrations/express/index.js +3 -5
  119. package/build/esm/integrations/express/index.js.map +1 -1
  120. package/build/esm/integrations/express/utils.js +1 -7
  121. package/build/esm/integrations/express/utils.js.map +1 -1
  122. package/build/esm/integrations/extraerrordata.js +2 -2
  123. package/build/esm/integrations/extraerrordata.js.map +1 -1
  124. package/build/esm/integrations/http/add-outgoing-request-breadcrumb.js +41 -0
  125. package/build/esm/integrations/http/add-outgoing-request-breadcrumb.js.map +1 -0
  126. package/build/esm/integrations/http/client-patch.js +111 -0
  127. package/build/esm/integrations/http/client-patch.js.map +1 -0
  128. package/build/esm/integrations/http/client-subscriptions.js +164 -0
  129. package/build/esm/integrations/http/client-subscriptions.js.map +1 -0
  130. package/build/esm/integrations/http/constants.js +6 -0
  131. package/build/esm/integrations/http/constants.js.map +1 -0
  132. package/build/esm/integrations/http/double-wrap-warning.js +26 -0
  133. package/build/esm/integrations/http/double-wrap-warning.js.map +1 -0
  134. package/build/esm/integrations/http/get-outgoing-span-data.js +85 -0
  135. package/build/esm/integrations/http/get-outgoing-span-data.js.map +1 -0
  136. package/build/esm/integrations/http/get-request-url.js +49 -0
  137. package/build/esm/integrations/http/get-request-url.js.map +1 -0
  138. package/build/esm/integrations/http/inject-trace-propagation-headers.js +79 -0
  139. package/build/esm/integrations/http/inject-trace-propagation-headers.js.map +1 -0
  140. package/build/esm/integrations/postgresjs.js +10 -1
  141. package/build/esm/integrations/postgresjs.js.map +1 -1
  142. package/build/esm/integrations/requestdata.js +92 -6
  143. package/build/esm/integrations/requestdata.js.map +1 -1
  144. package/build/esm/integrations/supabase.js +39 -12
  145. package/build/esm/integrations/supabase.js.map +1 -1
  146. package/build/esm/logs/console-integration.js +3 -1
  147. package/build/esm/logs/console-integration.js.map +1 -1
  148. package/build/esm/logs/envelope.js +12 -2
  149. package/build/esm/logs/envelope.js.map +1 -1
  150. package/build/esm/logs/internal.js +7 -1
  151. package/build/esm/logs/internal.js.map +1 -1
  152. package/build/esm/metrics/envelope.js +15 -2
  153. package/build/esm/metrics/envelope.js.map +1 -1
  154. package/build/esm/metrics/internal.js +7 -1
  155. package/build/esm/metrics/internal.js.map +1 -1
  156. package/build/esm/package.json +1 -1
  157. package/build/esm/server-runtime-client.js +20 -2
  158. package/build/esm/server-runtime-client.js.map +1 -1
  159. package/build/esm/tracing/ai/gen-ai-attributes.js +6 -1
  160. package/build/esm/tracing/ai/gen-ai-attributes.js.map +1 -1
  161. package/build/esm/tracing/idleSpan.js +7 -1
  162. package/build/esm/tracing/idleSpan.js.map +1 -1
  163. package/build/esm/tracing/langchain/index.js +45 -10
  164. package/build/esm/tracing/langchain/index.js.map +1 -1
  165. package/build/esm/tracing/langchain/utils.js +44 -12
  166. package/build/esm/tracing/langchain/utils.js.map +1 -1
  167. package/build/esm/tracing/langgraph/index.js +107 -5
  168. package/build/esm/tracing/langgraph/index.js.map +1 -1
  169. package/build/esm/tracing/langgraph/utils.js +166 -2
  170. package/build/esm/tracing/langgraph/utils.js.map +1 -1
  171. package/build/esm/tracing/spans/captureSpan.js +170 -11
  172. package/build/esm/tracing/spans/captureSpan.js.map +1 -1
  173. package/build/esm/tracing/spans/envelope.js +13 -3
  174. package/build/esm/tracing/spans/envelope.js.map +1 -1
  175. package/build/esm/tracing/trace.js +2 -1
  176. package/build/esm/tracing/trace.js.map +1 -1
  177. package/build/esm/tracing/vercel-ai/constants.js +8 -1
  178. package/build/esm/tracing/vercel-ai/constants.js.map +1 -1
  179. package/build/esm/tracing/vercel-ai/index.js +95 -17
  180. package/build/esm/tracing/vercel-ai/index.js.map +1 -1
  181. package/build/esm/trpc.js +2 -3
  182. package/build/esm/trpc.js.map +1 -1
  183. package/build/esm/utils/baggage.js +73 -1
  184. package/build/esm/utils/baggage.js.map +1 -1
  185. package/build/esm/utils/chain-and-copy-promiselike.js +1 -0
  186. package/build/esm/utils/chain-and-copy-promiselike.js.map +1 -1
  187. package/build/esm/utils/get-default-export.js +30 -0
  188. package/build/esm/utils/get-default-export.js.map +1 -0
  189. package/build/esm/utils/isSentryRequestUrl.js +9 -1
  190. package/build/esm/utils/isSentryRequestUrl.js.map +1 -1
  191. package/build/esm/utils/normalizationHints.js +33 -0
  192. package/build/esm/utils/normalizationHints.js.map +1 -0
  193. package/build/esm/utils/normalize.js +7 -11
  194. package/build/esm/utils/normalize.js.map +1 -1
  195. package/build/esm/utils/object.js +1 -1
  196. package/build/esm/utils/object.js.map +1 -1
  197. package/build/esm/utils/request.js +190 -13
  198. package/build/esm/utils/request.js.map +1 -1
  199. package/build/esm/utils/should-ignore-span.js +27 -8
  200. package/build/esm/utils/should-ignore-span.js.map +1 -1
  201. package/build/esm/utils/spanUtils.js +1 -1
  202. package/build/esm/utils/spanUtils.js.map +1 -1
  203. package/build/esm/utils/version.js +1 -1
  204. package/build/types/client.d.ts +12 -1
  205. package/build/types/client.d.ts.map +1 -1
  206. package/build/types/envelope.d.ts.map +1 -1
  207. package/build/types/fetch.d.ts.map +1 -1
  208. package/build/types/index.d.ts +17 -6
  209. package/build/types/index.d.ts.map +1 -1
  210. package/build/types/instrument/console.d.ts +2 -1
  211. package/build/types/instrument/console.d.ts.map +1 -1
  212. package/build/types/instrument/fetch.d.ts +4 -2
  213. package/build/types/instrument/fetch.d.ts.map +1 -1
  214. package/build/types/instrument/handlers.d.ts +2 -2
  215. package/build/types/instrument/handlers.d.ts.map +1 -1
  216. package/build/types/integrations/console.d.ts.map +1 -1
  217. package/build/types/integrations/express/index.d.ts.map +1 -1
  218. package/build/types/integrations/express/utils.d.ts +1 -5
  219. package/build/types/integrations/express/utils.d.ts.map +1 -1
  220. package/build/types/integrations/http/add-outgoing-request-breadcrumb.d.ts +6 -0
  221. package/build/types/integrations/http/add-outgoing-request-breadcrumb.d.ts.map +1 -0
  222. package/build/types/integrations/http/client-patch.d.ts +46 -0
  223. package/build/types/integrations/http/client-patch.d.ts.map +1 -0
  224. package/build/types/integrations/http/client-subscriptions.d.ts +21 -0
  225. package/build/types/integrations/http/client-subscriptions.d.ts.map +1 -0
  226. package/build/types/integrations/http/constants.d.ts +6 -0
  227. package/build/types/integrations/http/constants.d.ts.map +1 -0
  228. package/build/types/integrations/http/double-wrap-warning.d.ts +4 -0
  229. package/build/types/integrations/http/double-wrap-warning.d.ts.map +1 -0
  230. package/build/types/integrations/http/get-outgoing-span-data.d.ts +13 -0
  231. package/build/types/integrations/http/get-outgoing-span-data.d.ts.map +1 -0
  232. package/build/types/integrations/http/get-request-url.d.ts +10 -0
  233. package/build/types/integrations/http/get-request-url.d.ts.map +1 -0
  234. package/build/types/integrations/http/index.d.ts +4 -0
  235. package/build/types/integrations/http/index.d.ts.map +1 -0
  236. package/build/types/integrations/http/inject-trace-propagation-headers.d.ts +12 -0
  237. package/build/types/integrations/http/inject-trace-propagation-headers.d.ts.map +1 -0
  238. package/build/types/integrations/http/types.d.ts +249 -0
  239. package/build/types/integrations/http/types.d.ts.map +1 -0
  240. package/build/types/integrations/postgresjs.d.ts.map +1 -1
  241. package/build/types/integrations/requestdata.d.ts.map +1 -1
  242. package/build/types/integrations/supabase.d.ts.map +1 -1
  243. package/build/types/logs/console-integration.d.ts.map +1 -1
  244. package/build/types/logs/envelope.d.ts +5 -2
  245. package/build/types/logs/envelope.d.ts.map +1 -1
  246. package/build/types/logs/internal.d.ts.map +1 -1
  247. package/build/types/metrics/envelope.d.ts +5 -2
  248. package/build/types/metrics/envelope.d.ts.map +1 -1
  249. package/build/types/metrics/internal.d.ts.map +1 -1
  250. package/build/types/server-runtime-client.d.ts +5 -0
  251. package/build/types/server-runtime-client.d.ts.map +1 -1
  252. package/build/types/tracing/idleSpan.d.ts.map +1 -1
  253. package/build/types/tracing/index.d.ts +1 -1
  254. package/build/types/tracing/index.d.ts.map +1 -1
  255. package/build/types/tracing/langchain/index.d.ts.map +1 -1
  256. package/build/types/tracing/langchain/types.d.ts +8 -0
  257. package/build/types/tracing/langchain/types.d.ts.map +1 -1
  258. package/build/types/tracing/langchain/utils.d.ts +2 -0
  259. package/build/types/tracing/langchain/utils.d.ts.map +1 -1
  260. package/build/types/tracing/langgraph/index.d.ts +4 -0
  261. package/build/types/tracing/langgraph/index.d.ts.map +1 -1
  262. package/build/types/tracing/langgraph/utils.d.ts +18 -2
  263. package/build/types/tracing/langgraph/utils.d.ts.map +1 -1
  264. package/build/types/tracing/spans/captureSpan.d.ts +13 -3
  265. package/build/types/tracing/spans/captureSpan.d.ts.map +1 -1
  266. package/build/types/tracing/spans/envelope.d.ts.map +1 -1
  267. package/build/types/tracing/trace.d.ts +1 -0
  268. package/build/types/tracing/trace.d.ts.map +1 -1
  269. package/build/types/tracing/vercel-ai/constants.d.ts +1 -0
  270. package/build/types/tracing/vercel-ai/constants.d.ts.map +1 -1
  271. package/build/types/tracing/vercel-ai/index.d.ts +9 -0
  272. package/build/types/tracing/vercel-ai/index.d.ts.map +1 -1
  273. package/build/types/trpc.d.ts.map +1 -1
  274. package/build/types/types-hoist/feedback/config.d.ts +20 -0
  275. package/build/types/types-hoist/feedback/config.d.ts.map +1 -1
  276. package/build/types/types-hoist/feedback/index.d.ts +2 -2
  277. package/build/types/types-hoist/feedback/index.d.ts.map +1 -1
  278. package/build/types/types-hoist/feedback/sendFeedback.d.ts +3 -0
  279. package/build/types/types-hoist/feedback/sendFeedback.d.ts.map +1 -1
  280. package/build/types/types-hoist/log.d.ts +5 -0
  281. package/build/types/types-hoist/log.d.ts.map +1 -1
  282. package/build/types/types-hoist/metric.d.ts +5 -0
  283. package/build/types/types-hoist/metric.d.ts.map +1 -1
  284. package/build/types/types-hoist/options.d.ts +37 -2
  285. package/build/types/types-hoist/options.d.ts.map +1 -1
  286. package/build/types/types-hoist/span.d.ts +5 -0
  287. package/build/types/types-hoist/span.d.ts.map +1 -1
  288. package/build/types/types-hoist/webfetchapi.d.ts +2 -0
  289. package/build/types/types-hoist/webfetchapi.d.ts.map +1 -1
  290. package/build/types/utils/baggage.d.ts +13 -0
  291. package/build/types/utils/baggage.d.ts.map +1 -1
  292. package/build/types/utils/get-default-export.d.ts +22 -0
  293. package/build/types/utils/get-default-export.d.ts.map +1 -0
  294. package/build/types/utils/normalizationHints.d.ts +9 -0
  295. package/build/types/utils/normalizationHints.d.ts.map +1 -0
  296. package/build/types/utils/normalize.d.ts.map +1 -1
  297. package/build/types/utils/object.d.ts +1 -1
  298. package/build/types/utils/object.d.ts.map +1 -1
  299. package/build/types/utils/request.d.ts +30 -0
  300. package/build/types/utils/request.d.ts.map +1 -1
  301. package/build/types/utils/should-ignore-span.d.ts +3 -1
  302. package/build/types/utils/should-ignore-span.d.ts.map +1 -1
  303. package/build/types/utils/spanUtils.d.ts +1 -1
  304. package/build/types-ts3.8/client.d.ts +12 -1
  305. package/build/types-ts3.8/index.d.ts +17 -6
  306. package/build/types-ts3.8/instrument/console.d.ts +2 -1
  307. package/build/types-ts3.8/instrument/fetch.d.ts +4 -2
  308. package/build/types-ts3.8/instrument/handlers.d.ts +2 -2
  309. package/build/types-ts3.8/integrations/express/utils.d.ts +1 -5
  310. package/build/types-ts3.8/integrations/http/add-outgoing-request-breadcrumb.d.ts +6 -0
  311. package/build/types-ts3.8/integrations/http/client-patch.d.ts +46 -0
  312. package/build/types-ts3.8/integrations/http/client-subscriptions.d.ts +21 -0
  313. package/build/types-ts3.8/integrations/http/constants.d.ts +6 -0
  314. package/build/types-ts3.8/integrations/http/double-wrap-warning.d.ts +4 -0
  315. package/build/types-ts3.8/integrations/http/get-outgoing-span-data.d.ts +13 -0
  316. package/build/types-ts3.8/integrations/http/get-request-url.d.ts +10 -0
  317. package/build/types-ts3.8/integrations/http/index.d.ts +4 -0
  318. package/build/types-ts3.8/integrations/http/inject-trace-propagation-headers.d.ts +12 -0
  319. package/build/types-ts3.8/integrations/http/types.d.ts +252 -0
  320. package/build/types-ts3.8/logs/envelope.d.ts +5 -2
  321. package/build/types-ts3.8/metrics/envelope.d.ts +5 -2
  322. package/build/types-ts3.8/server-runtime-client.d.ts +5 -0
  323. package/build/types-ts3.8/tracing/index.d.ts +1 -1
  324. package/build/types-ts3.8/tracing/langchain/types.d.ts +8 -0
  325. package/build/types-ts3.8/tracing/langchain/utils.d.ts +2 -0
  326. package/build/types-ts3.8/tracing/langgraph/index.d.ts +4 -0
  327. package/build/types-ts3.8/tracing/langgraph/utils.d.ts +18 -2
  328. package/build/types-ts3.8/tracing/spans/captureSpan.d.ts +13 -3
  329. package/build/types-ts3.8/tracing/trace.d.ts +1 -0
  330. package/build/types-ts3.8/tracing/vercel-ai/constants.d.ts +1 -0
  331. package/build/types-ts3.8/tracing/vercel-ai/index.d.ts +9 -0
  332. package/build/types-ts3.8/types-hoist/feedback/config.d.ts +20 -0
  333. package/build/types-ts3.8/types-hoist/feedback/index.d.ts +2 -2
  334. package/build/types-ts3.8/types-hoist/feedback/sendFeedback.d.ts +3 -0
  335. package/build/types-ts3.8/types-hoist/log.d.ts +5 -0
  336. package/build/types-ts3.8/types-hoist/metric.d.ts +5 -0
  337. package/build/types-ts3.8/types-hoist/options.d.ts +37 -2
  338. package/build/types-ts3.8/types-hoist/span.d.ts +5 -0
  339. package/build/types-ts3.8/types-hoist/webfetchapi.d.ts +2 -0
  340. package/build/types-ts3.8/utils/baggage.d.ts +13 -0
  341. package/build/types-ts3.8/utils/get-default-export.d.ts +22 -0
  342. package/build/types-ts3.8/utils/normalizationHints.d.ts +9 -0
  343. package/build/types-ts3.8/utils/object.d.ts +1 -1
  344. package/build/types-ts3.8/utils/request.d.ts +30 -0
  345. package/build/types-ts3.8/utils/should-ignore-span.d.ts +3 -1
  346. package/build/types-ts3.8/utils/spanUtils.d.ts +1 -1
  347. package/package.json +1 -1
@@ -3,6 +3,13 @@
3
3
  // without keeping full Span objects (and their potentially large attributes) alive.
4
4
  const toolCallSpanContextMap = new Map();
5
5
 
6
+ // Used to make tool descriptions available to execute_tool spans in the span streaming path.
7
+ // Streamed spans are processed individually, so execute_tool spans cannot look up descriptions
8
+ // from their sibling doGenerate span on span end (as we do for transactions).
9
+ // Instead we store descriptions at spanStart and apply them in the processSpan hook.
10
+ // Stores parent_span_id -> Map<toolName, description>
11
+ const toolDescriptionMap = new Map();
12
+
6
13
  /** Maps Vercel AI span names to standardized OpenTelemetry operation names. */
7
14
  const SPAN_TO_OPERATION_NAME = new Map([
8
15
  ['ai.generateText', 'invoke_agent'],
@@ -19,5 +26,5 @@ const SPAN_TO_OPERATION_NAME = new Map([
19
26
  ['ai.toolCall', 'execute_tool'],
20
27
  ]);
21
28
 
22
- export { SPAN_TO_OPERATION_NAME, toolCallSpanContextMap };
29
+ export { SPAN_TO_OPERATION_NAME, toolCallSpanContextMap, toolDescriptionMap };
23
30
  //# sourceMappingURL=constants.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sources":["../../../../src/tracing/vercel-ai/constants.ts"],"sourcesContent":["import type { ToolCallSpanContext } from './types';\n\n// Global map to track tool call IDs to their corresponding span contexts.\n// This allows us to capture tool errors and link them to the correct span\n// without keeping full Span objects (and their potentially large attributes) alive.\nexport const toolCallSpanContextMap = new Map<string, ToolCallSpanContext>();\n\n/** Maps Vercel AI span names to standardized OpenTelemetry operation names. */\nexport const SPAN_TO_OPERATION_NAME = new Map<string, string>([\n ['ai.generateText', 'invoke_agent'],\n ['ai.streamText', 'invoke_agent'],\n ['ai.generateObject', 'invoke_agent'],\n ['ai.streamObject', 'invoke_agent'],\n ['ai.generateText.doGenerate', 'generate_content'],\n ['ai.streamText.doStream', 'generate_content'],\n ['ai.generateObject.doGenerate', 'generate_content'],\n ['ai.streamObject.doStream', 'generate_content'],\n ['ai.embed.doEmbed', 'embeddings'],\n ['ai.embedMany.doEmbed', 'embeddings'],\n ['ai.rerank.doRerank', 'rerank'],\n ['ai.toolCall', 'execute_tool'],\n]);\n"],"names":[],"mappings":"AAEA;AACA;AACA;MACa,sBAAA,GAAyB,IAAI,GAAG;;AAE7C;AACO,MAAM,sBAAA,GAAyB,IAAI,GAAG,CAAiB;AAC9D,EAAE,CAAC,iBAAiB,EAAE,cAAc,CAAC;AACrC,EAAE,CAAC,eAAe,EAAE,cAAc,CAAC;AACnC,EAAE,CAAC,mBAAmB,EAAE,cAAc,CAAC;AACvC,EAAE,CAAC,iBAAiB,EAAE,cAAc,CAAC;AACrC,EAAE,CAAC,4BAA4B,EAAE,kBAAkB,CAAC;AACpD,EAAE,CAAC,wBAAwB,EAAE,kBAAkB,CAAC;AAChD,EAAE,CAAC,8BAA8B,EAAE,kBAAkB,CAAC;AACtD,EAAE,CAAC,0BAA0B,EAAE,kBAAkB,CAAC;AAClD,EAAE,CAAC,kBAAkB,EAAE,YAAY,CAAC;AACpC,EAAE,CAAC,sBAAsB,EAAE,YAAY,CAAC;AACxC,EAAE,CAAC,oBAAoB,EAAE,QAAQ,CAAC;AAClC,EAAE,CAAC,aAAa,EAAE,cAAc,CAAC;AACjC,CAAC;;;;"}
1
+ {"version":3,"file":"constants.js","sources":["../../../../src/tracing/vercel-ai/constants.ts"],"sourcesContent":["import type { ToolCallSpanContext } from './types';\n\n// Global map to track tool call IDs to their corresponding span contexts.\n// This allows us to capture tool errors and link them to the correct span\n// without keeping full Span objects (and their potentially large attributes) alive.\nexport const toolCallSpanContextMap = new Map<string, ToolCallSpanContext>();\n\n// Used to make tool descriptions available to execute_tool spans in the span streaming path.\n// Streamed spans are processed individually, so execute_tool spans cannot look up descriptions\n// from their sibling doGenerate span on span end (as we do for transactions).\n// Instead we store descriptions at spanStart and apply them in the processSpan hook.\n// Stores parent_span_id -> Map<toolName, description>\nexport const toolDescriptionMap = new Map<string, Map<string, string>>();\n\n/** Maps Vercel AI span names to standardized OpenTelemetry operation names. */\nexport const SPAN_TO_OPERATION_NAME = new Map<string, string>([\n ['ai.generateText', 'invoke_agent'],\n ['ai.streamText', 'invoke_agent'],\n ['ai.generateObject', 'invoke_agent'],\n ['ai.streamObject', 'invoke_agent'],\n ['ai.generateText.doGenerate', 'generate_content'],\n ['ai.streamText.doStream', 'generate_content'],\n ['ai.generateObject.doGenerate', 'generate_content'],\n ['ai.streamObject.doStream', 'generate_content'],\n ['ai.embed.doEmbed', 'embeddings'],\n ['ai.embedMany.doEmbed', 'embeddings'],\n ['ai.rerank.doRerank', 'rerank'],\n ['ai.toolCall', 'execute_tool'],\n]);\n"],"names":[],"mappings":"AAEA;AACA;AACA;MACa,sBAAA,GAAyB,IAAI,GAAG;;AAE7C;AACA;AACA;AACA;AACA;MACa,kBAAA,GAAqB,IAAI,GAAG;;AAEzC;AACO,MAAM,sBAAA,GAAyB,IAAI,GAAG,CAAiB;AAC9D,EAAE,CAAC,iBAAiB,EAAE,cAAc,CAAC;AACrC,EAAE,CAAC,eAAe,EAAE,cAAc,CAAC;AACnC,EAAE,CAAC,mBAAmB,EAAE,cAAc,CAAC;AACvC,EAAE,CAAC,iBAAiB,EAAE,cAAc,CAAC;AACrC,EAAE,CAAC,4BAA4B,EAAE,kBAAkB,CAAC;AACpD,EAAE,CAAC,wBAAwB,EAAE,kBAAkB,CAAC;AAChD,EAAE,CAAC,8BAA8B,EAAE,kBAAkB,CAAC;AACtD,EAAE,CAAC,0BAA0B,EAAE,kBAAkB,CAAC;AAClD,EAAE,CAAC,kBAAkB,EAAE,YAAY,CAAC;AACpC,EAAE,CAAC,sBAAsB,EAAE,YAAY,CAAC;AACxC,EAAE,CAAC,oBAAoB,EAAE,QAAQ,CAAC;AAClC,EAAE,CAAC,aAAa,EAAE,cAAc,CAAC;AACjC,CAAC;;;;"}
@@ -2,8 +2,9 @@ import { getClient } from '../../currentScopes.js';
2
2
  import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_OP } from '../../semanticAttributes.js';
3
3
  import { shouldEnableTruncation } from '../ai/utils.js';
4
4
  import { spanToJSON } from '../../utils/spanUtils.js';
5
- import { GEN_AI_OPERATION_NAME_ATTRIBUTE, GEN_AI_TOOL_CALL_ID_ATTRIBUTE, GEN_AI_TOOL_TYPE_ATTRIBUTE, GEN_AI_TOOL_NAME_ATTRIBUTE, GEN_AI_RESPONSE_MODEL_ATTRIBUTE, GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE, GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE, GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE, GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE, GEN_AI_EMBEDDINGS_INPUT_ATTRIBUTE, GEN_AI_OUTPUT_MESSAGES_ATTRIBUTE, GEN_AI_USAGE_INPUT_TOKENS_CACHE_WRITE_ATTRIBUTE, GEN_AI_INPUT_MESSAGES_ATTRIBUTE, GEN_AI_TOOL_INPUT_ATTRIBUTE, GEN_AI_TOOL_OUTPUT_ATTRIBUTE, GEN_AI_REQUEST_MODEL_ATTRIBUTE } from '../ai/gen-ai-attributes.js';
6
- import { toolCallSpanContextMap, SPAN_TO_OPERATION_NAME } from './constants.js';
5
+ import { GEN_AI_TOOL_NAME_ATTRIBUTE, GEN_AI_TOOL_DESCRIPTION_ATTRIBUTE, GEN_AI_OPERATION_NAME_ATTRIBUTE, GEN_AI_TOOL_CALL_ID_ATTRIBUTE, GEN_AI_TOOL_TYPE_ATTRIBUTE, GEN_AI_RESPONSE_MODEL_ATTRIBUTE, GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE, GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE, GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE, GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE, GEN_AI_EMBEDDINGS_INPUT_ATTRIBUTE, GEN_AI_OUTPUT_MESSAGES_ATTRIBUTE, GEN_AI_USAGE_INPUT_TOKENS_CACHE_WRITE_ATTRIBUTE, GEN_AI_INPUT_MESSAGES_ATTRIBUTE, GEN_AI_TOOL_INPUT_ATTRIBUTE, GEN_AI_TOOL_OUTPUT_ATTRIBUTE, GEN_AI_REQUEST_MODEL_ATTRIBUTE } from '../ai/gen-ai-attributes.js';
6
+ import { toolDescriptionMap, toolCallSpanContextMap, SPAN_TO_OPERATION_NAME } from './constants.js';
7
+ import { hasSpanStreamingEnabled } from '../spans/hasSpanStreamingEnabled.js';
7
8
  import { accumulateTokensForParent, applyToolDescriptionsAndTokens, applyAccumulatedTokens, requestMessagesFromPrompt, convertAvailableToolsToJsonString } from './utils.js';
8
9
  import { AI_TOOL_CALL_NAME_ATTRIBUTE, AI_TOOL_CALL_ID_ATTRIBUTE, AI_OPERATION_ID_ATTRIBUTE, AI_TELEMETRY_FUNCTION_ID_ATTRIBUTE, AI_MODEL_ID_ATTRIBUTE, AI_PROMPT_TOOLS_ATTRIBUTE, OPERATION_NAME_ATTRIBUTE, AI_VALUES_ATTRIBUTE, AI_RESPONSE_TEXT_ATTRIBUTE, AI_RESPONSE_TOOL_CALLS_ATTRIBUTE, AI_RESPONSE_FINISH_REASON_ATTRIBUTE, AI_RESPONSE_PROVIDER_METADATA_ATTRIBUTE, AI_USAGE_COMPLETION_TOKENS_ATTRIBUTE, AI_USAGE_PROMPT_TOKENS_ATTRIBUTE, AI_USAGE_CACHED_INPUT_TOKENS_ATTRIBUTE, AI_USAGE_TOKENS_ATTRIBUTE, AI_PROMPT_MESSAGES_ATTRIBUTE, AI_RESPONSE_OBJECT_ATTRIBUTE, AI_TOOL_CALL_ARGS_ATTRIBUTE, AI_TOOL_CALL_RESULT_ATTRIBUTE, AI_SCHEMA_ATTRIBUTE } from './vercel-ai-attributes.js';
9
10
 
@@ -176,19 +177,12 @@ function buildOutputMessages(attributes) {
176
177
  /**
177
178
  * Post-process spans emitted by the Vercel AI SDK.
178
179
  */
179
- function processEndedVercelAiSpan(span) {
180
- const { data: attributes, origin } = span;
181
-
182
- if (origin !== 'auto.vercelai.otel') {
183
- return;
184
- }
185
-
186
- // The Vercel AI SDK sets span status to raw error message strings.
187
- // Any such value should be normalized to a SpanStatusType value. We pick internal_error as it is the most generic.
188
- if (span.status && span.status !== 'ok') {
189
- span.status = 'internal_error';
190
- }
191
-
180
+ /**
181
+ * Rename and normalize Vercel AI SDK attributes to OpenTelemetry semantic conventions.
182
+ * This is the shared attribute processing logic used by both the legacy event processor
183
+ * path (SpanJSON) and the streamed span path (StreamedSpanJSON).
184
+ */
185
+ function processVercelAiSpanAttributes(attributes) {
192
186
  renameAttributeKey(attributes, AI_USAGE_COMPLETION_TOKENS_ATTRIBUTE, GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE);
193
187
  renameAttributeKey(attributes, AI_USAGE_PROMPT_TOKENS_ATTRIBUTE, GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE);
194
188
  renameAttributeKey(attributes, AI_USAGE_CACHED_INPUT_TOKENS_ATTRIBUTE, GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE);
@@ -281,6 +275,49 @@ function processEndedVercelAiSpan(span) {
281
275
  }
282
276
  }
283
277
 
278
+ function processEndedVercelAiSpan(span) {
279
+ const { data: attributes, origin } = span;
280
+
281
+ if (origin !== 'auto.vercelai.otel') {
282
+ return;
283
+ }
284
+
285
+ // The Vercel AI SDK sets span status to raw error message strings.
286
+ // Any such value should be normalized to a SpanStatusType value. We pick internal_error as it is the most generic.
287
+ if (span.status && span.status !== 'ok') {
288
+ span.status = 'internal_error';
289
+ }
290
+
291
+ processVercelAiSpanAttributes(attributes);
292
+ }
293
+
294
+ function processVercelAiStreamedSpan(span) {
295
+ const attributes = span.attributes;
296
+ if (attributes?.[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN] !== 'auto.vercelai.otel') {
297
+ return;
298
+ }
299
+
300
+ processVercelAiSpanAttributes(attributes);
301
+
302
+ // Look up tool description from the toolDescriptionMap for execute_tool spans
303
+ if (attributes[SEMANTIC_ATTRIBUTE_SENTRY_OP] === 'gen_ai.execute_tool' && span.parent_span_id) {
304
+ const descriptions = toolDescriptionMap.get(span.parent_span_id);
305
+
306
+ if (descriptions) {
307
+ const toolName = attributes[GEN_AI_TOOL_NAME_ATTRIBUTE];
308
+ if (typeof toolName === 'string') {
309
+ const desc = descriptions.get(toolName);
310
+ if (desc) {
311
+ attributes[GEN_AI_TOOL_DESCRIPTION_ATTRIBUTE] = desc;
312
+ }
313
+ }
314
+ }
315
+ }
316
+
317
+ // Clean up tool descriptions when the parent span ends
318
+ toolDescriptionMap.delete(span.span_id);
319
+ }
320
+
284
321
  /**
285
322
  * Renames an attribute key in the provided attributes object if the old key exists.
286
323
  * This function safely handles null and undefined values.
@@ -361,6 +398,40 @@ function processGenerateSpan(span, name, attributes, enableTruncation) {
361
398
  if (modelId && operationName) {
362
399
  span.updateName(`${operationName} ${modelId}`);
363
400
  }
401
+
402
+ // Store tool descriptions in the toolDescriptionMap so processSpan can apply them to execute_tool spans.
403
+ // This is only needed for span streaming (transaction path handles this separately)
404
+ const client = getClient();
405
+ if (
406
+ client &&
407
+ hasSpanStreamingEnabled(client) &&
408
+ attributes[AI_PROMPT_TOOLS_ATTRIBUTE] &&
409
+ Array.isArray(attributes[AI_PROMPT_TOOLS_ATTRIBUTE])
410
+ ) {
411
+ const descriptions = new Map();
412
+
413
+ // parse tool names and descriptions from tool string array
414
+ for (const toolStr of attributes[AI_PROMPT_TOOLS_ATTRIBUTE] ) {
415
+ try {
416
+ const parsed = (typeof toolStr === 'string' ? JSON.parse(toolStr) : toolStr)
417
+
418
+ ;
419
+ if (parsed?.name && parsed?.description) {
420
+ descriptions.set(parsed.name, parsed.description);
421
+ }
422
+ } catch {
423
+ // ignore parse errors
424
+ }
425
+ }
426
+ if (descriptions.size > 0) {
427
+ // Tool call spans are siblings of doGenerate (both children of invoke_agent),
428
+ // so we key by the parent span ID (the invoke_agent span).
429
+ const parentSpanId = spanToJSON(span).parent_span_id;
430
+ if (parentSpanId) {
431
+ toolDescriptionMap.set(parentSpanId, descriptions);
432
+ }
433
+ }
434
+ }
364
435
  }
365
436
 
366
437
  /**
@@ -370,6 +441,9 @@ function addVercelAiProcessors(client) {
370
441
  client.on('spanStart', onVercelAiSpanStart);
371
442
  // Note: We cannot do this on `spanEnd`, because the span cannot be mutated anymore at this point
372
443
  client.addEventProcessor(Object.assign(vercelAiEventProcessor, { id: 'VercelAiEventProcessor' }));
444
+ client.on('processSpan', span => {
445
+ processVercelAiStreamedSpan(span);
446
+ });
373
447
  }
374
448
 
375
449
  function addProviderMetadataToAttributes(attributes) {
@@ -449,11 +523,15 @@ function addProviderMetadataToAttributes(attributes) {
449
523
  /**
450
524
  * Sets an attribute only if the value is not null or undefined.
451
525
  */
452
- function setAttributeIfDefined(attributes, key, value) {
526
+ function setAttributeIfDefined(
527
+ attributes,
528
+ key,
529
+ value,
530
+ ) {
453
531
  if (value != null) {
454
532
  attributes[key] = value;
455
533
  }
456
534
  }
457
535
 
458
- export { addVercelAiProcessors };
536
+ export { addVercelAiProcessors, processVercelAiSpanAttributes };
459
537
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../../src/tracing/vercel-ai/index.ts"],"sourcesContent":["/* eslint-disable max-lines */\nimport type { Client } from '../../client';\nimport { getClient } from '../../currentScopes';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '../../semanticAttributes';\nimport { shouldEnableTruncation } from '../ai/utils';\nimport type { Event } from '../../types-hoist/event';\nimport type { Span, SpanAttributes, SpanAttributeValue, SpanJSON } from '../../types-hoist/span';\nimport { spanToJSON } from '../../utils/spanUtils';\nimport {\n GEN_AI_EMBEDDINGS_INPUT_ATTRIBUTE,\n GEN_AI_INPUT_MESSAGES_ATTRIBUTE,\n GEN_AI_OPERATION_NAME_ATTRIBUTE,\n GEN_AI_OUTPUT_MESSAGES_ATTRIBUTE,\n GEN_AI_REQUEST_MODEL_ATTRIBUTE,\n GEN_AI_RESPONSE_MODEL_ATTRIBUTE,\n GEN_AI_TOOL_CALL_ID_ATTRIBUTE,\n GEN_AI_TOOL_INPUT_ATTRIBUTE,\n GEN_AI_TOOL_NAME_ATTRIBUTE,\n GEN_AI_TOOL_OUTPUT_ATTRIBUTE,\n GEN_AI_TOOL_TYPE_ATTRIBUTE,\n GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE,\n GEN_AI_USAGE_INPUT_TOKENS_CACHE_WRITE_ATTRIBUTE,\n GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE,\n GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE,\n GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE,\n} from '../ai/gen-ai-attributes';\nimport { SPAN_TO_OPERATION_NAME, toolCallSpanContextMap } from './constants';\nimport type { TokenSummary } from './types';\nimport {\n accumulateTokensForParent,\n applyAccumulatedTokens,\n applyToolDescriptionsAndTokens,\n convertAvailableToolsToJsonString,\n requestMessagesFromPrompt,\n} from './utils';\nimport type { OpenAiProviderMetadata, ProviderMetadata } from './vercel-ai-attributes';\nimport {\n AI_MODEL_ID_ATTRIBUTE,\n AI_OPERATION_ID_ATTRIBUTE,\n AI_PROMPT_MESSAGES_ATTRIBUTE,\n AI_PROMPT_TOOLS_ATTRIBUTE,\n AI_RESPONSE_FINISH_REASON_ATTRIBUTE,\n AI_RESPONSE_OBJECT_ATTRIBUTE,\n AI_RESPONSE_PROVIDER_METADATA_ATTRIBUTE,\n AI_RESPONSE_TEXT_ATTRIBUTE,\n AI_RESPONSE_TOOL_CALLS_ATTRIBUTE,\n AI_SCHEMA_ATTRIBUTE,\n AI_TELEMETRY_FUNCTION_ID_ATTRIBUTE,\n AI_TOOL_CALL_ARGS_ATTRIBUTE,\n AI_TOOL_CALL_ID_ATTRIBUTE,\n AI_TOOL_CALL_NAME_ATTRIBUTE,\n AI_TOOL_CALL_RESULT_ATTRIBUTE,\n AI_USAGE_CACHED_INPUT_TOKENS_ATTRIBUTE,\n AI_USAGE_COMPLETION_TOKENS_ATTRIBUTE,\n AI_USAGE_PROMPT_TOKENS_ATTRIBUTE,\n AI_USAGE_TOKENS_ATTRIBUTE,\n AI_VALUES_ATTRIBUTE,\n OPERATION_NAME_ATTRIBUTE,\n} from './vercel-ai-attributes';\n\n/**\n * Post-process spans emitted by the Vercel AI SDK.\n * This is supposed to be used in `client.on('spanStart', ...)\n */\nfunction onVercelAiSpanStart(span: Span): void {\n const { data: attributes, description: name } = spanToJSON(span);\n\n if (!name) {\n return;\n }\n\n // Tool call spans\n // https://ai-sdk.dev/docs/ai-sdk-core/telemetry#tool-call-spans\n if (attributes[AI_TOOL_CALL_NAME_ATTRIBUTE] && attributes[AI_TOOL_CALL_ID_ATTRIBUTE] && name === 'ai.toolCall') {\n processToolCallSpan(span, attributes);\n return;\n }\n\n // V6+ Check if this is a Vercel AI span by checking if the operation ID attribute is present.\n // V5+ Check if this is a Vercel AI span by name pattern.\n if (!attributes[AI_OPERATION_ID_ATTRIBUTE] && !name.startsWith('ai.')) {\n return;\n }\n\n const client = getClient();\n const integration = client?.getIntegrationByName('VercelAI') as\n | { options?: { enableTruncation?: boolean } }\n | undefined;\n const enableTruncation = shouldEnableTruncation(integration?.options?.enableTruncation);\n\n processGenerateSpan(span, name, attributes, enableTruncation);\n}\n\nfunction vercelAiEventProcessor(event: Event): Event {\n if (event.type === 'transaction' && event.spans) {\n // Map to accumulate token data by parent span ID\n const tokenAccumulator: Map<string, TokenSummary> = new Map();\n\n // First pass: process all spans and accumulate token data\n for (const span of event.spans) {\n processEndedVercelAiSpan(span);\n\n // Accumulate token data for parent spans\n accumulateTokensForParent(span, tokenAccumulator);\n }\n\n // Second pass: apply tool descriptions and accumulated tokens\n applyToolDescriptionsAndTokens(event.spans, tokenAccumulator);\n\n // Also apply to root when it is the invoke_agent pipeline\n const trace = event.contexts?.trace;\n if (trace?.op === 'gen_ai.invoke_agent') {\n applyAccumulatedTokens(trace, tokenAccumulator);\n }\n }\n\n return event;\n}\n\n/**\n * Tool call structure from Vercel AI SDK\n * Note: V5/V6 use 'input' for arguments, V4 and earlier use 'args'\n */\ninterface VercelToolCall {\n toolCallId: string;\n toolName: string;\n input?: Record<string, unknown> | string; // V5/V6\n args?: string; // V4 and earlier\n}\n\n/**\n * Normalize finish reason to match OpenTelemetry semantic conventions.\n * Valid values: \"stop\", \"length\", \"content_filter\", \"tool_call\", \"error\"\n *\n * Vercel AI SDK uses \"tool-calls\" (plural, with hyphen) which we map to \"tool_call\".\n */\nfunction normalizeFinishReason(finishReason: unknown): string {\n if (typeof finishReason !== 'string') {\n return 'stop';\n }\n\n // Map Vercel AI SDK finish reasons to OpenTelemetry semantic convention values\n switch (finishReason) {\n case 'tool-calls':\n return 'tool_call';\n case 'stop':\n case 'length':\n case 'content_filter':\n case 'error':\n return finishReason;\n default:\n // For unknown values, return as-is (schema allows arbitrary strings)\n return finishReason;\n }\n}\n\n/**\n * Build gen_ai.output.messages from ai.response.text and/or ai.response.toolCalls\n *\n * Format follows OpenTelemetry semantic conventions:\n * [{\"role\": \"assistant\", \"parts\": [...], \"finish_reason\": \"stop\"}]\n *\n * Parts can be:\n * - {\"type\": \"text\", \"content\": \"...\"}\n * - {\"type\": \"tool_call\", \"id\": \"...\", \"name\": \"...\", \"arguments\": \"...\"}\n */\nfunction buildOutputMessages(attributes: Record<string, unknown>): void {\n const responseText = attributes[AI_RESPONSE_TEXT_ATTRIBUTE];\n const responseToolCalls = attributes[AI_RESPONSE_TOOL_CALLS_ATTRIBUTE];\n const finishReason = attributes[AI_RESPONSE_FINISH_REASON_ATTRIBUTE];\n\n // Skip if neither text nor tool calls are present\n if (responseText == null && responseToolCalls == null) {\n return;\n }\n\n const parts: Array<Record<string, unknown>> = [];\n\n // Add text part if present\n if (typeof responseText === 'string' && responseText.length > 0) {\n parts.push({\n type: 'text',\n content: responseText,\n });\n }\n\n // Add tool call parts if present\n if (responseToolCalls != null) {\n try {\n // Tool calls can be a string (JSON) or already parsed array\n const toolCalls: VercelToolCall[] =\n typeof responseToolCalls === 'string' ? JSON.parse(responseToolCalls) : responseToolCalls;\n\n if (Array.isArray(toolCalls)) {\n for (const toolCall of toolCalls) {\n // V5/V6 use 'input', V4 and earlier use 'args'\n const args = toolCall.input ?? toolCall.args;\n parts.push({\n type: 'tool_call',\n id: toolCall.toolCallId,\n name: toolCall.toolName,\n // Handle undefined args: JSON.stringify(undefined) returns undefined, not a string,\n // which would cause the property to be omitted from the final JSON output\n arguments: typeof args === 'string' ? args : JSON.stringify(args ?? {}),\n });\n }\n // Only delete tool calls attribute if we successfully processed them\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete attributes[AI_RESPONSE_TOOL_CALLS_ATTRIBUTE];\n }\n } catch {\n // Ignore parsing errors - tool calls attribute is preserved\n }\n }\n\n // Only set output messages and delete text attribute if we have parts\n if (parts.length > 0) {\n const outputMessage = {\n role: 'assistant',\n parts,\n finish_reason: normalizeFinishReason(finishReason),\n };\n\n attributes[GEN_AI_OUTPUT_MESSAGES_ATTRIBUTE] = JSON.stringify([outputMessage]);\n\n // Remove the text attribute since it's now captured in gen_ai.output.messages\n // Note: tool calls attribute is deleted above only if successfully parsed\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete attributes[AI_RESPONSE_TEXT_ATTRIBUTE];\n }\n}\n\n/**\n * Post-process spans emitted by the Vercel AI SDK.\n */\nfunction processEndedVercelAiSpan(span: SpanJSON): void {\n const { data: attributes, origin } = span;\n\n if (origin !== 'auto.vercelai.otel') {\n return;\n }\n\n // The Vercel AI SDK sets span status to raw error message strings.\n // Any such value should be normalized to a SpanStatusType value. We pick internal_error as it is the most generic.\n if (span.status && span.status !== 'ok') {\n span.status = 'internal_error';\n }\n\n renameAttributeKey(attributes, AI_USAGE_COMPLETION_TOKENS_ATTRIBUTE, GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE);\n renameAttributeKey(attributes, AI_USAGE_PROMPT_TOKENS_ATTRIBUTE, GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE);\n renameAttributeKey(attributes, AI_USAGE_CACHED_INPUT_TOKENS_ATTRIBUTE, GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE);\n\n // Parent spans (ai.streamText, ai.streamObject, etc.) use inputTokens/outputTokens instead of promptTokens/completionTokens\n renameAttributeKey(attributes, 'ai.usage.inputTokens', GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE);\n renameAttributeKey(attributes, 'ai.usage.outputTokens', GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE);\n\n // Embedding spans use ai.usage.tokens instead of promptTokens/completionTokens\n renameAttributeKey(attributes, AI_USAGE_TOKENS_ATTRIBUTE, GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE);\n\n // AI SDK uses avgOutputTokensPerSecond, map to our expected attribute name\n renameAttributeKey(attributes, 'ai.response.avgOutputTokensPerSecond', 'ai.response.avgCompletionTokensPerSecond');\n\n // Input tokens is the sum of prompt tokens and cached input tokens\n if (\n typeof attributes[GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE] === 'number' &&\n typeof attributes[GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE] === 'number'\n ) {\n attributes[GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE] =\n attributes[GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE] + attributes[GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE];\n }\n\n // Compute total tokens from input + output (embeddings may only have input tokens)\n if (typeof attributes[GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE] === 'number') {\n const outputTokens =\n typeof attributes[GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE] === 'number'\n ? attributes[GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE]\n : 0;\n attributes[GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE] = outputTokens + attributes[GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE];\n }\n\n // Convert the available tools array to a JSON string\n if (attributes[AI_PROMPT_TOOLS_ATTRIBUTE] && Array.isArray(attributes[AI_PROMPT_TOOLS_ATTRIBUTE])) {\n attributes[AI_PROMPT_TOOLS_ATTRIBUTE] = convertAvailableToolsToJsonString(\n attributes[AI_PROMPT_TOOLS_ATTRIBUTE] as unknown[],\n );\n }\n\n // Rename AI SDK attributes to standardized gen_ai attributes\n // Map operation.name to OpenTelemetry semantic convention values\n if (attributes[OPERATION_NAME_ATTRIBUTE]) {\n // V6+ sets ai.operationId to the bare operation (e.g. \"ai.streamText\") while\n // operation.name appends functionId (e.g. \"ai.streamText myAgent\").\n // When ai.operationId is present, use it for correct mapping.\n const rawOperationName = attributes[AI_OPERATION_ID_ATTRIBUTE]\n ? (attributes[AI_OPERATION_ID_ATTRIBUTE] as string)\n : (attributes[OPERATION_NAME_ATTRIBUTE] as string);\n const operationName = SPAN_TO_OPERATION_NAME.get(rawOperationName) ?? rawOperationName;\n attributes[GEN_AI_OPERATION_NAME_ATTRIBUTE] = operationName;\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete attributes[OPERATION_NAME_ATTRIBUTE];\n }\n renameAttributeKey(attributes, AI_PROMPT_MESSAGES_ATTRIBUTE, GEN_AI_INPUT_MESSAGES_ATTRIBUTE);\n\n // Build gen_ai.output.messages from response text and/or tool calls\n // Note: buildOutputMessages also removes the source attributes when output is successfully generated\n buildOutputMessages(attributes);\n\n renameAttributeKey(attributes, AI_RESPONSE_OBJECT_ATTRIBUTE, 'gen_ai.response.object');\n renameAttributeKey(attributes, AI_PROMPT_TOOLS_ATTRIBUTE, 'gen_ai.request.available_tools');\n\n renameAttributeKey(attributes, AI_TOOL_CALL_ARGS_ATTRIBUTE, GEN_AI_TOOL_INPUT_ATTRIBUTE);\n renameAttributeKey(attributes, AI_TOOL_CALL_RESULT_ATTRIBUTE, GEN_AI_TOOL_OUTPUT_ATTRIBUTE);\n\n renameAttributeKey(attributes, AI_SCHEMA_ATTRIBUTE, 'gen_ai.request.schema');\n renameAttributeKey(attributes, AI_MODEL_ID_ATTRIBUTE, GEN_AI_REQUEST_MODEL_ATTRIBUTE);\n\n // Map embedding input: ai.values → gen_ai.embeddings.input\n // Vercel AI SDK JSON-stringifies each value individually, so we parse each element back.\n // Single embed gets unwrapped to a plain value; batch embedMany stays as a JSON array.\n if (Array.isArray(attributes[AI_VALUES_ATTRIBUTE])) {\n const parsed = (attributes[AI_VALUES_ATTRIBUTE] as string[]).map(v => {\n try {\n return JSON.parse(v);\n } catch {\n return v;\n }\n });\n attributes[GEN_AI_EMBEDDINGS_INPUT_ATTRIBUTE] = parsed.length === 1 ? parsed[0] : JSON.stringify(parsed);\n }\n\n addProviderMetadataToAttributes(attributes);\n\n // Change attributes namespaced with `ai.X` to `vercel.ai.X`\n for (const key of Object.keys(attributes)) {\n if (key.startsWith('ai.')) {\n renameAttributeKey(attributes, key, `vercel.${key}`);\n }\n }\n}\n\n/**\n * Renames an attribute key in the provided attributes object if the old key exists.\n * This function safely handles null and undefined values.\n */\nfunction renameAttributeKey(attributes: Record<string, unknown>, oldKey: string, newKey: string): void {\n if (attributes[oldKey] != null) {\n attributes[newKey] = attributes[oldKey];\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete attributes[oldKey];\n }\n}\n\nfunction processToolCallSpan(span: Span, attributes: SpanAttributes): void {\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.vercelai.otel');\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, 'gen_ai.execute_tool');\n span.setAttribute(GEN_AI_OPERATION_NAME_ATTRIBUTE, 'execute_tool');\n renameAttributeKey(attributes, AI_TOOL_CALL_NAME_ATTRIBUTE, GEN_AI_TOOL_NAME_ATTRIBUTE);\n renameAttributeKey(attributes, AI_TOOL_CALL_ID_ATTRIBUTE, GEN_AI_TOOL_CALL_ID_ATTRIBUTE);\n\n // Store the span context in our global map using the tool call ID.\n // This allows us to capture tool errors and link them to the correct span\n // without retaining the full Span object in memory.\n const toolCallId = attributes[GEN_AI_TOOL_CALL_ID_ATTRIBUTE];\n\n if (typeof toolCallId === 'string') {\n toolCallSpanContextMap.set(toolCallId, span.spanContext());\n }\n\n // https://opentelemetry.io/docs/specs/semconv/registry/attributes/gen-ai/#gen-ai-tool-type\n if (!attributes[GEN_AI_TOOL_TYPE_ATTRIBUTE]) {\n span.setAttribute(GEN_AI_TOOL_TYPE_ATTRIBUTE, 'function');\n }\n const toolName = attributes[GEN_AI_TOOL_NAME_ATTRIBUTE];\n if (toolName) {\n span.updateName(`execute_tool ${toolName}`);\n }\n}\n\nfunction processGenerateSpan(span: Span, name: string, attributes: SpanAttributes, enableTruncation: boolean): void {\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.vercelai.otel');\n\n const nameWthoutAi = name.replace('ai.', '');\n span.setAttribute('ai.pipeline.name', nameWthoutAi);\n span.updateName(nameWthoutAi);\n\n const functionId = attributes[AI_TELEMETRY_FUNCTION_ID_ATTRIBUTE];\n if (functionId && typeof functionId === 'string') {\n span.setAttribute('gen_ai.function_id', functionId);\n }\n\n requestMessagesFromPrompt(span, attributes, enableTruncation);\n\n if (attributes[AI_MODEL_ID_ATTRIBUTE] && !attributes[GEN_AI_RESPONSE_MODEL_ATTRIBUTE]) {\n span.setAttribute(GEN_AI_RESPONSE_MODEL_ATTRIBUTE, attributes[AI_MODEL_ID_ATTRIBUTE]);\n }\n span.setAttribute('ai.streaming', name.includes('stream'));\n\n // Set the op based on the operation name registry\n const operationName = SPAN_TO_OPERATION_NAME.get(name);\n if (operationName) {\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, `gen_ai.${operationName}`);\n } else if (name.startsWith('ai.stream')) {\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, 'ai.run');\n }\n\n // For invoke_agent pipeline spans, use 'invoke_agent' as the description\n // to be consistent with other AI integrations (e.g. LangGraph)\n if (operationName === 'invoke_agent') {\n if (functionId && typeof functionId === 'string') {\n span.updateName(`invoke_agent ${functionId}`);\n } else {\n span.updateName('invoke_agent');\n }\n return;\n }\n\n const modelId = attributes[AI_MODEL_ID_ATTRIBUTE];\n if (modelId && operationName) {\n span.updateName(`${operationName} ${modelId}`);\n }\n}\n\n/**\n * Add event processors to the given client to process Vercel AI spans.\n */\nexport function addVercelAiProcessors(client: Client): void {\n client.on('spanStart', onVercelAiSpanStart);\n // Note: We cannot do this on `spanEnd`, because the span cannot be mutated anymore at this point\n client.addEventProcessor(Object.assign(vercelAiEventProcessor, { id: 'VercelAiEventProcessor' }));\n}\n\nfunction addProviderMetadataToAttributes(attributes: SpanAttributes): void {\n const providerMetadata = attributes[AI_RESPONSE_PROVIDER_METADATA_ATTRIBUTE] as string | undefined;\n if (providerMetadata) {\n try {\n const providerMetadataObject = JSON.parse(providerMetadata) as ProviderMetadata;\n\n // Handle OpenAI metadata (v5 uses 'openai', v6 Azure Responses API uses 'azure')\n const openaiMetadata: OpenAiProviderMetadata | undefined =\n providerMetadataObject.openai ?? providerMetadataObject.azure;\n if (openaiMetadata) {\n setAttributeIfDefined(\n attributes,\n GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE,\n openaiMetadata.cachedPromptTokens,\n );\n setAttributeIfDefined(attributes, 'gen_ai.usage.output_tokens.reasoning', openaiMetadata.reasoningTokens);\n setAttributeIfDefined(\n attributes,\n 'gen_ai.usage.output_tokens.prediction_accepted',\n openaiMetadata.acceptedPredictionTokens,\n );\n setAttributeIfDefined(\n attributes,\n 'gen_ai.usage.output_tokens.prediction_rejected',\n openaiMetadata.rejectedPredictionTokens,\n );\n if (!attributes['gen_ai.conversation.id']) {\n setAttributeIfDefined(attributes, 'gen_ai.conversation.id', openaiMetadata.responseId);\n }\n }\n\n if (providerMetadataObject.anthropic) {\n const cachedInputTokens =\n providerMetadataObject.anthropic.usage?.cache_read_input_tokens ??\n providerMetadataObject.anthropic.cacheReadInputTokens;\n setAttributeIfDefined(attributes, GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE, cachedInputTokens);\n\n const cacheWriteInputTokens =\n providerMetadataObject.anthropic.usage?.cache_creation_input_tokens ??\n providerMetadataObject.anthropic.cacheCreationInputTokens;\n setAttributeIfDefined(attributes, GEN_AI_USAGE_INPUT_TOKENS_CACHE_WRITE_ATTRIBUTE, cacheWriteInputTokens);\n }\n\n if (providerMetadataObject.bedrock?.usage) {\n setAttributeIfDefined(\n attributes,\n GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE,\n providerMetadataObject.bedrock.usage.cacheReadInputTokens,\n );\n setAttributeIfDefined(\n attributes,\n GEN_AI_USAGE_INPUT_TOKENS_CACHE_WRITE_ATTRIBUTE,\n providerMetadataObject.bedrock.usage.cacheWriteInputTokens,\n );\n }\n\n if (providerMetadataObject.deepseek) {\n setAttributeIfDefined(\n attributes,\n GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE,\n providerMetadataObject.deepseek.promptCacheHitTokens,\n );\n setAttributeIfDefined(\n attributes,\n 'gen_ai.usage.input_tokens.cache_miss',\n providerMetadataObject.deepseek.promptCacheMissTokens,\n );\n }\n } catch {\n // Ignore\n }\n }\n}\n\n/**\n * Sets an attribute only if the value is not null or undefined.\n */\nfunction setAttributeIfDefined(attributes: SpanAttributes, key: string, value: SpanAttributeValue | undefined): void {\n if (value != null) {\n attributes[key] = value;\n }\n}\n"],"names":[],"mappings":";;;;;;;;;AA4DA;AACA;AACA;AACA;AACA,SAAS,mBAAmB,CAAC,IAAI,EAAc;AAC/C,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,IAAA,EAAK,GAAI,UAAU,CAAC,IAAI,CAAC;;AAElE,EAAE,IAAI,CAAC,IAAI,EAAE;AACb,IAAI;AACJ,EAAE;;AAEF;AACA;AACA,EAAE,IAAI,UAAU,CAAC,2BAA2B,CAAA,IAAK,UAAU,CAAC,yBAAyB,CAAA,IAAK,IAAA,KAAS,aAAa,EAAE;AAClH,IAAI,mBAAmB,CAAC,IAAI,EAAE,UAAU,CAAC;AACzC,IAAI;AACJ,EAAE;;AAEF;AACA;AACA,EAAE,IAAI,CAAC,UAAU,CAAC,yBAAyB,CAAA,IAAK,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE;AACzE,IAAI;AACJ,EAAE;;AAEF,EAAE,MAAM,MAAA,GAAS,SAAS,EAAE;AAC5B,EAAE,MAAM,cAAc,MAAM,EAAE,oBAAoB,CAAC,UAAU;;AAEzD;AACJ,EAAE,MAAM,gBAAA,GAAmB,sBAAsB,CAAC,WAAW,EAAE,OAAO,EAAE,gBAAgB,CAAC;;AAEzF,EAAE,mBAAmB,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,gBAAgB,CAAC;AAC/D;;AAEA,SAAS,sBAAsB,CAAC,KAAK,EAAgB;AACrD,EAAE,IAAI,KAAK,CAAC,IAAA,KAAS,aAAA,IAAiB,KAAK,CAAC,KAAK,EAAE;AACnD;AACA,IAAI,MAAM,gBAAgB,GAA8B,IAAI,GAAG,EAAE;;AAEjE;AACA,IAAI,KAAK,MAAM,IAAA,IAAQ,KAAK,CAAC,KAAK,EAAE;AACpC,MAAM,wBAAwB,CAAC,IAAI,CAAC;;AAEpC;AACA,MAAM,yBAAyB,CAAC,IAAI,EAAE,gBAAgB,CAAC;AACvD,IAAI;;AAEJ;AACA,IAAI,8BAA8B,CAAC,KAAK,CAAC,KAAK,EAAE,gBAAgB,CAAC;;AAEjE;AACA,IAAI,MAAM,KAAA,GAAQ,KAAK,CAAC,QAAQ,EAAE,KAAK;AACvC,IAAI,IAAI,KAAK,EAAE,EAAA,KAAO,qBAAqB,EAAE;AAC7C,MAAM,sBAAsB,CAAC,KAAK,EAAE,gBAAgB,CAAC;AACrD,IAAI;AACJ,EAAE;;AAEF,EAAE,OAAO,KAAK;AACd;;AAEA;AACA;AACA;AACA;;AAQA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,qBAAqB,CAAC,YAAY,EAAmB;AAC9D,EAAE,IAAI,OAAO,YAAA,KAAiB,QAAQ,EAAE;AACxC,IAAI,OAAO,MAAM;AACjB,EAAE;;AAEF;AACA,EAAE,QAAQ,YAAY;AACtB,IAAI,KAAK,YAAY;AACrB,MAAM,OAAO,WAAW;AACxB,IAAI,KAAK,MAAM;AACf,IAAI,KAAK,QAAQ;AACjB,IAAI,KAAK,gBAAgB;AACzB,IAAI,KAAK,OAAO;AAChB,MAAM,OAAO,YAAY;AACzB,IAAI;AACJ;AACA,MAAM,OAAO,YAAY;AACzB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,mBAAmB,CAAC,UAAU,EAAiC;AACxE,EAAE,MAAM,YAAA,GAAe,UAAU,CAAC,0BAA0B,CAAC;AAC7D,EAAE,MAAM,iBAAA,GAAoB,UAAU,CAAC,gCAAgC,CAAC;AACxE,EAAE,MAAM,YAAA,GAAe,UAAU,CAAC,mCAAmC,CAAC;;AAEtE;AACA,EAAE,IAAI,YAAA,IAAgB,QAAQ,iBAAA,IAAqB,IAAI,EAAE;AACzD,IAAI;AACJ,EAAE;;AAEF,EAAE,MAAM,KAAK,GAAmC,EAAE;;AAElD;AACA,EAAE,IAAI,OAAO,YAAA,KAAiB,QAAA,IAAY,YAAY,CAAC,MAAA,GAAS,CAAC,EAAE;AACnE,IAAI,KAAK,CAAC,IAAI,CAAC;AACf,MAAM,IAAI,EAAE,MAAM;AAClB,MAAM,OAAO,EAAE,YAAY;AAC3B,KAAK,CAAC;AACN,EAAE;;AAEF;AACA,EAAE,IAAI,iBAAA,IAAqB,IAAI,EAAE;AACjC,IAAI,IAAI;AACR;AACA,MAAM,MAAM,SAAS;AACrB,QAAQ,OAAO,iBAAA,KAAsB,QAAA,GAAW,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAA,GAAI,iBAAiB;;AAEjG,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE;AACpC,QAAQ,KAAK,MAAM,QAAA,IAAY,SAAS,EAAE;AAC1C;AACA,UAAU,MAAM,OAAO,QAAQ,CAAC,KAAA,IAAS,QAAQ,CAAC,IAAI;AACtD,UAAU,KAAK,CAAC,IAAI,CAAC;AACrB,YAAY,IAAI,EAAE,WAAW;AAC7B,YAAY,EAAE,EAAE,QAAQ,CAAC,UAAU;AACnC,YAAY,IAAI,EAAE,QAAQ,CAAC,QAAQ;AACnC;AACA;AACA,YAAY,SAAS,EAAE,OAAO,IAAA,KAAS,WAAW,IAAA,GAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;AACnF,WAAW,CAAC;AACZ,QAAQ;AACR;AACA;AACA,QAAQ,OAAO,UAAU,CAAC,gCAAgC,CAAC;AAC3D,MAAM;AACN,IAAI,EAAE,MAAM;AACZ;AACA,IAAI;AACJ,EAAE;;AAEF;AACA,EAAE,IAAI,KAAK,CAAC,MAAA,GAAS,CAAC,EAAE;AACxB,IAAI,MAAM,gBAAgB;AAC1B,MAAM,IAAI,EAAE,WAAW;AACvB,MAAM,KAAK;AACX,MAAM,aAAa,EAAE,qBAAqB,CAAC,YAAY,CAAC;AACxD,KAAK;;AAEL,IAAI,UAAU,CAAC,gCAAgC,CAAA,GAAI,IAAI,CAAC,SAAS,CAAC,CAAC,aAAa,CAAC,CAAC;;AAElF;AACA;AACA;AACA,IAAI,OAAO,UAAU,CAAC,0BAA0B,CAAC;AACjD,EAAE;AACF;;AAEA;AACA;AACA;AACA,SAAS,wBAAwB,CAAC,IAAI,EAAkB;AACxD,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,MAAA,EAAO,GAAI,IAAI;;AAE3C,EAAE,IAAI,MAAA,KAAW,oBAAoB,EAAE;AACvC,IAAI;AACJ,EAAE;;AAEF;AACA;AACA,EAAE,IAAI,IAAI,CAAC,MAAA,IAAU,IAAI,CAAC,MAAA,KAAW,IAAI,EAAE;AAC3C,IAAI,IAAI,CAAC,MAAA,GAAS,gBAAgB;AAClC,EAAE;;AAEF,EAAE,kBAAkB,CAAC,UAAU,EAAE,oCAAoC,EAAE,oCAAoC,CAAC;AAC5G,EAAE,kBAAkB,CAAC,UAAU,EAAE,gCAAgC,EAAE,mCAAmC,CAAC;AACvG,EAAE,kBAAkB,CAAC,UAAU,EAAE,sCAAsC,EAAE,0CAA0C,CAAC;;AAEpH;AACA,EAAE,kBAAkB,CAAC,UAAU,EAAE,sBAAsB,EAAE,mCAAmC,CAAC;AAC7F,EAAE,kBAAkB,CAAC,UAAU,EAAE,uBAAuB,EAAE,oCAAoC,CAAC;;AAE/F;AACA,EAAE,kBAAkB,CAAC,UAAU,EAAE,yBAAyB,EAAE,mCAAmC,CAAC;;AAEhG;AACA,EAAE,kBAAkB,CAAC,UAAU,EAAE,sCAAsC,EAAE,0CAA0C,CAAC;;AAEpH;AACA,EAAE;AACF,IAAI,OAAO,UAAU,CAAC,mCAAmC,CAAA,KAAM,QAAA;AAC/D,IAAI,OAAO,UAAU,CAAC,0CAA0C,MAAM;AACtE,IAAI;AACJ,IAAI,UAAU,CAAC,mCAAmC,CAAA;AAClD,MAAM,UAAU,CAAC,mCAAmC,CAAA,GAAI,UAAU,CAAC,0CAA0C,CAAC;AAC9G,EAAE;;AAEF;AACA,EAAE,IAAI,OAAO,UAAU,CAAC,mCAAmC,CAAA,KAAM,QAAQ,EAAE;AAC3E,IAAI,MAAM,YAAA;AACV,MAAM,OAAO,UAAU,CAAC,oCAAoC,MAAM;AAClE,UAAU,UAAU,CAAC,oCAAoC;AACzD,UAAU,CAAC;AACX,IAAI,UAAU,CAAC,mCAAmC,CAAA,GAAI,eAAe,UAAU,CAAC,mCAAmC,CAAC;AACpH,EAAE;;AAEF;AACA,EAAE,IAAI,UAAU,CAAC,yBAAyB,KAAK,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,yBAAyB,CAAC,CAAC,EAAE;AACrG,IAAI,UAAU,CAAC,yBAAyB,CAAA,GAAI,iCAAiC;AAC7E,MAAM,UAAU,CAAC,yBAAyB,CAAA;AAC1C,KAAK;AACL,EAAE;;AAEF;AACA;AACA,EAAE,IAAI,UAAU,CAAC,wBAAwB,CAAC,EAAE;AAC5C;AACA;AACA;AACA,IAAI,MAAM,gBAAA,GAAmB,UAAU,CAAC,yBAAyB;AACjE,SAAS,UAAU,CAAC,yBAAyB,CAAA;AAC7C,SAAS,UAAU,CAAC,wBAAwB,GAAY;AACxD,IAAI,MAAM,aAAA,GAAgB,sBAAsB,CAAC,GAAG,CAAC,gBAAgB,CAAA,IAAK,gBAAgB;AAC1F,IAAI,UAAU,CAAC,+BAA+B,CAAA,GAAI,aAAa;AAC/D;AACA,IAAI,OAAO,UAAU,CAAC,wBAAwB,CAAC;AAC/C,EAAE;AACF,EAAE,kBAAkB,CAAC,UAAU,EAAE,4BAA4B,EAAE,+BAA+B,CAAC;;AAE/F;AACA;AACA,EAAE,mBAAmB,CAAC,UAAU,CAAC;;AAEjC,EAAE,kBAAkB,CAAC,UAAU,EAAE,4BAA4B,EAAE,wBAAwB,CAAC;AACxF,EAAE,kBAAkB,CAAC,UAAU,EAAE,yBAAyB,EAAE,gCAAgC,CAAC;;AAE7F,EAAE,kBAAkB,CAAC,UAAU,EAAE,2BAA2B,EAAE,2BAA2B,CAAC;AAC1F,EAAE,kBAAkB,CAAC,UAAU,EAAE,6BAA6B,EAAE,4BAA4B,CAAC;;AAE7F,EAAE,kBAAkB,CAAC,UAAU,EAAE,mBAAmB,EAAE,uBAAuB,CAAC;AAC9E,EAAE,kBAAkB,CAAC,UAAU,EAAE,qBAAqB,EAAE,8BAA8B,CAAC;;AAEvF;AACA;AACA;AACA,EAAE,IAAI,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,mBAAmB,CAAC,CAAC,EAAE;AACtD,IAAI,MAAM,MAAA,GAAS,CAAC,UAAU,CAAC,mBAAmB,CAAA,GAAe,GAAG,CAAC,KAAK;AAC1E,MAAM,IAAI;AACV,QAAQ,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;AAC5B,MAAM,EAAE,MAAM;AACd,QAAQ,OAAO,CAAC;AAChB,MAAM;AACN,IAAI,CAAC,CAAC;AACN,IAAI,UAAU,CAAC,iCAAiC,CAAA,GAAI,MAAM,CAAC,WAAW,CAAA,GAAI,MAAM,CAAC,CAAC,CAAA,GAAI,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;AAC5G,EAAE;;AAEF,EAAE,+BAA+B,CAAC,UAAU,CAAC;;AAE7C;AACA,EAAE,KAAK,MAAM,GAAA,IAAO,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE;AAC7C,IAAI,IAAI,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE;AAC/B,MAAM,kBAAkB,CAAC,UAAU,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,GAAG,CAAC,CAAA,CAAA;AACA,IAAA;AACA,EAAA;AACA;;AAEA;AACA;AACA;AACA;AACA,SAAA,kBAAA,CAAA,UAAA,EAAA,MAAA,EAAA,MAAA,EAAA;AACA,EAAA,IAAA,UAAA,CAAA,MAAA,CAAA,IAAA,IAAA,EAAA;AACA,IAAA,UAAA,CAAA,MAAA,CAAA,GAAA,UAAA,CAAA,MAAA,CAAA;AACA;AACA,IAAA,OAAA,UAAA,CAAA,MAAA,CAAA;AACA,EAAA;AACA;;AAEA,SAAA,mBAAA,CAAA,IAAA,EAAA,UAAA,EAAA;AACA,EAAA,IAAA,CAAA,YAAA,CAAA,gCAAA,EAAA,oBAAA,CAAA;AACA,EAAA,IAAA,CAAA,YAAA,CAAA,4BAAA,EAAA,qBAAA,CAAA;AACA,EAAA,IAAA,CAAA,YAAA,CAAA,+BAAA,EAAA,cAAA,CAAA;AACA,EAAA,kBAAA,CAAA,UAAA,EAAA,2BAAA,EAAA,0BAAA,CAAA;AACA,EAAA,kBAAA,CAAA,UAAA,EAAA,yBAAA,EAAA,6BAAA,CAAA;;AAEA;AACA;AACA;AACA,EAAA,MAAA,UAAA,GAAA,UAAA,CAAA,6BAAA,CAAA;;AAEA,EAAA,IAAA,OAAA,UAAA,KAAA,QAAA,EAAA;AACA,IAAA,sBAAA,CAAA,GAAA,CAAA,UAAA,EAAA,IAAA,CAAA,WAAA,EAAA,CAAA;AACA,EAAA;;AAEA;AACA,EAAA,IAAA,CAAA,UAAA,CAAA,0BAAA,CAAA,EAAA;AACA,IAAA,IAAA,CAAA,YAAA,CAAA,0BAAA,EAAA,UAAA,CAAA;AACA,EAAA;AACA,EAAA,MAAA,QAAA,GAAA,UAAA,CAAA,0BAAA,CAAA;AACA,EAAA,IAAA,QAAA,EAAA;AACA,IAAA,IAAA,CAAA,UAAA,CAAA,CAAA,aAAA,EAAA,QAAA,CAAA,CAAA,CAAA;AACA,EAAA;AACA;;AAEA,SAAA,mBAAA,CAAA,IAAA,EAAA,IAAA,EAAA,UAAA,EAAA,gBAAA,EAAA;AACA,EAAA,IAAA,CAAA,YAAA,CAAA,gCAAA,EAAA,oBAAA,CAAA;;AAEA,EAAA,MAAA,YAAA,GAAA,IAAA,CAAA,OAAA,CAAA,KAAA,EAAA,EAAA,CAAA;AACA,EAAA,IAAA,CAAA,YAAA,CAAA,kBAAA,EAAA,YAAA,CAAA;AACA,EAAA,IAAA,CAAA,UAAA,CAAA,YAAA,CAAA;;AAEA,EAAA,MAAA,UAAA,GAAA,UAAA,CAAA,kCAAA,CAAA;AACA,EAAA,IAAA,UAAA,IAAA,OAAA,UAAA,KAAA,QAAA,EAAA;AACA,IAAA,IAAA,CAAA,YAAA,CAAA,oBAAA,EAAA,UAAA,CAAA;AACA,EAAA;;AAEA,EAAA,yBAAA,CAAA,IAAA,EAAA,UAAA,EAAA,gBAAA,CAAA;;AAEA,EAAA,IAAA,UAAA,CAAA,qBAAA,CAAA,IAAA,CAAA,UAAA,CAAA,+BAAA,CAAA,EAAA;AACA,IAAA,IAAA,CAAA,YAAA,CAAA,+BAAA,EAAA,UAAA,CAAA,qBAAA,CAAA,CAAA;AACA,EAAA;AACA,EAAA,IAAA,CAAA,YAAA,CAAA,cAAA,EAAA,IAAA,CAAA,QAAA,CAAA,QAAA,CAAA,CAAA;;AAEA;AACA,EAAA,MAAA,aAAA,GAAA,sBAAA,CAAA,GAAA,CAAA,IAAA,CAAA;AACA,EAAA,IAAA,aAAA,EAAA;AACA,IAAA,IAAA,CAAA,YAAA,CAAA,4BAAA,EAAA,CAAA,OAAA,EAAA,aAAA,CAAA,CAAA,CAAA;AACA,EAAA,CAAA,MAAA,IAAA,IAAA,CAAA,UAAA,CAAA,WAAA,CAAA,EAAA;AACA,IAAA,IAAA,CAAA,YAAA,CAAA,4BAAA,EAAA,QAAA,CAAA;AACA,EAAA;;AAEA;AACA;AACA,EAAA,IAAA,aAAA,KAAA,cAAA,EAAA;AACA,IAAA,IAAA,UAAA,IAAA,OAAA,UAAA,KAAA,QAAA,EAAA;AACA,MAAA,IAAA,CAAA,UAAA,CAAA,CAAA,aAAA,EAAA,UAAA,CAAA,CAAA,CAAA;AACA,IAAA,CAAA,MAAA;AACA,MAAA,IAAA,CAAA,UAAA,CAAA,cAAA,CAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;;AAEA,EAAA,MAAA,OAAA,GAAA,UAAA,CAAA,qBAAA,CAAA;AACA,EAAA,IAAA,OAAA,IAAA,aAAA,EAAA;AACA,IAAA,IAAA,CAAA,UAAA,CAAA,CAAA,EAAA,aAAA,CAAA,CAAA,EAAA,OAAA,CAAA,CAAA,CAAA;AACA,EAAA;AACA;;AAEA;AACA;AACA;AACA,SAAA,qBAAA,CAAA,MAAA,EAAA;AACA,EAAA,MAAA,CAAA,EAAA,CAAA,WAAA,EAAA,mBAAA,CAAA;AACA;AACA,EAAA,MAAA,CAAA,iBAAA,CAAA,MAAA,CAAA,MAAA,CAAA,sBAAA,EAAA,EAAA,EAAA,EAAA,wBAAA,EAAA,CAAA,CAAA;AACA;;AAEA,SAAA,+BAAA,CAAA,UAAA,EAAA;AACA,EAAA,MAAA,gBAAA,GAAA,UAAA,CAAA,uCAAA,CAAA;AACA,EAAA,IAAA,gBAAA,EAAA;AACA,IAAA,IAAA;AACA,MAAA,MAAA,sBAAA,GAAA,IAAA,CAAA,KAAA,CAAA,gBAAA,CAAA;;AAEA;AACA,MAAA,MAAA,cAAA;AACA,QAAA,sBAAA,CAAA,MAAA,IAAA,sBAAA,CAAA,KAAA;AACA,MAAA,IAAA,cAAA,EAAA;AACA,QAAA,qBAAA;AACA,UAAA,UAAA;AACA,UAAA,0CAAA;AACA,UAAA,cAAA,CAAA,kBAAA;AACA,SAAA;AACA,QAAA,qBAAA,CAAA,UAAA,EAAA,sCAAA,EAAA,cAAA,CAAA,eAAA,CAAA;AACA,QAAA,qBAAA;AACA,UAAA,UAAA;AACA,UAAA,gDAAA;AACA,UAAA,cAAA,CAAA,wBAAA;AACA,SAAA;AACA,QAAA,qBAAA;AACA,UAAA,UAAA;AACA,UAAA,gDAAA;AACA,UAAA,cAAA,CAAA,wBAAA;AACA,SAAA;AACA,QAAA,IAAA,CAAA,UAAA,CAAA,wBAAA,CAAA,EAAA;AACA,UAAA,qBAAA,CAAA,UAAA,EAAA,wBAAA,EAAA,cAAA,CAAA,UAAA,CAAA;AACA,QAAA;AACA,MAAA;;AAEA,MAAA,IAAA,sBAAA,CAAA,SAAA,EAAA;AACA,QAAA,MAAA,iBAAA;AACA,UAAA,sBAAA,CAAA,SAAA,CAAA,KAAA,EAAA,uBAAA;AACA,UAAA,sBAAA,CAAA,SAAA,CAAA,oBAAA;AACA,QAAA,qBAAA,CAAA,UAAA,EAAA,0CAAA,EAAA,iBAAA,CAAA;;AAEA,QAAA,MAAA,qBAAA;AACA,UAAA,sBAAA,CAAA,SAAA,CAAA,KAAA,EAAA,2BAAA;AACA,UAAA,sBAAA,CAAA,SAAA,CAAA,wBAAA;AACA,QAAA,qBAAA,CAAA,UAAA,EAAA,+CAAA,EAAA,qBAAA,CAAA;AACA,MAAA;;AAEA,MAAA,IAAA,sBAAA,CAAA,OAAA,EAAA,KAAA,EAAA;AACA,QAAA,qBAAA;AACA,UAAA,UAAA;AACA,UAAA,0CAAA;AACA,UAAA,sBAAA,CAAA,OAAA,CAAA,KAAA,CAAA,oBAAA;AACA,SAAA;AACA,QAAA,qBAAA;AACA,UAAA,UAAA;AACA,UAAA,+CAAA;AACA,UAAA,sBAAA,CAAA,OAAA,CAAA,KAAA,CAAA,qBAAA;AACA,SAAA;AACA,MAAA;;AAEA,MAAA,IAAA,sBAAA,CAAA,QAAA,EAAA;AACA,QAAA,qBAAA;AACA,UAAA,UAAA;AACA,UAAA,0CAAA;AACA,UAAA,sBAAA,CAAA,QAAA,CAAA,oBAAA;AACA,SAAA;AACA,QAAA,qBAAA;AACA,UAAA,UAAA;AACA,UAAA,sCAAA;AACA,UAAA,sBAAA,CAAA,QAAA,CAAA,qBAAA;AACA,SAAA;AACA,MAAA;AACA,IAAA,CAAA,CAAA,MAAA;AACA;AACA,IAAA;AACA,EAAA;AACA;;AAEA;AACA;AACA;AACA,SAAA,qBAAA,CAAA,UAAA,EAAA,GAAA,EAAA,KAAA,EAAA;AACA,EAAA,IAAA,KAAA,IAAA,IAAA,EAAA;AACA,IAAA,UAAA,CAAA,GAAA,CAAA,GAAA,KAAA;AACA,EAAA;AACA;;;;"}
1
+ {"version":3,"file":"index.js","sources":["../../../../src/tracing/vercel-ai/index.ts"],"sourcesContent":["/* eslint-disable max-lines */\nimport type { Client } from '../../client';\nimport { getClient } from '../../currentScopes';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '../../semanticAttributes';\nimport { shouldEnableTruncation } from '../ai/utils';\nimport type { Event } from '../../types-hoist/event';\nimport type { Span, SpanAttributes, SpanAttributeValue, SpanJSON, StreamedSpanJSON } from '../../types-hoist/span';\nimport { spanToJSON } from '../../utils/spanUtils';\nimport {\n GEN_AI_EMBEDDINGS_INPUT_ATTRIBUTE,\n GEN_AI_INPUT_MESSAGES_ATTRIBUTE,\n GEN_AI_OPERATION_NAME_ATTRIBUTE,\n GEN_AI_OUTPUT_MESSAGES_ATTRIBUTE,\n GEN_AI_REQUEST_MODEL_ATTRIBUTE,\n GEN_AI_RESPONSE_MODEL_ATTRIBUTE,\n GEN_AI_TOOL_CALL_ID_ATTRIBUTE,\n GEN_AI_TOOL_DESCRIPTION_ATTRIBUTE,\n GEN_AI_TOOL_INPUT_ATTRIBUTE,\n GEN_AI_TOOL_NAME_ATTRIBUTE,\n GEN_AI_TOOL_OUTPUT_ATTRIBUTE,\n GEN_AI_TOOL_TYPE_ATTRIBUTE,\n GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE,\n GEN_AI_USAGE_INPUT_TOKENS_CACHE_WRITE_ATTRIBUTE,\n GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE,\n GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE,\n GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE,\n} from '../ai/gen-ai-attributes';\nimport { SPAN_TO_OPERATION_NAME, toolCallSpanContextMap, toolDescriptionMap } from './constants';\nimport type { TokenSummary } from './types';\nimport { hasSpanStreamingEnabled } from '../spans/hasSpanStreamingEnabled';\nimport {\n accumulateTokensForParent,\n applyAccumulatedTokens,\n applyToolDescriptionsAndTokens,\n convertAvailableToolsToJsonString,\n requestMessagesFromPrompt,\n} from './utils';\nimport type { OpenAiProviderMetadata, ProviderMetadata } from './vercel-ai-attributes';\nimport {\n AI_MODEL_ID_ATTRIBUTE,\n AI_OPERATION_ID_ATTRIBUTE,\n AI_PROMPT_MESSAGES_ATTRIBUTE,\n AI_PROMPT_TOOLS_ATTRIBUTE,\n AI_RESPONSE_FINISH_REASON_ATTRIBUTE,\n AI_RESPONSE_OBJECT_ATTRIBUTE,\n AI_RESPONSE_PROVIDER_METADATA_ATTRIBUTE,\n AI_RESPONSE_TEXT_ATTRIBUTE,\n AI_RESPONSE_TOOL_CALLS_ATTRIBUTE,\n AI_SCHEMA_ATTRIBUTE,\n AI_TELEMETRY_FUNCTION_ID_ATTRIBUTE,\n AI_TOOL_CALL_ARGS_ATTRIBUTE,\n AI_TOOL_CALL_ID_ATTRIBUTE,\n AI_TOOL_CALL_NAME_ATTRIBUTE,\n AI_TOOL_CALL_RESULT_ATTRIBUTE,\n AI_USAGE_CACHED_INPUT_TOKENS_ATTRIBUTE,\n AI_USAGE_COMPLETION_TOKENS_ATTRIBUTE,\n AI_USAGE_PROMPT_TOKENS_ATTRIBUTE,\n AI_USAGE_TOKENS_ATTRIBUTE,\n AI_VALUES_ATTRIBUTE,\n OPERATION_NAME_ATTRIBUTE,\n} from './vercel-ai-attributes';\n\n/**\n * Post-process spans emitted by the Vercel AI SDK.\n * This is supposed to be used in `client.on('spanStart', ...)\n */\nfunction onVercelAiSpanStart(span: Span): void {\n const { data: attributes, description: name } = spanToJSON(span);\n\n if (!name) {\n return;\n }\n\n // Tool call spans\n // https://ai-sdk.dev/docs/ai-sdk-core/telemetry#tool-call-spans\n if (attributes[AI_TOOL_CALL_NAME_ATTRIBUTE] && attributes[AI_TOOL_CALL_ID_ATTRIBUTE] && name === 'ai.toolCall') {\n processToolCallSpan(span, attributes);\n return;\n }\n\n // V6+ Check if this is a Vercel AI span by checking if the operation ID attribute is present.\n // V5+ Check if this is a Vercel AI span by name pattern.\n if (!attributes[AI_OPERATION_ID_ATTRIBUTE] && !name.startsWith('ai.')) {\n return;\n }\n\n const client = getClient();\n const integration = client?.getIntegrationByName('VercelAI') as\n | { options?: { enableTruncation?: boolean } }\n | undefined;\n const enableTruncation = shouldEnableTruncation(integration?.options?.enableTruncation);\n\n processGenerateSpan(span, name, attributes, enableTruncation);\n}\n\nfunction vercelAiEventProcessor(event: Event): Event {\n if (event.type === 'transaction' && event.spans) {\n // Map to accumulate token data by parent span ID\n const tokenAccumulator: Map<string, TokenSummary> = new Map();\n\n // First pass: process all spans and accumulate token data\n for (const span of event.spans) {\n processEndedVercelAiSpan(span);\n\n // Accumulate token data for parent spans\n accumulateTokensForParent(span, tokenAccumulator);\n }\n\n // Second pass: apply tool descriptions and accumulated tokens\n applyToolDescriptionsAndTokens(event.spans, tokenAccumulator);\n\n // Also apply to root when it is the invoke_agent pipeline\n const trace = event.contexts?.trace;\n if (trace?.op === 'gen_ai.invoke_agent') {\n applyAccumulatedTokens(trace, tokenAccumulator);\n }\n }\n\n return event;\n}\n\n/**\n * Tool call structure from Vercel AI SDK\n * Note: V5/V6 use 'input' for arguments, V4 and earlier use 'args'\n */\ninterface VercelToolCall {\n toolCallId: string;\n toolName: string;\n input?: Record<string, unknown> | string; // V5/V6\n args?: string; // V4 and earlier\n}\n\n/**\n * Normalize finish reason to match OpenTelemetry semantic conventions.\n * Valid values: \"stop\", \"length\", \"content_filter\", \"tool_call\", \"error\"\n *\n * Vercel AI SDK uses \"tool-calls\" (plural, with hyphen) which we map to \"tool_call\".\n */\nfunction normalizeFinishReason(finishReason: unknown): string {\n if (typeof finishReason !== 'string') {\n return 'stop';\n }\n\n // Map Vercel AI SDK finish reasons to OpenTelemetry semantic convention values\n switch (finishReason) {\n case 'tool-calls':\n return 'tool_call';\n case 'stop':\n case 'length':\n case 'content_filter':\n case 'error':\n return finishReason;\n default:\n // For unknown values, return as-is (schema allows arbitrary strings)\n return finishReason;\n }\n}\n\n/**\n * Build gen_ai.output.messages from ai.response.text and/or ai.response.toolCalls\n *\n * Format follows OpenTelemetry semantic conventions:\n * [{\"role\": \"assistant\", \"parts\": [...], \"finish_reason\": \"stop\"}]\n *\n * Parts can be:\n * - {\"type\": \"text\", \"content\": \"...\"}\n * - {\"type\": \"tool_call\", \"id\": \"...\", \"name\": \"...\", \"arguments\": \"...\"}\n */\nfunction buildOutputMessages(attributes: Record<string, unknown>): void {\n const responseText = attributes[AI_RESPONSE_TEXT_ATTRIBUTE];\n const responseToolCalls = attributes[AI_RESPONSE_TOOL_CALLS_ATTRIBUTE];\n const finishReason = attributes[AI_RESPONSE_FINISH_REASON_ATTRIBUTE];\n\n // Skip if neither text nor tool calls are present\n if (responseText == null && responseToolCalls == null) {\n return;\n }\n\n const parts: Array<Record<string, unknown>> = [];\n\n // Add text part if present\n if (typeof responseText === 'string' && responseText.length > 0) {\n parts.push({\n type: 'text',\n content: responseText,\n });\n }\n\n // Add tool call parts if present\n if (responseToolCalls != null) {\n try {\n // Tool calls can be a string (JSON) or already parsed array\n const toolCalls: VercelToolCall[] =\n typeof responseToolCalls === 'string' ? JSON.parse(responseToolCalls) : responseToolCalls;\n\n if (Array.isArray(toolCalls)) {\n for (const toolCall of toolCalls) {\n // V5/V6 use 'input', V4 and earlier use 'args'\n const args = toolCall.input ?? toolCall.args;\n parts.push({\n type: 'tool_call',\n id: toolCall.toolCallId,\n name: toolCall.toolName,\n // Handle undefined args: JSON.stringify(undefined) returns undefined, not a string,\n // which would cause the property to be omitted from the final JSON output\n arguments: typeof args === 'string' ? args : JSON.stringify(args ?? {}),\n });\n }\n // Only delete tool calls attribute if we successfully processed them\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete attributes[AI_RESPONSE_TOOL_CALLS_ATTRIBUTE];\n }\n } catch {\n // Ignore parsing errors - tool calls attribute is preserved\n }\n }\n\n // Only set output messages and delete text attribute if we have parts\n if (parts.length > 0) {\n const outputMessage = {\n role: 'assistant',\n parts,\n finish_reason: normalizeFinishReason(finishReason),\n };\n\n attributes[GEN_AI_OUTPUT_MESSAGES_ATTRIBUTE] = JSON.stringify([outputMessage]);\n\n // Remove the text attribute since it's now captured in gen_ai.output.messages\n // Note: tool calls attribute is deleted above only if successfully parsed\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete attributes[AI_RESPONSE_TEXT_ATTRIBUTE];\n }\n}\n\n/**\n * Post-process spans emitted by the Vercel AI SDK.\n */\n/**\n * Rename and normalize Vercel AI SDK attributes to OpenTelemetry semantic conventions.\n * This is the shared attribute processing logic used by both the legacy event processor\n * path (SpanJSON) and the streamed span path (StreamedSpanJSON).\n */\nexport function processVercelAiSpanAttributes(attributes: Record<string, unknown>): void {\n renameAttributeKey(attributes, AI_USAGE_COMPLETION_TOKENS_ATTRIBUTE, GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE);\n renameAttributeKey(attributes, AI_USAGE_PROMPT_TOKENS_ATTRIBUTE, GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE);\n renameAttributeKey(attributes, AI_USAGE_CACHED_INPUT_TOKENS_ATTRIBUTE, GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE);\n\n // Parent spans (ai.streamText, ai.streamObject, etc.) use inputTokens/outputTokens instead of promptTokens/completionTokens\n renameAttributeKey(attributes, 'ai.usage.inputTokens', GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE);\n renameAttributeKey(attributes, 'ai.usage.outputTokens', GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE);\n\n // Embedding spans use ai.usage.tokens instead of promptTokens/completionTokens\n renameAttributeKey(attributes, AI_USAGE_TOKENS_ATTRIBUTE, GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE);\n\n // AI SDK uses avgOutputTokensPerSecond, map to our expected attribute name\n renameAttributeKey(attributes, 'ai.response.avgOutputTokensPerSecond', 'ai.response.avgCompletionTokensPerSecond');\n\n // Input tokens is the sum of prompt tokens and cached input tokens\n if (\n typeof attributes[GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE] === 'number' &&\n typeof attributes[GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE] === 'number'\n ) {\n attributes[GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE] =\n attributes[GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE] + attributes[GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE];\n }\n\n // Compute total tokens from input + output (embeddings may only have input tokens)\n if (typeof attributes[GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE] === 'number') {\n const outputTokens =\n typeof attributes[GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE] === 'number'\n ? attributes[GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE]\n : 0;\n attributes[GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE] = outputTokens + attributes[GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE];\n }\n\n // Convert the available tools array to a JSON string\n if (attributes[AI_PROMPT_TOOLS_ATTRIBUTE] && Array.isArray(attributes[AI_PROMPT_TOOLS_ATTRIBUTE])) {\n attributes[AI_PROMPT_TOOLS_ATTRIBUTE] = convertAvailableToolsToJsonString(\n attributes[AI_PROMPT_TOOLS_ATTRIBUTE] as unknown[],\n );\n }\n\n // Rename AI SDK attributes to standardized gen_ai attributes\n // Map operation.name to OpenTelemetry semantic convention values\n if (attributes[OPERATION_NAME_ATTRIBUTE]) {\n // V6+ sets ai.operationId to the bare operation (e.g. \"ai.streamText\") while\n // operation.name appends functionId (e.g. \"ai.streamText myAgent\").\n // When ai.operationId is present, use it for correct mapping.\n const rawOperationName = attributes[AI_OPERATION_ID_ATTRIBUTE]\n ? (attributes[AI_OPERATION_ID_ATTRIBUTE] as string)\n : (attributes[OPERATION_NAME_ATTRIBUTE] as string);\n const operationName = SPAN_TO_OPERATION_NAME.get(rawOperationName) ?? rawOperationName;\n attributes[GEN_AI_OPERATION_NAME_ATTRIBUTE] = operationName;\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete attributes[OPERATION_NAME_ATTRIBUTE];\n }\n renameAttributeKey(attributes, AI_PROMPT_MESSAGES_ATTRIBUTE, GEN_AI_INPUT_MESSAGES_ATTRIBUTE);\n\n // Build gen_ai.output.messages from response text and/or tool calls\n // Note: buildOutputMessages also removes the source attributes when output is successfully generated\n buildOutputMessages(attributes);\n\n renameAttributeKey(attributes, AI_RESPONSE_OBJECT_ATTRIBUTE, 'gen_ai.response.object');\n renameAttributeKey(attributes, AI_PROMPT_TOOLS_ATTRIBUTE, 'gen_ai.request.available_tools');\n\n renameAttributeKey(attributes, AI_TOOL_CALL_ARGS_ATTRIBUTE, GEN_AI_TOOL_INPUT_ATTRIBUTE);\n renameAttributeKey(attributes, AI_TOOL_CALL_RESULT_ATTRIBUTE, GEN_AI_TOOL_OUTPUT_ATTRIBUTE);\n\n renameAttributeKey(attributes, AI_SCHEMA_ATTRIBUTE, 'gen_ai.request.schema');\n renameAttributeKey(attributes, AI_MODEL_ID_ATTRIBUTE, GEN_AI_REQUEST_MODEL_ATTRIBUTE);\n\n // Map embedding input: ai.values → gen_ai.embeddings.input\n // Vercel AI SDK JSON-stringifies each value individually, so we parse each element back.\n // Single embed gets unwrapped to a plain value; batch embedMany stays as a JSON array.\n if (Array.isArray(attributes[AI_VALUES_ATTRIBUTE])) {\n const parsed = (attributes[AI_VALUES_ATTRIBUTE] as string[]).map(v => {\n try {\n return JSON.parse(v);\n } catch {\n return v;\n }\n });\n attributes[GEN_AI_EMBEDDINGS_INPUT_ATTRIBUTE] = parsed.length === 1 ? parsed[0] : JSON.stringify(parsed);\n }\n\n addProviderMetadataToAttributes(attributes);\n\n // Change attributes namespaced with `ai.X` to `vercel.ai.X`\n for (const key of Object.keys(attributes)) {\n if (key.startsWith('ai.')) {\n renameAttributeKey(attributes, key, `vercel.${key}`);\n }\n }\n}\n\nfunction processEndedVercelAiSpan(span: SpanJSON): void {\n const { data: attributes, origin } = span;\n\n if (origin !== 'auto.vercelai.otel') {\n return;\n }\n\n // The Vercel AI SDK sets span status to raw error message strings.\n // Any such value should be normalized to a SpanStatusType value. We pick internal_error as it is the most generic.\n if (span.status && span.status !== 'ok') {\n span.status = 'internal_error';\n }\n\n processVercelAiSpanAttributes(attributes);\n}\n\nfunction processVercelAiStreamedSpan(span: StreamedSpanJSON): void {\n const attributes = span.attributes;\n if (attributes?.[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN] !== 'auto.vercelai.otel') {\n return;\n }\n\n processVercelAiSpanAttributes(attributes);\n\n // Look up tool description from the toolDescriptionMap for execute_tool spans\n if (attributes[SEMANTIC_ATTRIBUTE_SENTRY_OP] === 'gen_ai.execute_tool' && span.parent_span_id) {\n const descriptions = toolDescriptionMap.get(span.parent_span_id);\n\n if (descriptions) {\n const toolName = attributes[GEN_AI_TOOL_NAME_ATTRIBUTE];\n if (typeof toolName === 'string') {\n const desc = descriptions.get(toolName);\n if (desc) {\n attributes[GEN_AI_TOOL_DESCRIPTION_ATTRIBUTE] = desc;\n }\n }\n }\n }\n\n // Clean up tool descriptions when the parent span ends\n toolDescriptionMap.delete(span.span_id);\n}\n\n/**\n * Renames an attribute key in the provided attributes object if the old key exists.\n * This function safely handles null and undefined values.\n */\nfunction renameAttributeKey(attributes: Record<string, unknown>, oldKey: string, newKey: string): void {\n if (attributes[oldKey] != null) {\n attributes[newKey] = attributes[oldKey];\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete attributes[oldKey];\n }\n}\n\nfunction processToolCallSpan(span: Span, attributes: SpanAttributes): void {\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.vercelai.otel');\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, 'gen_ai.execute_tool');\n span.setAttribute(GEN_AI_OPERATION_NAME_ATTRIBUTE, 'execute_tool');\n renameAttributeKey(attributes, AI_TOOL_CALL_NAME_ATTRIBUTE, GEN_AI_TOOL_NAME_ATTRIBUTE);\n renameAttributeKey(attributes, AI_TOOL_CALL_ID_ATTRIBUTE, GEN_AI_TOOL_CALL_ID_ATTRIBUTE);\n\n // Store the span context in our global map using the tool call ID.\n // This allows us to capture tool errors and link them to the correct span\n // without retaining the full Span object in memory.\n const toolCallId = attributes[GEN_AI_TOOL_CALL_ID_ATTRIBUTE];\n\n if (typeof toolCallId === 'string') {\n toolCallSpanContextMap.set(toolCallId, span.spanContext());\n }\n\n // https://opentelemetry.io/docs/specs/semconv/registry/attributes/gen-ai/#gen-ai-tool-type\n if (!attributes[GEN_AI_TOOL_TYPE_ATTRIBUTE]) {\n span.setAttribute(GEN_AI_TOOL_TYPE_ATTRIBUTE, 'function');\n }\n const toolName = attributes[GEN_AI_TOOL_NAME_ATTRIBUTE];\n if (toolName) {\n span.updateName(`execute_tool ${toolName}`);\n }\n}\n\nfunction processGenerateSpan(span: Span, name: string, attributes: SpanAttributes, enableTruncation: boolean): void {\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.vercelai.otel');\n\n const nameWthoutAi = name.replace('ai.', '');\n span.setAttribute('ai.pipeline.name', nameWthoutAi);\n span.updateName(nameWthoutAi);\n\n const functionId = attributes[AI_TELEMETRY_FUNCTION_ID_ATTRIBUTE];\n if (functionId && typeof functionId === 'string') {\n span.setAttribute('gen_ai.function_id', functionId);\n }\n\n requestMessagesFromPrompt(span, attributes, enableTruncation);\n\n if (attributes[AI_MODEL_ID_ATTRIBUTE] && !attributes[GEN_AI_RESPONSE_MODEL_ATTRIBUTE]) {\n span.setAttribute(GEN_AI_RESPONSE_MODEL_ATTRIBUTE, attributes[AI_MODEL_ID_ATTRIBUTE]);\n }\n span.setAttribute('ai.streaming', name.includes('stream'));\n\n // Set the op based on the operation name registry\n const operationName = SPAN_TO_OPERATION_NAME.get(name);\n if (operationName) {\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, `gen_ai.${operationName}`);\n } else if (name.startsWith('ai.stream')) {\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, 'ai.run');\n }\n\n // For invoke_agent pipeline spans, use 'invoke_agent' as the description\n // to be consistent with other AI integrations (e.g. LangGraph)\n if (operationName === 'invoke_agent') {\n if (functionId && typeof functionId === 'string') {\n span.updateName(`invoke_agent ${functionId}`);\n } else {\n span.updateName('invoke_agent');\n }\n return;\n }\n\n const modelId = attributes[AI_MODEL_ID_ATTRIBUTE];\n if (modelId && operationName) {\n span.updateName(`${operationName} ${modelId}`);\n }\n\n // Store tool descriptions in the toolDescriptionMap so processSpan can apply them to execute_tool spans.\n // This is only needed for span streaming (transaction path handles this separately)\n const client = getClient();\n if (\n client &&\n hasSpanStreamingEnabled(client) &&\n attributes[AI_PROMPT_TOOLS_ATTRIBUTE] &&\n Array.isArray(attributes[AI_PROMPT_TOOLS_ATTRIBUTE])\n ) {\n const descriptions = new Map<string, string>();\n\n // parse tool names and descriptions from tool string array\n for (const toolStr of attributes[AI_PROMPT_TOOLS_ATTRIBUTE] as unknown[]) {\n try {\n const parsed = (typeof toolStr === 'string' ? JSON.parse(toolStr) : toolStr) as {\n name?: string;\n description?: string;\n };\n if (parsed?.name && parsed?.description) {\n descriptions.set(parsed.name, parsed.description);\n }\n } catch {\n // ignore parse errors\n }\n }\n if (descriptions.size > 0) {\n // Tool call spans are siblings of doGenerate (both children of invoke_agent),\n // so we key by the parent span ID (the invoke_agent span).\n const parentSpanId = spanToJSON(span).parent_span_id;\n if (parentSpanId) {\n toolDescriptionMap.set(parentSpanId, descriptions);\n }\n }\n }\n}\n\n/**\n * Add event processors to the given client to process Vercel AI spans.\n */\nexport function addVercelAiProcessors(client: Client): void {\n client.on('spanStart', onVercelAiSpanStart);\n // Note: We cannot do this on `spanEnd`, because the span cannot be mutated anymore at this point\n client.addEventProcessor(Object.assign(vercelAiEventProcessor, { id: 'VercelAiEventProcessor' }));\n client.on('processSpan', span => {\n processVercelAiStreamedSpan(span);\n });\n}\n\nfunction addProviderMetadataToAttributes(attributes: Record<string, unknown>): void {\n const providerMetadata = attributes[AI_RESPONSE_PROVIDER_METADATA_ATTRIBUTE] as string | undefined;\n if (providerMetadata) {\n try {\n const providerMetadataObject = JSON.parse(providerMetadata) as ProviderMetadata;\n\n // Handle OpenAI metadata (v5 uses 'openai', v6 Azure Responses API uses 'azure')\n const openaiMetadata: OpenAiProviderMetadata | undefined =\n providerMetadataObject.openai ?? providerMetadataObject.azure;\n if (openaiMetadata) {\n setAttributeIfDefined(\n attributes,\n GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE,\n openaiMetadata.cachedPromptTokens,\n );\n setAttributeIfDefined(attributes, 'gen_ai.usage.output_tokens.reasoning', openaiMetadata.reasoningTokens);\n setAttributeIfDefined(\n attributes,\n 'gen_ai.usage.output_tokens.prediction_accepted',\n openaiMetadata.acceptedPredictionTokens,\n );\n setAttributeIfDefined(\n attributes,\n 'gen_ai.usage.output_tokens.prediction_rejected',\n openaiMetadata.rejectedPredictionTokens,\n );\n if (!attributes['gen_ai.conversation.id']) {\n setAttributeIfDefined(attributes, 'gen_ai.conversation.id', openaiMetadata.responseId);\n }\n }\n\n if (providerMetadataObject.anthropic) {\n const cachedInputTokens =\n providerMetadataObject.anthropic.usage?.cache_read_input_tokens ??\n providerMetadataObject.anthropic.cacheReadInputTokens;\n setAttributeIfDefined(attributes, GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE, cachedInputTokens);\n\n const cacheWriteInputTokens =\n providerMetadataObject.anthropic.usage?.cache_creation_input_tokens ??\n providerMetadataObject.anthropic.cacheCreationInputTokens;\n setAttributeIfDefined(attributes, GEN_AI_USAGE_INPUT_TOKENS_CACHE_WRITE_ATTRIBUTE, cacheWriteInputTokens);\n }\n\n if (providerMetadataObject.bedrock?.usage) {\n setAttributeIfDefined(\n attributes,\n GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE,\n providerMetadataObject.bedrock.usage.cacheReadInputTokens,\n );\n setAttributeIfDefined(\n attributes,\n GEN_AI_USAGE_INPUT_TOKENS_CACHE_WRITE_ATTRIBUTE,\n providerMetadataObject.bedrock.usage.cacheWriteInputTokens,\n );\n }\n\n if (providerMetadataObject.deepseek) {\n setAttributeIfDefined(\n attributes,\n GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE,\n providerMetadataObject.deepseek.promptCacheHitTokens,\n );\n setAttributeIfDefined(\n attributes,\n 'gen_ai.usage.input_tokens.cache_miss',\n providerMetadataObject.deepseek.promptCacheMissTokens,\n );\n }\n } catch {\n // Ignore\n }\n }\n}\n\n/**\n * Sets an attribute only if the value is not null or undefined.\n */\nfunction setAttributeIfDefined(\n attributes: Record<string, unknown>,\n key: string,\n value: SpanAttributeValue | undefined,\n): void {\n if (value != null) {\n attributes[key] = value;\n }\n}\n"],"names":[],"mappings":"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"}
package/build/esm/trpc.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import { getClient, withIsolationScope } from './currentScopes.js';
2
2
  import { captureException } from './exports.js';
3
3
  import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from './semanticAttributes.js';
4
- import { addNonEnumerableProperty } from './utils/object.js';
5
4
  import { normalize } from './utils/normalize.js';
6
5
  import { startSpanManual } from './tracing/trace.js';
6
+ import { setNormalizationDepthOverrideHint } from './utils/normalizationHints.js';
7
7
 
8
8
  const trpcCaptureContext = { mechanism: { handled: false, type: 'auto.rpc.trpc.middleware' } };
9
9
 
@@ -37,9 +37,8 @@ function trpcMiddleware(options = {}) {
37
37
  procedure_type: type,
38
38
  };
39
39
 
40
- addNonEnumerableProperty(
40
+ setNormalizationDepthOverrideHint(
41
41
  trpcContext,
42
- '__sentry_override_normalization_depth__',
43
42
  1 + // 1 for context.input + the normal normalization depth
44
43
  (clientOptions?.normalizeDepth ?? 5), // 5 is a sane depth
45
44
  );
@@ -1 +1 @@
1
- {"version":3,"file":"trpc.js","sources":["../../src/trpc.ts"],"sourcesContent":["import { getClient, withIsolationScope } from './currentScopes';\nimport { captureException } from './exports';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from './semanticAttributes';\nimport { startSpanManual } from './tracing';\nimport { normalize } from './utils/normalize';\nimport { addNonEnumerableProperty } from './utils/object';\n\ninterface SentryTrpcMiddlewareOptions {\n /** Whether to include procedure inputs in reported events. Defaults to `false`. */\n attachRpcInput?: boolean;\n forceTransaction?: boolean;\n}\n\nexport interface SentryTrpcMiddlewareArguments<T> {\n path?: unknown;\n type?: unknown;\n next: () => T;\n rawInput?: unknown;\n getRawInput?: () => Promise<unknown>;\n}\n\nconst trpcCaptureContext = { mechanism: { handled: false, type: 'auto.rpc.trpc.middleware' } };\n\nfunction captureIfError(nextResult: unknown): void {\n // TODO: Set span status based on what TRPCError was encountered\n if (\n typeof nextResult === 'object' &&\n nextResult !== null &&\n 'ok' in nextResult &&\n !nextResult.ok &&\n 'error' in nextResult\n ) {\n captureException(nextResult.error, trpcCaptureContext);\n }\n}\n\ntype SentryTrpcMiddleware<T> = T extends Promise<unknown> ? T : Promise<T>;\n\n/**\n * Sentry tRPC middleware that captures errors and creates spans for tRPC procedures.\n */\nexport function trpcMiddleware(options: SentryTrpcMiddlewareOptions = {}) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n return async function <T>(opts: SentryTrpcMiddlewareArguments<T>): SentryTrpcMiddleware<T> {\n const { path, type, next, rawInput, getRawInput } = opts;\n\n const client = getClient();\n const clientOptions = client?.getOptions();\n\n const trpcContext: Record<string, unknown> = {\n procedure_path: path,\n procedure_type: type,\n };\n\n addNonEnumerableProperty(\n trpcContext,\n '__sentry_override_normalization_depth__',\n 1 + // 1 for context.input + the normal normalization depth\n (clientOptions?.normalizeDepth ?? 5), // 5 is a sane depth\n );\n\n if (options.attachRpcInput !== undefined ? options.attachRpcInput : clientOptions?.sendDefaultPii) {\n if (rawInput !== undefined) {\n trpcContext.input = normalize(rawInput);\n }\n\n if (getRawInput !== undefined && typeof getRawInput === 'function') {\n try {\n const rawRes = await getRawInput();\n\n trpcContext.input = normalize(rawRes);\n } catch {\n // noop\n }\n }\n }\n\n return withIsolationScope(scope => {\n scope.setContext('trpc', trpcContext);\n return startSpanManual(\n {\n name: `trpc/${path}`,\n op: 'rpc.server',\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.rpc.trpc',\n },\n forceTransaction: !!options.forceTransaction,\n },\n async span => {\n try {\n const nextResult = await next();\n captureIfError(nextResult);\n span.end();\n return nextResult;\n } catch (e) {\n captureException(e, trpcCaptureContext);\n span.end();\n throw e;\n }\n },\n ) as SentryTrpcMiddleware<T>;\n });\n };\n}\n"],"names":[],"mappings":";;;;;;;AAqBA,MAAM,kBAAA,GAAqB,EAAE,SAAS,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,0BAAA,IAA8B;;AAE9F,SAAS,cAAc,CAAC,UAAU,EAAiB;AACnD;AACA,EAAE;AACF,IAAI,OAAO,UAAA,KAAe,QAAA;AAC1B,IAAI,UAAA,KAAe,IAAA;AACnB,IAAI,IAAA,IAAQ,UAAA;AACZ,IAAI,CAAC,UAAU,CAAC,EAAA;AAChB,IAAI,WAAW;AACf,IAAI;AACJ,IAAI,gBAAgB,CAAC,UAAU,CAAC,KAAK,EAAE,kBAAkB,CAAC;AAC1D,EAAE;AACF;;AAIA;AACA;AACA;AACO,SAAS,cAAc,CAAC,OAAO,GAAgC,EAAE,EAAE;AAC1E;AACA;AACA,EAAE,OAAO,gBAAmB,IAAI,EAA6D;AAC7F,IAAI,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAA,EAAY,GAAI,IAAI;;AAE5D,IAAI,MAAM,MAAA,GAAS,SAAS,EAAE;AAC9B,IAAI,MAAM,aAAA,GAAgB,MAAM,EAAE,UAAU,EAAE;;AAE9C,IAAI,MAAM,WAAW,GAA4B;AACjD,MAAM,cAAc,EAAE,IAAI;AAC1B,MAAM,cAAc,EAAE,IAAI;AAC1B,KAAK;;AAEL,IAAI,wBAAwB;AAC5B,MAAM,WAAW;AACjB,MAAM,yCAAyC;AAC/C,MAAM,CAAA;AACN,SAAS,aAAa,EAAE,cAAA,IAAkB,CAAC,CAAC;AAC5C,KAAK;;AAEL,IAAI,IAAI,OAAO,CAAC,mBAAmB,SAAA,GAAY,OAAO,CAAC,cAAA,GAAiB,aAAa,EAAE,cAAc,EAAE;AACvG,MAAM,IAAI,QAAA,KAAa,SAAS,EAAE;AAClC,QAAQ,WAAW,CAAC,KAAA,GAAQ,SAAS,CAAC,QAAQ,CAAC;AAC/C,MAAM;;AAEN,MAAM,IAAI,WAAA,KAAgB,SAAA,IAAa,OAAO,WAAA,KAAgB,UAAU,EAAE;AAC1E,QAAQ,IAAI;AACZ,UAAU,MAAM,MAAA,GAAS,MAAM,WAAW,EAAE;;AAE5C,UAAU,WAAW,CAAC,KAAA,GAAQ,SAAS,CAAC,MAAM,CAAC;AAC/C,QAAQ,EAAE,MAAM;AAChB;AACA,QAAQ;AACR,MAAM;AACN,IAAI;;AAEJ,IAAI,OAAO,kBAAkB,CAAC,KAAA,IAAS;AACvC,MAAM,KAAK,CAAC,UAAU,CAAC,MAAM,EAAE,WAAW,CAAC;AAC3C,MAAM,OAAO,eAAe;AAC5B,QAAQ;AACR,UAAU,IAAI,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;AACA,UAAA,EAAA,EAAA,YAAA;AACA,UAAA,UAAA,EAAA;AACA,YAAA,CAAA,gCAAA,GAAA,OAAA;AACA,YAAA,CAAA,gCAAA,GAAA,eAAA;AACA,WAAA;AACA,UAAA,gBAAA,EAAA,CAAA,CAAA,OAAA,CAAA,gBAAA;AACA,SAAA;AACA,QAAA,MAAA,IAAA,IAAA;AACA,UAAA,IAAA;AACA,YAAA,MAAA,UAAA,GAAA,MAAA,IAAA,EAAA;AACA,YAAA,cAAA,CAAA,UAAA,CAAA;AACA,YAAA,IAAA,CAAA,GAAA,EAAA;AACA,YAAA,OAAA,UAAA;AACA,UAAA,CAAA,CAAA,OAAA,CAAA,EAAA;AACA,YAAA,gBAAA,CAAA,CAAA,EAAA,kBAAA,CAAA;AACA,YAAA,IAAA,CAAA,GAAA,EAAA;AACA,YAAA,MAAA,CAAA;AACA,UAAA;AACA,QAAA,CAAA;AACA,OAAA;AACA,IAAA,CAAA,CAAA;AACA,EAAA,CAAA;AACA;;;;"}
1
+ {"version":3,"file":"trpc.js","sources":["../../src/trpc.ts"],"sourcesContent":["import { getClient, withIsolationScope } from './currentScopes';\nimport { captureException } from './exports';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from './semanticAttributes';\nimport { startSpanManual } from './tracing';\nimport { normalize } from './utils/normalize';\nimport { setNormalizationDepthOverrideHint } from './utils/normalizationHints';\n\ninterface SentryTrpcMiddlewareOptions {\n /** Whether to include procedure inputs in reported events. Defaults to `false`. */\n attachRpcInput?: boolean;\n forceTransaction?: boolean;\n}\n\nexport interface SentryTrpcMiddlewareArguments<T> {\n path?: unknown;\n type?: unknown;\n next: () => T;\n rawInput?: unknown;\n getRawInput?: () => Promise<unknown>;\n}\n\nconst trpcCaptureContext = { mechanism: { handled: false, type: 'auto.rpc.trpc.middleware' } };\n\nfunction captureIfError(nextResult: unknown): void {\n // TODO: Set span status based on what TRPCError was encountered\n if (\n typeof nextResult === 'object' &&\n nextResult !== null &&\n 'ok' in nextResult &&\n !nextResult.ok &&\n 'error' in nextResult\n ) {\n captureException(nextResult.error, trpcCaptureContext);\n }\n}\n\ntype SentryTrpcMiddleware<T> = T extends Promise<unknown> ? T : Promise<T>;\n\n/**\n * Sentry tRPC middleware that captures errors and creates spans for tRPC procedures.\n */\nexport function trpcMiddleware(options: SentryTrpcMiddlewareOptions = {}) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n return async function <T>(opts: SentryTrpcMiddlewareArguments<T>): SentryTrpcMiddleware<T> {\n const { path, type, next, rawInput, getRawInput } = opts;\n\n const client = getClient();\n const clientOptions = client?.getOptions();\n\n const trpcContext: Record<string, unknown> = {\n procedure_path: path,\n procedure_type: type,\n };\n\n setNormalizationDepthOverrideHint(\n trpcContext,\n 1 + // 1 for context.input + the normal normalization depth\n (clientOptions?.normalizeDepth ?? 5), // 5 is a sane depth\n );\n\n if (options.attachRpcInput !== undefined ? options.attachRpcInput : clientOptions?.sendDefaultPii) {\n if (rawInput !== undefined) {\n trpcContext.input = normalize(rawInput);\n }\n\n if (getRawInput !== undefined && typeof getRawInput === 'function') {\n try {\n const rawRes = await getRawInput();\n\n trpcContext.input = normalize(rawRes);\n } catch {\n // noop\n }\n }\n }\n\n return withIsolationScope(scope => {\n scope.setContext('trpc', trpcContext);\n return startSpanManual(\n {\n name: `trpc/${path}`,\n op: 'rpc.server',\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.rpc.trpc',\n },\n forceTransaction: !!options.forceTransaction,\n },\n async span => {\n try {\n const nextResult = await next();\n captureIfError(nextResult);\n span.end();\n return nextResult;\n } catch (e) {\n captureException(e, trpcCaptureContext);\n span.end();\n throw e;\n }\n },\n ) as SentryTrpcMiddleware<T>;\n });\n };\n}\n"],"names":[],"mappings":";;;;;;;AAqBA,MAAM,kBAAA,GAAqB,EAAE,SAAS,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,0BAAA,IAA8B;;AAE9F,SAAS,cAAc,CAAC,UAAU,EAAiB;AACnD;AACA,EAAE;AACF,IAAI,OAAO,UAAA,KAAe,QAAA;AAC1B,IAAI,UAAA,KAAe,IAAA;AACnB,IAAI,IAAA,IAAQ,UAAA;AACZ,IAAI,CAAC,UAAU,CAAC,EAAA;AAChB,IAAI,WAAW;AACf,IAAI;AACJ,IAAI,gBAAgB,CAAC,UAAU,CAAC,KAAK,EAAE,kBAAkB,CAAC;AAC1D,EAAE;AACF;;AAIA;AACA;AACA;AACO,SAAS,cAAc,CAAC,OAAO,GAAgC,EAAE,EAAE;AAC1E;AACA;AACA,EAAE,OAAO,gBAAmB,IAAI,EAA6D;AAC7F,IAAI,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAA,EAAY,GAAI,IAAI;;AAE5D,IAAI,MAAM,MAAA,GAAS,SAAS,EAAE;AAC9B,IAAI,MAAM,aAAA,GAAgB,MAAM,EAAE,UAAU,EAAE;;AAE9C,IAAI,MAAM,WAAW,GAA4B;AACjD,MAAM,cAAc,EAAE,IAAI;AAC1B,MAAM,cAAc,EAAE,IAAI;AAC1B,KAAK;;AAEL,IAAI,iCAAiC;AACrC,MAAM,WAAW;AACjB,MAAM,CAAA;AACN,SAAS,aAAa,EAAE,cAAA,IAAkB,CAAC,CAAC;AAC5C,KAAK;;AAEL,IAAI,IAAI,OAAO,CAAC,mBAAmB,SAAA,GAAY,OAAO,CAAC,cAAA,GAAiB,aAAa,EAAE,cAAc,EAAE;AACvG,MAAM,IAAI,QAAA,KAAa,SAAS,EAAE;AAClC,QAAQ,WAAW,CAAC,KAAA,GAAQ,SAAS,CAAC,QAAQ,CAAC;AAC/C,MAAM;;AAEN,MAAM,IAAI,WAAA,KAAgB,SAAA,IAAa,OAAO,WAAA,KAAgB,UAAU,EAAE;AAC1E,QAAQ,IAAI;AACZ,UAAU,MAAM,MAAA,GAAS,MAAM,WAAW,EAAE;;AAE5C,UAAU,WAAW,CAAC,KAAA,GAAQ,SAAS,CAAC,MAAM,CAAC;AAC/C,QAAQ,EAAE,MAAM;AAChB;AACA,QAAQ;AACR,MAAM;AACN,IAAI;;AAEJ,IAAI,OAAO,kBAAkB,CAAC,KAAA,IAAS;AACvC,MAAM,KAAK,CAAC,UAAU,CAAC,MAAM,EAAE,WAAW,CAAC;AAC3C,MAAM,OAAO,eAAe;AAC5B,QAAQ;AACR,UAAU,IAAI,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;AACA,UAAA,EAAA,EAAA,YAAA;AACA,UAAA,UAAA,EAAA;AACA,YAAA,CAAA,gCAAA,GAAA,OAAA;AACA,YAAA,CAAA,gCAAA,GAAA,eAAA;AACA,WAAA;AACA,UAAA,gBAAA,EAAA,CAAA,CAAA,OAAA,CAAA,gBAAA;AACA,SAAA;AACA,QAAA,MAAA,IAAA,IAAA;AACA,UAAA,IAAA;AACA,YAAA,MAAA,UAAA,GAAA,MAAA,IAAA,EAAA;AACA,YAAA,cAAA,CAAA,UAAA,CAAA;AACA,YAAA,IAAA,CAAA,GAAA,EAAA;AACA,YAAA,OAAA,UAAA;AACA,UAAA,CAAA,CAAA,OAAA,CAAA,EAAA;AACA,YAAA,gBAAA,CAAA,CAAA,EAAA,kBAAA,CAAA;AACA,YAAA,IAAA,CAAA,GAAA,EAAA;AACA,YAAA,MAAA,CAAA;AACA,UAAA;AACA,QAAA,CAAA;AACA,OAAA;AACA,IAAA,CAAA,CAAA;AACA,EAAA,CAAA;AACA;;;;"}
@@ -166,5 +166,77 @@ function objectToBaggageHeader(object) {
166
166
  }, '');
167
167
  }
168
168
 
169
- export { MAX_BAGGAGE_STRING_LENGTH, SENTRY_BAGGAGE_KEY_PREFIX, SENTRY_BAGGAGE_KEY_PREFIX_REGEX, baggageHeaderToDynamicSamplingContext, dynamicSamplingContextToSentryBaggageHeader, objectToBaggageHeader, parseBaggageHeader };
169
+ /**
170
+ * Merge two baggage headers into one.
171
+ * - Sentry-specific entries (keys starting with "sentry-") from the new
172
+ * baggage take precedence
173
+ * - Non-Sentry entries from existing baggage take precedence
174
+ *
175
+ * The order of the existing baggage will be preserved, and new entries will
176
+ * be added to the end.
177
+ *
178
+ * This matches the behavior of OTEL's propagation.inject() which uses
179
+ * `baggage.setEntry()` to overwrite existing entries with the same key.
180
+ */
181
+ function mergeBaggageHeaders(
182
+ existing,
183
+ incoming,
184
+ ) {
185
+ if (!existing) {
186
+ return incoming;
187
+ }
188
+
189
+ const existingEntries = parseBaggageHeader(existing);
190
+ const incomingEntries = parseBaggageHeader(incoming);
191
+
192
+ if (!incomingEntries) {
193
+ return existing;
194
+ }
195
+
196
+ // 1. All non-sentry entries from existing are kept
197
+ // 2. All sentry- entries from the new baggage are retained
198
+ // 3. If sentry- entries present in new, ignore from old, else keep from old.
199
+ // 4. Non-sentry entries from new are only kept if not in existing.
200
+
201
+ const merged = {};
202
+
203
+ // partition incoming entries into sentry and non-sentry prefixed
204
+ let hasNewSentryEntries = false;
205
+ const newSentryEntries = {};
206
+ const newNonSentryEntries = {};
207
+ for (const [key, value] of Object.entries(incomingEntries)) {
208
+ if (key.startsWith(SENTRY_BAGGAGE_KEY_PREFIX)) {
209
+ newSentryEntries[key] = value;
210
+ hasNewSentryEntries = true;
211
+ } else {
212
+ newNonSentryEntries[key] = value;
213
+ }
214
+ }
215
+
216
+ // If new baggage contains at least one sentry- value, we remove all old
217
+ // sentry- values otherwise, we keep old sentry- values. If we don't remove
218
+ // old sentry- values, we end up with an inconsistent dynamic sampling
219
+ // context propagation.
220
+ if (existingEntries) {
221
+ for (const [key, value] of Object.entries(existingEntries)) {
222
+ if (!hasNewSentryEntries || !key.startsWith(SENTRY_BAGGAGE_KEY_PREFIX)) {
223
+ merged[key] = value;
224
+ }
225
+ }
226
+ }
227
+
228
+ // Assign new sentry fields.
229
+ if (hasNewSentryEntries) {
230
+ Object.assign(merged, newSentryEntries);
231
+ }
232
+
233
+ // assign new non-sentry fields not found on existing object.
234
+ for (const [key, value] of Object.entries(newNonSentryEntries)) {
235
+ merged[key] ??= value;
236
+ }
237
+
238
+ return objectToBaggageHeader(merged);
239
+ }
240
+
241
+ export { MAX_BAGGAGE_STRING_LENGTH, SENTRY_BAGGAGE_KEY_PREFIX, SENTRY_BAGGAGE_KEY_PREFIX_REGEX, baggageHeaderToDynamicSamplingContext, dynamicSamplingContextToSentryBaggageHeader, mergeBaggageHeaders, objectToBaggageHeader, parseBaggageHeader };
170
242
  //# sourceMappingURL=baggage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"baggage.js","sources":["../../../src/utils/baggage.ts"],"sourcesContent":["import { DEBUG_BUILD } from '../debug-build';\nimport type { DynamicSamplingContext } from '../types-hoist/envelope';\nimport { debug } from './debug-logger';\nimport { isString } from './is';\n\nexport const SENTRY_BAGGAGE_KEY_PREFIX = 'sentry-';\n\nexport const SENTRY_BAGGAGE_KEY_PREFIX_REGEX = /^sentry-/;\n\n/**\n * Max length of a serialized baggage string\n *\n * https://www.w3.org/TR/baggage/#limits\n */\nexport const MAX_BAGGAGE_STRING_LENGTH = 8192;\n\n/**\n * Takes a baggage header and turns it into Dynamic Sampling Context, by extracting all the \"sentry-\" prefixed values\n * from it.\n *\n * @param baggageHeader A very bread definition of a baggage header as it might appear in various frameworks.\n * @returns The Dynamic Sampling Context that was found on `baggageHeader`, if there was any, `undefined` otherwise.\n */\nexport function baggageHeaderToDynamicSamplingContext(\n // Very liberal definition of what any incoming header might look like\n baggageHeader: string | string[] | number | null | undefined | boolean,\n): Partial<DynamicSamplingContext> | undefined {\n const baggageObject = parseBaggageHeader(baggageHeader);\n\n if (!baggageObject) {\n return undefined;\n }\n\n // Read all \"sentry-\" prefixed values out of the baggage object and put it onto a dynamic sampling context object.\n const dynamicSamplingContext = Object.entries(baggageObject).reduce<Record<string, string>>((acc, [key, value]) => {\n if (key.startsWith(SENTRY_BAGGAGE_KEY_PREFIX)) {\n const nonPrefixedKey = key.slice(SENTRY_BAGGAGE_KEY_PREFIX.length);\n acc[nonPrefixedKey] = value;\n }\n return acc;\n }, {});\n\n // Only return a dynamic sampling context object if there are keys in it.\n // A keyless object means there were no sentry values on the header, which means that there is no DSC.\n if (Object.keys(dynamicSamplingContext).length > 0) {\n return dynamicSamplingContext as Partial<DynamicSamplingContext>;\n } else {\n return undefined;\n }\n}\n\n/**\n * Turns a Dynamic Sampling Object into a baggage header by prefixing all the keys on the object with \"sentry-\".\n *\n * @param dynamicSamplingContext The Dynamic Sampling Context to turn into a header. For convenience and compatibility\n * with the `getDynamicSamplingContext` method on the Transaction class ,this argument can also be `undefined`. If it is\n * `undefined` the function will return `undefined`.\n * @returns a baggage header, created from `dynamicSamplingContext`, or `undefined` either if `dynamicSamplingContext`\n * was `undefined`, or if `dynamicSamplingContext` didn't contain any values.\n */\nexport function dynamicSamplingContextToSentryBaggageHeader(\n // this also takes undefined for convenience and bundle size in other places\n dynamicSamplingContext?: Partial<DynamicSamplingContext>,\n): string | undefined {\n if (!dynamicSamplingContext) {\n return undefined;\n }\n\n // Prefix all DSC keys with \"sentry-\" and put them into a new object\n const sentryPrefixedDSC = Object.entries(dynamicSamplingContext).reduce<Record<string, string>>(\n (acc, [dscKey, dscValue]) => {\n if (dscValue) {\n acc[`${SENTRY_BAGGAGE_KEY_PREFIX}${dscKey}`] = dscValue;\n }\n return acc;\n },\n {},\n );\n\n return objectToBaggageHeader(sentryPrefixedDSC);\n}\n\n/**\n * Take a baggage header and parse it into an object.\n */\nexport function parseBaggageHeader(\n baggageHeader: string | string[] | number | null | undefined | boolean,\n): Record<string, string> | undefined {\n if (!baggageHeader || (!isString(baggageHeader) && !Array.isArray(baggageHeader))) {\n return undefined;\n }\n\n if (Array.isArray(baggageHeader)) {\n // Combine all baggage headers into one object containing the baggage values so we can later read the Sentry-DSC-values from it\n return baggageHeader.reduce<Record<string, string>>((acc, curr) => {\n const currBaggageObject = baggageHeaderToObject(curr);\n Object.entries(currBaggageObject).forEach(([key, value]) => {\n acc[key] = value;\n });\n return acc;\n }, {});\n }\n\n return baggageHeaderToObject(baggageHeader);\n}\n\n/**\n * Will parse a baggage header, which is a simple key-value map, into a flat object.\n *\n * @param baggageHeader The baggage header to parse.\n * @returns a flat object containing all the key-value pairs from `baggageHeader`.\n */\nfunction baggageHeaderToObject(baggageHeader: string): Record<string, string> {\n return baggageHeader\n .split(',')\n .map(baggageEntry => {\n const eqIdx = baggageEntry.indexOf('=');\n if (eqIdx === -1) {\n // Likely an invalid entry\n return [];\n }\n const key = baggageEntry.slice(0, eqIdx);\n const value = baggageEntry.slice(eqIdx + 1);\n return [key, value].map(keyOrValue => {\n try {\n return decodeURIComponent(keyOrValue.trim());\n } catch {\n // We ignore errors here, e.g. if the value cannot be URL decoded.\n // This will then be skipped in the next step\n return;\n }\n });\n })\n .reduce<Record<string, string>>((acc, [key, value]) => {\n if (key && value) {\n acc[key] = value;\n }\n return acc;\n }, {});\n}\n\n/**\n * Turns a flat object (key-value pairs) into a baggage header, which is also just key-value pairs.\n *\n * @param object The object to turn into a baggage header.\n * @returns a baggage header string, or `undefined` if the object didn't have any values, since an empty baggage header\n * is not spec compliant.\n */\nexport function objectToBaggageHeader(object: Record<string, string>): string | undefined {\n if (Object.keys(object).length === 0) {\n // An empty baggage header is not spec compliant: We return undefined.\n return undefined;\n }\n\n return Object.entries(object).reduce((baggageHeader, [objectKey, objectValue], currentIndex) => {\n const baggageEntry = `${encodeURIComponent(objectKey)}=${encodeURIComponent(objectValue)}`;\n const newBaggageHeader = currentIndex === 0 ? baggageEntry : `${baggageHeader},${baggageEntry}`;\n if (newBaggageHeader.length > MAX_BAGGAGE_STRING_LENGTH) {\n DEBUG_BUILD &&\n debug.warn(\n `Not adding key: ${objectKey} with val: ${objectValue} to baggage header due to exceeding baggage size limits.`,\n );\n return baggageHeader;\n } else {\n return newBaggageHeader;\n }\n }, '');\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"baggage.js","sources":["../../../src/utils/baggage.ts"],"sourcesContent":["import { DEBUG_BUILD } from '../debug-build';\nimport type { DynamicSamplingContext } from '../types-hoist/envelope';\nimport { debug } from './debug-logger';\nimport { isString } from './is';\n\nexport const SENTRY_BAGGAGE_KEY_PREFIX = 'sentry-';\n\nexport const SENTRY_BAGGAGE_KEY_PREFIX_REGEX = /^sentry-/;\n\n/**\n * Max length of a serialized baggage string\n *\n * https://www.w3.org/TR/baggage/#limits\n */\nexport const MAX_BAGGAGE_STRING_LENGTH = 8192;\n\n/**\n * Takes a baggage header and turns it into Dynamic Sampling Context, by extracting all the \"sentry-\" prefixed values\n * from it.\n *\n * @param baggageHeader A very bread definition of a baggage header as it might appear in various frameworks.\n * @returns The Dynamic Sampling Context that was found on `baggageHeader`, if there was any, `undefined` otherwise.\n */\nexport function baggageHeaderToDynamicSamplingContext(\n // Very liberal definition of what any incoming header might look like\n baggageHeader: string | string[] | number | null | undefined | boolean,\n): Partial<DynamicSamplingContext> | undefined {\n const baggageObject = parseBaggageHeader(baggageHeader);\n\n if (!baggageObject) {\n return undefined;\n }\n\n // Read all \"sentry-\" prefixed values out of the baggage object and put it onto a dynamic sampling context object.\n const dynamicSamplingContext = Object.entries(baggageObject).reduce<Record<string, string>>((acc, [key, value]) => {\n if (key.startsWith(SENTRY_BAGGAGE_KEY_PREFIX)) {\n const nonPrefixedKey = key.slice(SENTRY_BAGGAGE_KEY_PREFIX.length);\n acc[nonPrefixedKey] = value;\n }\n return acc;\n }, {});\n\n // Only return a dynamic sampling context object if there are keys in it.\n // A keyless object means there were no sentry values on the header, which means that there is no DSC.\n if (Object.keys(dynamicSamplingContext).length > 0) {\n return dynamicSamplingContext as Partial<DynamicSamplingContext>;\n } else {\n return undefined;\n }\n}\n\n/**\n * Turns a Dynamic Sampling Object into a baggage header by prefixing all the keys on the object with \"sentry-\".\n *\n * @param dynamicSamplingContext The Dynamic Sampling Context to turn into a header. For convenience and compatibility\n * with the `getDynamicSamplingContext` method on the Transaction class ,this argument can also be `undefined`. If it is\n * `undefined` the function will return `undefined`.\n * @returns a baggage header, created from `dynamicSamplingContext`, or `undefined` either if `dynamicSamplingContext`\n * was `undefined`, or if `dynamicSamplingContext` didn't contain any values.\n */\nexport function dynamicSamplingContextToSentryBaggageHeader(\n // this also takes undefined for convenience and bundle size in other places\n dynamicSamplingContext?: Partial<DynamicSamplingContext>,\n): string | undefined {\n if (!dynamicSamplingContext) {\n return undefined;\n }\n\n // Prefix all DSC keys with \"sentry-\" and put them into a new object\n const sentryPrefixedDSC = Object.entries(dynamicSamplingContext).reduce<Record<string, string>>(\n (acc, [dscKey, dscValue]) => {\n if (dscValue) {\n acc[`${SENTRY_BAGGAGE_KEY_PREFIX}${dscKey}`] = dscValue;\n }\n return acc;\n },\n {},\n );\n\n return objectToBaggageHeader(sentryPrefixedDSC);\n}\n\n/**\n * Take a baggage header and parse it into an object.\n */\nexport function parseBaggageHeader(\n baggageHeader: string | string[] | number | null | undefined | boolean,\n): Record<string, string> | undefined {\n if (!baggageHeader || (!isString(baggageHeader) && !Array.isArray(baggageHeader))) {\n return undefined;\n }\n\n if (Array.isArray(baggageHeader)) {\n // Combine all baggage headers into one object containing the baggage values so we can later read the Sentry-DSC-values from it\n return baggageHeader.reduce<Record<string, string>>((acc, curr) => {\n const currBaggageObject = baggageHeaderToObject(curr);\n Object.entries(currBaggageObject).forEach(([key, value]) => {\n acc[key] = value;\n });\n return acc;\n }, {});\n }\n\n return baggageHeaderToObject(baggageHeader);\n}\n\n/**\n * Will parse a baggage header, which is a simple key-value map, into a flat object.\n *\n * @param baggageHeader The baggage header to parse.\n * @returns a flat object containing all the key-value pairs from `baggageHeader`.\n */\nfunction baggageHeaderToObject(baggageHeader: string): Record<string, string> {\n return baggageHeader\n .split(',')\n .map(baggageEntry => {\n const eqIdx = baggageEntry.indexOf('=');\n if (eqIdx === -1) {\n // Likely an invalid entry\n return [];\n }\n const key = baggageEntry.slice(0, eqIdx);\n const value = baggageEntry.slice(eqIdx + 1);\n return [key, value].map(keyOrValue => {\n try {\n return decodeURIComponent(keyOrValue.trim());\n } catch {\n // We ignore errors here, e.g. if the value cannot be URL decoded.\n // This will then be skipped in the next step\n return;\n }\n });\n })\n .reduce<Record<string, string>>((acc, [key, value]) => {\n if (key && value) {\n acc[key] = value;\n }\n return acc;\n }, {});\n}\n\n/**\n * Turns a flat object (key-value pairs) into a baggage header, which is also just key-value pairs.\n *\n * @param object The object to turn into a baggage header.\n * @returns a baggage header string, or `undefined` if the object didn't have any values, since an empty baggage header\n * is not spec compliant.\n */\nexport function objectToBaggageHeader(object: Record<string, string>): string | undefined {\n if (Object.keys(object).length === 0) {\n // An empty baggage header is not spec compliant: We return undefined.\n return undefined;\n }\n\n return Object.entries(object).reduce((baggageHeader, [objectKey, objectValue], currentIndex) => {\n const baggageEntry = `${encodeURIComponent(objectKey)}=${encodeURIComponent(objectValue)}`;\n const newBaggageHeader = currentIndex === 0 ? baggageEntry : `${baggageHeader},${baggageEntry}`;\n if (newBaggageHeader.length > MAX_BAGGAGE_STRING_LENGTH) {\n DEBUG_BUILD &&\n debug.warn(\n `Not adding key: ${objectKey} with val: ${objectValue} to baggage header due to exceeding baggage size limits.`,\n );\n return baggageHeader;\n } else {\n return newBaggageHeader;\n }\n }, '');\n}\n\n/**\n * Merge two baggage headers into one.\n * - Sentry-specific entries (keys starting with \"sentry-\") from the new\n * baggage take precedence\n * - Non-Sentry entries from existing baggage take precedence\n *\n * The order of the existing baggage will be preserved, and new entries will\n * be added to the end.\n *\n * This matches the behavior of OTEL's propagation.inject() which uses\n * `baggage.setEntry()` to overwrite existing entries with the same key.\n */\nexport function mergeBaggageHeaders<Existing extends string | string[] | number | undefined>(\n existing: Existing,\n incoming: string,\n): string | undefined | Existing {\n if (!existing) {\n return incoming;\n }\n\n const existingEntries = parseBaggageHeader(existing);\n const incomingEntries = parseBaggageHeader(incoming);\n\n if (!incomingEntries) {\n return existing;\n }\n\n // 1. All non-sentry entries from existing are kept\n // 2. All sentry- entries from the new baggage are retained\n // 3. If sentry- entries present in new, ignore from old, else keep from old.\n // 4. Non-sentry entries from new are only kept if not in existing.\n\n const merged: Record<string, string> = {};\n\n // partition incoming entries into sentry and non-sentry prefixed\n let hasNewSentryEntries = false;\n const newSentryEntries: Record<string, string> = {};\n const newNonSentryEntries: Record<string, string> = {};\n for (const [key, value] of Object.entries(incomingEntries)) {\n if (key.startsWith(SENTRY_BAGGAGE_KEY_PREFIX)) {\n newSentryEntries[key] = value;\n hasNewSentryEntries = true;\n } else {\n newNonSentryEntries[key] = value;\n }\n }\n\n // If new baggage contains at least one sentry- value, we remove all old\n // sentry- values otherwise, we keep old sentry- values. If we don't remove\n // old sentry- values, we end up with an inconsistent dynamic sampling\n // context propagation.\n if (existingEntries) {\n for (const [key, value] of Object.entries(existingEntries)) {\n if (!hasNewSentryEntries || !key.startsWith(SENTRY_BAGGAGE_KEY_PREFIX)) {\n merged[key] = value;\n }\n }\n }\n\n // Assign new sentry fields.\n if (hasNewSentryEntries) {\n Object.assign(merged, newSentryEntries);\n }\n\n // assign new non-sentry fields not found on existing object.\n for (const [key, value] of Object.entries(newNonSentryEntries)) {\n merged[key] ??= value;\n }\n\n return objectToBaggageHeader(merged);\n}\n"],"names":[],"mappings":"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"}
@@ -29,6 +29,7 @@ const chainAndCopyPromiseLike = (
29
29
 
30
30
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
31
31
  const copyProps = (original, chained) => {
32
+ if (!chained) return original;
32
33
  let mutated = false;
33
34
  //oxlint-disable-next-line guard-for-in
34
35
  for (const key in original) {
@@ -1 +1 @@
1
- {"version":3,"file":"chain-and-copy-promiselike.js","sources":["../../../src/utils/chain-and-copy-promiselike.ts"],"sourcesContent":["const isActualPromise = (p: unknown) =>\n p instanceof Promise && !(p as unknown as ChainedPromiseLike<unknown>)[kChainedCopy];\n\ntype ChainedPromiseLike<T> = PromiseLike<T> & {\n [kChainedCopy]: true;\n};\nconst kChainedCopy = Symbol('chained PromiseLike');\n\n/**\n * Copy the properties from a decorated promiselike object onto its chained\n * actual promise.\n */\nexport const chainAndCopyPromiseLike = <V, T extends PromiseLike<V>>(\n original: T,\n onSuccess: (value: V) => void,\n onError: (e: unknown) => void,\n): T => {\n const chained = original.then(\n value => {\n onSuccess(value);\n return value;\n },\n err => {\n onError(err);\n throw err;\n },\n ) as T;\n\n // if we're just dealing with \"normal\" Promise objects, return the chain\n return isActualPromise(chained) && isActualPromise(original) ? chained : copyProps(original, chained);\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst copyProps = <T extends Record<string, any>>(original: T, chained: T): T => {\n let mutated = false;\n //oxlint-disable-next-line guard-for-in\n for (const key in original) {\n if (key in chained) continue;\n mutated = true;\n const value = original[key];\n if (typeof value === 'function') {\n Object.defineProperty(chained, key, {\n value: (...args: unknown[]) => value.apply(original, args),\n enumerable: true,\n configurable: true,\n writable: true,\n });\n } else {\n (chained as Record<string, unknown>)[key] = value;\n }\n }\n\n if (mutated) Object.assign(chained, { [kChainedCopy]: true });\n return chained;\n};\n"],"names":[],"mappings":"AAAA,MAAM,eAAA,GAAkB,CAAC,CAAC;AAC1B,EAAE,CAAA,YAAa,OAAA,IAAW,CAAC,CAAC,CAAA,GAA6C,YAAY,CAAC;;AAKtF,MAAM,YAAA,GAAe,MAAM,CAAC,qBAAqB,CAAC;;AAElD;AACA;AACA;AACA;AACO,MAAM,0BAA0B;AACvC,EAAE,QAAQ;AACV,EAAE,SAAS;AACX,EAAE,OAAO;AACT,KAAQ;AACR,EAAE,MAAM,OAAA,GAAU,QAAQ,CAAC,IAAI;AAC/B,IAAI,SAAS;AACb,MAAM,SAAS,CAAC,KAAK,CAAC;AACtB,MAAM,OAAO,KAAK;AAClB,IAAI,CAAC;AACL,IAAI,OAAO;AACX,MAAM,OAAO,CAAC,GAAG,CAAC;AAClB,MAAM,MAAM,GAAG;AACf,IAAI,CAAC;AACL,GAAE;;AAEF;AACA,EAAE,OAAO,eAAe,CAAC,OAAO,CAAA,IAAK,eAAe,CAAC,QAAQ,CAAA,GAAI,UAAU,SAAS,CAAC,QAAQ,EAAE,OAAO,CAAC;AACvG;;AAEA;AACA,MAAM,YAAY,CAAgC,QAAQ,EAAK,OAAO,KAAW;AACjF,EAAE,IAAI,OAAA,GAAU,KAAK;AACrB;AACA,EAAE,KAAK,MAAM,GAAA,IAAO,QAAQ,EAAE;AAC9B,IAAI,IAAI,GAAA,IAAO,OAAO,EAAE;AACxB,IAAI,OAAA,GAAU,IAAI;AAClB,IAAI,MAAM,KAAA,GAAQ,QAAQ,CAAC,GAAG,CAAC;AAC/B,IAAI,IAAI,OAAO,KAAA,KAAU,UAAU,EAAE;AACrC,MAAM,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,GAAG,EAAE;AAC1C,QAAQ,KAAK,EAAE,CAAC,GAAG,IAAI,KAAgB,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,CAAC;AAClE,QAAQ,UAAU,EAAE,IAAI;AACxB,QAAQ,YAAY,EAAE,IAAI;AAC1B,QAAQ,QAAQ,EAAE,IAAI;AACtB,OAAO,CAAC;AACR,IAAI,OAAO;AACX,MAAM,CAAC,OAAA,GAAoC,GAAG,CAAA,GAAI,KAAK;AACvD,IAAI;AACJ,EAAE;;AAEF,EAAE,IAAI,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC,YAAY,GAAG,IAAA,EAAM,CAAC;AAC/D,EAAE,OAAO,OAAO;AAChB,CAAC;;;;"}
1
+ {"version":3,"file":"chain-and-copy-promiselike.js","sources":["../../../src/utils/chain-and-copy-promiselike.ts"],"sourcesContent":["const isActualPromise = (p: unknown) =>\n p instanceof Promise && !(p as unknown as ChainedPromiseLike<unknown>)[kChainedCopy];\n\ntype ChainedPromiseLike<T> = PromiseLike<T> & {\n [kChainedCopy]: true;\n};\nconst kChainedCopy = Symbol('chained PromiseLike');\n\n/**\n * Copy the properties from a decorated promiselike object onto its chained\n * actual promise.\n */\nexport const chainAndCopyPromiseLike = <V, T extends PromiseLike<V>>(\n original: T,\n onSuccess: (value: V) => void,\n onError: (e: unknown) => void,\n): T => {\n const chained = original.then(\n value => {\n onSuccess(value);\n return value;\n },\n err => {\n onError(err);\n throw err;\n },\n ) as T;\n\n // if we're just dealing with \"normal\" Promise objects, return the chain\n return isActualPromise(chained) && isActualPromise(original) ? chained : copyProps(original, chained);\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst copyProps = <T extends Record<string, any>>(original: T, chained: T): T => {\n if (!chained) return original;\n let mutated = false;\n //oxlint-disable-next-line guard-for-in\n for (const key in original) {\n if (key in chained) continue;\n mutated = true;\n const value = original[key];\n if (typeof value === 'function') {\n Object.defineProperty(chained, key, {\n value: (...args: unknown[]) => value.apply(original, args),\n enumerable: true,\n configurable: true,\n writable: true,\n });\n } else {\n (chained as Record<string, unknown>)[key] = value;\n }\n }\n\n if (mutated) Object.assign(chained, { [kChainedCopy]: true });\n return chained;\n};\n"],"names":[],"mappings":"AAAA,MAAM,eAAA,GAAkB,CAAC,CAAC;AAC1B,EAAE,CAAA,YAAa,OAAA,IAAW,CAAC,CAAC,CAAA,GAA6C,YAAY,CAAC;;AAKtF,MAAM,YAAA,GAAe,MAAM,CAAC,qBAAqB,CAAC;;AAElD;AACA;AACA;AACA;AACO,MAAM,0BAA0B;AACvC,EAAE,QAAQ;AACV,EAAE,SAAS;AACX,EAAE,OAAO;AACT,KAAQ;AACR,EAAE,MAAM,OAAA,GAAU,QAAQ,CAAC,IAAI;AAC/B,IAAI,SAAS;AACb,MAAM,SAAS,CAAC,KAAK,CAAC;AACtB,MAAM,OAAO,KAAK;AAClB,IAAI,CAAC;AACL,IAAI,OAAO;AACX,MAAM,OAAO,CAAC,GAAG,CAAC;AAClB,MAAM,MAAM,GAAG;AACf,IAAI,CAAC;AACL,GAAE;;AAEF;AACA,EAAE,OAAO,eAAe,CAAC,OAAO,CAAA,IAAK,eAAe,CAAC,QAAQ,CAAA,GAAI,UAAU,SAAS,CAAC,QAAQ,EAAE,OAAO,CAAC;AACvG;;AAEA;AACA,MAAM,YAAY,CAAgC,QAAQ,EAAK,OAAO,KAAW;AACjF,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,QAAQ;AAC/B,EAAE,IAAI,OAAA,GAAU,KAAK;AACrB;AACA,EAAE,KAAK,MAAM,GAAA,IAAO,QAAQ,EAAE;AAC9B,IAAI,IAAI,GAAA,IAAO,OAAO,EAAE;AACxB,IAAI,OAAA,GAAU,IAAI;AAClB,IAAI,MAAM,KAAA,GAAQ,QAAQ,CAAC,GAAG,CAAC;AAC/B,IAAI,IAAI,OAAO,KAAA,KAAU,UAAU,EAAE;AACrC,MAAM,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,GAAG,EAAE;AAC1C,QAAQ,KAAK,EAAE,CAAC,GAAG,IAAI,KAAgB,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,CAAC;AAClE,QAAQ,UAAU,EAAE,IAAI;AACxB,QAAQ,YAAY,EAAE,IAAI;AAC1B,QAAQ,QAAQ,EAAE,IAAI;AACtB,OAAO,CAAC;AACR,IAAI,OAAO;AACX,MAAM,CAAC,OAAA,GAAoC,GAAG,CAAA,GAAI,KAAK;AACvD,IAAI;AACJ,EAAE;;AAEF,EAAE,IAAI,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC,YAAY,GAAG,IAAA,EAAM,CAAC;AAC/D,EAAE,OAAO,OAAO;AAChB,CAAC;;;;"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Often we patch a module's default export, but we want to be able to do
3
+ * something like this:
4
+ *
5
+ * ```ts
6
+ * patchTheThing(await import('the-thing'));
7
+ * ```
8
+ *
9
+ * Or like this:
10
+ *
11
+ * ```ts
12
+ * import theThing from 'the-thing';
13
+ * patchTheThing(theThing);
14
+ * ```
15
+ *
16
+ * Note: this does not support modules with a falsey default export. However,
17
+ * presumably in those cases, there's no default export to patch anyway.
18
+ */
19
+ function getDefaultExport(moduleExport) {
20
+ return (
21
+ (!!moduleExport &&
22
+ typeof moduleExport === 'object' &&
23
+ 'default' in moduleExport &&
24
+ (moduleExport ).default) ||
25
+ (moduleExport )
26
+ );
27
+ }
28
+
29
+ export { getDefaultExport };
30
+ //# sourceMappingURL=get-default-export.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-default-export.js","sources":["../../../src/utils/get-default-export.ts"],"sourcesContent":["/**\n * Often we patch a module's default export, but we want to be able to do\n * something like this:\n *\n * ```ts\n * patchTheThing(await import('the-thing'));\n * ```\n *\n * Or like this:\n *\n * ```ts\n * import theThing from 'the-thing';\n * patchTheThing(theThing);\n * ```\n *\n * Note: this does not support modules with a falsey default export. However,\n * presumably in those cases, there's no default export to patch anyway.\n */\nexport function getDefaultExport<T>(moduleExport: T | { default: T }): T {\n return (\n (!!moduleExport &&\n typeof moduleExport === 'object' &&\n 'default' in moduleExport &&\n (moduleExport as { default: T }).default) ||\n (moduleExport as T)\n );\n}\n"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,gBAAgB,CAAI,YAAY,EAAyB;AACzE,EAAE;AACF,IAAI,CAAC,CAAC,CAAC,YAAA;AACP,MAAM,OAAO,YAAA,KAAiB,QAAA;AAC9B,MAAM,SAAA,IAAa,YAAA;AACnB,MAAM,CAAC,YAAA,GAAgC,OAAO;AAC9C,KAAK,YAAA;AACL;AACA;;;;"}