@@ -3,6 +3,7 @@ import { captureException } from '../../exports';
33import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '../../semanticAttributes' ;
44import { startSpan } from '../../tracing/trace' ;
55import type { Span , SpanAttributeValue } from '../../types-hoist/span' ;
6+ import { getActiveSpan , getRootSpan , spanToJSON } from '../../utils/spanUtils' ;
67import {
78 GEN_AI_OPERATION_NAME_ATTRIBUTE ,
89 GEN_AI_REQUEST_FREQUENCY_PENALTY_ATTRIBUTE ,
@@ -25,7 +26,7 @@ import {
2526 CHAT_PATH ,
2627 CHATS_CREATE_METHOD ,
2728 GOOGLE_GENAI_INTEGRATION_NAME ,
28- GOOGLE_GENAI_MODEL_PROPERTY ,
29+ GOOGLE_GENAI_SCOPE_MODEL_KEY ,
2930 GOOGLE_GENAI_SYSTEM_NAME ,
3031} from './constants' ;
3132import type {
@@ -39,21 +40,35 @@ import type {
3940import { shouldInstrument } from './utils' ;
4041
4142/**
42- * Extract model from parameters or context
43- * For chat instances, the model is stored during chat creation and retrieved from context
43+ * Store model information on the root span for later retrieval by chat.sendMessage
4444 */
45- export function extractModel ( params : Record < string , unknown > , context ?: unknown ) : string {
45+ function storeModelOnRootSpan ( model : string ) : void {
46+ const activeSpan = getActiveSpan ( ) ;
47+ if ( activeSpan ) {
48+ const rootSpan = getRootSpan ( activeSpan ) ;
49+ rootSpan . setAttributes ( {
50+ [ GOOGLE_GENAI_SCOPE_MODEL_KEY ] : model ,
51+ } ) ;
52+ }
53+ }
54+
55+ /**
56+ * Extract model from parameters or root span attributes
57+ * For chat instances, the model is stored on the root span during chat creation
58+ */
59+ export function extractModel ( params : Record < string , unknown > , _context ?: unknown ) : string {
4660 if ( 'model' in params && typeof params . model === 'string' ) {
4761 return params . model ;
4862 }
4963
50- // We retrieve the model from the chat context
51- // because the model is defined when the chat is created,
52- // not provided as a parameter in chat.sendMessage
53- if ( context && typeof context === 'object' ) {
54- const chatObj = context as Record < string , unknown > ;
55- if ( chatObj [ GOOGLE_GENAI_MODEL_PROPERTY ] && typeof chatObj [ GOOGLE_GENAI_MODEL_PROPERTY ] === 'string' ) {
56- return chatObj [ GOOGLE_GENAI_MODEL_PROPERTY ] ;
64+ // Try to get model from root span attributes
65+ const activeSpan = getActiveSpan ( ) ;
66+ if ( activeSpan ) {
67+ const rootSpan = getRootSpan ( activeSpan ) ;
68+ const spanData = spanToJSON ( rootSpan ) ;
69+ const modelFromSpan = spanData . data ?. [ GOOGLE_GENAI_SCOPE_MODEL_KEY ] ;
70+ if ( typeof modelFromSpan === 'string' ) {
71+ return modelFromSpan ;
5772 }
5873 }
5974
@@ -240,11 +255,9 @@ function instrumentMethod<T extends unknown[], R>(
240255 }
241256 const result = ( originalMethod as ( ...args : T ) => R ) . apply ( context , args ) ;
242257
243- if ( typeof model === 'string' && model !== 'unknown' && typeof result === 'object' ) {
244- // For chat instances, retrieve the model from the chat context.
245- // The model is defined when the chat is created,
246- // not provided as a parameter in chat.sendMessage.
247- ( result as Record < string , unknown > ) [ GOOGLE_GENAI_MODEL_PROPERTY ] = model ;
258+ if ( typeof model === 'string' && model !== 'unknown' ) {
259+ // Store model information on root span for later retrieval by chat.sendMessage
260+ storeModelOnRootSpan ( model ) ;
248261 }
249262
250263 // No response attributes for create (returns object of chat instance, not generated content)
0 commit comments