@sentry/core 10.47.0 → 10.48.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (316) hide show
  1. package/build/cjs/attributes.js +43 -0
  2. package/build/cjs/attributes.js.map +1 -1
  3. package/build/cjs/client.js +13 -6
  4. package/build/cjs/client.js.map +1 -1
  5. package/build/cjs/envelope.js +4 -3
  6. package/build/cjs/envelope.js.map +1 -1
  7. package/build/cjs/index.js +44 -13
  8. package/build/cjs/index.js.map +1 -1
  9. package/build/cjs/integration.js +6 -0
  10. package/build/cjs/integration.js.map +1 -1
  11. package/build/cjs/integrations/express/index.js +206 -0
  12. package/build/cjs/integrations/express/index.js.map +1 -0
  13. package/build/cjs/integrations/express/patch-layer.js +251 -0
  14. package/build/cjs/integrations/express/patch-layer.js.map +1 -0
  15. package/build/cjs/integrations/express/request-layer-store.js +25 -0
  16. package/build/cjs/integrations/express/request-layer-store.js.map +1 -0
  17. package/build/cjs/integrations/express/set-sdk-processing-metadata.js +17 -0
  18. package/build/cjs/integrations/express/set-sdk-processing-metadata.js.map +1 -0
  19. package/build/cjs/integrations/express/types.js +17 -0
  20. package/build/cjs/integrations/express/types.js.map +1 -0
  21. package/build/cjs/integrations/express/utils.js +238 -0
  22. package/build/cjs/integrations/express/utils.js.map +1 -0
  23. package/build/cjs/integrations/mcp-server/correlation.js +5 -1
  24. package/build/cjs/integrations/mcp-server/correlation.js.map +1 -1
  25. package/build/cjs/integrations/mcp-server/handlers.js +18 -10
  26. package/build/cjs/integrations/mcp-server/handlers.js.map +1 -1
  27. package/build/cjs/integrations/mcp-server/index.js +2 -1
  28. package/build/cjs/integrations/mcp-server/index.js.map +1 -1
  29. package/build/cjs/integrations/mcp-server/transport.js +1 -1
  30. package/build/cjs/integrations/mcp-server/transport.js.map +1 -1
  31. package/build/cjs/integrations/mcp-server/validation.js +7 -5
  32. package/build/cjs/integrations/mcp-server/validation.js.map +1 -1
  33. package/build/cjs/integrations/spanStreaming.js +48 -0
  34. package/build/cjs/integrations/spanStreaming.js.map +1 -0
  35. package/build/cjs/semanticAttributes.js +35 -3
  36. package/build/cjs/semanticAttributes.js.map +1 -1
  37. package/build/cjs/tracing/ai/gen-ai-attributes.js +9 -65
  38. package/build/cjs/tracing/ai/gen-ai-attributes.js.map +1 -1
  39. package/build/cjs/tracing/ai/utils.js +50 -0
  40. package/build/cjs/tracing/ai/utils.js.map +1 -1
  41. package/build/cjs/tracing/anthropic-ai/index.js +1 -12
  42. package/build/cjs/tracing/anthropic-ai/index.js.map +1 -1
  43. package/build/cjs/tracing/anthropic-ai/streaming.js +2 -100
  44. package/build/cjs/tracing/anthropic-ai/streaming.js.map +1 -1
  45. package/build/cjs/tracing/dynamicSamplingContext.js +2 -1
  46. package/build/cjs/tracing/dynamicSamplingContext.js.map +1 -1
  47. package/build/cjs/tracing/google-genai/constants.js +1 -6
  48. package/build/cjs/tracing/google-genai/constants.js.map +1 -1
  49. package/build/cjs/tracing/google-genai/index.js +24 -30
  50. package/build/cjs/tracing/google-genai/index.js.map +1 -1
  51. package/build/cjs/tracing/google-genai/streaming.js +2 -23
  52. package/build/cjs/tracing/google-genai/streaming.js.map +1 -1
  53. package/build/cjs/tracing/langchain/embeddings.js +132 -0
  54. package/build/cjs/tracing/langchain/embeddings.js.map +1 -0
  55. package/build/cjs/tracing/langchain/index.js.map +1 -1
  56. package/build/cjs/tracing/openai/index.js +2 -29
  57. package/build/cjs/tracing/openai/index.js.map +1 -1
  58. package/build/cjs/tracing/openai/streaming.js +3 -34
  59. package/build/cjs/tracing/openai/streaming.js.map +1 -1
  60. package/build/cjs/tracing/openai/utils.js +78 -204
  61. package/build/cjs/tracing/openai/utils.js.map +1 -1
  62. package/build/cjs/tracing/sentryNonRecordingSpan.js +7 -0
  63. package/build/cjs/tracing/sentryNonRecordingSpan.js.map +1 -1
  64. package/build/cjs/tracing/sentrySpan.js +39 -0
  65. package/build/cjs/tracing/sentrySpan.js.map +1 -1
  66. package/build/cjs/tracing/spans/beforeSendSpan.js +43 -0
  67. package/build/cjs/tracing/spans/beforeSendSpan.js.map +1 -0
  68. package/build/cjs/tracing/spans/captureSpan.js +126 -0
  69. package/build/cjs/tracing/spans/captureSpan.js.map +1 -0
  70. package/build/cjs/tracing/spans/envelope.js +38 -0
  71. package/build/cjs/tracing/spans/envelope.js.map +1 -0
  72. package/build/cjs/tracing/spans/estimateSize.js +41 -0
  73. package/build/cjs/tracing/spans/estimateSize.js.map +1 -0
  74. package/build/cjs/tracing/spans/hasSpanStreamingEnabled.js +11 -0
  75. package/build/cjs/tracing/spans/hasSpanStreamingEnabled.js.map +1 -0
  76. package/build/cjs/tracing/spans/spanBuffer.js +158 -0
  77. package/build/cjs/tracing/spans/spanBuffer.js.map +1 -0
  78. package/build/cjs/tracing/trace.js +83 -13
  79. package/build/cjs/tracing/trace.js.map +1 -1
  80. package/build/cjs/tracing/vercel-ai/utils.js +1 -4
  81. package/build/cjs/tracing/vercel-ai/utils.js.map +1 -1
  82. package/build/cjs/utils/featureFlags.js +6 -0
  83. package/build/cjs/utils/featureFlags.js.map +1 -1
  84. package/build/cjs/utils/object.js +33 -0
  85. package/build/cjs/utils/object.js.map +1 -1
  86. package/build/cjs/utils/spanUtils.js +116 -13
  87. package/build/cjs/utils/spanUtils.js.map +1 -1
  88. package/build/cjs/utils/stacktrace.js +3 -1
  89. package/build/cjs/utils/stacktrace.js.map +1 -1
  90. package/build/cjs/utils/string.js +3 -0
  91. package/build/cjs/utils/string.js.map +1 -1
  92. package/build/cjs/utils/version.js +1 -1
  93. package/build/esm/attributes.js +43 -1
  94. package/build/esm/attributes.js.map +1 -1
  95. package/build/esm/client.js +8 -1
  96. package/build/esm/client.js.map +1 -1
  97. package/build/esm/envelope.js +2 -1
  98. package/build/esm/envelope.js.map +1 -1
  99. package/build/esm/index.js +10 -2
  100. package/build/esm/index.js.map +1 -1
  101. package/build/esm/integration.js +6 -0
  102. package/build/esm/integration.js.map +1 -1
  103. package/build/esm/integrations/express/index.js +202 -0
  104. package/build/esm/integrations/express/index.js.map +1 -0
  105. package/build/esm/integrations/express/patch-layer.js +249 -0
  106. package/build/esm/integrations/express/patch-layer.js.map +1 -0
  107. package/build/esm/integrations/express/request-layer-store.js +22 -0
  108. package/build/esm/integrations/express/request-layer-store.js.map +1 -0
  109. package/build/esm/integrations/express/set-sdk-processing-metadata.js +15 -0
  110. package/build/esm/integrations/express/set-sdk-processing-metadata.js.map +1 -0
  111. package/build/esm/integrations/express/types.js +10 -0
  112. package/build/esm/integrations/express/types.js.map +1 -0
  113. package/build/esm/integrations/express/utils.js +225 -0
  114. package/build/esm/integrations/express/utils.js.map +1 -0
  115. package/build/esm/integrations/mcp-server/correlation.js +5 -1
  116. package/build/esm/integrations/mcp-server/correlation.js.map +1 -1
  117. package/build/esm/integrations/mcp-server/handlers.js +18 -10
  118. package/build/esm/integrations/mcp-server/handlers.js.map +1 -1
  119. package/build/esm/integrations/mcp-server/index.js +2 -1
  120. package/build/esm/integrations/mcp-server/index.js.map +1 -1
  121. package/build/esm/integrations/mcp-server/transport.js +1 -1
  122. package/build/esm/integrations/mcp-server/transport.js.map +1 -1
  123. package/build/esm/integrations/mcp-server/validation.js +7 -5
  124. package/build/esm/integrations/mcp-server/validation.js.map +1 -1
  125. package/build/esm/integrations/spanStreaming.js +46 -0
  126. package/build/esm/integrations/spanStreaming.js.map +1 -0
  127. package/build/esm/package.json +1 -1
  128. package/build/esm/semanticAttributes.js +26 -4
  129. package/build/esm/semanticAttributes.js.map +1 -1
  130. package/build/esm/tracing/ai/gen-ai-attributes.js +8 -56
  131. package/build/esm/tracing/ai/gen-ai-attributes.js.map +1 -1
  132. package/build/esm/tracing/ai/utils.js +51 -2
  133. package/build/esm/tracing/ai/utils.js.map +1 -1
  134. package/build/esm/tracing/anthropic-ai/index.js +2 -13
  135. package/build/esm/tracing/anthropic-ai/index.js.map +1 -1
  136. package/build/esm/tracing/anthropic-ai/streaming.js +3 -101
  137. package/build/esm/tracing/anthropic-ai/streaming.js.map +1 -1
  138. package/build/esm/tracing/dynamicSamplingContext.js +2 -1
  139. package/build/esm/tracing/dynamicSamplingContext.js.map +1 -1
  140. package/build/esm/tracing/google-genai/constants.js +2 -5
  141. package/build/esm/tracing/google-genai/constants.js.map +1 -1
  142. package/build/esm/tracing/google-genai/index.js +25 -31
  143. package/build/esm/tracing/google-genai/index.js.map +1 -1
  144. package/build/esm/tracing/google-genai/streaming.js +2 -23
  145. package/build/esm/tracing/google-genai/streaming.js.map +1 -1
  146. package/build/esm/tracing/langchain/embeddings.js +129 -0
  147. package/build/esm/tracing/langchain/embeddings.js.map +1 -0
  148. package/build/esm/tracing/langchain/index.js.map +1 -1
  149. package/build/esm/tracing/openai/index.js +3 -30
  150. package/build/esm/tracing/openai/index.js.map +1 -1
  151. package/build/esm/tracing/openai/streaming.js +4 -35
  152. package/build/esm/tracing/openai/streaming.js.map +1 -1
  153. package/build/esm/tracing/openai/utils.js +79 -196
  154. package/build/esm/tracing/openai/utils.js.map +1 -1
  155. package/build/esm/tracing/sentryNonRecordingSpan.js +7 -0
  156. package/build/esm/tracing/sentryNonRecordingSpan.js.map +1 -1
  157. package/build/esm/tracing/sentrySpan.js +40 -1
  158. package/build/esm/tracing/sentrySpan.js.map +1 -1
  159. package/build/esm/tracing/spans/beforeSendSpan.js +40 -0
  160. package/build/esm/tracing/spans/beforeSendSpan.js.map +1 -0
  161. package/build/esm/tracing/spans/captureSpan.js +122 -0
  162. package/build/esm/tracing/spans/captureSpan.js.map +1 -0
  163. package/build/esm/tracing/spans/envelope.js +36 -0
  164. package/build/esm/tracing/spans/envelope.js.map +1 -0
  165. package/build/esm/tracing/spans/estimateSize.js +39 -0
  166. package/build/esm/tracing/spans/estimateSize.js.map +1 -0
  167. package/build/esm/tracing/spans/hasSpanStreamingEnabled.js +9 -0
  168. package/build/esm/tracing/spans/hasSpanStreamingEnabled.js.map +1 -0
  169. package/build/esm/tracing/spans/spanBuffer.js +156 -0
  170. package/build/esm/tracing/spans/spanBuffer.js.map +1 -0
  171. package/build/esm/tracing/trace.js +84 -14
  172. package/build/esm/tracing/trace.js.map +1 -1
  173. package/build/esm/tracing/vercel-ai/utils.js +2 -5
  174. package/build/esm/tracing/vercel-ai/utils.js.map +1 -1
  175. package/build/esm/utils/featureFlags.js +6 -0
  176. package/build/esm/utils/featureFlags.js.map +1 -1
  177. package/build/esm/utils/object.js +33 -1
  178. package/build/esm/utils/object.js.map +1 -1
  179. package/build/esm/utils/spanUtils.js +112 -14
  180. package/build/esm/utils/spanUtils.js.map +1 -1
  181. package/build/esm/utils/stacktrace.js +3 -1
  182. package/build/esm/utils/stacktrace.js.map +1 -1
  183. package/build/esm/utils/string.js +3 -0
  184. package/build/esm/utils/string.js.map +1 -1
  185. package/build/esm/utils/version.js +1 -1
  186. package/build/types/attributes.d.ts +5 -0
  187. package/build/types/attributes.d.ts.map +1 -1
  188. package/build/types/client.d.ts +35 -1
  189. package/build/types/client.d.ts.map +1 -1
  190. package/build/types/envelope.d.ts.map +1 -1
  191. package/build/types/index.d.ts +12 -4
  192. package/build/types/index.d.ts.map +1 -1
  193. package/build/types/integration.d.ts.map +1 -1
  194. package/build/types/integrations/express/index.d.ts +75 -0
  195. package/build/types/integrations/express/index.d.ts.map +1 -0
  196. package/build/types/integrations/express/patch-layer.d.ts +32 -0
  197. package/build/types/integrations/express/patch-layer.d.ts.map +1 -0
  198. package/build/types/integrations/express/request-layer-store.d.ts +32 -0
  199. package/build/types/integrations/express/request-layer-store.d.ts.map +1 -0
  200. package/build/types/integrations/express/set-sdk-processing-metadata.d.ts +35 -0
  201. package/build/types/integrations/express/set-sdk-processing-metadata.d.ts.map +1 -0
  202. package/build/types/integrations/express/types.d.ts +154 -0
  203. package/build/types/integrations/express/types.d.ts.map +1 -0
  204. package/build/types/integrations/express/utils.d.ts +93 -0
  205. package/build/types/integrations/express/utils.d.ts.map +1 -0
  206. package/build/types/integrations/mcp-server/correlation.d.ts +2 -1
  207. package/build/types/integrations/mcp-server/correlation.d.ts.map +1 -1
  208. package/build/types/integrations/mcp-server/handlers.d.ts +9 -4
  209. package/build/types/integrations/mcp-server/handlers.d.ts.map +1 -1
  210. package/build/types/integrations/mcp-server/index.d.ts +2 -1
  211. package/build/types/integrations/mcp-server/index.d.ts.map +1 -1
  212. package/build/types/integrations/mcp-server/types.d.ts +40 -7
  213. package/build/types/integrations/mcp-server/types.d.ts.map +1 -1
  214. package/build/types/integrations/mcp-server/validation.d.ts +4 -1
  215. package/build/types/integrations/mcp-server/validation.d.ts.map +1 -1
  216. package/build/types/integrations/spanStreaming.d.ts +2 -0
  217. package/build/types/integrations/spanStreaming.d.ts.map +1 -0
  218. package/build/types/semanticAttributes.d.ts +23 -3
  219. package/build/types/semanticAttributes.d.ts.map +1 -1
  220. package/build/types/tracing/ai/gen-ai-attributes.d.ts +6 -38
  221. package/build/types/tracing/ai/gen-ai-attributes.d.ts.map +1 -1
  222. package/build/types/tracing/ai/utils.d.ts +21 -2
  223. package/build/types/tracing/ai/utils.d.ts.map +1 -1
  224. package/build/types/tracing/anthropic-ai/index.d.ts.map +1 -1
  225. package/build/types/tracing/anthropic-ai/streaming.d.ts.map +1 -1
  226. package/build/types/tracing/dynamicSamplingContext.d.ts.map +1 -1
  227. package/build/types/tracing/google-genai/constants.d.ts +1 -3
  228. package/build/types/tracing/google-genai/constants.d.ts.map +1 -1
  229. package/build/types/tracing/google-genai/index.d.ts.map +1 -1
  230. package/build/types/tracing/google-genai/streaming.d.ts.map +1 -1
  231. package/build/types/tracing/index.d.ts +1 -0
  232. package/build/types/tracing/index.d.ts.map +1 -1
  233. package/build/types/tracing/langchain/embeddings.d.ts +27 -0
  234. package/build/types/tracing/langchain/embeddings.d.ts.map +1 -0
  235. package/build/types/tracing/langchain/index.d.ts +1 -0
  236. package/build/types/tracing/langchain/index.d.ts.map +1 -1
  237. package/build/types/tracing/openai/index.d.ts.map +1 -1
  238. package/build/types/tracing/openai/streaming.d.ts.map +1 -1
  239. package/build/types/tracing/openai/utils.d.ts +4 -49
  240. package/build/types/tracing/openai/utils.d.ts.map +1 -1
  241. package/build/types/tracing/sentryNonRecordingSpan.d.ts +12 -1
  242. package/build/types/tracing/sentryNonRecordingSpan.d.ts.map +1 -1
  243. package/build/types/tracing/sentrySpan.d.ts +10 -1
  244. package/build/types/tracing/sentrySpan.d.ts.map +1 -1
  245. package/build/types/tracing/spans/beforeSendSpan.d.ts +35 -0
  246. package/build/types/tracing/spans/beforeSendSpan.d.ts.map +1 -0
  247. package/build/types/tracing/spans/captureSpan.d.ts +26 -0
  248. package/build/types/tracing/spans/captureSpan.d.ts.map +1 -0
  249. package/build/types/tracing/spans/envelope.d.ts +8 -0
  250. package/build/types/tracing/spans/envelope.d.ts.map +1 -0
  251. package/build/types/tracing/spans/estimateSize.d.ts +12 -0
  252. package/build/types/tracing/spans/estimateSize.d.ts.map +1 -0
  253. package/build/types/tracing/spans/hasSpanStreamingEnabled.d.ts +6 -0
  254. package/build/types/tracing/spans/hasSpanStreamingEnabled.d.ts.map +1 -0
  255. package/build/types/tracing/spans/spanBuffer.d.ts +60 -0
  256. package/build/types/tracing/spans/spanBuffer.d.ts.map +1 -0
  257. package/build/types/tracing/trace.d.ts.map +1 -1
  258. package/build/types/tracing/vercel-ai/utils.d.ts.map +1 -1
  259. package/build/types/types-hoist/envelope.d.ts +22 -2
  260. package/build/types/types-hoist/envelope.d.ts.map +1 -1
  261. package/build/types/types-hoist/integration.d.ts +8 -0
  262. package/build/types/types-hoist/integration.d.ts.map +1 -1
  263. package/build/types/types-hoist/link.d.ts +2 -2
  264. package/build/types/types-hoist/link.d.ts.map +1 -1
  265. package/build/types/types-hoist/options.d.ts +26 -2
  266. package/build/types/types-hoist/options.d.ts.map +1 -1
  267. package/build/types/types-hoist/span.d.ts +35 -0
  268. package/build/types/types-hoist/span.d.ts.map +1 -1
  269. package/build/types/utils/featureFlags.d.ts.map +1 -1
  270. package/build/types/utils/object.d.ts +10 -0
  271. package/build/types/utils/object.d.ts.map +1 -1
  272. package/build/types/utils/spanUtils.d.ts +27 -2
  273. package/build/types/utils/spanUtils.d.ts.map +1 -1
  274. package/build/types/utils/stacktrace.d.ts.map +1 -1
  275. package/build/types/utils/string.d.ts +2 -2
  276. package/build/types/utils/string.d.ts.map +1 -1
  277. package/build/types-ts3.8/attributes.d.ts +5 -0
  278. package/build/types-ts3.8/client.d.ts +35 -1
  279. package/build/types-ts3.8/index.d.ts +12 -4
  280. package/build/types-ts3.8/integrations/express/index.d.ts +75 -0
  281. package/build/types-ts3.8/integrations/express/patch-layer.d.ts +32 -0
  282. package/build/types-ts3.8/integrations/express/request-layer-store.d.ts +32 -0
  283. package/build/types-ts3.8/integrations/express/set-sdk-processing-metadata.d.ts +35 -0
  284. package/build/types-ts3.8/integrations/express/types.d.ts +154 -0
  285. package/build/types-ts3.8/integrations/express/utils.d.ts +96 -0
  286. package/build/types-ts3.8/integrations/mcp-server/correlation.d.ts +2 -1
  287. package/build/types-ts3.8/integrations/mcp-server/handlers.d.ts +9 -4
  288. package/build/types-ts3.8/integrations/mcp-server/index.d.ts +2 -1
  289. package/build/types-ts3.8/integrations/mcp-server/types.d.ts +40 -7
  290. package/build/types-ts3.8/integrations/mcp-server/validation.d.ts +4 -1
  291. package/build/types-ts3.8/integrations/spanStreaming.d.ts +2 -0
  292. package/build/types-ts3.8/semanticAttributes.d.ts +23 -3
  293. package/build/types-ts3.8/tracing/ai/gen-ai-attributes.d.ts +6 -38
  294. package/build/types-ts3.8/tracing/ai/utils.d.ts +21 -2
  295. package/build/types-ts3.8/tracing/google-genai/constants.d.ts +1 -3
  296. package/build/types-ts3.8/tracing/index.d.ts +1 -0
  297. package/build/types-ts3.8/tracing/langchain/embeddings.d.ts +27 -0
  298. package/build/types-ts3.8/tracing/langchain/index.d.ts +1 -0
  299. package/build/types-ts3.8/tracing/openai/utils.d.ts +4 -49
  300. package/build/types-ts3.8/tracing/sentryNonRecordingSpan.d.ts +12 -1
  301. package/build/types-ts3.8/tracing/sentrySpan.d.ts +10 -1
  302. package/build/types-ts3.8/tracing/spans/beforeSendSpan.d.ts +35 -0
  303. package/build/types-ts3.8/tracing/spans/captureSpan.d.ts +26 -0
  304. package/build/types-ts3.8/tracing/spans/envelope.d.ts +8 -0
  305. package/build/types-ts3.8/tracing/spans/estimateSize.d.ts +12 -0
  306. package/build/types-ts3.8/tracing/spans/hasSpanStreamingEnabled.d.ts +6 -0
  307. package/build/types-ts3.8/tracing/spans/spanBuffer.d.ts +60 -0
  308. package/build/types-ts3.8/types-hoist/envelope.d.ts +22 -2
  309. package/build/types-ts3.8/types-hoist/integration.d.ts +8 -0
  310. package/build/types-ts3.8/types-hoist/link.d.ts +2 -2
  311. package/build/types-ts3.8/types-hoist/options.d.ts +26 -2
  312. package/build/types-ts3.8/types-hoist/span.d.ts +35 -0
  313. package/build/types-ts3.8/utils/object.d.ts +10 -0
  314. package/build/types-ts3.8/utils/spanUtils.d.ts +27 -2
  315. package/build/types-ts3.8/utils/string.d.ts +2 -2
  316. package/package.json +1 -1
