Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 20s
Build & Deploy / 🧪 QA (push) Failing after 34s
Build & Deploy / 🏗️ Build (push) Has started running
Build & Deploy / 🚀 Deploy (push) Has been cancelled
Build & Deploy / 🧪 Smoke Test (push) Has been cancelled
Build & Deploy / ⚡ Lighthouse (push) Has been cancelled
Build & Deploy / 🔔 Notify (push) Has been cancelled
1 line
22 KiB
Plaintext
1 line
22 KiB
Plaintext
{"version":3,"file":"index.js","sources":["../../../../src/tracing/openai/index.ts"],"sourcesContent":["import { getClient } from '../../currentScopes';\nimport { DEBUG_BUILD } from '../../debug-build';\nimport { captureException } from '../../exports';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '../../semanticAttributes';\nimport { SPAN_STATUS_ERROR } from '../../tracing';\nimport { startSpan, startSpanManual } from '../../tracing/trace';\nimport type { Span, SpanAttributeValue } from '../../types-hoist/span';\nimport { debug } from '../../utils/debug-logger';\nimport { isThenable } from '../../utils/is';\nimport {\n GEN_AI_EMBEDDINGS_INPUT_ATTRIBUTE,\n GEN_AI_INPUT_MESSAGES_ATTRIBUTE,\n GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE,\n GEN_AI_OPERATION_NAME_ATTRIBUTE,\n GEN_AI_REQUEST_AVAILABLE_TOOLS_ATTRIBUTE,\n GEN_AI_REQUEST_MODEL_ATTRIBUTE,\n GEN_AI_RESPONSE_TEXT_ATTRIBUTE,\n GEN_AI_SYSTEM_ATTRIBUTE,\n GEN_AI_SYSTEM_INSTRUCTIONS_ATTRIBUTE,\n OPENAI_OPERATIONS,\n} from '../ai/gen-ai-attributes';\nimport { extractSystemInstructions, getTruncatedJsonString } from '../ai/utils';\nimport { instrumentStream } from './streaming';\nimport type {\n ChatCompletionChunk,\n InstrumentedMethod,\n OpenAiOptions,\n OpenAiResponse,\n OpenAIStream,\n ResponseStreamingEvent,\n} from './types';\nimport {\n addChatCompletionAttributes,\n addConversationAttributes,\n addEmbeddingsAttributes,\n addResponsesApiAttributes,\n buildMethodPath,\n extractRequestParameters,\n getOperationName,\n getSpanOperation,\n isChatCompletionResponse,\n isConversationResponse,\n isEmbeddingsResponse,\n isResponsesApiResponse,\n shouldInstrument,\n} from './utils';\n\n/**\n * Extract available tools from request parameters\n */\nfunction extractAvailableTools(params: Record<string, unknown>): string | undefined {\n const tools = Array.isArray(params.tools) ? params.tools : [];\n const hasWebSearchOptions = params.web_search_options && typeof params.web_search_options === 'object';\n const webSearchOptions = hasWebSearchOptions\n ? [{ type: 'web_search_options', ...(params.web_search_options as Record<string, unknown>) }]\n : [];\n\n const availableTools = [...tools, ...webSearchOptions];\n if (availableTools.length === 0) {\n return undefined;\n }\n\n try {\n return JSON.stringify(availableTools);\n } catch (error) {\n DEBUG_BUILD && debug.error('Failed to serialize OpenAI tools:', error);\n return undefined;\n }\n}\n\n/**\n * Extract request attributes from method arguments\n */\nfunction extractRequestAttributes(args: unknown[], methodPath: string): Record<string, unknown> {\n const attributes: Record<string, unknown> = {\n [GEN_AI_SYSTEM_ATTRIBUTE]: 'openai',\n [GEN_AI_OPERATION_NAME_ATTRIBUTE]: getOperationName(methodPath),\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ai.openai',\n };\n\n if (args.length > 0 && typeof args[0] === 'object' && args[0] !== null) {\n const params = args[0] as Record<string, unknown>;\n\n const availableTools = extractAvailableTools(params);\n if (availableTools) {\n attributes[GEN_AI_REQUEST_AVAILABLE_TOOLS_ATTRIBUTE] = availableTools;\n }\n\n Object.assign(attributes, extractRequestParameters(params));\n } else {\n attributes[GEN_AI_REQUEST_MODEL_ATTRIBUTE] = 'unknown';\n }\n\n return attributes;\n}\n\n/**\n * Add response attributes to spans\n * This supports Chat Completion, Responses API, Embeddings, and Conversations API responses\n */\nfunction addResponseAttributes(span: Span, result: unknown, recordOutputs?: boolean): void {\n if (!result || typeof result !== 'object') return;\n\n const response = result as OpenAiResponse;\n\n if (isChatCompletionResponse(response)) {\n addChatCompletionAttributes(span, response, recordOutputs);\n if (recordOutputs && response.choices?.length) {\n const responseTexts = response.choices.map(choice => choice.message?.content || '');\n span.setAttributes({ [GEN_AI_RESPONSE_TEXT_ATTRIBUTE]: JSON.stringify(responseTexts) });\n }\n } else if (isResponsesApiResponse(response)) {\n addResponsesApiAttributes(span, response, recordOutputs);\n if (recordOutputs && response.output_text) {\n span.setAttributes({ [GEN_AI_RESPONSE_TEXT_ATTRIBUTE]: response.output_text });\n }\n } else if (isEmbeddingsResponse(response)) {\n addEmbeddingsAttributes(span, response);\n } else if (isConversationResponse(response)) {\n addConversationAttributes(span, response);\n }\n}\n\n// Extract and record AI request inputs, if present. This is intentionally separate from response attributes.\nfunction addRequestAttributes(span: Span, params: Record<string, unknown>, operationName: string): void {\n // Store embeddings input on a separate attribute and do not truncate it\n if (operationName === OPENAI_OPERATIONS.EMBEDDINGS && 'input' in params) {\n const input = params.input;\n\n // No input provided\n if (input == null) {\n return;\n }\n\n // Empty input string\n if (typeof input === 'string' && input.length === 0) {\n return;\n }\n\n // Empty array input\n if (Array.isArray(input) && input.length === 0) {\n return;\n }\n\n // Store strings as-is, arrays/objects as JSON\n span.setAttribute(GEN_AI_EMBEDDINGS_INPUT_ATTRIBUTE, typeof input === 'string' ? input : JSON.stringify(input));\n return;\n }\n\n const src = 'input' in params ? params.input : 'messages' in params ? params.messages : undefined;\n\n if (!src) {\n return;\n }\n\n if (Array.isArray(src) && src.length === 0) {\n return;\n }\n\n const { systemInstructions, filteredMessages } = extractSystemInstructions(src);\n\n if (systemInstructions) {\n span.setAttribute(GEN_AI_SYSTEM_INSTRUCTIONS_ATTRIBUTE, systemInstructions);\n }\n\n const truncatedInput = getTruncatedJsonString(filteredMessages);\n span.setAttribute(GEN_AI_INPUT_MESSAGES_ATTRIBUTE, truncatedInput);\n\n if (Array.isArray(filteredMessages)) {\n span.setAttribute(GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE, filteredMessages.length);\n } else {\n span.setAttribute(GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE, 1);\n }\n}\n\n/**\n * Creates a wrapped version of .withResponse() that replaces the data field\n * with the instrumented result while preserving metadata (response, request_id).\n */\nasync function createWithResponseWrapper<T>(\n originalWithResponse: Promise<unknown>,\n instrumentedPromise: Promise<T>,\n): Promise<unknown> {\n // Attach catch handler to originalWithResponse immediately to prevent unhandled rejection\n // If instrumentedPromise rejects first, we still need this handled\n const safeOriginalWithResponse = originalWithResponse.catch(error => {\n captureException(error, {\n mechanism: {\n handled: false,\n type: 'auto.ai.openai',\n },\n });\n throw error;\n });\n\n const instrumentedResult = await instrumentedPromise;\n const originalWrapper = await safeOriginalWithResponse;\n\n // Combine instrumented result with original metadata\n if (originalWrapper && typeof originalWrapper === 'object' && 'data' in originalWrapper) {\n return {\n ...originalWrapper,\n data: instrumentedResult,\n };\n }\n return instrumentedResult;\n}\n\n/**\n * Wraps a promise-like object to preserve additional methods (like .withResponse())\n */\nfunction wrapPromiseWithMethods<R>(originalPromiseLike: Promise<R>, instrumentedPromise: Promise<R>): Promise<R> {\n // If the original result is not thenable, return the instrumented promise\n // Should not happen with current OpenAI SDK instrumented methods, but just in case.\n if (!isThenable(originalPromiseLike)) {\n return instrumentedPromise;\n }\n\n // Create a proxy that forwards Promise methods to instrumentedPromise\n // and preserves additional methods from the original result\n return new Proxy(originalPromiseLike, {\n get(target: object, prop: string | symbol): unknown {\n // For standard Promise methods (.then, .catch, .finally, Symbol.toStringTag),\n // use instrumentedPromise to preserve Sentry instrumentation.\n // For custom methods (like .withResponse()), use the original target.\n const useInstrumentedPromise = prop in Promise.prototype || prop === Symbol.toStringTag;\n const source = useInstrumentedPromise ? instrumentedPromise : target;\n\n const value = Reflect.get(source, prop) as unknown;\n\n // Special handling for .withResponse() to preserve instrumentation\n // .withResponse() returns { data: T, response: Response, request_id: string }\n if (prop === 'withResponse' && typeof value === 'function') {\n return function wrappedWithResponse(this: unknown): unknown {\n const originalWithResponse = (value as (...args: unknown[]) => unknown).call(target);\n return createWithResponseWrapper(originalWithResponse, instrumentedPromise);\n };\n }\n\n return typeof value === 'function' ? value.bind(source) : value;\n },\n }) as Promise<R>;\n}\n\n/**\n * Instrument a method with Sentry spans\n * Following Sentry AI Agents Manual Instrumentation conventions\n * @see https://docs.sentry.io/platforms/javascript/guides/node/tracing/instrumentation/ai-agents-module/#manual-instrumentation\n */\nfunction instrumentMethod<T extends unknown[], R>(\n originalMethod: (...args: T) => Promise<R>,\n methodPath: InstrumentedMethod,\n context: unknown,\n options: OpenAiOptions,\n): (...args: T) => Promise<R> {\n return function instrumentedMethod(...args: T): Promise<R> {\n const requestAttributes = extractRequestAttributes(args, methodPath);\n const model = (requestAttributes[GEN_AI_REQUEST_MODEL_ATTRIBUTE] as string) || 'unknown';\n const operationName = getOperationName(methodPath);\n\n const params = args[0] as Record<string, unknown> | undefined;\n const isStreamRequested = params && typeof params === 'object' && params.stream === true;\n\n const spanConfig = {\n name: `${operationName} ${model}${isStreamRequested ? ' stream-response' : ''}`,\n op: getSpanOperation(methodPath),\n attributes: requestAttributes as Record<string, SpanAttributeValue>,\n };\n\n if (isStreamRequested) {\n let originalResult!: Promise<R>;\n\n const instrumentedPromise = startSpanManual(spanConfig, (span: Span) => {\n originalResult = originalMethod.apply(context, args);\n\n if (options.recordInputs && params) {\n addRequestAttributes(span, params, operationName);\n }\n\n // Return async processing\n return (async () => {\n try {\n const result = await originalResult;\n return instrumentStream(\n result as OpenAIStream<ChatCompletionChunk | ResponseStreamingEvent>,\n span,\n options.recordOutputs ?? false,\n ) as unknown as R;\n } catch (error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureException(error, {\n mechanism: {\n handled: false,\n type: 'auto.ai.openai.stream',\n data: { function: methodPath },\n },\n });\n span.end();\n throw error;\n }\n })();\n });\n\n return wrapPromiseWithMethods(originalResult, instrumentedPromise);\n }\n\n // Non-streaming\n let originalResult!: Promise<R>;\n\n const instrumentedPromise = startSpan(spanConfig, (span: Span) => {\n // Call synchronously to capture the promise\n originalResult = originalMethod.apply(context, args);\n\n if (options.recordInputs && params) {\n addRequestAttributes(span, params, operationName);\n }\n\n return originalResult.then(\n result => {\n addResponseAttributes(span, result, options.recordOutputs);\n return result;\n },\n error => {\n captureException(error, {\n mechanism: {\n handled: false,\n type: 'auto.ai.openai',\n data: { function: methodPath },\n },\n });\n throw error;\n },\n );\n });\n\n return wrapPromiseWithMethods(originalResult, instrumentedPromise);\n };\n}\n\n/**\n * Create a deep proxy for OpenAI client instrumentation\n */\nfunction createDeepProxy<T extends object>(target: T, currentPath = '', options: OpenAiOptions): T {\n return new Proxy(target, {\n get(obj: object, prop: string): unknown {\n const value = (obj as Record<string, unknown>)[prop];\n const methodPath = buildMethodPath(currentPath, String(prop));\n\n if (typeof value === 'function' && shouldInstrument(methodPath)) {\n return instrumentMethod(value as (...args: unknown[]) => Promise<unknown>, methodPath, obj, options);\n }\n\n if (typeof value === 'function') {\n // Bind non-instrumented functions to preserve the original `this` context,\n // which is required for accessing private class fields (e.g. #baseURL) in OpenAI SDK v5.\n return value.bind(obj);\n }\n\n if (value && typeof value === 'object') {\n return createDeepProxy(value, methodPath, options);\n }\n\n return value;\n },\n }) as T;\n}\n\n/**\n * Instrument an OpenAI client with Sentry tracing\n * Can be used across Node.js, Cloudflare Workers, and Vercel Edge\n */\nexport function instrumentOpenAiClient<T extends object>(client: T, options?: OpenAiOptions): T {\n const sendDefaultPii = Boolean(getClient()?.getOptions().sendDefaultPii);\n\n const _options = {\n recordInputs: sendDefaultPii,\n recordOutputs: sendDefaultPii,\n ...options,\n };\n\n return createDeepProxy(client, '', _options);\n}\n"],"names":[],"mappings":"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"} |