@sentry/core 10.45.0 → 10.47.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 (151) hide show
  1. package/build/cjs/api.js +1 -0
  2. package/build/cjs/api.js.map +1 -1
  3. package/build/cjs/asyncContext/stackStrategy.js +6 -11
  4. package/build/cjs/asyncContext/stackStrategy.js.map +1 -1
  5. package/build/cjs/currentScopes.js +33 -0
  6. package/build/cjs/currentScopes.js.map +1 -1
  7. package/build/cjs/index.js +6 -0
  8. package/build/cjs/index.js.map +1 -1
  9. package/build/cjs/integrations/supabase.js +1 -1
  10. package/build/cjs/integrations/supabase.js.map +1 -1
  11. package/build/cjs/tracing/ai/gen-ai-attributes.js +0 -14
  12. package/build/cjs/tracing/ai/gen-ai-attributes.js.map +1 -1
  13. package/build/cjs/tracing/ai/messageTruncation.js +57 -39
  14. package/build/cjs/tracing/ai/messageTruncation.js.map +1 -1
  15. package/build/cjs/tracing/ai/utils.js +81 -35
  16. package/build/cjs/tracing/ai/utils.js.map +1 -1
  17. package/build/cjs/tracing/anthropic-ai/constants.js +10 -10
  18. package/build/cjs/tracing/anthropic-ai/constants.js.map +1 -1
  19. package/build/cjs/tracing/anthropic-ai/index.js +53 -28
  20. package/build/cjs/tracing/anthropic-ai/index.js.map +1 -1
  21. package/build/cjs/tracing/anthropic-ai/utils.js +0 -9
  22. package/build/cjs/tracing/anthropic-ai/utils.js.map +1 -1
  23. package/build/cjs/tracing/google-genai/constants.js +10 -8
  24. package/build/cjs/tracing/google-genai/constants.js.map +1 -1
  25. package/build/cjs/tracing/google-genai/index.js +44 -16
  26. package/build/cjs/tracing/google-genai/index.js.map +1 -1
  27. package/build/cjs/tracing/google-genai/utils.js +0 -25
  28. package/build/cjs/tracing/google-genai/utils.js.map +1 -1
  29. package/build/cjs/tracing/openai/constants.js +7 -7
  30. package/build/cjs/tracing/openai/constants.js.map +1 -1
  31. package/build/cjs/tracing/openai/index.js +22 -83
  32. package/build/cjs/tracing/openai/index.js.map +1 -1
  33. package/build/cjs/tracing/openai/utils.js +0 -47
  34. package/build/cjs/tracing/openai/utils.js.map +1 -1
  35. package/build/cjs/tracing/trace.js +5 -0
  36. package/build/cjs/tracing/trace.js.map +1 -1
  37. package/build/cjs/tracing/vercel-ai/index.js +9 -1
  38. package/build/cjs/tracing/vercel-ai/index.js.map +1 -1
  39. package/build/cjs/utils/chain-and-copy-promiselike.js +57 -0
  40. package/build/cjs/utils/chain-and-copy-promiselike.js.map +1 -0
  41. package/build/cjs/utils/handleCallbackErrors.js +15 -11
  42. package/build/cjs/utils/handleCallbackErrors.js.map +1 -1
  43. package/build/cjs/utils/traceData.js +11 -0
  44. package/build/cjs/utils/traceData.js.map +1 -1
  45. package/build/cjs/utils/version.js +1 -1
  46. package/build/esm/api.js +1 -1
  47. package/build/esm/api.js.map +1 -1
  48. package/build/esm/asyncContext/stackStrategy.js +6 -11
  49. package/build/esm/asyncContext/stackStrategy.js.map +1 -1
  50. package/build/esm/currentScopes.js +31 -1
  51. package/build/esm/currentScopes.js.map +1 -1
  52. package/build/esm/index.js +3 -2
  53. package/build/esm/index.js.map +1 -1
  54. package/build/esm/integrations/supabase.js +1 -1
  55. package/build/esm/integrations/supabase.js.map +1 -1
  56. package/build/esm/package.json +1 -1
  57. package/build/esm/tracing/ai/gen-ai-attributes.js +1 -14
  58. package/build/esm/tracing/ai/gen-ai-attributes.js.map +1 -1
  59. package/build/esm/tracing/ai/messageTruncation.js +57 -39
  60. package/build/esm/tracing/ai/messageTruncation.js.map +1 -1
  61. package/build/esm/tracing/ai/utils.js +81 -34
  62. package/build/esm/tracing/ai/utils.js.map +1 -1
  63. package/build/esm/tracing/anthropic-ai/constants.js +10 -10
  64. package/build/esm/tracing/anthropic-ai/constants.js.map +1 -1
  65. package/build/esm/tracing/anthropic-ai/index.js +56 -31
  66. package/build/esm/tracing/anthropic-ai/index.js.map +1 -1
  67. package/build/esm/tracing/anthropic-ai/utils.js +1 -9
  68. package/build/esm/tracing/anthropic-ai/utils.js.map +1 -1
  69. package/build/esm/tracing/google-genai/constants.js +10 -8
  70. package/build/esm/tracing/google-genai/constants.js.map +1 -1
  71. package/build/esm/tracing/google-genai/index.js +48 -20
  72. package/build/esm/tracing/google-genai/index.js.map +1 -1
  73. package/build/esm/tracing/google-genai/utils.js +1 -24
  74. package/build/esm/tracing/google-genai/utils.js.map +1 -1
  75. package/build/esm/tracing/openai/constants.js +7 -7
  76. package/build/esm/tracing/openai/constants.js.map +1 -1
  77. package/build/esm/tracing/openai/index.js +23 -84
  78. package/build/esm/tracing/openai/index.js.map +1 -1
  79. package/build/esm/tracing/openai/utils.js +2 -45
  80. package/build/esm/tracing/openai/utils.js.map +1 -1
  81. package/build/esm/tracing/trace.js +5 -0
  82. package/build/esm/tracing/trace.js.map +1 -1
  83. package/build/esm/tracing/vercel-ai/index.js +9 -1
  84. package/build/esm/tracing/vercel-ai/index.js.map +1 -1
  85. package/build/esm/utils/chain-and-copy-promiselike.js +55 -0
  86. package/build/esm/utils/chain-and-copy-promiselike.js.map +1 -0
  87. package/build/esm/utils/handleCallbackErrors.js +15 -11
  88. package/build/esm/utils/handleCallbackErrors.js.map +1 -1
  89. package/build/esm/utils/traceData.js +12 -1
  90. package/build/esm/utils/traceData.js.map +1 -1
  91. package/build/esm/utils/version.js +1 -1
  92. package/build/types/api.d.ts +1 -0
  93. package/build/types/api.d.ts.map +1 -1
  94. package/build/types/asyncContext/stackStrategy.d.ts.map +1 -1
  95. package/build/types/asyncContext/types.d.ts +3 -1
  96. package/build/types/asyncContext/types.d.ts.map +1 -1
  97. package/build/types/currentScopes.d.ts +20 -0
  98. package/build/types/currentScopes.d.ts.map +1 -1
  99. package/build/types/index.d.ts +3 -2
  100. package/build/types/index.d.ts.map +1 -1
  101. package/build/types/tracing/ai/gen-ai-attributes.d.ts +0 -8
  102. package/build/types/tracing/ai/gen-ai-attributes.d.ts.map +1 -1
  103. package/build/types/tracing/ai/messageTruncation.d.ts.map +1 -1
  104. package/build/types/tracing/ai/utils.d.ts +24 -9
  105. package/build/types/tracing/ai/utils.d.ts.map +1 -1
  106. package/build/types/tracing/anthropic-ai/constants.d.ts +24 -1
  107. package/build/types/tracing/anthropic-ai/constants.d.ts.map +1 -1
  108. package/build/types/tracing/anthropic-ai/index.d.ts.map +1 -1
  109. package/build/types/tracing/anthropic-ai/types.d.ts +5 -2
  110. package/build/types/tracing/anthropic-ai/types.d.ts.map +1 -1
  111. package/build/types/tracing/anthropic-ai/utils.d.ts +1 -5
  112. package/build/types/tracing/anthropic-ai/utils.d.ts.map +1 -1
  113. package/build/types/tracing/google-genai/constants.d.ts +22 -1
  114. package/build/types/tracing/google-genai/constants.d.ts.map +1 -1
  115. package/build/types/tracing/google-genai/index.d.ts.map +1 -1
  116. package/build/types/tracing/google-genai/types.d.ts +6 -2
  117. package/build/types/tracing/google-genai/types.d.ts.map +1 -1
  118. package/build/types/tracing/google-genai/utils.d.ts +0 -9
  119. package/build/types/tracing/google-genai/utils.d.ts.map +1 -1
  120. package/build/types/tracing/openai/constants.d.ts +14 -1
  121. package/build/types/tracing/openai/constants.d.ts.map +1 -1
  122. package/build/types/tracing/openai/index.d.ts.map +1 -1
  123. package/build/types/tracing/openai/types.d.ts +5 -2
  124. package/build/types/tracing/openai/types.d.ts.map +1 -1
  125. package/build/types/tracing/openai/utils.d.ts +1 -19
  126. package/build/types/tracing/openai/utils.d.ts.map +1 -1
  127. package/build/types/tracing/trace.d.ts.map +1 -1
  128. package/build/types/tracing/vercel-ai/index.d.ts.map +1 -1
  129. package/build/types/utils/chain-and-copy-promiselike.d.ts +6 -0
  130. package/build/types/utils/chain-and-copy-promiselike.d.ts.map +1 -0
  131. package/build/types/utils/handleCallbackErrors.d.ts.map +1 -1
  132. package/build/types/utils/traceData.d.ts +4 -0
  133. package/build/types/utils/traceData.d.ts.map +1 -1
  134. package/build/types-ts3.8/api.d.ts +1 -0
  135. package/build/types-ts3.8/asyncContext/types.d.ts +3 -1
  136. package/build/types-ts3.8/currentScopes.d.ts +20 -0
  137. package/build/types-ts3.8/index.d.ts +3 -2
  138. package/build/types-ts3.8/tracing/ai/gen-ai-attributes.d.ts +0 -8
  139. package/build/types-ts3.8/tracing/ai/utils.d.ts +24 -9
  140. package/build/types-ts3.8/tracing/anthropic-ai/constants.d.ts +24 -9
  141. package/build/types-ts3.8/tracing/anthropic-ai/types.d.ts +5 -2
  142. package/build/types-ts3.8/tracing/anthropic-ai/utils.d.ts +1 -5
  143. package/build/types-ts3.8/tracing/google-genai/constants.d.ts +22 -7
  144. package/build/types-ts3.8/tracing/google-genai/types.d.ts +6 -2
  145. package/build/types-ts3.8/tracing/google-genai/utils.d.ts +0 -9
  146. package/build/types-ts3.8/tracing/openai/constants.d.ts +14 -6
  147. package/build/types-ts3.8/tracing/openai/types.d.ts +5 -2
  148. package/build/types-ts3.8/tracing/openai/utils.d.ts +1 -19
  149. package/build/types-ts3.8/utils/chain-and-copy-promiselike.d.ts +6 -0
  150. package/build/types-ts3.8/utils/traceData.d.ts +4 -0
  151. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../../src/tracing/openai/index.ts"],"sourcesContent":["import { 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, resolveAIRecordingOptions } 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}`,\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 return createDeepProxy(client, '', resolveAIRecordingOptions(options));\n}\n"],"names":[],"mappings":";;;;;;;;;;;;AA8CA;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,IAAI,cAAc,CAAC,MAAA,KAAW,CAAC,EAAE;AACnC,IAAI,OAAO,SAAS;AACpB,EAAE;;AAEF,EAAE,IAAI;AACN,IAAI,OAAO,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC;AACzC,EAAE,CAAA,CAAE,OAAO,KAAK,EAAE;AAClB,IAAI,WAAA,IAAe,KAAK,CAAC,KAAK,CAAC,mCAAmC,EAAE,KAAK,CAAC;AAC1E,IAAI,OAAO,SAAS;AACpB,EAAE;AACF;;AAEA;AACA;AACA;AACA,SAAS,wBAAwB,CAAC,IAAI,EAAa,UAAU,EAAmC;AAChG,EAAE,MAAM,UAAU,GAA4B;AAC9C,IAAI,CAAC,uBAAuB,GAAG,QAAQ;AACvC,IAAI,CAAC,+BAA+B,GAAG,gBAAgB,CAAC,UAAU,CAAC;AACnE,IAAI,CAAC,gCAAgC,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,CAAC,wCAAwC,CAAA,GAAI,cAAc;AAC3E,IAAI;;AAEJ,IAAI,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,wBAAwB,CAAC,MAAM,CAAC,CAAC;AAC/D,EAAE,OAAO;AACT,IAAI,UAAU,CAAC,8BAA8B,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,IAAI,wBAAwB,CAAC,QAAQ,CAAC,EAAE;AAC1C,IAAI,2BAA2B,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,CAAC,8BAA8B,GAAG,IAAI,CAAC,SAAS,CAAC,aAAa,CAAA,EAAG,CAAC;AAC7F,IAAI;AACJ,EAAE,CAAA,MAAO,IAAI,sBAAsB,CAAC,QAAQ,CAAC,EAAE;AAC/C,IAAI,yBAAyB,CAAC,IAAI,EAAE,QAAQ,EAAE,aAAa,CAAC;AAC5D,IAAI,IAAI,aAAA,IAAiB,QAAQ,CAAC,WAAW,EAAE;AAC/C,MAAM,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,8BAA8B,GAAG,QAAQ,CAAC,WAAA,EAAa,CAAC;AACpF,IAAI;AACJ,EAAE,CAAA,MAAO,IAAI,oBAAoB,CAAC,QAAQ,CAAC,EAAE;AAC7C,IAAI,uBAAuB,CAAC,IAAI,EAAE,QAAQ,CAAC;AAC3C,EAAE,CAAA,MAAO,IAAI,sBAAsB,CAAC,QAAQ,CAAC,EAAE;AAC/C,IAAI,yBAAyB,CAAC,IAAI,EAAE,QAAQ,CAAC;AAC7C,EAAE;AACF;;AAEA;AACA,SAAS,oBAAoB,CAAC,IAAI,EAAQ,MAAM,EAA2B,aAAa,EAAgB;AACxG;AACA,EAAE,IAAI,aAAA,KAAkB,iBAAiB,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,CAAC,iCAAiC,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,KAAqB,yBAAyB,CAAC,GAAG,CAAC;;AAEjF,EAAE,IAAI,kBAAkB,EAAE;AAC1B,IAAI,IAAI,CAAC,YAAY,CAAC,oCAAoC,EAAE,kBAAkB,CAAC;AAC/E,EAAE;;AAEF,EAAE,MAAM,cAAA,GAAiB,sBAAsB,CAAC,gBAAgB,CAAC;AACjE,EAAE,IAAI,CAAC,YAAY,CAAC,+BAA+B,EAAE,cAAc,CAAC;;AAEpE,EAAE,IAAI,KAAK,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE;AACvC,IAAI,IAAI,CAAC,YAAY,CAAC,+CAA+C,EAAE,gBAAgB,CAAC,MAAM,CAAC;AAC/F,EAAE,OAAO;AACT,IAAI,IAAI,CAAC,YAAY,CAAC,+CAA+C,EAAE,CAAC,CAAC;AACzE,EAAE;AACF;;AAEA;AACA;AACA;AACA;AACA,eAAe,yBAAyB;AACxC,EAAE,oBAAoB;AACtB,EAAE,mBAAmB;AACrB,EAAoB;AACpB;AACA;AACA,EAAE,MAAM,2BAA2B,oBAAoB,CAAC,KAAK,CAAC,SAAS;AACvE,IAAI,gBAAgB,CAAC,KAAK,EAAE;AAC5B,MAAM,SAAS,EAAE;AACjB,QAAQ,OAAO,EAAE,KAAK;AACtB,QAAQ,IAAI,EAAE,gBAAgB;AAC9B,OAAO;AACP,KAAK,CAAC;AACN,IAAI,MAAM,KAAK;AACf,EAAE,CAAC,CAAC;;AAEJ,EAAE,MAAM,kBAAA,GAAqB,MAAM,mBAAmB;AACtD,EAAE,MAAM,eAAA,GAAkB,MAAM,wBAAwB;;AAExD;AACA,EAAE,IAAI,eAAA,IAAmB,OAAO,eAAA,KAAoB,QAAA,IAAY,MAAA,IAAU,eAAe,EAAE;AAC3F,IAAI,OAAO;AACX,MAAM,GAAG,eAAe;AACxB,MAAM,IAAI,EAAE,kBAAkB;AAC9B,KAAK;AACL,EAAE;AACF,EAAE,OAAO,kBAAkB;AAC3B;;AAEA;AACA;AACA;AACA,SAAS,sBAAsB,CAAI,mBAAmB,EAAc,mBAAmB,EAA0B;AACjH;AACA;AACA,EAAE,IAAI,CAAC,UAAU,CAAC,mBAAmB,CAAC,EAAE;AACxC,IAAI,OAAO,mBAAmB;AAC9B,EAAE;;AAEF;AACA;AACA,EAAE,OAAO,IAAI,KAAK,CAAC,mBAAmB,EAAE;AACxC,IAAI,GAAG,CAAC,MAAM,EAAU,IAAI,EAA4B;AACxD;AACA;AACA;AACA,MAAM,MAAM,sBAAA,GAAyB,IAAA,IAAQ,OAAO,CAAC,SAAA,IAAa,IAAA,KAAS,MAAM,CAAC,WAAW;AAC7F,MAAM,MAAM,MAAA,GAAS,yBAAyB,mBAAA,GAAsB,MAAM;;AAE1E,MAAM,MAAM,KAAA,GAAQ,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAA;;AAE5C;AACA;AACA,MAAM,IAAI,IAAA,KAAS,cAAA,IAAkB,OAAO,KAAA,KAAU,UAAU,EAAE;AAClE,QAAQ,OAAO,SAAS,mBAAmB,GAAyB;AACpE,UAAU,MAAM,oBAAA,GAAuB,CAAC,KAAA,GAA0C,IAAI,CAAC,MAAM,CAAC;AAC9F,UAAU,OAAO,yBAAyB,CAAC,oBAAoB,EAAE,mBAAmB,CAAC;AACrF,QAAQ,CAAC;AACT,MAAM;;AAEN,MAAM,OAAO,OAAO,KAAA,KAAU,UAAA,GAAa,KAAK,CAAC,IAAI,CAAC,MAAM,CAAA,GAAI,KAAK;AACrE,IAAI,CAAC;AACL,GAAG,CAAA;AACH;;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,SAAS,kBAAkB,CAAC,GAAG,IAAI,EAAiB;AAC7D,IAAI,MAAM,oBAAoB,wBAAwB,CAAC,IAAI,EAAE,UAAU,CAAC;AACxE,IAAI,MAAM,KAAA,GAAQ,CAAC,iBAAiB,CAAC,8BAA8B,CAAA,MAAgB,SAAS;AAC5F,IAAI,MAAM,aAAA,GAAgB,gBAAgB,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,MAAM,aAAa;AACvB,MAAM,IAAI,EAAE,CAAC,EAAA,aAAA,CAAA,CAAA,EAAA,KAAA,CAAA,CAAA;AACA,MAAA,EAAA,EAAA,gBAAA,CAAA,UAAA,CAAA;AACA,MAAA,UAAA,EAAA,iBAAA;AACA,KAAA;;AAEA,IAAA,IAAA,iBAAA,EAAA;AACA,MAAA,IAAA,cAAA;;AAEA,MAAA,MAAA,mBAAA,GAAA,eAAA,CAAA,UAAA,EAAA,CAAA,IAAA,KAAA;AACA,QAAA,cAAA,GAAA,cAAA,CAAA,KAAA,CAAA,OAAA,EAAA,IAAA,CAAA;;AAEA,QAAA,IAAA,OAAA,CAAA,YAAA,IAAA,MAAA,EAAA;AACA,UAAA,oBAAA,CAAA,IAAA,EAAA,MAAA,EAAA,aAAA,CAAA;AACA,QAAA;;AAEA;AACA,QAAA,OAAA,CAAA,YAAA;AACA,UAAA,IAAA;AACA,YAAA,MAAA,MAAA,GAAA,MAAA,cAAA;AACA,YAAA,OAAA,gBAAA;AACA,cAAA,MAAA;AACA,cAAA,IAAA;AACA,cAAA,OAAA,CAAA,aAAA,IAAA,KAAA;AACA,aAAA;AACA,UAAA,CAAA,CAAA,OAAA,KAAA,EAAA;AACA,YAAA,IAAA,CAAA,SAAA,CAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,gBAAA,EAAA,CAAA;AACA,YAAA,gBAAA,CAAA,KAAA,EAAA;AACA,cAAA,SAAA,EAAA;AACA,gBAAA,OAAA,EAAA,KAAA;AACA,gBAAA,IAAA,EAAA,uBAAA;AACA,gBAAA,IAAA,EAAA,EAAA,QAAA,EAAA,UAAA,EAAA;AACA,eAAA;AACA,aAAA,CAAA;AACA,YAAA,IAAA,CAAA,GAAA,EAAA;AACA,YAAA,MAAA,KAAA;AACA,UAAA;AACA,QAAA,CAAA,GAAA;AACA,MAAA,CAAA,CAAA;;AAEA,MAAA,OAAA,sBAAA,CAAA,cAAA,EAAA,mBAAA,CAAA;AACA,IAAA;;AAEA;AACA,IAAA,IAAA,cAAA;;AAEA,IAAA,MAAA,mBAAA,GAAA,SAAA,CAAA,UAAA,EAAA,CAAA,IAAA,KAAA;AACA;AACA,MAAA,cAAA,GAAA,cAAA,CAAA,KAAA,CAAA,OAAA,EAAA,IAAA,CAAA;;AAEA,MAAA,IAAA,OAAA,CAAA,YAAA,IAAA,MAAA,EAAA;AACA,QAAA,oBAAA,CAAA,IAAA,EAAA,MAAA,EAAA,aAAA,CAAA;AACA,MAAA;;AAEA,MAAA,OAAA,cAAA,CAAA,IAAA;AACA,QAAA,MAAA,IAAA;AACA,UAAA,qBAAA,CAAA,IAAA,EAAA,MAAA,EAAA,OAAA,CAAA,aAAA,CAAA;AACA,UAAA,OAAA,MAAA;AACA,QAAA,CAAA;AACA,QAAA,KAAA,IAAA;AACA,UAAA,gBAAA,CAAA,KAAA,EAAA;AACA,YAAA,SAAA,EAAA;AACA,cAAA,OAAA,EAAA,KAAA;AACA,cAAA,IAAA,EAAA,gBAAA;AACA,cAAA,IAAA,EAAA,EAAA,QAAA,EAAA,UAAA,EAAA;AACA,aAAA;AACA,WAAA,CAAA;AACA,UAAA,MAAA,KAAA;AACA,QAAA,CAAA;AACA,OAAA;AACA,IAAA,CAAA,CAAA;;AAEA,IAAA,OAAA,sBAAA,CAAA,cAAA,EAAA,mBAAA,CAAA;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,GAAA,eAAA,CAAA,WAAA,EAAA,MAAA,CAAA,IAAA,CAAA,CAAA;;AAEA,MAAA,IAAA,OAAA,KAAA,KAAA,UAAA,IAAA,gBAAA,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,OAAA,eAAA,CAAA,MAAA,EAAA,EAAA,EAAA,yBAAA,CAAA,OAAA,CAAA,CAAA;AACA;;;;"}
1
+ {"version":3,"file":"index.js","sources":["../../../../src/tracing/openai/index.ts"],"sourcesContent":["import { 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 {\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} from '../ai/gen-ai-attributes';\nimport type { InstrumentedMethodEntry } from '../ai/utils';\nimport {\n buildMethodPath,\n extractSystemInstructions,\n getTruncatedJsonString,\n resolveAIRecordingOptions,\n wrapPromiseWithMethods,\n} from '../ai/utils';\nimport { OPENAI_METHOD_REGISTRY } from './constants';\nimport { instrumentStream } from './streaming';\nimport type { ChatCompletionChunk, OpenAiOptions, OpenAiResponse, OpenAIStream, ResponseStreamingEvent } from './types';\nimport {\n addChatCompletionAttributes,\n addConversationAttributes,\n addEmbeddingsAttributes,\n addResponsesApiAttributes,\n extractRequestParameters,\n isChatCompletionResponse,\n isConversationResponse,\n isEmbeddingsResponse,\n isResponsesApiResponse,\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[], operationName: string): Record<string, unknown> {\n const attributes: Record<string, unknown> = {\n [GEN_AI_SYSTEM_ATTRIBUTE]: 'openai',\n [GEN_AI_OPERATION_NAME_ATTRIBUTE]: operationName,\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 === '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: string,\n instrumentedMethod: InstrumentedMethodEntry,\n context: unknown,\n options: OpenAiOptions,\n): (...args: T) => Promise<R> {\n return function instrumentedCall(...args: T): Promise<R> {\n const operationName = instrumentedMethod.operation;\n const requestAttributes = extractRequestAttributes(args, operationName);\n const model = (requestAttributes[GEN_AI_REQUEST_MODEL_ATTRIBUTE] as string) || 'unknown';\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}`,\n op: `gen_ai.${operationName}`,\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, 'auto.ai.openai');\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, 'auto.ai.openai');\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 const instrumentedMethod = OPENAI_METHOD_REGISTRY[methodPath as keyof typeof OPENAI_METHOD_REGISTRY];\n if (typeof value === 'function' && instrumentedMethod) {\n return instrumentMethod(\n value as (...args: unknown[]) => Promise<unknown>,\n methodPath,\n instrumentedMethod,\n obj,\n options,\n );\n }\n\n if (typeof value === 'function') {\n // Bind non-instrumented functions to preserve the original `this` context,\n // 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 return createDeepProxy(client, '', resolveAIRecordingOptions(options));\n}\n"],"names":[],"mappings":"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"}
@@ -1,47 +1,4 @@
1
- import { OPENAI_OPERATIONS, GEN_AI_REQUEST_MODEL_ATTRIBUTE, GEN_AI_REQUEST_TEMPERATURE_ATTRIBUTE, GEN_AI_REQUEST_TOP_P_ATTRIBUTE, GEN_AI_REQUEST_FREQUENCY_PENALTY_ATTRIBUTE, GEN_AI_REQUEST_PRESENCE_PENALTY_ATTRIBUTE, GEN_AI_REQUEST_STREAM_ATTRIBUTE, GEN_AI_REQUEST_ENCODING_FORMAT_ATTRIBUTE, GEN_AI_REQUEST_DIMENSIONS_ATTRIBUTE, GEN_AI_CONVERSATION_ID_ATTRIBUTE, GEN_AI_RESPONSE_ID_ATTRIBUTE, OPENAI_RESPONSE_ID_ATTRIBUTE, GEN_AI_RESPONSE_MODEL_ATTRIBUTE, OPENAI_RESPONSE_MODEL_ATTRIBUTE, OPENAI_RESPONSE_TIMESTAMP_ATTRIBUTE, GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE, GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE, GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE, OPENAI_USAGE_PROMPT_TOKENS_ATTRIBUTE, GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE, OPENAI_USAGE_COMPLETION_TOKENS_ATTRIBUTE, GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE } from '../ai/gen-ai-attributes.js';
2
- import { INSTRUMENTED_METHODS } from './constants.js';
3
-
4
- /**
5
- * Maps OpenAI method paths to OpenTelemetry semantic convention operation names
6
- * @see https://opentelemetry.io/docs/specs/semconv/gen-ai/gen-ai-spans/#llm-request-spans
7
- */
8
- function getOperationName(methodPath) {
9
- if (methodPath.includes('chat.completions')) {
10
- return OPENAI_OPERATIONS.CHAT;
11
- }
12
- if (methodPath.includes('responses')) {
13
- return OPENAI_OPERATIONS.CHAT;
14
- }
15
- if (methodPath.includes('embeddings')) {
16
- return OPENAI_OPERATIONS.EMBEDDINGS;
17
- }
18
- if (methodPath.includes('conversations')) {
19
- return OPENAI_OPERATIONS.CHAT;
20
- }
21
- return methodPath.split('.').pop() || 'unknown';
22
- }
23
-
24
- /**
25
- * Get the span operation for OpenAI methods
26
- * Following Sentry's convention: "gen_ai.{operation_name}"
27
- */
28
- function getSpanOperation(methodPath) {
29
- return `gen_ai.${getOperationName(methodPath)}`;
30
- }
31
-
32
- /**
33
- * Check if a method path should be instrumented
34
- */
35
- function shouldInstrument(methodPath) {
36
- return INSTRUMENTED_METHODS.includes(methodPath );
37
- }
38
-
39
- /**
40
- * Build method path from current traversal
41
- */
42
- function buildMethodPath(currentPath, prop) {
43
- return currentPath ? `${currentPath}.${prop}` : prop;
44
- }
1
+ import { GEN_AI_REQUEST_MODEL_ATTRIBUTE, GEN_AI_REQUEST_TEMPERATURE_ATTRIBUTE, GEN_AI_REQUEST_TOP_P_ATTRIBUTE, GEN_AI_REQUEST_FREQUENCY_PENALTY_ATTRIBUTE, GEN_AI_REQUEST_PRESENCE_PENALTY_ATTRIBUTE, GEN_AI_REQUEST_STREAM_ATTRIBUTE, GEN_AI_REQUEST_ENCODING_FORMAT_ATTRIBUTE, GEN_AI_REQUEST_DIMENSIONS_ATTRIBUTE, GEN_AI_CONVERSATION_ID_ATTRIBUTE, GEN_AI_RESPONSE_ID_ATTRIBUTE, OPENAI_RESPONSE_ID_ATTRIBUTE, GEN_AI_RESPONSE_MODEL_ATTRIBUTE, OPENAI_RESPONSE_MODEL_ATTRIBUTE, OPENAI_RESPONSE_TIMESTAMP_ATTRIBUTE, GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE, GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE, GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE, OPENAI_USAGE_PROMPT_TOKENS_ATTRIBUTE, GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE, OPENAI_USAGE_COMPLETION_TOKENS_ATTRIBUTE, GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE } from '../ai/gen-ai-attributes.js';
45
2
 
46
3
  /**
47
4
  * Check if response is a Chat Completion object
@@ -332,5 +289,5 @@ function extractRequestParameters(params) {
332
289
  return attributes;
333
290
  }
334
291
 
335
- export { addChatCompletionAttributes, addConversationAttributes, addEmbeddingsAttributes, addResponsesApiAttributes, buildMethodPath, extractRequestParameters, getOperationName, getSpanOperation, isChatCompletionChunk, isChatCompletionResponse, isConversationResponse, isEmbeddingsResponse, isResponsesApiResponse, isResponsesApiStreamEvent, setCommonResponseAttributes, setTokenUsageAttributes, shouldInstrument };
292
+ export { addChatCompletionAttributes, addConversationAttributes, addEmbeddingsAttributes, addResponsesApiAttributes, extractRequestParameters, isChatCompletionChunk, isChatCompletionResponse, isConversationResponse, isEmbeddingsResponse, isResponsesApiResponse, isResponsesApiStreamEvent, setCommonResponseAttributes, setTokenUsageAttributes };
336
293
  //# sourceMappingURL=utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sources":["../../../../src/tracing/openai/utils.ts"],"sourcesContent":["import type { Span } from '../../types-hoist/span';\nimport {\n GEN_AI_CONVERSATION_ID_ATTRIBUTE,\n GEN_AI_REQUEST_DIMENSIONS_ATTRIBUTE,\n GEN_AI_REQUEST_ENCODING_FORMAT_ATTRIBUTE,\n GEN_AI_REQUEST_FREQUENCY_PENALTY_ATTRIBUTE,\n GEN_AI_REQUEST_MODEL_ATTRIBUTE,\n GEN_AI_REQUEST_PRESENCE_PENALTY_ATTRIBUTE,\n GEN_AI_REQUEST_STREAM_ATTRIBUTE,\n GEN_AI_REQUEST_TEMPERATURE_ATTRIBUTE,\n GEN_AI_REQUEST_TOP_P_ATTRIBUTE,\n GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE,\n GEN_AI_RESPONSE_ID_ATTRIBUTE,\n GEN_AI_RESPONSE_MODEL_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 OPENAI_OPERATIONS,\n OPENAI_RESPONSE_ID_ATTRIBUTE,\n OPENAI_RESPONSE_MODEL_ATTRIBUTE,\n OPENAI_RESPONSE_TIMESTAMP_ATTRIBUTE,\n OPENAI_USAGE_COMPLETION_TOKENS_ATTRIBUTE,\n OPENAI_USAGE_PROMPT_TOKENS_ATTRIBUTE,\n} from '../ai/gen-ai-attributes';\nimport { INSTRUMENTED_METHODS } from './constants';\nimport type {\n ChatCompletionChunk,\n InstrumentedMethod,\n OpenAiChatCompletionObject,\n OpenAIConversationObject,\n OpenAICreateEmbeddingsObject,\n OpenAIResponseObject,\n ResponseStreamingEvent,\n} from './types';\n\n/**\n * Maps OpenAI method paths to OpenTelemetry semantic convention operation names\n * @see https://opentelemetry.io/docs/specs/semconv/gen-ai/gen-ai-spans/#llm-request-spans\n */\nexport function getOperationName(methodPath: string): string {\n if (methodPath.includes('chat.completions')) {\n return OPENAI_OPERATIONS.CHAT;\n }\n if (methodPath.includes('responses')) {\n return OPENAI_OPERATIONS.CHAT;\n }\n if (methodPath.includes('embeddings')) {\n return OPENAI_OPERATIONS.EMBEDDINGS;\n }\n if (methodPath.includes('conversations')) {\n return OPENAI_OPERATIONS.CHAT;\n }\n return methodPath.split('.').pop() || 'unknown';\n}\n\n/**\n * Get the span operation for OpenAI methods\n * Following Sentry's convention: \"gen_ai.{operation_name}\"\n */\nexport function getSpanOperation(methodPath: string): string {\n return `gen_ai.${getOperationName(methodPath)}`;\n}\n\n/**\n * Check if a method path should be instrumented\n */\nexport function shouldInstrument(methodPath: string): methodPath is InstrumentedMethod {\n return INSTRUMENTED_METHODS.includes(methodPath as InstrumentedMethod);\n}\n\n/**\n * Build method path from current traversal\n */\nexport function buildMethodPath(currentPath: string, prop: string): string {\n return currentPath ? `${currentPath}.${prop}` : prop;\n}\n\n/**\n * Check if response is a Chat Completion object\n */\nexport function isChatCompletionResponse(response: unknown): response is OpenAiChatCompletionObject {\n return (\n response !== null &&\n typeof response === 'object' &&\n 'object' in response &&\n (response as Record<string, unknown>).object === 'chat.completion'\n );\n}\n\n/**\n * Check if response is a Responses API object\n */\nexport function isResponsesApiResponse(response: unknown): response is OpenAIResponseObject {\n return (\n response !== null &&\n typeof response === 'object' &&\n 'object' in response &&\n (response as Record<string, unknown>).object === 'response'\n );\n}\n\n/**\n * Check if response is an Embeddings API object\n */\nexport function isEmbeddingsResponse(response: unknown): response is OpenAICreateEmbeddingsObject {\n if (response === null || typeof response !== 'object' || !('object' in response)) {\n return false;\n }\n const responseObject = response as Record<string, unknown>;\n return (\n responseObject.object === 'list' &&\n typeof responseObject.model === 'string' &&\n responseObject.model.toLowerCase().includes('embedding')\n );\n}\n\n/**\n * Check if response is a Conversations API object\n * @see https://platform.openai.com/docs/api-reference/conversations\n */\nexport function isConversationResponse(response: unknown): response is OpenAIConversationObject {\n return (\n response !== null &&\n typeof response === 'object' &&\n 'object' in response &&\n (response as Record<string, unknown>).object === 'conversation'\n );\n}\n\n/**\n * Check if streaming event is from the Responses API\n */\nexport function isResponsesApiStreamEvent(event: unknown): event is ResponseStreamingEvent {\n return (\n event !== null &&\n typeof event === 'object' &&\n 'type' in event &&\n typeof (event as Record<string, unknown>).type === 'string' &&\n ((event as Record<string, unknown>).type as string).startsWith('response.')\n );\n}\n\n/**\n * Check if streaming event is a chat completion chunk\n */\nexport function isChatCompletionChunk(event: unknown): event is ChatCompletionChunk {\n return (\n event !== null &&\n typeof event === 'object' &&\n 'object' in event &&\n (event as Record<string, unknown>).object === 'chat.completion.chunk'\n );\n}\n\n/**\n * Add attributes for Chat Completion responses\n */\nexport function addChatCompletionAttributes(\n span: Span,\n response: OpenAiChatCompletionObject,\n recordOutputs?: boolean,\n): void {\n setCommonResponseAttributes(span, response.id, response.model, response.created);\n if (response.usage) {\n setTokenUsageAttributes(\n span,\n response.usage.prompt_tokens,\n response.usage.completion_tokens,\n response.usage.total_tokens,\n );\n }\n if (Array.isArray(response.choices)) {\n const finishReasons = response.choices\n .map(choice => choice.finish_reason)\n .filter((reason): reason is string => reason !== null);\n if (finishReasons.length > 0) {\n span.setAttributes({\n [GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE]: JSON.stringify(finishReasons),\n });\n }\n\n // Extract tool calls from all choices (only if recordOutputs is true)\n if (recordOutputs) {\n const toolCalls = response.choices\n .map(choice => choice.message?.tool_calls)\n .filter(calls => Array.isArray(calls) && calls.length > 0)\n .flat();\n\n if (toolCalls.length > 0) {\n span.setAttributes({\n [GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE]: JSON.stringify(toolCalls),\n });\n }\n }\n }\n}\n\n/**\n * Add attributes for Responses API responses\n */\nexport function addResponsesApiAttributes(span: Span, response: OpenAIResponseObject, recordOutputs?: boolean): void {\n setCommonResponseAttributes(span, response.id, response.model, response.created_at);\n if (response.status) {\n span.setAttributes({\n [GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE]: JSON.stringify([response.status]),\n });\n }\n if (response.usage) {\n setTokenUsageAttributes(\n span,\n response.usage.input_tokens,\n response.usage.output_tokens,\n response.usage.total_tokens,\n );\n }\n\n // Extract function calls from output (only if recordOutputs is true)\n if (recordOutputs) {\n const responseWithOutput = response as OpenAIResponseObject & { output?: unknown[] };\n if (Array.isArray(responseWithOutput.output) && responseWithOutput.output.length > 0) {\n // Filter for function_call type objects in the output array\n const functionCalls = responseWithOutput.output.filter(\n (item): unknown =>\n // oxlint-disable-next-line typescript/prefer-optional-chain\n typeof item === 'object' && item !== null && (item as Record<string, unknown>).type === 'function_call',\n );\n\n if (functionCalls.length > 0) {\n span.setAttributes({\n [GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE]: JSON.stringify(functionCalls),\n });\n }\n }\n }\n}\n\n/**\n * Add attributes for Embeddings API responses\n */\nexport function addEmbeddingsAttributes(span: Span, response: OpenAICreateEmbeddingsObject): void {\n span.setAttributes({\n [OPENAI_RESPONSE_MODEL_ATTRIBUTE]: response.model,\n [GEN_AI_RESPONSE_MODEL_ATTRIBUTE]: response.model,\n });\n\n if (response.usage) {\n setTokenUsageAttributes(span, response.usage.prompt_tokens, undefined, response.usage.total_tokens);\n }\n}\n\n/**\n * Add attributes for Conversations API responses\n * @see https://platform.openai.com/docs/api-reference/conversations\n */\nexport function addConversationAttributes(span: Span, response: OpenAIConversationObject): void {\n const { id, created_at } = response;\n\n span.setAttributes({\n [OPENAI_RESPONSE_ID_ATTRIBUTE]: id,\n [GEN_AI_RESPONSE_ID_ATTRIBUTE]: id,\n // The conversation id is used to link messages across API calls\n [GEN_AI_CONVERSATION_ID_ATTRIBUTE]: id,\n });\n\n if (created_at) {\n span.setAttributes({\n [OPENAI_RESPONSE_TIMESTAMP_ATTRIBUTE]: new Date(created_at * 1000).toISOString(),\n });\n }\n}\n\n/**\n * Set token usage attributes\n * @param span - The span to add attributes to\n * @param promptTokens - The number of prompt tokens\n * @param completionTokens - The number of completion tokens\n * @param totalTokens - The number of total tokens\n */\nexport function setTokenUsageAttributes(\n span: Span,\n promptTokens?: number,\n completionTokens?: number,\n totalTokens?: number,\n): void {\n if (promptTokens !== undefined) {\n span.setAttributes({\n [OPENAI_USAGE_PROMPT_TOKENS_ATTRIBUTE]: promptTokens,\n [GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE]: promptTokens,\n });\n }\n if (completionTokens !== undefined) {\n span.setAttributes({\n [OPENAI_USAGE_COMPLETION_TOKENS_ATTRIBUTE]: completionTokens,\n [GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE]: completionTokens,\n });\n }\n if (totalTokens !== undefined) {\n span.setAttributes({\n [GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE]: totalTokens,\n });\n }\n}\n\n/**\n * Set common response attributes\n * @param span - The span to add attributes to\n * @param id - The response id\n * @param model - The response model\n * @param timestamp - The response timestamp\n */\nexport function setCommonResponseAttributes(span: Span, id: string, model: string, timestamp: number): void {\n span.setAttributes({\n [OPENAI_RESPONSE_ID_ATTRIBUTE]: id,\n [GEN_AI_RESPONSE_ID_ATTRIBUTE]: id,\n });\n span.setAttributes({\n [OPENAI_RESPONSE_MODEL_ATTRIBUTE]: model,\n [GEN_AI_RESPONSE_MODEL_ATTRIBUTE]: model,\n });\n span.setAttributes({\n [OPENAI_RESPONSE_TIMESTAMP_ATTRIBUTE]: new Date(timestamp * 1000).toISOString(),\n });\n}\n\n/**\n * Extract conversation ID from request parameters\n * Supports both Conversations API and previous_response_id chaining\n * @see https://platform.openai.com/docs/guides/conversation-state\n */\nfunction extractConversationId(params: Record<string, unknown>): string | undefined {\n // Conversations API: conversation parameter (e.g., \"conv_...\")\n if ('conversation' in params && typeof params.conversation === 'string') {\n return params.conversation;\n }\n // Responses chaining: previous_response_id links to parent response\n if ('previous_response_id' in params && typeof params.previous_response_id === 'string') {\n return params.previous_response_id;\n }\n return undefined;\n}\n\n/**\n * Extract request parameters including model settings and conversation context\n */\nexport function extractRequestParameters(params: Record<string, unknown>): Record<string, unknown> {\n const attributes: Record<string, unknown> = {\n [GEN_AI_REQUEST_MODEL_ATTRIBUTE]: params.model ?? 'unknown',\n };\n\n if ('temperature' in params) attributes[GEN_AI_REQUEST_TEMPERATURE_ATTRIBUTE] = params.temperature;\n if ('top_p' in params) attributes[GEN_AI_REQUEST_TOP_P_ATTRIBUTE] = params.top_p;\n if ('frequency_penalty' in params) attributes[GEN_AI_REQUEST_FREQUENCY_PENALTY_ATTRIBUTE] = params.frequency_penalty;\n if ('presence_penalty' in params) attributes[GEN_AI_REQUEST_PRESENCE_PENALTY_ATTRIBUTE] = params.presence_penalty;\n if ('stream' in params) attributes[GEN_AI_REQUEST_STREAM_ATTRIBUTE] = params.stream;\n if ('encoding_format' in params) attributes[GEN_AI_REQUEST_ENCODING_FORMAT_ATTRIBUTE] = params.encoding_format;\n if ('dimensions' in params) attributes[GEN_AI_REQUEST_DIMENSIONS_ATTRIBUTE] = params.dimensions;\n\n // Capture conversation ID for linking messages across API calls\n const conversationId = extractConversationId(params);\n if (conversationId) {\n attributes[GEN_AI_CONVERSATION_ID_ATTRIBUTE] = conversationId;\n }\n\n return attributes;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"utils.js","sources":["../../../../src/tracing/openai/utils.ts"],"sourcesContent":["import type { Span } from '../../types-hoist/span';\nimport {\n GEN_AI_CONVERSATION_ID_ATTRIBUTE,\n GEN_AI_REQUEST_DIMENSIONS_ATTRIBUTE,\n GEN_AI_REQUEST_ENCODING_FORMAT_ATTRIBUTE,\n GEN_AI_REQUEST_FREQUENCY_PENALTY_ATTRIBUTE,\n GEN_AI_REQUEST_MODEL_ATTRIBUTE,\n GEN_AI_REQUEST_PRESENCE_PENALTY_ATTRIBUTE,\n GEN_AI_REQUEST_STREAM_ATTRIBUTE,\n GEN_AI_REQUEST_TEMPERATURE_ATTRIBUTE,\n GEN_AI_REQUEST_TOP_P_ATTRIBUTE,\n GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE,\n GEN_AI_RESPONSE_ID_ATTRIBUTE,\n GEN_AI_RESPONSE_MODEL_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 OPENAI_RESPONSE_ID_ATTRIBUTE,\n OPENAI_RESPONSE_MODEL_ATTRIBUTE,\n OPENAI_RESPONSE_TIMESTAMP_ATTRIBUTE,\n OPENAI_USAGE_COMPLETION_TOKENS_ATTRIBUTE,\n OPENAI_USAGE_PROMPT_TOKENS_ATTRIBUTE,\n} from '../ai/gen-ai-attributes';\nimport type {\n ChatCompletionChunk,\n OpenAiChatCompletionObject,\n OpenAIConversationObject,\n OpenAICreateEmbeddingsObject,\n OpenAIResponseObject,\n ResponseStreamingEvent,\n} from './types';\n\n/**\n * Check if response is a Chat Completion object\n */\nexport function isChatCompletionResponse(response: unknown): response is OpenAiChatCompletionObject {\n return (\n response !== null &&\n typeof response === 'object' &&\n 'object' in response &&\n (response as Record<string, unknown>).object === 'chat.completion'\n );\n}\n\n/**\n * Check if response is a Responses API object\n */\nexport function isResponsesApiResponse(response: unknown): response is OpenAIResponseObject {\n return (\n response !== null &&\n typeof response === 'object' &&\n 'object' in response &&\n (response as Record<string, unknown>).object === 'response'\n );\n}\n\n/**\n * Check if response is an Embeddings API object\n */\nexport function isEmbeddingsResponse(response: unknown): response is OpenAICreateEmbeddingsObject {\n if (response === null || typeof response !== 'object' || !('object' in response)) {\n return false;\n }\n const responseObject = response as Record<string, unknown>;\n return (\n responseObject.object === 'list' &&\n typeof responseObject.model === 'string' &&\n responseObject.model.toLowerCase().includes('embedding')\n );\n}\n\n/**\n * Check if response is a Conversations API object\n * @see https://platform.openai.com/docs/api-reference/conversations\n */\nexport function isConversationResponse(response: unknown): response is OpenAIConversationObject {\n return (\n response !== null &&\n typeof response === 'object' &&\n 'object' in response &&\n (response as Record<string, unknown>).object === 'conversation'\n );\n}\n\n/**\n * Check if streaming event is from the Responses API\n */\nexport function isResponsesApiStreamEvent(event: unknown): event is ResponseStreamingEvent {\n return (\n event !== null &&\n typeof event === 'object' &&\n 'type' in event &&\n typeof (event as Record<string, unknown>).type === 'string' &&\n ((event as Record<string, unknown>).type as string).startsWith('response.')\n );\n}\n\n/**\n * Check if streaming event is a chat completion chunk\n */\nexport function isChatCompletionChunk(event: unknown): event is ChatCompletionChunk {\n return (\n event !== null &&\n typeof event === 'object' &&\n 'object' in event &&\n (event as Record<string, unknown>).object === 'chat.completion.chunk'\n );\n}\n\n/**\n * Add attributes for Chat Completion responses\n */\nexport function addChatCompletionAttributes(\n span: Span,\n response: OpenAiChatCompletionObject,\n recordOutputs?: boolean,\n): void {\n setCommonResponseAttributes(span, response.id, response.model, response.created);\n if (response.usage) {\n setTokenUsageAttributes(\n span,\n response.usage.prompt_tokens,\n response.usage.completion_tokens,\n response.usage.total_tokens,\n );\n }\n if (Array.isArray(response.choices)) {\n const finishReasons = response.choices\n .map(choice => choice.finish_reason)\n .filter((reason): reason is string => reason !== null);\n if (finishReasons.length > 0) {\n span.setAttributes({\n [GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE]: JSON.stringify(finishReasons),\n });\n }\n\n // Extract tool calls from all choices (only if recordOutputs is true)\n if (recordOutputs) {\n const toolCalls = response.choices\n .map(choice => choice.message?.tool_calls)\n .filter(calls => Array.isArray(calls) && calls.length > 0)\n .flat();\n\n if (toolCalls.length > 0) {\n span.setAttributes({\n [GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE]: JSON.stringify(toolCalls),\n });\n }\n }\n }\n}\n\n/**\n * Add attributes for Responses API responses\n */\nexport function addResponsesApiAttributes(span: Span, response: OpenAIResponseObject, recordOutputs?: boolean): void {\n setCommonResponseAttributes(span, response.id, response.model, response.created_at);\n if (response.status) {\n span.setAttributes({\n [GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE]: JSON.stringify([response.status]),\n });\n }\n if (response.usage) {\n setTokenUsageAttributes(\n span,\n response.usage.input_tokens,\n response.usage.output_tokens,\n response.usage.total_tokens,\n );\n }\n\n // Extract function calls from output (only if recordOutputs is true)\n if (recordOutputs) {\n const responseWithOutput = response as OpenAIResponseObject & { output?: unknown[] };\n if (Array.isArray(responseWithOutput.output) && responseWithOutput.output.length > 0) {\n // Filter for function_call type objects in the output array\n const functionCalls = responseWithOutput.output.filter(\n (item): unknown =>\n // oxlint-disable-next-line typescript/prefer-optional-chain\n typeof item === 'object' && item !== null && (item as Record<string, unknown>).type === 'function_call',\n );\n\n if (functionCalls.length > 0) {\n span.setAttributes({\n [GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE]: JSON.stringify(functionCalls),\n });\n }\n }\n }\n}\n\n/**\n * Add attributes for Embeddings API responses\n */\nexport function addEmbeddingsAttributes(span: Span, response: OpenAICreateEmbeddingsObject): void {\n span.setAttributes({\n [OPENAI_RESPONSE_MODEL_ATTRIBUTE]: response.model,\n [GEN_AI_RESPONSE_MODEL_ATTRIBUTE]: response.model,\n });\n\n if (response.usage) {\n setTokenUsageAttributes(span, response.usage.prompt_tokens, undefined, response.usage.total_tokens);\n }\n}\n\n/**\n * Add attributes for Conversations API responses\n * @see https://platform.openai.com/docs/api-reference/conversations\n */\nexport function addConversationAttributes(span: Span, response: OpenAIConversationObject): void {\n const { id, created_at } = response;\n\n span.setAttributes({\n [OPENAI_RESPONSE_ID_ATTRIBUTE]: id,\n [GEN_AI_RESPONSE_ID_ATTRIBUTE]: id,\n // The conversation id is used to link messages across API calls\n [GEN_AI_CONVERSATION_ID_ATTRIBUTE]: id,\n });\n\n if (created_at) {\n span.setAttributes({\n [OPENAI_RESPONSE_TIMESTAMP_ATTRIBUTE]: new Date(created_at * 1000).toISOString(),\n });\n }\n}\n\n/**\n * Set token usage attributes\n * @param span - The span to add attributes to\n * @param promptTokens - The number of prompt tokens\n * @param completionTokens - The number of completion tokens\n * @param totalTokens - The number of total tokens\n */\nexport function setTokenUsageAttributes(\n span: Span,\n promptTokens?: number,\n completionTokens?: number,\n totalTokens?: number,\n): void {\n if (promptTokens !== undefined) {\n span.setAttributes({\n [OPENAI_USAGE_PROMPT_TOKENS_ATTRIBUTE]: promptTokens,\n [GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE]: promptTokens,\n });\n }\n if (completionTokens !== undefined) {\n span.setAttributes({\n [OPENAI_USAGE_COMPLETION_TOKENS_ATTRIBUTE]: completionTokens,\n [GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE]: completionTokens,\n });\n }\n if (totalTokens !== undefined) {\n span.setAttributes({\n [GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE]: totalTokens,\n });\n }\n}\n\n/**\n * Set common response attributes\n * @param span - The span to add attributes to\n * @param id - The response id\n * @param model - The response model\n * @param timestamp - The response timestamp\n */\nexport function setCommonResponseAttributes(span: Span, id: string, model: string, timestamp: number): void {\n span.setAttributes({\n [OPENAI_RESPONSE_ID_ATTRIBUTE]: id,\n [GEN_AI_RESPONSE_ID_ATTRIBUTE]: id,\n });\n span.setAttributes({\n [OPENAI_RESPONSE_MODEL_ATTRIBUTE]: model,\n [GEN_AI_RESPONSE_MODEL_ATTRIBUTE]: model,\n });\n span.setAttributes({\n [OPENAI_RESPONSE_TIMESTAMP_ATTRIBUTE]: new Date(timestamp * 1000).toISOString(),\n });\n}\n\n/**\n * Extract conversation ID from request parameters\n * Supports both Conversations API and previous_response_id chaining\n * @see https://platform.openai.com/docs/guides/conversation-state\n */\nfunction extractConversationId(params: Record<string, unknown>): string | undefined {\n // Conversations API: conversation parameter (e.g., \"conv_...\")\n if ('conversation' in params && typeof params.conversation === 'string') {\n return params.conversation;\n }\n // Responses chaining: previous_response_id links to parent response\n if ('previous_response_id' in params && typeof params.previous_response_id === 'string') {\n return params.previous_response_id;\n }\n return undefined;\n}\n\n/**\n * Extract request parameters including model settings and conversation context\n */\nexport function extractRequestParameters(params: Record<string, unknown>): Record<string, unknown> {\n const attributes: Record<string, unknown> = {\n [GEN_AI_REQUEST_MODEL_ATTRIBUTE]: params.model ?? 'unknown',\n };\n\n if ('temperature' in params) attributes[GEN_AI_REQUEST_TEMPERATURE_ATTRIBUTE] = params.temperature;\n if ('top_p' in params) attributes[GEN_AI_REQUEST_TOP_P_ATTRIBUTE] = params.top_p;\n if ('frequency_penalty' in params) attributes[GEN_AI_REQUEST_FREQUENCY_PENALTY_ATTRIBUTE] = params.frequency_penalty;\n if ('presence_penalty' in params) attributes[GEN_AI_REQUEST_PRESENCE_PENALTY_ATTRIBUTE] = params.presence_penalty;\n if ('stream' in params) attributes[GEN_AI_REQUEST_STREAM_ATTRIBUTE] = params.stream;\n if ('encoding_format' in params) attributes[GEN_AI_REQUEST_ENCODING_FORMAT_ATTRIBUTE] = params.encoding_format;\n if ('dimensions' in params) attributes[GEN_AI_REQUEST_DIMENSIONS_ATTRIBUTE] = params.dimensions;\n\n // Capture conversation ID for linking messages across API calls\n const conversationId = extractConversationId(params);\n if (conversationId) {\n attributes[GEN_AI_CONVERSATION_ID_ATTRIBUTE] = conversationId;\n }\n\n return attributes;\n}\n"],"names":[],"mappings":"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"}
@@ -285,6 +285,11 @@ function suppressTracing(callback) {
285
285
  * or page will automatically create a new trace.
286
286
  */
287
287
  function startNewTrace(callback) {
288
+ const acs = getAcs();
289
+ if (acs.startNewTrace) {
290
+ return acs.startNewTrace(callback);
291
+ }
292
+
288
293
  return withScope(scope => {
289
294
  scope.setPropagationContext({
290
295
  traceId: generateTraceId(),
@@ -1 +1 @@
1
- {"version":3,"file":"trace.js","sources":["../../../src/tracing/trace.ts"],"sourcesContent":["/* eslint-disable max-lines */\n\nimport { getAsyncContextStrategy } from '../asyncContext';\nimport type { AsyncContextStrategy } from '../asyncContext/types';\nimport { getMainCarrier } from '../carrier';\nimport { getClient, getCurrentScope, getIsolationScope, withScope } from '../currentScopes';\nimport { DEBUG_BUILD } from '../debug-build';\nimport type { Scope } from '../scope';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '../semanticAttributes';\nimport type { DynamicSamplingContext } from '../types-hoist/envelope';\nimport type { ClientOptions } from '../types-hoist/options';\nimport type { SentrySpanArguments, Span, SpanTimeInput } from '../types-hoist/span';\nimport type { StartSpanOptions } from '../types-hoist/startSpanOptions';\nimport { baggageHeaderToDynamicSamplingContext } from '../utils/baggage';\nimport { debug } from '../utils/debug-logger';\nimport { handleCallbackErrors } from '../utils/handleCallbackErrors';\nimport { hasSpansEnabled } from '../utils/hasSpansEnabled';\nimport { parseSampleRate } from '../utils/parseSampleRate';\nimport { generateTraceId } from '../utils/propagationContext';\nimport { safeMathRandom } from '../utils/randomSafeContext';\nimport { _getSpanForScope, _setSpanForScope } from '../utils/spanOnScope';\nimport { addChildSpanToSpan, getRootSpan, spanIsSampled, spanTimeInputToSeconds, spanToJSON } from '../utils/spanUtils';\nimport { propagationContextFromHeaders, shouldContinueTrace } from '../utils/tracing';\nimport { freezeDscOnSpan, getDynamicSamplingContextFromSpan } from './dynamicSamplingContext';\nimport { logSpanStart } from './logSpans';\nimport { sampleSpan } from './sampling';\nimport { SentryNonRecordingSpan } from './sentryNonRecordingSpan';\nimport { SentrySpan } from './sentrySpan';\nimport { SPAN_STATUS_ERROR } from './spanstatus';\nimport { setCapturedScopesOnSpan } from './utils';\n\nconst SUPPRESS_TRACING_KEY = '__SENTRY_SUPPRESS_TRACING__';\n\n/**\n * Wraps a function with a transaction/span and finishes the span after the function is done.\n * The created span is the active span and will be used as parent by other spans created inside the function\n * and can be accessed via `Sentry.getActiveSpan()`, as long as the function is executed while the scope is active.\n *\n * If you want to create a span that is not set as active, use {@link startInactiveSpan}.\n *\n * You'll always get a span passed to the callback,\n * it may just be a non-recording span if the span is not sampled or if tracing is disabled.\n */\nexport function startSpan<T>(options: StartSpanOptions, callback: (span: Span) => T): T {\n const acs = getAcs();\n if (acs.startSpan) {\n return acs.startSpan(options, callback);\n }\n\n const spanArguments = parseSentrySpanArguments(options);\n const { forceTransaction, parentSpan: customParentSpan, scope: customScope } = options;\n\n // We still need to fork a potentially passed scope, as we set the active span on it\n // and we need to ensure that it is cleaned up properly once the span ends.\n const customForkedScope = customScope?.clone();\n\n return withScope(customForkedScope, () => {\n // If `options.parentSpan` is defined, we want to wrap the callback in `withActiveSpan`\n const wrapper = getActiveSpanWrapper<T>(customParentSpan);\n\n return wrapper(() => {\n const scope = getCurrentScope();\n const parentSpan = getParentSpan(scope, customParentSpan);\n\n const shouldSkipSpan = options.onlyIfParent && !parentSpan;\n const activeSpan = shouldSkipSpan\n ? new SentryNonRecordingSpan()\n : createChildOrRootSpan({\n parentSpan,\n spanArguments,\n forceTransaction,\n scope,\n });\n\n _setSpanForScope(scope, activeSpan);\n\n return handleCallbackErrors(\n () => callback(activeSpan),\n () => {\n // Only update the span status if it hasn't been changed yet, and the span is not yet finished\n const { status } = spanToJSON(activeSpan);\n if (activeSpan.isRecording() && (!status || status === 'ok')) {\n activeSpan.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n }\n },\n () => {\n activeSpan.end();\n },\n );\n });\n });\n}\n\n/**\n * Similar to `Sentry.startSpan`. Wraps a function with a transaction/span, but does not finish the span\n * after the function is done automatically. Use `span.end()` to end the span.\n *\n * The created span is the active span and will be used as parent by other spans created inside the function\n * and can be accessed via `Sentry.getActiveSpan()`, as long as the function is executed while the scope is active.\n *\n * You'll always get a span passed to the callback,\n * it may just be a non-recording span if the span is not sampled or if tracing is disabled.\n */\nexport function startSpanManual<T>(options: StartSpanOptions, callback: (span: Span, finish: () => void) => T): T {\n const acs = getAcs();\n if (acs.startSpanManual) {\n return acs.startSpanManual(options, callback);\n }\n\n const spanArguments = parseSentrySpanArguments(options);\n const { forceTransaction, parentSpan: customParentSpan, scope: customScope } = options;\n\n const customForkedScope = customScope?.clone();\n\n return withScope(customForkedScope, () => {\n // If `options.parentSpan` is defined, we want to wrap the callback in `withActiveSpan`\n const wrapper = getActiveSpanWrapper<T>(customParentSpan);\n\n return wrapper(() => {\n const scope = getCurrentScope();\n const parentSpan = getParentSpan(scope, customParentSpan);\n\n const shouldSkipSpan = options.onlyIfParent && !parentSpan;\n const activeSpan = shouldSkipSpan\n ? new SentryNonRecordingSpan()\n : createChildOrRootSpan({\n parentSpan,\n spanArguments,\n forceTransaction,\n scope,\n });\n\n _setSpanForScope(scope, activeSpan);\n\n return handleCallbackErrors(\n // We pass the `finish` function to the callback, so the user can finish the span manually\n // this is mainly here for historic purposes because previously, we instructed users to call\n // `finish` instead of `span.end()` to also clean up the scope. Nowadays, calling `span.end()`\n // or `finish` has the same effect and we simply leave it here to avoid breaking user code.\n () => callback(activeSpan, () => activeSpan.end()),\n () => {\n // Only update the span status if it hasn't been changed yet, and the span is not yet finished\n const { status } = spanToJSON(activeSpan);\n if (activeSpan.isRecording() && (!status || status === 'ok')) {\n activeSpan.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n }\n },\n );\n });\n });\n}\n\n/**\n * Creates a span. This span is not set as active, so will not get automatic instrumentation spans\n * as children or be able to be accessed via `Sentry.getActiveSpan()`.\n *\n * If you want to create a span that is set as active, use {@link startSpan}.\n *\n * This function will always return a span,\n * it may just be a non-recording span if the span is not sampled or if tracing is disabled.\n */\nexport function startInactiveSpan(options: StartSpanOptions): Span {\n const acs = getAcs();\n if (acs.startInactiveSpan) {\n return acs.startInactiveSpan(options);\n }\n\n const spanArguments = parseSentrySpanArguments(options);\n const { forceTransaction, parentSpan: customParentSpan } = options;\n\n // If `options.scope` is defined, we use this as as a wrapper,\n // If `options.parentSpan` is defined, we want to wrap the callback in `withActiveSpan`\n const wrapper = options.scope\n ? (callback: () => Span) => withScope(options.scope, callback)\n : customParentSpan !== undefined\n ? (callback: () => Span) => withActiveSpan(customParentSpan, callback)\n : (callback: () => Span) => callback();\n\n return wrapper(() => {\n const scope = getCurrentScope();\n const parentSpan = getParentSpan(scope, customParentSpan);\n\n const shouldSkipSpan = options.onlyIfParent && !parentSpan;\n\n if (shouldSkipSpan) {\n return new SentryNonRecordingSpan();\n }\n\n return createChildOrRootSpan({\n parentSpan,\n spanArguments,\n forceTransaction,\n scope,\n });\n });\n}\n\n/**\n * Continue a trace from `sentry-trace` and `baggage` values.\n * These values can be obtained from incoming request headers, or in the browser from `<meta name=\"sentry-trace\">`\n * and `<meta name=\"baggage\">` HTML tags.\n *\n * Spans started with `startSpan`, `startSpanManual` and `startInactiveSpan`, within the callback will automatically\n * be attached to the incoming trace.\n */\nexport const continueTrace = <V>(\n options: {\n sentryTrace: Parameters<typeof propagationContextFromHeaders>[0];\n baggage: Parameters<typeof propagationContextFromHeaders>[1];\n },\n callback: () => V,\n): V => {\n const carrier = getMainCarrier();\n const acs = getAsyncContextStrategy(carrier);\n if (acs.continueTrace) {\n return acs.continueTrace(options, callback);\n }\n\n const { sentryTrace, baggage } = options;\n\n const client = getClient();\n const incomingDsc = baggageHeaderToDynamicSamplingContext(baggage);\n if (client && !shouldContinueTrace(client, incomingDsc?.org_id)) {\n return startNewTrace(callback);\n }\n\n return withScope(scope => {\n const propagationContext = propagationContextFromHeaders(sentryTrace, baggage);\n scope.setPropagationContext(propagationContext);\n _setSpanForScope(scope, undefined);\n return callback();\n });\n};\n\n/**\n * Forks the current scope and sets the provided span as active span in the context of the provided callback. Can be\n * passed `null` to start an entirely new span tree.\n *\n * @param span Spans started in the context of the provided callback will be children of this span. If `null` is passed,\n * spans started within the callback will not be attached to a parent span.\n * @param callback Execution context in which the provided span will be active. Is passed the newly forked scope.\n * @returns the value returned from the provided callback function.\n */\nexport function withActiveSpan<T>(span: Span | null, callback: (scope: Scope) => T): T {\n const acs = getAcs();\n if (acs.withActiveSpan) {\n return acs.withActiveSpan(span, callback);\n }\n\n return withScope(scope => {\n _setSpanForScope(scope, span || undefined);\n return callback(scope);\n });\n}\n\n/** Suppress tracing in the given callback, ensuring no spans are generated inside of it. */\nexport function suppressTracing<T>(callback: () => T): T {\n const acs = getAcs();\n\n if (acs.suppressTracing) {\n return acs.suppressTracing(callback);\n }\n\n return withScope(scope => {\n // Note: We do not wait for the callback to finish before we reset the metadata\n // the reason for this is that otherwise, in the browser this can lead to very weird behavior\n // as there is only a single top scope, if the callback takes longer to finish,\n // other, unrelated spans may also be suppressed, which we do not want\n // so instead, we only suppress tracing synchronoysly in the browser\n scope.setSDKProcessingMetadata({ [SUPPRESS_TRACING_KEY]: true });\n const res = callback();\n scope.setSDKProcessingMetadata({ [SUPPRESS_TRACING_KEY]: undefined });\n return res;\n });\n}\n\n/**\n * Starts a new trace for the duration of the provided callback. Spans started within the\n * callback will be part of the new trace instead of a potentially previously started trace.\n *\n * Important: Only use this function if you want to override the default trace lifetime and\n * propagation mechanism of the SDK for the duration and scope of the provided callback.\n * The newly created trace will also be the root of a new distributed trace, for example if\n * you make http requests within the callback.\n * This function might be useful if the operation you want to instrument should not be part\n * of a potentially ongoing trace.\n *\n * Default behavior:\n * - Server-side: A new trace is started for each incoming request.\n * - Browser: A new trace is started for each page our route. Navigating to a new route\n * or page will automatically create a new trace.\n */\nexport function startNewTrace<T>(callback: () => T): T {\n return withScope(scope => {\n scope.setPropagationContext({\n traceId: generateTraceId(),\n sampleRand: safeMathRandom(),\n });\n DEBUG_BUILD && debug.log(`Starting a new trace with id ${scope.getPropagationContext().traceId}`);\n return withActiveSpan(null, callback);\n });\n}\n\nfunction createChildOrRootSpan({\n parentSpan,\n spanArguments,\n forceTransaction,\n scope,\n}: {\n parentSpan: SentrySpan | undefined;\n spanArguments: SentrySpanArguments;\n forceTransaction?: boolean;\n scope: Scope;\n}): Span {\n if (!hasSpansEnabled()) {\n const span = new SentryNonRecordingSpan();\n\n // If this is a root span, we ensure to freeze a DSC\n // So we can have at least partial data here\n if (forceTransaction || !parentSpan) {\n const dsc = {\n sampled: 'false',\n sample_rate: '0',\n transaction: spanArguments.name,\n ...getDynamicSamplingContextFromSpan(span),\n } satisfies Partial<DynamicSamplingContext>;\n freezeDscOnSpan(span, dsc);\n }\n\n return span;\n }\n\n const isolationScope = getIsolationScope();\n\n let span: Span;\n if (parentSpan && !forceTransaction) {\n span = _startChildSpan(parentSpan, scope, spanArguments);\n addChildSpanToSpan(parentSpan, span);\n } else if (parentSpan) {\n // If we forced a transaction but have a parent span, make sure to continue from the parent span, not the scope\n const dsc = getDynamicSamplingContextFromSpan(parentSpan);\n const { traceId, spanId: parentSpanId } = parentSpan.spanContext();\n const parentSampled = spanIsSampled(parentSpan);\n\n span = _startRootSpan(\n {\n traceId,\n parentSpanId,\n ...spanArguments,\n },\n scope,\n parentSampled,\n );\n\n freezeDscOnSpan(span, dsc);\n } else {\n const {\n traceId,\n dsc,\n parentSpanId,\n sampled: parentSampled,\n } = {\n ...isolationScope.getPropagationContext(),\n ...scope.getPropagationContext(),\n };\n\n span = _startRootSpan(\n {\n traceId,\n parentSpanId,\n ...spanArguments,\n },\n scope,\n parentSampled,\n );\n\n if (dsc) {\n freezeDscOnSpan(span, dsc);\n }\n }\n\n logSpanStart(span);\n\n setCapturedScopesOnSpan(span, scope, isolationScope);\n\n return span;\n}\n\n/**\n * This converts StartSpanOptions to SentrySpanArguments.\n * For the most part (for now) we accept the same options,\n * but some of them need to be transformed.\n */\nfunction parseSentrySpanArguments(options: StartSpanOptions): SentrySpanArguments {\n const exp = options.experimental || {};\n const initialCtx: SentrySpanArguments = {\n isStandalone: exp.standalone,\n ...options,\n };\n\n if (options.startTime) {\n const ctx: SentrySpanArguments & { startTime?: SpanTimeInput } = { ...initialCtx };\n ctx.startTimestamp = spanTimeInputToSeconds(options.startTime);\n delete ctx.startTime;\n return ctx;\n }\n\n return initialCtx;\n}\n\nfunction getAcs(): AsyncContextStrategy {\n const carrier = getMainCarrier();\n return getAsyncContextStrategy(carrier);\n}\n\nfunction _startRootSpan(spanArguments: SentrySpanArguments, scope: Scope, parentSampled?: boolean): SentrySpan {\n const client = getClient();\n const options: Partial<ClientOptions> = client?.getOptions() || {};\n\n const { name = '' } = spanArguments;\n\n const mutableSpanSamplingData = { spanAttributes: { ...spanArguments.attributes }, spanName: name, parentSampled };\n\n // we don't care about the decision for the moment; this is just a placeholder\n client?.emit('beforeSampling', mutableSpanSamplingData, { decision: false });\n\n // If hook consumers override the parentSampled flag, we will use that value instead of the actual one\n const finalParentSampled = mutableSpanSamplingData.parentSampled ?? parentSampled;\n const finalAttributes = mutableSpanSamplingData.spanAttributes;\n\n const currentPropagationContext = scope.getPropagationContext();\n const [sampled, sampleRate, localSampleRateWasApplied] = scope.getScopeData().sdkProcessingMetadata[\n SUPPRESS_TRACING_KEY\n ]\n ? [false]\n : sampleSpan(\n options,\n {\n name,\n parentSampled: finalParentSampled,\n attributes: finalAttributes,\n parentSampleRate: parseSampleRate(currentPropagationContext.dsc?.sample_rate),\n },\n currentPropagationContext.sampleRand,\n );\n\n const rootSpan = new SentrySpan({\n ...spanArguments,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'custom',\n [SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE]:\n sampleRate !== undefined && localSampleRateWasApplied ? sampleRate : undefined,\n ...finalAttributes,\n },\n sampled,\n });\n\n if (!sampled && client) {\n DEBUG_BUILD && debug.log('[Tracing] Discarding root span because its trace was not chosen to be sampled.');\n client.recordDroppedEvent('sample_rate', 'transaction');\n }\n\n if (client) {\n client.emit('spanStart', rootSpan);\n }\n\n return rootSpan;\n}\n\n/**\n * Creates a new `Span` while setting the current `Span.id` as `parentSpanId`.\n * This inherits the sampling decision from the parent span.\n */\nfunction _startChildSpan(parentSpan: Span, scope: Scope, spanArguments: SentrySpanArguments): Span {\n const { spanId, traceId } = parentSpan.spanContext();\n const sampled = scope.getScopeData().sdkProcessingMetadata[SUPPRESS_TRACING_KEY] ? false : spanIsSampled(parentSpan);\n\n const childSpan = sampled\n ? new SentrySpan({\n ...spanArguments,\n parentSpanId: spanId,\n traceId,\n sampled,\n })\n : new SentryNonRecordingSpan({ traceId });\n\n addChildSpanToSpan(parentSpan, childSpan);\n\n const client = getClient();\n if (client) {\n client.emit('spanStart', childSpan);\n // If it has an endTimestamp, it's already ended\n if (spanArguments.endTimestamp) {\n client.emit('spanEnd', childSpan);\n }\n }\n\n return childSpan;\n}\n\nfunction getParentSpan(scope: Scope, customParentSpan: Span | null | undefined): SentrySpan | undefined {\n // always use the passed in span directly\n if (customParentSpan) {\n return customParentSpan as SentrySpan;\n }\n\n // This is different from `undefined` as it means the user explicitly wants no parent span\n if (customParentSpan === null) {\n return undefined;\n }\n\n const span = _getSpanForScope(scope) as SentrySpan | undefined;\n\n if (!span) {\n return undefined;\n }\n\n const client = getClient();\n const options: Partial<ClientOptions> = client ? client.getOptions() : {};\n if (options.parentSpanIsAlwaysRootSpan) {\n return getRootSpan(span) as SentrySpan;\n }\n\n return span;\n}\n\nfunction getActiveSpanWrapper<T>(parentSpan: Span | undefined | null): (callback: () => T) => T {\n return parentSpan !== undefined\n ? (callback: () => T) => {\n return withActiveSpan(parentSpan, callback);\n }\n : (callback: () => T) => callback();\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"trace.js","sources":["../../../src/tracing/trace.ts"],"sourcesContent":["/* eslint-disable max-lines */\n\nimport { getAsyncContextStrategy } from '../asyncContext';\nimport type { AsyncContextStrategy } from '../asyncContext/types';\nimport { getMainCarrier } from '../carrier';\nimport { getClient, getCurrentScope, getIsolationScope, withScope } from '../currentScopes';\nimport { DEBUG_BUILD } from '../debug-build';\nimport type { Scope } from '../scope';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '../semanticAttributes';\nimport type { DynamicSamplingContext } from '../types-hoist/envelope';\nimport type { ClientOptions } from '../types-hoist/options';\nimport type { SentrySpanArguments, Span, SpanTimeInput } from '../types-hoist/span';\nimport type { StartSpanOptions } from '../types-hoist/startSpanOptions';\nimport { baggageHeaderToDynamicSamplingContext } from '../utils/baggage';\nimport { debug } from '../utils/debug-logger';\nimport { handleCallbackErrors } from '../utils/handleCallbackErrors';\nimport { hasSpansEnabled } from '../utils/hasSpansEnabled';\nimport { parseSampleRate } from '../utils/parseSampleRate';\nimport { generateTraceId } from '../utils/propagationContext';\nimport { safeMathRandom } from '../utils/randomSafeContext';\nimport { _getSpanForScope, _setSpanForScope } from '../utils/spanOnScope';\nimport { addChildSpanToSpan, getRootSpan, spanIsSampled, spanTimeInputToSeconds, spanToJSON } from '../utils/spanUtils';\nimport { propagationContextFromHeaders, shouldContinueTrace } from '../utils/tracing';\nimport { freezeDscOnSpan, getDynamicSamplingContextFromSpan } from './dynamicSamplingContext';\nimport { logSpanStart } from './logSpans';\nimport { sampleSpan } from './sampling';\nimport { SentryNonRecordingSpan } from './sentryNonRecordingSpan';\nimport { SentrySpan } from './sentrySpan';\nimport { SPAN_STATUS_ERROR } from './spanstatus';\nimport { setCapturedScopesOnSpan } from './utils';\n\nconst SUPPRESS_TRACING_KEY = '__SENTRY_SUPPRESS_TRACING__';\n\n/**\n * Wraps a function with a transaction/span and finishes the span after the function is done.\n * The created span is the active span and will be used as parent by other spans created inside the function\n * and can be accessed via `Sentry.getActiveSpan()`, as long as the function is executed while the scope is active.\n *\n * If you want to create a span that is not set as active, use {@link startInactiveSpan}.\n *\n * You'll always get a span passed to the callback,\n * it may just be a non-recording span if the span is not sampled or if tracing is disabled.\n */\nexport function startSpan<T>(options: StartSpanOptions, callback: (span: Span) => T): T {\n const acs = getAcs();\n if (acs.startSpan) {\n return acs.startSpan(options, callback);\n }\n\n const spanArguments = parseSentrySpanArguments(options);\n const { forceTransaction, parentSpan: customParentSpan, scope: customScope } = options;\n\n // We still need to fork a potentially passed scope, as we set the active span on it\n // and we need to ensure that it is cleaned up properly once the span ends.\n const customForkedScope = customScope?.clone();\n\n return withScope(customForkedScope, () => {\n // If `options.parentSpan` is defined, we want to wrap the callback in `withActiveSpan`\n const wrapper = getActiveSpanWrapper<T>(customParentSpan);\n\n return wrapper(() => {\n const scope = getCurrentScope();\n const parentSpan = getParentSpan(scope, customParentSpan);\n\n const shouldSkipSpan = options.onlyIfParent && !parentSpan;\n const activeSpan = shouldSkipSpan\n ? new SentryNonRecordingSpan()\n : createChildOrRootSpan({\n parentSpan,\n spanArguments,\n forceTransaction,\n scope,\n });\n\n _setSpanForScope(scope, activeSpan);\n\n return handleCallbackErrors(\n () => callback(activeSpan),\n () => {\n // Only update the span status if it hasn't been changed yet, and the span is not yet finished\n const { status } = spanToJSON(activeSpan);\n if (activeSpan.isRecording() && (!status || status === 'ok')) {\n activeSpan.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n }\n },\n () => {\n activeSpan.end();\n },\n );\n });\n });\n}\n\n/**\n * Similar to `Sentry.startSpan`. Wraps a function with a transaction/span, but does not finish the span\n * after the function is done automatically. Use `span.end()` to end the span.\n *\n * The created span is the active span and will be used as parent by other spans created inside the function\n * and can be accessed via `Sentry.getActiveSpan()`, as long as the function is executed while the scope is active.\n *\n * You'll always get a span passed to the callback,\n * it may just be a non-recording span if the span is not sampled or if tracing is disabled.\n */\nexport function startSpanManual<T>(options: StartSpanOptions, callback: (span: Span, finish: () => void) => T): T {\n const acs = getAcs();\n if (acs.startSpanManual) {\n return acs.startSpanManual(options, callback);\n }\n\n const spanArguments = parseSentrySpanArguments(options);\n const { forceTransaction, parentSpan: customParentSpan, scope: customScope } = options;\n\n const customForkedScope = customScope?.clone();\n\n return withScope(customForkedScope, () => {\n // If `options.parentSpan` is defined, we want to wrap the callback in `withActiveSpan`\n const wrapper = getActiveSpanWrapper<T>(customParentSpan);\n\n return wrapper(() => {\n const scope = getCurrentScope();\n const parentSpan = getParentSpan(scope, customParentSpan);\n\n const shouldSkipSpan = options.onlyIfParent && !parentSpan;\n const activeSpan = shouldSkipSpan\n ? new SentryNonRecordingSpan()\n : createChildOrRootSpan({\n parentSpan,\n spanArguments,\n forceTransaction,\n scope,\n });\n\n _setSpanForScope(scope, activeSpan);\n\n return handleCallbackErrors(\n // We pass the `finish` function to the callback, so the user can finish the span manually\n // this is mainly here for historic purposes because previously, we instructed users to call\n // `finish` instead of `span.end()` to also clean up the scope. Nowadays, calling `span.end()`\n // or `finish` has the same effect and we simply leave it here to avoid breaking user code.\n () => callback(activeSpan, () => activeSpan.end()),\n () => {\n // Only update the span status if it hasn't been changed yet, and the span is not yet finished\n const { status } = spanToJSON(activeSpan);\n if (activeSpan.isRecording() && (!status || status === 'ok')) {\n activeSpan.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n }\n },\n );\n });\n });\n}\n\n/**\n * Creates a span. This span is not set as active, so will not get automatic instrumentation spans\n * as children or be able to be accessed via `Sentry.getActiveSpan()`.\n *\n * If you want to create a span that is set as active, use {@link startSpan}.\n *\n * This function will always return a span,\n * it may just be a non-recording span if the span is not sampled or if tracing is disabled.\n */\nexport function startInactiveSpan(options: StartSpanOptions): Span {\n const acs = getAcs();\n if (acs.startInactiveSpan) {\n return acs.startInactiveSpan(options);\n }\n\n const spanArguments = parseSentrySpanArguments(options);\n const { forceTransaction, parentSpan: customParentSpan } = options;\n\n // If `options.scope` is defined, we use this as as a wrapper,\n // If `options.parentSpan` is defined, we want to wrap the callback in `withActiveSpan`\n const wrapper = options.scope\n ? (callback: () => Span) => withScope(options.scope, callback)\n : customParentSpan !== undefined\n ? (callback: () => Span) => withActiveSpan(customParentSpan, callback)\n : (callback: () => Span) => callback();\n\n return wrapper(() => {\n const scope = getCurrentScope();\n const parentSpan = getParentSpan(scope, customParentSpan);\n\n const shouldSkipSpan = options.onlyIfParent && !parentSpan;\n\n if (shouldSkipSpan) {\n return new SentryNonRecordingSpan();\n }\n\n return createChildOrRootSpan({\n parentSpan,\n spanArguments,\n forceTransaction,\n scope,\n });\n });\n}\n\n/**\n * Continue a trace from `sentry-trace` and `baggage` values.\n * These values can be obtained from incoming request headers, or in the browser from `<meta name=\"sentry-trace\">`\n * and `<meta name=\"baggage\">` HTML tags.\n *\n * Spans started with `startSpan`, `startSpanManual` and `startInactiveSpan`, within the callback will automatically\n * be attached to the incoming trace.\n */\nexport const continueTrace = <V>(\n options: {\n sentryTrace: Parameters<typeof propagationContextFromHeaders>[0];\n baggage: Parameters<typeof propagationContextFromHeaders>[1];\n },\n callback: () => V,\n): V => {\n const carrier = getMainCarrier();\n const acs = getAsyncContextStrategy(carrier);\n if (acs.continueTrace) {\n return acs.continueTrace(options, callback);\n }\n\n const { sentryTrace, baggage } = options;\n\n const client = getClient();\n const incomingDsc = baggageHeaderToDynamicSamplingContext(baggage);\n if (client && !shouldContinueTrace(client, incomingDsc?.org_id)) {\n return startNewTrace(callback);\n }\n\n return withScope(scope => {\n const propagationContext = propagationContextFromHeaders(sentryTrace, baggage);\n scope.setPropagationContext(propagationContext);\n _setSpanForScope(scope, undefined);\n return callback();\n });\n};\n\n/**\n * Forks the current scope and sets the provided span as active span in the context of the provided callback. Can be\n * passed `null` to start an entirely new span tree.\n *\n * @param span Spans started in the context of the provided callback will be children of this span. If `null` is passed,\n * spans started within the callback will not be attached to a parent span.\n * @param callback Execution context in which the provided span will be active. Is passed the newly forked scope.\n * @returns the value returned from the provided callback function.\n */\nexport function withActiveSpan<T>(span: Span | null, callback: (scope: Scope) => T): T {\n const acs = getAcs();\n if (acs.withActiveSpan) {\n return acs.withActiveSpan(span, callback);\n }\n\n return withScope(scope => {\n _setSpanForScope(scope, span || undefined);\n return callback(scope);\n });\n}\n\n/** Suppress tracing in the given callback, ensuring no spans are generated inside of it. */\nexport function suppressTracing<T>(callback: () => T): T {\n const acs = getAcs();\n\n if (acs.suppressTracing) {\n return acs.suppressTracing(callback);\n }\n\n return withScope(scope => {\n // Note: We do not wait for the callback to finish before we reset the metadata\n // the reason for this is that otherwise, in the browser this can lead to very weird behavior\n // as there is only a single top scope, if the callback takes longer to finish,\n // other, unrelated spans may also be suppressed, which we do not want\n // so instead, we only suppress tracing synchronoysly in the browser\n scope.setSDKProcessingMetadata({ [SUPPRESS_TRACING_KEY]: true });\n const res = callback();\n scope.setSDKProcessingMetadata({ [SUPPRESS_TRACING_KEY]: undefined });\n return res;\n });\n}\n\n/**\n * Starts a new trace for the duration of the provided callback. Spans started within the\n * callback will be part of the new trace instead of a potentially previously started trace.\n *\n * Important: Only use this function if you want to override the default trace lifetime and\n * propagation mechanism of the SDK for the duration and scope of the provided callback.\n * The newly created trace will also be the root of a new distributed trace, for example if\n * you make http requests within the callback.\n * This function might be useful if the operation you want to instrument should not be part\n * of a potentially ongoing trace.\n *\n * Default behavior:\n * - Server-side: A new trace is started for each incoming request.\n * - Browser: A new trace is started for each page our route. Navigating to a new route\n * or page will automatically create a new trace.\n */\nexport function startNewTrace<T>(callback: () => T): T {\n const acs = getAcs();\n if (acs.startNewTrace) {\n return acs.startNewTrace(callback);\n }\n\n return withScope(scope => {\n scope.setPropagationContext({\n traceId: generateTraceId(),\n sampleRand: safeMathRandom(),\n });\n DEBUG_BUILD && debug.log(`Starting a new trace with id ${scope.getPropagationContext().traceId}`);\n return withActiveSpan(null, callback);\n });\n}\n\nfunction createChildOrRootSpan({\n parentSpan,\n spanArguments,\n forceTransaction,\n scope,\n}: {\n parentSpan: SentrySpan | undefined;\n spanArguments: SentrySpanArguments;\n forceTransaction?: boolean;\n scope: Scope;\n}): Span {\n if (!hasSpansEnabled()) {\n const span = new SentryNonRecordingSpan();\n\n // If this is a root span, we ensure to freeze a DSC\n // So we can have at least partial data here\n if (forceTransaction || !parentSpan) {\n const dsc = {\n sampled: 'false',\n sample_rate: '0',\n transaction: spanArguments.name,\n ...getDynamicSamplingContextFromSpan(span),\n } satisfies Partial<DynamicSamplingContext>;\n freezeDscOnSpan(span, dsc);\n }\n\n return span;\n }\n\n const isolationScope = getIsolationScope();\n\n let span: Span;\n if (parentSpan && !forceTransaction) {\n span = _startChildSpan(parentSpan, scope, spanArguments);\n addChildSpanToSpan(parentSpan, span);\n } else if (parentSpan) {\n // If we forced a transaction but have a parent span, make sure to continue from the parent span, not the scope\n const dsc = getDynamicSamplingContextFromSpan(parentSpan);\n const { traceId, spanId: parentSpanId } = parentSpan.spanContext();\n const parentSampled = spanIsSampled(parentSpan);\n\n span = _startRootSpan(\n {\n traceId,\n parentSpanId,\n ...spanArguments,\n },\n scope,\n parentSampled,\n );\n\n freezeDscOnSpan(span, dsc);\n } else {\n const {\n traceId,\n dsc,\n parentSpanId,\n sampled: parentSampled,\n } = {\n ...isolationScope.getPropagationContext(),\n ...scope.getPropagationContext(),\n };\n\n span = _startRootSpan(\n {\n traceId,\n parentSpanId,\n ...spanArguments,\n },\n scope,\n parentSampled,\n );\n\n if (dsc) {\n freezeDscOnSpan(span, dsc);\n }\n }\n\n logSpanStart(span);\n\n setCapturedScopesOnSpan(span, scope, isolationScope);\n\n return span;\n}\n\n/**\n * This converts StartSpanOptions to SentrySpanArguments.\n * For the most part (for now) we accept the same options,\n * but some of them need to be transformed.\n */\nfunction parseSentrySpanArguments(options: StartSpanOptions): SentrySpanArguments {\n const exp = options.experimental || {};\n const initialCtx: SentrySpanArguments = {\n isStandalone: exp.standalone,\n ...options,\n };\n\n if (options.startTime) {\n const ctx: SentrySpanArguments & { startTime?: SpanTimeInput } = { ...initialCtx };\n ctx.startTimestamp = spanTimeInputToSeconds(options.startTime);\n delete ctx.startTime;\n return ctx;\n }\n\n return initialCtx;\n}\n\nfunction getAcs(): AsyncContextStrategy {\n const carrier = getMainCarrier();\n return getAsyncContextStrategy(carrier);\n}\n\nfunction _startRootSpan(spanArguments: SentrySpanArguments, scope: Scope, parentSampled?: boolean): SentrySpan {\n const client = getClient();\n const options: Partial<ClientOptions> = client?.getOptions() || {};\n\n const { name = '' } = spanArguments;\n\n const mutableSpanSamplingData = { spanAttributes: { ...spanArguments.attributes }, spanName: name, parentSampled };\n\n // we don't care about the decision for the moment; this is just a placeholder\n client?.emit('beforeSampling', mutableSpanSamplingData, { decision: false });\n\n // If hook consumers override the parentSampled flag, we will use that value instead of the actual one\n const finalParentSampled = mutableSpanSamplingData.parentSampled ?? parentSampled;\n const finalAttributes = mutableSpanSamplingData.spanAttributes;\n\n const currentPropagationContext = scope.getPropagationContext();\n const [sampled, sampleRate, localSampleRateWasApplied] = scope.getScopeData().sdkProcessingMetadata[\n SUPPRESS_TRACING_KEY\n ]\n ? [false]\n : sampleSpan(\n options,\n {\n name,\n parentSampled: finalParentSampled,\n attributes: finalAttributes,\n parentSampleRate: parseSampleRate(currentPropagationContext.dsc?.sample_rate),\n },\n currentPropagationContext.sampleRand,\n );\n\n const rootSpan = new SentrySpan({\n ...spanArguments,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'custom',\n [SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE]:\n sampleRate !== undefined && localSampleRateWasApplied ? sampleRate : undefined,\n ...finalAttributes,\n },\n sampled,\n });\n\n if (!sampled && client) {\n DEBUG_BUILD && debug.log('[Tracing] Discarding root span because its trace was not chosen to be sampled.');\n client.recordDroppedEvent('sample_rate', 'transaction');\n }\n\n if (client) {\n client.emit('spanStart', rootSpan);\n }\n\n return rootSpan;\n}\n\n/**\n * Creates a new `Span` while setting the current `Span.id` as `parentSpanId`.\n * This inherits the sampling decision from the parent span.\n */\nfunction _startChildSpan(parentSpan: Span, scope: Scope, spanArguments: SentrySpanArguments): Span {\n const { spanId, traceId } = parentSpan.spanContext();\n const sampled = scope.getScopeData().sdkProcessingMetadata[SUPPRESS_TRACING_KEY] ? false : spanIsSampled(parentSpan);\n\n const childSpan = sampled\n ? new SentrySpan({\n ...spanArguments,\n parentSpanId: spanId,\n traceId,\n sampled,\n })\n : new SentryNonRecordingSpan({ traceId });\n\n addChildSpanToSpan(parentSpan, childSpan);\n\n const client = getClient();\n if (client) {\n client.emit('spanStart', childSpan);\n // If it has an endTimestamp, it's already ended\n if (spanArguments.endTimestamp) {\n client.emit('spanEnd', childSpan);\n }\n }\n\n return childSpan;\n}\n\nfunction getParentSpan(scope: Scope, customParentSpan: Span | null | undefined): SentrySpan | undefined {\n // always use the passed in span directly\n if (customParentSpan) {\n return customParentSpan as SentrySpan;\n }\n\n // This is different from `undefined` as it means the user explicitly wants no parent span\n if (customParentSpan === null) {\n return undefined;\n }\n\n const span = _getSpanForScope(scope) as SentrySpan | undefined;\n\n if (!span) {\n return undefined;\n }\n\n const client = getClient();\n const options: Partial<ClientOptions> = client ? client.getOptions() : {};\n if (options.parentSpanIsAlwaysRootSpan) {\n return getRootSpan(span) as SentrySpan;\n }\n\n return span;\n}\n\nfunction getActiveSpanWrapper<T>(parentSpan: Span | undefined | null): (callback: () => T) => T {\n return parentSpan !== undefined\n ? (callback: () => T) => {\n return withActiveSpan(parentSpan, callback);\n }\n : (callback: () => T) => callback();\n}\n"],"names":[],"mappings":"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"}
@@ -201,6 +201,12 @@ function processEndedVercelAiSpan(span) {
201
201
  return;
202
202
  }
203
203
 
204
+ // The Vercel AI SDK sets span status to raw error message strings.
205
+ // Any such value should be normalized to a SpanStatusType value. We pick internal_error as it is the most generic.
206
+ if (span.status && span.status !== 'ok') {
207
+ span.status = 'internal_error';
208
+ }
209
+
204
210
  renameAttributeKey(attributes, AI_USAGE_COMPLETION_TOKENS_ATTRIBUTE, GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE);
205
211
  renameAttributeKey(attributes, AI_USAGE_PROMPT_TOKENS_ATTRIBUTE, GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE);
206
212
  renameAttributeKey(attributes, AI_USAGE_CACHED_INPUT_TOKENS_ATTRIBUTE, GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE);
@@ -405,7 +411,9 @@ function addProviderMetadataToAttributes(attributes) {
405
411
  'gen_ai.usage.output_tokens.prediction_rejected',
406
412
  openaiMetadata.rejectedPredictionTokens,
407
413
  );
408
- setAttributeIfDefined(attributes, 'gen_ai.conversation.id', openaiMetadata.responseId);
414
+ if (!attributes['gen_ai.conversation.id']) {
415
+ setAttributeIfDefined(attributes, 'gen_ai.conversation.id', openaiMetadata.responseId);
416
+ }
409
417
  }
410
418
 
411
419
  if (providerMetadataObject.anthropic) {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../../src/tracing/vercel-ai/index.ts"],"sourcesContent":["/* eslint-disable max-lines */\nimport type { Client } from '../../client';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '../../semanticAttributes';\nimport type { Event } from '../../types-hoist/event';\nimport type { Span, SpanAttributes, SpanAttributeValue, SpanJSON } from '../../types-hoist/span';\nimport { spanToJSON } from '../../utils/spanUtils';\nimport {\n GEN_AI_EMBEDDINGS_INPUT_ATTRIBUTE,\n GEN_AI_INPUT_MESSAGES_ATTRIBUTE,\n GEN_AI_OPERATION_NAME_ATTRIBUTE,\n GEN_AI_OUTPUT_MESSAGES_ATTRIBUTE,\n GEN_AI_REQUEST_MODEL_ATTRIBUTE,\n GEN_AI_RESPONSE_MODEL_ATTRIBUTE,\n GEN_AI_TOOL_CALL_ID_ATTRIBUTE,\n GEN_AI_TOOL_INPUT_ATTRIBUTE,\n GEN_AI_TOOL_NAME_ATTRIBUTE,\n GEN_AI_TOOL_OUTPUT_ATTRIBUTE,\n GEN_AI_TOOL_TYPE_ATTRIBUTE,\n GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE,\n GEN_AI_USAGE_INPUT_TOKENS_CACHE_WRITE_ATTRIBUTE,\n GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE,\n GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE,\n GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE,\n} from '../ai/gen-ai-attributes';\nimport {\n DO_SPAN_NAME_PREFIX,\n EMBEDDINGS_OPS,\n GENERATE_CONTENT_OPS,\n INVOKE_AGENT_OPS,\n RERANK_OPS,\n toolCallSpanContextMap,\n} from './constants';\nimport type { TokenSummary } from './types';\nimport {\n accumulateTokensForParent,\n applyAccumulatedTokens,\n applyToolDescriptionsAndTokens,\n convertAvailableToolsToJsonString,\n getSpanOpFromName,\n requestMessagesFromPrompt,\n} from './utils';\nimport type { OpenAiProviderMetadata, ProviderMetadata } from './vercel-ai-attributes';\nimport {\n AI_MODEL_ID_ATTRIBUTE,\n AI_OPERATION_ID_ATTRIBUTE,\n AI_PROMPT_MESSAGES_ATTRIBUTE,\n AI_PROMPT_TOOLS_ATTRIBUTE,\n AI_RESPONSE_FINISH_REASON_ATTRIBUTE,\n AI_RESPONSE_OBJECT_ATTRIBUTE,\n AI_RESPONSE_PROVIDER_METADATA_ATTRIBUTE,\n AI_RESPONSE_TEXT_ATTRIBUTE,\n AI_RESPONSE_TOOL_CALLS_ATTRIBUTE,\n AI_SCHEMA_ATTRIBUTE,\n AI_TELEMETRY_FUNCTION_ID_ATTRIBUTE,\n AI_TOOL_CALL_ARGS_ATTRIBUTE,\n AI_TOOL_CALL_ID_ATTRIBUTE,\n AI_TOOL_CALL_NAME_ATTRIBUTE,\n AI_TOOL_CALL_RESULT_ATTRIBUTE,\n AI_USAGE_CACHED_INPUT_TOKENS_ATTRIBUTE,\n AI_USAGE_COMPLETION_TOKENS_ATTRIBUTE,\n AI_USAGE_PROMPT_TOKENS_ATTRIBUTE,\n AI_USAGE_TOKENS_ATTRIBUTE,\n AI_VALUES_ATTRIBUTE,\n OPERATION_NAME_ATTRIBUTE,\n} from './vercel-ai-attributes';\n\n/**\n * Maps Vercel AI SDK operation names to OpenTelemetry semantic convention values\n * @see https://opentelemetry.io/docs/specs/semconv/gen-ai/gen-ai-spans/#llm-request-spans\n */\nfunction mapVercelAiOperationName(operationName: string): string {\n // Top-level pipeline operations map to invoke_agent\n if (INVOKE_AGENT_OPS.has(operationName)) {\n return 'invoke_agent';\n }\n // .do* operations are the actual LLM calls\n if (GENERATE_CONTENT_OPS.has(operationName)) {\n return 'generate_content';\n }\n if (EMBEDDINGS_OPS.has(operationName)) {\n return 'embeddings';\n }\n if (RERANK_OPS.has(operationName)) {\n return 'rerank';\n }\n if (operationName === 'ai.toolCall') {\n return 'execute_tool';\n }\n // Return the original value for unknown operations\n return operationName;\n}\n\n/**\n * Post-process spans emitted by the Vercel AI SDK.\n * This is supposed to be used in `client.on('spanStart', ...)\n */\nfunction onVercelAiSpanStart(span: Span): void {\n const { data: attributes, description: name } = spanToJSON(span);\n\n if (!name) {\n return;\n }\n\n // Tool call spans\n // https://ai-sdk.dev/docs/ai-sdk-core/telemetry#tool-call-spans\n if (attributes[AI_TOOL_CALL_NAME_ATTRIBUTE] && attributes[AI_TOOL_CALL_ID_ATTRIBUTE] && name === 'ai.toolCall') {\n processToolCallSpan(span, attributes);\n return;\n }\n\n // V6+ Check if this is a Vercel AI span by checking if the operation ID attribute is present.\n // V5+ Check if this is a Vercel AI span by name pattern.\n if (!attributes[AI_OPERATION_ID_ATTRIBUTE] && !name.startsWith('ai.')) {\n return;\n }\n\n processGenerateSpan(span, name, attributes);\n}\n\nfunction vercelAiEventProcessor(event: Event): Event {\n if (event.type === 'transaction' && event.spans) {\n // Map to accumulate token data by parent span ID\n const tokenAccumulator: Map<string, TokenSummary> = new Map();\n\n // First pass: process all spans and accumulate token data\n for (const span of event.spans) {\n processEndedVercelAiSpan(span);\n\n // Accumulate token data for parent spans\n accumulateTokensForParent(span, tokenAccumulator);\n }\n\n // Second pass: apply tool descriptions and accumulated tokens\n applyToolDescriptionsAndTokens(event.spans, tokenAccumulator);\n\n // Also apply to root when it is the invoke_agent pipeline\n const trace = event.contexts?.trace;\n if (trace?.op === 'gen_ai.invoke_agent') {\n applyAccumulatedTokens(trace, tokenAccumulator);\n }\n }\n\n return event;\n}\n\n/**\n * Tool call structure from Vercel AI SDK\n * Note: V5/V6 use 'input' for arguments, V4 and earlier use 'args'\n */\ninterface VercelToolCall {\n toolCallId: string;\n toolName: string;\n input?: Record<string, unknown> | string; // V5/V6\n args?: string; // V4 and earlier\n}\n\n/**\n * Normalize finish reason to match OpenTelemetry semantic conventions.\n * Valid values: \"stop\", \"length\", \"content_filter\", \"tool_call\", \"error\"\n *\n * Vercel AI SDK uses \"tool-calls\" (plural, with hyphen) which we map to \"tool_call\".\n */\nfunction normalizeFinishReason(finishReason: unknown): string {\n if (typeof finishReason !== 'string') {\n return 'stop';\n }\n\n // Map Vercel AI SDK finish reasons to OpenTelemetry semantic convention values\n switch (finishReason) {\n case 'tool-calls':\n return 'tool_call';\n case 'stop':\n case 'length':\n case 'content_filter':\n case 'error':\n return finishReason;\n default:\n // For unknown values, return as-is (schema allows arbitrary strings)\n return finishReason;\n }\n}\n\n/**\n * Build gen_ai.output.messages from ai.response.text and/or ai.response.toolCalls\n *\n * Format follows OpenTelemetry semantic conventions:\n * [{\"role\": \"assistant\", \"parts\": [...], \"finish_reason\": \"stop\"}]\n *\n * Parts can be:\n * - {\"type\": \"text\", \"content\": \"...\"}\n * - {\"type\": \"tool_call\", \"id\": \"...\", \"name\": \"...\", \"arguments\": \"...\"}\n */\nfunction buildOutputMessages(attributes: Record<string, unknown>): void {\n const responseText = attributes[AI_RESPONSE_TEXT_ATTRIBUTE];\n const responseToolCalls = attributes[AI_RESPONSE_TOOL_CALLS_ATTRIBUTE];\n const finishReason = attributes[AI_RESPONSE_FINISH_REASON_ATTRIBUTE];\n\n // Skip if neither text nor tool calls are present\n if (responseText == null && responseToolCalls == null) {\n return;\n }\n\n const parts: Array<Record<string, unknown>> = [];\n\n // Add text part if present\n if (typeof responseText === 'string' && responseText.length > 0) {\n parts.push({\n type: 'text',\n content: responseText,\n });\n }\n\n // Add tool call parts if present\n if (responseToolCalls != null) {\n try {\n // Tool calls can be a string (JSON) or already parsed array\n const toolCalls: VercelToolCall[] =\n typeof responseToolCalls === 'string' ? JSON.parse(responseToolCalls) : responseToolCalls;\n\n if (Array.isArray(toolCalls)) {\n for (const toolCall of toolCalls) {\n // V5/V6 use 'input', V4 and earlier use 'args'\n const args = toolCall.input ?? toolCall.args;\n parts.push({\n type: 'tool_call',\n id: toolCall.toolCallId,\n name: toolCall.toolName,\n // Handle undefined args: JSON.stringify(undefined) returns undefined, not a string,\n // which would cause the property to be omitted from the final JSON output\n arguments: typeof args === 'string' ? args : JSON.stringify(args ?? {}),\n });\n }\n // Only delete tool calls attribute if we successfully processed them\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete attributes[AI_RESPONSE_TOOL_CALLS_ATTRIBUTE];\n }\n } catch {\n // Ignore parsing errors - tool calls attribute is preserved\n }\n }\n\n // Only set output messages and delete text attribute if we have parts\n if (parts.length > 0) {\n const outputMessage = {\n role: 'assistant',\n parts,\n finish_reason: normalizeFinishReason(finishReason),\n };\n\n attributes[GEN_AI_OUTPUT_MESSAGES_ATTRIBUTE] = JSON.stringify([outputMessage]);\n\n // Remove the text attribute since it's now captured in gen_ai.output.messages\n // Note: tool calls attribute is deleted above only if successfully parsed\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete attributes[AI_RESPONSE_TEXT_ATTRIBUTE];\n }\n}\n\n/**\n * Post-process spans emitted by the Vercel AI SDK.\n */\nfunction processEndedVercelAiSpan(span: SpanJSON): void {\n const { data: attributes, origin } = span;\n\n if (origin !== 'auto.vercelai.otel') {\n return;\n }\n\n renameAttributeKey(attributes, AI_USAGE_COMPLETION_TOKENS_ATTRIBUTE, GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE);\n renameAttributeKey(attributes, AI_USAGE_PROMPT_TOKENS_ATTRIBUTE, GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE);\n renameAttributeKey(attributes, AI_USAGE_CACHED_INPUT_TOKENS_ATTRIBUTE, GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE);\n\n // Parent spans (ai.streamText, ai.streamObject, etc.) use inputTokens/outputTokens instead of promptTokens/completionTokens\n renameAttributeKey(attributes, 'ai.usage.inputTokens', GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE);\n renameAttributeKey(attributes, 'ai.usage.outputTokens', GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE);\n\n // Embedding spans use ai.usage.tokens instead of promptTokens/completionTokens\n renameAttributeKey(attributes, AI_USAGE_TOKENS_ATTRIBUTE, GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE);\n\n // AI SDK uses avgOutputTokensPerSecond, map to our expected attribute name\n renameAttributeKey(attributes, 'ai.response.avgOutputTokensPerSecond', 'ai.response.avgCompletionTokensPerSecond');\n\n // Input tokens is the sum of prompt tokens and cached input tokens\n if (\n typeof attributes[GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE] === 'number' &&\n typeof attributes[GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE] === 'number'\n ) {\n attributes[GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE] =\n attributes[GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE] + attributes[GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE];\n }\n\n // Compute total tokens from input + output (embeddings may only have input tokens)\n if (typeof attributes[GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE] === 'number') {\n const outputTokens =\n typeof attributes[GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE] === 'number'\n ? attributes[GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE]\n : 0;\n attributes[GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE] = outputTokens + attributes[GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE];\n }\n\n // Convert the available tools array to a JSON string\n if (attributes[AI_PROMPT_TOOLS_ATTRIBUTE] && Array.isArray(attributes[AI_PROMPT_TOOLS_ATTRIBUTE])) {\n attributes[AI_PROMPT_TOOLS_ATTRIBUTE] = convertAvailableToolsToJsonString(\n attributes[AI_PROMPT_TOOLS_ATTRIBUTE] as unknown[],\n );\n }\n\n // Rename AI SDK attributes to standardized gen_ai attributes\n // Map operation.name to OpenTelemetry semantic convention values\n if (attributes[OPERATION_NAME_ATTRIBUTE]) {\n const operationName = mapVercelAiOperationName(attributes[OPERATION_NAME_ATTRIBUTE] as string);\n attributes[GEN_AI_OPERATION_NAME_ATTRIBUTE] = operationName;\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete attributes[OPERATION_NAME_ATTRIBUTE];\n }\n renameAttributeKey(attributes, AI_PROMPT_MESSAGES_ATTRIBUTE, GEN_AI_INPUT_MESSAGES_ATTRIBUTE);\n\n // Build gen_ai.output.messages from response text and/or tool calls\n // Note: buildOutputMessages also removes the source attributes when output is successfully generated\n buildOutputMessages(attributes);\n\n renameAttributeKey(attributes, AI_RESPONSE_OBJECT_ATTRIBUTE, 'gen_ai.response.object');\n renameAttributeKey(attributes, AI_PROMPT_TOOLS_ATTRIBUTE, 'gen_ai.request.available_tools');\n\n renameAttributeKey(attributes, AI_TOOL_CALL_ARGS_ATTRIBUTE, GEN_AI_TOOL_INPUT_ATTRIBUTE);\n renameAttributeKey(attributes, AI_TOOL_CALL_RESULT_ATTRIBUTE, GEN_AI_TOOL_OUTPUT_ATTRIBUTE);\n\n renameAttributeKey(attributes, AI_SCHEMA_ATTRIBUTE, 'gen_ai.request.schema');\n renameAttributeKey(attributes, AI_MODEL_ID_ATTRIBUTE, GEN_AI_REQUEST_MODEL_ATTRIBUTE);\n\n // Map embedding input: ai.values → gen_ai.embeddings.input\n // Vercel AI SDK JSON-stringifies each value individually, so we parse each element back.\n // Single embed gets unwrapped to a plain value; batch embedMany stays as a JSON array.\n if (Array.isArray(attributes[AI_VALUES_ATTRIBUTE])) {\n const parsed = (attributes[AI_VALUES_ATTRIBUTE] as string[]).map(v => {\n try {\n return JSON.parse(v);\n } catch {\n return v;\n }\n });\n attributes[GEN_AI_EMBEDDINGS_INPUT_ATTRIBUTE] = parsed.length === 1 ? parsed[0] : JSON.stringify(parsed);\n }\n\n addProviderMetadataToAttributes(attributes);\n\n // Change attributes namespaced with `ai.X` to `vercel.ai.X`\n for (const key of Object.keys(attributes)) {\n if (key.startsWith('ai.')) {\n renameAttributeKey(attributes, key, `vercel.${key}`);\n }\n }\n}\n\n/**\n * Renames an attribute key in the provided attributes object if the old key exists.\n * This function safely handles null and undefined values.\n */\nfunction renameAttributeKey(attributes: Record<string, unknown>, oldKey: string, newKey: string): void {\n if (attributes[oldKey] != null) {\n attributes[newKey] = attributes[oldKey];\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete attributes[oldKey];\n }\n}\n\nfunction processToolCallSpan(span: Span, attributes: SpanAttributes): void {\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.vercelai.otel');\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, 'gen_ai.execute_tool');\n span.setAttribute(GEN_AI_OPERATION_NAME_ATTRIBUTE, 'execute_tool');\n renameAttributeKey(attributes, AI_TOOL_CALL_NAME_ATTRIBUTE, GEN_AI_TOOL_NAME_ATTRIBUTE);\n renameAttributeKey(attributes, AI_TOOL_CALL_ID_ATTRIBUTE, GEN_AI_TOOL_CALL_ID_ATTRIBUTE);\n\n // Store the span context in our global map using the tool call ID.\n // This allows us to capture tool errors and link them to the correct span\n // without retaining the full Span object in memory.\n const toolCallId = attributes[GEN_AI_TOOL_CALL_ID_ATTRIBUTE];\n\n if (typeof toolCallId === 'string') {\n toolCallSpanContextMap.set(toolCallId, span.spanContext());\n }\n\n // https://opentelemetry.io/docs/specs/semconv/registry/attributes/gen-ai/#gen-ai-tool-type\n if (!attributes[GEN_AI_TOOL_TYPE_ATTRIBUTE]) {\n span.setAttribute(GEN_AI_TOOL_TYPE_ATTRIBUTE, 'function');\n }\n const toolName = attributes[GEN_AI_TOOL_NAME_ATTRIBUTE];\n if (toolName) {\n span.updateName(`execute_tool ${toolName}`);\n }\n}\n\nfunction processGenerateSpan(span: Span, name: string, attributes: SpanAttributes): void {\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.vercelai.otel');\n\n const nameWthoutAi = name.replace('ai.', '');\n span.setAttribute('ai.pipeline.name', nameWthoutAi);\n span.updateName(nameWthoutAi);\n\n const functionId = attributes[AI_TELEMETRY_FUNCTION_ID_ATTRIBUTE];\n if (functionId && typeof functionId === 'string') {\n span.setAttribute('gen_ai.function_id', functionId);\n }\n\n requestMessagesFromPrompt(span, attributes);\n\n if (attributes[AI_MODEL_ID_ATTRIBUTE] && !attributes[GEN_AI_RESPONSE_MODEL_ATTRIBUTE]) {\n span.setAttribute(GEN_AI_RESPONSE_MODEL_ATTRIBUTE, attributes[AI_MODEL_ID_ATTRIBUTE]);\n }\n span.setAttribute('ai.streaming', name.includes('stream'));\n\n // Set the op based on the span name\n const op = getSpanOpFromName(name);\n if (op) {\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, op);\n }\n\n // For invoke_agent pipeline spans, use 'invoke_agent' as the description\n // to be consistent with other AI integrations (e.g. LangGraph)\n if (INVOKE_AGENT_OPS.has(name)) {\n if (functionId && typeof functionId === 'string') {\n span.updateName(`invoke_agent ${functionId}`);\n } else {\n span.updateName('invoke_agent');\n }\n return;\n }\n\n const modelId = attributes[AI_MODEL_ID_ATTRIBUTE];\n if (modelId) {\n const doSpanPrefix = GENERATE_CONTENT_OPS.has(name) ? 'generate_content' : DO_SPAN_NAME_PREFIX[name];\n if (doSpanPrefix) {\n span.updateName(`${doSpanPrefix} ${modelId}`);\n }\n }\n}\n\n/**\n * Add event processors to the given client to process Vercel AI spans.\n */\nexport function addVercelAiProcessors(client: Client): void {\n client.on('spanStart', onVercelAiSpanStart);\n // Note: We cannot do this on `spanEnd`, because the span cannot be mutated anymore at this point\n client.addEventProcessor(Object.assign(vercelAiEventProcessor, { id: 'VercelAiEventProcessor' }));\n}\n\nfunction addProviderMetadataToAttributes(attributes: SpanAttributes): void {\n const providerMetadata = attributes[AI_RESPONSE_PROVIDER_METADATA_ATTRIBUTE] as string | undefined;\n if (providerMetadata) {\n try {\n const providerMetadataObject = JSON.parse(providerMetadata) as ProviderMetadata;\n\n // Handle OpenAI metadata (v5 uses 'openai', v6 Azure Responses API uses 'azure')\n const openaiMetadata: OpenAiProviderMetadata | undefined =\n providerMetadataObject.openai ?? providerMetadataObject.azure;\n if (openaiMetadata) {\n setAttributeIfDefined(\n attributes,\n GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE,\n openaiMetadata.cachedPromptTokens,\n );\n setAttributeIfDefined(attributes, 'gen_ai.usage.output_tokens.reasoning', openaiMetadata.reasoningTokens);\n setAttributeIfDefined(\n attributes,\n 'gen_ai.usage.output_tokens.prediction_accepted',\n openaiMetadata.acceptedPredictionTokens,\n );\n setAttributeIfDefined(\n attributes,\n 'gen_ai.usage.output_tokens.prediction_rejected',\n openaiMetadata.rejectedPredictionTokens,\n );\n setAttributeIfDefined(attributes, 'gen_ai.conversation.id', openaiMetadata.responseId);\n }\n\n if (providerMetadataObject.anthropic) {\n const cachedInputTokens =\n providerMetadataObject.anthropic.usage?.cache_read_input_tokens ??\n providerMetadataObject.anthropic.cacheReadInputTokens;\n setAttributeIfDefined(attributes, GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE, cachedInputTokens);\n\n const cacheWriteInputTokens =\n providerMetadataObject.anthropic.usage?.cache_creation_input_tokens ??\n providerMetadataObject.anthropic.cacheCreationInputTokens;\n setAttributeIfDefined(attributes, GEN_AI_USAGE_INPUT_TOKENS_CACHE_WRITE_ATTRIBUTE, cacheWriteInputTokens);\n }\n\n if (providerMetadataObject.bedrock?.usage) {\n setAttributeIfDefined(\n attributes,\n GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE,\n providerMetadataObject.bedrock.usage.cacheReadInputTokens,\n );\n setAttributeIfDefined(\n attributes,\n GEN_AI_USAGE_INPUT_TOKENS_CACHE_WRITE_ATTRIBUTE,\n providerMetadataObject.bedrock.usage.cacheWriteInputTokens,\n );\n }\n\n if (providerMetadataObject.deepseek) {\n setAttributeIfDefined(\n attributes,\n GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE,\n providerMetadataObject.deepseek.promptCacheHitTokens,\n );\n setAttributeIfDefined(\n attributes,\n 'gen_ai.usage.input_tokens.cache_miss',\n providerMetadataObject.deepseek.promptCacheMissTokens,\n );\n }\n } catch {\n // Ignore\n }\n }\n}\n\n/**\n * Sets an attribute only if the value is not null or undefined.\n */\nfunction setAttributeIfDefined(attributes: SpanAttributes, key: string, value: SpanAttributeValue | undefined): void {\n if (value != null) {\n attributes[key] = value;\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../../../src/tracing/vercel-ai/index.ts"],"sourcesContent":["/* eslint-disable max-lines */\nimport type { Client } from '../../client';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '../../semanticAttributes';\nimport type { Event } from '../../types-hoist/event';\nimport type { Span, SpanAttributes, SpanAttributeValue, SpanJSON } from '../../types-hoist/span';\nimport { spanToJSON } from '../../utils/spanUtils';\nimport {\n GEN_AI_EMBEDDINGS_INPUT_ATTRIBUTE,\n GEN_AI_INPUT_MESSAGES_ATTRIBUTE,\n GEN_AI_OPERATION_NAME_ATTRIBUTE,\n GEN_AI_OUTPUT_MESSAGES_ATTRIBUTE,\n GEN_AI_REQUEST_MODEL_ATTRIBUTE,\n GEN_AI_RESPONSE_MODEL_ATTRIBUTE,\n GEN_AI_TOOL_CALL_ID_ATTRIBUTE,\n GEN_AI_TOOL_INPUT_ATTRIBUTE,\n GEN_AI_TOOL_NAME_ATTRIBUTE,\n GEN_AI_TOOL_OUTPUT_ATTRIBUTE,\n GEN_AI_TOOL_TYPE_ATTRIBUTE,\n GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE,\n GEN_AI_USAGE_INPUT_TOKENS_CACHE_WRITE_ATTRIBUTE,\n GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE,\n GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE,\n GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE,\n} from '../ai/gen-ai-attributes';\nimport {\n DO_SPAN_NAME_PREFIX,\n EMBEDDINGS_OPS,\n GENERATE_CONTENT_OPS,\n INVOKE_AGENT_OPS,\n RERANK_OPS,\n toolCallSpanContextMap,\n} from './constants';\nimport type { TokenSummary } from './types';\nimport {\n accumulateTokensForParent,\n applyAccumulatedTokens,\n applyToolDescriptionsAndTokens,\n convertAvailableToolsToJsonString,\n getSpanOpFromName,\n requestMessagesFromPrompt,\n} from './utils';\nimport type { OpenAiProviderMetadata, ProviderMetadata } from './vercel-ai-attributes';\nimport {\n AI_MODEL_ID_ATTRIBUTE,\n AI_OPERATION_ID_ATTRIBUTE,\n AI_PROMPT_MESSAGES_ATTRIBUTE,\n AI_PROMPT_TOOLS_ATTRIBUTE,\n AI_RESPONSE_FINISH_REASON_ATTRIBUTE,\n AI_RESPONSE_OBJECT_ATTRIBUTE,\n AI_RESPONSE_PROVIDER_METADATA_ATTRIBUTE,\n AI_RESPONSE_TEXT_ATTRIBUTE,\n AI_RESPONSE_TOOL_CALLS_ATTRIBUTE,\n AI_SCHEMA_ATTRIBUTE,\n AI_TELEMETRY_FUNCTION_ID_ATTRIBUTE,\n AI_TOOL_CALL_ARGS_ATTRIBUTE,\n AI_TOOL_CALL_ID_ATTRIBUTE,\n AI_TOOL_CALL_NAME_ATTRIBUTE,\n AI_TOOL_CALL_RESULT_ATTRIBUTE,\n AI_USAGE_CACHED_INPUT_TOKENS_ATTRIBUTE,\n AI_USAGE_COMPLETION_TOKENS_ATTRIBUTE,\n AI_USAGE_PROMPT_TOKENS_ATTRIBUTE,\n AI_USAGE_TOKENS_ATTRIBUTE,\n AI_VALUES_ATTRIBUTE,\n OPERATION_NAME_ATTRIBUTE,\n} from './vercel-ai-attributes';\n\n/**\n * Maps Vercel AI SDK operation names to OpenTelemetry semantic convention values\n * @see https://opentelemetry.io/docs/specs/semconv/gen-ai/gen-ai-spans/#llm-request-spans\n */\nfunction mapVercelAiOperationName(operationName: string): string {\n // Top-level pipeline operations map to invoke_agent\n if (INVOKE_AGENT_OPS.has(operationName)) {\n return 'invoke_agent';\n }\n // .do* operations are the actual LLM calls\n if (GENERATE_CONTENT_OPS.has(operationName)) {\n return 'generate_content';\n }\n if (EMBEDDINGS_OPS.has(operationName)) {\n return 'embeddings';\n }\n if (RERANK_OPS.has(operationName)) {\n return 'rerank';\n }\n if (operationName === 'ai.toolCall') {\n return 'execute_tool';\n }\n // Return the original value for unknown operations\n return operationName;\n}\n\n/**\n * Post-process spans emitted by the Vercel AI SDK.\n * This is supposed to be used in `client.on('spanStart', ...)\n */\nfunction onVercelAiSpanStart(span: Span): void {\n const { data: attributes, description: name } = spanToJSON(span);\n\n if (!name) {\n return;\n }\n\n // Tool call spans\n // https://ai-sdk.dev/docs/ai-sdk-core/telemetry#tool-call-spans\n if (attributes[AI_TOOL_CALL_NAME_ATTRIBUTE] && attributes[AI_TOOL_CALL_ID_ATTRIBUTE] && name === 'ai.toolCall') {\n processToolCallSpan(span, attributes);\n return;\n }\n\n // V6+ Check if this is a Vercel AI span by checking if the operation ID attribute is present.\n // V5+ Check if this is a Vercel AI span by name pattern.\n if (!attributes[AI_OPERATION_ID_ATTRIBUTE] && !name.startsWith('ai.')) {\n return;\n }\n\n processGenerateSpan(span, name, attributes);\n}\n\nfunction vercelAiEventProcessor(event: Event): Event {\n if (event.type === 'transaction' && event.spans) {\n // Map to accumulate token data by parent span ID\n const tokenAccumulator: Map<string, TokenSummary> = new Map();\n\n // First pass: process all spans and accumulate token data\n for (const span of event.spans) {\n processEndedVercelAiSpan(span);\n\n // Accumulate token data for parent spans\n accumulateTokensForParent(span, tokenAccumulator);\n }\n\n // Second pass: apply tool descriptions and accumulated tokens\n applyToolDescriptionsAndTokens(event.spans, tokenAccumulator);\n\n // Also apply to root when it is the invoke_agent pipeline\n const trace = event.contexts?.trace;\n if (trace?.op === 'gen_ai.invoke_agent') {\n applyAccumulatedTokens(trace, tokenAccumulator);\n }\n }\n\n return event;\n}\n\n/**\n * Tool call structure from Vercel AI SDK\n * Note: V5/V6 use 'input' for arguments, V4 and earlier use 'args'\n */\ninterface VercelToolCall {\n toolCallId: string;\n toolName: string;\n input?: Record<string, unknown> | string; // V5/V6\n args?: string; // V4 and earlier\n}\n\n/**\n * Normalize finish reason to match OpenTelemetry semantic conventions.\n * Valid values: \"stop\", \"length\", \"content_filter\", \"tool_call\", \"error\"\n *\n * Vercel AI SDK uses \"tool-calls\" (plural, with hyphen) which we map to \"tool_call\".\n */\nfunction normalizeFinishReason(finishReason: unknown): string {\n if (typeof finishReason !== 'string') {\n return 'stop';\n }\n\n // Map Vercel AI SDK finish reasons to OpenTelemetry semantic convention values\n switch (finishReason) {\n case 'tool-calls':\n return 'tool_call';\n case 'stop':\n case 'length':\n case 'content_filter':\n case 'error':\n return finishReason;\n default:\n // For unknown values, return as-is (schema allows arbitrary strings)\n return finishReason;\n }\n}\n\n/**\n * Build gen_ai.output.messages from ai.response.text and/or ai.response.toolCalls\n *\n * Format follows OpenTelemetry semantic conventions:\n * [{\"role\": \"assistant\", \"parts\": [...], \"finish_reason\": \"stop\"}]\n *\n * Parts can be:\n * - {\"type\": \"text\", \"content\": \"...\"}\n * - {\"type\": \"tool_call\", \"id\": \"...\", \"name\": \"...\", \"arguments\": \"...\"}\n */\nfunction buildOutputMessages(attributes: Record<string, unknown>): void {\n const responseText = attributes[AI_RESPONSE_TEXT_ATTRIBUTE];\n const responseToolCalls = attributes[AI_RESPONSE_TOOL_CALLS_ATTRIBUTE];\n const finishReason = attributes[AI_RESPONSE_FINISH_REASON_ATTRIBUTE];\n\n // Skip if neither text nor tool calls are present\n if (responseText == null && responseToolCalls == null) {\n return;\n }\n\n const parts: Array<Record<string, unknown>> = [];\n\n // Add text part if present\n if (typeof responseText === 'string' && responseText.length > 0) {\n parts.push({\n type: 'text',\n content: responseText,\n });\n }\n\n // Add tool call parts if present\n if (responseToolCalls != null) {\n try {\n // Tool calls can be a string (JSON) or already parsed array\n const toolCalls: VercelToolCall[] =\n typeof responseToolCalls === 'string' ? JSON.parse(responseToolCalls) : responseToolCalls;\n\n if (Array.isArray(toolCalls)) {\n for (const toolCall of toolCalls) {\n // V5/V6 use 'input', V4 and earlier use 'args'\n const args = toolCall.input ?? toolCall.args;\n parts.push({\n type: 'tool_call',\n id: toolCall.toolCallId,\n name: toolCall.toolName,\n // Handle undefined args: JSON.stringify(undefined) returns undefined, not a string,\n // which would cause the property to be omitted from the final JSON output\n arguments: typeof args === 'string' ? args : JSON.stringify(args ?? {}),\n });\n }\n // Only delete tool calls attribute if we successfully processed them\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete attributes[AI_RESPONSE_TOOL_CALLS_ATTRIBUTE];\n }\n } catch {\n // Ignore parsing errors - tool calls attribute is preserved\n }\n }\n\n // Only set output messages and delete text attribute if we have parts\n if (parts.length > 0) {\n const outputMessage = {\n role: 'assistant',\n parts,\n finish_reason: normalizeFinishReason(finishReason),\n };\n\n attributes[GEN_AI_OUTPUT_MESSAGES_ATTRIBUTE] = JSON.stringify([outputMessage]);\n\n // Remove the text attribute since it's now captured in gen_ai.output.messages\n // Note: tool calls attribute is deleted above only if successfully parsed\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete attributes[AI_RESPONSE_TEXT_ATTRIBUTE];\n }\n}\n\n/**\n * Post-process spans emitted by the Vercel AI SDK.\n */\nfunction processEndedVercelAiSpan(span: SpanJSON): void {\n const { data: attributes, origin } = span;\n\n if (origin !== 'auto.vercelai.otel') {\n return;\n }\n\n // The Vercel AI SDK sets span status to raw error message strings.\n // Any such value should be normalized to a SpanStatusType value. We pick internal_error as it is the most generic.\n if (span.status && span.status !== 'ok') {\n span.status = 'internal_error';\n }\n\n renameAttributeKey(attributes, AI_USAGE_COMPLETION_TOKENS_ATTRIBUTE, GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE);\n renameAttributeKey(attributes, AI_USAGE_PROMPT_TOKENS_ATTRIBUTE, GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE);\n renameAttributeKey(attributes, AI_USAGE_CACHED_INPUT_TOKENS_ATTRIBUTE, GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE);\n\n // Parent spans (ai.streamText, ai.streamObject, etc.) use inputTokens/outputTokens instead of promptTokens/completionTokens\n renameAttributeKey(attributes, 'ai.usage.inputTokens', GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE);\n renameAttributeKey(attributes, 'ai.usage.outputTokens', GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE);\n\n // Embedding spans use ai.usage.tokens instead of promptTokens/completionTokens\n renameAttributeKey(attributes, AI_USAGE_TOKENS_ATTRIBUTE, GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE);\n\n // AI SDK uses avgOutputTokensPerSecond, map to our expected attribute name\n renameAttributeKey(attributes, 'ai.response.avgOutputTokensPerSecond', 'ai.response.avgCompletionTokensPerSecond');\n\n // Input tokens is the sum of prompt tokens and cached input tokens\n if (\n typeof attributes[GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE] === 'number' &&\n typeof attributes[GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE] === 'number'\n ) {\n attributes[GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE] =\n attributes[GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE] + attributes[GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE];\n }\n\n // Compute total tokens from input + output (embeddings may only have input tokens)\n if (typeof attributes[GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE] === 'number') {\n const outputTokens =\n typeof attributes[GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE] === 'number'\n ? attributes[GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE]\n : 0;\n attributes[GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE] = outputTokens + attributes[GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE];\n }\n\n // Convert the available tools array to a JSON string\n if (attributes[AI_PROMPT_TOOLS_ATTRIBUTE] && Array.isArray(attributes[AI_PROMPT_TOOLS_ATTRIBUTE])) {\n attributes[AI_PROMPT_TOOLS_ATTRIBUTE] = convertAvailableToolsToJsonString(\n attributes[AI_PROMPT_TOOLS_ATTRIBUTE] as unknown[],\n );\n }\n\n // Rename AI SDK attributes to standardized gen_ai attributes\n // Map operation.name to OpenTelemetry semantic convention values\n if (attributes[OPERATION_NAME_ATTRIBUTE]) {\n const operationName = mapVercelAiOperationName(attributes[OPERATION_NAME_ATTRIBUTE] as string);\n attributes[GEN_AI_OPERATION_NAME_ATTRIBUTE] = operationName;\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete attributes[OPERATION_NAME_ATTRIBUTE];\n }\n renameAttributeKey(attributes, AI_PROMPT_MESSAGES_ATTRIBUTE, GEN_AI_INPUT_MESSAGES_ATTRIBUTE);\n\n // Build gen_ai.output.messages from response text and/or tool calls\n // Note: buildOutputMessages also removes the source attributes when output is successfully generated\n buildOutputMessages(attributes);\n\n renameAttributeKey(attributes, AI_RESPONSE_OBJECT_ATTRIBUTE, 'gen_ai.response.object');\n renameAttributeKey(attributes, AI_PROMPT_TOOLS_ATTRIBUTE, 'gen_ai.request.available_tools');\n\n renameAttributeKey(attributes, AI_TOOL_CALL_ARGS_ATTRIBUTE, GEN_AI_TOOL_INPUT_ATTRIBUTE);\n renameAttributeKey(attributes, AI_TOOL_CALL_RESULT_ATTRIBUTE, GEN_AI_TOOL_OUTPUT_ATTRIBUTE);\n\n renameAttributeKey(attributes, AI_SCHEMA_ATTRIBUTE, 'gen_ai.request.schema');\n renameAttributeKey(attributes, AI_MODEL_ID_ATTRIBUTE, GEN_AI_REQUEST_MODEL_ATTRIBUTE);\n\n // Map embedding input: ai.values → gen_ai.embeddings.input\n // Vercel AI SDK JSON-stringifies each value individually, so we parse each element back.\n // Single embed gets unwrapped to a plain value; batch embedMany stays as a JSON array.\n if (Array.isArray(attributes[AI_VALUES_ATTRIBUTE])) {\n const parsed = (attributes[AI_VALUES_ATTRIBUTE] as string[]).map(v => {\n try {\n return JSON.parse(v);\n } catch {\n return v;\n }\n });\n attributes[GEN_AI_EMBEDDINGS_INPUT_ATTRIBUTE] = parsed.length === 1 ? parsed[0] : JSON.stringify(parsed);\n }\n\n addProviderMetadataToAttributes(attributes);\n\n // Change attributes namespaced with `ai.X` to `vercel.ai.X`\n for (const key of Object.keys(attributes)) {\n if (key.startsWith('ai.')) {\n renameAttributeKey(attributes, key, `vercel.${key}`);\n }\n }\n}\n\n/**\n * Renames an attribute key in the provided attributes object if the old key exists.\n * This function safely handles null and undefined values.\n */\nfunction renameAttributeKey(attributes: Record<string, unknown>, oldKey: string, newKey: string): void {\n if (attributes[oldKey] != null) {\n attributes[newKey] = attributes[oldKey];\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete attributes[oldKey];\n }\n}\n\nfunction processToolCallSpan(span: Span, attributes: SpanAttributes): void {\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.vercelai.otel');\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, 'gen_ai.execute_tool');\n span.setAttribute(GEN_AI_OPERATION_NAME_ATTRIBUTE, 'execute_tool');\n renameAttributeKey(attributes, AI_TOOL_CALL_NAME_ATTRIBUTE, GEN_AI_TOOL_NAME_ATTRIBUTE);\n renameAttributeKey(attributes, AI_TOOL_CALL_ID_ATTRIBUTE, GEN_AI_TOOL_CALL_ID_ATTRIBUTE);\n\n // Store the span context in our global map using the tool call ID.\n // This allows us to capture tool errors and link them to the correct span\n // without retaining the full Span object in memory.\n const toolCallId = attributes[GEN_AI_TOOL_CALL_ID_ATTRIBUTE];\n\n if (typeof toolCallId === 'string') {\n toolCallSpanContextMap.set(toolCallId, span.spanContext());\n }\n\n // https://opentelemetry.io/docs/specs/semconv/registry/attributes/gen-ai/#gen-ai-tool-type\n if (!attributes[GEN_AI_TOOL_TYPE_ATTRIBUTE]) {\n span.setAttribute(GEN_AI_TOOL_TYPE_ATTRIBUTE, 'function');\n }\n const toolName = attributes[GEN_AI_TOOL_NAME_ATTRIBUTE];\n if (toolName) {\n span.updateName(`execute_tool ${toolName}`);\n }\n}\n\nfunction processGenerateSpan(span: Span, name: string, attributes: SpanAttributes): void {\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.vercelai.otel');\n\n const nameWthoutAi = name.replace('ai.', '');\n span.setAttribute('ai.pipeline.name', nameWthoutAi);\n span.updateName(nameWthoutAi);\n\n const functionId = attributes[AI_TELEMETRY_FUNCTION_ID_ATTRIBUTE];\n if (functionId && typeof functionId === 'string') {\n span.setAttribute('gen_ai.function_id', functionId);\n }\n\n requestMessagesFromPrompt(span, attributes);\n\n if (attributes[AI_MODEL_ID_ATTRIBUTE] && !attributes[GEN_AI_RESPONSE_MODEL_ATTRIBUTE]) {\n span.setAttribute(GEN_AI_RESPONSE_MODEL_ATTRIBUTE, attributes[AI_MODEL_ID_ATTRIBUTE]);\n }\n span.setAttribute('ai.streaming', name.includes('stream'));\n\n // Set the op based on the span name\n const op = getSpanOpFromName(name);\n if (op) {\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, op);\n }\n\n // For invoke_agent pipeline spans, use 'invoke_agent' as the description\n // to be consistent with other AI integrations (e.g. LangGraph)\n if (INVOKE_AGENT_OPS.has(name)) {\n if (functionId && typeof functionId === 'string') {\n span.updateName(`invoke_agent ${functionId}`);\n } else {\n span.updateName('invoke_agent');\n }\n return;\n }\n\n const modelId = attributes[AI_MODEL_ID_ATTRIBUTE];\n if (modelId) {\n const doSpanPrefix = GENERATE_CONTENT_OPS.has(name) ? 'generate_content' : DO_SPAN_NAME_PREFIX[name];\n if (doSpanPrefix) {\n span.updateName(`${doSpanPrefix} ${modelId}`);\n }\n }\n}\n\n/**\n * Add event processors to the given client to process Vercel AI spans.\n */\nexport function addVercelAiProcessors(client: Client): void {\n client.on('spanStart', onVercelAiSpanStart);\n // Note: We cannot do this on `spanEnd`, because the span cannot be mutated anymore at this point\n client.addEventProcessor(Object.assign(vercelAiEventProcessor, { id: 'VercelAiEventProcessor' }));\n}\n\nfunction addProviderMetadataToAttributes(attributes: SpanAttributes): void {\n const providerMetadata = attributes[AI_RESPONSE_PROVIDER_METADATA_ATTRIBUTE] as string | undefined;\n if (providerMetadata) {\n try {\n const providerMetadataObject = JSON.parse(providerMetadata) as ProviderMetadata;\n\n // Handle OpenAI metadata (v5 uses 'openai', v6 Azure Responses API uses 'azure')\n const openaiMetadata: OpenAiProviderMetadata | undefined =\n providerMetadataObject.openai ?? providerMetadataObject.azure;\n if (openaiMetadata) {\n setAttributeIfDefined(\n attributes,\n GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE,\n openaiMetadata.cachedPromptTokens,\n );\n setAttributeIfDefined(attributes, 'gen_ai.usage.output_tokens.reasoning', openaiMetadata.reasoningTokens);\n setAttributeIfDefined(\n attributes,\n 'gen_ai.usage.output_tokens.prediction_accepted',\n openaiMetadata.acceptedPredictionTokens,\n );\n setAttributeIfDefined(\n attributes,\n 'gen_ai.usage.output_tokens.prediction_rejected',\n openaiMetadata.rejectedPredictionTokens,\n );\n if (!attributes['gen_ai.conversation.id']) {\n setAttributeIfDefined(attributes, 'gen_ai.conversation.id', openaiMetadata.responseId);\n }\n }\n\n if (providerMetadataObject.anthropic) {\n const cachedInputTokens =\n providerMetadataObject.anthropic.usage?.cache_read_input_tokens ??\n providerMetadataObject.anthropic.cacheReadInputTokens;\n setAttributeIfDefined(attributes, GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE, cachedInputTokens);\n\n const cacheWriteInputTokens =\n providerMetadataObject.anthropic.usage?.cache_creation_input_tokens ??\n providerMetadataObject.anthropic.cacheCreationInputTokens;\n setAttributeIfDefined(attributes, GEN_AI_USAGE_INPUT_TOKENS_CACHE_WRITE_ATTRIBUTE, cacheWriteInputTokens);\n }\n\n if (providerMetadataObject.bedrock?.usage) {\n setAttributeIfDefined(\n attributes,\n GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE,\n providerMetadataObject.bedrock.usage.cacheReadInputTokens,\n );\n setAttributeIfDefined(\n attributes,\n GEN_AI_USAGE_INPUT_TOKENS_CACHE_WRITE_ATTRIBUTE,\n providerMetadataObject.bedrock.usage.cacheWriteInputTokens,\n );\n }\n\n if (providerMetadataObject.deepseek) {\n setAttributeIfDefined(\n attributes,\n GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE,\n providerMetadataObject.deepseek.promptCacheHitTokens,\n );\n setAttributeIfDefined(\n attributes,\n 'gen_ai.usage.input_tokens.cache_miss',\n providerMetadataObject.deepseek.promptCacheMissTokens,\n );\n }\n } catch {\n // Ignore\n }\n }\n}\n\n/**\n * Sets an attribute only if the value is not null or undefined.\n */\nfunction setAttributeIfDefined(attributes: SpanAttributes, key: string, value: SpanAttributeValue | undefined): void {\n if (value != null) {\n attributes[key] = value;\n }\n}\n"],"names":[],"mappings":"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"}