@@ -2,10 +2,14 @@ import {IconArrow} from 'sentry/icons';
22import { t } from 'sentry/locale' ;
33import type { EventTransaction } from 'sentry/types/event' ;
44import type { Organization } from 'sentry/types/organization' ;
5+ import { formatAbbreviatedNumberWithDynamicPrecision } from 'sentry/utils/formatters' ;
56import { prettifyAttributeName } from 'sentry/views/explore/components/traceItemAttributes/utils' ;
67import type { TraceItemResponseAttribute } from 'sentry/views/explore/hooks/useTraceItemDetails' ;
78import { hasAgentInsightsFeature } from 'sentry/views/insights/agentMonitoring/utils/features' ;
8- import { getIsAiSpan } from 'sentry/views/insights/agentMonitoring/utils/query' ;
9+ import {
10+ getIsAiSpan ,
11+ legacyAttributeKeys ,
12+ } from 'sentry/views/insights/agentMonitoring/utils/query' ;
913import {
1014 isEAPSpanNode ,
1115 isSpanNode ,
@@ -32,6 +36,29 @@ function ensureAttributeObject(
3236 return attributes ;
3337}
3438
39+ /**
40+ * Get an attribute from the attribute object, checking both the current and legacy keys.
41+ * @param attributeObject - The attribute object.
42+ * @param key - The key to check.
43+ * @returns The attribute value, or undefined if the attribute is not found.
44+ */
45+ function getAttribute ( attributeObject : Record < string , string > , key : string ) {
46+ if ( attributeObject [ key ] ) {
47+ return attributeObject [ key ] ;
48+ }
49+ const legacyKeys = legacyAttributeKeys . get ( key ) ?? [ ] ;
50+ for ( const legacyKey of legacyKeys ) {
51+ if ( attributeObject [ legacyKey ] ) {
52+ return attributeObject [ legacyKey ] ;
53+ }
54+ }
55+ return undefined ;
56+ }
57+
58+ function formatCost ( cost : string ) {
59+ return `US $${ formatAbbreviatedNumberWithDynamicPrecision ( cost ) } ` ;
60+ }
61+
3562export function getHighlightedSpanAttributes ( {
3663 op,
3764 description,
@@ -51,16 +78,17 @@ export function getHighlightedSpanAttributes({
5178 const attributeObject = ensureAttributeObject ( attributes ) ;
5279 const highlightedAttributes = [ ] ;
5380
54- if ( attributeObject [ 'ai.model.id' ] ) {
81+ const model = getAttribute ( attributeObject , 'gen_ai.request.model' ) ;
82+ if ( model ) {
5583 highlightedAttributes . push ( {
5684 name : t ( 'Model' ) ,
57- value : attributeObject [ 'ai. model.id' ] ,
85+ value : model ,
5886 } ) ;
5987 }
6088
61- const promptTokens = attributeObject [ 'ai.prompt_tokens.used' ] ;
62- const completionTokens = attributeObject [ 'ai.completion_tokens.used' ] ;
63- const totalTokens = attributeObject [ 'ai.total_tokens.used' ] ;
89+ const promptTokens = getAttribute ( attributeObject , 'gen_ai.usage.input_tokens' ) ;
90+ const completionTokens = getAttribute ( attributeObject , 'gen_ai.usage.output_tokens' ) ;
91+ const totalTokens = getAttribute ( attributeObject , 'gen_ai.usage.total_tokens' ) ;
6492 if ( promptTokens && completionTokens && totalTokens ) {
6593 highlightedAttributes . push ( {
6694 name : t ( 'Tokens' ) ,
@@ -73,6 +101,14 @@ export function getHighlightedSpanAttributes({
73101 } ) ;
74102 }
75103
104+ const totalCosts = getAttribute ( attributeObject , 'gen_ai.usage.total_cost' ) ;
105+ if ( totalCosts ) {
106+ highlightedAttributes . push ( {
107+ name : t ( 'Cost' ) ,
108+ value : formatCost ( totalCosts ) ,
109+ } ) ;
110+ }
111+
76112 if ( attributeObject [ 'ai.toolCall.name' ] ) {
77113 highlightedAttributes . push ( {
78114 name : t ( 'Tool Name' ) ,
0 commit comments