@@ -22,21 +22,13 @@ import {
2222 GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE ,
2323 GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE ,
2424} from '../ai/gen-ai-attributes' ;
25- import {
26- DO_SPAN_NAME_PREFIX ,
27- EMBEDDINGS_OPS ,
28- GENERATE_CONTENT_OPS ,
29- INVOKE_AGENT_OPS ,
30- RERANK_OPS ,
31- toolCallSpanContextMap ,
32- } from './constants' ;
25+ import { SPAN_TO_OPERATION_NAME , toolCallSpanContextMap } from './constants' ;
3326import type { TokenSummary } from './types' ;
3427import {
3528 accumulateTokensForParent ,
3629 applyAccumulatedTokens ,
3730 applyToolDescriptionsAndTokens ,
3831 convertAvailableToolsToJsonString ,
39- getSpanOpFromName ,
4032 requestMessagesFromPrompt ,
4133} from './utils' ;
4234import type { OpenAiProviderMetadata , ProviderMetadata } from './vercel-ai-attributes' ;
@@ -64,32 +56,6 @@ import {
6456 OPERATION_NAME_ATTRIBUTE ,
6557} from './vercel-ai-attributes' ;
6658
67- /**
68- * Maps Vercel AI SDK operation names to OpenTelemetry semantic convention values
69- * @see https://opentelemetry.io/docs/specs/semconv/gen-ai/gen-ai-spans/#llm-request-spans
70- */
71- function mapVercelAiOperationName ( operationName : string ) : string {
72- // Top-level pipeline operations map to invoke_agent
73- if ( INVOKE_AGENT_OPS . has ( operationName ) ) {
74- return 'invoke_agent' ;
75- }
76- // .do* operations are the actual LLM calls
77- if ( GENERATE_CONTENT_OPS . has ( operationName ) ) {
78- return 'generate_content' ;
79- }
80- if ( EMBEDDINGS_OPS . has ( operationName ) ) {
81- return 'embeddings' ;
82- }
83- if ( RERANK_OPS . has ( operationName ) ) {
84- return 'rerank' ;
85- }
86- if ( operationName === 'ai.toolCall' ) {
87- return 'execute_tool' ;
88- }
89- // Return the original value for unknown operations
90- return operationName ;
91- }
92-
9359/**
9460 * Post-process spans emitted by the Vercel AI SDK.
9561 * This is supposed to be used in `client.on('spanStart', ...)
@@ -314,7 +280,9 @@ function processEndedVercelAiSpan(span: SpanJSON): void {
314280 // Rename AI SDK attributes to standardized gen_ai attributes
315281 // Map operation.name to OpenTelemetry semantic convention values
316282 if ( attributes [ OPERATION_NAME_ATTRIBUTE ] ) {
317- const operationName = mapVercelAiOperationName ( attributes [ OPERATION_NAME_ATTRIBUTE ] as string ) ;
283+ const operationName =
284+ SPAN_TO_OPERATION_NAME . get ( attributes [ OPERATION_NAME_ATTRIBUTE ] as string ) ??
285+ ( attributes [ OPERATION_NAME_ATTRIBUTE ] as string ) ;
318286 attributes [ GEN_AI_OPERATION_NAME_ATTRIBUTE ] = operationName ;
319287 // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
320288 delete attributes [ OPERATION_NAME_ATTRIBUTE ] ;
@@ -415,15 +383,17 @@ function processGenerateSpan(span: Span, name: string, attributes: SpanAttribute
415383 }
416384 span . setAttribute ( 'ai.streaming' , name . includes ( 'stream' ) ) ;
417385
418- // Set the op based on the span name
419- const op = getSpanOpFromName ( name ) ;
420- if ( op ) {
421- span . setAttribute ( SEMANTIC_ATTRIBUTE_SENTRY_OP , op ) ;
386+ // Set the op based on the operation name registry
387+ const operationName = SPAN_TO_OPERATION_NAME . get ( name ) ;
388+ if ( operationName ) {
389+ span . setAttribute ( SEMANTIC_ATTRIBUTE_SENTRY_OP , `gen_ai.${ operationName } ` ) ;
390+ } else if ( name . startsWith ( 'ai.stream' ) ) {
391+ span . setAttribute ( SEMANTIC_ATTRIBUTE_SENTRY_OP , 'ai.run' ) ;
422392 }
423393
424394 // For invoke_agent pipeline spans, use 'invoke_agent' as the description
425395 // to be consistent with other AI integrations (e.g. LangGraph)
426- if ( INVOKE_AGENT_OPS . has ( name ) ) {
396+ if ( operationName === 'invoke_agent' ) {
427397 if ( functionId && typeof functionId === 'string' ) {
428398 span . updateName ( `invoke_agent ${ functionId } ` ) ;
429399 } else {
@@ -433,11 +403,8 @@ function processGenerateSpan(span: Span, name: string, attributes: SpanAttribute
433403 }
434404
435405 const modelId = attributes [ AI_MODEL_ID_ATTRIBUTE ] ;
436- if ( modelId ) {
437- const doSpanPrefix = GENERATE_CONTENT_OPS . has ( name ) ? 'generate_content' : DO_SPAN_NAME_PREFIX [ name ] ;
438- if ( doSpanPrefix ) {
439- span . updateName ( `${ doSpanPrefix } ${ modelId } ` ) ;
440- }
406+ if ( modelId && operationName ) {
407+ span . updateName ( `${ operationName } ${ modelId } ` ) ;
441408 }
442409}
443410
0 commit comments