@sentry/core 10.47.0 → 10.49.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.
- package/build/cjs/attributes.js +43 -0
- package/build/cjs/attributes.js.map +1 -1
- package/build/cjs/client.js +13 -6
- package/build/cjs/client.js.map +1 -1
- package/build/cjs/envelope.js +4 -3
- package/build/cjs/envelope.js.map +1 -1
- package/build/cjs/fetch.js +36 -17
- package/build/cjs/fetch.js.map +1 -1
- package/build/cjs/index.js +53 -18
- package/build/cjs/index.js.map +1 -1
- package/build/cjs/integration.js +6 -0
- package/build/cjs/integration.js.map +1 -1
- package/build/cjs/integrations/conversationId.js +11 -0
- package/build/cjs/integrations/conversationId.js.map +1 -1
- package/build/cjs/integrations/express/index.js +243 -0
- package/build/cjs/integrations/express/index.js.map +1 -0
- package/build/cjs/integrations/express/patch-layer.js +257 -0
- package/build/cjs/integrations/express/patch-layer.js.map +1 -0
- package/build/cjs/integrations/express/request-layer-store.js +25 -0
- package/build/cjs/integrations/express/request-layer-store.js.map +1 -0
- package/build/cjs/integrations/express/set-sdk-processing-metadata.js +17 -0
- package/build/cjs/integrations/express/set-sdk-processing-metadata.js.map +1 -0
- package/build/cjs/integrations/express/types.js +17 -0
- package/build/cjs/integrations/express/types.js.map +1 -0
- package/build/cjs/integrations/express/utils.js +238 -0
- package/build/cjs/integrations/express/utils.js.map +1 -0
- package/build/cjs/integrations/mcp-server/correlation.js +5 -1
- package/build/cjs/integrations/mcp-server/correlation.js.map +1 -1
- package/build/cjs/integrations/mcp-server/handlers.js +18 -10
- package/build/cjs/integrations/mcp-server/handlers.js.map +1 -1
- package/build/cjs/integrations/mcp-server/index.js +2 -1
- package/build/cjs/integrations/mcp-server/index.js.map +1 -1
- package/build/cjs/integrations/mcp-server/transport.js +1 -1
- package/build/cjs/integrations/mcp-server/transport.js.map +1 -1
- package/build/cjs/integrations/mcp-server/validation.js +7 -5
- package/build/cjs/integrations/mcp-server/validation.js.map +1 -1
- package/build/cjs/integrations/requestdata.js.map +1 -1
- package/build/cjs/integrations/spanStreaming.js +48 -0
- package/build/cjs/integrations/spanStreaming.js.map +1 -0
- package/build/cjs/semanticAttributes.js +35 -3
- package/build/cjs/semanticAttributes.js.map +1 -1
- package/build/cjs/tracing/ai/gen-ai-attributes.js +3 -89
- package/build/cjs/tracing/ai/gen-ai-attributes.js.map +1 -1
- package/build/cjs/tracing/ai/utils.js +74 -0
- package/build/cjs/tracing/ai/utils.js.map +1 -1
- package/build/cjs/tracing/anthropic-ai/index.js +6 -17
- package/build/cjs/tracing/anthropic-ai/index.js.map +1 -1
- package/build/cjs/tracing/anthropic-ai/streaming.js +2 -100
- package/build/cjs/tracing/anthropic-ai/streaming.js.map +1 -1
- package/build/cjs/tracing/anthropic-ai/utils.js +4 -2
- package/build/cjs/tracing/anthropic-ai/utils.js.map +1 -1
- package/build/cjs/tracing/dynamicSamplingContext.js +2 -1
- package/build/cjs/tracing/dynamicSamplingContext.js.map +1 -1
- package/build/cjs/tracing/google-genai/constants.js +1 -6
- package/build/cjs/tracing/google-genai/constants.js.map +1 -1
- package/build/cjs/tracing/google-genai/index.js +40 -35
- package/build/cjs/tracing/google-genai/index.js.map +1 -1
- package/build/cjs/tracing/google-genai/streaming.js +2 -23
- package/build/cjs/tracing/google-genai/streaming.js.map +1 -1
- package/build/cjs/tracing/langchain/embeddings.js +132 -0
- package/build/cjs/tracing/langchain/embeddings.js.map +1 -0
- package/build/cjs/tracing/langchain/index.js +3 -0
- package/build/cjs/tracing/langchain/index.js.map +1 -1
- package/build/cjs/tracing/langchain/utils.js +12 -4
- package/build/cjs/tracing/langchain/utils.js.map +1 -1
- package/build/cjs/tracing/langgraph/index.js +4 -3
- package/build/cjs/tracing/langgraph/index.js.map +1 -1
- package/build/cjs/tracing/openai/index.js +14 -34
- package/build/cjs/tracing/openai/index.js.map +1 -1
- package/build/cjs/tracing/openai/streaming.js +3 -34
- package/build/cjs/tracing/openai/streaming.js.map +1 -1
- package/build/cjs/tracing/openai/utils.js +78 -204
- package/build/cjs/tracing/openai/utils.js.map +1 -1
- package/build/cjs/tracing/sentryNonRecordingSpan.js +7 -0
- package/build/cjs/tracing/sentryNonRecordingSpan.js.map +1 -1
- package/build/cjs/tracing/sentrySpan.js +39 -0
- package/build/cjs/tracing/sentrySpan.js.map +1 -1
- package/build/cjs/tracing/spans/beforeSendSpan.js +43 -0
- package/build/cjs/tracing/spans/beforeSendSpan.js.map +1 -0
- package/build/cjs/tracing/spans/captureSpan.js +126 -0
- package/build/cjs/tracing/spans/captureSpan.js.map +1 -0
- package/build/cjs/tracing/spans/envelope.js +38 -0
- package/build/cjs/tracing/spans/envelope.js.map +1 -0
- package/build/cjs/tracing/spans/estimateSize.js +41 -0
- package/build/cjs/tracing/spans/estimateSize.js.map +1 -0
- package/build/cjs/tracing/spans/hasSpanStreamingEnabled.js +11 -0
- package/build/cjs/tracing/spans/hasSpanStreamingEnabled.js.map +1 -0
- package/build/cjs/tracing/spans/spanBuffer.js +158 -0
- package/build/cjs/tracing/spans/spanBuffer.js.map +1 -0
- package/build/cjs/tracing/trace.js +83 -13
- package/build/cjs/tracing/trace.js.map +1 -1
- package/build/cjs/tracing/utils.js +3 -37
- package/build/cjs/tracing/utils.js.map +1 -1
- package/build/cjs/tracing/vercel-ai/constants.js +15 -23
- package/build/cjs/tracing/vercel-ai/constants.js.map +1 -1
- package/build/cjs/tracing/vercel-ai/index.js +32 -45
- package/build/cjs/tracing/vercel-ai/index.js.map +1 -1
- package/build/cjs/tracing/vercel-ai/utils.js +11 -42
- package/build/cjs/tracing/vercel-ai/utils.js.map +1 -1
- package/build/cjs/tracing/vercel-ai/vercel-ai-attributes.js +4 -1
- package/build/cjs/tracing/vercel-ai/vercel-ai-attributes.js.map +1 -1
- package/build/cjs/utils/browser.js +2 -3
- package/build/cjs/utils/browser.js.map +1 -1
- package/build/cjs/utils/featureFlags.js +6 -0
- package/build/cjs/utils/featureFlags.js.map +1 -1
- package/build/cjs/utils/object.js +33 -0
- package/build/cjs/utils/object.js.map +1 -1
- package/build/cjs/utils/spanUtils.js +116 -13
- package/build/cjs/utils/spanUtils.js.map +1 -1
- package/build/cjs/utils/stacktrace.js +3 -1
- package/build/cjs/utils/stacktrace.js.map +1 -1
- package/build/cjs/utils/string.js +3 -0
- package/build/cjs/utils/string.js.map +1 -1
- package/build/cjs/utils/version.js +1 -1
- package/build/cjs/utils/weakRef.js +62 -0
- package/build/cjs/utils/weakRef.js.map +1 -0
- package/build/esm/attributes.js +43 -1
- package/build/esm/attributes.js.map +1 -1
- package/build/esm/client.js +8 -1
- package/build/esm/client.js.map +1 -1
- package/build/esm/envelope.js +2 -1
- package/build/esm/envelope.js.map +1 -1
- package/build/esm/fetch.js +36 -17
- package/build/esm/fetch.js.map +1 -1
- package/build/esm/index.js +12 -3
- package/build/esm/index.js.map +1 -1
- package/build/esm/integration.js +6 -0
- package/build/esm/integration.js.map +1 -1
- package/build/esm/integrations/conversationId.js +11 -0
- package/build/esm/integrations/conversationId.js.map +1 -1
- package/build/esm/integrations/express/index.js +239 -0
- package/build/esm/integrations/express/index.js.map +1 -0
- package/build/esm/integrations/express/patch-layer.js +255 -0
- package/build/esm/integrations/express/patch-layer.js.map +1 -0
- package/build/esm/integrations/express/request-layer-store.js +22 -0
- package/build/esm/integrations/express/request-layer-store.js.map +1 -0
- package/build/esm/integrations/express/set-sdk-processing-metadata.js +15 -0
- package/build/esm/integrations/express/set-sdk-processing-metadata.js.map +1 -0
- package/build/esm/integrations/express/types.js +10 -0
- package/build/esm/integrations/express/types.js.map +1 -0
- package/build/esm/integrations/express/utils.js +225 -0
- package/build/esm/integrations/express/utils.js.map +1 -0
- package/build/esm/integrations/mcp-server/correlation.js +5 -1
- package/build/esm/integrations/mcp-server/correlation.js.map +1 -1
- package/build/esm/integrations/mcp-server/handlers.js +18 -10
- package/build/esm/integrations/mcp-server/handlers.js.map +1 -1
- package/build/esm/integrations/mcp-server/index.js +2 -1
- package/build/esm/integrations/mcp-server/index.js.map +1 -1
- package/build/esm/integrations/mcp-server/transport.js +1 -1
- package/build/esm/integrations/mcp-server/transport.js.map +1 -1
- package/build/esm/integrations/mcp-server/validation.js +7 -5
- package/build/esm/integrations/mcp-server/validation.js.map +1 -1
- package/build/esm/integrations/requestdata.js.map +1 -1
- package/build/esm/integrations/spanStreaming.js +46 -0
- package/build/esm/integrations/spanStreaming.js.map +1 -0
- package/build/esm/package.json +1 -1
- package/build/esm/semanticAttributes.js +26 -4
- package/build/esm/semanticAttributes.js.map +1 -1
- package/build/esm/tracing/ai/gen-ai-attributes.js +3 -76
- package/build/esm/tracing/ai/gen-ai-attributes.js.map +1 -1
- package/build/esm/tracing/ai/utils.js +73 -2
- package/build/esm/tracing/ai/utils.js.map +1 -1
- package/build/esm/tracing/anthropic-ai/index.js +8 -19
- package/build/esm/tracing/anthropic-ai/index.js.map +1 -1
- package/build/esm/tracing/anthropic-ai/streaming.js +3 -101
- package/build/esm/tracing/anthropic-ai/streaming.js.map +1 -1
- package/build/esm/tracing/anthropic-ai/utils.js +5 -3
- package/build/esm/tracing/anthropic-ai/utils.js.map +1 -1
- package/build/esm/tracing/dynamicSamplingContext.js +2 -1
- package/build/esm/tracing/dynamicSamplingContext.js.map +1 -1
- package/build/esm/tracing/google-genai/constants.js +2 -5
- package/build/esm/tracing/google-genai/constants.js.map +1 -1
- package/build/esm/tracing/google-genai/index.js +42 -37
- package/build/esm/tracing/google-genai/index.js.map +1 -1
- package/build/esm/tracing/google-genai/streaming.js +2 -23
- package/build/esm/tracing/google-genai/streaming.js.map +1 -1
- package/build/esm/tracing/langchain/embeddings.js +129 -0
- package/build/esm/tracing/langchain/embeddings.js.map +1 -0
- package/build/esm/tracing/langchain/index.js +4 -1
- package/build/esm/tracing/langchain/index.js.map +1 -1
- package/build/esm/tracing/langchain/utils.js +13 -5
- package/build/esm/tracing/langchain/utils.js.map +1 -1
- package/build/esm/tracing/langgraph/index.js +5 -4
- package/build/esm/tracing/langgraph/index.js.map +1 -1
- package/build/esm/tracing/openai/index.js +16 -36
- package/build/esm/tracing/openai/index.js.map +1 -1
- package/build/esm/tracing/openai/streaming.js +4 -35
- package/build/esm/tracing/openai/streaming.js.map +1 -1
- package/build/esm/tracing/openai/utils.js +79 -196
- package/build/esm/tracing/openai/utils.js.map +1 -1
- package/build/esm/tracing/sentryNonRecordingSpan.js +7 -0
- package/build/esm/tracing/sentryNonRecordingSpan.js.map +1 -1
- package/build/esm/tracing/sentrySpan.js +40 -1
- package/build/esm/tracing/sentrySpan.js.map +1 -1
- package/build/esm/tracing/spans/beforeSendSpan.js +40 -0
- package/build/esm/tracing/spans/beforeSendSpan.js.map +1 -0
- package/build/esm/tracing/spans/captureSpan.js +122 -0
- package/build/esm/tracing/spans/captureSpan.js.map +1 -0
- package/build/esm/tracing/spans/envelope.js +36 -0
- package/build/esm/tracing/spans/envelope.js.map +1 -0
- package/build/esm/tracing/spans/estimateSize.js +39 -0
- package/build/esm/tracing/spans/estimateSize.js.map +1 -0
- package/build/esm/tracing/spans/hasSpanStreamingEnabled.js +9 -0
- package/build/esm/tracing/spans/hasSpanStreamingEnabled.js.map +1 -0
- package/build/esm/tracing/spans/spanBuffer.js +156 -0
- package/build/esm/tracing/spans/spanBuffer.js.map +1 -0
- package/build/esm/tracing/trace.js +84 -14
- package/build/esm/tracing/trace.js.map +1 -1
- package/build/esm/tracing/utils.js +3 -37
- package/build/esm/tracing/utils.js.map +1 -1
- package/build/esm/tracing/vercel-ai/constants.js +15 -19
- package/build/esm/tracing/vercel-ai/constants.js.map +1 -1
- package/build/esm/tracing/vercel-ai/index.js +29 -42
- package/build/esm/tracing/vercel-ai/index.js.map +1 -1
- package/build/esm/tracing/vercel-ai/utils.js +14 -44
- package/build/esm/tracing/vercel-ai/utils.js.map +1 -1
- package/build/esm/tracing/vercel-ai/vercel-ai-attributes.js +4 -1
- package/build/esm/tracing/vercel-ai/vercel-ai-attributes.js.map +1 -1
- package/build/esm/utils/browser.js +2 -3
- package/build/esm/utils/browser.js.map +1 -1
- package/build/esm/utils/featureFlags.js +6 -0
- package/build/esm/utils/featureFlags.js.map +1 -1
- package/build/esm/utils/object.js +33 -1
- package/build/esm/utils/object.js.map +1 -1
- package/build/esm/utils/spanUtils.js +112 -14
- package/build/esm/utils/spanUtils.js.map +1 -1
- package/build/esm/utils/stacktrace.js +3 -1
- package/build/esm/utils/stacktrace.js.map +1 -1
- package/build/esm/utils/string.js +3 -0
- package/build/esm/utils/string.js.map +1 -1
- package/build/esm/utils/version.js +1 -1
- package/build/esm/utils/weakRef.js +59 -0
- package/build/esm/utils/weakRef.js.map +1 -0
- package/build/types/attributes.d.ts +5 -0
- package/build/types/attributes.d.ts.map +1 -1
- package/build/types/build-time-plugins/buildTimeOptionsBase.d.ts +13 -0
- package/build/types/build-time-plugins/buildTimeOptionsBase.d.ts.map +1 -1
- package/build/types/client.d.ts +35 -1
- package/build/types/client.d.ts.map +1 -1
- package/build/types/envelope.d.ts.map +1 -1
- package/build/types/fetch.d.ts +12 -8
- package/build/types/fetch.d.ts.map +1 -1
- package/build/types/index.d.ts +16 -5
- package/build/types/index.d.ts.map +1 -1
- package/build/types/integration.d.ts.map +1 -1
- package/build/types/integrations/conversationId.d.ts.map +1 -1
- package/build/types/integrations/express/index.d.ts +82 -0
- package/build/types/integrations/express/index.d.ts.map +1 -0
- package/build/types/integrations/express/patch-layer.d.ts +32 -0
- package/build/types/integrations/express/patch-layer.d.ts.map +1 -0
- package/build/types/integrations/express/request-layer-store.d.ts +32 -0
- package/build/types/integrations/express/request-layer-store.d.ts.map +1 -0
- package/build/types/integrations/express/set-sdk-processing-metadata.d.ts +35 -0
- package/build/types/integrations/express/set-sdk-processing-metadata.d.ts.map +1 -0
- package/build/types/integrations/express/types.d.ts +158 -0
- package/build/types/integrations/express/types.d.ts.map +1 -0
- package/build/types/integrations/express/utils.d.ts +93 -0
- package/build/types/integrations/express/utils.d.ts.map +1 -0
- package/build/types/integrations/mcp-server/correlation.d.ts +2 -1
- package/build/types/integrations/mcp-server/correlation.d.ts.map +1 -1
- package/build/types/integrations/mcp-server/handlers.d.ts +9 -4
- package/build/types/integrations/mcp-server/handlers.d.ts.map +1 -1
- package/build/types/integrations/mcp-server/index.d.ts +2 -1
- package/build/types/integrations/mcp-server/index.d.ts.map +1 -1
- package/build/types/integrations/mcp-server/types.d.ts +40 -7
- package/build/types/integrations/mcp-server/types.d.ts.map +1 -1
- package/build/types/integrations/mcp-server/validation.d.ts +4 -1
- package/build/types/integrations/mcp-server/validation.d.ts.map +1 -1
- package/build/types/integrations/requestdata.d.ts.map +1 -1
- package/build/types/integrations/spanStreaming.d.ts +2 -0
- package/build/types/integrations/spanStreaming.d.ts.map +1 -0
- package/build/types/semanticAttributes.d.ts +23 -3
- package/build/types/semanticAttributes.d.ts.map +1 -1
- package/build/types/tracing/ai/gen-ai-attributes.d.ts +4 -44
- package/build/types/tracing/ai/gen-ai-attributes.d.ts.map +1 -1
- package/build/types/tracing/ai/utils.d.ts +32 -2
- package/build/types/tracing/ai/utils.d.ts.map +1 -1
- package/build/types/tracing/anthropic-ai/index.d.ts.map +1 -1
- package/build/types/tracing/anthropic-ai/streaming.d.ts.map +1 -1
- package/build/types/tracing/anthropic-ai/types.d.ts +5 -0
- package/build/types/tracing/anthropic-ai/types.d.ts.map +1 -1
- package/build/types/tracing/anthropic-ai/utils.d.ts +1 -1
- package/build/types/tracing/anthropic-ai/utils.d.ts.map +1 -1
- package/build/types/tracing/dynamicSamplingContext.d.ts.map +1 -1
- package/build/types/tracing/google-genai/constants.d.ts +1 -3
- package/build/types/tracing/google-genai/constants.d.ts.map +1 -1
- package/build/types/tracing/google-genai/index.d.ts.map +1 -1
- package/build/types/tracing/google-genai/streaming.d.ts.map +1 -1
- package/build/types/tracing/google-genai/types.d.ts +5 -0
- package/build/types/tracing/google-genai/types.d.ts.map +1 -1
- package/build/types/tracing/index.d.ts +1 -0
- package/build/types/tracing/index.d.ts.map +1 -1
- package/build/types/tracing/langchain/embeddings.d.ts +27 -0
- package/build/types/tracing/langchain/embeddings.d.ts.map +1 -0
- package/build/types/tracing/langchain/index.d.ts +1 -0
- package/build/types/tracing/langchain/index.d.ts.map +1 -1
- package/build/types/tracing/langchain/types.d.ts +5 -0
- package/build/types/tracing/langchain/types.d.ts.map +1 -1
- package/build/types/tracing/langchain/utils.d.ts +2 -2
- package/build/types/tracing/langchain/utils.d.ts.map +1 -1
- package/build/types/tracing/langgraph/index.d.ts.map +1 -1
- package/build/types/tracing/langgraph/types.d.ts +5 -0
- package/build/types/tracing/langgraph/types.d.ts.map +1 -1
- package/build/types/tracing/openai/index.d.ts.map +1 -1
- package/build/types/tracing/openai/streaming.d.ts.map +1 -1
- package/build/types/tracing/openai/types.d.ts +5 -0
- package/build/types/tracing/openai/types.d.ts.map +1 -1
- package/build/types/tracing/openai/utils.d.ts +4 -49
- package/build/types/tracing/openai/utils.d.ts.map +1 -1
- package/build/types/tracing/sentryNonRecordingSpan.d.ts +12 -1
- package/build/types/tracing/sentryNonRecordingSpan.d.ts.map +1 -1
- package/build/types/tracing/sentrySpan.d.ts +10 -1
- package/build/types/tracing/sentrySpan.d.ts.map +1 -1
- package/build/types/tracing/spans/beforeSendSpan.d.ts +35 -0
- package/build/types/tracing/spans/beforeSendSpan.d.ts.map +1 -0
- package/build/types/tracing/spans/captureSpan.d.ts +26 -0
- package/build/types/tracing/spans/captureSpan.d.ts.map +1 -0
- package/build/types/tracing/spans/envelope.d.ts +8 -0
- package/build/types/tracing/spans/envelope.d.ts.map +1 -0
- package/build/types/tracing/spans/estimateSize.d.ts +12 -0
- package/build/types/tracing/spans/estimateSize.d.ts.map +1 -0
- package/build/types/tracing/spans/hasSpanStreamingEnabled.d.ts +6 -0
- package/build/types/tracing/spans/hasSpanStreamingEnabled.d.ts.map +1 -0
- package/build/types/tracing/spans/spanBuffer.d.ts +60 -0
- package/build/types/tracing/spans/spanBuffer.d.ts.map +1 -0
- package/build/types/tracing/trace.d.ts.map +1 -1
- package/build/types/tracing/utils.d.ts.map +1 -1
- package/build/types/tracing/vercel-ai/constants.d.ts +2 -5
- package/build/types/tracing/vercel-ai/constants.d.ts.map +1 -1
- package/build/types/tracing/vercel-ai/index.d.ts.map +1 -1
- package/build/types/tracing/vercel-ai/utils.d.ts +1 -5
- package/build/types/tracing/vercel-ai/utils.d.ts.map +1 -1
- package/build/types/tracing/vercel-ai/vercel-ai-attributes.d.ts +0 -480
- package/build/types/tracing/vercel-ai/vercel-ai-attributes.d.ts.map +1 -1
- package/build/types/types-hoist/envelope.d.ts +22 -2
- package/build/types/types-hoist/envelope.d.ts.map +1 -1
- package/build/types/types-hoist/integration.d.ts +8 -0
- package/build/types/types-hoist/integration.d.ts.map +1 -1
- package/build/types/types-hoist/link.d.ts +2 -2
- package/build/types/types-hoist/link.d.ts.map +1 -1
- package/build/types/types-hoist/options.d.ts +26 -2
- package/build/types/types-hoist/options.d.ts.map +1 -1
- package/build/types/types-hoist/span.d.ts +35 -0
- package/build/types/types-hoist/span.d.ts.map +1 -1
- package/build/types/types-hoist/view-hierarchy.d.ts +1 -0
- package/build/types/types-hoist/view-hierarchy.d.ts.map +1 -1
- package/build/types/utils/browser.d.ts +1 -1
- package/build/types/utils/browser.d.ts.map +1 -1
- package/build/types/utils/featureFlags.d.ts.map +1 -1
- package/build/types/utils/object.d.ts +10 -0
- package/build/types/utils/object.d.ts.map +1 -1
- package/build/types/utils/spanUtils.d.ts +27 -2
- package/build/types/utils/spanUtils.d.ts.map +1 -1
- package/build/types/utils/stacktrace.d.ts.map +1 -1
- package/build/types/utils/string.d.ts +2 -2
- package/build/types/utils/string.d.ts.map +1 -1
- package/build/types/utils/weakRef.d.ts +34 -0
- package/build/types/utils/weakRef.d.ts.map +1 -0
- package/build/types-ts3.8/attributes.d.ts +5 -0
- package/build/types-ts3.8/build-time-plugins/buildTimeOptionsBase.d.ts +13 -0
- package/build/types-ts3.8/client.d.ts +35 -1
- package/build/types-ts3.8/fetch.d.ts +14 -10
- package/build/types-ts3.8/index.d.ts +16 -5
- package/build/types-ts3.8/integrations/express/index.d.ts +82 -0
- package/build/types-ts3.8/integrations/express/patch-layer.d.ts +32 -0
- package/build/types-ts3.8/integrations/express/request-layer-store.d.ts +32 -0
- package/build/types-ts3.8/integrations/express/set-sdk-processing-metadata.d.ts +35 -0
- package/build/types-ts3.8/integrations/express/types.d.ts +158 -0
- package/build/types-ts3.8/integrations/express/utils.d.ts +96 -0
- package/build/types-ts3.8/integrations/mcp-server/correlation.d.ts +2 -1
- package/build/types-ts3.8/integrations/mcp-server/handlers.d.ts +9 -4
- package/build/types-ts3.8/integrations/mcp-server/index.d.ts +2 -1
- package/build/types-ts3.8/integrations/mcp-server/types.d.ts +40 -7
- package/build/types-ts3.8/integrations/mcp-server/validation.d.ts +4 -1
- package/build/types-ts3.8/integrations/spanStreaming.d.ts +2 -0
- package/build/types-ts3.8/semanticAttributes.d.ts +23 -3
- package/build/types-ts3.8/tracing/ai/gen-ai-attributes.d.ts +4 -44
- package/build/types-ts3.8/tracing/ai/utils.d.ts +32 -2
- package/build/types-ts3.8/tracing/anthropic-ai/types.d.ts +5 -0
- package/build/types-ts3.8/tracing/anthropic-ai/utils.d.ts +1 -1
- package/build/types-ts3.8/tracing/google-genai/constants.d.ts +1 -3
- package/build/types-ts3.8/tracing/google-genai/types.d.ts +5 -0
- package/build/types-ts3.8/tracing/index.d.ts +1 -0
- package/build/types-ts3.8/tracing/langchain/embeddings.d.ts +27 -0
- package/build/types-ts3.8/tracing/langchain/index.d.ts +1 -0
- package/build/types-ts3.8/tracing/langchain/types.d.ts +5 -0
- package/build/types-ts3.8/tracing/langchain/utils.d.ts +2 -2
- package/build/types-ts3.8/tracing/langgraph/types.d.ts +5 -0
- package/build/types-ts3.8/tracing/openai/types.d.ts +5 -0
- package/build/types-ts3.8/tracing/openai/utils.d.ts +4 -49
- package/build/types-ts3.8/tracing/sentryNonRecordingSpan.d.ts +12 -1
- package/build/types-ts3.8/tracing/sentrySpan.d.ts +10 -1
- package/build/types-ts3.8/tracing/spans/beforeSendSpan.d.ts +35 -0
- package/build/types-ts3.8/tracing/spans/captureSpan.d.ts +26 -0
- package/build/types-ts3.8/tracing/spans/envelope.d.ts +8 -0
- package/build/types-ts3.8/tracing/spans/estimateSize.d.ts +12 -0
- package/build/types-ts3.8/tracing/spans/hasSpanStreamingEnabled.d.ts +6 -0
- package/build/types-ts3.8/tracing/spans/spanBuffer.d.ts +60 -0
- package/build/types-ts3.8/tracing/vercel-ai/constants.d.ts +2 -5
- package/build/types-ts3.8/tracing/vercel-ai/utils.d.ts +1 -5
- package/build/types-ts3.8/tracing/vercel-ai/vercel-ai-attributes.d.ts +0 -480
- package/build/types-ts3.8/types-hoist/envelope.d.ts +22 -2
- package/build/types-ts3.8/types-hoist/integration.d.ts +8 -0
- package/build/types-ts3.8/types-hoist/link.d.ts +2 -2
- package/build/types-ts3.8/types-hoist/options.d.ts +26 -2
- package/build/types-ts3.8/types-hoist/span.d.ts +35 -0
- package/build/types-ts3.8/types-hoist/view-hierarchy.d.ts +1 -0
- package/build/types-ts3.8/utils/browser.d.ts +1 -1
- package/build/types-ts3.8/utils/object.d.ts +10 -0
- package/build/types-ts3.8/utils/spanUtils.d.ts +27 -2
- package/build/types-ts3.8/utils/string.d.ts +2 -2
- package/build/types-ts3.8/utils/weakRef.d.ts +34 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"streaming.js","sources":["../../../../src/tracing/openai/streaming.ts"],"sourcesContent":["import { captureException } from '../../exports';\nimport { SPAN_STATUS_ERROR } from '../../tracing';\nimport type { Span } from '../../types-hoist/span';\nimport {\n GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE,\n GEN_AI_RESPONSE_STREAMING_ATTRIBUTE,\n GEN_AI_RESPONSE_TEXT_ATTRIBUTE,\n GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE,\n} from '../ai/gen-ai-attributes';\nimport { RESPONSE_EVENT_TYPES } from './constants';\nimport type {\n ChatCompletionChunk,\n ChatCompletionToolCall,\n OpenAIResponseObject,\n ResponseFunctionCall,\n ResponseStreamingEvent,\n} from './types';\nimport {\n isChatCompletionChunk,\n isResponsesApiStreamEvent,\n setCommonResponseAttributes,\n setTokenUsageAttributes,\n} from './utils';\n\n/**\n * State object used to accumulate information from a stream of OpenAI events/chunks.\n */\ninterface StreamingState {\n /** Types of events encountered in the stream. */\n eventTypes: string[];\n /** Collected response text fragments (for output recording). */\n responseTexts: string[];\n /** Reasons for finishing the response, as reported by the API. */\n finishReasons: string[];\n /** The response ID. */\n responseId: string;\n /** The model name. */\n responseModel: string;\n /** The timestamp of the response. */\n responseTimestamp: number;\n /** Number of prompt/input tokens used. */\n promptTokens: number | undefined;\n /** Number of completion/output tokens used. */\n completionTokens: number | undefined;\n /** Total number of tokens used (prompt + completion). */\n totalTokens: number | undefined;\n /**\n * Accumulated tool calls from Chat Completion streaming, indexed by tool call index.\n * @see https://platform.openai.com/docs/guides/function-calling?api-mode=chat#streaming\n */\n chatCompletionToolCalls: Record<number, ChatCompletionToolCall>;\n /**\n * Accumulated function calls from Responses API streaming.\n * @see https://platform.openai.com/docs/guides/function-calling?api-mode=responses#streaming\n */\n responsesApiToolCalls: Array<ResponseFunctionCall | unknown>;\n}\n\n/**\n * Processes tool calls from a chat completion chunk delta.\n * Follows the pattern: accumulate by index, then convert to array at the end.\n *\n * @param toolCalls - Array of tool calls from the delta.\n * @param state - The current streaming state to update.\n *\n * @see https://platform.openai.com/docs/guides/function-calling#streaming\n */\nfunction processChatCompletionToolCalls(toolCalls: ChatCompletionToolCall[], state: StreamingState): void {\n for (const toolCall of toolCalls) {\n const index = toolCall.index;\n if (index === undefined || !toolCall.function) continue;\n\n // Initialize tool call if this is the first chunk for this index\n if (!(index in state.chatCompletionToolCalls)) {\n state.chatCompletionToolCalls[index] = {\n ...toolCall,\n function: {\n name: toolCall.function.name,\n arguments: toolCall.function.arguments || '',\n },\n };\n } else {\n // Accumulate function arguments from subsequent chunks\n const existingToolCall = state.chatCompletionToolCalls[index];\n if (toolCall.function.arguments && existingToolCall?.function) {\n existingToolCall.function.arguments += toolCall.function.arguments;\n }\n }\n }\n}\n\n/**\n * Processes a single OpenAI ChatCompletionChunk event, updating the streaming state.\n *\n * @param chunk - The ChatCompletionChunk event to process.\n * @param state - The current streaming state to update.\n * @param recordOutputs - Whether to record output text fragments.\n */\nfunction processChatCompletionChunk(chunk: ChatCompletionChunk, state: StreamingState, recordOutputs: boolean): void {\n state.responseId = chunk.id ?? state.responseId;\n state.responseModel = chunk.model ?? state.responseModel;\n state.responseTimestamp = chunk.created ?? state.responseTimestamp;\n\n if (chunk.usage) {\n // For stream responses, the input tokens remain constant across all events in the stream.\n // Output tokens, however, are only finalized in the last event.\n // Since we can't guarantee that the last event will include usage data or even be a typed event,\n // we update the output token values on every event that includes them.\n // This ensures that output token usage is always set, even if the final event lacks it.\n state.promptTokens = chunk.usage.prompt_tokens;\n state.completionTokens = chunk.usage.completion_tokens;\n state.totalTokens = chunk.usage.total_tokens;\n }\n\n for (const choice of chunk.choices ?? []) {\n if (recordOutputs) {\n if (choice.delta?.content) {\n state.responseTexts.push(choice.delta.content);\n }\n\n // Handle tool calls from delta\n if (choice.delta?.tool_calls) {\n processChatCompletionToolCalls(choice.delta.tool_calls, state);\n }\n }\n if (choice.finish_reason) {\n state.finishReasons.push(choice.finish_reason);\n }\n }\n}\n\n/**\n * Processes a single OpenAI Responses API streaming event, updating the streaming state and span.\n *\n * @param streamEvent - The event to process (may be an error or unknown object).\n * @param state - The current streaming state to update.\n * @param recordOutputs - Whether to record output text fragments.\n * @param span - The span to update with error status if needed.\n */\nfunction processResponsesApiEvent(\n streamEvent: ResponseStreamingEvent | unknown | Error,\n state: StreamingState,\n recordOutputs: boolean,\n span: Span,\n): void {\n if (!(streamEvent && typeof streamEvent === 'object')) {\n state.eventTypes.push('unknown:non-object');\n return;\n }\n if (streamEvent instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureException(streamEvent, {\n mechanism: {\n handled: false,\n type: 'auto.ai.openai.stream-response',\n },\n });\n return;\n }\n\n if (!('type' in streamEvent)) return;\n const event = streamEvent as ResponseStreamingEvent;\n\n if (!RESPONSE_EVENT_TYPES.includes(event.type)) {\n state.eventTypes.push(event.type);\n return;\n }\n\n // Handle output text delta\n if (recordOutputs) {\n // Handle tool call events for Responses API\n if (event.type === 'response.output_item.done' && 'item' in event) {\n state.responsesApiToolCalls.push(event.item);\n }\n\n if (event.type === 'response.output_text.delta' && 'delta' in event && event.delta) {\n state.responseTexts.push(event.delta);\n return;\n }\n }\n\n if ('response' in event) {\n const { response } = event as { response: OpenAIResponseObject };\n state.responseId = response.id ?? state.responseId;\n state.responseModel = response.model ?? state.responseModel;\n state.responseTimestamp = response.created_at ?? state.responseTimestamp;\n\n if (response.usage) {\n // For stream responses, the input tokens remain constant across all events in the stream.\n // Output tokens, however, are only finalized in the last event.\n // Since we can't guarantee that the last event will include usage data or even be a typed event,\n // we update the output token values on every event that includes them.\n // This ensures that output token usage is always set, even if the final event lacks it.\n state.promptTokens = response.usage.input_tokens;\n state.completionTokens = response.usage.output_tokens;\n state.totalTokens = response.usage.total_tokens;\n }\n\n if (response.status) {\n state.finishReasons.push(response.status);\n }\n\n if (recordOutputs && response.output_text) {\n state.responseTexts.push(response.output_text);\n }\n }\n}\n\n/**\n * Instruments a stream of OpenAI events, updating the provided span with relevant attributes and\n * optionally recording output text. This function yields each event from the input stream as it is processed.\n *\n * @template T - The type of events in the stream.\n * @param stream - The async iterable stream of events to instrument.\n * @param span - The span to add attributes to and to finish at the end of the stream.\n * @param recordOutputs - Whether to record output text fragments in the span.\n * @returns An async generator yielding each event from the input stream.\n */\nexport async function* instrumentStream<T>(\n stream: AsyncIterable<T>,\n span: Span,\n recordOutputs: boolean,\n): AsyncGenerator<T, void, unknown> {\n const state: StreamingState = {\n eventTypes: [],\n responseTexts: [],\n finishReasons: [],\n responseId: '',\n responseModel: '',\n responseTimestamp: 0,\n promptTokens: undefined,\n completionTokens: undefined,\n totalTokens: undefined,\n chatCompletionToolCalls: {},\n responsesApiToolCalls: [],\n };\n\n try {\n for await (const event of stream) {\n if (isChatCompletionChunk(event)) {\n processChatCompletionChunk(event as ChatCompletionChunk, state, recordOutputs);\n } else if (isResponsesApiStreamEvent(event)) {\n processResponsesApiEvent(event as ResponseStreamingEvent, state, recordOutputs, span);\n }\n yield event;\n }\n } finally {\n setCommonResponseAttributes(span, state.responseId, state.responseModel, state.responseTimestamp);\n setTokenUsageAttributes(span, state.promptTokens, state.completionTokens, state.totalTokens);\n\n span.setAttributes({\n [GEN_AI_RESPONSE_STREAMING_ATTRIBUTE]: true,\n });\n\n if (state.finishReasons.length) {\n span.setAttributes({\n [GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE]: JSON.stringify(state.finishReasons),\n });\n }\n\n if (recordOutputs && state.responseTexts.length) {\n span.setAttributes({\n [GEN_AI_RESPONSE_TEXT_ATTRIBUTE]: state.responseTexts.join(''),\n });\n }\n\n // Set tool calls attribute if any were accumulated\n const chatCompletionToolCallsArray = Object.values(state.chatCompletionToolCalls);\n const allToolCalls = [...chatCompletionToolCallsArray, ...state.responsesApiToolCalls];\n\n if (allToolCalls.length > 0) {\n span.setAttributes({\n [GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE]: JSON.stringify(allToolCalls),\n });\n }\n\n span.end();\n }\n}\n"],"names":["SPAN_STATUS_ERROR","captureException","RESPONSE_EVENT_TYPES","isChatCompletionChunk","isResponsesApiStreamEvent","setCommonResponseAttributes","setTokenUsageAttributes","GEN_AI_RESPONSE_STREAMING_ATTRIBUTE","GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE","GEN_AI_RESPONSE_TEXT_ATTRIBUTE","GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"streaming.js","sources":["../../../../src/tracing/openai/streaming.ts"],"sourcesContent":["import { captureException } from '../../exports';\nimport { SPAN_STATUS_ERROR } from '../../tracing';\nimport type { Span } from '../../types-hoist/span';\nimport { endStreamSpan } from '../ai/utils';\nimport { RESPONSE_EVENT_TYPES } from './constants';\nimport type {\n ChatCompletionChunk,\n ChatCompletionToolCall,\n OpenAIResponseObject,\n ResponseFunctionCall,\n ResponseStreamingEvent,\n} from './types';\nimport { isChatCompletionChunk, isResponsesApiStreamEvent } from './utils';\n\n/**\n * State object used to accumulate information from a stream of OpenAI events/chunks.\n */\ninterface StreamingState {\n /** Types of events encountered in the stream. */\n eventTypes: string[];\n /** Collected response text fragments (for output recording). */\n responseTexts: string[];\n /** Reasons for finishing the response, as reported by the API. */\n finishReasons: string[];\n /** The response ID. */\n responseId: string;\n /** The model name. */\n responseModel: string;\n /** Number of prompt/input tokens used. */\n promptTokens: number | undefined;\n /** Number of completion/output tokens used. */\n completionTokens: number | undefined;\n /** Total number of tokens used (prompt + completion). */\n totalTokens: number | undefined;\n /**\n * Accumulated tool calls from Chat Completion streaming, indexed by tool call index.\n * @see https://platform.openai.com/docs/guides/function-calling?api-mode=chat#streaming\n */\n chatCompletionToolCalls: Record<number, ChatCompletionToolCall>;\n /**\n * Accumulated function calls from Responses API streaming.\n * @see https://platform.openai.com/docs/guides/function-calling?api-mode=responses#streaming\n */\n responsesApiToolCalls: Array<ResponseFunctionCall | unknown>;\n}\n\n/**\n * Processes tool calls from a chat completion chunk delta.\n * Follows the pattern: accumulate by index, then convert to array at the end.\n *\n * @param toolCalls - Array of tool calls from the delta.\n * @param state - The current streaming state to update.\n *\n * @see https://platform.openai.com/docs/guides/function-calling#streaming\n */\nfunction processChatCompletionToolCalls(toolCalls: ChatCompletionToolCall[], state: StreamingState): void {\n for (const toolCall of toolCalls) {\n const index = toolCall.index;\n if (index === undefined || !toolCall.function) continue;\n\n // Initialize tool call if this is the first chunk for this index\n if (!(index in state.chatCompletionToolCalls)) {\n state.chatCompletionToolCalls[index] = {\n ...toolCall,\n function: {\n name: toolCall.function.name,\n arguments: toolCall.function.arguments || '',\n },\n };\n } else {\n // Accumulate function arguments from subsequent chunks\n const existingToolCall = state.chatCompletionToolCalls[index];\n if (toolCall.function.arguments && existingToolCall?.function) {\n existingToolCall.function.arguments += toolCall.function.arguments;\n }\n }\n }\n}\n\n/**\n * Processes a single OpenAI ChatCompletionChunk event, updating the streaming state.\n *\n * @param chunk - The ChatCompletionChunk event to process.\n * @param state - The current streaming state to update.\n * @param recordOutputs - Whether to record output text fragments.\n */\nfunction processChatCompletionChunk(chunk: ChatCompletionChunk, state: StreamingState, recordOutputs: boolean): void {\n state.responseId = chunk.id ?? state.responseId;\n state.responseModel = chunk.model ?? state.responseModel;\n\n if (chunk.usage) {\n // For stream responses, the input tokens remain constant across all events in the stream.\n // Output tokens, however, are only finalized in the last event.\n // Since we can't guarantee that the last event will include usage data or even be a typed event,\n // we update the output token values on every event that includes them.\n // This ensures that output token usage is always set, even if the final event lacks it.\n state.promptTokens = chunk.usage.prompt_tokens;\n state.completionTokens = chunk.usage.completion_tokens;\n state.totalTokens = chunk.usage.total_tokens;\n }\n\n for (const choice of chunk.choices ?? []) {\n if (recordOutputs) {\n if (choice.delta?.content) {\n state.responseTexts.push(choice.delta.content);\n }\n\n // Handle tool calls from delta\n if (choice.delta?.tool_calls) {\n processChatCompletionToolCalls(choice.delta.tool_calls, state);\n }\n }\n if (choice.finish_reason) {\n state.finishReasons.push(choice.finish_reason);\n }\n }\n}\n\n/**\n * Processes a single OpenAI Responses API streaming event, updating the streaming state and span.\n *\n * @param streamEvent - The event to process (may be an error or unknown object).\n * @param state - The current streaming state to update.\n * @param recordOutputs - Whether to record output text fragments.\n * @param span - The span to update with error status if needed.\n */\nfunction processResponsesApiEvent(\n streamEvent: ResponseStreamingEvent | unknown | Error,\n state: StreamingState,\n recordOutputs: boolean,\n span: Span,\n): void {\n if (!(streamEvent && typeof streamEvent === 'object')) {\n state.eventTypes.push('unknown:non-object');\n return;\n }\n if (streamEvent instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureException(streamEvent, {\n mechanism: {\n handled: false,\n type: 'auto.ai.openai.stream-response',\n },\n });\n return;\n }\n\n if (!('type' in streamEvent)) return;\n const event = streamEvent as ResponseStreamingEvent;\n\n if (!RESPONSE_EVENT_TYPES.includes(event.type)) {\n state.eventTypes.push(event.type);\n return;\n }\n\n // Handle output text delta\n if (recordOutputs) {\n // Handle tool call events for Responses API\n if (event.type === 'response.output_item.done' && 'item' in event) {\n state.responsesApiToolCalls.push(event.item);\n }\n\n if (event.type === 'response.output_text.delta' && 'delta' in event && event.delta) {\n state.responseTexts.push(event.delta);\n return;\n }\n }\n\n if ('response' in event) {\n const { response } = event as { response: OpenAIResponseObject };\n state.responseId = response.id ?? state.responseId;\n state.responseModel = response.model ?? state.responseModel;\n\n if (response.usage) {\n // For stream responses, the input tokens remain constant across all events in the stream.\n // Output tokens, however, are only finalized in the last event.\n // Since we can't guarantee that the last event will include usage data or even be a typed event,\n // we update the output token values on every event that includes them.\n // This ensures that output token usage is always set, even if the final event lacks it.\n state.promptTokens = response.usage.input_tokens;\n state.completionTokens = response.usage.output_tokens;\n state.totalTokens = response.usage.total_tokens;\n }\n\n if (response.status) {\n state.finishReasons.push(response.status);\n }\n\n if (recordOutputs && response.output_text) {\n state.responseTexts.push(response.output_text);\n }\n }\n}\n\n/**\n * Instruments a stream of OpenAI events, updating the provided span with relevant attributes and\n * optionally recording output text. This function yields each event from the input stream as it is processed.\n *\n * @template T - The type of events in the stream.\n * @param stream - The async iterable stream of events to instrument.\n * @param span - The span to add attributes to and to finish at the end of the stream.\n * @param recordOutputs - Whether to record output text fragments in the span.\n * @returns An async generator yielding each event from the input stream.\n */\nexport async function* instrumentStream<T>(\n stream: AsyncIterable<T>,\n span: Span,\n recordOutputs: boolean,\n): AsyncGenerator<T, void, unknown> {\n const state: StreamingState = {\n eventTypes: [],\n responseTexts: [],\n finishReasons: [],\n responseId: '',\n responseModel: '',\n promptTokens: undefined,\n completionTokens: undefined,\n totalTokens: undefined,\n chatCompletionToolCalls: {},\n responsesApiToolCalls: [],\n };\n\n try {\n for await (const event of stream) {\n if (isChatCompletionChunk(event)) {\n processChatCompletionChunk(event as ChatCompletionChunk, state, recordOutputs);\n } else if (isResponsesApiStreamEvent(event)) {\n processResponsesApiEvent(event as ResponseStreamingEvent, state, recordOutputs, span);\n }\n yield event;\n }\n } finally {\n const allToolCalls = [...Object.values(state.chatCompletionToolCalls), ...state.responsesApiToolCalls];\n endStreamSpan(span, { ...state, toolCalls: allToolCalls }, recordOutputs);\n }\n}\n"],"names":["SPAN_STATUS_ERROR","captureException","RESPONSE_EVENT_TYPES","isChatCompletionChunk","isResponsesApiStreamEvent","endStreamSpan"],"mappings":"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"}
|
|
@@ -2,58 +2,6 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
2
2
|
|
|
3
3
|
const genAiAttributes = require('../ai/gen-ai-attributes.js');
|
|
4
4
|
|
|
5
|
-
/**
|
|
6
|
-
* Check if response is a Chat Completion object
|
|
7
|
-
*/
|
|
8
|
-
function isChatCompletionResponse(response) {
|
|
9
|
-
return (
|
|
10
|
-
response !== null &&
|
|
11
|
-
typeof response === 'object' &&
|
|
12
|
-
'object' in response &&
|
|
13
|
-
(response ).object === 'chat.completion'
|
|
14
|
-
);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Check if response is a Responses API object
|
|
19
|
-
*/
|
|
20
|
-
function isResponsesApiResponse(response) {
|
|
21
|
-
return (
|
|
22
|
-
response !== null &&
|
|
23
|
-
typeof response === 'object' &&
|
|
24
|
-
'object' in response &&
|
|
25
|
-
(response ).object === 'response'
|
|
26
|
-
);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Check if response is an Embeddings API object
|
|
31
|
-
*/
|
|
32
|
-
function isEmbeddingsResponse(response) {
|
|
33
|
-
if (response === null || typeof response !== 'object' || !('object' in response)) {
|
|
34
|
-
return false;
|
|
35
|
-
}
|
|
36
|
-
const responseObject = response ;
|
|
37
|
-
return (
|
|
38
|
-
responseObject.object === 'list' &&
|
|
39
|
-
typeof responseObject.model === 'string' &&
|
|
40
|
-
responseObject.model.toLowerCase().includes('embedding')
|
|
41
|
-
);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Check if response is a Conversations API object
|
|
46
|
-
* @see https://platform.openai.com/docs/api-reference/conversations
|
|
47
|
-
*/
|
|
48
|
-
function isConversationResponse(response) {
|
|
49
|
-
return (
|
|
50
|
-
response !== null &&
|
|
51
|
-
typeof response === 'object' &&
|
|
52
|
-
'object' in response &&
|
|
53
|
-
(response ).object === 'conversation'
|
|
54
|
-
);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
5
|
/**
|
|
58
6
|
* Check if streaming event is from the Responses API
|
|
59
7
|
*/
|
|
@@ -80,173 +28,108 @@ function isChatCompletionChunk(event) {
|
|
|
80
28
|
}
|
|
81
29
|
|
|
82
30
|
/**
|
|
83
|
-
* Add attributes
|
|
31
|
+
* Add response attributes to a span using duck-typing.
|
|
32
|
+
* Works for Chat Completions, Responses API, Embeddings, and Conversations API responses.
|
|
84
33
|
*/
|
|
85
|
-
function
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
34
|
+
function addResponseAttributes(span, result, recordOutputs) {
|
|
35
|
+
if (!result || typeof result !== 'object') return;
|
|
36
|
+
|
|
37
|
+
const response = result ;
|
|
38
|
+
const attrs = {};
|
|
39
|
+
|
|
40
|
+
// Response ID
|
|
41
|
+
if (typeof response.id === 'string') {
|
|
42
|
+
attrs[genAiAttributes.GEN_AI_RESPONSE_ID_ATTRIBUTE] = response.id;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Response model
|
|
46
|
+
if (typeof response.model === 'string') {
|
|
47
|
+
attrs[genAiAttributes.GEN_AI_RESPONSE_MODEL_ATTRIBUTE] = response.model;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Conversation ID (conversation objects use id as conversation link)
|
|
51
|
+
if (response.object === 'conversation' && typeof response.id === 'string') {
|
|
52
|
+
attrs[genAiAttributes.GEN_AI_CONVERSATION_ID_ATTRIBUTE] = response.id;
|
|
98
53
|
}
|
|
54
|
+
|
|
55
|
+
// Token usage — supports both naming conventions (chat: prompt_tokens/completion_tokens, responses: input_tokens/output_tokens)
|
|
56
|
+
if (response.usage && typeof response.usage === 'object') {
|
|
57
|
+
const usage = response.usage ;
|
|
58
|
+
|
|
59
|
+
const inputTokens = usage.prompt_tokens ?? usage.input_tokens;
|
|
60
|
+
if (typeof inputTokens === 'number') {
|
|
61
|
+
attrs[genAiAttributes.GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE] = inputTokens;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const outputTokens = usage.completion_tokens ?? usage.output_tokens;
|
|
65
|
+
if (typeof outputTokens === 'number') {
|
|
66
|
+
attrs[genAiAttributes.GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE] = outputTokens;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (typeof usage.total_tokens === 'number') {
|
|
70
|
+
attrs[genAiAttributes.GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE] = usage.total_tokens;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Finish reasons from choices (chat completions)
|
|
99
75
|
if (Array.isArray(response.choices)) {
|
|
100
|
-
const
|
|
76
|
+
const choices = response.choices ;
|
|
77
|
+
const finishReasons = choices
|
|
101
78
|
.map(choice => choice.finish_reason)
|
|
102
|
-
.filter((reason) => reason
|
|
79
|
+
.filter((reason) => typeof reason === 'string');
|
|
103
80
|
if (finishReasons.length > 0) {
|
|
104
|
-
|
|
105
|
-
[genAiAttributes.GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE]: JSON.stringify(finishReasons),
|
|
106
|
-
});
|
|
81
|
+
attrs[genAiAttributes.GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE] = JSON.stringify(finishReasons);
|
|
107
82
|
}
|
|
108
83
|
|
|
109
|
-
// Extract tool calls from all choices (only if recordOutputs is true)
|
|
110
84
|
if (recordOutputs) {
|
|
111
|
-
|
|
112
|
-
|
|
85
|
+
// Response text from choices
|
|
86
|
+
const responseTexts = choices.map(choice => {
|
|
87
|
+
const message = choice.message ;
|
|
88
|
+
return (message?.content ) || '';
|
|
89
|
+
});
|
|
90
|
+
attrs[genAiAttributes.GEN_AI_RESPONSE_TEXT_ATTRIBUTE] = JSON.stringify(responseTexts);
|
|
91
|
+
|
|
92
|
+
// Tool calls from choices
|
|
93
|
+
const toolCalls = choices
|
|
94
|
+
.map(choice => {
|
|
95
|
+
const message = choice.message ;
|
|
96
|
+
return message?.tool_calls;
|
|
97
|
+
})
|
|
113
98
|
.filter(calls => Array.isArray(calls) && calls.length > 0)
|
|
114
99
|
.flat();
|
|
115
100
|
|
|
116
101
|
if (toolCalls.length > 0) {
|
|
117
|
-
|
|
118
|
-
[genAiAttributes.GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE]: JSON.stringify(toolCalls),
|
|
119
|
-
});
|
|
102
|
+
attrs[genAiAttributes.GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE] = JSON.stringify(toolCalls);
|
|
120
103
|
}
|
|
121
104
|
}
|
|
122
105
|
}
|
|
123
|
-
}
|
|
124
106
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
span.setAttributes({
|
|
132
|
-
[genAiAttributes.GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE]: JSON.stringify([response.status]),
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
if (response.usage) {
|
|
136
|
-
setTokenUsageAttributes(
|
|
137
|
-
span,
|
|
138
|
-
response.usage.input_tokens,
|
|
139
|
-
response.usage.output_tokens,
|
|
140
|
-
response.usage.total_tokens,
|
|
141
|
-
);
|
|
107
|
+
// Finish reason from status (responses API)
|
|
108
|
+
if (typeof response.status === 'string') {
|
|
109
|
+
// Only set if not already set from choices
|
|
110
|
+
if (!attrs[genAiAttributes.GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE]) {
|
|
111
|
+
attrs[genAiAttributes.GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE] = JSON.stringify([response.status]);
|
|
112
|
+
}
|
|
142
113
|
}
|
|
143
114
|
|
|
144
|
-
// Extract function calls from output (only if recordOutputs is true)
|
|
145
115
|
if (recordOutputs) {
|
|
146
|
-
|
|
147
|
-
if (
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
(item) =>
|
|
151
|
-
// oxlint-disable-next-line typescript/prefer-optional-chain
|
|
152
|
-
typeof item === 'object' && item !== null && (item ).type === 'function_call',
|
|
153
|
-
);
|
|
116
|
+
// Response text from output_text (responses API)
|
|
117
|
+
if (typeof response.output_text === 'string' && !attrs[genAiAttributes.GEN_AI_RESPONSE_TEXT_ATTRIBUTE]) {
|
|
118
|
+
attrs[genAiAttributes.GEN_AI_RESPONSE_TEXT_ATTRIBUTE] = response.output_text;
|
|
119
|
+
}
|
|
154
120
|
|
|
121
|
+
// Tool calls from output array (responses API)
|
|
122
|
+
if (Array.isArray(response.output) && response.output.length > 0 && !attrs[genAiAttributes.GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE]) {
|
|
123
|
+
const functionCalls = (response.output ).filter(
|
|
124
|
+
item => item?.type === 'function_call',
|
|
125
|
+
);
|
|
155
126
|
if (functionCalls.length > 0) {
|
|
156
|
-
|
|
157
|
-
[genAiAttributes.GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE]: JSON.stringify(functionCalls),
|
|
158
|
-
});
|
|
127
|
+
attrs[genAiAttributes.GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE] = JSON.stringify(functionCalls);
|
|
159
128
|
}
|
|
160
129
|
}
|
|
161
130
|
}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* Add attributes for Embeddings API responses
|
|
166
|
-
*/
|
|
167
|
-
function addEmbeddingsAttributes(span, response) {
|
|
168
|
-
span.setAttributes({
|
|
169
|
-
[genAiAttributes.OPENAI_RESPONSE_MODEL_ATTRIBUTE]: response.model,
|
|
170
|
-
[genAiAttributes.GEN_AI_RESPONSE_MODEL_ATTRIBUTE]: response.model,
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
if (response.usage) {
|
|
174
|
-
setTokenUsageAttributes(span, response.usage.prompt_tokens, undefined, response.usage.total_tokens);
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
* Add attributes for Conversations API responses
|
|
180
|
-
* @see https://platform.openai.com/docs/api-reference/conversations
|
|
181
|
-
*/
|
|
182
|
-
function addConversationAttributes(span, response) {
|
|
183
|
-
const { id, created_at } = response;
|
|
184
|
-
|
|
185
|
-
span.setAttributes({
|
|
186
|
-
[genAiAttributes.OPENAI_RESPONSE_ID_ATTRIBUTE]: id,
|
|
187
|
-
[genAiAttributes.GEN_AI_RESPONSE_ID_ATTRIBUTE]: id,
|
|
188
|
-
// The conversation id is used to link messages across API calls
|
|
189
|
-
[genAiAttributes.GEN_AI_CONVERSATION_ID_ATTRIBUTE]: id,
|
|
190
|
-
});
|
|
191
|
-
|
|
192
|
-
if (created_at) {
|
|
193
|
-
span.setAttributes({
|
|
194
|
-
[genAiAttributes.OPENAI_RESPONSE_TIMESTAMP_ATTRIBUTE]: new Date(created_at * 1000).toISOString(),
|
|
195
|
-
});
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
/**
|
|
200
|
-
* Set token usage attributes
|
|
201
|
-
* @param span - The span to add attributes to
|
|
202
|
-
* @param promptTokens - The number of prompt tokens
|
|
203
|
-
* @param completionTokens - The number of completion tokens
|
|
204
|
-
* @param totalTokens - The number of total tokens
|
|
205
|
-
*/
|
|
206
|
-
function setTokenUsageAttributes(
|
|
207
|
-
span,
|
|
208
|
-
promptTokens,
|
|
209
|
-
completionTokens,
|
|
210
|
-
totalTokens,
|
|
211
|
-
) {
|
|
212
|
-
if (promptTokens !== undefined) {
|
|
213
|
-
span.setAttributes({
|
|
214
|
-
[genAiAttributes.OPENAI_USAGE_PROMPT_TOKENS_ATTRIBUTE]: promptTokens,
|
|
215
|
-
[genAiAttributes.GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE]: promptTokens,
|
|
216
|
-
});
|
|
217
|
-
}
|
|
218
|
-
if (completionTokens !== undefined) {
|
|
219
|
-
span.setAttributes({
|
|
220
|
-
[genAiAttributes.OPENAI_USAGE_COMPLETION_TOKENS_ATTRIBUTE]: completionTokens,
|
|
221
|
-
[genAiAttributes.GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE]: completionTokens,
|
|
222
|
-
});
|
|
223
|
-
}
|
|
224
|
-
if (totalTokens !== undefined) {
|
|
225
|
-
span.setAttributes({
|
|
226
|
-
[genAiAttributes.GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE]: totalTokens,
|
|
227
|
-
});
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
131
|
|
|
231
|
-
|
|
232
|
-
* Set common response attributes
|
|
233
|
-
* @param span - The span to add attributes to
|
|
234
|
-
* @param id - The response id
|
|
235
|
-
* @param model - The response model
|
|
236
|
-
* @param timestamp - The response timestamp
|
|
237
|
-
*/
|
|
238
|
-
function setCommonResponseAttributes(span, id, model, timestamp) {
|
|
239
|
-
span.setAttributes({
|
|
240
|
-
[genAiAttributes.OPENAI_RESPONSE_ID_ATTRIBUTE]: id,
|
|
241
|
-
[genAiAttributes.GEN_AI_RESPONSE_ID_ATTRIBUTE]: id,
|
|
242
|
-
});
|
|
243
|
-
span.setAttributes({
|
|
244
|
-
[genAiAttributes.OPENAI_RESPONSE_MODEL_ATTRIBUTE]: model,
|
|
245
|
-
[genAiAttributes.GEN_AI_RESPONSE_MODEL_ATTRIBUTE]: model,
|
|
246
|
-
});
|
|
247
|
-
span.setAttributes({
|
|
248
|
-
[genAiAttributes.OPENAI_RESPONSE_TIMESTAMP_ATTRIBUTE]: new Date(timestamp * 1000).toISOString(),
|
|
249
|
-
});
|
|
132
|
+
span.setAttributes(attrs);
|
|
250
133
|
}
|
|
251
134
|
|
|
252
135
|
/**
|
|
@@ -291,17 +174,8 @@ function extractRequestParameters(params) {
|
|
|
291
174
|
return attributes;
|
|
292
175
|
}
|
|
293
176
|
|
|
294
|
-
exports.
|
|
295
|
-
exports.addConversationAttributes = addConversationAttributes;
|
|
296
|
-
exports.addEmbeddingsAttributes = addEmbeddingsAttributes;
|
|
297
|
-
exports.addResponsesApiAttributes = addResponsesApiAttributes;
|
|
177
|
+
exports.addResponseAttributes = addResponseAttributes;
|
|
298
178
|
exports.extractRequestParameters = extractRequestParameters;
|
|
299
179
|
exports.isChatCompletionChunk = isChatCompletionChunk;
|
|
300
|
-
exports.isChatCompletionResponse = isChatCompletionResponse;
|
|
301
|
-
exports.isConversationResponse = isConversationResponse;
|
|
302
|
-
exports.isEmbeddingsResponse = isEmbeddingsResponse;
|
|
303
|
-
exports.isResponsesApiResponse = isResponsesApiResponse;
|
|
304
180
|
exports.isResponsesApiStreamEvent = isResponsesApiStreamEvent;
|
|
305
|
-
exports.setCommonResponseAttributes = setCommonResponseAttributes;
|
|
306
|
-
exports.setTokenUsageAttributes = setTokenUsageAttributes;
|
|
307
181
|
//# 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_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":["GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE","GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE","OPENAI_RESPONSE_MODEL_ATTRIBUTE","GEN_AI_RESPONSE_MODEL_ATTRIBUTE","OPENAI_RESPONSE_ID_ATTRIBUTE","GEN_AI_RESPONSE_ID_ATTRIBUTE","GEN_AI_CONVERSATION_ID_ATTRIBUTE","OPENAI_RESPONSE_TIMESTAMP_ATTRIBUTE","OPENAI_USAGE_PROMPT_TOKENS_ATTRIBUTE","GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE","OPENAI_USAGE_COMPLETION_TOKENS_ATTRIBUTE","GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE","GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE","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"],"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 type { SpanAttributeValue } 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_TEXT_ATTRIBUTE,\n GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE,\n GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE,\n GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE,\n GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE,\n} from '../ai/gen-ai-attributes';\nimport type { ChatCompletionChunk, ResponseStreamingEvent } from './types';\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 response attributes to a span using duck-typing.\n * Works for Chat Completions, Responses API, Embeddings, and Conversations API responses.\n */\nexport function addResponseAttributes(span: Span, result: unknown, recordOutputs?: boolean): void {\n if (!result || typeof result !== 'object') return;\n\n const response = result as Record<string, unknown>;\n const attrs: Record<string, SpanAttributeValue> = {};\n\n // Response ID\n if (typeof response.id === 'string') {\n attrs[GEN_AI_RESPONSE_ID_ATTRIBUTE] = response.id;\n }\n\n // Response model\n if (typeof response.model === 'string') {\n attrs[GEN_AI_RESPONSE_MODEL_ATTRIBUTE] = response.model;\n }\n\n // Conversation ID (conversation objects use id as conversation link)\n if (response.object === 'conversation' && typeof response.id === 'string') {\n attrs[GEN_AI_CONVERSATION_ID_ATTRIBUTE] = response.id;\n }\n\n // Token usage — supports both naming conventions (chat: prompt_tokens/completion_tokens, responses: input_tokens/output_tokens)\n if (response.usage && typeof response.usage === 'object') {\n const usage = response.usage as Record<string, unknown>;\n\n const inputTokens = usage.prompt_tokens ?? usage.input_tokens;\n if (typeof inputTokens === 'number') {\n attrs[GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE] = inputTokens;\n }\n\n const outputTokens = usage.completion_tokens ?? usage.output_tokens;\n if (typeof outputTokens === 'number') {\n attrs[GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE] = outputTokens;\n }\n\n if (typeof usage.total_tokens === 'number') {\n attrs[GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE] = usage.total_tokens;\n }\n }\n\n // Finish reasons from choices (chat completions)\n if (Array.isArray(response.choices)) {\n const choices = response.choices as Array<Record<string, unknown>>;\n const finishReasons = choices\n .map(choice => choice.finish_reason)\n .filter((reason): reason is string => typeof reason === 'string');\n if (finishReasons.length > 0) {\n attrs[GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE] = JSON.stringify(finishReasons);\n }\n\n if (recordOutputs) {\n // Response text from choices\n const responseTexts = choices.map(choice => {\n const message = choice.message as Record<string, unknown> | undefined;\n return (message?.content as string) || '';\n });\n attrs[GEN_AI_RESPONSE_TEXT_ATTRIBUTE] = JSON.stringify(responseTexts);\n\n // Tool calls from choices\n const toolCalls = choices\n .map(choice => {\n const message = choice.message as Record<string, unknown> | undefined;\n return message?.tool_calls;\n })\n .filter(calls => Array.isArray(calls) && calls.length > 0)\n .flat();\n\n if (toolCalls.length > 0) {\n attrs[GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE] = JSON.stringify(toolCalls);\n }\n }\n }\n\n // Finish reason from status (responses API)\n if (typeof response.status === 'string') {\n // Only set if not already set from choices\n if (!attrs[GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE]) {\n attrs[GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE] = JSON.stringify([response.status]);\n }\n }\n\n if (recordOutputs) {\n // Response text from output_text (responses API)\n if (typeof response.output_text === 'string' && !attrs[GEN_AI_RESPONSE_TEXT_ATTRIBUTE]) {\n attrs[GEN_AI_RESPONSE_TEXT_ATTRIBUTE] = response.output_text;\n }\n\n // Tool calls from output array (responses API)\n if (Array.isArray(response.output) && response.output.length > 0 && !attrs[GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE]) {\n const functionCalls = (response.output as Array<Record<string, unknown>>).filter(\n item => item?.type === 'function_call',\n );\n if (functionCalls.length > 0) {\n attrs[GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE] = JSON.stringify(functionCalls);\n }\n }\n }\n\n span.setAttributes(attrs);\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":["GEN_AI_RESPONSE_ID_ATTRIBUTE","GEN_AI_RESPONSE_MODEL_ATTRIBUTE","GEN_AI_CONVERSATION_ID_ATTRIBUTE","GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE","GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE","GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE","GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE","GEN_AI_RESPONSE_TEXT_ATTRIBUTE","GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE","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"],"mappings":"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"}
|
|
@@ -8,9 +8,16 @@ const spanUtils = require('../utils/spanUtils.js');
|
|
|
8
8
|
*/
|
|
9
9
|
class SentryNonRecordingSpan {
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Reason why this span was dropped, if applicable ('ignored' or 'sample_rate').
|
|
13
|
+
* Used to propagate the correct client report outcome to descendant spans
|
|
14
|
+
* when span streaming is enabled.
|
|
15
|
+
*/
|
|
16
|
+
|
|
11
17
|
constructor(spanContext = {}) {
|
|
12
18
|
this._traceId = spanContext.traceId || propagationContext.generateTraceId();
|
|
13
19
|
this._spanId = spanContext.spanId || propagationContext.generateSpanId();
|
|
20
|
+
this.dropReason = spanContext.dropReason;
|
|
14
21
|
}
|
|
15
22
|
|
|
16
23
|
/** @inheritdoc */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sentryNonRecordingSpan.js","sources":["../../../src/tracing/sentryNonRecordingSpan.ts"],"sourcesContent":["import type {\n SentrySpanArguments,\n Span,\n SpanAttributes,\n SpanAttributeValue,\n SpanContextData,\n SpanTimeInput,\n} from '../types-hoist/span';\nimport type { SpanStatus } from '../types-hoist/spanStatus';\nimport { generateSpanId, generateTraceId } from '../utils/propagationContext';\nimport { TRACE_FLAG_NONE } from '../utils/spanUtils';\n\n/**\n * A Sentry Span that is non-recording, meaning it will not be sent to Sentry.\n */\nexport class SentryNonRecordingSpan implements Span {\n private _traceId: string;\n private _spanId: string;\n\n public constructor(spanContext:
|
|
1
|
+
{"version":3,"file":"sentryNonRecordingSpan.js","sources":["../../../src/tracing/sentryNonRecordingSpan.ts"],"sourcesContent":["import type { EventDropReason } from '../types-hoist/clientreport';\nimport type {\n SentrySpanArguments,\n Span,\n SpanAttributes,\n SpanAttributeValue,\n SpanContextData,\n SpanTimeInput,\n} from '../types-hoist/span';\nimport type { SpanStatus } from '../types-hoist/spanStatus';\nimport { generateSpanId, generateTraceId } from '../utils/propagationContext';\nimport { TRACE_FLAG_NONE } from '../utils/spanUtils';\n\ninterface SentryNonRecordingSpanArguments extends SentrySpanArguments {\n dropReason?: EventDropReason;\n}\n\n/**\n * A Sentry Span that is non-recording, meaning it will not be sent to Sentry.\n */\nexport class SentryNonRecordingSpan implements Span {\n private _traceId: string;\n private _spanId: string;\n\n /**\n * Reason why this span was dropped, if applicable ('ignored' or 'sample_rate').\n * Used to propagate the correct client report outcome to descendant spans\n * when span streaming is enabled.\n */\n public dropReason?: EventDropReason;\n\n public constructor(spanContext: SentryNonRecordingSpanArguments = {}) {\n this._traceId = spanContext.traceId || generateTraceId();\n this._spanId = spanContext.spanId || generateSpanId();\n this.dropReason = spanContext.dropReason;\n }\n\n /** @inheritdoc */\n public spanContext(): SpanContextData {\n return {\n spanId: this._spanId,\n traceId: this._traceId,\n traceFlags: TRACE_FLAG_NONE,\n };\n }\n\n /** @inheritdoc */\n public end(_timestamp?: SpanTimeInput): void {}\n\n /** @inheritdoc */\n public setAttribute(_key: string, _value: SpanAttributeValue | undefined): this {\n return this;\n }\n\n /** @inheritdoc */\n public setAttributes(_values: SpanAttributes): this {\n return this;\n }\n\n /** @inheritdoc */\n public setStatus(_status: SpanStatus): this {\n return this;\n }\n\n /** @inheritdoc */\n public updateName(_name: string): this {\n return this;\n }\n\n /** @inheritdoc */\n public isRecording(): boolean {\n return false;\n }\n\n /** @inheritdoc */\n public addEvent(\n _name: string,\n _attributesOrStartTime?: SpanAttributes | SpanTimeInput,\n _startTime?: SpanTimeInput,\n ): this {\n return this;\n }\n\n /** @inheritDoc */\n public addLink(_link: unknown): this {\n return this;\n }\n\n /** @inheritDoc */\n public addLinks(_links: unknown[]): this {\n return this;\n }\n\n /**\n * This should generally not be used,\n * but we need it for being compliant with the OTEL Span interface.\n *\n * @hidden\n * @internal\n */\n public recordException(_exception: unknown, _time?: number | undefined): void {\n // noop\n }\n}\n"],"names":["generateTraceId","generateSpanId","TRACE_FLAG_NONE"],"mappings":";;;;;AAiBA;AACA;AACA;AACO,MAAM,wBAAuC;;AAIpD;AACA;AACA;AACA;AACA;;AAGA,GAAS,WAAW,CAAC,WAAW,GAAoC,EAAE,EAAE;AACxE,IAAI,IAAI,CAAC,QAAA,GAAW,WAAW,CAAC,OAAA,IAAWA,kCAAe,EAAE;AAC5D,IAAI,IAAI,CAAC,OAAA,GAAU,WAAW,CAAC,MAAA,IAAUC,iCAAc,EAAE;AACzD,IAAI,IAAI,CAAC,UAAA,GAAa,WAAW,CAAC,UAAU;AAC5C,EAAE;;AAEF;AACA,GAAS,WAAW,GAAoB;AACxC,IAAI,OAAO;AACX,MAAM,MAAM,EAAE,IAAI,CAAC,OAAO;AAC1B,MAAM,OAAO,EAAE,IAAI,CAAC,QAAQ;AAC5B,MAAM,UAAU,EAAEC,yBAAe;AACjC,KAAK;AACL,EAAE;;AAEF;AACA,GAAS,GAAG,CAAC,UAAU,EAAwB,CAAC;;AAEhD;AACA,GAAS,YAAY,CAAC,IAAI,EAAU,MAAM,EAAwC;AAClF,IAAI,OAAO,IAAI;AACf,EAAE;;AAEF;AACA,GAAS,aAAa,CAAC,OAAO,EAAwB;AACtD,IAAI,OAAO,IAAI;AACf,EAAE;;AAEF;AACA,GAAS,SAAS,CAAC,OAAO,EAAoB;AAC9C,IAAI,OAAO,IAAI;AACf,EAAE;;AAEF;AACA,GAAS,UAAU,CAAC,KAAK,EAAgB;AACzC,IAAI,OAAO,IAAI;AACf,EAAE;;AAEF;AACA,GAAS,WAAW,GAAY;AAChC,IAAI,OAAO,KAAK;AAChB,EAAE;;AAEF;AACA,GAAS,QAAQ;AACjB,IAAI,KAAK;AACT,IAAI,sBAAsB;AAC1B,IAAI,UAAU;AACd,IAAU;AACV,IAAI,OAAO,IAAI;AACf,EAAE;;AAEF;AACA,GAAS,OAAO,CAAC,KAAK,EAAiB;AACvC,IAAI,OAAO,IAAI;AACf,EAAE;;AAEF;AACA,GAAS,QAAQ,CAAC,MAAM,EAAmB;AAC3C,IAAI,OAAO,IAAI;AACf,EAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAS,eAAe,CAAC,UAAU,EAAW,KAAK,EAA6B;AAChF;AACA,EAAE;AACF;;;;"}
|
|
@@ -11,8 +11,11 @@ const time = require('../utils/time.js');
|
|
|
11
11
|
const dynamicSamplingContext = require('./dynamicSamplingContext.js');
|
|
12
12
|
const logSpans = require('./logSpans.js');
|
|
13
13
|
const measurement = require('./measurement.js');
|
|
14
|
+
const hasSpanStreamingEnabled = require('./spans/hasSpanStreamingEnabled.js');
|
|
14
15
|
const utils = require('./utils.js');
|
|
15
16
|
|
|
17
|
+
/* eslint-disable max-lines */
|
|
18
|
+
|
|
16
19
|
const MAX_SPAN_COUNT = 1000;
|
|
17
20
|
|
|
18
21
|
/**
|
|
@@ -203,6 +206,30 @@ class SentrySpan {
|
|
|
203
206
|
};
|
|
204
207
|
}
|
|
205
208
|
|
|
209
|
+
/**
|
|
210
|
+
* Get {@link StreamedSpanJSON} representation of this span.
|
|
211
|
+
*
|
|
212
|
+
* @hidden
|
|
213
|
+
* @internal This method is purely for internal purposes and should not be used outside
|
|
214
|
+
* of SDK code. If you need to get a JSON representation of a span,
|
|
215
|
+
* use `spanToStreamedSpanJSON(span)` instead.
|
|
216
|
+
*/
|
|
217
|
+
getStreamedSpanJSON() {
|
|
218
|
+
return {
|
|
219
|
+
name: this._name ?? '',
|
|
220
|
+
span_id: this._spanId,
|
|
221
|
+
trace_id: this._traceId,
|
|
222
|
+
parent_span_id: this._parentSpanId,
|
|
223
|
+
start_timestamp: this._startTime,
|
|
224
|
+
// just in case _endTime is not set, we use the start time (i.e. duration 0)
|
|
225
|
+
end_timestamp: this._endTime ?? this._startTime,
|
|
226
|
+
is_segment: this._isStandaloneSpan || this === spanUtils.getRootSpan(this),
|
|
227
|
+
status: spanUtils.getSimpleStatusMessage(this._status),
|
|
228
|
+
attributes: this._attributes,
|
|
229
|
+
links: spanUtils.getStreamedSpanLinks(this._links),
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
|
|
206
233
|
/** @inheritdoc */
|
|
207
234
|
isRecording() {
|
|
208
235
|
return !this._endTime && !!this._sampled;
|
|
@@ -249,6 +276,14 @@ class SentrySpan {
|
|
|
249
276
|
const client = currentScopes.getClient();
|
|
250
277
|
if (client) {
|
|
251
278
|
client.emit('spanEnd', this);
|
|
279
|
+
// Guarding sending standalone v1 spans as v2 streamed spans for now.
|
|
280
|
+
// Otherwise they'd be sent once as v1 spans and again as streamed spans.
|
|
281
|
+
// We'll migrate CLS and LCP spans to streamed spans in a later PR and
|
|
282
|
+
// INP spans in the next major of the SDK. At that point, we can fully remove
|
|
283
|
+
// standalone v1 spans <3
|
|
284
|
+
if (!this._isStandaloneSpan) {
|
|
285
|
+
client.emit('afterSpanEnd', this);
|
|
286
|
+
}
|
|
252
287
|
}
|
|
253
288
|
|
|
254
289
|
// A segment span is basically the root span of a local span tree.
|
|
@@ -272,6 +307,10 @@ class SentrySpan {
|
|
|
272
307
|
}
|
|
273
308
|
}
|
|
274
309
|
return;
|
|
310
|
+
} else if (client && hasSpanStreamingEnabled.hasSpanStreamingEnabled(client)) {
|
|
311
|
+
// TODO (spans): Remove standalone span custom logic in favor of sending simple v2 web vital spans
|
|
312
|
+
client.emit('afterSegmentSpanEnd', this);
|
|
313
|
+
return;
|
|
275
314
|
}
|
|
276
315
|
|
|
277
316
|
const transactionEvent = this._convertSpanToTransaction();
|