@@ -3,6 +3,7 @@ import { captureException } from '../../exports';
3
3
import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '../../semanticAttributes' ;
4
4
import { startSpan } from '../../tracing/trace' ;
5
5
import type { Span , SpanAttributeValue } from '../../types-hoist/span' ;
6
+ import { getActiveSpan , getRootSpan , spanToJSON } from '../../utils/spanUtils' ;
6
7
import {
7
8
GEN_AI_OPERATION_NAME_ATTRIBUTE ,
8
9
GEN_AI_REQUEST_FREQUENCY_PENALTY_ATTRIBUTE ,
@@ -25,7 +26,7 @@ import {
25
26
CHAT_PATH ,
26
27
CHATS_CREATE_METHOD ,
27
28
GOOGLE_GENAI_INTEGRATION_NAME ,
28
- GOOGLE_GENAI_MODEL_PROPERTY ,
29
+ GOOGLE_GENAI_SCOPE_MODEL_KEY ,
29
30
GOOGLE_GENAI_SYSTEM_NAME ,
30
31
} from './constants' ;
31
32
import type {
@@ -39,21 +40,35 @@ import type {
39
40
import { shouldInstrument } from './utils' ;
40
41
41
42
/**
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
44
44
*/
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 {
46
60
if ( 'model' in params && typeof params . model === 'string' ) {
47
61
return params . model ;
48
62
}
49
63
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 ;
57
72
}
58
73
}
59
74
@@ -240,11 +255,9 @@ function instrumentMethod<T extends unknown[], R>(
240
255
}
241
256
const result = ( originalMethod as ( ...args : T ) => R ) . apply ( context , args ) ;
242
257
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 ) ;
248
261
}
249
262
250
263
// No response attributes for create (returns object of chat instance, not generated content)
0 commit comments