@@ -26,13 +26,7 @@ import {
2626import { buildMethodPath , getFinalOperationName , getSpanOperation , setTokenUsageAttributes } from '../ai/utils' ;
2727import { handleCallbackErrors } from '../handleCallbackErrors' ;
2828import { instrumentStream } from './streaming' ;
29- import type {
30- AnthropicAiInstrumentedMethod ,
31- AnthropicAiOptions ,
32- AnthropicAiResponse ,
33- AnthropicAiStreamingEvent ,
34- ContentBlock ,
35- } from './types' ;
29+ import type { AnthropicAiInstrumentedMethod , AnthropicAiOptions , AnthropicAiResponse , ContentBlock } from './types' ;
3630import { shouldInstrument } from './utils' ;
3731
3832/**
@@ -205,82 +199,82 @@ function instrumentMethod<T extends unknown[], R>(
205199 context : unknown ,
206200 options : AnthropicAiOptions ,
207201) : ( ...args : T ) => Promise < R > {
208- return async function instrumentedMethod ( ...args : T ) : Promise < R > {
209- const requestAttributes = extractRequestAttributes ( args , methodPath ) ;
210- const model = requestAttributes [ GEN_AI_REQUEST_MODEL_ATTRIBUTE ] ?? 'unknown' ;
211- const operationName = getFinalOperationName ( methodPath ) ;
202+ return new Proxy ( originalMethod , {
203+ apply ( target , thisArg , args : T ) : Promise < R > {
204+ const requestAttributes = extractRequestAttributes ( args , methodPath ) ;
205+ const model = requestAttributes [ GEN_AI_REQUEST_MODEL_ATTRIBUTE ] ?? 'unknown' ;
206+ const operationName = getFinalOperationName ( methodPath ) ;
212207
213- const params = typeof args [ 0 ] === 'object' ? ( args [ 0 ] as Record < string , unknown > ) : undefined ;
214- const isStreamRequested = Boolean ( params ?. stream ) ;
215- const isStreamingMethod = methodPath === 'messages.stream' ;
208+ const params = typeof args [ 0 ] === 'object' ? ( args [ 0 ] as Record < string , unknown > ) : undefined ;
209+ const isStreamRequested = Boolean ( params ?. stream ) ;
210+ const isStreamingMethod = methodPath === 'messages.stream' ;
216211
217- if ( isStreamRequested || isStreamingMethod ) {
218- return startSpanManual (
212+ if ( isStreamRequested || isStreamingMethod ) {
213+ const messageStream = target . apply ( context , args ) ;
214+
215+ // Create span for instrumentation using startSpanManual
216+ return startSpanManual (
217+ {
218+ name : `${ operationName } ${ model } stream-response` ,
219+ op : getSpanOperation ( methodPath ) ,
220+ attributes : requestAttributes as Record < string , SpanAttributeValue > ,
221+ } ,
222+ span => {
223+ try {
224+ if ( options . recordInputs && params ) {
225+ addPrivateRequestAttributes ( span , params ) ;
226+ }
227+
228+ return instrumentStream ( messageStream , span , options . recordOutputs ?? false ) ;
229+ } catch ( error ) {
230+ span . setStatus ( { code : SPAN_STATUS_ERROR , message : 'internal_error' } ) ;
231+ captureException ( error , {
232+ mechanism : {
233+ handled : false ,
234+ type : 'auto.ai.anthropic' ,
235+ data : {
236+ function : methodPath ,
237+ } ,
238+ } ,
239+ } ) ;
240+ span . end ( ) ;
241+ throw error ;
242+ }
243+ } ,
244+ ) ;
245+ }
246+
247+ return startSpan (
219248 {
220- name : `${ operationName } ${ model } stream-response ` ,
249+ name : `${ operationName } ${ model } ` ,
221250 op : getSpanOperation ( methodPath ) ,
222251 attributes : requestAttributes as Record < string , SpanAttributeValue > ,
223252 } ,
224- async span => {
225- try {
226- if ( options . recordInputs && params ) {
227- addPrivateRequestAttributes ( span , params ) ;
228- }
253+ span => {
254+ if ( options . recordInputs && params ) {
255+ addPrivateRequestAttributes ( span , params ) ;
256+ }
229257
230- const result = await originalMethod . apply ( context , args ) ;
231- return instrumentStream (
232- result as AsyncIterable < AnthropicAiStreamingEvent > ,
233- span ,
234- options . recordOutputs ?? false ,
235- ) as unknown as R ;
236- } catch ( error ) {
237- span . setStatus ( { code : SPAN_STATUS_ERROR , message : 'internal_error' } ) ;
238- captureException ( error , {
239- mechanism : {
240- handled : false ,
241- type : 'auto.ai.anthropic' ,
242- data : {
243- function : methodPath ,
258+ return handleCallbackErrors (
259+ ( ) => target . apply ( context , args ) ,
260+ error => {
261+ captureException ( error , {
262+ mechanism : {
263+ handled : false ,
264+ type : 'auto.ai.anthropic' ,
265+ data : {
266+ function : methodPath ,
267+ } ,
244268 } ,
245- } ,
246- } ) ;
247- span . end ( ) ;
248- throw error ;
249- }
269+ } ) ;
270+ } ,
271+ ( ) => { } ,
272+ result => addResponseAttributes ( span , result as AnthropicAiResponse , options . recordOutputs ) ,
273+ ) ;
250274 } ,
251275 ) ;
252- }
253-
254- return startSpan (
255- {
256- name : `${ operationName } ${ model } ` ,
257- op : getSpanOperation ( methodPath ) ,
258- attributes : requestAttributes as Record < string , SpanAttributeValue > ,
259- } ,
260- span => {
261- if ( options . recordInputs && params ) {
262- addPrivateRequestAttributes ( span , params ) ;
263- }
264-
265- return handleCallbackErrors (
266- ( ) => originalMethod . apply ( context , args ) ,
267- error => {
268- captureException ( error , {
269- mechanism : {
270- handled : false ,
271- type : 'auto.ai.anthropic' ,
272- data : {
273- function : methodPath ,
274- } ,
275- } ,
276- } ) ;
277- } ,
278- ( ) => { } ,
279- result => addResponseAttributes ( span , result as AnthropicAiResponse , options . recordOutputs ) ,
280- ) ;
281- } ,
282- ) ;
283- } ;
276+ } ,
277+ } ) as ( ...args : T ) => Promise < R > ;
284278}
285279
286280/**
0 commit comments