@@ -204,24 +204,9 @@ const GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE = 'gen_ai.usage.input_tokens.ca
204
204
  const GEN_AI_INVOKE_AGENT_OPERATION_ATTRIBUTE = 'gen_ai.invoke_agent';
205
205
 
206
206
  /**
207
- * The span operation name for generating text
207
+ * The span operation name for generating content
208
208
  */
209
- const GEN_AI_GENERATE_TEXT_DO_GENERATE_OPERATION_ATTRIBUTE = 'gen_ai.generate_text';
210
-
211
- /**
212
- * The span operation name for streaming text
213
- */
214
- const GEN_AI_STREAM_TEXT_DO_STREAM_OPERATION_ATTRIBUTE = 'gen_ai.stream_text';
215
-
216
- /**
217
- * The span operation name for generating object
218
- */
219
- const GEN_AI_GENERATE_OBJECT_DO_GENERATE_OPERATION_ATTRIBUTE = 'gen_ai.generate_object';
220
-
221
- /**
222
- * The span operation name for streaming object
223
- */
224
- const GEN_AI_STREAM_OBJECT_DO_STREAM_OPERATION_ATTRIBUTE = 'gen_ai.stream_object';
209
+ const GEN_AI_GENERATE_CONTENT_OPERATION_ATTRIBUTE = 'gen_ai.generate_content';
225
210
 
226
211
  /**
227
212
  * The embeddings input
@@ -229,6 +214,11 @@ const GEN_AI_STREAM_OBJECT_DO_STREAM_OPERATION_ATTRIBUTE = 'gen_ai.stream_object
229
214
  */
230
215
  const GEN_AI_EMBEDDINGS_INPUT_ATTRIBUTE = 'gen_ai.embeddings.input';
231
216
 
217
+ /**
218
+ * The span operation for embeddings
219
+ */
220
+ const GEN_AI_EMBEDDINGS_OPERATION_ATTRIBUTE = 'gen_ai.embeddings';
221
+
232
222
  /**
233
223
  * The span operation name for embedding
234
224
  */
@@ -280,53 +270,14 @@ const GEN_AI_TOOL_OUTPUT_ATTRIBUTE = 'gen_ai.tool.output';
280
270
  */
281
271
  const GEN_AI_TOOL_DESCRIPTION_ATTRIBUTE = 'gen_ai.tool.description';
282
272
 
283
- // =============================================================================
284
- // OPENAI-SPECIFIC ATTRIBUTES
285
- // =============================================================================
286
-
287
- /**
288
- * The response ID from OpenAI
289
- */
290
- const OPENAI_RESPONSE_ID_ATTRIBUTE = 'openai.response.id';
291
-
292
- /**
293
- * The response model from OpenAI
294
- */
295
- const OPENAI_RESPONSE_MODEL_ATTRIBUTE = 'openai.response.model';
296
-
297
- /**
298
- * The response timestamp from OpenAI (ISO string)
299
- */
300
- const OPENAI_RESPONSE_TIMESTAMP_ATTRIBUTE = 'openai.response.timestamp';
301
-
302
- /**
303
- * The number of completion tokens used
304
- */
305
- const OPENAI_USAGE_COMPLETION_TOKENS_ATTRIBUTE = 'openai.usage.completion_tokens';
306
-
307
- /**
308
- * The number of prompt tokens used
309
- */
310
- const OPENAI_USAGE_PROMPT_TOKENS_ATTRIBUTE = 'openai.usage.prompt_tokens';
311
-
312
- // =============================================================================
313
- // ANTHROPIC AI OPERATIONS
314
- // =============================================================================
315
-
316
- /**
317
- * The response timestamp from Anthropic AI (ISO string)
318
- */
319
- const ANTHROPIC_AI_RESPONSE_TIMESTAMP_ATTRIBUTE = 'anthropic.response.timestamp';
320
-
321
- exports.ANTHROPIC_AI_RESPONSE_TIMESTAMP_ATTRIBUTE = ANTHROPIC_AI_RESPONSE_TIMESTAMP_ATTRIBUTE;
322
273
  exports.GEN_AI_AGENT_NAME_ATTRIBUTE = GEN_AI_AGENT_NAME_ATTRIBUTE;
323
274
  exports.GEN_AI_CONVERSATION_ID_ATTRIBUTE = GEN_AI_CONVERSATION_ID_ATTRIBUTE;
324
275
  exports.GEN_AI_EMBEDDINGS_INPUT_ATTRIBUTE = GEN_AI_EMBEDDINGS_INPUT_ATTRIBUTE;
276
+ exports.GEN_AI_EMBEDDINGS_OPERATION_ATTRIBUTE = GEN_AI_EMBEDDINGS_OPERATION_ATTRIBUTE;
325
277
  exports.GEN_AI_EMBED_DO_EMBED_OPERATION_ATTRIBUTE = GEN_AI_EMBED_DO_EMBED_OPERATION_ATTRIBUTE;
326
278
  exports.GEN_AI_EMBED_MANY_DO_EMBED_OPERATION_ATTRIBUTE = GEN_AI_EMBED_MANY_DO_EMBED_OPERATION_ATTRIBUTE;
327
279
  exports.GEN_AI_EXECUTE_TOOL_OPERATION_ATTRIBUTE = GEN_AI_EXECUTE_TOOL_OPERATION_ATTRIBUTE;
328
- exports.GEN_AI_GENERATE_OBJECT_DO_GENERATE_OPERATION_ATTRIBUTE = GEN_AI_GENERATE_OBJECT_DO_GENERATE_OPERATION_ATTRIBUTE;
329
- exports.GEN_AI_GENERATE_TEXT_DO_GENERATE_OPERATION_ATTRIBUTE = GEN_AI_GENERATE_TEXT_DO_GENERATE_OPERATION_ATTRIBUTE;
280
+ exports.GEN_AI_GENERATE_CONTENT_OPERATION_ATTRIBUTE = GEN_AI_GENERATE_CONTENT_OPERATION_ATTRIBUTE;
330
281
  exports.GEN_AI_INPUT_MESSAGES_ATTRIBUTE = GEN_AI_INPUT_MESSAGES_ATTRIBUTE;
331
282
  exports.GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE = GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE;
332
283
  exports.GEN_AI_INVOKE_AGENT_OPERATION_ATTRIBUTE = GEN_AI_INVOKE_AGENT_OPERATION_ATTRIBUTE;
@@ -353,8 +304,6 @@ exports.GEN_AI_RESPONSE_STOP_REASON_ATTRIBUTE = GEN_AI_RESPONSE_STOP_REASON_ATTR
353
304
  exports.GEN_AI_RESPONSE_STREAMING_ATTRIBUTE = GEN_AI_RESPONSE_STREAMING_ATTRIBUTE;
354
305
  exports.GEN_AI_RESPONSE_TEXT_ATTRIBUTE = GEN_AI_RESPONSE_TEXT_ATTRIBUTE;
355
306
  exports.GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE = GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE;
356
- exports.GEN_AI_STREAM_OBJECT_DO_STREAM_OPERATION_ATTRIBUTE = GEN_AI_STREAM_OBJECT_DO_STREAM_OPERATION_ATTRIBUTE;
357
- exports.GEN_AI_STREAM_TEXT_DO_STREAM_OPERATION_ATTRIBUTE = GEN_AI_STREAM_TEXT_DO_STREAM_OPERATION_ATTRIBUTE;
358
307
  exports.GEN_AI_SYSTEM_ATTRIBUTE = GEN_AI_SYSTEM_ATTRIBUTE;
359
308
  exports.GEN_AI_SYSTEM_INSTRUCTIONS_ATTRIBUTE = GEN_AI_SYSTEM_INSTRUCTIONS_ATTRIBUTE;
360
309
  exports.GEN_AI_TOOL_CALL_ID_ATTRIBUTE = GEN_AI_TOOL_CALL_ID_ATTRIBUTE;
@@ -370,9 +319,4 @@ exports.GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE = GEN_AI_USAGE_INPUT_TOKENS_C
370
319
  exports.GEN_AI_USAGE_INPUT_TOKENS_CACHE_WRITE_ATTRIBUTE = GEN_AI_USAGE_INPUT_TOKENS_CACHE_WRITE_ATTRIBUTE;
371
320
  exports.GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE = GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE;
372
321
  exports.GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE = GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE;
