@sentry/core 10.37.0 → 10.39.0-alpha.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 (296) hide show
  1. package/build/cjs/attributes.js.map +1 -1
  2. package/build/cjs/client.js +22 -12
  3. package/build/cjs/client.js.map +1 -1
  4. package/build/cjs/envelope.js +41 -7
  5. package/build/cjs/envelope.js.map +1 -1
  6. package/build/cjs/index.js +131 -79
  7. package/build/cjs/index.js.map +1 -1
  8. package/build/cjs/integration.js +12 -0
  9. package/build/cjs/integration.js.map +1 -1
  10. package/build/cjs/integrations/captureconsole.js +2 -2
  11. package/build/cjs/integrations/captureconsole.js.map +1 -1
  12. package/build/cjs/integrations/eventFilters.js +1 -1
  13. package/build/cjs/integrations/eventFilters.js.map +1 -1
  14. package/build/cjs/integrations/mcp-server/correlation.js +54 -10
  15. package/build/cjs/integrations/mcp-server/correlation.js.map +1 -1
  16. package/build/cjs/integrations/mcp-server/errorCapture.js +2 -2
  17. package/build/cjs/integrations/mcp-server/errorCapture.js.map +1 -1
  18. package/build/cjs/integrations/mcp-server/sessionManagement.js +50 -16
  19. package/build/cjs/integrations/mcp-server/sessionManagement.js.map +1 -1
  20. package/build/cjs/integrations/requestdata.js +72 -6
  21. package/build/cjs/integrations/requestdata.js.map +1 -1
  22. package/build/cjs/integrations/spanStreaming.js +54 -0
  23. package/build/cjs/integrations/spanStreaming.js.map +1 -0
  24. package/build/cjs/integrations/supabase.js +4 -4
  25. package/build/cjs/integrations/supabase.js.map +1 -1
  26. package/build/cjs/metrics/public-api.js +3 -3
  27. package/build/cjs/metrics/public-api.js.map +1 -1
  28. package/build/cjs/scope.js +1 -1
  29. package/build/cjs/scope.js.map +1 -1
  30. package/build/cjs/semanticAttributes.js +84 -0
  31. package/build/cjs/semanticAttributes.js.map +1 -1
  32. package/build/cjs/spans/captureSpan.js +104 -0
  33. package/build/cjs/spans/captureSpan.js.map +1 -0
  34. package/build/cjs/spans/spanBuffer.js +121 -0
  35. package/build/cjs/spans/spanBuffer.js.map +1 -0
  36. package/build/cjs/spans/spanFirstUtils.js +186 -0
  37. package/build/cjs/spans/spanFirstUtils.js.map +1 -0
  38. package/build/cjs/tracing/ai/gen-ai-attributes.js +6 -0
  39. package/build/cjs/tracing/ai/gen-ai-attributes.js.map +1 -1
  40. package/build/cjs/tracing/anthropic-ai/index.js +3 -3
  41. package/build/cjs/tracing/anthropic-ai/index.js.map +1 -1
  42. package/build/cjs/tracing/anthropic-ai/streaming.js +3 -3
  43. package/build/cjs/tracing/anthropic-ai/streaming.js.map +1 -1
  44. package/build/cjs/tracing/anthropic-ai/utils.js +2 -2
  45. package/build/cjs/tracing/anthropic-ai/utils.js.map +1 -1
  46. package/build/cjs/tracing/google-genai/index.js +3 -3
  47. package/build/cjs/tracing/google-genai/index.js.map +1 -1
  48. package/build/cjs/tracing/google-genai/streaming.js +2 -2
  49. package/build/cjs/tracing/google-genai/streaming.js.map +1 -1
  50. package/build/cjs/tracing/langchain/index.js +4 -4
  51. package/build/cjs/tracing/langchain/index.js.map +1 -1
  52. package/build/cjs/tracing/langgraph/index.js +3 -3
  53. package/build/cjs/tracing/langgraph/index.js.map +1 -1
  54. package/build/cjs/tracing/openai/index.js +136 -53
  55. package/build/cjs/tracing/openai/index.js.map +1 -1
  56. package/build/cjs/tracing/openai/streaming.js +2 -2
  57. package/build/cjs/tracing/openai/streaming.js.map +1 -1
  58. package/build/cjs/tracing/sentrySpan.js +32 -0
  59. package/build/cjs/tracing/sentrySpan.js.map +1 -1
  60. package/build/cjs/tracing/trace.js +1 -0
  61. package/build/cjs/tracing/trace.js.map +1 -1
  62. package/build/cjs/tracing/vercel-ai/constants.js +4 -0
  63. package/build/cjs/tracing/vercel-ai/constants.js.map +1 -1
  64. package/build/cjs/tracing/vercel-ai/index.js +14 -0
  65. package/build/cjs/tracing/vercel-ai/index.js.map +1 -1
  66. package/build/cjs/tracing/vercel-ai/utils.js +71 -22
  67. package/build/cjs/tracing/vercel-ai/utils.js.map +1 -1
  68. package/build/cjs/transports/base.js +18 -2
  69. package/build/cjs/transports/base.js.map +1 -1
  70. package/build/cjs/transports/offline.js +16 -17
  71. package/build/cjs/transports/offline.js.map +1 -1
  72. package/build/cjs/trpc.js +3 -3
  73. package/build/cjs/trpc.js.map +1 -1
  74. package/build/cjs/utils/aggregate-errors.js +13 -5
  75. package/build/cjs/utils/aggregate-errors.js.map +1 -1
  76. package/build/cjs/utils/beforeSendSpan.js +36 -0
  77. package/build/cjs/utils/beforeSendSpan.js.map +1 -0
  78. package/build/cjs/utils/envToBool.js +32 -0
  79. package/build/cjs/utils/envToBool.js.map +1 -0
  80. package/build/cjs/utils/exports.js +7 -7
  81. package/build/cjs/utils/exports.js.map +1 -1
  82. package/build/cjs/utils/featureFlags.js +1 -0
  83. package/build/cjs/utils/featureFlags.js.map +1 -1
  84. package/build/cjs/utils/flushIfServerless.js +2 -2
  85. package/build/cjs/utils/flushIfServerless.js.map +1 -1
  86. package/build/cjs/utils/hasSpanStreamingEnabled.js +21 -0
  87. package/build/cjs/utils/hasSpanStreamingEnabled.js.map +1 -0
  88. package/build/cjs/utils/prepareEvent.js +6 -1
  89. package/build/cjs/utils/prepareEvent.js.map +1 -1
  90. package/build/cjs/utils/promisebuffer.js +5 -3
  91. package/build/cjs/utils/promisebuffer.js.map +1 -1
  92. package/build/cjs/utils/scopeData.js +4 -0
  93. package/build/cjs/utils/scopeData.js.map +1 -1
  94. package/build/cjs/utils/sdkMetadata.js +7 -11
  95. package/build/cjs/utils/sdkMetadata.js.map +1 -1
  96. package/build/cjs/utils/should-ignore-span.js +31 -9
  97. package/build/cjs/utils/should-ignore-span.js.map +1 -1
  98. package/build/cjs/utils/spanUtils.js +90 -2
  99. package/build/cjs/utils/spanUtils.js.map +1 -1
  100. package/build/cjs/utils/timer.js +20 -0
  101. package/build/cjs/utils/timer.js.map +1 -0
  102. package/build/cjs/utils/traceData.js +2 -2
  103. package/build/cjs/utils/traceData.js.map +1 -1
  104. package/build/cjs/utils/tracePropagationTargets.js +38 -0
  105. package/build/cjs/utils/tracePropagationTargets.js.map +1 -0
  106. package/build/cjs/utils/version.js +1 -1
  107. package/build/cjs/utils/version.js.map +1 -1
  108. package/build/esm/attributes.js.map +1 -1
  109. package/build/esm/client.js +18 -8
  110. package/build/esm/client.js.map +1 -1
  111. package/build/esm/envelope.js +41 -8
  112. package/build/esm/envelope.js.map +1 -1
  113. package/build/esm/exports.js +2 -2
  114. package/build/esm/feedback.js +1 -1
  115. package/build/esm/index.js +12 -3
  116. package/build/esm/index.js.map +1 -1
  117. package/build/esm/integration.js +12 -1
  118. package/build/esm/integration.js.map +1 -1
  119. package/build/esm/integrations/eventFilters.js +1 -1
  120. package/build/esm/integrations/eventFilters.js.map +1 -1
  121. package/build/esm/integrations/mcp-server/correlation.js +54 -10
  122. package/build/esm/integrations/mcp-server/correlation.js.map +1 -1
  123. package/build/esm/integrations/mcp-server/sessionManagement.js +50 -16
  124. package/build/esm/integrations/mcp-server/sessionManagement.js.map +1 -1
  125. package/build/esm/integrations/moduleMetadata.js +1 -1
  126. package/build/esm/integrations/requestdata.js +72 -6
  127. package/build/esm/integrations/requestdata.js.map +1 -1
  128. package/build/esm/integrations/spanStreaming.js +52 -0
  129. package/build/esm/integrations/spanStreaming.js.map +1 -0
  130. package/build/esm/integrations/third-party-errors-filter.js +1 -1
  131. package/build/esm/logs/internal.js +1 -1
  132. package/build/esm/metrics/public-api.js +3 -3
  133. package/build/esm/metrics/public-api.js.map +1 -1
  134. package/build/esm/package.json +1 -1
  135. package/build/esm/scope.js +1 -1
  136. package/build/esm/scope.js.map +1 -1
  137. package/build/esm/semanticAttributes.js +57 -1
  138. package/build/esm/semanticAttributes.js.map +1 -1
  139. package/build/esm/spans/captureSpan.js +102 -0
  140. package/build/esm/spans/captureSpan.js.map +1 -0
  141. package/build/esm/spans/spanBuffer.js +119 -0
  142. package/build/esm/spans/spanBuffer.js.map +1 -0
  143. package/build/esm/spans/spanFirstUtils.js +182 -0
  144. package/build/esm/spans/spanFirstUtils.js.map +1 -0
  145. package/build/esm/tracing/ai/gen-ai-attributes.js +6 -1
  146. package/build/esm/tracing/ai/gen-ai-attributes.js.map +1 -1
  147. package/build/esm/tracing/measurement.js +1 -1
  148. package/build/esm/tracing/openai/index.js +134 -51
  149. package/build/esm/tracing/openai/index.js.map +1 -1
  150. package/build/esm/tracing/sentrySpan.js +33 -1
  151. package/build/esm/tracing/sentrySpan.js.map +1 -1
  152. package/build/esm/tracing/trace.js +4 -3
  153. package/build/esm/tracing/trace.js.map +1 -1
  154. package/build/esm/tracing/vercel-ai/constants.js +4 -1
  155. package/build/esm/tracing/vercel-ai/constants.js.map +1 -1
  156. package/build/esm/tracing/vercel-ai/index.js +15 -1
  157. package/build/esm/tracing/vercel-ai/index.js.map +1 -1
  158. package/build/esm/tracing/vercel-ai/utils.js +73 -24
  159. package/build/esm/tracing/vercel-ai/utils.js.map +1 -1
  160. package/build/esm/transports/base.js +18 -2
  161. package/build/esm/transports/base.js.map +1 -1
  162. package/build/esm/transports/offline.js +16 -17
  163. package/build/esm/transports/offline.js.map +1 -1
  164. package/build/esm/utils/aggregate-errors.js +13 -5
  165. package/build/esm/utils/aggregate-errors.js.map +1 -1
  166. package/build/esm/utils/beforeSendSpan.js +33 -0
  167. package/build/esm/utils/beforeSendSpan.js.map +1 -0
  168. package/build/esm/utils/envToBool.js +28 -0
  169. package/build/esm/utils/envToBool.js.map +1 -0
  170. package/build/esm/utils/exports.js +7 -7
  171. package/build/esm/utils/exports.js.map +1 -1
  172. package/build/esm/utils/featureFlags.js +1 -0
  173. package/build/esm/utils/featureFlags.js.map +1 -1
  174. package/build/esm/utils/flushIfServerless.js.map +1 -1
  175. package/build/esm/utils/hasSpanStreamingEnabled.js +19 -0
  176. package/build/esm/utils/hasSpanStreamingEnabled.js.map +1 -0
  177. package/build/esm/utils/prepareEvent.js +6 -1
  178. package/build/esm/utils/prepareEvent.js.map +1 -1
  179. package/build/esm/utils/promisebuffer.js +5 -3
  180. package/build/esm/utils/promisebuffer.js.map +1 -1
  181. package/build/esm/utils/scopeData.js +4 -0
  182. package/build/esm/utils/scopeData.js.map +1 -1
  183. package/build/esm/utils/sdkMetadata.js +7 -11
  184. package/build/esm/utils/sdkMetadata.js.map +1 -1
  185. package/build/esm/utils/should-ignore-span.js +31 -9
  186. package/build/esm/utils/should-ignore-span.js.map +1 -1
  187. package/build/esm/utils/spanUtils.js +87 -3
  188. package/build/esm/utils/spanUtils.js.map +1 -1
  189. package/build/esm/utils/timer.js +18 -0
  190. package/build/esm/utils/timer.js.map +1 -0
  191. package/build/esm/utils/tracePropagationTargets.js +36 -0
  192. package/build/esm/utils/tracePropagationTargets.js.map +1 -0
  193. package/build/esm/utils/version.js +1 -1
  194. package/build/esm/utils/version.js.map +1 -1
  195. package/build/types/attributes.d.ts +1 -1
  196. package/build/types/attributes.d.ts.map +1 -1
  197. package/build/types/client.d.ts +40 -2
  198. package/build/types/client.d.ts.map +1 -1
  199. package/build/types/envelope.d.ts +6 -1
  200. package/build/types/envelope.d.ts.map +1 -1
  201. package/build/types/index.d.ts +13 -4
  202. package/build/types/index.d.ts.map +1 -1
  203. package/build/types/integration.d.ts +4 -0
  204. package/build/types/integration.d.ts.map +1 -1
  205. package/build/types/integrations/mcp-server/correlation.d.ts +6 -2
  206. package/build/types/integrations/mcp-server/correlation.d.ts.map +1 -1
  207. package/build/types/integrations/mcp-server/sessionManagement.d.ts +8 -2
  208. package/build/types/integrations/mcp-server/sessionManagement.d.ts.map +1 -1
  209. package/build/types/integrations/requestdata.d.ts.map +1 -1
  210. package/build/types/integrations/spanStreaming.d.ts +11 -0
  211. package/build/types/integrations/spanStreaming.d.ts.map +1 -0
  212. package/build/types/metrics/public-api.d.ts +3 -3
  213. package/build/types/semanticAttributes.d.ts +38 -0
  214. package/build/types/semanticAttributes.d.ts.map +1 -1
  215. package/build/types/spans/captureSpan.d.ts +10 -0
  216. package/build/types/spans/captureSpan.d.ts.map +1 -0
  217. package/build/types/spans/spanBuffer.d.ts +35 -0
  218. package/build/types/spans/spanBuffer.d.ts.map +1 -0
  219. package/build/types/spans/spanFirstUtils.d.ts +20 -0
  220. package/build/types/spans/spanFirstUtils.d.ts.map +1 -0
  221. package/build/types/tracing/ai/gen-ai-attributes.d.ts +4 -0
  222. package/build/types/tracing/ai/gen-ai-attributes.d.ts.map +1 -1
  223. package/build/types/tracing/openai/index.d.ts.map +1 -1
  224. package/build/types/tracing/sentrySpan.d.ts +10 -1
  225. package/build/types/tracing/sentrySpan.d.ts.map +1 -1
  226. package/build/types/tracing/vercel-ai/constants.d.ts +1 -0
  227. package/build/types/tracing/vercel-ai/constants.d.ts.map +1 -1
  228. package/build/types/tracing/vercel-ai/index.d.ts.map +1 -1
  229. package/build/types/tracing/vercel-ai/utils.d.ts +2 -2
  230. package/build/types/tracing/vercel-ai/utils.d.ts.map +1 -1
  231. package/build/types/transports/base.d.ts.map +1 -1
  232. package/build/types/transports/offline.d.ts.map +1 -1
  233. package/build/types/types-hoist/attributes.d.ts +19 -0
  234. package/build/types/types-hoist/attributes.d.ts.map +1 -0
  235. package/build/types/types-hoist/envelope.d.ts +22 -2
  236. package/build/types/types-hoist/envelope.d.ts.map +1 -1
  237. package/build/types/types-hoist/feedback/index.d.ts.map +1 -1
  238. package/build/types/types-hoist/integration.d.ts +7 -0
  239. package/build/types/types-hoist/integration.d.ts.map +1 -1
  240. package/build/types/types-hoist/link.d.ts +2 -2
  241. package/build/types/types-hoist/link.d.ts.map +1 -1
  242. package/build/types/types-hoist/options.d.ts +18 -2
  243. package/build/types/types-hoist/options.d.ts.map +1 -1
  244. package/build/types/types-hoist/span.d.ts +27 -0
  245. package/build/types/types-hoist/span.d.ts.map +1 -1
  246. package/build/types/utils/beforeSendSpan.d.ts +22 -0
  247. package/build/types/utils/beforeSendSpan.d.ts.map +1 -0
  248. package/build/types/utils/envToBool.d.ts +13 -0
  249. package/build/types/utils/envToBool.d.ts.map +1 -0
  250. package/build/types/utils/featureFlags.d.ts.map +1 -1
  251. package/build/types/utils/flushIfServerless.d.ts.map +1 -1
  252. package/build/types/utils/hasSpanStreamingEnabled.d.ts +9 -0
  253. package/build/types/utils/hasSpanStreamingEnabled.d.ts.map +1 -0
  254. package/build/types/utils/prepareEvent.d.ts.map +1 -1
  255. package/build/types/utils/promisebuffer.d.ts.map +1 -1
  256. package/build/types/utils/scopeData.d.ts.map +1 -1
  257. package/build/types/utils/sdkMetadata.d.ts.map +1 -1
  258. package/build/types/utils/should-ignore-span.d.ts +3 -3
  259. package/build/types/utils/should-ignore-span.d.ts.map +1 -1
  260. package/build/types/utils/spanUtils.d.ts +22 -2
  261. package/build/types/utils/spanUtils.d.ts.map +1 -1
  262. package/build/types/utils/timer.d.ts +11 -0
  263. package/build/types/utils/timer.d.ts.map +1 -0
  264. package/build/types/utils/tracePropagationTargets.d.ts +9 -0
  265. package/build/types/utils/tracePropagationTargets.d.ts.map +1 -0
  266. package/build/types-ts3.8/attributes.d.ts +1 -1
  267. package/build/types-ts3.8/client.d.ts +40 -2
  268. package/build/types-ts3.8/envelope.d.ts +6 -1
  269. package/build/types-ts3.8/index.d.ts +13 -4
  270. package/build/types-ts3.8/integration.d.ts +4 -0
  271. package/build/types-ts3.8/integrations/mcp-server/correlation.d.ts +6 -2
  272. package/build/types-ts3.8/integrations/mcp-server/sessionManagement.d.ts +8 -2
  273. package/build/types-ts3.8/integrations/spanStreaming.d.ts +11 -0
  274. package/build/types-ts3.8/metrics/public-api.d.ts +3 -3
  275. package/build/types-ts3.8/semanticAttributes.d.ts +38 -0
  276. package/build/types-ts3.8/spans/captureSpan.d.ts +10 -0
  277. package/build/types-ts3.8/spans/spanBuffer.d.ts +35 -0
  278. package/build/types-ts3.8/spans/spanFirstUtils.d.ts +20 -0
  279. package/build/types-ts3.8/tracing/ai/gen-ai-attributes.d.ts +4 -0
  280. package/build/types-ts3.8/tracing/sentrySpan.d.ts +10 -1
  281. package/build/types-ts3.8/tracing/vercel-ai/constants.d.ts +1 -0
  282. package/build/types-ts3.8/tracing/vercel-ai/utils.d.ts +2 -2
  283. package/build/types-ts3.8/types-hoist/attributes.d.ts +19 -0
  284. package/build/types-ts3.8/types-hoist/envelope.d.ts +22 -2
  285. package/build/types-ts3.8/types-hoist/integration.d.ts +7 -0
  286. package/build/types-ts3.8/types-hoist/link.d.ts +2 -2
  287. package/build/types-ts3.8/types-hoist/options.d.ts +18 -2
  288. package/build/types-ts3.8/types-hoist/span.d.ts +27 -0
  289. package/build/types-ts3.8/utils/beforeSendSpan.d.ts +22 -0
  290. package/build/types-ts3.8/utils/envToBool.d.ts +13 -0
  291. package/build/types-ts3.8/utils/hasSpanStreamingEnabled.d.ts +9 -0
  292. package/build/types-ts3.8/utils/should-ignore-span.d.ts +3 -3
  293. package/build/types-ts3.8/utils/spanUtils.d.ts +22 -2
  294. package/build/types-ts3.8/utils/timer.d.ts +11 -0
  295. package/build/types-ts3.8/utils/tracePropagationTargets.d.ts +9 -0
  296. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"streaming.js","sources":["../../../../src/tracing/google-genai/streaming.ts"],"sourcesContent":["import { captureException } from '../../exports';\nimport { SPAN_STATUS_ERROR } from '../../tracing';\nimport type { Span, SpanAttributeValue } from '../../types-hoist/span';\nimport {\n GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE,\n GEN_AI_RESPONSE_ID_ATTRIBUTE,\n GEN_AI_RESPONSE_MODEL_ATTRIBUTE,\n GEN_AI_RESPONSE_STREAMING_ATTRIBUTE,\n GEN_AI_RESPONSE_TEXT_ATTRIBUTE,\n GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE,\n GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE,\n GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE,\n GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE,\n} from '../ai/gen-ai-attributes';\nimport type { GoogleGenAIResponse } from './types';\n\n/**\n * State object used to accumulate information from a stream of Google GenAI events.\n */\ninterface StreamingState {\n /** Collected response text fragments (for output recording). */\n responseTexts: string[];\n /** Reasons for finishing the response, as reported by the API. */\n finishReasons: string[];\n /** The response ID. */\n responseId?: string;\n /** The model name. */\n responseModel?: string;\n /** Number of prompt/input tokens used. */\n promptTokens?: number;\n /** Number of completion/output tokens used. */\n completionTokens?: number;\n /** Number of total tokens used. */\n totalTokens?: number;\n /** Accumulated tool calls (finalized) */\n toolCalls: Array<Record<string, unknown>>;\n}\n\n/**\n * Checks if a response chunk contains an error\n * @param chunk - The response chunk to check\n * @param span - The span to update if error is found\n * @returns Whether an error occurred\n */\nfunction isErrorChunk(chunk: GoogleGenAIResponse, span: Span): boolean {\n const feedback = chunk?.promptFeedback;\n if (feedback?.blockReason) {\n const message = feedback.blockReasonMessage ?? feedback.blockReason;\n span.setStatus({ code: SPAN_STATUS_ERROR, message: `Content blocked: ${message}` });\n captureException(`Content blocked: ${message}`, {\n mechanism: { handled: false, type: 'auto.ai.google_genai' },\n });\n return true;\n }\n return false;\n}\n\n/**\n * Processes response metadata from a chunk\n * @param chunk - The response chunk to process\n * @param state - The state of the streaming process\n */\nfunction handleResponseMetadata(chunk: GoogleGenAIResponse, state: StreamingState): void {\n if (typeof chunk.responseId === 'string') state.responseId = chunk.responseId;\n if (typeof chunk.modelVersion === 'string') state.responseModel = chunk.modelVersion;\n\n const usage = chunk.usageMetadata;\n if (usage) {\n if (typeof usage.promptTokenCount === 'number') state.promptTokens = usage.promptTokenCount;\n if (typeof usage.candidatesTokenCount === 'number') state.completionTokens = usage.candidatesTokenCount;\n if (typeof usage.totalTokenCount === 'number') state.totalTokens = usage.totalTokenCount;\n }\n}\n\n/**\n * Processes candidate content from a response chunk\n * @param chunk - The response chunk to process\n * @param state - The state of the streaming process\n * @param recordOutputs - Whether to record outputs\n */\nfunction handleCandidateContent(chunk: GoogleGenAIResponse, state: StreamingState, recordOutputs: boolean): void {\n if (Array.isArray(chunk.functionCalls)) {\n state.toolCalls.push(...chunk.functionCalls);\n }\n\n for (const candidate of chunk.candidates ?? []) {\n if (candidate?.finishReason && !state.finishReasons.includes(candidate.finishReason)) {\n state.finishReasons.push(candidate.finishReason);\n }\n\n for (const part of candidate?.content?.parts ?? []) {\n if (recordOutputs && part.text) state.responseTexts.push(part.text);\n if (part.functionCall) {\n state.toolCalls.push({\n type: 'function',\n id: part.functionCall.id,\n name: part.functionCall.name,\n arguments: part.functionCall.args,\n });\n }\n }\n }\n}\n\n/**\n * Processes a single chunk from the Google GenAI stream\n * @param chunk - The chunk to process\n * @param state - The state of the streaming process\n * @param recordOutputs - Whether to record outputs\n * @param span - The span to update\n */\nfunction processChunk(chunk: GoogleGenAIResponse, state: StreamingState, recordOutputs: boolean, span: Span): void {\n if (!chunk || isErrorChunk(chunk, span)) return;\n handleResponseMetadata(chunk, state);\n handleCandidateContent(chunk, state, recordOutputs);\n}\n\n/**\n * Instruments an async iterable stream of Google GenAI response chunks, updates the span with\n * streaming attributes and (optionally) the aggregated output text, and yields\n * each chunk from the input stream unchanged.\n */\nexport async function* instrumentStream(\n stream: AsyncIterable<GoogleGenAIResponse>,\n span: Span,\n recordOutputs: boolean,\n): AsyncGenerator<GoogleGenAIResponse, void, unknown> {\n const state: StreamingState = {\n responseTexts: [],\n finishReasons: [],\n toolCalls: [],\n };\n\n try {\n for await (const chunk of stream) {\n processChunk(chunk, state, recordOutputs, span);\n yield chunk;\n }\n } finally {\n const attrs: Record<string, SpanAttributeValue> = {\n [GEN_AI_RESPONSE_STREAMING_ATTRIBUTE]: true,\n };\n\n if (state.responseId) attrs[GEN_AI_RESPONSE_ID_ATTRIBUTE] = state.responseId;\n if (state.responseModel) attrs[GEN_AI_RESPONSE_MODEL_ATTRIBUTE] = state.responseModel;\n if (state.promptTokens !== undefined) attrs[GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE] = state.promptTokens;\n if (state.completionTokens !== undefined) attrs[GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE] = state.completionTokens;\n if (state.totalTokens !== undefined) attrs[GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE] = state.totalTokens;\n\n if (state.finishReasons.length) {\n attrs[GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE] = JSON.stringify(state.finishReasons);\n }\n if (recordOutputs && state.responseTexts.length) {\n attrs[GEN_AI_RESPONSE_TEXT_ATTRIBUTE] = state.responseTexts.join('');\n }\n if (recordOutputs && state.toolCalls.length) {\n attrs[GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE] = JSON.stringify(state.toolCalls);\n }\n\n span.setAttributes(attrs);\n span.end();\n }\n}\n"],"names":["SPAN_STATUS_ERROR","captureException","GEN_AI_RESPONSE_STREAMING_ATTRIBUTE","GEN_AI_RESPONSE_ID_ATTRIBUTE","GEN_AI_RESPONSE_MODEL_ATTRIBUTE","GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE","GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE","GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE","GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE","GEN_AI_RESPONSE_TEXT_ATTRIBUTE","GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE"],"mappings":"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"}
