@@ -15,6 +15,32 @@ function getAiSdkOpenAiPackage (vercelAiVersion) {
15
15
return semifies ( vercelAiVersion , '>=5.0.0' ) ?
'@ai-sdk/openai' :
'@ai-sdk/[email protected] '
16
16
}
17
17
18
+ // making a different reference from the default no-op tracer in the instrumentation
19
+ // attempted to use the DD tracer provider, but it double-traces the request
20
+ // in practice, there is no need to pass in the DD OTel tracer provider, so this
21
+ // case shouldn't be an issue in practice
22
+ const myTracer = {
23
+ startActiveSpan ( ) {
24
+ const fn = arguments [ arguments . length - 1 ]
25
+
26
+ const span = {
27
+ spanContext ( ) { return { traceId : '' , spanId : '' , traceFlags : 0 } } ,
28
+ setAttribute ( ) { return this } ,
29
+ setAttributes ( ) { return this } ,
30
+ addEvent ( ) { return this } ,
31
+ addLink ( ) { return this } ,
32
+ addLinks ( ) { return this } ,
33
+ setStatus ( ) { return this } ,
34
+ updateName ( ) { return this } ,
35
+ end ( ) { return this } ,
36
+ isRecording ( ) { return false } ,
37
+ recordException ( ) { return this }
38
+ }
39
+
40
+ return fn ( span )
41
+ }
42
+ }
43
+
18
44
describe ( 'Plugin' , ( ) => {
19
45
useEnv ( {
20
46
OPENAI_API_KEY : '<not-a-real-key>'
@@ -38,6 +64,123 @@ describe('Plugin', () => {
38
64
} )
39
65
} )
40
66
67
+ describe ( 'patching behavior with experimental_telemetry options' , ( ) => {
68
+ it ( 'should not error when `isEnabled` is false' , async ( ) => {
69
+ const experimentalTelemetry = { isEnabled : false }
70
+ const result = await ai . generateText ( {
71
+ model : openai ( 'gpt-4o-mini' ) ,
72
+ system : 'You are a helpful assistant' ,
73
+ prompt : 'Hello, OpenAI!' ,
74
+ maxTokens : 100 ,
75
+ temperature : 0.5 ,
76
+ experimental_telemetry : experimentalTelemetry
77
+ } )
78
+
79
+ assert . ok ( result . text , 'Expected result to be truthy' )
80
+ assert . ok ( experimentalTelemetry . tracer == null , 'Tracer should not be set by default' )
81
+ } )
82
+
83
+ it ( 'should not error when a `tracer` is not passed in' , async ( ) => {
84
+ const checkTraces = agent . assertSomeTraces ( traces => {
85
+ const generateTextSpan = traces [ 0 ] [ 0 ]
86
+ const doGenerateSpan = traces [ 0 ] [ 1 ]
87
+
88
+ assert . strictEqual ( generateTextSpan . name , 'ai.generateText' )
89
+ assert . strictEqual ( generateTextSpan . resource , 'ai.generateText' )
90
+ assert . strictEqual ( generateTextSpan . meta [ 'ai.request.model' ] , 'gpt-4o-mini' )
91
+ assert . strictEqual ( generateTextSpan . meta [ 'ai.request.model_provider' ] , 'openai' )
92
+
93
+ assert . strictEqual ( doGenerateSpan . name , 'ai.generateText.doGenerate' )
94
+ assert . strictEqual ( doGenerateSpan . resource , 'ai.generateText.doGenerate' )
95
+ assert . strictEqual ( doGenerateSpan . meta [ 'ai.request.model' ] , 'gpt-4o-mini' )
96
+ assert . strictEqual ( doGenerateSpan . meta [ 'ai.request.model_provider' ] , 'openai' )
97
+ } )
98
+
99
+ const experimentalTelemetry = { isEnabled : true }
100
+
101
+ const result = await ai . generateText ( {
102
+ model : openai ( 'gpt-4o-mini' ) ,
103
+ system : 'You are a helpful assistant' ,
104
+ prompt : 'Hello, OpenAI!' ,
105
+ maxTokens : 100 ,
106
+ temperature : 0.5 ,
107
+ experimental_telemetry : experimentalTelemetry
108
+ } )
109
+
110
+ assert . ok ( result . text , 'Expected result to be truthy' )
111
+ assert . ok ( experimentalTelemetry . tracer != null , 'Tracer should be set when `isEnabled` is true' )
112
+
113
+ await checkTraces
114
+ } )
115
+
116
+ it ( 'should not error when only a `tracer` is not passed in' , async ( ) => {
117
+ const checkTraces = agent . assertSomeTraces ( traces => {
118
+ const generateTextSpan = traces [ 0 ] [ 0 ]
119
+ const doGenerateSpan = traces [ 0 ] [ 1 ]
120
+
121
+ assert . strictEqual ( generateTextSpan . name , 'ai.generateText' )
122
+ assert . strictEqual ( generateTextSpan . resource , 'ai.generateText' )
123
+ assert . strictEqual ( generateTextSpan . meta [ 'ai.request.model' ] , 'gpt-4o-mini' )
124
+ assert . strictEqual ( generateTextSpan . meta [ 'ai.request.model_provider' ] , 'openai' )
125
+
126
+ assert . strictEqual ( doGenerateSpan . name , 'ai.generateText.doGenerate' )
127
+ assert . strictEqual ( doGenerateSpan . resource , 'ai.generateText.doGenerate' )
128
+ assert . strictEqual ( doGenerateSpan . meta [ 'ai.request.model' ] , 'gpt-4o-mini' )
129
+ assert . strictEqual ( doGenerateSpan . meta [ 'ai.request.model_provider' ] , 'openai' )
130
+ } )
131
+
132
+ const experimentalTelemetry = { tracer : myTracer }
133
+
134
+ const result = await ai . generateText ( {
135
+ model : openai ( 'gpt-4o-mini' ) ,
136
+ system : 'You are a helpful assistant' ,
137
+ prompt : 'Hello, OpenAI!' ,
138
+ maxTokens : 100 ,
139
+ temperature : 0.5 ,
140
+ experimental_telemetry : experimentalTelemetry
141
+ } )
142
+
143
+ assert . ok ( result . text , 'Expected result to be truthy' )
144
+ assert . ok ( experimentalTelemetry . isEnabled , 'isEnabled should be set to true' )
145
+ assert . ok ( experimentalTelemetry . tracer === myTracer , 'Tracer should be set when `isEnabled` is true' )
146
+
147
+ await checkTraces
148
+ } )
149
+
150
+ it ( 'should use the passed in `tracer`' , async ( ) => {
151
+ const checkTraces = agent . assertSomeTraces ( traces => {
152
+ const generateTextSpan = traces [ 0 ] [ 0 ]
153
+ const doGenerateSpan = traces [ 0 ] [ 1 ]
154
+
155
+ assert . strictEqual ( generateTextSpan . name , 'ai.generateText' )
156
+ assert . strictEqual ( generateTextSpan . resource , 'ai.generateText' )
157
+ assert . strictEqual ( generateTextSpan . meta [ 'ai.request.model' ] , 'gpt-4o-mini' )
158
+ assert . strictEqual ( generateTextSpan . meta [ 'ai.request.model_provider' ] , 'openai' )
159
+
160
+ assert . strictEqual ( doGenerateSpan . name , 'ai.generateText.doGenerate' )
161
+ assert . strictEqual ( doGenerateSpan . resource , 'ai.generateText.doGenerate' )
162
+ assert . strictEqual ( doGenerateSpan . meta [ 'ai.request.model' ] , 'gpt-4o-mini' )
163
+ assert . strictEqual ( doGenerateSpan . meta [ 'ai.request.model_provider' ] , 'openai' )
164
+ } )
165
+
166
+ const experimentalTelemetry = { isEnabled : true , tracer : myTracer }
167
+
168
+ const result = await ai . generateText ( {
169
+ model : openai ( 'gpt-4o-mini' ) ,
170
+ system : 'You are a helpful assistant' ,
171
+ prompt : 'Hello, OpenAI!' ,
172
+ maxTokens : 100 ,
173
+ temperature : 0.5 ,
174
+ experimental_telemetry : experimentalTelemetry
175
+ } )
176
+
177
+ assert . ok ( result . text , 'Expected result to be truthy' )
178
+ assert . ok ( experimentalTelemetry . tracer === myTracer , 'Tracer should not override provided tracer' )
179
+
180
+ await checkTraces
181
+ } )
182
+ } )
183
+
41
184
it ( 'creates a span for generateText' , async ( ) => {
42
185
const checkTraces = agent . assertSomeTraces ( traces => {
43
186
const generateTextSpan = traces [ 0 ] [ 0 ]
0 commit comments