373
- exports.OPENAI_RESPONSE_ID_ATTRIBUTE = OPENAI_RESPONSE_ID_ATTRIBUTE;
374
- exports.OPENAI_RESPONSE_MODEL_ATTRIBUTE = OPENAI_RESPONSE_MODEL_ATTRIBUTE;
375
- exports.OPENAI_RESPONSE_TIMESTAMP_ATTRIBUTE = OPENAI_RESPONSE_TIMESTAMP_ATTRIBUTE;
376
- exports.OPENAI_USAGE_COMPLETION_TOKENS_ATTRIBUTE = OPENAI_USAGE_COMPLETION_TOKENS_ATTRIBUTE;
377
- exports.OPENAI_USAGE_PROMPT_TOKENS_ATTRIBUTE = OPENAI_USAGE_PROMPT_TOKENS_ATTRIBUTE;
378
322
  //# sourceMappingURL=gen-ai-attributes.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"gen-ai-attributes.js","sources":["../../../../src/tracing/ai/gen-ai-attributes.ts"],"sourcesContent":["/**\n * OpenAI Integration Telemetry Attributes\n * Based on OpenTelemetry Semantic Conventions for Generative AI\n * @see https://opentelemetry.io/docs/specs/semconv/gen-ai/\n */\n\n// =============================================================================\n// OPENTELEMETRY SEMANTIC CONVENTIONS FOR GENAI\n// =============================================================================\n\n/**\n * The input messages sent to the model\n */\nexport const GEN_AI_PROMPT_ATTRIBUTE = 'gen_ai.prompt';\n\n/**\n * The Generative AI system being used\n * For OpenAI, this should always be \"openai\"\n */\nexport const GEN_AI_SYSTEM_ATTRIBUTE = 'gen_ai.system';\n\n/**\n * The name of the model as requested\n * Examples: \"gpt-4\", \"gpt-3.5-turbo\"\n */\nexport const GEN_AI_REQUEST_MODEL_ATTRIBUTE = 'gen_ai.request.model';\n\n/**\n * Whether streaming was enabled for the request\n */\nexport const GEN_AI_REQUEST_STREAM_ATTRIBUTE = 'gen_ai.request.stream';\n\n/**\n * The temperature setting for the model request\n */\nexport const GEN_AI_REQUEST_TEMPERATURE_ATTRIBUTE = 'gen_ai.request.temperature';\n\n/**\n * The maximum number of tokens requested\n */\nexport const GEN_AI_REQUEST_MAX_TOKENS_ATTRIBUTE = 'gen_ai.request.max_tokens';\n\n/**\n * The frequency penalty setting for the model request\n */\nexport const GEN_AI_REQUEST_FREQUENCY_PENALTY_ATTRIBUTE = 'gen_ai.request.frequency_penalty';\n\n/**\n * The presence penalty setting for the model request\n */\nexport const GEN_AI_REQUEST_PRESENCE_PENALTY_ATTRIBUTE = 'gen_ai.request.presence_penalty';\n\n/**\n * The top_p (nucleus sampling) setting for the model request\n */\nexport const GEN_AI_REQUEST_TOP_P_ATTRIBUTE = 'gen_ai.request.top_p';\n\n/**\n * The top_k setting for the model request\n */\nexport const GEN_AI_REQUEST_TOP_K_ATTRIBUTE = 'gen_ai.request.top_k';\n\n/**\n * Stop sequences for the model request\n */\nexport const GEN_AI_REQUEST_STOP_SEQUENCES_ATTRIBUTE = 'gen_ai.request.stop_sequences';\n\n/**\n * The encoding format for the model request\n */\nexport const GEN_AI_REQUEST_ENCODING_FORMAT_ATTRIBUTE = 'gen_ai.request.encoding_format';\n\n/**\n * The dimensions for the model request\n */\nexport const GEN_AI_REQUEST_DIMENSIONS_ATTRIBUTE = 'gen_ai.request.dimensions';\n\n/**\n * Array of reasons why the model stopped generating tokens\n */\nexport const GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE = 'gen_ai.response.finish_reasons';\n\n/**\n * The name of the model that generated the response\n */\nexport const GEN_AI_RESPONSE_MODEL_ATTRIBUTE = 'gen_ai.response.model';\n\n/**\n * The unique identifier for the response\n */\nexport const GEN_AI_RESPONSE_ID_ATTRIBUTE = 'gen_ai.response.id';\n\n/**\n * The reason why the model stopped generating tokens\n */\nexport const GEN_AI_RESPONSE_STOP_REASON_ATTRIBUTE = 'gen_ai.response.stop_reason';\n\n/**\n * The number of tokens used in the prompt\n */\nexport const GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE = 'gen_ai.usage.input_tokens';\n\n/**\n * The number of tokens used in the response\n */\nexport const GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE = 'gen_ai.usage.output_tokens';\n\n/**\n * The total number of tokens used (input + output)\n */\nexport const GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE = 'gen_ai.usage.total_tokens';\n\n/**\n * The operation name\n */\nexport const GEN_AI_OPERATION_NAME_ATTRIBUTE = 'gen_ai.operation.name';\n\n/**\n * Original length of messages array, used to indicate truncations had occured\n */\nexport const GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE = 'sentry.sdk_meta.gen_ai.input.messages.original_length';\n\n/**\n * The prompt messages\n * Only recorded when recordInputs is enabled\n */\nexport const GEN_AI_INPUT_MESSAGES_ATTRIBUTE = 'gen_ai.input.messages';\n\n/**\n * The model's response messages including text and tool calls\n * Only recorded when recordOutputs is enabled\n * Format: stringified array of message objects with role, parts, and finish_reason\n * @see https://opentelemetry.io/docs/specs/semconv/registry/attributes/gen-ai/#gen-ai-output-messages\n */\nexport const GEN_AI_OUTPUT_MESSAGES_ATTRIBUTE = 'gen_ai.output.messages';\n\n/**\n * The system instructions extracted from system messages\n * Only recorded when recordInputs is enabled\n * According to OpenTelemetry spec: https://opentelemetry.io/docs/specs/semconv/registry/attributes/gen-ai/#gen-ai-system-instructions\n */\nexport const GEN_AI_SYSTEM_INSTRUCTIONS_ATTRIBUTE = 'gen_ai.system_instructions';\n\n/**\n * The response text\n * Only recorded when recordOutputs is enabled\n */\nexport const GEN_AI_RESPONSE_TEXT_ATTRIBUTE = 'gen_ai.response.text';\n\n/**\n * The available tools from incoming request\n * Only recorded when recordInputs is enabled\n */\nexport const GEN_AI_REQUEST_AVAILABLE_TOOLS_ATTRIBUTE = 'gen_ai.request.available_tools';\n\n/**\n * Whether the response is a streaming response\n */\nexport const GEN_AI_RESPONSE_STREAMING_ATTRIBUTE = 'gen_ai.response.streaming';\n\n/**\n * The tool calls from the response\n * Only recorded when recordOutputs is enabled\n */\nexport const GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE = 'gen_ai.response.tool_calls';\n\n/**\n * The agent name\n */\nexport const GEN_AI_AGENT_NAME_ATTRIBUTE = 'gen_ai.agent.name';\n\n/**\n * The pipeline name\n */\nexport const GEN_AI_PIPELINE_NAME_ATTRIBUTE = 'gen_ai.pipeline.name';\n\n/**\n * The conversation ID for linking messages across API calls\n * For OpenAI Assistants API: thread_id\n * For LangGraph: configurable.thread_id\n */\nexport const GEN_AI_CONVERSATION_ID_ATTRIBUTE = 'gen_ai.conversation.id';\n\n/**\n * The number of cache creation input tokens used\n */\nexport const GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS_ATTRIBUTE = 'gen_ai.usage.cache_creation_input_tokens';\n\n/**\n * The number of cache read input tokens used\n */\nexport const GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS_ATTRIBUTE = 'gen_ai.usage.cache_read_input_tokens';\n\n/**\n * The number of cache write input tokens used\n */\nexport const GEN_AI_USAGE_INPUT_TOKENS_CACHE_WRITE_ATTRIBUTE = 'gen_ai.usage.input_tokens.cache_write';\n\n/**\n * The number of cached input tokens that were used\n */\nexport const GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE = 'gen_ai.usage.input_tokens.cached';\n\n/**\n * The span operation name for invoking an agent\n */\nexport const GEN_AI_INVOKE_AGENT_OPERATION_ATTRIBUTE = 'gen_ai.invoke_agent';\n\n/**\n * The span operation name for generating text\n */\nexport const GEN_AI_GENERATE_TEXT_DO_GENERATE_OPERATION_ATTRIBUTE = 'gen_ai.generate_text';\n\n/**\n * The span operation name for streaming text\n */\nexport const GEN_AI_STREAM_TEXT_DO_STREAM_OPERATION_ATTRIBUTE = 'gen_ai.stream_text';\n\n/**\n * The span operation name for generating object\n */\nexport const GEN_AI_GENERATE_OBJECT_DO_GENERATE_OPERATION_ATTRIBUTE = 'gen_ai.generate_object';\n\n/**\n * The span operation name for streaming object\n */\nexport const GEN_AI_STREAM_OBJECT_DO_STREAM_OPERATION_ATTRIBUTE = 'gen_ai.stream_object';\n\n/**\n * The embeddings input\n * Only recorded when recordInputs is enabled\n */\nexport const GEN_AI_EMBEDDINGS_INPUT_ATTRIBUTE = 'gen_ai.embeddings.input';\n\n/**\n * The span operation name for embedding\n */\nexport const GEN_AI_EMBED_DO_EMBED_OPERATION_ATTRIBUTE = 'gen_ai.embeddings';\n\n/**\n * The span operation name for embedding many\n */\nexport const GEN_AI_EMBED_MANY_DO_EMBED_OPERATION_ATTRIBUTE = 'gen_ai.embeddings';\n\n/**\n * The span operation name for reranking\n */\nexport const GEN_AI_RERANK_DO_RERANK_OPERATION_ATTRIBUTE = 'gen_ai.rerank';\n\n/**\n * The span operation name for executing a tool\n */\nexport const GEN_AI_EXECUTE_TOOL_OPERATION_ATTRIBUTE = 'gen_ai.execute_tool';\n\n/**\n * The tool name for tool call spans\n */\nexport const GEN_AI_TOOL_NAME_ATTRIBUTE = 'gen_ai.tool.name';\n\n/**\n * The tool call ID\n */\nexport const GEN_AI_TOOL_CALL_ID_ATTRIBUTE = 'gen_ai.tool.call.id';\n\n/**\n * The tool type (e.g., 'function')\n */\nexport const GEN_AI_TOOL_TYPE_ATTRIBUTE = 'gen_ai.tool.type';\n\n/**\n * The tool input/arguments\n */\nexport const GEN_AI_TOOL_INPUT_ATTRIBUTE = 'gen_ai.tool.input';\n\n/**\n * The tool output/result\n */\nexport const GEN_AI_TOOL_OUTPUT_ATTRIBUTE = 'gen_ai.tool.output';\n\n/**\n * The description of the tool being used\n * @see https://opentelemetry.io/docs/specs/semconv/registry/attributes/gen-ai/#gen-ai-tool-description\n */\nexport const GEN_AI_TOOL_DESCRIPTION_ATTRIBUTE = 'gen_ai.tool.description';\n\n// =============================================================================\n// OPENAI-SPECIFIC ATTRIBUTES\n// =============================================================================\n\n/**\n * The response ID from OpenAI\n */\nexport const OPENAI_RESPONSE_ID_ATTRIBUTE = 'openai.response.id';\n\n/**\n * The response model from OpenAI\n */\nexport const OPENAI_RESPONSE_MODEL_ATTRIBUTE = 'openai.response.model';\n\n/**\n * The response timestamp from OpenAI (ISO string)\n */\nexport const OPENAI_RESPONSE_TIMESTAMP_ATTRIBUTE = 'openai.response.timestamp';\n\n/**\n * The number of completion tokens used\n */\nexport const OPENAI_USAGE_COMPLETION_TOKENS_ATTRIBUTE = 'openai.usage.completion_tokens';\n\n/**\n * The number of prompt tokens used\n */\nexport const OPENAI_USAGE_PROMPT_TOKENS_ATTRIBUTE = 'openai.usage.prompt_tokens';\n\n// =============================================================================\n// ANTHROPIC AI OPERATIONS\n// =============================================================================\n\n/**\n * The response timestamp from Anthropic AI (ISO string)\n */\nexport const ANTHROPIC_AI_RESPONSE_TIMESTAMP_ATTRIBUTE = 'anthropic.response.timestamp';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"gen-ai-attributes.js","sources":["../../../../src/tracing/ai/gen-ai-attributes.ts"],"sourcesContent":["/**\n * OpenAI Integration Telemetry Attributes\n * Based on OpenTelemetry Semantic Conventions for Generative AI\n * @see https://opentelemetry.io/docs/specs/semconv/gen-ai/\n */\n\n// =============================================================================\n// OPENTELEMETRY SEMANTIC CONVENTIONS FOR GENAI\n// =============================================================================\n\n/**\n * The input messages sent to the model\n */\nexport const GEN_AI_PROMPT_ATTRIBUTE = 'gen_ai.prompt';\n\n/**\n * The Generative AI system being used\n * For OpenAI, this should always be \"openai\"\n */\nexport const GEN_AI_SYSTEM_ATTRIBUTE = 'gen_ai.system';\n\n/**\n * The name of the model as requested\n * Examples: \"gpt-4\", \"gpt-3.5-turbo\"\n */\nexport const GEN_AI_REQUEST_MODEL_ATTRIBUTE = 'gen_ai.request.model';\n\n/**\n * Whether streaming was enabled for the request\n */\nexport const GEN_AI_REQUEST_STREAM_ATTRIBUTE = 'gen_ai.request.stream';\n\n/**\n * The temperature setting for the model request\n */\nexport const GEN_AI_REQUEST_TEMPERATURE_ATTRIBUTE = 'gen_ai.request.temperature';\n\n/**\n * The maximum number of tokens requested\n */\nexport const GEN_AI_REQUEST_MAX_TOKENS_ATTRIBUTE = 'gen_ai.request.max_tokens';\n\n/**\n * The frequency penalty setting for the model request\n */\nexport const GEN_AI_REQUEST_FREQUENCY_PENALTY_ATTRIBUTE = 'gen_ai.request.frequency_penalty';\n\n/**\n * The presence penalty setting for the model request\n */\nexport const GEN_AI_REQUEST_PRESENCE_PENALTY_ATTRIBUTE = 'gen_ai.request.presence_penalty';\n\n/**\n * The top_p (nucleus sampling) setting for the model request\n */\nexport const GEN_AI_REQUEST_TOP_P_ATTRIBUTE = 'gen_ai.request.top_p';\n\n/**\n * The top_k setting for the model request\n */\nexport const GEN_AI_REQUEST_TOP_K_ATTRIBUTE = 'gen_ai.request.top_k';\n\n/**\n * Stop sequences for the model request\n */\nexport const GEN_AI_REQUEST_STOP_SEQUENCES_ATTRIBUTE = 'gen_ai.request.stop_sequences';\n\n/**\n * The encoding format for the model request\n */\nexport const GEN_AI_REQUEST_ENCODING_FORMAT_ATTRIBUTE = 'gen_ai.request.encoding_format';\n\n/**\n * The dimensions for the model request\n */\nexport const GEN_AI_REQUEST_DIMENSIONS_ATTRIBUTE = 'gen_ai.request.dimensions';\n\n/**\n * Array of reasons why the model stopped generating tokens\n */\nexport const GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE = 'gen_ai.response.finish_reasons';\n\n/**\n * The name of the model that generated the response\n */\nexport const GEN_AI_RESPONSE_MODEL_ATTRIBUTE = 'gen_ai.response.model';\n\n/**\n * The unique identifier for the response\n */\nexport const GEN_AI_RESPONSE_ID_ATTRIBUTE = 'gen_ai.response.id';\n\n/**\n * The reason why the model stopped generating tokens\n */\nexport const GEN_AI_RESPONSE_STOP_REASON_ATTRIBUTE = 'gen_ai.response.stop_reason';\n\n/**\n * The number of tokens used in the prompt\n */\nexport const GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE = 'gen_ai.usage.input_tokens';\n\n/**\n * The number of tokens used in the response\n */\nexport const GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE = 'gen_ai.usage.output_tokens';\n\n/**\n * The total number of tokens used (input + output)\n */\nexport const GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE = 'gen_ai.usage.total_tokens';\n\n/**\n * The operation name\n */\nexport const GEN_AI_OPERATION_NAME_ATTRIBUTE = 'gen_ai.operation.name';\n\n/**\n * Original length of messages array, used to indicate truncations had occured\n */\nexport const GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE = 'sentry.sdk_meta.gen_ai.input.messages.original_length';\n\n/**\n * The prompt messages\n * Only recorded when recordInputs is enabled\n */\nexport const GEN_AI_INPUT_MESSAGES_ATTRIBUTE = 'gen_ai.input.messages';\n\n/**\n * The model's response messages including text and tool calls\n * Only recorded when recordOutputs is enabled\n * Format: stringified array of message objects with role, parts, and finish_reason\n * @see https://opentelemetry.io/docs/specs/semconv/registry/attributes/gen-ai/#gen-ai-output-messages\n */\nexport const GEN_AI_OUTPUT_MESSAGES_ATTRIBUTE = 'gen_ai.output.messages';\n\n/**\n * The system instructions extracted from system messages\n * Only recorded when recordInputs is enabled\n * According to OpenTelemetry spec: https://opentelemetry.io/docs/specs/semconv/registry/attributes/gen-ai/#gen-ai-system-instructions\n */\nexport const GEN_AI_SYSTEM_INSTRUCTIONS_ATTRIBUTE = 'gen_ai.system_instructions';\n\n/**\n * The response text\n * Only recorded when recordOutputs is enabled\n */\nexport const GEN_AI_RESPONSE_TEXT_ATTRIBUTE = 'gen_ai.response.text';\n\n/**\n * The available tools from incoming request\n * Only recorded when recordInputs is enabled\n */\nexport const GEN_AI_REQUEST_AVAILABLE_TOOLS_ATTRIBUTE = 'gen_ai.request.available_tools';\n\n/**\n * Whether the response is a streaming response\n */\nexport const GEN_AI_RESPONSE_STREAMING_ATTRIBUTE = 'gen_ai.response.streaming';\n\n/**\n * The tool calls from the response\n * Only recorded when recordOutputs is enabled\n */\nexport const GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE = 'gen_ai.response.tool_calls';\n\n/**\n * The agent name\n */\nexport const GEN_AI_AGENT_NAME_ATTRIBUTE = 'gen_ai.agent.name';\n\n/**\n * The pipeline name\n */\nexport const GEN_AI_PIPELINE_NAME_ATTRIBUTE = 'gen_ai.pipeline.name';\n\n/**\n * The conversation ID for linking messages across API calls\n * For OpenAI Assistants API: thread_id\n * For LangGraph: configurable.thread_id\n */\nexport const GEN_AI_CONVERSATION_ID_ATTRIBUTE = 'gen_ai.conversation.id';\n\n/**\n * The number of cache creation input tokens used\n */\nexport const GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS_ATTRIBUTE = 'gen_ai.usage.cache_creation_input_tokens';\n\n/**\n * The number of cache read input tokens used\n */\nexport const GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS_ATTRIBUTE = 'gen_ai.usage.cache_read_input_tokens';\n\n/**\n * The number of cache write input tokens used\n */\nexport const GEN_AI_USAGE_INPUT_TOKENS_CACHE_WRITE_ATTRIBUTE = 'gen_ai.usage.input_tokens.cache_write';\n\n/**\n * The number of cached input tokens that were used\n */\nexport const GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE = 'gen_ai.usage.input_tokens.cached';\n\n/**\n * The span operation name for invoking an agent\n */\nexport const GEN_AI_INVOKE_AGENT_OPERATION_ATTRIBUTE = 'gen_ai.invoke_agent';\n\n/**\n * The span operation name for generating content\n */\nexport const GEN_AI_GENERATE_CONTENT_OPERATION_ATTRIBUTE = 'gen_ai.generate_content';\n\n/**\n * The embeddings input\n * Only recorded when recordInputs is enabled\n */\nexport const GEN_AI_EMBEDDINGS_INPUT_ATTRIBUTE = 'gen_ai.embeddings.input';\n\n/**\n * The span operation for embeddings\n */\nexport const GEN_AI_EMBEDDINGS_OPERATION_ATTRIBUTE = 'gen_ai.embeddings';\n\n/**\n * The span operation name for embedding\n */\nexport const GEN_AI_EMBED_DO_EMBED_OPERATION_ATTRIBUTE = 'gen_ai.embeddings';\n\n/**\n * The span operation name for embedding many\n */\nexport const GEN_AI_EMBED_MANY_DO_EMBED_OPERATION_ATTRIBUTE = 'gen_ai.embeddings';\n\n/**\n * The span operation name for reranking\n */\nexport const GEN_AI_RERANK_DO_RERANK_OPERATION_ATTRIBUTE = 'gen_ai.rerank';\n\n/**\n * The span operation name for executing a tool\n */\nexport const GEN_AI_EXECUTE_TOOL_OPERATION_ATTRIBUTE = 'gen_ai.execute_tool';\n\n/**\n * The tool name for tool call spans\n */\nexport const GEN_AI_TOOL_NAME_ATTRIBUTE = 'gen_ai.tool.name';\n\n/**\n * The tool call ID\n */\nexport const GEN_AI_TOOL_CALL_ID_ATTRIBUTE = 'gen_ai.tool.call.id';\n\n/**\n * The tool type (e.g., 'function')\n */\nexport const GEN_AI_TOOL_TYPE_ATTRIBUTE = 'gen_ai.tool.type';\n\n/**\n * The tool input/arguments\n */\nexport const GEN_AI_TOOL_INPUT_ATTRIBUTE = 'gen_ai.tool.input';\n\n/**\n * The tool output/result\n */\nexport const GEN_AI_TOOL_OUTPUT_ATTRIBUTE = 'gen_ai.tool.output';\n\n/**\n * The description of the tool being used\n * @see https://opentelemetry.io/docs/specs/semconv/registry/attributes/gen-ai/#gen-ai-tool-description\n */\nexport const GEN_AI_TOOL_DESCRIPTION_ATTRIBUTE = 'gen_ai.tool.description';\n"],"names":[],"mappings":"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"}