1
+ {"version":3,"file":"streaming.js","sources":["../../../../src/tracing/google-genai/streaming.ts"],"sourcesContent":["import { captureException } from '../../exports';\nimport { SPAN_STATUS_ERROR } from '../../tracing';\nimport type { Span, SpanAttributeValue } from '../../types-hoist/span';\nimport {\n GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE,\n GEN_AI_RESPONSE_ID_ATTRIBUTE,\n GEN_AI_RESPONSE_MODEL_ATTRIBUTE,\n GEN_AI_RESPONSE_STREAMING_ATTRIBUTE,\n GEN_AI_RESPONSE_TEXT_ATTRIBUTE,\n GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE,\n GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE,\n GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE,\n GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE,\n} from '../ai/gen-ai-attributes';\nimport type { GoogleGenAIResponse } from './types';\n\n/**\n * State object used to accumulate information from a stream of Google GenAI events.\n */\ninterface StreamingState {\n /** Collected response text fragments (for output recording). */\n responseTexts: string[];\n /** Reasons for finishing the response, as reported by the API. */\n finishReasons: string[];\n /** The response ID. */\n responseId?: string;\n /** The model name. */\n responseModel?: string;\n /** Number of prompt/input tokens used. */\n promptTokens?: number;\n /** Number of completion/output tokens used. */\n completionTokens?: number;\n /** Number of total tokens used. */\n totalTokens?: number;\n /** Accumulated tool calls (finalized) */\n toolCalls: Array<Record<string, unknown>>;\n}\n\n/**\n * Checks if a response chunk contains an error\n * @param chunk - The response chunk to check\n * @param span - The span to update if error is found\n * @returns Whether an error occurred\n */\nfunction isErrorChunk(chunk: GoogleGenAIResponse, span: Span): boolean {\n const feedback = chunk?.promptFeedback;\n if (feedback?.blockReason) {\n const message = feedback.blockReasonMessage ?? feedback.blockReason;\n span.setStatus({ code: SPAN_STATUS_ERROR, message: `Content blocked: ${message}` });\n captureException(`Content blocked: ${message}`, {\n mechanism: { handled: false, type: 'auto.ai.google_genai' },\n });\n return true;\n }\n return false;\n}\n\n/**\n * Processes response metadata from a chunk\n * @param chunk - The response chunk to process\n * @param state - The state of the streaming process\n */\nfunction handleResponseMetadata(chunk: GoogleGenAIResponse, state: StreamingState): void {\n if (typeof chunk.responseId === 'string') state.responseId = chunk.responseId;\n if (typeof chunk.modelVersion === 'string') state.responseModel = chunk.modelVersion;\n\n const usage = chunk.usageMetadata;\n if (usage) {\n if (typeof usage.promptTokenCount === 'number') state.promptTokens = usage.promptTokenCount;\n if (typeof usage.candidatesTokenCount === 'number') state.completionTokens = usage.candidatesTokenCount;\n if (typeof usage.totalTokenCount === 'number') state.totalTokens = usage.totalTokenCount;\n }\n}\n\n/**\n * Processes candidate content from a response chunk\n * @param chunk - The response chunk to process\n * @param state - The state of the streaming process\n * @param recordOutputs - Whether to record outputs\n */\nfunction handleCandidateContent(chunk: GoogleGenAIResponse, state: StreamingState, recordOutputs: boolean): void {\n if (Array.isArray(chunk.functionCalls)) {\n state.toolCalls.push(...chunk.functionCalls);\n }\n\n for (const candidate of chunk.candidates ?? []) {\n if (candidate?.finishReason && !state.finishReasons.includes(candidate.finishReason)) {\n state.finishReasons.push(candidate.finishReason);\n }\n\n for (const part of candidate?.content?.parts ?? []) {\n if (recordOutputs && part.text) state.responseTexts.push(part.text);\n if (part.functionCall) {\n state.toolCalls.push({\n type: 'function',\n id: part.functionCall.id,\n name: part.functionCall.name,\n arguments: part.functionCall.args,\n });\n }\n }\n }\n}\n\n/**\n * Processes a single chunk from the Google GenAI stream\n * @param chunk - The chunk to process\n * @param state - The state of the streaming process\n * @param recordOutputs - Whether to record outputs\n * @param span - The span to update\n */\nfunction processChunk(chunk: GoogleGenAIResponse, state: StreamingState, recordOutputs: boolean, span: Span): void {\n if (!chunk || isErrorChunk(chunk, span)) return;\n handleResponseMetadata(chunk, state);\n handleCandidateContent(chunk, state, recordOutputs);\n}\n\n/**\n * Instruments an async iterable stream of Google GenAI response chunks, updates the span with\n * streaming attributes and (optionally) the aggregated output text, and yields\n * each chunk from the input stream unchanged.\n */\nexport async function* instrumentStream(\n stream: AsyncIterable<GoogleGenAIResponse>,\n span: Span,\n recordOutputs: boolean,\n): AsyncGenerator<GoogleGenAIResponse, void, unknown> {\n const state: StreamingState = {\n responseTexts: [],\n finishReasons: [],\n toolCalls: [],\n };\n\n try {\n for await (const chunk of stream) {\n processChunk(chunk, state, recordOutputs, span);\n yield chunk;\n }\n } finally {\n const attrs: Record<string, SpanAttributeValue> = {\n [GEN_AI_RESPONSE_STREAMING_ATTRIBUTE]: true,\n };\n\n if (state.responseId) attrs[GEN_AI_RESPONSE_ID_ATTRIBUTE] = state.responseId;\n if (state.responseModel) attrs[GEN_AI_RESPONSE_MODEL_ATTRIBUTE] = state.responseModel;\n if (state.promptTokens !== undefined) attrs[GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE] = state.promptTokens;\n if (state.completionTokens !== undefined) attrs[GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE] = state.completionTokens;\n if (state.totalTokens !== undefined) attrs[GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE] = state.totalTokens;\n\n if (state.finishReasons.length) {\n attrs[GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE] = JSON.stringify(state.finishReasons);\n }\n if (recordOutputs && state.responseTexts.length) {\n attrs[GEN_AI_RESPONSE_TEXT_ATTRIBUTE] = state.responseTexts.join('');\n }\n if (recordOutputs && state.toolCalls.length) {\n attrs[GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE] = JSON.stringify(state.toolCalls);\n }\n\n span.setAttributes(attrs);\n span.end();\n }\n}\n"],"names":["SPAN_STATUS_ERROR","captureException","GEN_AI_RESPONSE_STREAMING_ATTRIBUTE","GEN_AI_RESPONSE_ID_ATTRIBUTE","GEN_AI_RESPONSE_MODEL_ATTRIBUTE","GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE","GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE","GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE","GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE","GEN_AI_RESPONSE_TEXT_ATTRIBUTE","GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
 
3
- const exports$1 = require('../../exports.js');
3
+ const _exports = require('../../exports.js');
4
4
  const semanticAttributes = require('../../semanticAttributes.js');
5
5
  const spanstatus = require('../spanstatus.js');
6
6
  const trace = require('../trace.js');
@@ -158,7 +158,7 @@ function createLangChainCallbackHandler(options = {}) {
158
158
  exitSpan(runId);
159
159
  }
160
160
 
161
- exports$1.captureException(error, {
161
+ _exports.captureException(error, {
162
162
  mechanism: {
163
163
  handled: false,
164
164
  type: `${constants.LANGCHAIN_ORIGIN}.llm_error_handler`,
@@ -217,7 +217,7 @@ function createLangChainCallbackHandler(options = {}) {
217
217
  exitSpan(runId);
218
218
  }
219
219
 
220
- exports$1.captureException(error, {
220
+ _exports.captureException(error, {
221
221
  mechanism: {
222
222
  handled: false,
223
223
  type: `${constants.LANGCHAIN_ORIGIN}.chain_error_handler`,
@@ -276,7 +276,7 @@ function createLangChainCallbackHandler(options = {}) {
276
276
  exitSpan(runId);
277
277
  }
278
278
 
279
- exports$1.captureException(error, {
279
+ _exports.captureException(error, {
280
280
  mechanism: {
281
281
  handled: false,
282
282
  type: `${constants.LANGCHAIN_ORIGIN}.tool_error_handler`,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../../src/tracing/langchain/index.ts"],"sourcesContent":["import { captureException } from '../../exports';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '../../semanticAttributes';\nimport { SPAN_STATUS_ERROR } from '../../tracing';\nimport { startSpanManual } from '../../tracing/trace';\nimport type { Span, SpanAttributeValue } from '../../types-hoist/span';\nimport {\n GEN_AI_OPERATION_NAME_ATTRIBUTE,\n GEN_AI_REQUEST_MODEL_ATTRIBUTE,\n GEN_AI_TOOL_INPUT_ATTRIBUTE,\n GEN_AI_TOOL_NAME_ATTRIBUTE,\n GEN_AI_TOOL_OUTPUT_ATTRIBUTE,\n} from '../ai/gen-ai-attributes';\nimport { LANGCHAIN_ORIGIN } from './constants';\nimport type {\n LangChainCallbackHandler,\n LangChainLLMResult,\n LangChainMessage,\n LangChainOptions,\n LangChainSerialized,\n} from './types';\nimport {\n extractChatModelRequestAttributes,\n extractLLMRequestAttributes,\n extractLlmResponseAttributes,\n getInvocationParams,\n} from './utils';\n\n/**\n * Creates a Sentry callback handler for LangChain\n * Returns a plain object that LangChain will call via duck-typing\n *\n * This is a stateful handler that tracks spans across multiple LangChain executions.\n */\nexport function createLangChainCallbackHandler(options: LangChainOptions = {}): LangChainCallbackHandler {\n const recordInputs = options.recordInputs ?? false;\n const recordOutputs = options.recordOutputs ?? false;\n\n // Internal state - single instance tracks all spans\n const spanMap = new Map<string, Span>();\n\n /**\n * Exit a span and clean up\n */\n const exitSpan = (runId: string): void => {\n const span = spanMap.get(runId);\n if (span?.isRecording()) {\n span.end();\n spanMap.delete(runId);\n }\n };\n\n /**\n * Handler for LLM Start\n * This handler will be called by LangChain's callback handler when an LLM event is detected.\n */\n const handler: LangChainCallbackHandler = {\n // Required LangChain BaseCallbackHandler properties\n lc_serializable: false,\n lc_namespace: ['langchain_core', 'callbacks', 'sentry'],\n lc_secrets: undefined,\n lc_attributes: undefined,\n lc_aliases: undefined,\n lc_serializable_keys: undefined,\n lc_id: ['langchain_core', 'callbacks', 'sentry'],\n lc_kwargs: {},\n name: 'SentryCallbackHandler',\n\n // BaseCallbackHandlerInput boolean flags\n ignoreLLM: false,\n ignoreChain: false,\n ignoreAgent: false,\n ignoreRetriever: false,\n ignoreCustomEvent: false,\n raiseError: false,\n awaitHandlers: true,\n\n handleLLMStart(\n llm: unknown,\n prompts: string[],\n runId: string,\n _parentRunId?: string,\n _extraParams?: Record<string, unknown>,\n tags?: string[],\n metadata?: Record<string, unknown>,\n _runName?: string,\n ) {\n const invocationParams = getInvocationParams(tags);\n const attributes = extractLLMRequestAttributes(\n llm as LangChainSerialized,\n prompts,\n recordInputs,\n invocationParams,\n metadata,\n );\n const modelName = attributes[GEN_AI_REQUEST_MODEL_ATTRIBUTE];\n const operationName = attributes[GEN_AI_OPERATION_NAME_ATTRIBUTE];\n\n startSpanManual(\n {\n name: `${operationName} ${modelName}`,\n op: 'gen_ai.chat',\n attributes: {\n ...attributes,\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'gen_ai.chat',\n },\n },\n span => {\n spanMap.set(runId, span);\n return span;\n },\n );\n },\n\n // Chat Model Start Handler\n handleChatModelStart(\n llm: unknown,\n messages: unknown,\n runId: string,\n _parentRunId?: string,\n _extraParams?: Record<string, unknown>,\n tags?: string[],\n metadata?: Record<string, unknown>,\n _runName?: string,\n ) {\n const invocationParams = getInvocationParams(tags);\n const attributes = extractChatModelRequestAttributes(\n llm as LangChainSerialized,\n messages as LangChainMessage[][],\n recordInputs,\n invocationParams,\n metadata,\n );\n const modelName = attributes[GEN_AI_REQUEST_MODEL_ATTRIBUTE];\n const operationName = attributes[GEN_AI_OPERATION_NAME_ATTRIBUTE];\n\n startSpanManual(\n {\n name: `${operationName} ${modelName}`,\n op: 'gen_ai.chat',\n attributes: {\n ...attributes,\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'gen_ai.chat',\n },\n },\n span => {\n spanMap.set(runId, span);\n return span;\n },\n );\n },\n\n // LLM End Handler - note: handleLLMEnd with capital LLM (used by both LLMs and chat models!)\n handleLLMEnd(\n output: unknown,\n runId: string,\n _parentRunId?: string,\n _tags?: string[],\n _extraParams?: Record<string, unknown>,\n ) {\n const span = spanMap.get(runId);\n if (span?.isRecording()) {\n const attributes = extractLlmResponseAttributes(output as LangChainLLMResult, recordOutputs);\n if (attributes) {\n span.setAttributes(attributes);\n }\n exitSpan(runId);\n }\n },\n\n // LLM Error Handler - note: handleLLMError with capital LLM\n handleLLMError(error: Error, runId: string) {\n const span = spanMap.get(runId);\n if (span?.isRecording()) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'llm_error' });\n exitSpan(runId);\n }\n\n captureException(error, {\n mechanism: {\n handled: false,\n type: `${LANGCHAIN_ORIGIN}.llm_error_handler`,\n },\n });\n },\n\n // Chain Start Handler\n handleChainStart(chain: { name?: string }, inputs: Record<string, unknown>, runId: string, _parentRunId?: string) {\n const chainName = chain.name || 'unknown_chain';\n const attributes: Record<string, SpanAttributeValue> = {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ai.langchain',\n 'langchain.chain.name': chainName,\n };\n\n // Add inputs if recordInputs is enabled\n if (recordInputs) {\n attributes['langchain.chain.inputs'] = JSON.stringify(inputs);\n }\n\n startSpanManual(\n {\n name: `chain ${chainName}`,\n op: 'gen_ai.invoke_agent',\n attributes: {\n ...attributes,\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'gen_ai.invoke_agent',\n },\n },\n span => {\n spanMap.set(runId, span);\n return span;\n },\n );\n },\n\n // Chain End Handler\n handleChainEnd(outputs: unknown, runId: string) {\n const span = spanMap.get(runId);\n if (span?.isRecording()) {\n // Add outputs if recordOutputs is enabled\n if (recordOutputs) {\n span.setAttributes({\n 'langchain.chain.outputs': JSON.stringify(outputs),\n });\n }\n exitSpan(runId);\n }\n },\n\n // Chain Error Handler\n handleChainError(error: Error, runId: string) {\n const span = spanMap.get(runId);\n if (span?.isRecording()) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'chain_error' });\n exitSpan(runId);\n }\n\n captureException(error, {\n mechanism: {\n handled: false,\n type: `${LANGCHAIN_ORIGIN}.chain_error_handler`,\n },\n });\n },\n\n // Tool Start Handler\n handleToolStart(tool: { name?: string }, input: string, runId: string, _parentRunId?: string) {\n const toolName = tool.name || 'unknown_tool';\n const attributes: Record<string, SpanAttributeValue> = {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: LANGCHAIN_ORIGIN,\n [GEN_AI_TOOL_NAME_ATTRIBUTE]: toolName,\n };\n\n // Add input if recordInputs is enabled\n if (recordInputs) {\n attributes[GEN_AI_TOOL_INPUT_ATTRIBUTE] = input;\n }\n\n startSpanManual(\n {\n name: `execute_tool ${toolName}`,\n op: 'gen_ai.execute_tool',\n attributes: {\n ...attributes,\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'gen_ai.execute_tool',\n },\n },\n span => {\n spanMap.set(runId, span);\n return span;\n },\n );\n },\n\n // Tool End Handler\n handleToolEnd(output: unknown, runId: string) {\n const span = spanMap.get(runId);\n if (span?.isRecording()) {\n // Add output if recordOutputs is enabled\n if (recordOutputs) {\n span.setAttributes({\n [GEN_AI_TOOL_OUTPUT_ATTRIBUTE]: JSON.stringify(output),\n });\n }\n exitSpan(runId);\n }\n },\n\n // Tool Error Handler\n handleToolError(error: Error, runId: string) {\n const span = spanMap.get(runId);\n if (span?.isRecording()) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'tool_error' });\n exitSpan(runId);\n }\n\n captureException(error, {\n mechanism: {\n handled: false,\n type: `${LANGCHAIN_ORIGIN}.tool_error_handler`,\n },\n });\n },\n\n // LangChain BaseCallbackHandler required methods\n copy() {\n return handler;\n },\n\n toJSON() {\n return {\n lc: 1,\n type: 'not_implemented',\n id: handler.lc_id,\n };\n },\n\n toJSONNotImplemented() {\n return {\n lc: 1,\n type: 'not_implemented',\n id: handler.lc_id,\n };\n },\n };\n\n return handler;\n}\n"],"names":["getInvocationParams","extractLLMRequestAttributes","GEN_AI_REQUEST_MODEL_ATTRIBUTE","GEN_AI_OPERATION_NAME_ATTRIBUTE","startSpanManual","SEMANTIC_ATTRIBUTE_SENTRY_OP","extractChatModelRequestAttributes","extractLlmResponseAttributes","SPAN_STATUS_ERROR","captureException","LANGCHAIN_ORIGIN","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","GEN_AI_TOOL_NAME_ATTRIBUTE","GEN_AI_TOOL_INPUT_ATTRIBUTE","GEN_AI_TOOL_OUTPUT_ATTRIBUTE"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../../../src/tracing/langchain/index.ts"],"sourcesContent":["import { captureException } from '../../exports';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '../../semanticAttributes';\nimport { SPAN_STATUS_ERROR } from '../../tracing';\nimport { startSpanManual } from '../../tracing/trace';\nimport type { Span, SpanAttributeValue } from '../../types-hoist/span';\nimport {\n GEN_AI_OPERATION_NAME_ATTRIBUTE,\n GEN_AI_REQUEST_MODEL_ATTRIBUTE,\n GEN_AI_TOOL_INPUT_ATTRIBUTE,\n GEN_AI_TOOL_NAME_ATTRIBUTE,\n GEN_AI_TOOL_OUTPUT_ATTRIBUTE,\n} from '../ai/gen-ai-attributes';\nimport { LANGCHAIN_ORIGIN } from './constants';\nimport type {\n LangChainCallbackHandler,\n LangChainLLMResult,\n LangChainMessage,\n LangChainOptions,\n LangChainSerialized,\n} from './types';\nimport {\n extractChatModelRequestAttributes,\n extractLLMRequestAttributes,\n extractLlmResponseAttributes,\n getInvocationParams,\n} from './utils';\n\n/**\n * Creates a Sentry callback handler for LangChain\n * Returns a plain object that LangChain will call via duck-typing\n *\n * This is a stateful handler that tracks spans across multiple LangChain executions.\n */\nexport function createLangChainCallbackHandler(options: LangChainOptions = {}): LangChainCallbackHandler {\n const recordInputs = options.recordInputs ?? false;\n const recordOutputs = options.recordOutputs ?? false;\n\n // Internal state - single instance tracks all spans\n const spanMap = new Map<string, Span>();\n\n /**\n * Exit a span and clean up\n */\n const exitSpan = (runId: string): void => {\n const span = spanMap.get(runId);\n if (span?.isRecording()) {\n span.end();\n spanMap.delete(runId);\n }\n };\n\n /**\n * Handler for LLM Start\n * This handler will be called by LangChain's callback handler when an LLM event is detected.\n */\n const handler: LangChainCallbackHandler = {\n // Required LangChain BaseCallbackHandler properties\n lc_serializable: false,\n lc_namespace: ['langchain_core', 'callbacks', 'sentry'],\n lc_secrets: undefined,\n lc_attributes: undefined,\n lc_aliases: undefined,\n lc_serializable_keys: undefined,\n lc_id: ['langchain_core', 'callbacks', 'sentry'],\n lc_kwargs: {},\n name: 'SentryCallbackHandler',\n\n // BaseCallbackHandlerInput boolean flags\n ignoreLLM: false,\n ignoreChain: false,\n ignoreAgent: false,\n ignoreRetriever: false,\n ignoreCustomEvent: false,\n raiseError: false,\n awaitHandlers: true,\n\n handleLLMStart(\n llm: unknown,\n prompts: string[],\n runId: string,\n _parentRunId?: string,\n _extraParams?: Record<string, unknown>,\n tags?: string[],\n metadata?: Record<string, unknown>,\n _runName?: string,\n ) {\n const invocationParams = getInvocationParams(tags);\n const attributes = extractLLMRequestAttributes(\n llm as LangChainSerialized,\n prompts,\n recordInputs,\n invocationParams,\n metadata,\n );\n const modelName = attributes[GEN_AI_REQUEST_MODEL_ATTRIBUTE];\n const operationName = attributes[GEN_AI_OPERATION_NAME_ATTRIBUTE];\n\n startSpanManual(\n {\n name: `${operationName} ${modelName}`,\n op: 'gen_ai.chat',\n attributes: {\n ...attributes,\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'gen_ai.chat',\n },\n },\n span => {\n spanMap.set(runId, span);\n return span;\n },\n );\n },\n\n // Chat Model Start Handler\n handleChatModelStart(\n llm: unknown,\n messages: unknown,\n runId: string,\n _parentRunId?: string,\n _extraParams?: Record<string, unknown>,\n tags?: string[],\n metadata?: Record<string, unknown>,\n _runName?: string,\n ) {\n const invocationParams = getInvocationParams(tags);\n const attributes = extractChatModelRequestAttributes(\n llm as LangChainSerialized,\n messages as LangChainMessage[][],\n recordInputs,\n invocationParams,\n metadata,\n );\n const modelName = attributes[GEN_AI_REQUEST_MODEL_ATTRIBUTE];\n const operationName = attributes[GEN_AI_OPERATION_NAME_ATTRIBUTE];\n\n startSpanManual(\n {\n name: `${operationName} ${modelName}`,\n op: 'gen_ai.chat',\n attributes: {\n ...attributes,\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'gen_ai.chat',\n },\n },\n span => {\n spanMap.set(runId, span);\n return span;\n },\n );\n },\n\n // LLM End Handler - note: handleLLMEnd with capital LLM (used by both LLMs and chat models!)\n handleLLMEnd(\n output: unknown,\n runId: string,\n _parentRunId?: string,\n _tags?: string[],\n _extraParams?: Record<string, unknown>,\n ) {\n const span = spanMap.get(runId);\n if (span?.isRecording()) {\n const attributes = extractLlmResponseAttributes(output as LangChainLLMResult, recordOutputs);\n if (attributes) {\n span.setAttributes(attributes);\n }\n exitSpan(runId);\n }\n },\n\n // LLM Error Handler - note: handleLLMError with capital LLM\n handleLLMError(error: Error, runId: string) {\n const span = spanMap.get(runId);\n if (span?.isRecording()) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'llm_error' });\n exitSpan(runId);\n }\n\n captureException(error, {\n mechanism: {\n handled: false,\n type: `${LANGCHAIN_ORIGIN}.llm_error_handler`,\n },\n });\n },\n\n // Chain Start Handler\n handleChainStart(chain: { name?: string }, inputs: Record<string, unknown>, runId: string, _parentRunId?: string) {\n const chainName = chain.name || 'unknown_chain';\n const attributes: Record<string, SpanAttributeValue> = {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ai.langchain',\n 'langchain.chain.name': chainName,\n };\n\n // Add inputs if recordInputs is enabled\n if (recordInputs) {\n attributes['langchain.chain.inputs'] = JSON.stringify(inputs);\n }\n\n startSpanManual(\n {\n name: `chain ${chainName}`,\n op: 'gen_ai.invoke_agent',\n attributes: {\n ...attributes,\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'gen_ai.invoke_agent',\n },\n },\n span => {\n spanMap.set(runId, span);\n return span;\n },\n );\n },\n\n // Chain End Handler\n handleChainEnd(outputs: unknown, runId: string) {\n const span = spanMap.get(runId);\n if (span?.isRecording()) {\n // Add outputs if recordOutputs is enabled\n if (recordOutputs) {\n span.setAttributes({\n 'langchain.chain.outputs': JSON.stringify(outputs),\n });\n }\n exitSpan(runId);\n }\n },\n\n // Chain Error Handler\n handleChainError(error: Error, runId: string) {\n const span = spanMap.get(runId);\n if (span?.isRecording()) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'chain_error' });\n exitSpan(runId);\n }\n\n captureException(error, {\n mechanism: {\n handled: false,\n type: `${LANGCHAIN_ORIGIN}.chain_error_handler`,\n },\n });\n },\n\n // Tool Start Handler\n handleToolStart(tool: { name?: string }, input: string, runId: string, _parentRunId?: string) {\n const toolName = tool.name || 'unknown_tool';\n const attributes: Record<string, SpanAttributeValue> = {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: LANGCHAIN_ORIGIN,\n [GEN_AI_TOOL_NAME_ATTRIBUTE]: toolName,\n };\n\n // Add input if recordInputs is enabled\n if (recordInputs) {\n attributes[GEN_AI_TOOL_INPUT_ATTRIBUTE] = input;\n }\n\n startSpanManual(\n {\n name: `execute_tool ${toolName}`,\n op: 'gen_ai.execute_tool',\n attributes: {\n ...attributes,\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'gen_ai.execute_tool',\n },\n },\n span => {\n spanMap.set(runId, span);\n return span;\n },\n );\n },\n\n // Tool End Handler\n handleToolEnd(output: unknown, runId: string) {\n const span = spanMap.get(runId);\n if (span?.isRecording()) {\n // Add output if recordOutputs is enabled\n if (recordOutputs) {\n span.setAttributes({\n [GEN_AI_TOOL_OUTPUT_ATTRIBUTE]: JSON.stringify(output),\n });\n }\n exitSpan(runId);\n }\n },\n\n // Tool Error Handler\n handleToolError(error: Error, runId: string) {\n const span = spanMap.get(runId);\n if (span?.isRecording()) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'tool_error' });\n exitSpan(runId);\n }\n\n captureException(error, {\n mechanism: {\n handled: false,\n type: `${LANGCHAIN_ORIGIN}.tool_error_handler`,\n },\n });\n },\n\n // LangChain BaseCallbackHandler required methods\n copy() {\n return handler;\n },\n\n toJSON() {\n return {\n lc: 1,\n type: 'not_implemented',\n id: handler.lc_id,\n };\n },\n\n toJSONNotImplemented() {\n return {\n lc: 1,\n type: 'not_implemented',\n id: handler.lc_id,\n };\n },\n };\n\n return handler;\n}\n"],"names":["getInvocationParams","extractLLMRequestAttributes","GEN_AI_REQUEST_MODEL_ATTRIBUTE","GEN_AI_OPERATION_NAME_ATTRIBUTE","startSpanManual","SEMANTIC_ATTRIBUTE_SENTRY_OP","extractChatModelRequestAttributes","extractLlmResponseAttributes","SPAN_STATUS_ERROR","captureException","LANGCHAIN_ORIGIN","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","GEN_AI_TOOL_NAME_ATTRIBUTE","GEN_AI_TOOL_INPUT_ATTRIBUTE","GEN_AI_TOOL_OUTPUT_ATTRIBUTE"],"mappings":";;;;;;;;;;AA2BA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,8BAA8B,CAAC,OAAO,GAAqB,EAAE,EAA4B;AACzG,EAAE,MAAM,YAAA,GAAe,OAAO,CAAC,YAAA,IAAgB,KAAK;AACpD,EAAE,MAAM,aAAA,GAAgB,OAAO,CAAC,aAAA,IAAiB,KAAK;;AAEtD;AACA,EAAE,MAAM,OAAA,GAAU,IAAI,GAAG,EAAgB;;AAEzC;AACA;AACA;AACA,EAAE,MAAM,QAAA,GAAW,CAAC,KAAK,KAAmB;AAC5C,IAAI,MAAM,OAAO,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;AACnC,IAAI,IAAI,IAAI,EAAE,WAAW,EAAE,EAAE;AAC7B,MAAM,IAAI,CAAC,GAAG,EAAE;AAChB,MAAM,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;AAC3B,IAAI;AACJ,EAAE,CAAC;;AAEH;AACA;AACA;AACA;AACA,EAAE,MAAM,OAAO,GAA6B;AAC5C;AACA,IAAI,eAAe,EAAE,KAAK;AAC1B,IAAI,YAAY,EAAE,CAAC,gBAAgB,EAAE,WAAW,EAAE,QAAQ,CAAC;AAC3D,IAAI,UAAU,EAAE,SAAS;AACzB,IAAI,aAAa,EAAE,SAAS;AAC5B,IAAI,UAAU,EAAE,SAAS;AACzB,IAAI,oBAAoB,EAAE,SAAS;AACnC,IAAI,KAAK,EAAE,CAAC,gBAAgB,EAAE,WAAW,EAAE,QAAQ,CAAC;AACpD,IAAI,SAAS,EAAE,EAAE;AACjB,IAAI,IAAI,EAAE,uBAAuB;;AAEjC;AACA,IAAI,SAAS,EAAE,KAAK;AACpB,IAAI,WAAW,EAAE,KAAK;AACtB,IAAI,WAAW,EAAE,KAAK;AACtB,IAAI,eAAe,EAAE,KAAK;AAC1B,IAAI,iBAAiB,EAAE,KAAK;AAC5B,IAAI,UAAU,EAAE,KAAK;AACrB,IAAI,aAAa,EAAE,IAAI;;AAEvB,IAAI,cAAc;AAClB,MAAM,GAAG;AACT,MAAM,OAAO;AACb,MAAM,KAAK;AACX,MAAM,YAAY;AAClB,MAAM,YAAY;AAClB,MAAM,IAAI;AACV,MAAM,QAAQ;AACd,MAAM,QAAQ;AACd,MAAM;AACN,MAAM,MAAM,gBAAA,GAAmBA,yBAAmB,CAAC,IAAI,CAAC;AACxD,MAAM,MAAM,UAAA,GAAaC,iCAA2B;AACpD,QAAQ,GAAA;AACR,QAAQ,OAAO;AACf,QAAQ,YAAY;AACpB,QAAQ,gBAAgB;AACxB,QAAQ,QAAQ;AAChB,OAAO;AACP,MAAM,MAAM,SAAA,GAAY,UAAU,CAACC,8CAA8B,CAAC;AAClE,MAAM,MAAM,aAAA,GAAgB,UAAU,CAACC,+CAA+B,CAAC;;AAEvE,MAAMC,qBAAe;AACrB,QAAQ;AACR,UAAU,IAAI,EAAE,CAAC,EAAA,aAAA,CAAA,CAAA,EAAA,SAAA,CAAA,CAAA;AACA,UAAA,EAAA,EAAA,aAAA;AACA,UAAA,UAAA,EAAA;AACA,YAAA,GAAA,UAAA;AACA,YAAA,CAAAC,+CAAA,GAAA,aAAA;AACA,WAAA;AACA,SAAA;AACA,QAAA,IAAA,IAAA;AACA,UAAA,OAAA,CAAA,GAAA,CAAA,KAAA,EAAA,IAAA,CAAA;AACA,UAAA,OAAA,IAAA;AACA,QAAA,CAAA;AACA,OAAA;AACA,IAAA,CAAA;;AAEA;AACA,IAAA,oBAAA;AACA,MAAA,GAAA;AACA,MAAA,QAAA;AACA,MAAA,KAAA;AACA,MAAA,YAAA;AACA,MAAA,YAAA;AACA,MAAA,IAAA;AACA,MAAA,QAAA;AACA,MAAA,QAAA;AACA,MAAA;AACA,MAAA,MAAA,gBAAA,GAAAL,yBAAA,CAAA,IAAA,CAAA;AACA,MAAA,MAAA,UAAA,GAAAM,uCAAA;AACA,QAAA,GAAA;AACA,QAAA,QAAA;AACA,QAAA,YAAA;AACA,QAAA,gBAAA;AACA,QAAA,QAAA;AACA,OAAA;AACA,MAAA,MAAA,SAAA,GAAA,UAAA,CAAAJ,8CAAA,CAAA;AACA,MAAA,MAAA,aAAA,GAAA,UAAA,CAAAC,+CAAA,CAAA;;AAEA,MAAAC,qBAAA;AACA,QAAA;AACA,UAAA,IAAA,EAAA,CAAA,EAAA,aAAA,CAAA,CAAA,EAAA,SAAA,CAAA,CAAA;AACA,UAAA,EAAA,EAAA,aAAA;AACA,UAAA,UAAA,EAAA;AACA,YAAA,GAAA,UAAA;AACA,YAAA,CAAAC,+CAAA,GAAA,aAAA;AACA,WAAA;AACA,SAAA;AACA,QAAA,IAAA,IAAA;AACA,UAAA,OAAA,CAAA,GAAA,CAAA,KAAA,EAAA,IAAA,CAAA;AACA,UAAA,OAAA,IAAA;AACA,QAAA,CAAA;AACA,OAAA;AACA,IAAA,CAAA;;AAEA;AACA,IAAA,YAAA;AACA,MAAA,MAAA;AACA,MAAA,KAAA;AACA,MAAA,YAAA;AACA,MAAA,KAAA;AACA,MAAA,YAAA;AACA,MAAA;AACA,MAAA,MAAA,IAAA,GAAA,OAAA,CAAA,GAAA,CAAA,KAAA,CAAA;AACA,MAAA,IAAA,IAAA,EAAA,WAAA,EAAA,EAAA;AACA,QAAA,MAAA,UAAA,GAAAE,kCAAA,CAAA,MAAA,GAAA,aAAA,CAAA;AACA,QAAA,IAAA,UAAA,EAAA;AACA,UAAA,IAAA,CAAA,aAAA,CAAA,UAAA,CAAA;AACA,QAAA;AACA,QAAA,QAAA,CAAA,KAAA,CAAA;AACA,MAAA;AACA,IAAA,CAAA;;AAEA;AACA,IAAA,cAAA,CAAA,KAAA,EAAA,KAAA,EAAA;AACA,MAAA,MAAA,IAAA,GAAA,OAAA,CAAA,GAAA,CAAA,KAAA,CAAA;AACA,MAAA,IAAA,IAAA,EAAA,WAAA,EAAA,EAAA;AACA,QAAA,IAAA,CAAA,SAAA,CAAA,EAAA,IAAA,EAAAC,4BAAA,EAAA,OAAA,EAAA,WAAA,EAAA,CAAA;AACA,QAAA,QAAA,CAAA,KAAA,CAAA;AACA,MAAA;;AAEA,MAAAC,yBAAA,CAAA,KAAA,EAAA;AACA,QAAA,SAAA,EAAA;AACA,UAAA,OAAA,EAAA,KAAA;AACA,UAAA,IAAA,EAAA,CAAA,EAAAC,0BAAA,CAAA,kBAAA,CAAA;AACA,SAAA;AACA,OAAA,CAAA;AACA,IAAA,CAAA;;AAEA;AACA,IAAA,gBAAA,CAAA,KAAA,EAAA,MAAA,EAAA,KAAA,EAAA,YAAA,EAAA;AACA,MAAA,MAAA,SAAA,GAAA,KAAA,CAAA,IAAA,IAAA,eAAA;AACA,MAAA,MAAA,UAAA,GAAA;AACA,QAAA,CAAAC,mDAAA,GAAA,mBAAA;AACA,QAAA,sBAAA,EAAA,SAAA;AACA,OAAA;;AAEA;AACA,MAAA,IAAA,YAAA,EAAA;AACA,QAAA,UAAA,CAAA,wBAAA,CAAA,GAAA,IAAA,CAAA,SAAA,CAAA,MAAA,CAAA;AACA,MAAA;;AAEA,MAAAP,qBAAA;AACA,QAAA;AACA,UAAA,IAAA,EAAA,CAAA,MAAA,EAAA,SAAA,CAAA,CAAA;AACA,UAAA,EAAA,EAAA,qBAAA;AACA,UAAA,UAAA,EAAA;AACA,YAAA,GAAA,UAAA;AACA,YAAA,CAAAC,+CAAA,GAAA,qBAAA;AACA,WAAA;AACA,SAAA;AACA,QAAA,IAAA,IAAA;AACA,UAAA,OAAA,CAAA,GAAA,CAAA,KAAA,EAAA,IAAA,CAAA;AACA,UAAA,OAAA,IAAA;AACA,QAAA,CAAA;AACA,OAAA;AACA,IAAA,CAAA;;AAEA;AACA,IAAA,cAAA,CAAA,OAAA,EAAA,KAAA,EAAA;AACA,MAAA,MAAA,IAAA,GAAA,OAAA,CAAA,GAAA,CAAA,KAAA,CAAA;AACA,MAAA,IAAA,IAAA,EAAA,WAAA,EAAA,EAAA;AACA;AACA,QAAA,IAAA,aAAA,EAAA;AACA,UAAA,IAAA,CAAA,aAAA,CAAA;AACA,YAAA,yBAAA,EAAA,IAAA,CAAA,SAAA,CAAA,OAAA,CAAA;AACA,WAAA,CAAA;AACA,QAAA;AACA,QAAA,QAAA,CAAA,KAAA,CAAA;AACA,MAAA;AACA,IAAA,CAAA;;AAEA;AACA,IAAA,gBAAA,CAAA,KAAA,EAAA,KAAA,EAAA;AACA,MAAA,MAAA,IAAA,GAAA,OAAA,CAAA,GAAA,CAAA,KAAA,CAAA;AACA,MAAA,IAAA,IAAA,EAAA,WAAA,EAAA,EAAA;AACA,QAAA,IAAA,CAAA,SAAA,CAAA,EAAA,IAAA,EAAAG,4BAAA,EAAA,OAAA,EAAA,aAAA,EAAA,CAAA;AACA,QAAA,QAAA,CAAA,KAAA,CAAA;AACA,MAAA;;AAEA,MAAAC,yBAAA,CAAA,KAAA,EAAA;AACA,QAAA,SAAA,EAAA;AACA,UAAA,OAAA,EAAA,KAAA;AACA,UAAA,IAAA,EAAA,CAAA,EAAAC,0BAAA,CAAA,oBAAA,CAAA;AACA,SAAA;AACA,OAAA,CAAA;AACA,IAAA,CAAA;;AAEA;AACA,IAAA,eAAA,CAAA,IAAA,EAAA,KAAA,EAAA,KAAA,EAAA,YAAA,EAAA;AACA,MAAA,MAAA,QAAA,GAAA,IAAA,CAAA,IAAA,IAAA,cAAA;AACA,MAAA,MAAA,UAAA,GAAA;AACA,QAAA,CAAAC,mDAAA,GAAAD,0BAAA;AACA,QAAA,CAAAE,0CAAA,GAAA,QAAA;AACA,OAAA;;AAEA;AACA,MAAA,IAAA,YAAA,EAAA;AACA,QAAA,UAAA,CAAAC,2CAAA,CAAA,GAAA,KAAA;AACA,MAAA;;AAEA,MAAAT,qBAAA;AACA,QAAA;AACA,UAAA,IAAA,EAAA,CAAA,aAAA,EAAA,QAAA,CAAA,CAAA;AACA,UAAA,EAAA,EAAA,qBAAA;AACA,UAAA,UAAA,EAAA;AACA,YAAA,GAAA,UAAA;AACA,YAAA,CAAAC,+CAAA,GAAA,qBAAA;AACA,WAAA;AACA,SAAA;AACA,QAAA,IAAA,IAAA;AACA,UAAA,OAAA,CAAA,GAAA,CAAA,KAAA,EAAA,IAAA,CAAA;AACA,UAAA,OAAA,IAAA;AACA,QAAA,CAAA;AACA,OAAA;AACA,IAAA,CAAA;;AAEA;AACA,IAAA,aAAA,CAAA,MAAA,EAAA,KAAA,EAAA;AACA,MAAA,MAAA,IAAA,GAAA,OAAA,CAAA,GAAA,CAAA,KAAA,CAAA;AACA,MAAA,IAAA,IAAA,EAAA,WAAA,EAAA,EAAA;AACA;AACA,QAAA,IAAA,aAAA,EAAA;AACA,UAAA,IAAA,CAAA,aAAA,CAAA;AACA,YAAA,CAAAS,4CAAA,GAAA,IAAA,CAAA,SAAA,CAAA,MAAA,CAAA;AACA,WAAA,CAAA;AACA,QAAA;AACA,QAAA,QAAA,CAAA,KAAA,CAAA;AACA,MAAA;AACA,IAAA,CAAA;;AAEA;AACA,IAAA,eAAA,CAAA,KAAA,EAAA,KAAA,EAAA;AACA,MAAA,MAAA,IAAA,GAAA,OAAA,CAAA,GAAA,CAAA,KAAA,CAAA;AACA,MAAA,IAAA,IAAA,EAAA,WAAA,EAAA,EAAA;AACA,QAAA,IAAA,CAAA,SAAA,CAAA,EAAA,IAAA,EAAAN,4BAAA,EAAA,OAAA,EAAA,YAAA,EAAA,CAAA;AACA,QAAA,QAAA,CAAA,KAAA,CAAA;AACA,MAAA;;AAEA,MAAAC,yBAAA,CAAA,KAAA,EAAA;AACA,QAAA,SAAA,EAAA;AACA,UAAA,OAAA,EAAA,KAAA;AACA,UAAA,IAAA,EAAA,CAAA,EAAAC,0BAAA,CAAA,mBAAA,CAAA;AACA,SAAA;AACA,OAAA,CAAA;AACA,IAAA,CAAA;;AAEA;AACA,IAAA,IAAA,GAAA;AACA,MAAA,OAAA,OAAA;AACA,IAAA,CAAA;;AAEA,IAAA,MAAA,GAAA;AACA,MAAA,OAAA;AACA,QAAA,EAAA,EAAA,CAAA;AACA,QAAA,IAAA,EAAA,iBAAA;AACA,QAAA,EAAA,EAAA,OAAA,CAAA,KAAA;AACA,OAAA;AACA,IAAA,CAAA;;AAEA,IAAA,oBAAA,GAAA;AACA,MAAA,OAAA;AACA,QAAA,EAAA,EAAA,CAAA;AACA,QAAA,IAAA,EAAA,iBAAA;AACA,QAAA,EAAA,EAAA,OAAA,CAAA,KAAA;AACA,OAAA;AACA,IAAA,CAAA;AACA,GAAA;;AAEA,EAAA,OAAA,OAAA;AACA;;;;"}
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
 
3
- const exports$1 = require('../../exports.js');
3
+ const _exports = require('../../exports.js');
4
4
  const semanticAttributes = require('../../semanticAttributes.js');
5
5
  const spanstatus = require('../spanstatus.js');
6
6
  const trace = require('../trace.js');
@@ -60,7 +60,7 @@ function instrumentStateGraphCompile(
60
60
  return compiledGraph;
61
61
  } catch (error) {
62
62
  span.setStatus({ code: spanstatus.SPAN_STATUS_ERROR, message: 'internal_error' });
63
- exports$1.captureException(error, {
63
+ _exports.captureException(error, {
64
64
  mechanism: {
65
65
  handled: false,
66
66
  type: 'auto.ai.langgraph.error',
@@ -155,7 +155,7 @@ function instrumentCompiledGraphInvoke(
155
155
  return result;
156
156
  } catch (error) {
157
157
  span.setStatus({ code: spanstatus.SPAN_STATUS_ERROR, message: 'internal_error' });
158
- exports$1.captureException(error, {
158
+ _exports.captureException(error, {
159
159
  mechanism: {
160
160
  handled: false,
161
161
  type: 'auto.ai.langgraph.error',
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../../src/tracing/langgraph/index.ts"],"sourcesContent":["import { captureException } from '../../exports';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '../../semanticAttributes';\nimport { SPAN_STATUS_ERROR } from '../../tracing';\nimport {\n GEN_AI_AGENT_NAME_ATTRIBUTE,\n GEN_AI_CONVERSATION_ID_ATTRIBUTE,\n GEN_AI_INPUT_MESSAGES_ATTRIBUTE,\n GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE,\n GEN_AI_INVOKE_AGENT_OPERATION_ATTRIBUTE,\n GEN_AI_OPERATION_NAME_ATTRIBUTE,\n GEN_AI_PIPELINE_NAME_ATTRIBUTE,\n GEN_AI_REQUEST_AVAILABLE_TOOLS_ATTRIBUTE,\n GEN_AI_SYSTEM_INSTRUCTIONS_ATTRIBUTE,\n} from '../ai/gen-ai-attributes';\nimport { truncateGenAiMessages } from '../ai/messageTruncation';\nimport { extractSystemInstructions } from '../ai/utils';\nimport type { LangChainMessage } from '../langchain/types';\nimport { normalizeLangChainMessages } from '../langchain/utils';\nimport { startSpan } from '../trace';\nimport { LANGGRAPH_ORIGIN } from './constants';\nimport type { CompiledGraph, LangGraphOptions } from './types';\nimport { extractToolsFromCompiledGraph, setResponseAttributes } from './utils';\n\n/**\n * Instruments StateGraph's compile method to create spans for agent creation and invocation\n *\n * Wraps the compile() method to:\n * - Create a `gen_ai.create_agent` span when compile() is called\n * - Automatically wrap the invoke() method on the returned compiled graph with a `gen_ai.invoke_agent` span\n *\n */\nexport function instrumentStateGraphCompile(\n originalCompile: (...args: unknown[]) => CompiledGraph,\n options: LangGraphOptions,\n): (...args: unknown[]) => CompiledGraph {\n return new Proxy(originalCompile, {\n apply(target, thisArg, args: unknown[]): CompiledGraph {\n return startSpan(\n {\n op: 'gen_ai.create_agent',\n name: 'create_agent',\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: LANGGRAPH_ORIGIN,\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'gen_ai.create_agent',\n [GEN_AI_OPERATION_NAME_ATTRIBUTE]: 'create_agent',\n },\n },\n span => {\n try {\n const compiledGraph = Reflect.apply(target, thisArg, args);\n const compileOptions = args.length > 0 ? (args[0] as Record<string, unknown>) : {};\n\n // Extract graph name\n if (compileOptions?.name && typeof compileOptions.name === 'string') {\n span.setAttribute(GEN_AI_AGENT_NAME_ATTRIBUTE, compileOptions.name);\n span.updateName(`create_agent ${compileOptions.name}`);\n }\n\n // Instrument agent invoke method on the compiled graph\n const originalInvoke = compiledGraph.invoke;\n if (originalInvoke && typeof originalInvoke === 'function') {\n compiledGraph.invoke = instrumentCompiledGraphInvoke(\n originalInvoke.bind(compiledGraph) as (...args: unknown[]) => Promise<unknown>,\n compiledGraph,\n compileOptions,\n options,\n ) as typeof originalInvoke;\n }\n\n return compiledGraph;\n } catch (error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureException(error, {\n mechanism: {\n handled: false,\n type: 'auto.ai.langgraph.error',\n },\n });\n throw error;\n }\n },\n );\n },\n }) as (...args: unknown[]) => CompiledGraph;\n}\n\n/**\n * Instruments CompiledGraph's invoke method to create spans for agent invocation\n *\n * Creates a `gen_ai.invoke_agent` span when invoke() is called\n */\nfunction instrumentCompiledGraphInvoke(\n originalInvoke: (...args: unknown[]) => Promise<unknown>,\n graphInstance: CompiledGraph,\n compileOptions: Record<string, unknown>,\n options: LangGraphOptions,\n): (...args: unknown[]) => Promise<unknown> {\n return new Proxy(originalInvoke, {\n apply(target, thisArg, args: unknown[]): Promise<unknown> {\n return startSpan(\n {\n op: 'gen_ai.invoke_agent',\n name: 'invoke_agent',\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: LANGGRAPH_ORIGIN,\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: GEN_AI_INVOKE_AGENT_OPERATION_ATTRIBUTE,\n [GEN_AI_OPERATION_NAME_ATTRIBUTE]: 'invoke_agent',\n },\n },\n async span => {\n try {\n const graphName = compileOptions?.name;\n\n if (graphName && typeof graphName === 'string') {\n span.setAttribute(GEN_AI_PIPELINE_NAME_ATTRIBUTE, graphName);\n span.setAttribute(GEN_AI_AGENT_NAME_ATTRIBUTE, graphName);\n span.updateName(`invoke_agent ${graphName}`);\n }\n\n // Extract thread_id from the config (second argument)\n // LangGraph uses config.configurable.thread_id for conversation/session linking\n const config = args.length > 1 ? (args[1] as Record<string, unknown> | undefined) : undefined;\n const configurable = config?.configurable as Record<string, unknown> | undefined;\n const threadId = configurable?.thread_id;\n if (threadId && typeof threadId === 'string') {\n span.setAttribute(GEN_AI_CONVERSATION_ID_ATTRIBUTE, threadId);\n }\n\n // Extract available tools from the graph instance\n const tools = extractToolsFromCompiledGraph(graphInstance);\n if (tools) {\n span.setAttribute(GEN_AI_REQUEST_AVAILABLE_TOOLS_ATTRIBUTE, JSON.stringify(tools));\n }\n\n // Parse input messages\n const recordInputs = options.recordInputs;\n const recordOutputs = options.recordOutputs;\n const inputMessages =\n args.length > 0 ? ((args[0] as { messages?: LangChainMessage[] }).messages ?? []) : [];\n\n if (inputMessages && recordInputs) {\n const normalizedMessages = normalizeLangChainMessages(inputMessages);\n const { systemInstructions, filteredMessages } = extractSystemInstructions(normalizedMessages);\n\n if (systemInstructions) {\n span.setAttribute(GEN_AI_SYSTEM_INSTRUCTIONS_ATTRIBUTE, systemInstructions);\n }\n\n const truncatedMessages = truncateGenAiMessages(filteredMessages as unknown[]);\n const filteredLength = Array.isArray(filteredMessages) ? filteredMessages.length : 0;\n span.setAttributes({\n [GEN_AI_INPUT_MESSAGES_ATTRIBUTE]: JSON.stringify(truncatedMessages),\n [GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE]: filteredLength,\n });\n }\n\n // Call original invoke\n const result = await Reflect.apply(target, thisArg, args);\n\n // Set response attributes\n if (recordOutputs) {\n setResponseAttributes(span, inputMessages ?? null, result);\n }\n\n return result;\n } catch (error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureException(error, {\n mechanism: {\n handled: false,\n type: 'auto.ai.langgraph.error',\n },\n });\n throw error;\n }\n },\n );\n },\n }) as (...args: unknown[]) => Promise<unknown>;\n}\n\n/**\n * Directly instruments a StateGraph instance to add tracing spans\n *\n * This function can be used to manually instrument LangGraph StateGraph instances\n * in environments where automatic instrumentation is not available or desired.\n *\n * @param stateGraph - The StateGraph instance to instrument\n * @param options - Optional configuration for recording inputs/outputs\n *\n * @example\n * ```typescript\n * import { instrumentLangGraph } from '@sentry/cloudflare';\n * import { StateGraph } from '@langchain/langgraph';\n *\n * const graph = new StateGraph(MessagesAnnotation)\n * .addNode('agent', mockLlm)\n * .addEdge(START, 'agent')\n * .addEdge('agent', END);\n *\n * instrumentLangGraph(graph, { recordInputs: true, recordOutputs: true });\n * const compiled = graph.compile({ name: 'my_agent' });\n * ```\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function instrumentLangGraph<T extends { compile: (...args: any[]) => any }>(\n stateGraph: T,\n options?: LangGraphOptions,\n): T {\n const _options: LangGraphOptions = options || {};\n\n stateGraph.compile = instrumentStateGraphCompile(stateGraph.compile.bind(stateGraph), _options);\n\n return stateGraph;\n}\n"],"names":["startSpan","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","LANGGRAPH_ORIGIN","SEMANTIC_ATTRIBUTE_SENTRY_OP","GEN_AI_OPERATION_NAME_ATTRIBUTE","GEN_AI_AGENT_NAME_ATTRIBUTE","SPAN_STATUS_ERROR","captureException","GEN_AI_INVOKE_AGENT_OPERATION_ATTRIBUTE","GEN_AI_PIPELINE_NAME_ATTRIBUTE","GEN_AI_CONVERSATION_ID_ATTRIBUTE","extractToolsFromCompiledGraph","GEN_AI_REQUEST_AVAILABLE_TOOLS_ATTRIBUTE","normalizeLangChainMessages","extractSystemInstructions","GEN_AI_SYSTEM_INSTRUCTIONS_ATTRIBUTE","truncateGenAiMessages","GEN_AI_INPUT_MESSAGES_ATTRIBUTE","GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE","setResponseAttributes"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../../../src/tracing/langgraph/index.ts"],"sourcesContent":["import { captureException } from '../../exports';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '../../semanticAttributes';\nimport { SPAN_STATUS_ERROR } from '../../tracing';\nimport {\n GEN_AI_AGENT_NAME_ATTRIBUTE,\n GEN_AI_CONVERSATION_ID_ATTRIBUTE,\n GEN_AI_INPUT_MESSAGES_ATTRIBUTE,\n GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE,\n GEN_AI_INVOKE_AGENT_OPERATION_ATTRIBUTE,\n GEN_AI_OPERATION_NAME_ATTRIBUTE,\n GEN_AI_PIPELINE_NAME_ATTRIBUTE,\n GEN_AI_REQUEST_AVAILABLE_TOOLS_ATTRIBUTE,\n GEN_AI_SYSTEM_INSTRUCTIONS_ATTRIBUTE,\n} from '../ai/gen-ai-attributes';\nimport { truncateGenAiMessages } from '../ai/messageTruncation';\nimport { extractSystemInstructions } from '../ai/utils';\nimport type { LangChainMessage } from '../langchain/types';\nimport { normalizeLangChainMessages } from '../langchain/utils';\nimport { startSpan } from '../trace';\nimport { LANGGRAPH_ORIGIN } from './constants';\nimport type { CompiledGraph, LangGraphOptions } from './types';\nimport { extractToolsFromCompiledGraph, setResponseAttributes } from './utils';\n\n/**\n * Instruments StateGraph's compile method to create spans for agent creation and invocation\n *\n * Wraps the compile() method to:\n * - Create a `gen_ai.create_agent` span when compile() is called\n * - Automatically wrap the invoke() method on the returned compiled graph with a `gen_ai.invoke_agent` span\n *\n */\nexport function instrumentStateGraphCompile(\n originalCompile: (...args: unknown[]) => CompiledGraph,\n options: LangGraphOptions,\n): (...args: unknown[]) => CompiledGraph {\n return new Proxy(originalCompile, {\n apply(target, thisArg, args: unknown[]): CompiledGraph {\n return startSpan(\n {\n op: 'gen_ai.create_agent',\n name: 'create_agent',\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: LANGGRAPH_ORIGIN,\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'gen_ai.create_agent',\n [GEN_AI_OPERATION_NAME_ATTRIBUTE]: 'create_agent',\n },\n },\n span => {\n try {\n const compiledGraph = Reflect.apply(target, thisArg, args);\n const compileOptions = args.length > 0 ? (args[0] as Record<string, unknown>) : {};\n\n // Extract graph name\n if (compileOptions?.name && typeof compileOptions.name === 'string') {\n span.setAttribute(GEN_AI_AGENT_NAME_ATTRIBUTE, compileOptions.name);\n span.updateName(`create_agent ${compileOptions.name}`);\n }\n\n // Instrument agent invoke method on the compiled graph\n const originalInvoke = compiledGraph.invoke;\n if (originalInvoke && typeof originalInvoke === 'function') {\n compiledGraph.invoke = instrumentCompiledGraphInvoke(\n originalInvoke.bind(compiledGraph) as (...args: unknown[]) => Promise<unknown>,\n compiledGraph,\n compileOptions,\n options,\n ) as typeof originalInvoke;\n }\n\n return compiledGraph;\n } catch (error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureException(error, {\n mechanism: {\n handled: false,\n type: 'auto.ai.langgraph.error',\n },\n });\n throw error;\n }\n },\n );\n },\n }) as (...args: unknown[]) => CompiledGraph;\n}\n\n/**\n * Instruments CompiledGraph's invoke method to create spans for agent invocation\n *\n * Creates a `gen_ai.invoke_agent` span when invoke() is called\n */\nfunction instrumentCompiledGraphInvoke(\n originalInvoke: (...args: unknown[]) => Promise<unknown>,\n graphInstance: CompiledGraph,\n compileOptions: Record<string, unknown>,\n options: LangGraphOptions,\n): (...args: unknown[]) => Promise<unknown> {\n return new Proxy(originalInvoke, {\n apply(target, thisArg, args: unknown[]): Promise<unknown> {\n return startSpan(\n {\n op: 'gen_ai.invoke_agent',\n name: 'invoke_agent',\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: LANGGRAPH_ORIGIN,\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: GEN_AI_INVOKE_AGENT_OPERATION_ATTRIBUTE,\n [GEN_AI_OPERATION_NAME_ATTRIBUTE]: 'invoke_agent',\n },\n },\n async span => {\n try {\n const graphName = compileOptions?.name;\n\n if (graphName && typeof graphName === 'string') {\n span.setAttribute(GEN_AI_PIPELINE_NAME_ATTRIBUTE, graphName);\n span.setAttribute(GEN_AI_AGENT_NAME_ATTRIBUTE, graphName);\n span.updateName(`invoke_agent ${graphName}`);\n }\n\n // Extract thread_id from the config (second argument)\n // LangGraph uses config.configurable.thread_id for conversation/session linking\n const config = args.length > 1 ? (args[1] as Record<string, unknown> | undefined) : undefined;\n const configurable = config?.configurable as Record<string, unknown> | undefined;\n const threadId = configurable?.thread_id;\n if (threadId && typeof threadId === 'string') {\n span.setAttribute(GEN_AI_CONVERSATION_ID_ATTRIBUTE, threadId);\n }\n\n // Extract available tools from the graph instance\n const tools = extractToolsFromCompiledGraph(graphInstance);\n if (tools) {\n span.setAttribute(GEN_AI_REQUEST_AVAILABLE_TOOLS_ATTRIBUTE, JSON.stringify(tools));\n }\n\n // Parse input messages\n const recordInputs = options.recordInputs;\n const recordOutputs = options.recordOutputs;\n const inputMessages =\n args.length > 0 ? ((args[0] as { messages?: LangChainMessage[] }).messages ?? []) : [];\n\n if (inputMessages && recordInputs) {\n const normalizedMessages = normalizeLangChainMessages(inputMessages);\n const { systemInstructions, filteredMessages } = extractSystemInstructions(normalizedMessages);\n\n if (systemInstructions) {\n span.setAttribute(GEN_AI_SYSTEM_INSTRUCTIONS_ATTRIBUTE, systemInstructions);\n }\n\n const truncatedMessages = truncateGenAiMessages(filteredMessages as unknown[]);\n const filteredLength = Array.isArray(filteredMessages) ? filteredMessages.length : 0;\n span.setAttributes({\n [GEN_AI_INPUT_MESSAGES_ATTRIBUTE]: JSON.stringify(truncatedMessages),\n [GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE]: filteredLength,\n });\n }\n\n // Call original invoke\n const result = await Reflect.apply(target, thisArg, args);\n\n // Set response attributes\n if (recordOutputs) {\n setResponseAttributes(span, inputMessages ?? null, result);\n }\n\n return result;\n } catch (error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureException(error, {\n mechanism: {\n handled: false,\n type: 'auto.ai.langgraph.error',\n },\n });\n throw error;\n }\n },\n );\n },\n }) as (...args: unknown[]) => Promise<unknown>;\n}\n\n/**\n * Directly instruments a StateGraph instance to add tracing spans\n *\n * This function can be used to manually instrument LangGraph StateGraph instances\n * in environments where automatic instrumentation is not available or desired.\n *\n * @param stateGraph - The StateGraph instance to instrument\n * @param options - Optional configuration for recording inputs/outputs\n *\n * @example\n * ```typescript\n * import { instrumentLangGraph } from '@sentry/cloudflare';\n * import { StateGraph } from '@langchain/langgraph';\n *\n * const graph = new StateGraph(MessagesAnnotation)\n * .addNode('agent', mockLlm)\n * .addEdge(START, 'agent')\n * .addEdge('agent', END);\n *\n * instrumentLangGraph(graph, { recordInputs: true, recordOutputs: true });\n * const compiled = graph.compile({ name: 'my_agent' });\n * ```\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function instrumentLangGraph<T extends { compile: (...args: any[]) => any }>(\n stateGraph: T,\n options?: LangGraphOptions,\n): T {\n const _options: LangGraphOptions = options || {};\n\n stateGraph.compile = instrumentStateGraphCompile(stateGraph.compile.bind(stateGraph), _options);\n\n return stateGraph;\n}\n"],"names":["startSpan","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","LANGGRAPH_ORIGIN","SEMANTIC_ATTRIBUTE_SENTRY_OP","GEN_AI_OPERATION_NAME_ATTRIBUTE","GEN_AI_AGENT_NAME_ATTRIBUTE","SPAN_STATUS_ERROR","captureException","GEN_AI_INVOKE_AGENT_OPERATION_ATTRIBUTE","GEN_AI_PIPELINE_NAME_ATTRIBUTE","GEN_AI_CONVERSATION_ID_ATTRIBUTE","extractToolsFromCompiledGraph","GEN_AI_REQUEST_AVAILABLE_TOOLS_ATTRIBUTE","normalizeLangChainMessages","extractSystemInstructions","GEN_AI_SYSTEM_INSTRUCTIONS_ATTRIBUTE","truncateGenAiMessages","GEN_AI_INPUT_MESSAGES_ATTRIBUTE","GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE","setResponseAttributes"],"mappings":"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"}
@@ -1,8 +1,11 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
 
3
3
  const currentScopes = require('../../currentScopes.js');
4
- const exports$1 = require('../../exports.js');
4
+ const debugBuild = require('../../debug-build.js');
5
+ const _exports = require('../../exports.js');
5
6
  const semanticAttributes = require('../../semanticAttributes.js');
7
+ const debugLogger = require('../../utils/debug-logger.js');
8
+ const is = require('../../utils/is.js');
6
9
  const spanstatus = require('../spanstatus.js');
7
10
  const trace = require('../trace.js');
8
11
  const genAiAttributes = require('../ai/gen-ai-attributes.js');
@@ -21,7 +24,16 @@ function extractAvailableTools(params) {
21
24
  : [];
22
25
 
23
26
  const availableTools = [...tools, ...webSearchOptions];
24
- return availableTools.length > 0 ? JSON.stringify(availableTools) : undefined;
27
+ if (availableTools.length === 0) {
28
+ return undefined;
29
+ }
30
+
31
+ try {
32
+ return JSON.stringify(availableTools);
33
+ } catch (error) {
34
+ debugBuild.DEBUG_BUILD && debugLogger.debug.error('Failed to serialize OpenAI tools:', error);
35
+ return undefined;
36
+ }
25
37
  }
26
38
 
27
39
  /**
@@ -129,6 +141,75 @@ function addRequestAttributes(span, params, operationName) {
129
141
  }
130
142
  }
131
143
 
144
+ /**
145
+ * Creates a wrapped version of .withResponse() that replaces the data field
146
+ * with the instrumented result while preserving metadata (response, request_id).
147
+ */
148
+ async function createWithResponseWrapper(
149
+ originalWithResponse,
150
+ instrumentedPromise,
151
+ ) {
152
+ // Attach catch handler to originalWithResponse immediately to prevent unhandled rejection
153
+ // If instrumentedPromise rejects first, we still need this handled
154
+ const safeOriginalWithResponse = originalWithResponse.catch(error => {
155
+ _exports.captureException(error, {
156
+ mechanism: {
157
+ handled: false,
158
+ type: 'auto.ai.openai',
159
+ },
160
+ });
161
+ throw error;
162
+ });
163
+
164
+ const instrumentedResult = await instrumentedPromise;
165
+ const originalWrapper = await safeOriginalWithResponse;
166
+
167
+ // Combine instrumented result with original metadata
168
+ if (originalWrapper && typeof originalWrapper === 'object' && 'data' in originalWrapper) {
169
+ return {
170
+ ...originalWrapper,
171
+ data: instrumentedResult,
172
+ };
173
+ }
174
+ return instrumentedResult;
175
+ }
176
+
177
+ /**
178
+ * Wraps a promise-like object to preserve additional methods (like .withResponse())
179
+ */
180
+ function wrapPromiseWithMethods(originalPromiseLike, instrumentedPromise) {
181
+ // If the original result is not thenable, return the instrumented promise
182
+ // Should not happen with current OpenAI SDK instrumented methods, but just in case.
183
+ if (!is.isThenable(originalPromiseLike)) {
184
+ return instrumentedPromise;
185
+ }
186
+
187
+ // Create a proxy that forwards Promise methods to instrumentedPromise
188
+ // and preserves additional methods from the original result
189
+ return new Proxy(originalPromiseLike, {
190
+ get(target, prop) {
191
+ // For standard Promise methods (.then, .catch, .finally, Symbol.toStringTag),
192
+ // use instrumentedPromise to preserve Sentry instrumentation.
193
+ // For custom methods (like .withResponse()), use the original target.
194
+ const useInstrumentedPromise = prop in Promise.prototype || prop === Symbol.toStringTag;
195
+ const source = useInstrumentedPromise ? instrumentedPromise : target;
196
+
197
+ const value = Reflect.get(source, prop) ;
198
+
199
+ // Special handling for .withResponse() to preserve instrumentation
200
+ // .withResponse() returns { data: T, response: Response, request_id: string }
201
+ if (prop === 'withResponse' && typeof value === 'function') {
202
+ return function wrappedWithResponse() {
203
+ const originalWithResponse = (value ).call(target);
204
+ return createWithResponseWrapper(originalWithResponse, instrumentedPromise);
205
+ };
206
+ }
207
+
208
+ return typeof value === 'function' ? value.bind(source) : value;
209
+ },
210
+ }) ;
211
+ }
212
+
132
213
  /**
133
214
  * Instrument a method with Sentry spans
134
215
  * Following Sentry AI Agents Manual Instrumentation conventions
@@ -140,7 +221,7 @@ function instrumentMethod(
140
221
  context,
141
222
  options,
142
223
  ) {
143
- return async function instrumentedMethod(...args) {
224
+ return function instrumentedMethod(...args) {
144
225
  const requestAttributes = extractRequestAttributes(args, methodPath);
145
226
  const model = (requestAttributes[genAiAttributes.GEN_AI_REQUEST_MODEL_ATTRIBUTE] ) || 'unknown';
146
227
  const operationName = utils.getOperationName(methodPath);
@@ -148,77 +229,79 @@ function instrumentMethod(
148
229
  const params = args[0] ;
149
230
  const isStreamRequested = params && typeof params === 'object' && params.stream === true;
150
231
 
232
+ const spanConfig = {
233
+ name: `${operationName} ${model}${isStreamRequested ? ' stream-response' : ''}`,
234
+ op: utils.getSpanOperation(methodPath),
235
+ attributes: requestAttributes ,
236
+ };
237
+
151
238
  if (isStreamRequested) {
152
- // For streaming responses, use manual span management to properly handle the async generator lifecycle
153
- return trace.startSpanManual(
154
- {
155
- name: `${operationName} ${model} stream-response`,
156
- op: utils.getSpanOperation(methodPath),
157
- attributes: requestAttributes ,
158
- },
159
- async (span) => {
160
- try {
161
- if (options.recordInputs && params) {
162
- addRequestAttributes(span, params, operationName);
163
- }
239
+ let originalResult;
164
240
 
165
- const result = await originalMethod.apply(context, args);
241
+ const instrumentedPromise = trace.startSpanManual(spanConfig, (span) => {
242
+ originalResult = originalMethod.apply(context, args);
166
243
 
244
+ if (options.recordInputs && params) {
245
+ addRequestAttributes(span, params, operationName);
246
+ }
247
+
248
+ // Return async processing
249
+ return (async () => {
250
+ try {
251
+ const result = await originalResult;
167
252
  return streaming.instrumentStream(
168
253
  result ,
169
254
  span,
170
255
  options.recordOutputs ?? false,
171
256
  ) ;
172
257
  } catch (error) {
173
- // For streaming requests that fail before stream creation, we still want to record
174
- // them as streaming requests but end the span gracefully
175
258
  span.setStatus({ code: spanstatus.SPAN_STATUS_ERROR, message: 'internal_error' });
176
- exports$1.captureException(error, {
259
+ _exports.captureException(error, {
177
260
  mechanism: {
178
261
  handled: false,
179
262
  type: 'auto.ai.openai.stream',
180
- data: {
181
- function: methodPath,
182
- },
263
+ data: { function: methodPath },
183
264
  },
184
265
  });
185
266
  span.end();
186
267
  throw error;
187
268
  }
188
- },
189
- );
190
- } else {
191
- // Non-streaming responses
192
- return trace.startSpan(
193
- {
194
- name: `${operationName} ${model}`,
195
- op: utils.getSpanOperation(methodPath),
196
- attributes: requestAttributes ,
197
- },
198
- async (span) => {
199
- try {
200
- if (options.recordInputs && params) {
201
- addRequestAttributes(span, params, operationName);
202
- }
269
+ })();
270
+ });
203
271
 
204
- const result = await originalMethod.apply(context, args);
205
- addResponseAttributes(span, result, options.recordOutputs);
206
- return result;
207
- } catch (error) {
208
- exports$1.captureException(error, {
209
- mechanism: {
210
- handled: false,
211
- type: 'auto.ai.openai',
212
- data: {
213
- function: methodPath,
214
- },
215
- },
216
- });
217
- throw error;
218
- }
272
+ return wrapPromiseWithMethods(originalResult, instrumentedPromise);
273
+ }
274
+
275
+ // Non-streaming
276
+ let originalResult;
277
+
278
+ const instrumentedPromise = trace.startSpan(spanConfig, (span) => {
279
+ // Call synchronously to capture the promise
280
+ originalResult = originalMethod.apply(context, args);
281
+
282
+ if (options.recordInputs && params) {
283
+ addRequestAttributes(span, params, operationName);
284
+ }
285
+
286
+ return originalResult.then(
287
+ result => {
288
+ addResponseAttributes(span, result, options.recordOutputs);
289
+ return result;
290
+ },
291
+ error => {
292
+ _exports.captureException(error, {
293
+ mechanism: {
294
+ handled: false,
295
+ type: 'auto.ai.openai',
296
+ data: { function: methodPath },
297
+ },
298
+ });
299
+ throw error;
219
300
  },
220
301
  );
221
- }
302
+ });
303
+
304
+ return wrapPromiseWithMethods(originalResult, instrumentedPromise);
222
305
  };
223
306
  }
224
307
 
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../../src/tracing/openai/index.ts"],"sourcesContent":["import { getClient } from '../../currentScopes';\nimport { captureException } from '../../exports';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '../../semanticAttributes';\nimport { SPAN_STATUS_ERROR } from '../../tracing';\nimport { startSpan, startSpanManual } from '../../tracing/trace';\nimport type { Span, SpanAttributeValue } from '../../types-hoist/span';\nimport {\n GEN_AI_EMBEDDINGS_INPUT_ATTRIBUTE,\n GEN_AI_INPUT_MESSAGES_ATTRIBUTE,\n GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE,\n GEN_AI_OPERATION_NAME_ATTRIBUTE,\n GEN_AI_REQUEST_AVAILABLE_TOOLS_ATTRIBUTE,\n GEN_AI_REQUEST_MODEL_ATTRIBUTE,\n GEN_AI_RESPONSE_TEXT_ATTRIBUTE,\n GEN_AI_SYSTEM_ATTRIBUTE,\n GEN_AI_SYSTEM_INSTRUCTIONS_ATTRIBUTE,\n OPENAI_OPERATIONS,\n} from '../ai/gen-ai-attributes';\nimport { extractSystemInstructions, getTruncatedJsonString } from '../ai/utils';\nimport { instrumentStream } from './streaming';\nimport type {\n ChatCompletionChunk,\n InstrumentedMethod,\n OpenAiOptions,\n OpenAiResponse,\n OpenAIStream,\n ResponseStreamingEvent,\n} from './types';\nimport {\n addChatCompletionAttributes,\n addConversationAttributes,\n addEmbeddingsAttributes,\n addResponsesApiAttributes,\n buildMethodPath,\n extractRequestParameters,\n getOperationName,\n getSpanOperation,\n isChatCompletionResponse,\n isConversationResponse,\n isEmbeddingsResponse,\n isResponsesApiResponse,\n shouldInstrument,\n} from './utils';\n\n/**\n * Extract available tools from request parameters\n */\nfunction extractAvailableTools(params: Record<string, unknown>): string | undefined {\n const tools = Array.isArray(params.tools) ? params.tools : [];\n const hasWebSearchOptions = params.web_search_options && typeof params.web_search_options === 'object';\n const webSearchOptions = hasWebSearchOptions\n ? [{ type: 'web_search_options', ...(params.web_search_options as Record<string, unknown>) }]\n : [];\n\n const availableTools = [...tools, ...webSearchOptions];\n return availableTools.length > 0 ? JSON.stringify(availableTools) : undefined;\n}\n\n/**\n * Extract request attributes from method arguments\n */\nfunction extractRequestAttributes(args: unknown[], methodPath: string): Record<string, unknown> {\n const attributes: Record<string, unknown> = {\n [GEN_AI_SYSTEM_ATTRIBUTE]: 'openai',\n [GEN_AI_OPERATION_NAME_ATTRIBUTE]: getOperationName(methodPath),\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ai.openai',\n };\n\n if (args.length > 0 && typeof args[0] === 'object' && args[0] !== null) {\n const params = args[0] as Record<string, unknown>;\n\n const availableTools = extractAvailableTools(params);\n if (availableTools) {\n attributes[GEN_AI_REQUEST_AVAILABLE_TOOLS_ATTRIBUTE] = availableTools;\n }\n\n Object.assign(attributes, extractRequestParameters(params));\n } else {\n attributes[GEN_AI_REQUEST_MODEL_ATTRIBUTE] = 'unknown';\n }\n\n return attributes;\n}\n\n/**\n * Add response attributes to spans\n * This supports Chat Completion, Responses API, Embeddings, and Conversations API responses\n */\nfunction addResponseAttributes(span: Span, result: unknown, recordOutputs?: boolean): void {\n if (!result || typeof result !== 'object') return;\n\n const response = result as OpenAiResponse;\n\n if (isChatCompletionResponse(response)) {\n addChatCompletionAttributes(span, response, recordOutputs);\n if (recordOutputs && response.choices?.length) {\n const responseTexts = response.choices.map(choice => choice.message?.content || '');\n span.setAttributes({ [GEN_AI_RESPONSE_TEXT_ATTRIBUTE]: JSON.stringify(responseTexts) });\n }\n } else if (isResponsesApiResponse(response)) {\n addResponsesApiAttributes(span, response, recordOutputs);\n if (recordOutputs && response.output_text) {\n span.setAttributes({ [GEN_AI_RESPONSE_TEXT_ATTRIBUTE]: response.output_text });\n }\n } else if (isEmbeddingsResponse(response)) {\n addEmbeddingsAttributes(span, response);\n } else if (isConversationResponse(response)) {\n addConversationAttributes(span, response);\n }\n}\n\n// Extract and record AI request inputs, if present. This is intentionally separate from response attributes.\nfunction addRequestAttributes(span: Span, params: Record<string, unknown>, operationName: string): void {\n // Store embeddings input on a separate attribute and do not truncate it\n if (operationName === OPENAI_OPERATIONS.EMBEDDINGS && 'input' in params) {\n const input = params.input;\n\n // No input provided\n if (input == null) {\n return;\n }\n\n // Empty input string\n if (typeof input === 'string' && input.length === 0) {\n return;\n }\n\n // Empty array input\n if (Array.isArray(input) && input.length === 0) {\n return;\n }\n\n // Store strings as-is, arrays/objects as JSON\n span.setAttribute(GEN_AI_EMBEDDINGS_INPUT_ATTRIBUTE, typeof input === 'string' ? input : JSON.stringify(input));\n return;\n }\n\n const src = 'input' in params ? params.input : 'messages' in params ? params.messages : undefined;\n\n if (!src) {\n return;\n }\n\n if (Array.isArray(src) && src.length === 0) {\n return;\n }\n\n const { systemInstructions, filteredMessages } = extractSystemInstructions(src);\n\n if (systemInstructions) {\n span.setAttribute(GEN_AI_SYSTEM_INSTRUCTIONS_ATTRIBUTE, systemInstructions);\n }\n\n const truncatedInput = getTruncatedJsonString(filteredMessages);\n span.setAttribute(GEN_AI_INPUT_MESSAGES_ATTRIBUTE, truncatedInput);\n\n if (Array.isArray(filteredMessages)) {\n span.setAttribute(GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE, filteredMessages.length);\n } else {\n span.setAttribute(GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE, 1);\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) => Promise<R>,\n methodPath: InstrumentedMethod,\n context: unknown,\n options: OpenAiOptions,\n): (...args: T) => Promise<R> {\n return async function instrumentedMethod(...args: T): Promise<R> {\n const requestAttributes = extractRequestAttributes(args, methodPath);\n const model = (requestAttributes[GEN_AI_REQUEST_MODEL_ATTRIBUTE] as string) || 'unknown';\n const operationName = getOperationName(methodPath);\n\n const params = args[0] as Record<string, unknown> | undefined;\n const isStreamRequested = params && typeof params === 'object' && params.stream === true;\n\n if (isStreamRequested) {\n // For streaming responses, use manual span management to properly handle the async generator lifecycle\n return startSpanManual(\n {\n name: `${operationName} ${model} stream-response`,\n op: getSpanOperation(methodPath),\n attributes: requestAttributes as Record<string, SpanAttributeValue>,\n },\n async (span: Span) => {\n try {\n if (options.recordInputs && params) {\n addRequestAttributes(span, params, operationName);\n }\n\n const result = await originalMethod.apply(context, args);\n\n return instrumentStream(\n result as OpenAIStream<ChatCompletionChunk | ResponseStreamingEvent>,\n span,\n options.recordOutputs ?? false,\n ) as unknown as R;\n } catch (error) {\n // For streaming requests that fail before stream creation, we still want to record\n // them as streaming requests but end the span gracefully\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureException(error, {\n mechanism: {\n handled: false,\n type: 'auto.ai.openai.stream',\n data: {\n function: methodPath,\n },\n },\n });\n span.end();\n throw error;\n }\n },\n );\n } else {\n // Non-streaming responses\n return startSpan(\n {\n name: `${operationName} ${model}`,\n op: getSpanOperation(methodPath),\n attributes: requestAttributes as Record<string, SpanAttributeValue>,\n },\n async (span: Span) => {\n try {\n if (options.recordInputs && params) {\n addRequestAttributes(span, params, operationName);\n }\n\n const result = await originalMethod.apply(context, args);\n addResponseAttributes(span, result, options.recordOutputs);\n return result;\n } catch (error) {\n captureException(error, {\n mechanism: {\n handled: false,\n type: 'auto.ai.openai',\n data: {\n function: methodPath,\n },\n },\n });\n throw error;\n }\n },\n );\n }\n };\n}\n\n/**\n * Create a deep proxy for OpenAI client instrumentation\n */\nfunction createDeepProxy<T extends object>(target: T, currentPath = '', options: OpenAiOptions): 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 if (typeof value === 'function' && shouldInstrument(methodPath)) {\n return instrumentMethod(value as (...args: unknown[]) => Promise<unknown>, methodPath, obj, options);\n }\n\n if (typeof value === 'function') {\n // Bind non-instrumented functions to preserve the original `this` context,\n // which is required for accessing private class fields (e.g. #baseURL) in OpenAI SDK v5.\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 OpenAI client with Sentry tracing\n * Can be used across Node.js, Cloudflare Workers, and Vercel Edge\n */\nexport function instrumentOpenAiClient<T extends object>(client: T, options?: OpenAiOptions): T {\n const sendDefaultPii = Boolean(getClient()?.getOptions().sendDefaultPii);\n\n const _options = {\n recordInputs: sendDefaultPii,\n recordOutputs: sendDefaultPii,\n ...options,\n };\n\n return createDeepProxy(client, '', _options);\n}\n"],"names":["GEN_AI_SYSTEM_ATTRIBUTE","GEN_AI_OPERATION_NAME_ATTRIBUTE","getOperationName","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","GEN_AI_REQUEST_AVAILABLE_TOOLS_ATTRIBUTE","extractRequestParameters","GEN_AI_REQUEST_MODEL_ATTRIBUTE","isChatCompletionResponse","addChatCompletionAttributes","GEN_AI_RESPONSE_TEXT_ATTRIBUTE","isResponsesApiResponse","addResponsesApiAttributes","isEmbeddingsResponse","addEmbeddingsAttributes","isConversationResponse","addConversationAttributes","OPENAI_OPERATIONS","GEN_AI_EMBEDDINGS_INPUT_ATTRIBUTE","extractSystemInstructions","GEN_AI_SYSTEM_INSTRUCTIONS_ATTRIBUTE","getTruncatedJsonString","GEN_AI_INPUT_MESSAGES_ATTRIBUTE","GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE","startSpanManual","getSpanOperation","instrumentStream","SPAN_STATUS_ERROR","captureException","startSpan","buildMethodPath","shouldInstrument","getClient"],"mappings":";;;;;;;;;;;;AA4CA;AACA;AACA;AACA,SAAS,qBAAqB,CAAC,MAAM,EAA+C;AACpF,EAAE,MAAM,KAAA,GAAQ,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,KAAA,GAAQ,EAAE;AAC/D,EAAE,MAAM,mBAAA,GAAsB,MAAM,CAAC,kBAAA,IAAsB,OAAO,MAAM,CAAC,kBAAA,KAAuB,QAAQ;AACxG,EAAE,MAAM,mBAAmB;AAC3B,MAAM,CAAC,EAAE,IAAI,EAAE,oBAAoB,EAAE,IAAI,MAAM,CAAC,kBAAA,IAAgD;AAChG,MAAM,EAAE;;AAER,EAAE,MAAM,iBAAiB,CAAC,GAAG,KAAK,EAAE,GAAG,gBAAgB,CAAC;AACxD,EAAE,OAAO,cAAc,CAAC,MAAA,GAAS,CAAA,GAAI,IAAI,CAAC,SAAS,CAAC,cAAc,CAAA,GAAI,SAAS;AAC/E;;AAEA;AACA;AACA;AACA,SAAS,wBAAwB,CAAC,IAAI,EAAa,UAAU,EAAmC;AAChG,EAAE,MAAM,UAAU,GAA4B;AAC9C,IAAI,CAACA,uCAAuB,GAAG,QAAQ;AACvC,IAAI,CAACC,+CAA+B,GAAGC,sBAAgB,CAAC,UAAU,CAAC;AACnE,IAAI,CAACC,mDAAgC,GAAG,gBAAgB;AACxD,GAAG;;AAEH,EAAE,IAAI,IAAI,CAAC,SAAS,CAAA,IAAK,OAAO,IAAI,CAAC,CAAC,CAAA,KAAM,YAAY,IAAI,CAAC,CAAC,CAAA,KAAM,IAAI,EAAE;AAC1E,IAAI,MAAM,MAAA,GAAS,IAAI,CAAC,CAAC,CAAA;;AAEzB,IAAI,MAAM,cAAA,GAAiB,qBAAqB,CAAC,MAAM,CAAC;AACxD,IAAI,IAAI,cAAc,EAAE;AACxB,MAAM,UAAU,CAACC,wDAAwC,CAAA,GAAI,cAAc;AAC3E,IAAI;;AAEJ,IAAI,MAAM,CAAC,MAAM,CAAC,UAAU,EAAEC,8BAAwB,CAAC,MAAM,CAAC,CAAC;AAC/D,EAAE,OAAO;AACT,IAAI,UAAU,CAACC,8CAA8B,CAAA,GAAI,SAAS;AAC1D,EAAE;;AAEF,EAAE,OAAO,UAAU;AACnB;;AAEA;AACA;AACA;AACA;AACA,SAAS,qBAAqB,CAAC,IAAI,EAAQ,MAAM,EAAW,aAAa,EAAkB;AAC3F,EAAE,IAAI,CAAC,MAAA,IAAU,OAAO,MAAA,KAAW,QAAQ,EAAE;;AAE7C,EAAE,MAAM,QAAA,GAAW,MAAA;;AAEnB,EAAE,IAAIC,8BAAwB,CAAC,QAAQ,CAAC,EAAE;AAC1C,IAAIC,iCAA2B,CAAC,IAAI,EAAE,QAAQ,EAAE,aAAa,CAAC;AAC9D,IAAI,IAAI,aAAA,IAAiB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE;AACnD,MAAM,MAAM,aAAA,GAAgB,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,MAAA,IAAU,MAAM,CAAC,OAAO,EAAE,OAAA,IAAW,EAAE,CAAC;AACzF,MAAM,IAAI,CAAC,aAAa,CAAC,EAAE,CAACC,8CAA8B,GAAG,IAAI,CAAC,SAAS,CAAC,aAAa,CAAA,EAAG,CAAC;AAC7F,IAAI;AACJ,EAAE,CAAA,MAAO,IAAIC,4BAAsB,CAAC,QAAQ,CAAC,EAAE;AAC/C,IAAIC,+BAAyB,CAAC,IAAI,EAAE,QAAQ,EAAE,aAAa,CAAC;AAC5D,IAAI,IAAI,aAAA,IAAiB,QAAQ,CAAC,WAAW,EAAE;AAC/C,MAAM,IAAI,CAAC,aAAa,CAAC,EAAE,CAACF,8CAA8B,GAAG,QAAQ,CAAC,WAAA,EAAa,CAAC;AACpF,IAAI;AACJ,EAAE,CAAA,MAAO,IAAIG,0BAAoB,CAAC,QAAQ,CAAC,EAAE;AAC7C,IAAIC,6BAAuB,CAAC,IAAI,EAAE,QAAQ,CAAC;AAC3C,EAAE,CAAA,MAAO,IAAIC,4BAAsB,CAAC,QAAQ,CAAC,EAAE;AAC/C,IAAIC,+BAAyB,CAAC,IAAI,EAAE,QAAQ,CAAC;AAC7C,EAAE;AACF;;AAEA;AACA,SAAS,oBAAoB,CAAC,IAAI,EAAQ,MAAM,EAA2B,aAAa,EAAgB;AACxG;AACA,EAAE,IAAI,aAAA,KAAkBC,iCAAiB,CAAC,UAAA,IAAc,OAAA,IAAW,MAAM,EAAE;AAC3E,IAAI,MAAM,KAAA,GAAQ,MAAM,CAAC,KAAK;;AAE9B;AACA,IAAI,IAAI,KAAA,IAAS,IAAI,EAAE;AACvB,MAAM;AACN,IAAI;;AAEJ;AACA,IAAI,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,KAAK,CAAC,MAAA,KAAW,CAAC,EAAE;AACzD,MAAM;AACN,IAAI;;AAEJ;AACA,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAA,IAAK,KAAK,CAAC,MAAA,KAAW,CAAC,EAAE;AACpD,MAAM;AACN,IAAI;;AAEJ;AACA,IAAI,IAAI,CAAC,YAAY,CAACC,iDAAiC,EAAE,OAAO,KAAA,KAAU,WAAW,KAAA,GAAQ,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;AACnH,IAAI;AACJ,EAAE;;AAEF,EAAE,MAAM,GAAA,GAAM,WAAW,MAAA,GAAS,MAAM,CAAC,QAAQ,UAAA,IAAc,MAAA,GAAS,MAAM,CAAC,QAAA,GAAW,SAAS;;AAEnG,EAAE,IAAI,CAAC,GAAG,EAAE;AACZ,IAAI;AACJ,EAAE;;AAEF,EAAE,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAA,IAAK,GAAG,CAAC,MAAA,KAAW,CAAC,EAAE;AAC9C,IAAI;AACJ,EAAE;;AAEF,EAAE,MAAM,EAAE,kBAAkB,EAAE,gBAAA,KAAqBC,iCAAyB,CAAC,GAAG,CAAC;;AAEjF,EAAE,IAAI,kBAAkB,EAAE;AAC1B,IAAI,IAAI,CAAC,YAAY,CAACC,oDAAoC,EAAE,kBAAkB,CAAC;AAC/E,EAAE;;AAEF,EAAE,MAAM,cAAA,GAAiBC,8BAAsB,CAAC,gBAAgB,CAAC;AACjE,EAAE,IAAI,CAAC,YAAY,CAACC,+CAA+B,EAAE,cAAc,CAAC;;AAEpE,EAAE,IAAI,KAAK,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE;AACvC,IAAI,IAAI,CAAC,YAAY,CAACC,+DAA+C,EAAE,gBAAgB,CAAC,MAAM,CAAC;AAC/F,EAAE,OAAO;AACT,IAAI,IAAI,CAAC,YAAY,CAACA,+DAA+C,EAAE,CAAC,CAAC;AACzE,EAAE;AACF;;AAEA;AACA;AACA;AACA;AACA;AACA,SAAS,gBAAgB;AACzB,EAAE,cAAc;AAChB,EAAE,UAAU;AACZ,EAAE,OAAO;AACT,EAAE,OAAO;AACT,EAA8B;AAC9B,EAAE,OAAO,eAAe,kBAAkB,CAAC,GAAG,IAAI,EAAiB;AACnE,IAAI,MAAM,oBAAoB,wBAAwB,CAAC,IAAI,EAAE,UAAU,CAAC;AACxE,IAAI,MAAM,KAAA,GAAQ,CAAC,iBAAiB,CAAChB,8CAA8B,CAAA,MAAgB,SAAS;AAC5F,IAAI,MAAM,aAAA,GAAgBJ,sBAAgB,CAAC,UAAU,CAAC;;AAEtD,IAAI,MAAM,MAAA,GAAS,IAAI,CAAC,CAAC,CAAA;AACzB,IAAI,MAAM,iBAAA,GAAoB,MAAA,IAAU,OAAO,MAAA,KAAW,QAAA,IAAY,MAAM,CAAC,MAAA,KAAW,IAAI;;AAE5F,IAAI,IAAI,iBAAiB,EAAE;AAC3B;AACA,MAAM,OAAOqB,qBAAe;AAC5B,QAAQ;AACR,UAAU,IAAI,EAAE,CAAC,EAAA,aAAA,CAAA,CAAA,EAAA,KAAA,CAAA,gBAAA,CAAA;AACA,UAAA,EAAA,EAAAC,sBAAA,CAAA,UAAA,CAAA;AACA,UAAA,UAAA,EAAA,iBAAA;AACA,SAAA;AACA,QAAA,OAAA,IAAA,KAAA;AACA,UAAA,IAAA;AACA,YAAA,IAAA,OAAA,CAAA,YAAA,IAAA,MAAA,EAAA;AACA,cAAA,oBAAA,CAAA,IAAA,EAAA,MAAA,EAAA,aAAA,CAAA;AACA,YAAA;;AAEA,YAAA,MAAA,MAAA,GAAA,MAAA,cAAA,CAAA,KAAA,CAAA,OAAA,EAAA,IAAA,CAAA;;AAEA,YAAA,OAAAC,0BAAA;AACA,cAAA,MAAA;AACA,cAAA,IAAA;AACA,cAAA,OAAA,CAAA,aAAA,IAAA,KAAA;AACA,aAAA;AACA,UAAA,CAAA,CAAA,OAAA,KAAA,EAAA;AACA;AACA;AACA,YAAA,IAAA,CAAA,SAAA,CAAA,EAAA,IAAA,EAAAC,4BAAA,EAAA,OAAA,EAAA,gBAAA,EAAA,CAAA;AACA,YAAAC,0BAAA,CAAA,KAAA,EAAA;AACA,cAAA,SAAA,EAAA;AACA,gBAAA,OAAA,EAAA,KAAA;AACA,gBAAA,IAAA,EAAA,uBAAA;AACA,gBAAA,IAAA,EAAA;AACA,kBAAA,QAAA,EAAA,UAAA;AACA,iBAAA;AACA,eAAA;AACA,aAAA,CAAA;AACA,YAAA,IAAA,CAAA,GAAA,EAAA;AACA,YAAA,MAAA,KAAA;AACA,UAAA;AACA,QAAA,CAAA;AACA,OAAA;AACA,IAAA,CAAA,MAAA;AACA;AACA,MAAA,OAAAC,eAAA;AACA,QAAA;AACA,UAAA,IAAA,EAAA,CAAA,EAAA,aAAA,CAAA,CAAA,EAAA,KAAA,CAAA,CAAA;AACA,UAAA,EAAA,EAAAJ,sBAAA,CAAA,UAAA,CAAA;AACA,UAAA,UAAA,EAAA,iBAAA;AACA,SAAA;AACA,QAAA,OAAA,IAAA,KAAA;AACA,UAAA,IAAA;AACA,YAAA,IAAA,OAAA,CAAA,YAAA,IAAA,MAAA,EAAA;AACA,cAAA,oBAAA,CAAA,IAAA,EAAA,MAAA,EAAA,aAAA,CAAA;AACA,YAAA;;AAEA,YAAA,MAAA,MAAA,GAAA,MAAA,cAAA,CAAA,KAAA,CAAA,OAAA,EAAA,IAAA,CAAA;AACA,YAAA,qBAAA,CAAA,IAAA,EAAA,MAAA,EAAA,OAAA,CAAA,aAAA,CAAA;AACA,YAAA,OAAA,MAAA;AACA,UAAA,CAAA,CAAA,OAAA,KAAA,EAAA;AACA,YAAAG,0BAAA,CAAA,KAAA,EAAA;AACA,cAAA,SAAA,EAAA;AACA,gBAAA,OAAA,EAAA,KAAA;AACA,gBAAA,IAAA,EAAA,gBAAA;AACA,gBAAA,IAAA,EAAA;AACA,kBAAA,QAAA,EAAA,UAAA;AACA,iBAAA;AACA,eAAA;AACA,aAAA,CAAA;AACA,YAAA,MAAA,KAAA;AACA,UAAA;AACA,QAAA,CAAA;AACA,OAAA;AACA,IAAA;AACA,EAAA,CAAA;AACA;;AAEA;AACA;AACA;AACA,SAAA,eAAA,CAAA,MAAA,EAAA,WAAA,GAAA,EAAA,EAAA,OAAA,EAAA;AACA,EAAA,OAAA,IAAA,KAAA,CAAA,MAAA,EAAA;AACA,IAAA,GAAA,CAAA,GAAA,EAAA,IAAA,EAAA;AACA,MAAA,MAAA,KAAA,GAAA,CAAA,GAAA,GAAA,IAAA,CAAA;AACA,MAAA,MAAA,UAAA,GAAAE,qBAAA,CAAA,WAAA,EAAA,MAAA,CAAA,IAAA,CAAA,CAAA;;AAEA,MAAA,IAAA,OAAA,KAAA,KAAA,UAAA,IAAAC,sBAAA,CAAA,UAAA,CAAA,EAAA;AACA,QAAA,OAAA,gBAAA,CAAA,KAAA,GAAA,UAAA,EAAA,GAAA,EAAA,OAAA,CAAA;AACA,MAAA;;AAEA,MAAA,IAAA,OAAA,KAAA,KAAA,UAAA,EAAA;AACA;AACA;AACA,QAAA,OAAA,KAAA,CAAA,IAAA,CAAA,GAAA,CAAA;AACA,MAAA;;AAEA,MAAA,IAAA,KAAA,IAAA,OAAA,KAAA,KAAA,QAAA,EAAA;AACA,QAAA,OAAA,eAAA,CAAA,KAAA,EAAA,UAAA,EAAA,OAAA,CAAA;AACA,MAAA;;AAEA,MAAA,OAAA,KAAA;AACA,IAAA,CAAA;AACA,GAAA,CAAA;AACA;;AAEA;AACA;AACA;AACA;AACA,SAAA,sBAAA,CAAA,MAAA,EAAA,OAAA,EAAA;AACA,EAAA,MAAA,cAAA,GAAA,OAAA,CAAAC,uBAAA,EAAA,EAAA,UAAA,EAAA,CAAA,cAAA,CAAA;;AAEA,EAAA,MAAA,QAAA,GAAA;AACA,IAAA,YAAA,EAAA,cAAA;AACA,IAAA,aAAA,EAAA,cAAA;AACA,IAAA,GAAA,OAAA;AACA,GAAA;;AAEA,EAAA,OAAA,eAAA,CAAA,MAAA,EAAA,EAAA,EAAA,QAAA,CAAA;AACA;;;;"}
1
+ {"version":3,"file":"index.js","sources":["../../../../src/tracing/openai/index.ts"],"sourcesContent":["import { getClient } from '../../currentScopes';\nimport { DEBUG_BUILD } from '../../debug-build';\nimport { captureException } from '../../exports';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '../../semanticAttributes';\nimport { SPAN_STATUS_ERROR } from '../../tracing';\nimport { startSpan, startSpanManual } from '../../tracing/trace';\nimport type { Span, SpanAttributeValue } from '../../types-hoist/span';\nimport { debug } from '../../utils/debug-logger';\nimport { isThenable } from '../../utils/is';\nimport {\n GEN_AI_EMBEDDINGS_INPUT_ATTRIBUTE,\n GEN_AI_INPUT_MESSAGES_ATTRIBUTE,\n GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE,\n GEN_AI_OPERATION_NAME_ATTRIBUTE,\n GEN_AI_REQUEST_AVAILABLE_TOOLS_ATTRIBUTE,\n GEN_AI_REQUEST_MODEL_ATTRIBUTE,\n GEN_AI_RESPONSE_TEXT_ATTRIBUTE,\n GEN_AI_SYSTEM_ATTRIBUTE,\n GEN_AI_SYSTEM_INSTRUCTIONS_ATTRIBUTE,\n OPENAI_OPERATIONS,\n} from '../ai/gen-ai-attributes';\nimport { extractSystemInstructions, getTruncatedJsonString } from '../ai/utils';\nimport { instrumentStream } from './streaming';\nimport type {\n ChatCompletionChunk,\n InstrumentedMethod,\n OpenAiOptions,\n OpenAiResponse,\n OpenAIStream,\n ResponseStreamingEvent,\n} from './types';\nimport {\n addChatCompletionAttributes,\n addConversationAttributes,\n addEmbeddingsAttributes,\n addResponsesApiAttributes,\n buildMethodPath,\n extractRequestParameters,\n getOperationName,\n getSpanOperation,\n isChatCompletionResponse,\n isConversationResponse,\n isEmbeddingsResponse,\n isResponsesApiResponse,\n shouldInstrument,\n} from './utils';\n\n/**\n * Extract available tools from request parameters\n */\nfunction extractAvailableTools(params: Record<string, unknown>): string | undefined {\n const tools = Array.isArray(params.tools) ? params.tools : [];\n const hasWebSearchOptions = params.web_search_options && typeof params.web_search_options === 'object';\n const webSearchOptions = hasWebSearchOptions\n ? [{ type: 'web_search_options', ...(params.web_search_options as Record<string, unknown>) }]\n : [];\n\n const availableTools = [...tools, ...webSearchOptions];\n if (availableTools.length === 0) {\n return undefined;\n }\n\n try {\n return JSON.stringify(availableTools);\n } catch (error) {\n DEBUG_BUILD && debug.error('Failed to serialize OpenAI tools:', error);\n return undefined;\n }\n}\n\n/**\n * Extract request attributes from method arguments\n */\nfunction extractRequestAttributes(args: unknown[], methodPath: string): Record<string, unknown> {\n const attributes: Record<string, unknown> = {\n [GEN_AI_SYSTEM_ATTRIBUTE]: 'openai',\n [GEN_AI_OPERATION_NAME_ATTRIBUTE]: getOperationName(methodPath),\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ai.openai',\n };\n\n if (args.length > 0 && typeof args[0] === 'object' && args[0] !== null) {\n const params = args[0] as Record<string, unknown>;\n\n const availableTools = extractAvailableTools(params);\n if (availableTools) {\n attributes[GEN_AI_REQUEST_AVAILABLE_TOOLS_ATTRIBUTE] = availableTools;\n }\n\n Object.assign(attributes, extractRequestParameters(params));\n } else {\n attributes[GEN_AI_REQUEST_MODEL_ATTRIBUTE] = 'unknown';\n }\n\n return attributes;\n}\n\n/**\n * Add response attributes to spans\n * This supports Chat Completion, Responses API, Embeddings, and Conversations API responses\n */\nfunction addResponseAttributes(span: Span, result: unknown, recordOutputs?: boolean): void {\n if (!result || typeof result !== 'object') return;\n\n const response = result as OpenAiResponse;\n\n if (isChatCompletionResponse(response)) {\n addChatCompletionAttributes(span, response, recordOutputs);\n if (recordOutputs && response.choices?.length) {\n const responseTexts = response.choices.map(choice => choice.message?.content || '');\n span.setAttributes({ [GEN_AI_RESPONSE_TEXT_ATTRIBUTE]: JSON.stringify(responseTexts) });\n }\n } else if (isResponsesApiResponse(response)) {\n addResponsesApiAttributes(span, response, recordOutputs);\n if (recordOutputs && response.output_text) {\n span.setAttributes({ [GEN_AI_RESPONSE_TEXT_ATTRIBUTE]: response.output_text });\n }\n } else if (isEmbeddingsResponse(response)) {\n addEmbeddingsAttributes(span, response);\n } else if (isConversationResponse(response)) {\n addConversationAttributes(span, response);\n }\n}\n\n// Extract and record AI request inputs, if present. This is intentionally separate from response attributes.\nfunction addRequestAttributes(span: Span, params: Record<string, unknown>, operationName: string): void {\n // Store embeddings input on a separate attribute and do not truncate it\n if (operationName === OPENAI_OPERATIONS.EMBEDDINGS && 'input' in params) {\n const input = params.input;\n\n // No input provided\n if (input == null) {\n return;\n }\n\n // Empty input string\n if (typeof input === 'string' && input.length === 0) {\n return;\n }\n\n // Empty array input\n if (Array.isArray(input) && input.length === 0) {\n return;\n }\n\n // Store strings as-is, arrays/objects as JSON\n span.setAttribute(GEN_AI_EMBEDDINGS_INPUT_ATTRIBUTE, typeof input === 'string' ? input : JSON.stringify(input));\n return;\n }\n\n const src = 'input' in params ? params.input : 'messages' in params ? params.messages : undefined;\n\n if (!src) {\n return;\n }\n\n if (Array.isArray(src) && src.length === 0) {\n return;\n }\n\n const { systemInstructions, filteredMessages } = extractSystemInstructions(src);\n\n if (systemInstructions) {\n span.setAttribute(GEN_AI_SYSTEM_INSTRUCTIONS_ATTRIBUTE, systemInstructions);\n }\n\n const truncatedInput = getTruncatedJsonString(filteredMessages);\n span.setAttribute(GEN_AI_INPUT_MESSAGES_ATTRIBUTE, truncatedInput);\n\n if (Array.isArray(filteredMessages)) {\n span.setAttribute(GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE, filteredMessages.length);\n } else {\n span.setAttribute(GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE, 1);\n }\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): 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: 'auto.ai.openai',\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 */\nfunction wrapPromiseWithMethods<R>(originalPromiseLike: Promise<R>, instrumentedPromise: Promise<R>): Promise<R> {\n // If the original result is not thenable, return the instrumented promise\n // Should not happen with current OpenAI SDK instrumented methods, but just in case.\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);\n };\n }\n\n return typeof value === 'function' ? value.bind(source) : value;\n },\n }) as Promise<R>;\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) => Promise<R>,\n methodPath: InstrumentedMethod,\n context: unknown,\n options: OpenAiOptions,\n): (...args: T) => Promise<R> {\n return function instrumentedMethod(...args: T): Promise<R> {\n const requestAttributes = extractRequestAttributes(args, methodPath);\n const model = (requestAttributes[GEN_AI_REQUEST_MODEL_ATTRIBUTE] as string) || 'unknown';\n const operationName = getOperationName(methodPath);\n\n const params = args[0] as Record<string, unknown> | undefined;\n const isStreamRequested = params && typeof params === 'object' && params.stream === true;\n\n const spanConfig = {\n name: `${operationName} ${model}${isStreamRequested ? ' stream-response' : ''}`,\n op: getSpanOperation(methodPath),\n attributes: requestAttributes as Record<string, SpanAttributeValue>,\n };\n\n if (isStreamRequested) {\n let originalResult!: Promise<R>;\n\n const instrumentedPromise = startSpanManual(spanConfig, (span: Span) => {\n originalResult = originalMethod.apply(context, args);\n\n if (options.recordInputs && params) {\n addRequestAttributes(span, params, operationName);\n }\n\n // Return async processing\n return (async () => {\n try {\n const result = await originalResult;\n return instrumentStream(\n result as OpenAIStream<ChatCompletionChunk | ResponseStreamingEvent>,\n span,\n options.recordOutputs ?? false,\n ) as unknown as R;\n } catch (error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureException(error, {\n mechanism: {\n handled: false,\n type: 'auto.ai.openai.stream',\n data: { function: methodPath },\n },\n });\n span.end();\n throw error;\n }\n })();\n });\n\n return wrapPromiseWithMethods(originalResult, instrumentedPromise);\n }\n\n // Non-streaming\n let originalResult!: Promise<R>;\n\n const instrumentedPromise = startSpan(spanConfig, (span: Span) => {\n // Call synchronously to capture the promise\n originalResult = originalMethod.apply(context, args);\n\n if (options.recordInputs && params) {\n addRequestAttributes(span, params, operationName);\n }\n\n return originalResult.then(\n result => {\n addResponseAttributes(span, result, options.recordOutputs);\n return result;\n },\n error => {\n captureException(error, {\n mechanism: {\n handled: false,\n type: 'auto.ai.openai',\n data: { function: methodPath },\n },\n });\n throw error;\n },\n );\n });\n\n return wrapPromiseWithMethods(originalResult, instrumentedPromise);\n };\n}\n\n/**\n * Create a deep proxy for OpenAI client instrumentation\n */\nfunction createDeepProxy<T extends object>(target: T, currentPath = '', options: OpenAiOptions): 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 if (typeof value === 'function' && shouldInstrument(methodPath)) {\n return instrumentMethod(value as (...args: unknown[]) => Promise<unknown>, methodPath, obj, options);\n }\n\n if (typeof value === 'function') {\n // Bind non-instrumented functions to preserve the original `this` context,\n // which is required for accessing private class fields (e.g. #baseURL) in OpenAI SDK v5.\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 OpenAI client with Sentry tracing\n * Can be used across Node.js, Cloudflare Workers, and Vercel Edge\n */\nexport function instrumentOpenAiClient<T extends object>(client: T, options?: OpenAiOptions): T {\n const sendDefaultPii = Boolean(getClient()?.getOptions().sendDefaultPii);\n\n const _options = {\n recordInputs: sendDefaultPii,\n recordOutputs: sendDefaultPii,\n ...options,\n };\n\n return createDeepProxy(client, '', _options);\n}\n"],"names":["DEBUG_BUILD","debug","GEN_AI_SYSTEM_ATTRIBUTE","GEN_AI_OPERATION_NAME_ATTRIBUTE","getOperationName","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","GEN_AI_REQUEST_AVAILABLE_TOOLS_ATTRIBUTE","extractRequestParameters","GEN_AI_REQUEST_MODEL_ATTRIBUTE","isChatCompletionResponse","addChatCompletionAttributes","GEN_AI_RESPONSE_TEXT_ATTRIBUTE","isResponsesApiResponse","addResponsesApiAttributes","isEmbeddingsResponse","addEmbeddingsAttributes","isConversationResponse","addConversationAttributes","OPENAI_OPERATIONS","GEN_AI_EMBEDDINGS_INPUT_ATTRIBUTE","extractSystemInstructions","GEN_AI_SYSTEM_INSTRUCTIONS_ATTRIBUTE","getTruncatedJsonString","GEN_AI_INPUT_MESSAGES_ATTRIBUTE","GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE","captureException","isThenable","getSpanOperation","startSpanManual","instrumentStream","SPAN_STATUS_ERROR","startSpan","buildMethodPath","shouldInstrument","getClient"],"mappings":"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"}