@@ -26,18 +26,13 @@ import {
2626 GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE ,
2727} from '../ai/gen-ai-attributes' ;
2828import { truncateGenAiMessages } from '../ai/messageTruncation' ;
29- import { buildMethodPath , extractSystemInstructions , getOperationName , resolveAIRecordingOptions } from '../ai/utils' ;
30- import { CHAT_PATH , CHATS_CREATE_METHOD , GOOGLE_GENAI_SYSTEM_NAME } from './constants' ;
29+ import type { InstrumentedMethodEntry } from '../ai/utils' ;
30+ import { buildMethodPath , extractSystemInstructions , resolveAIRecordingOptions } from '../ai/utils' ;
31+ import { CHAT_PATH , CHATS_CREATE_METHOD , GOOGLE_GENAI_METHOD_REGISTRY , GOOGLE_GENAI_SYSTEM_NAME } from './constants' ;
3132import { instrumentStream } from './streaming' ;
32- import type {
33- Candidate ,
34- ContentPart ,
35- GoogleGenAIIstrumentedMethod ,
36- GoogleGenAIOptions ,
37- GoogleGenAIResponse ,
38- } from './types' ;
33+ import type { Candidate , ContentPart , GoogleGenAIOptions , GoogleGenAIResponse } from './types' ;
3934import type { ContentListUnion , ContentUnion , Message , PartListUnion } from './utils' ;
40- import { contentUnionToMessages , isStreamingMethod , shouldInstrument } from './utils' ;
35+ import { contentUnionToMessages } from './utils' ;
4136
4237/**
4338 * Extract model from parameters or chat context object
@@ -99,13 +94,13 @@ function extractConfigAttributes(config: Record<string, unknown>): Record<string
9994 * Builds the base attributes for span creation including system info, model, and config
10095 */
10196function extractRequestAttributes (
102- methodPath : string ,
97+ operationName : string ,
10398 params ?: Record < string , unknown > ,
10499 context ?: unknown ,
105100) : Record < string , SpanAttributeValue > {
106101 const attributes : Record < string , SpanAttributeValue > = {
107102 [ GEN_AI_SYSTEM_ATTRIBUTE ] : GOOGLE_GENAI_SYSTEM_NAME ,
108- [ GEN_AI_OPERATION_NAME_ATTRIBUTE ] : getOperationName ( methodPath ) ,
103+ [ GEN_AI_OPERATION_NAME_ATTRIBUTE ] : operationName ,
109104 [ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] : 'auto.ai.google_genai' ,
110105 } ;
111106
@@ -251,21 +246,22 @@ function addResponseAttributes(span: Span, response: GoogleGenAIResponse, record
251246 */
252247function instrumentMethod < T extends unknown [ ] , R > (
253248 originalMethod : ( ...args : T ) => R | Promise < R > ,
254- methodPath : GoogleGenAIIstrumentedMethod ,
249+ methodPath : string ,
250+ instrumentedMethod : InstrumentedMethodEntry ,
255251 context : unknown ,
256252 options : GoogleGenAIOptions ,
257253) : ( ...args : T ) => R | Promise < R > {
258254 const isSyncCreate = methodPath === CHATS_CREATE_METHOD ;
259255
260256 return new Proxy ( originalMethod , {
261257 apply ( target , _ , args : T ) : R | Promise < R > {
258+ const operationName = instrumentedMethod . operation ;
262259 const params = args [ 0 ] as Record < string , unknown > | undefined ;
263- const requestAttributes = extractRequestAttributes ( methodPath , params , context ) ;
260+ const requestAttributes = extractRequestAttributes ( operationName , params , context ) ;
264261 const model = requestAttributes [ GEN_AI_REQUEST_MODEL_ATTRIBUTE ] ?? 'unknown' ;
265- const operationName = getOperationName ( methodPath ) ;
266262
267263 // Check if this is a streaming method
268- if ( isStreamingMethod ( methodPath ) ) {
264+ if ( instrumentedMethod . streaming ) {
269265 // Use startSpanManual for streaming methods to control span lifecycle
270266 return startSpanManual (
271267 {
@@ -338,12 +334,19 @@ function createDeepProxy<T extends object>(target: T, currentPath = '', options:
338334 const value = Reflect . get ( t , prop , receiver ) ;
339335 const methodPath = buildMethodPath ( currentPath , String ( prop ) ) ;
340336
341- if ( typeof value === 'function' && shouldInstrument ( methodPath ) ) {
337+ const instrumentedMethod = GOOGLE_GENAI_METHOD_REGISTRY [ methodPath as keyof typeof GOOGLE_GENAI_METHOD_REGISTRY ] ;
338+ if ( typeof value === 'function' && instrumentedMethod ) {
342339 // Special case: chats.create is synchronous but needs both instrumentation AND result proxying
343340 if ( methodPath === CHATS_CREATE_METHOD ) {
344- const instrumentedMethod = instrumentMethod ( value as ( ...args : unknown [ ] ) => unknown , methodPath , t , options ) ;
341+ const wrappedMethod = instrumentMethod (
342+ value as ( ...args : unknown [ ] ) => unknown ,
343+ methodPath ,
344+ instrumentedMethod ,
345+ t ,
346+ options ,
347+ ) ;
345348 return function instrumentedAndProxiedCreate ( ...args : unknown [ ] ) : unknown {
346- const result = instrumentedMethod ( ...args ) ;
349+ const result = wrappedMethod ( ...args ) ;
347350 // If the result is an object (like a chat instance), proxy it too
348351 if ( result && typeof result === 'object' ) {
349352 return createDeepProxy ( result , CHAT_PATH , options ) ;
@@ -352,7 +355,13 @@ function createDeepProxy<T extends object>(target: T, currentPath = '', options:
352355 } ;
353356 }
354357
355- return instrumentMethod ( value as ( ...args : unknown [ ] ) => Promise < unknown > , methodPath , t , options ) ;
358+ return instrumentMethod (
359+ value as ( ...args : unknown [ ] ) => Promise < unknown > ,
360+ methodPath ,
361+ instrumentedMethod ,
362+ t ,
363+ options ,
364+ ) ;
356365 }
357366
358367 if ( typeof value === 'function' ) {
0 commit comments