@@ -74,6 +74,55 @@ function setTokenUsageAttributes(
74
74
  }
75
75
  }
76
76
 
77
+ /**
78
+ * Ends a streaming span by setting all accumulated response attributes and ending the span.
79
+ * Shared across OpenAI, Anthropic, and Google GenAI streaming implementations.
80
+ */
81
+ function endStreamSpan(span, state, recordOutputs) {
82
+ if (!span.isRecording()) {
83
+ return;
84
+ }
85
+
86
+ const attrs = {
87
+ [genAiAttributes.GEN_AI_RESPONSE_STREAMING_ATTRIBUTE]: true,
88
+ };
89
+
90
+ if (state.responseId) attrs[genAiAttributes.GEN_AI_RESPONSE_ID_ATTRIBUTE] = state.responseId;
91
+ if (state.responseModel) attrs[genAiAttributes.GEN_AI_RESPONSE_MODEL_ATTRIBUTE] = state.responseModel;
92
+
93
+ if (state.promptTokens !== undefined) attrs[genAiAttributes.GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE] = state.promptTokens;
94
+ if (state.completionTokens !== undefined) attrs[genAiAttributes.GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE] = state.completionTokens;
95
+
96
+ // Use explicit total if provided (OpenAI, Google), otherwise compute from cache tokens (Anthropic)
97
+ if (state.totalTokens !== undefined) {
98
+ attrs[genAiAttributes.GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE] = state.totalTokens;
99
+ } else if (
100
+ state.promptTokens !== undefined ||
101
+ state.completionTokens !== undefined ||
102
+ state.cacheCreationInputTokens !== undefined ||
103
+ state.cacheReadInputTokens !== undefined
104
+ ) {
105
+ attrs[genAiAttributes.GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE] =
106
+ (state.promptTokens ?? 0) +
107
+ (state.completionTokens ?? 0) +
108
+ (state.cacheCreationInputTokens ?? 0) +
109
+ (state.cacheReadInputTokens ?? 0);
110
+ }
111
+
112
+ if (state.finishReasons.length) {
113
+ attrs[genAiAttributes.GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE] = JSON.stringify(state.finishReasons);
114
+ }
115
+ if (recordOutputs && state.responseTexts.length) {
116
+ attrs[genAiAttributes.GEN_AI_RESPONSE_TEXT_ATTRIBUTE] = state.responseTexts.join('');
117
+ }
118
+ if (recordOutputs && state.toolCalls.length) {
119
+ attrs[genAiAttributes.GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE] = JSON.stringify(state.toolCalls);
120
+ }
121
+
122
+ span.setAttributes(attrs);
123
+ span.end();
124
+ }
125
+
77
126
  /**
78
127
  * Get the truncated JSON string for a string or array of strings.
79
128
  *
@@ -213,6 +262,7 @@ function wrapPromiseWithMethods(
213
262
  }
214
263
 
215
264
  exports.buildMethodPath = buildMethodPath;
265
+ exports.endStreamSpan = endStreamSpan;
216
266
  exports.extractSystemInstructions = extractSystemInstructions;
217
267
  exports.getTruncatedJsonString = getTruncatedJsonString;
218
268
  exports.resolveAIRecordingOptions = resolveAIRecordingOptions;
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sources":["../../../../src/tracing/ai/utils.ts"],"sourcesContent":["/**\n * Shared utils for AI integrations (OpenAI, Anthropic, Verce.AI, etc.)\n */\nimport { captureException } from '../../exports';\nimport { getClient } from '../../currentScopes';\nimport type { Span } from '../../types-hoist/span';\nimport { isThenable } from '../../utils/is';\nimport {\n GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE,\n GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE,\n GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE,\n} from './gen-ai-attributes';\nimport { truncateGenAiMessages, truncateGenAiStringInput } from './messageTruncation';\n\nexport interface AIRecordingOptions {\n recordInputs?: boolean;\n recordOutputs?: boolean;\n}\n\n/**\n * A method registry entry describes a single instrumented method:\n * which gen_ai operation it maps to and whether it is intrinsically streaming.\n */\nexport interface InstrumentedMethodEntry {\n /** Operation name (e.g. 'chat', 'embeddings', 'generate_content') */\n operation: string;\n /** True if the method itself is always streaming (not param-based) */\n streaming?: boolean;\n}\n\n/**\n * Maps method paths to their registry entries.\n * Used by proxy-based AI client instrumentations to determine which methods\n * to instrument, what operation name to use, and whether they stream.\n */\nexport type InstrumentedMethodRegistry = Record<string, InstrumentedMethodEntry>;\n\n/**\n * Resolves AI recording options by falling back to the client's `sendDefaultPii` setting.\n * Precedence: explicit option > sendDefaultPii > false\n */\nexport function resolveAIRecordingOptions<T extends AIRecordingOptions>(options?: T): T & Required<AIRecordingOptions> {\n const sendDefaultPii = Boolean(getClient()?.getOptions().sendDefaultPii);\n return {\n ...options,\n recordInputs: options?.recordInputs ?? sendDefaultPii,\n recordOutputs: options?.recordOutputs ?? sendDefaultPii,\n } as T & Required<AIRecordingOptions>;\n}\n\n/**\n * Build method path from current traversal\n */\nexport function buildMethodPath(currentPath: string, prop: string): string {\n return currentPath ? `${currentPath}.${prop}` : prop;\n}\n\n/**\n * Set token usage attributes\n * @param span - The span to add attributes to\n * @param promptTokens - The number of prompt tokens\n * @param completionTokens - The number of completion tokens\n * @param cachedInputTokens - The number of cached input tokens\n * @param cachedOutputTokens - The number of cached output tokens\n */\nexport function setTokenUsageAttributes(\n span: Span,\n promptTokens?: number,\n completionTokens?: number,\n cachedInputTokens?: number,\n cachedOutputTokens?: number,\n): void {\n if (promptTokens !== undefined) {\n span.setAttributes({\n [GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE]: promptTokens,\n });\n }\n if (completionTokens !== undefined) {\n span.setAttributes({\n [GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE]: completionTokens,\n });\n }\n if (\n promptTokens !== undefined ||\n completionTokens !== undefined ||\n cachedInputTokens !== undefined ||\n cachedOutputTokens !== undefined\n ) {\n /**\n * Total input tokens in a request is the summation of `input_tokens`,\n * `cache_creation_input_tokens`, and `cache_read_input_tokens`.\n */\n const totalTokens =\n (promptTokens ?? 0) + (completionTokens ?? 0) + (cachedInputTokens ?? 0) + (cachedOutputTokens ?? 0);\n\n span.setAttributes({\n [GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE]: totalTokens,\n });\n }\n}\n\n/**\n * Get the truncated JSON string for a string or array of strings.\n *\n * @param value - The string or array of strings to truncate\n * @returns The truncated JSON string\n */\nexport function getTruncatedJsonString<T>(value: T | T[]): string {\n if (typeof value === 'string') {\n // Some values are already JSON strings, so we don't need to duplicate the JSON parsing\n return truncateGenAiStringInput(value);\n }\n if (Array.isArray(value)) {\n // truncateGenAiMessages returns an array of strings, so we need to stringify it\n const truncatedMessages = truncateGenAiMessages(value);\n return JSON.stringify(truncatedMessages);\n }\n // value is an object, so we need to stringify it\n return JSON.stringify(value);\n}\n\n/**\n * Extract system instructions from messages array.\n * Finds the first system message and formats it according to OpenTelemetry semantic conventions.\n *\n * @param messages - Array of messages to extract system instructions from\n * @returns systemInstructions (JSON string) and filteredMessages (without system message)\n */\nexport function extractSystemInstructions(messages: unknown[] | unknown): {\n systemInstructions: string | undefined;\n filteredMessages: unknown[] | unknown;\n} {\n if (!Array.isArray(messages)) {\n return { systemInstructions: undefined, filteredMessages: messages };\n }\n\n const systemMessageIndex = messages.findIndex(\n msg => msg && typeof msg === 'object' && 'role' in msg && (msg as { role: string }).role === 'system',\n );\n\n if (systemMessageIndex === -1) {\n return { systemInstructions: undefined, filteredMessages: messages };\n }\n\n const systemMessage = messages[systemMessageIndex] as { role: string; content?: string | unknown };\n const systemContent =\n typeof systemMessage.content === 'string'\n ? systemMessage.content\n : systemMessage.content !== undefined\n ? JSON.stringify(systemMessage.content)\n : undefined;\n\n if (!systemContent) {\n return { systemInstructions: undefined, filteredMessages: messages };\n }\n\n const systemInstructions = JSON.stringify([{ type: 'text', content: systemContent }]);\n const filteredMessages = [...messages.slice(0, systemMessageIndex), ...messages.slice(systemMessageIndex + 1)];\n\n return { systemInstructions, filteredMessages };\n}\n\n/**\n * Creates a wrapped version of .withResponse() that replaces the data field\n * with the instrumented result while preserving metadata (response, request_id).\n */\nasync function createWithResponseWrapper<T>(\n originalWithResponse: Promise<unknown>,\n instrumentedPromise: Promise<T>,\n mechanismType: string,\n): Promise<unknown> {\n // Attach catch handler to originalWithResponse immediately to prevent unhandled rejection\n // If instrumentedPromise rejects first, we still need this handled\n const safeOriginalWithResponse = originalWithResponse.catch(error => {\n captureException(error, {\n mechanism: {\n handled: false,\n type: mechanismType,\n },\n });\n throw error;\n });\n\n const instrumentedResult = await instrumentedPromise;\n const originalWrapper = await safeOriginalWithResponse;\n\n // Combine instrumented result with original metadata\n if (originalWrapper && typeof originalWrapper === 'object' && 'data' in originalWrapper) {\n return {\n ...originalWrapper,\n data: instrumentedResult,\n };\n }\n return instrumentedResult;\n}\n\n/**\n * Wraps a promise-like object to preserve additional methods (like .withResponse())\n * that AI SDK clients (OpenAI, Anthropic) attach to their APIPromise return values.\n *\n * Standard Promise methods (.then, .catch, .finally) are routed to the instrumented\n * promise to preserve Sentry's span instrumentation, while custom SDK methods are\n * forwarded to the original promise to maintain the SDK's API surface.\n */\nexport function wrapPromiseWithMethods<R>(\n originalPromiseLike: Promise<R>,\n instrumentedPromise: Promise<R>,\n mechanismType: string,\n): Promise<R> {\n // If the original result is not thenable, return the instrumented promise\n if (!isThenable(originalPromiseLike)) {\n return instrumentedPromise;\n }\n\n // Create a proxy that forwards Promise methods to instrumentedPromise\n // and preserves additional methods from the original result\n return new Proxy(originalPromiseLike, {\n get(target: object, prop: string | symbol): unknown {\n // For standard Promise methods (.then, .catch, .finally, Symbol.toStringTag),\n // use instrumentedPromise to preserve Sentry instrumentation.\n // For custom methods (like .withResponse()), use the original target.\n const useInstrumentedPromise = prop in Promise.prototype || prop === Symbol.toStringTag;\n const source = useInstrumentedPromise ? instrumentedPromise : target;\n\n const value = Reflect.get(source, prop) as unknown;\n\n // Special handling for .withResponse() to preserve instrumentation\n // .withResponse() returns { data: T, response: Response, request_id: string }\n if (prop === 'withResponse' && typeof value === 'function') {\n return function wrappedWithResponse(this: unknown): unknown {\n const originalWithResponse = (value as (...args: unknown[]) => unknown).call(target);\n return createWithResponseWrapper(originalWithResponse, instrumentedPromise, mechanismType);\n };\n }\n\n return typeof value === 'function' ? value.bind(source) : value;\n },\n }) as Promise<R>;\n}\n"],"names":["getClient","GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE","GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE","GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE","truncateGenAiStringInput","truncateGenAiMessages","captureException","isThenable"],"mappings":"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"}
1
+ {"version":3,"file":"utils.js","sources":["../../../../src/tracing/ai/utils.ts"],"sourcesContent":["/**\n * Shared utils for AI integrations (OpenAI, Anthropic, Verce.AI, etc.)\n */\nimport { captureException } from '../../exports';\nimport { getClient } from '../../currentScopes';\nimport type { Span } from '../../types-hoist/span';\nimport { isThenable } from '../../utils/is';\nimport {\n GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE,\n GEN_AI_RESPONSE_ID_ATTRIBUTE,\n GEN_AI_RESPONSE_MODEL_ATTRIBUTE,\n GEN_AI_RESPONSE_STREAMING_ATTRIBUTE,\n GEN_AI_RESPONSE_TEXT_ATTRIBUTE,\n GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE,\n GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE,\n GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE,\n GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE,\n} from './gen-ai-attributes';\nimport { truncateGenAiMessages, truncateGenAiStringInput } from './messageTruncation';\n\nexport interface AIRecordingOptions {\n recordInputs?: boolean;\n recordOutputs?: boolean;\n}\n\n/**\n * A method registry entry describes a single instrumented method:\n * which gen_ai operation it maps to and whether it is intrinsically streaming.\n */\nexport interface InstrumentedMethodEntry {\n /** Operation name (e.g. 'chat', 'embeddings', 'generate_content'). Omit for factory methods that only need result proxying. */\n operation?: string;\n /** True if the method itself is always streaming (not param-based) */\n streaming?: boolean;\n /** When set, the method's return value is re-proxied with this as the base path */\n proxyResultPath?: string;\n}\n\n/**\n * Maps method paths to their registry entries.\n * Used by proxy-based AI client instrumentations to determine which methods\n * to instrument, what operation name to use, and whether they stream.\n */\nexport type InstrumentedMethodRegistry = Record<string, InstrumentedMethodEntry>;\n\n/**\n * Resolves AI recording options by falling back to the client's `sendDefaultPii` setting.\n * Precedence: explicit option > sendDefaultPii > false\n */\nexport function resolveAIRecordingOptions<T extends AIRecordingOptions>(options?: T): T & Required<AIRecordingOptions> {\n const sendDefaultPii = Boolean(getClient()?.getOptions().sendDefaultPii);\n return {\n ...options,\n recordInputs: options?.recordInputs ?? sendDefaultPii,\n recordOutputs: options?.recordOutputs ?? sendDefaultPii,\n } as T & Required<AIRecordingOptions>;\n}\n\n/**\n * Build method path from current traversal\n */\nexport function buildMethodPath(currentPath: string, prop: string): string {\n return currentPath ? `${currentPath}.${prop}` : prop;\n}\n\n/**\n * Set token usage attributes\n * @param span - The span to add attributes to\n * @param promptTokens - The number of prompt tokens\n * @param completionTokens - The number of completion tokens\n * @param cachedInputTokens - The number of cached input tokens\n * @param cachedOutputTokens - The number of cached output tokens\n */\nexport function setTokenUsageAttributes(\n span: Span,\n promptTokens?: number,\n completionTokens?: number,\n cachedInputTokens?: number,\n cachedOutputTokens?: number,\n): void {\n if (promptTokens !== undefined) {\n span.setAttributes({\n [GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE]: promptTokens,\n });\n }\n if (completionTokens !== undefined) {\n span.setAttributes({\n [GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE]: completionTokens,\n });\n }\n if (\n promptTokens !== undefined ||\n completionTokens !== undefined ||\n cachedInputTokens !== undefined ||\n cachedOutputTokens !== undefined\n ) {\n /**\n * Total input tokens in a request is the summation of `input_tokens`,\n * `cache_creation_input_tokens`, and `cache_read_input_tokens`.\n */\n const totalTokens =\n (promptTokens ?? 0) + (completionTokens ?? 0) + (cachedInputTokens ?? 0) + (cachedOutputTokens ?? 0);\n\n span.setAttributes({\n [GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE]: totalTokens,\n });\n }\n}\n\nexport interface StreamResponseState {\n responseId?: string;\n responseModel?: string;\n finishReasons: string[];\n responseTexts: string[];\n toolCalls: unknown[];\n promptTokens?: number;\n completionTokens?: number;\n totalTokens?: number;\n cacheCreationInputTokens?: number;\n cacheReadInputTokens?: number;\n}\n\n/**\n * Ends a streaming span by setting all accumulated response attributes and ending the span.\n * Shared across OpenAI, Anthropic, and Google GenAI streaming implementations.\n */\nexport function endStreamSpan(span: Span, state: StreamResponseState, recordOutputs: boolean): void {\n if (!span.isRecording()) {\n return;\n }\n\n const attrs: Record<string, string | number | boolean> = {\n [GEN_AI_RESPONSE_STREAMING_ATTRIBUTE]: true,\n };\n\n if (state.responseId) attrs[GEN_AI_RESPONSE_ID_ATTRIBUTE] = state.responseId;\n if (state.responseModel) attrs[GEN_AI_RESPONSE_MODEL_ATTRIBUTE] = state.responseModel;\n\n if (state.promptTokens !== undefined) attrs[GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE] = state.promptTokens;\n if (state.completionTokens !== undefined) attrs[GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE] = state.completionTokens;\n\n // Use explicit total if provided (OpenAI, Google), otherwise compute from cache tokens (Anthropic)\n if (state.totalTokens !== undefined) {\n attrs[GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE] = state.totalTokens;\n } else if (\n state.promptTokens !== undefined ||\n state.completionTokens !== undefined ||\n state.cacheCreationInputTokens !== undefined ||\n state.cacheReadInputTokens !== undefined\n ) {\n attrs[GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE] =\n (state.promptTokens ?? 0) +\n (state.completionTokens ?? 0) +\n (state.cacheCreationInputTokens ?? 0) +\n (state.cacheReadInputTokens ?? 0);\n }\n\n if (state.finishReasons.length) {\n attrs[GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE] = JSON.stringify(state.finishReasons);\n }\n if (recordOutputs && state.responseTexts.length) {\n attrs[GEN_AI_RESPONSE_TEXT_ATTRIBUTE] = state.responseTexts.join('');\n }\n if (recordOutputs && state.toolCalls.length) {\n attrs[GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE] = JSON.stringify(state.toolCalls);\n }\n\n span.setAttributes(attrs);\n span.end();\n}\n\n/**\n * Get the truncated JSON string for a string or array of strings.\n *\n * @param value - The string or array of strings to truncate\n * @returns The truncated JSON string\n */\nexport function getTruncatedJsonString<T>(value: T | T[]): string {\n if (typeof value === 'string') {\n // Some values are already JSON strings, so we don't need to duplicate the JSON parsing\n return truncateGenAiStringInput(value);\n }\n if (Array.isArray(value)) {\n // truncateGenAiMessages returns an array of strings, so we need to stringify it\n const truncatedMessages = truncateGenAiMessages(value);\n return JSON.stringify(truncatedMessages);\n }\n // value is an object, so we need to stringify it\n return JSON.stringify(value);\n}\n\n/**\n * Extract system instructions from messages array.\n * Finds the first system message and formats it according to OpenTelemetry semantic conventions.\n *\n * @param messages - Array of messages to extract system instructions from\n * @returns systemInstructions (JSON string) and filteredMessages (without system message)\n */\nexport function extractSystemInstructions(messages: unknown[] | unknown): {\n systemInstructions: string | undefined;\n filteredMessages: unknown[] | unknown;\n} {\n if (!Array.isArray(messages)) {\n return { systemInstructions: undefined, filteredMessages: messages };\n }\n\n const systemMessageIndex = messages.findIndex(\n msg => msg && typeof msg === 'object' && 'role' in msg && (msg as { role: string }).role === 'system',\n );\n\n if (systemMessageIndex === -1) {\n return { systemInstructions: undefined, filteredMessages: messages };\n }\n\n const systemMessage = messages[systemMessageIndex] as { role: string; content?: string | unknown };\n const systemContent =\n typeof systemMessage.content === 'string'\n ? systemMessage.content\n : systemMessage.content !== undefined\n ? JSON.stringify(systemMessage.content)\n : undefined;\n\n if (!systemContent) {\n return { systemInstructions: undefined, filteredMessages: messages };\n }\n\n const systemInstructions = JSON.stringify([{ type: 'text', content: systemContent }]);\n const filteredMessages = [...messages.slice(0, systemMessageIndex), ...messages.slice(systemMessageIndex + 1)];\n\n return { systemInstructions, filteredMessages };\n}\n\n/**\n * Creates a wrapped version of .withResponse() that replaces the data field\n * with the instrumented result while preserving metadata (response, request_id).\n */\nasync function createWithResponseWrapper<T>(\n originalWithResponse: Promise<unknown>,\n instrumentedPromise: Promise<T>,\n mechanismType: string,\n): Promise<unknown> {\n // Attach catch handler to originalWithResponse immediately to prevent unhandled rejection\n // If instrumentedPromise rejects first, we still need this handled\n const safeOriginalWithResponse = originalWithResponse.catch(error => {\n captureException(error, {\n mechanism: {\n handled: false,\n type: mechanismType,\n },\n });\n throw error;\n });\n\n const instrumentedResult = await instrumentedPromise;\n const originalWrapper = await safeOriginalWithResponse;\n\n // Combine instrumented result with original metadata\n if (originalWrapper && typeof originalWrapper === 'object' && 'data' in originalWrapper) {\n return {\n ...originalWrapper,\n data: instrumentedResult,\n };\n }\n return instrumentedResult;\n}\n\n/**\n * Wraps a promise-like object to preserve additional methods (like .withResponse())\n * that AI SDK clients (OpenAI, Anthropic) attach to their APIPromise return values.\n *\n * Standard Promise methods (.then, .catch, .finally) are routed to the instrumented\n * promise to preserve Sentry's span instrumentation, while custom SDK methods are\n * forwarded to the original promise to maintain the SDK's API surface.\n */\nexport function wrapPromiseWithMethods<R>(\n originalPromiseLike: Promise<R>,\n instrumentedPromise: Promise<R>,\n mechanismType: string,\n): Promise<R> {\n // If the original result is not thenable, return the instrumented promise\n if (!isThenable(originalPromiseLike)) {\n return instrumentedPromise;\n }\n\n // Create a proxy that forwards Promise methods to instrumentedPromise\n // and preserves additional methods from the original result\n return new Proxy(originalPromiseLike, {\n get(target: object, prop: string | symbol): unknown {\n // For standard Promise methods (.then, .catch, .finally, Symbol.toStringTag),\n // use instrumentedPromise to preserve Sentry instrumentation.\n // For custom methods (like .withResponse()), use the original target.\n const useInstrumentedPromise = prop in Promise.prototype || prop === Symbol.toStringTag;\n const source = useInstrumentedPromise ? instrumentedPromise : target;\n\n const value = Reflect.get(source, prop) as unknown;\n\n // Special handling for .withResponse() to preserve instrumentation\n // .withResponse() returns { data: T, response: Response, request_id: string }\n if (prop === 'withResponse' && typeof value === 'function') {\n return function wrappedWithResponse(this: unknown): unknown {\n const originalWithResponse = (value as (...args: unknown[]) => unknown).call(target);\n return createWithResponseWrapper(originalWithResponse, instrumentedPromise, mechanismType);\n };\n }\n\n return typeof value === 'function' ? value.bind(source) : value;\n },\n }) as Promise<R>;\n}\n"],"names":["getClient","GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE","GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE","GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE","GEN_AI_RESPONSE_STREAMING_ATTRIBUTE","GEN_AI_RESPONSE_ID_ATTRIBUTE","GEN_AI_RESPONSE_MODEL_ATTRIBUTE","GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE","GEN_AI_RESPONSE_TEXT_ATTRIBUTE","GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE","truncateGenAiStringInput","truncateGenAiMessages","captureException","isThenable"],"mappings":";;;;;;;;AAAA;AACA;AACA;;AA2CA;AACA;AACA;AACA;AACO,SAAS,yBAAyB,CAA+B,OAAO,EAAwC;AACvH,EAAE,MAAM,cAAA,GAAiB,OAAO,CAACA,uBAAS,EAAE,EAAE,UAAU,EAAE,CAAC,cAAc,CAAC;AAC1E,EAAE,OAAO;AACT,IAAI,GAAG,OAAO;AACd,IAAI,YAAY,EAAE,OAAO,EAAE,YAAA,IAAgB,cAAc;AACzD,IAAI,aAAa,EAAE,OAAO,EAAE,aAAA,IAAiB,cAAc;AAC3D,GAAE;AACF;;AAEA;AACA;AACA;AACO,SAAS,eAAe,CAAC,WAAW,EAAU,IAAI,EAAkB;AAC3E,EAAE,OAAO,WAAA,GAAc,CAAC,EAAA,WAAA,CAAA,CAAA,EAAA,IAAA,CAAA,CAAA,GAAA,IAAA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAA,uBAAA;AACA,EAAA,IAAA;AACA,EAAA,YAAA;AACA,EAAA,gBAAA;AACA,EAAA,iBAAA;AACA,EAAA,kBAAA;AACA,EAAA;AACA,EAAA,IAAA,YAAA,KAAA,SAAA,EAAA;AACA,IAAA,IAAA,CAAA,aAAA,CAAA;AACA,MAAA,CAAAC,mDAAA,GAAA,YAAA;AACA,KAAA,CAAA;AACA,EAAA;AACA,EAAA,IAAA,gBAAA,KAAA,SAAA,EAAA;AACA,IAAA,IAAA,CAAA,aAAA,CAAA;AACA,MAAA,CAAAC,oDAAA,GAAA,gBAAA;AACA,KAAA,CAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA,YAAA,KAAA,SAAA;AACA,IAAA,gBAAA,KAAA,SAAA;AACA,IAAA,iBAAA,KAAA,SAAA;AACA,IAAA,kBAAA,KAAA;AACA,IAAA;AACA;AACA;AACA;AACA;AACA,IAAA,MAAA,WAAA;AACA,MAAA,CAAA,YAAA,IAAA,CAAA,KAAA,gBAAA,IAAA,CAAA,CAAA,IAAA,iBAAA,IAAA,CAAA,CAAA,IAAA,kBAAA,IAAA,CAAA,CAAA;;AAEA,IAAA,IAAA,CAAA,aAAA,CAAA;AACA,MAAA,CAAAC,mDAAA,GAAA,WAAA;AACA,KAAA,CAAA;AACA,EAAA;AACA;;AAeA;AACA;AACA;AACA;AACA,SAAA,aAAA,CAAA,IAAA,EAAA,KAAA,EAAA,aAAA,EAAA;AACA,EAAA,IAAA,CAAA,IAAA,CAAA,WAAA,EAAA,EAAA;AACA,IAAA;AACA,EAAA;;AAEA,EAAA,MAAA,KAAA,GAAA;AACA,IAAA,CAAAC,mDAAA,GAAA,IAAA;AACA,GAAA;;AAEA,EAAA,IAAA,KAAA,CAAA,UAAA,EAAA,KAAA,CAAAC,4CAAA,CAAA,GAAA,KAAA,CAAA,UAAA;AACA,EAAA,IAAA,KAAA,CAAA,aAAA,EAAA,KAAA,CAAAC,+CAAA,CAAA,GAAA,KAAA,CAAA,aAAA;;AAEA,EAAA,IAAA,KAAA,CAAA,YAAA,KAAA,SAAA,EAAA,KAAA,CAAAL,mDAAA,CAAA,GAAA,KAAA,CAAA,YAAA;AACA,EAAA,IAAA,KAAA,CAAA,gBAAA,KAAA,SAAA,EAAA,KAAA,CAAAC,oDAAA,CAAA,GAAA,KAAA,CAAA,gBAAA;;AAEA;AACA,EAAA,IAAA,KAAA,CAAA,WAAA,KAAA,SAAA,EAAA;AACA,IAAA,KAAA,CAAAC,mDAAA,CAAA,GAAA,KAAA,CAAA,WAAA;AACA,EAAA,CAAA,MAAA;AACA,IAAA,KAAA,CAAA,YAAA,KAAA,SAAA;AACA,IAAA,KAAA,CAAA,gBAAA,KAAA,SAAA;AACA,IAAA,KAAA,CAAA,wBAAA,KAAA,SAAA;AACA,IAAA,KAAA,CAAA,oBAAA,KAAA;AACA,IAAA;AACA,IAAA,KAAA,CAAAA,mDAAA,CAAA;AACA,MAAA,CAAA,KAAA,CAAA,YAAA,IAAA,CAAA;AACA,OAAA,KAAA,CAAA,gBAAA,IAAA,CAAA,CAAA;AACA,OAAA,KAAA,CAAA,wBAAA,IAAA,CAAA,CAAA;AACA,OAAA,KAAA,CAAA,oBAAA,IAAA,CAAA,CAAA;AACA,EAAA;;AAEA,EAAA,IAAA,KAAA,CAAA,aAAA,CAAA,MAAA,EAAA;AACA,IAAA,KAAA,CAAAI,wDAAA,CAAA,GAAA,IAAA,CAAA,SAAA,CAAA,KAAA,CAAA,aAAA,CAAA;AACA,EAAA;AACA,EAAA,IAAA,aAAA,IAAA,KAAA,CAAA,aAAA,CAAA,MAAA,EAAA;AACA,IAAA,KAAA,CAAAC,8CAAA,CAAA,GAAA,KAAA,CAAA,aAAA,CAAA,IAAA,CAAA,EAAA,CAAA;AACA,EAAA;AACA,EAAA,IAAA,aAAA,IAAA,KAAA,CAAA,SAAA,CAAA,MAAA,EAAA;AACA,IAAA,KAAA,CAAAC,oDAAA,CAAA,GAAA,IAAA,CAAA,SAAA,CAAA,KAAA,CAAA,SAAA,CAAA;AACA,EAAA;;AAEA,EAAA,IAAA,CAAA,aAAA,CAAA,KAAA,CAAA;AACA,EAAA,IAAA,CAAA,GAAA,EAAA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAAA,sBAAA,CAAA,KAAA,EAAA;AACA,EAAA,IAAA,OAAA,KAAA,KAAA,QAAA,EAAA;AACA;AACA,IAAA,OAAAC,0CAAA,CAAA,KAAA,CAAA;AACA,EAAA;AACA,EAAA,IAAA,KAAA,CAAA,OAAA,CAAA,KAAA,CAAA,EAAA;AACA;AACA,IAAA,MAAA,iBAAA,GAAAC,uCAAA,CAAA,KAAA,CAAA;AACA,IAAA,OAAA,IAAA,CAAA,SAAA,CAAA,iBAAA,CAAA;AACA,EAAA;AACA;AACA,EAAA,OAAA,IAAA,CAAA,SAAA,CAAA,KAAA,CAAA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAA,yBAAA,CAAA,QAAA;;AAGA,CAAA;AACA,EAAA,IAAA,CAAA,KAAA,CAAA,OAAA,CAAA,QAAA,CAAA,EAAA;AACA,IAAA,OAAA,EAAA,kBAAA,EAAA,SAAA,EAAA,gBAAA,EAAA,QAAA,EAAA;AACA,EAAA;;AAEA,EAAA,MAAA,kBAAA,GAAA,QAAA,CAAA,SAAA;AACA,IAAA,GAAA,IAAA,GAAA,IAAA,OAAA,GAAA,KAAA,QAAA,IAAA,MAAA,IAAA,GAAA,IAAA,CAAA,GAAA,GAAA,IAAA,KAAA,QAAA;AACA,GAAA;;AAEA,EAAA,IAAA,kBAAA,KAAA,EAAA,EAAA;AACA,IAAA,OAAA,EAAA,kBAAA,EAAA,SAAA,EAAA,gBAAA,EAAA,QAAA,EAAA;AACA,EAAA;;AAEA,EAAA,MAAA,aAAA,GAAA,QAAA,CAAA,kBAAA,CAAA;AACA,EAAA,MAAA,aAAA;AACA,IAAA,OAAA,aAAA,CAAA,OAAA,KAAA;AACA,QAAA,aAAA,CAAA;AACA,QAAA,aAAA,CAAA,OAAA,KAAA;AACA,UAAA,IAAA,CAAA,SAAA,CAAA,aAAA,CAAA,OAAA;AACA,UAAA,SAAA;;AAEA,EAAA,IAAA,CAAA,aAAA,EAAA;AACA,IAAA,OAAA,EAAA,kBAAA,EAAA,SAAA,EAAA,gBAAA,EAAA,QAAA,EAAA;AACA,EAAA;;AAEA,EAAA,MAAA,kBAAA,GAAA,IAAA,CAAA,SAAA,CAAA,CAAA,EAAA,IAAA,EAAA,MAAA,EAAA,OAAA,EAAA,aAAA,EAAA,CAAA,CAAA;AACA,EAAA,MAAA,gBAAA,GAAA,CAAA,GAAA,QAAA,CAAA,KAAA,CAAA,CAAA,EAAA,kBAAA,CAAA,EAAA,GAAA,QAAA,CAAA,KAAA,CAAA,kBAAA,GAAA,CAAA,CAAA,CAAA;;AAEA,EAAA,OAAA,EAAA,kBAAA,EAAA,gBAAA,EAAA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAA,yBAAA;AACA,EAAA,oBAAA;AACA,EAAA,mBAAA;AACA,EAAA,aAAA;AACA,EAAA;AACA;AACA;AACA,EAAA,MAAA,wBAAA,GAAA,oBAAA,CAAA,KAAA,CAAA,KAAA,IAAA;AACA,IAAAC,yBAAA,CAAA,KAAA,EAAA;AACA,MAAA,SAAA,EAAA;AACA,QAAA,OAAA,EAAA,KAAA;AACA,QAAA,IAAA,EAAA,aAAA;AACA,OAAA;AACA,KAAA,CAAA;AACA,IAAA,MAAA,KAAA;AACA,EAAA,CAAA,CAAA;;AAEA,EAAA,MAAA,kBAAA,GAAA,MAAA,mBAAA;AACA,EAAA,MAAA,eAAA,GAAA,MAAA,wBAAA;;AAEA;AACA,EAAA,IAAA,eAAA,IAAA,OAAA,eAAA,KAAA,QAAA,IAAA,MAAA,IAAA,eAAA,EAAA;AACA,IAAA,OAAA;AACA,MAAA,GAAA,eAAA;AACA,MAAA,IAAA,EAAA,kBAAA;AACA,KAAA;AACA,EAAA;AACA,EAAA,OAAA,kBAAA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAA,sBAAA;AACA,EAAA,mBAAA;AACA,EAAA,mBAAA;AACA,EAAA,aAAA;AACA,EAAA;AACA;AACA,EAAA,IAAA,CAAAC,aAAA,CAAA,mBAAA,CAAA,EAAA;AACA,IAAA,OAAA,mBAAA;AACA,EAAA;;AAEA;AACA;AACA,EAAA,OAAA,IAAA,KAAA,CAAA,mBAAA,EAAA;AACA,IAAA,GAAA,CAAA,MAAA,EAAA,IAAA,EAAA;AACA;AACA;AACA;AACA,MAAA,MAAA,sBAAA,GAAA,IAAA,IAAA,OAAA,CAAA,SAAA,IAAA,IAAA,KAAA,MAAA,CAAA,WAAA;AACA,MAAA,MAAA,MAAA,GAAA,sBAAA,GAAA,mBAAA,GAAA,MAAA;;AAEA,MAAA,MAAA,KAAA,GAAA,OAAA,CAAA,GAAA,CAAA,MAAA,EAAA,IAAA,CAAA;;AAEA;AACA;AACA,MAAA,IAAA,IAAA,KAAA,cAAA,IAAA,OAAA,KAAA,KAAA,UAAA,EAAA;AACA,QAAA,OAAA,SAAA,mBAAA,GAAA;AACA,UAAA,MAAA,oBAAA,GAAA,CAAA,KAAA,GAAA,IAAA,CAAA,MAAA,CAAA;AACA,UAAA,OAAA,yBAAA,CAAA,oBAAA,EAAA,mBAAA,EAAA,aAAA,CAAA;AACA,QAAA,CAAA;AACA,MAAA;;AAEA,MAAA,OAAA,OAAA,KAAA,KAAA,UAAA,GAAA,KAAA,CAAA,IAAA,CAAA,MAAA,CAAA,GAAA,KAAA;AACA,IAAA,CAAA;AACA,GAAA,CAAA;AACA;;;;;;;;;;"}
@@ -105,17 +105,6 @@ function addMetadataAttributes(span, response) {
105
105
  [genAiAttributes.GEN_AI_RESPONSE_MODEL_ATTRIBUTE]: response.model,
106
106
  });
107
107
 
108
- if ('created' in response && typeof response.created === 'number') {
109
- span.setAttributes({
110
- [genAiAttributes.ANTHROPIC_AI_RESPONSE_TIMESTAMP_ATTRIBUTE]: new Date(response.created * 1000).toISOString(),
111
- });
112
- }
113
- if ('created_at' in response && typeof response.created_at === 'number') {
114
- span.setAttributes({
115
- [genAiAttributes.ANTHROPIC_AI_RESPONSE_TIMESTAMP_ATTRIBUTE]: new Date(response.created_at * 1000).toISOString(),
116
- });
117
- }
118
-
119
108
  if ('usage' in response && response.usage) {
120
109
  utils.setTokenUsageAttributes(
121
110
  span,
@@ -242,7 +231,7 @@ function instrumentMethod(
242
231
  ) {
243
232
  return new Proxy(originalMethod, {
244
233
  apply(target, thisArg, args) {
245
- const operationName = instrumentedMethod.operation;
234
+ const operationName = instrumentedMethod.operation || 'unknown';
246
235
  const requestAttributes = extractRequestAttributes(args, methodPath, operationName);
247
236
  const model = requestAttributes[genAiAttributes.GEN_AI_REQUEST_MODEL_ATTRIBUTE] ?? 'unknown';
248
237
 
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../../src/tracing/anthropic-ai/index.ts"],"sourcesContent":["import { captureException } from '../../exports';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '../../semanticAttributes';\nimport { SPAN_STATUS_ERROR } from '../../tracing';\nimport { startSpan, startSpanManual } from '../../tracing/trace';\nimport type { Span, SpanAttributeValue } from '../../types-hoist/span';\nimport {\n ANTHROPIC_AI_RESPONSE_TIMESTAMP_ATTRIBUTE,\n GEN_AI_OPERATION_NAME_ATTRIBUTE,\n GEN_AI_PROMPT_ATTRIBUTE,\n GEN_AI_REQUEST_AVAILABLE_TOOLS_ATTRIBUTE,\n GEN_AI_REQUEST_FREQUENCY_PENALTY_ATTRIBUTE,\n GEN_AI_REQUEST_MAX_TOKENS_ATTRIBUTE,\n GEN_AI_REQUEST_MODEL_ATTRIBUTE,\n GEN_AI_REQUEST_STREAM_ATTRIBUTE,\n GEN_AI_REQUEST_TEMPERATURE_ATTRIBUTE,\n GEN_AI_REQUEST_TOP_K_ATTRIBUTE,\n GEN_AI_REQUEST_TOP_P_ATTRIBUTE,\n GEN_AI_RESPONSE_ID_ATTRIBUTE,\n GEN_AI_RESPONSE_MODEL_ATTRIBUTE,\n GEN_AI_RESPONSE_TEXT_ATTRIBUTE,\n GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE,\n GEN_AI_SYSTEM_ATTRIBUTE,\n} from '../ai/gen-ai-attributes';\nimport type { InstrumentedMethodEntry } from '../ai/utils';\nimport {\n buildMethodPath,\n resolveAIRecordingOptions,\n setTokenUsageAttributes,\n wrapPromiseWithMethods,\n} from '../ai/utils';\nimport { ANTHROPIC_METHOD_REGISTRY } from './constants';\nimport { instrumentAsyncIterableStream, instrumentMessageStream } from './streaming';\nimport type { AnthropicAiOptions, AnthropicAiResponse, AnthropicAiStreamingEvent, ContentBlock } from './types';\nimport { handleResponseError, messagesFromParams, setMessagesAttribute } from './utils';\n\n/**\n * Extract request attributes from method arguments\n */\nfunction extractRequestAttributes(args: unknown[], methodPath: string, operationName: string): Record<string, unknown> {\n const attributes: Record<string, unknown> = {\n [GEN_AI_SYSTEM_ATTRIBUTE]: 'anthropic',\n [GEN_AI_OPERATION_NAME_ATTRIBUTE]: operationName,\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ai.anthropic',\n };\n\n if (args.length > 0 && typeof args[0] === 'object' && args[0] !== null) {\n const params = args[0] as Record<string, unknown>;\n if (params.tools && Array.isArray(params.tools)) {\n attributes[GEN_AI_REQUEST_AVAILABLE_TOOLS_ATTRIBUTE] = JSON.stringify(params.tools);\n }\n\n attributes[GEN_AI_REQUEST_MODEL_ATTRIBUTE] = params.model ?? 'unknown';\n if ('temperature' in params) attributes[GEN_AI_REQUEST_TEMPERATURE_ATTRIBUTE] = params.temperature;\n if ('top_p' in params) attributes[GEN_AI_REQUEST_TOP_P_ATTRIBUTE] = params.top_p;\n if ('stream' in params) attributes[GEN_AI_REQUEST_STREAM_ATTRIBUTE] = params.stream;\n if ('top_k' in params) attributes[GEN_AI_REQUEST_TOP_K_ATTRIBUTE] = params.top_k;\n if ('frequency_penalty' in params)\n attributes[GEN_AI_REQUEST_FREQUENCY_PENALTY_ATTRIBUTE] = params.frequency_penalty;\n if ('max_tokens' in params) attributes[GEN_AI_REQUEST_MAX_TOKENS_ATTRIBUTE] = params.max_tokens;\n } else {\n if (methodPath === 'models.retrieve' || methodPath === 'models.get') {\n // models.retrieve(model-id) and models.get(model-id)\n attributes[GEN_AI_REQUEST_MODEL_ATTRIBUTE] = args[0];\n } else {\n attributes[GEN_AI_REQUEST_MODEL_ATTRIBUTE] = 'unknown';\n }\n }\n\n return attributes;\n}\n\n/**\n * Add private request attributes to spans.\n * This is only recorded if recordInputs is true.\n */\nfunction addPrivateRequestAttributes(span: Span, params: Record<string, unknown>): void {\n const messages = messagesFromParams(params);\n setMessagesAttribute(span, messages);\n\n if ('prompt' in params) {\n span.setAttributes({ [GEN_AI_PROMPT_ATTRIBUTE]: JSON.stringify(params.prompt) });\n }\n}\n\n/**\n * Add content attributes when recordOutputs is enabled\n */\nfunction addContentAttributes(span: Span, response: AnthropicAiResponse): void {\n // Messages.create\n if ('content' in response) {\n if (Array.isArray(response.content)) {\n span.setAttributes({\n [GEN_AI_RESPONSE_TEXT_ATTRIBUTE]: response.content\n .map((item: ContentBlock) => item.text)\n .filter(text => !!text)\n .join(''),\n });\n\n const toolCalls: Array<ContentBlock> = [];\n\n for (const item of response.content) {\n if (item.type === 'tool_use' || item.type === 'server_tool_use') {\n toolCalls.push(item);\n }\n }\n if (toolCalls.length > 0) {\n span.setAttributes({ [GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE]: JSON.stringify(toolCalls) });\n }\n }\n }\n // Completions.create\n if ('completion' in response) {\n span.setAttributes({ [GEN_AI_RESPONSE_TEXT_ATTRIBUTE]: response.completion });\n }\n // Models.countTokens\n if ('input_tokens' in response) {\n span.setAttributes({ [GEN_AI_RESPONSE_TEXT_ATTRIBUTE]: JSON.stringify(response.input_tokens) });\n }\n}\n\n/**\n * Add basic metadata attributes from the response\n */\nfunction addMetadataAttributes(span: Span, response: AnthropicAiResponse): void {\n if ('id' in response && 'model' in response) {\n span.setAttributes({\n [GEN_AI_RESPONSE_ID_ATTRIBUTE]: response.id,\n [GEN_AI_RESPONSE_MODEL_ATTRIBUTE]: response.model,\n });\n\n if ('created' in response && typeof response.created === 'number') {\n span.setAttributes({\n [ANTHROPIC_AI_RESPONSE_TIMESTAMP_ATTRIBUTE]: new Date(response.created * 1000).toISOString(),\n });\n }\n if ('created_at' in response && typeof response.created_at === 'number') {\n span.setAttributes({\n [ANTHROPIC_AI_RESPONSE_TIMESTAMP_ATTRIBUTE]: new Date(response.created_at * 1000).toISOString(),\n });\n }\n\n if ('usage' in response && response.usage) {\n setTokenUsageAttributes(\n span,\n response.usage.input_tokens,\n response.usage.output_tokens,\n response.usage.cache_creation_input_tokens,\n response.usage.cache_read_input_tokens,\n );\n }\n }\n}\n\n/**\n * Add response attributes to spans\n */\nfunction addResponseAttributes(span: Span, response: AnthropicAiResponse, recordOutputs?: boolean): void {\n if (!response || typeof response !== 'object') return;\n\n // capture error, do not add attributes if error (they shouldn't exist)\n if ('type' in response && response.type === 'error') {\n handleResponseError(span, response);\n return;\n }\n\n // Private response attributes that are only recorded if recordOutputs is true.\n if (recordOutputs) {\n addContentAttributes(span, response);\n }\n\n // Add basic metadata attributes\n addMetadataAttributes(span, response);\n}\n\n/**\n * Handle common error catching and reporting for streaming requests\n */\nfunction handleStreamingError(error: unknown, span: Span, methodPath: string): never {\n captureException(error, {\n mechanism: { handled: false, type: 'auto.ai.anthropic', data: { function: methodPath } },\n });\n\n if (span.isRecording()) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n span.end();\n }\n throw error;\n}\n\n/**\n * Handle streaming cases with common logic\n */\nfunction handleStreamingRequest<T extends unknown[], R>(\n originalMethod: (...args: T) => R | Promise<R>,\n target: (...args: T) => R | Promise<R>,\n context: unknown,\n args: T,\n requestAttributes: Record<string, unknown>,\n operationName: string,\n methodPath: string,\n params: Record<string, unknown> | undefined,\n options: AnthropicAiOptions,\n isStreamRequested: boolean,\n isStreamingMethod: boolean,\n): R | Promise<R> {\n const model = requestAttributes[GEN_AI_REQUEST_MODEL_ATTRIBUTE] ?? 'unknown';\n const spanConfig = {\n name: `${operationName} ${model}`,\n op: `gen_ai.${operationName}`,\n attributes: requestAttributes as Record<string, SpanAttributeValue>,\n };\n\n // messages.stream() always returns a sync MessageStream, even with stream: true param\n if (isStreamRequested && !isStreamingMethod) {\n let originalResult!: Promise<R>;\n\n const instrumentedPromise = startSpanManual(spanConfig, (span: Span) => {\n originalResult = originalMethod.apply(context, args) as Promise<R>;\n\n if (options.recordInputs && params) {\n addPrivateRequestAttributes(span, params);\n }\n\n return (async () => {\n try {\n const result = await originalResult;\n return instrumentAsyncIterableStream(\n result as AsyncIterable<AnthropicAiStreamingEvent>,\n span,\n options.recordOutputs ?? false,\n ) as unknown as R;\n } catch (error) {\n return handleStreamingError(error, span, methodPath);\n }\n })();\n });\n\n return wrapPromiseWithMethods(originalResult, instrumentedPromise, 'auto.ai.anthropic');\n } else {\n return startSpanManual(spanConfig, span => {\n try {\n if (options.recordInputs && params) {\n addPrivateRequestAttributes(span, params);\n }\n const messageStream = target.apply(context, args);\n return instrumentMessageStream(messageStream, span, options.recordOutputs ?? false);\n } catch (error) {\n return handleStreamingError(error, span, methodPath);\n }\n });\n }\n}\n\n/**\n * Instrument a method with Sentry spans\n * Following Sentry AI Agents Manual Instrumentation conventions\n * @see https://docs.sentry.io/platforms/javascript/guides/node/tracing/instrumentation/ai-agents-module/#manual-instrumentation\n */\nfunction instrumentMethod<T extends unknown[], R>(\n originalMethod: (...args: T) => R | Promise<R>,\n methodPath: string,\n instrumentedMethod: InstrumentedMethodEntry,\n context: unknown,\n options: AnthropicAiOptions,\n): (...args: T) => R | Promise<R> {\n return new Proxy(originalMethod, {\n apply(target, thisArg, args: T): R | Promise<R> {\n const operationName = instrumentedMethod.operation;\n const requestAttributes = extractRequestAttributes(args, methodPath, operationName);\n const model = requestAttributes[GEN_AI_REQUEST_MODEL_ATTRIBUTE] ?? 'unknown';\n\n const params = typeof args[0] === 'object' ? (args[0] as Record<string, unknown>) : undefined;\n const isStreamRequested = Boolean(params?.stream);\n const isStreamingMethod = instrumentedMethod.streaming === true;\n\n if (isStreamRequested || isStreamingMethod) {\n return handleStreamingRequest(\n originalMethod,\n target,\n context,\n args,\n requestAttributes,\n operationName,\n methodPath,\n params,\n options,\n isStreamRequested,\n isStreamingMethod,\n );\n }\n\n let originalResult!: Promise<R>;\n\n const instrumentedPromise = startSpan(\n {\n name: `${operationName} ${model}`,\n op: `gen_ai.${operationName}`,\n attributes: requestAttributes as Record<string, SpanAttributeValue>,\n },\n span => {\n originalResult = target.apply(context, args) as Promise<R>;\n\n if (options.recordInputs && params) {\n addPrivateRequestAttributes(span, params);\n }\n\n return originalResult.then(\n result => {\n addResponseAttributes(span, result as AnthropicAiResponse, options.recordOutputs);\n return result;\n },\n error => {\n captureException(error, {\n mechanism: {\n handled: false,\n type: 'auto.ai.anthropic',\n data: {\n function: methodPath,\n },\n },\n });\n throw error;\n },\n );\n },\n );\n\n return wrapPromiseWithMethods(originalResult, instrumentedPromise, 'auto.ai.anthropic');\n },\n }) as (...args: T) => R | Promise<R>;\n}\n\n/**\n * Create a deep proxy for Anthropic AI client instrumentation\n */\nfunction createDeepProxy<T extends object>(target: T, currentPath = '', options: AnthropicAiOptions): T {\n return new Proxy(target, {\n get(obj: object, prop: string): unknown {\n const value = (obj as Record<string, unknown>)[prop];\n const methodPath = buildMethodPath(currentPath, String(prop));\n\n const instrumentedMethod = ANTHROPIC_METHOD_REGISTRY[methodPath as keyof typeof ANTHROPIC_METHOD_REGISTRY];\n if (typeof value === 'function' && instrumentedMethod) {\n return instrumentMethod(\n value as (...args: unknown[]) => unknown | Promise<unknown>,\n methodPath,\n instrumentedMethod,\n obj,\n options,\n );\n }\n\n if (typeof value === 'function') {\n // Bind non-instrumented functions to preserve the original `this` context,\n return value.bind(obj);\n }\n\n if (value && typeof value === 'object') {\n return createDeepProxy(value, methodPath, options);\n }\n\n return value;\n },\n }) as T;\n}\n\n/**\n * Instrument an Anthropic AI client with Sentry tracing\n * Can be used across Node.js, Cloudflare Workers, and Vercel Edge\n *\n * @template T - The type of the client that extends object\n * @param client - The Anthropic AI client to instrument\n * @param options - Optional configuration for recording inputs and outputs\n * @returns The instrumented client with the same type as the input\n */\nexport function instrumentAnthropicAiClient<T extends object>(anthropicAiClient: T, options?: AnthropicAiOptions): T {\n return createDeepProxy(anthropicAiClient, '', resolveAIRecordingOptions(options));\n}\n"],"names":["GEN_AI_SYSTEM_ATTRIBUTE","GEN_AI_OPERATION_NAME_ATTRIBUTE","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","GEN_AI_REQUEST_AVAILABLE_TOOLS_ATTRIBUTE","GEN_AI_REQUEST_MODEL_ATTRIBUTE","GEN_AI_REQUEST_TEMPERATURE_ATTRIBUTE","GEN_AI_REQUEST_TOP_P_ATTRIBUTE","GEN_AI_REQUEST_STREAM_ATTRIBUTE","GEN_AI_REQUEST_TOP_K_ATTRIBUTE","GEN_AI_REQUEST_FREQUENCY_PENALTY_ATTRIBUTE","GEN_AI_REQUEST_MAX_TOKENS_ATTRIBUTE","messagesFromParams","setMessagesAttribute","GEN_AI_PROMPT_ATTRIBUTE","GEN_AI_RESPONSE_TEXT_ATTRIBUTE","GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE","GEN_AI_RESPONSE_ID_ATTRIBUTE","GEN_AI_RESPONSE_MODEL_ATTRIBUTE","ANTHROPIC_AI_RESPONSE_TIMESTAMP_ATTRIBUTE","setTokenUsageAttributes","handleResponseError","captureException","SPAN_STATUS_ERROR","startSpanManual","instrumentAsyncIterableStream","wrapPromiseWithMethods","instrumentMessageStream","startSpan","buildMethodPath","ANTHROPIC_METHOD_REGISTRY","resolveAIRecordingOptions"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../../../src/tracing/anthropic-ai/index.ts"],"sourcesContent":["import { captureException } from '../../exports';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '../../semanticAttributes';\nimport { SPAN_STATUS_ERROR } from '../../tracing';\nimport { startSpan, startSpanManual } from '../../tracing/trace';\nimport type { Span, SpanAttributeValue } from '../../types-hoist/span';\nimport {\n GEN_AI_OPERATION_NAME_ATTRIBUTE,\n GEN_AI_PROMPT_ATTRIBUTE,\n GEN_AI_REQUEST_AVAILABLE_TOOLS_ATTRIBUTE,\n GEN_AI_REQUEST_FREQUENCY_PENALTY_ATTRIBUTE,\n GEN_AI_REQUEST_MAX_TOKENS_ATTRIBUTE,\n GEN_AI_REQUEST_MODEL_ATTRIBUTE,\n GEN_AI_REQUEST_STREAM_ATTRIBUTE,\n GEN_AI_REQUEST_TEMPERATURE_ATTRIBUTE,\n GEN_AI_REQUEST_TOP_K_ATTRIBUTE,\n GEN_AI_REQUEST_TOP_P_ATTRIBUTE,\n GEN_AI_RESPONSE_ID_ATTRIBUTE,\n GEN_AI_RESPONSE_MODEL_ATTRIBUTE,\n GEN_AI_RESPONSE_TEXT_ATTRIBUTE,\n GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE,\n GEN_AI_SYSTEM_ATTRIBUTE,\n} from '../ai/gen-ai-attributes';\nimport type { InstrumentedMethodEntry } from '../ai/utils';\nimport {\n buildMethodPath,\n resolveAIRecordingOptions,\n setTokenUsageAttributes,\n wrapPromiseWithMethods,\n} from '../ai/utils';\nimport { ANTHROPIC_METHOD_REGISTRY } from './constants';\nimport { instrumentAsyncIterableStream, instrumentMessageStream } from './streaming';\nimport type { AnthropicAiOptions, AnthropicAiResponse, AnthropicAiStreamingEvent, ContentBlock } from './types';\nimport { handleResponseError, messagesFromParams, setMessagesAttribute } from './utils';\n\n/**\n * Extract request attributes from method arguments\n */\nfunction extractRequestAttributes(args: unknown[], methodPath: string, operationName: string): Record<string, unknown> {\n const attributes: Record<string, unknown> = {\n [GEN_AI_SYSTEM_ATTRIBUTE]: 'anthropic',\n [GEN_AI_OPERATION_NAME_ATTRIBUTE]: operationName,\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ai.anthropic',\n };\n\n if (args.length > 0 && typeof args[0] === 'object' && args[0] !== null) {\n const params = args[0] as Record<string, unknown>;\n if (params.tools && Array.isArray(params.tools)) {\n attributes[GEN_AI_REQUEST_AVAILABLE_TOOLS_ATTRIBUTE] = JSON.stringify(params.tools);\n }\n\n attributes[GEN_AI_REQUEST_MODEL_ATTRIBUTE] = params.model ?? 'unknown';\n if ('temperature' in params) attributes[GEN_AI_REQUEST_TEMPERATURE_ATTRIBUTE] = params.temperature;\n if ('top_p' in params) attributes[GEN_AI_REQUEST_TOP_P_ATTRIBUTE] = params.top_p;\n if ('stream' in params) attributes[GEN_AI_REQUEST_STREAM_ATTRIBUTE] = params.stream;\n if ('top_k' in params) attributes[GEN_AI_REQUEST_TOP_K_ATTRIBUTE] = params.top_k;\n if ('frequency_penalty' in params)\n attributes[GEN_AI_REQUEST_FREQUENCY_PENALTY_ATTRIBUTE] = params.frequency_penalty;\n if ('max_tokens' in params) attributes[GEN_AI_REQUEST_MAX_TOKENS_ATTRIBUTE] = params.max_tokens;\n } else {\n if (methodPath === 'models.retrieve' || methodPath === 'models.get') {\n // models.retrieve(model-id) and models.get(model-id)\n attributes[GEN_AI_REQUEST_MODEL_ATTRIBUTE] = args[0];\n } else {\n attributes[GEN_AI_REQUEST_MODEL_ATTRIBUTE] = 'unknown';\n }\n }\n\n return attributes;\n}\n\n/**\n * Add private request attributes to spans.\n * This is only recorded if recordInputs is true.\n */\nfunction addPrivateRequestAttributes(span: Span, params: Record<string, unknown>): void {\n const messages = messagesFromParams(params);\n setMessagesAttribute(span, messages);\n\n if ('prompt' in params) {\n span.setAttributes({ [GEN_AI_PROMPT_ATTRIBUTE]: JSON.stringify(params.prompt) });\n }\n}\n\n/**\n * Add content attributes when recordOutputs is enabled\n */\nfunction addContentAttributes(span: Span, response: AnthropicAiResponse): void {\n // Messages.create\n if ('content' in response) {\n if (Array.isArray(response.content)) {\n span.setAttributes({\n [GEN_AI_RESPONSE_TEXT_ATTRIBUTE]: response.content\n .map((item: ContentBlock) => item.text)\n .filter(text => !!text)\n .join(''),\n });\n\n const toolCalls: Array<ContentBlock> = [];\n\n for (const item of response.content) {\n if (item.type === 'tool_use' || item.type === 'server_tool_use') {\n toolCalls.push(item);\n }\n }\n if (toolCalls.length > 0) {\n span.setAttributes({ [GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE]: JSON.stringify(toolCalls) });\n }\n }\n }\n // Completions.create\n if ('completion' in response) {\n span.setAttributes({ [GEN_AI_RESPONSE_TEXT_ATTRIBUTE]: response.completion });\n }\n // Models.countTokens\n if ('input_tokens' in response) {\n span.setAttributes({ [GEN_AI_RESPONSE_TEXT_ATTRIBUTE]: JSON.stringify(response.input_tokens) });\n }\n}\n\n/**\n * Add basic metadata attributes from the response\n */\nfunction addMetadataAttributes(span: Span, response: AnthropicAiResponse): void {\n if ('id' in response && 'model' in response) {\n span.setAttributes({\n [GEN_AI_RESPONSE_ID_ATTRIBUTE]: response.id,\n [GEN_AI_RESPONSE_MODEL_ATTRIBUTE]: response.model,\n });\n\n if ('usage' in response && response.usage) {\n setTokenUsageAttributes(\n span,\n response.usage.input_tokens,\n response.usage.output_tokens,\n response.usage.cache_creation_input_tokens,\n response.usage.cache_read_input_tokens,\n );\n }\n }\n}\n\n/**\n * Add response attributes to spans\n */\nfunction addResponseAttributes(span: Span, response: AnthropicAiResponse, recordOutputs?: boolean): void {\n if (!response || typeof response !== 'object') return;\n\n // capture error, do not add attributes if error (they shouldn't exist)\n if ('type' in response && response.type === 'error') {\n handleResponseError(span, response);\n return;\n }\n\n // Private response attributes that are only recorded if recordOutputs is true.\n if (recordOutputs) {\n addContentAttributes(span, response);\n }\n\n // Add basic metadata attributes\n addMetadataAttributes(span, response);\n}\n\n/**\n * Handle common error catching and reporting for streaming requests\n */\nfunction handleStreamingError(error: unknown, span: Span, methodPath: string): never {\n captureException(error, {\n mechanism: { handled: false, type: 'auto.ai.anthropic', data: { function: methodPath } },\n });\n\n if (span.isRecording()) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n span.end();\n }\n throw error;\n}\n\n/**\n * Handle streaming cases with common logic\n */\nfunction handleStreamingRequest<T extends unknown[], R>(\n originalMethod: (...args: T) => R | Promise<R>,\n target: (...args: T) => R | Promise<R>,\n context: unknown,\n args: T,\n requestAttributes: Record<string, unknown>,\n operationName: string,\n methodPath: string,\n params: Record<string, unknown> | undefined,\n options: AnthropicAiOptions,\n isStreamRequested: boolean,\n isStreamingMethod: boolean,\n): R | Promise<R> {\n const model = requestAttributes[GEN_AI_REQUEST_MODEL_ATTRIBUTE] ?? 'unknown';\n const spanConfig = {\n name: `${operationName} ${model}`,\n op: `gen_ai.${operationName}`,\n attributes: requestAttributes as Record<string, SpanAttributeValue>,\n };\n\n // messages.stream() always returns a sync MessageStream, even with stream: true param\n if (isStreamRequested && !isStreamingMethod) {\n let originalResult!: Promise<R>;\n\n const instrumentedPromise = startSpanManual(spanConfig, (span: Span) => {\n originalResult = originalMethod.apply(context, args) as Promise<R>;\n\n if (options.recordInputs && params) {\n addPrivateRequestAttributes(span, params);\n }\n\n return (async () => {\n try {\n const result = await originalResult;\n return instrumentAsyncIterableStream(\n result as AsyncIterable<AnthropicAiStreamingEvent>,\n span,\n options.recordOutputs ?? false,\n ) as unknown as R;\n } catch (error) {\n return handleStreamingError(error, span, methodPath);\n }\n })();\n });\n\n return wrapPromiseWithMethods(originalResult, instrumentedPromise, 'auto.ai.anthropic');\n } else {\n return startSpanManual(spanConfig, span => {\n try {\n if (options.recordInputs && params) {\n addPrivateRequestAttributes(span, params);\n }\n const messageStream = target.apply(context, args);\n return instrumentMessageStream(messageStream, span, options.recordOutputs ?? false);\n } catch (error) {\n return handleStreamingError(error, span, methodPath);\n }\n });\n }\n}\n\n/**\n * Instrument a method with Sentry spans\n * Following Sentry AI Agents Manual Instrumentation conventions\n * @see https://docs.sentry.io/platforms/javascript/guides/node/tracing/instrumentation/ai-agents-module/#manual-instrumentation\n */\nfunction instrumentMethod<T extends unknown[], R>(\n originalMethod: (...args: T) => R | Promise<R>,\n methodPath: string,\n instrumentedMethod: InstrumentedMethodEntry,\n context: unknown,\n options: AnthropicAiOptions,\n): (...args: T) => R | Promise<R> {\n return new Proxy(originalMethod, {\n apply(target, thisArg, args: T): R | Promise<R> {\n const operationName = instrumentedMethod.operation || 'unknown';\n const requestAttributes = extractRequestAttributes(args, methodPath, operationName);\n const model = requestAttributes[GEN_AI_REQUEST_MODEL_ATTRIBUTE] ?? 'unknown';\n\n const params = typeof args[0] === 'object' ? (args[0] as Record<string, unknown>) : undefined;\n const isStreamRequested = Boolean(params?.stream);\n const isStreamingMethod = instrumentedMethod.streaming === true;\n\n if (isStreamRequested || isStreamingMethod) {\n return handleStreamingRequest(\n originalMethod,\n target,\n context,\n args,\n requestAttributes,\n operationName,\n methodPath,\n params,\n options,\n isStreamRequested,\n isStreamingMethod,\n );\n }\n\n let originalResult!: Promise<R>;\n\n const instrumentedPromise = startSpan(\n {\n name: `${operationName} ${model}`,\n op: `gen_ai.${operationName}`,\n attributes: requestAttributes as Record<string, SpanAttributeValue>,\n },\n span => {\n originalResult = target.apply(context, args) as Promise<R>;\n\n if (options.recordInputs && params) {\n addPrivateRequestAttributes(span, params);\n }\n\n return originalResult.then(\n result => {\n addResponseAttributes(span, result as AnthropicAiResponse, options.recordOutputs);\n return result;\n },\n error => {\n captureException(error, {\n mechanism: {\n handled: false,\n type: 'auto.ai.anthropic',\n data: {\n function: methodPath,\n },\n },\n });\n throw error;\n },\n );\n },\n );\n\n return wrapPromiseWithMethods(originalResult, instrumentedPromise, 'auto.ai.anthropic');\n },\n }) as (...args: T) => R | Promise<R>;\n}\n\n/**\n * Create a deep proxy for Anthropic AI client instrumentation\n */\nfunction createDeepProxy<T extends object>(target: T, currentPath = '', options: AnthropicAiOptions): T {\n return new Proxy(target, {\n get(obj: object, prop: string): unknown {\n const value = (obj as Record<string, unknown>)[prop];\n const methodPath = buildMethodPath(currentPath, String(prop));\n\n const instrumentedMethod = ANTHROPIC_METHOD_REGISTRY[methodPath as keyof typeof ANTHROPIC_METHOD_REGISTRY];\n if (typeof value === 'function' && instrumentedMethod) {\n return instrumentMethod(\n value as (...args: unknown[]) => unknown | Promise<unknown>,\n methodPath,\n instrumentedMethod,\n obj,\n options,\n );\n }\n\n if (typeof value === 'function') {\n // Bind non-instrumented functions to preserve the original `this` context,\n return value.bind(obj);\n }\n\n if (value && typeof value === 'object') {\n return createDeepProxy(value, methodPath, options);\n }\n\n return value;\n },\n }) as T;\n}\n\n/**\n * Instrument an Anthropic AI client with Sentry tracing\n * Can be used across Node.js, Cloudflare Workers, and Vercel Edge\n *\n * @template T - The type of the client that extends object\n * @param client - The Anthropic AI client to instrument\n * @param options - Optional configuration for recording inputs and outputs\n * @returns The instrumented client with the same type as the input\n */\nexport function instrumentAnthropicAiClient<T extends object>(anthropicAiClient: T, options?: AnthropicAiOptions): T {\n return createDeepProxy(anthropicAiClient, '', resolveAIRecordingOptions(options));\n}\n"],"names":["GEN_AI_SYSTEM_ATTRIBUTE","GEN_AI_OPERATION_NAME_ATTRIBUTE","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","GEN_AI_REQUEST_AVAILABLE_TOOLS_ATTRIBUTE","GEN_AI_REQUEST_MODEL_ATTRIBUTE","GEN_AI_REQUEST_TEMPERATURE_ATTRIBUTE","GEN_AI_REQUEST_TOP_P_ATTRIBUTE","GEN_AI_REQUEST_STREAM_ATTRIBUTE","GEN_AI_REQUEST_TOP_K_ATTRIBUTE","GEN_AI_REQUEST_FREQUENCY_PENALTY_ATTRIBUTE","GEN_AI_REQUEST_MAX_TOKENS_ATTRIBUTE","messagesFromParams","setMessagesAttribute","GEN_AI_PROMPT_ATTRIBUTE","GEN_AI_RESPONSE_TEXT_ATTRIBUTE","GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE","GEN_AI_RESPONSE_ID_ATTRIBUTE","GEN_AI_RESPONSE_MODEL_ATTRIBUTE","setTokenUsageAttributes","handleResponseError","captureException","SPAN_STATUS_ERROR","startSpanManual","instrumentAsyncIterableStream","wrapPromiseWithMethods","instrumentMessageStream","startSpan","buildMethodPath","ANTHROPIC_METHOD_REGISTRY","resolveAIRecordingOptions"],"mappings":"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"}
@@ -2,7 +2,6 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
 
3
3
  const _exports = require('../../exports.js');
4
4
  const spanstatus = require('../spanstatus.js');
5
- const genAiAttributes = require('../ai/gen-ai-attributes.js');
6
5
  const utils = require('../ai/utils.js');
7
6
  const utils$1 = require('./utils.js');
8
7
 
@@ -172,60 +171,6 @@ function processEvent(
172
171
  handleContentBlockStop(event, state);
173
172
  }
174
173
 
175
- /**
176
- * Finalizes span attributes when stream processing completes
177
- */
178
- function finalizeStreamSpan(state, span, recordOutputs) {
179
- if (!span.isRecording()) {
180
- return;
181
- }
182
-
183
- // Set common response attributes if available
184
- if (state.responseId) {
185
- span.setAttributes({
186
- [genAiAttributes.GEN_AI_RESPONSE_ID_ATTRIBUTE]: state.responseId,
187
- });
188
- }
189
- if (state.responseModel) {
190
- span.setAttributes({
191
- [genAiAttributes.GEN_AI_RESPONSE_MODEL_ATTRIBUTE]: state.responseModel,
192
- });
193
- }
194
-
195
- utils.setTokenUsageAttributes(
196
- span,
197
- state.promptTokens,
198
- state.completionTokens,
199
- state.cacheCreationInputTokens,
200
- state.cacheReadInputTokens,
201
- );
202
-
203
- span.setAttributes({
204
- [genAiAttributes.GEN_AI_RESPONSE_STREAMING_ATTRIBUTE]: true,
205
- });
206
-
207
- if (state.finishReasons.length > 0) {
208
- span.setAttributes({
209
- [genAiAttributes.GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE]: JSON.stringify(state.finishReasons),
210
- });
211
- }
212
-
213
- if (recordOutputs && state.responseTexts.length > 0) {
214
- span.setAttributes({
215
- [genAiAttributes.GEN_AI_RESPONSE_TEXT_ATTRIBUTE]: state.responseTexts.join(''),
216
- });
217
- }
218
-
219
- // Set tool calls if any were captured
220
- if (recordOutputs && state.toolCalls.length > 0) {
221
- span.setAttributes({
222
- [genAiAttributes.GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE]: JSON.stringify(state.toolCalls),
223
- });
224
- }
225
-
226
- span.end();
227
- }
228
-
229
174
  /**
230
175
  * Instruments an async iterable stream of Anthropic events, updates the span with
231
176
  * streaming attributes and (optionally) the aggregated output text, and yields
@@ -255,50 +200,7 @@ async function* instrumentAsyncIterableStream(
255
200
  yield event;
256
201
  }
257
202
  } finally {
258
- // Set common response attributes if available
259
- if (state.responseId) {
260
- span.setAttributes({
261
- [genAiAttributes.GEN_AI_RESPONSE_ID_ATTRIBUTE]: state.responseId,
262
- });
263
- }
264
- if (state.responseModel) {
265
- span.setAttributes({
266
- [genAiAttributes.GEN_AI_RESPONSE_MODEL_ATTRIBUTE]: state.responseModel,
267
- });
268
- }
269
-
270
- utils.setTokenUsageAttributes(
271
- span,
272
- state.promptTokens,
273
- state.completionTokens,
274
- state.cacheCreationInputTokens,
275
- state.cacheReadInputTokens,
276
- );
277
-
278
- span.setAttributes({
279
- [genAiAttributes.GEN_AI_RESPONSE_STREAMING_ATTRIBUTE]: true,
280
- });
281
-
282
- if (state.finishReasons.length > 0) {
283
- span.setAttributes({
284
- [genAiAttributes.GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE]: JSON.stringify(state.finishReasons),
285
- });
286
- }
287
-
288
- if (recordOutputs && state.responseTexts.length > 0) {
289
- span.setAttributes({
290
- [genAiAttributes.GEN_AI_RESPONSE_TEXT_ATTRIBUTE]: state.responseTexts.join(''),
291
- });
292
- }
293
-
294
- // Set tool calls if any were captured
295
- if (recordOutputs && state.toolCalls.length > 0) {
296
- span.setAttributes({
297
- [genAiAttributes.GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE]: JSON.stringify(state.toolCalls),
298
- });
299
- }
300
-
301
- span.end();
203
+ utils.endStreamSpan(span, state, recordOutputs);
302
204
  }
303
205
  }
304
206
 
@@ -330,7 +232,7 @@ function instrumentMessageStream(
330
232
  // The event fired when a message is done being streamed by the API. Corresponds to the message_stop SSE event.
331
233
  // @see https://github.com/anthropics/anthropic-sdk-typescript/blob/d3be31f5a4e6ebb4c0a2f65dbb8f381ae73a9166/helpers.md?plain=1#L42-L44
332
234
  stream.on('message', () => {
333
- finalizeStreamSpan(state, span, recordOutputs);
235
+ utils.endStreamSpan(span, state, recordOutputs);
334
236
  });
335
237
 
336
238
  stream.on('error', (error) => {