@arizeai/openinference-instrumentation-openai 2.3.1 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -0
- package/dist/esm/instrumentation.d.ts.map +1 -1
- package/dist/esm/instrumentation.js +53 -9
- package/dist/esm/instrumentation.js.map +1 -1
- package/dist/esm/responsesAttributes.js +1 -1
- package/dist/esm/responsesAttributes.js.map +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/esnext/instrumentation.d.ts.map +1 -1
- package/dist/esnext/instrumentation.js +53 -9
- package/dist/esnext/instrumentation.js.map +1 -1
- package/dist/esnext/responsesAttributes.js +2 -1
- package/dist/esnext/responsesAttributes.js.map +1 -1
- package/dist/esnext/tsconfig.esnext.tsbuildinfo +1 -1
- package/dist/esnext/version.d.ts +1 -1
- package/dist/esnext/version.js +1 -1
- package/dist/src/instrumentation.d.ts.map +1 -1
- package/dist/src/instrumentation.js +53 -9
- package/dist/src/instrumentation.js.map +1 -1
- package/dist/src/responsesAttributes.js +2 -1
- package/dist/src/responsesAttributes.js.map +1 -1
- package/dist/src/version.d.ts +1 -1
- package/dist/src/version.js +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -2
- package/src/instrumentation.ts +82 -22
- package/src/responsesAttributes.ts +1 -1
- package/src/version.ts +1 -1
package/src/instrumentation.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import openai from "openai";
|
|
1
|
+
import openai, { APIPromise } from "openai";
|
|
2
2
|
import {
|
|
3
3
|
InstrumentationBase,
|
|
4
4
|
InstrumentationConfig,
|
|
@@ -123,7 +123,7 @@ export class OpenAIInstrumentation extends InstrumentationBase<typeof openai> {
|
|
|
123
123
|
protected init(): InstrumentationModuleDefinition<typeof openai> {
|
|
124
124
|
const module = new InstrumentationNodeModuleDefinition<typeof openai>(
|
|
125
125
|
"openai",
|
|
126
|
-
["^
|
|
126
|
+
["^5.0.0"],
|
|
127
127
|
this.patch.bind(this),
|
|
128
128
|
this.unpatch.bind(this),
|
|
129
129
|
);
|
|
@@ -188,9 +188,7 @@ export class OpenAIInstrumentation extends InstrumentationBase<typeof openai> {
|
|
|
188
188
|
},
|
|
189
189
|
);
|
|
190
190
|
const execContext = getExecContext(span);
|
|
191
|
-
const execPromise = safeExecuteInTheMiddle
|
|
192
|
-
ReturnType<ChatCompletionCreateType>
|
|
193
|
-
>(
|
|
191
|
+
const execPromise = safeExecuteInTheMiddle(
|
|
194
192
|
() => {
|
|
195
193
|
return context.with(trace.setSpan(execContext, span), () => {
|
|
196
194
|
return original.apply(this, args);
|
|
@@ -208,7 +206,12 @@ export class OpenAIInstrumentation extends InstrumentationBase<typeof openai> {
|
|
|
208
206
|
}
|
|
209
207
|
},
|
|
210
208
|
);
|
|
211
|
-
|
|
209
|
+
|
|
210
|
+
const wrappedPromiseThen = (
|
|
211
|
+
result:
|
|
212
|
+
| Stream<openai.Chat.Completions.ChatCompletionChunk>
|
|
213
|
+
| openai.Chat.Completions.ChatCompletion,
|
|
214
|
+
) => {
|
|
212
215
|
if (isChatCompletionResponse(result)) {
|
|
213
216
|
// Record the results
|
|
214
217
|
span.setAttributes({
|
|
@@ -231,7 +234,11 @@ export class OpenAIInstrumentation extends InstrumentationBase<typeof openai> {
|
|
|
231
234
|
}
|
|
232
235
|
|
|
233
236
|
return result;
|
|
234
|
-
}
|
|
237
|
+
};
|
|
238
|
+
const wrappedPromise = invokeMaybeAPIPromise(
|
|
239
|
+
execPromise,
|
|
240
|
+
wrappedPromiseThen,
|
|
241
|
+
);
|
|
235
242
|
return context.bind(execContext, wrappedPromise);
|
|
236
243
|
};
|
|
237
244
|
},
|
|
@@ -270,9 +277,7 @@ export class OpenAIInstrumentation extends InstrumentationBase<typeof openai> {
|
|
|
270
277
|
);
|
|
271
278
|
const execContext = getExecContext(span);
|
|
272
279
|
|
|
273
|
-
const execPromise = safeExecuteInTheMiddle
|
|
274
|
-
ReturnType<CompletionsCreateType>
|
|
275
|
-
>(
|
|
280
|
+
const execPromise = safeExecuteInTheMiddle(
|
|
276
281
|
() => {
|
|
277
282
|
return context.with(trace.setSpan(execContext, span), () => {
|
|
278
283
|
return original.apply(this, args);
|
|
@@ -290,7 +295,9 @@ export class OpenAIInstrumentation extends InstrumentationBase<typeof openai> {
|
|
|
290
295
|
}
|
|
291
296
|
},
|
|
292
297
|
);
|
|
293
|
-
const
|
|
298
|
+
const wrappedPromiseThen = (
|
|
299
|
+
result: Completion | Stream<Completion>,
|
|
300
|
+
) => {
|
|
294
301
|
if (isCompletionResponse(result)) {
|
|
295
302
|
// Record the results
|
|
296
303
|
span.setAttributes({
|
|
@@ -305,7 +312,11 @@ export class OpenAIInstrumentation extends InstrumentationBase<typeof openai> {
|
|
|
305
312
|
span.end();
|
|
306
313
|
}
|
|
307
314
|
return result;
|
|
308
|
-
}
|
|
315
|
+
};
|
|
316
|
+
const wrappedPromise = invokeMaybeAPIPromise(
|
|
317
|
+
execPromise,
|
|
318
|
+
wrappedPromiseThen,
|
|
319
|
+
);
|
|
309
320
|
return context.bind(execContext, wrappedPromise);
|
|
310
321
|
};
|
|
311
322
|
},
|
|
@@ -342,9 +353,7 @@ export class OpenAIInstrumentation extends InstrumentationBase<typeof openai> {
|
|
|
342
353
|
},
|
|
343
354
|
});
|
|
344
355
|
const execContext = getExecContext(span);
|
|
345
|
-
const execPromise = safeExecuteInTheMiddle
|
|
346
|
-
ReturnType<EmbeddingsCreateType>
|
|
347
|
-
>(
|
|
356
|
+
const execPromise = safeExecuteInTheMiddle(
|
|
348
357
|
() => {
|
|
349
358
|
return context.with(trace.setSpan(execContext, span), () => {
|
|
350
359
|
return original.apply(this, args);
|
|
@@ -362,7 +371,7 @@ export class OpenAIInstrumentation extends InstrumentationBase<typeof openai> {
|
|
|
362
371
|
}
|
|
363
372
|
},
|
|
364
373
|
);
|
|
365
|
-
const
|
|
374
|
+
const wrappedPromiseThen = (result: CreateEmbeddingResponse) => {
|
|
366
375
|
if (result) {
|
|
367
376
|
// Record the results
|
|
368
377
|
span.setAttributes({
|
|
@@ -373,7 +382,11 @@ export class OpenAIInstrumentation extends InstrumentationBase<typeof openai> {
|
|
|
373
382
|
span.setStatus({ code: SpanStatusCode.OK });
|
|
374
383
|
span.end();
|
|
375
384
|
return result;
|
|
376
|
-
}
|
|
385
|
+
};
|
|
386
|
+
const wrappedPromise = invokeMaybeAPIPromise(
|
|
387
|
+
execPromise,
|
|
388
|
+
wrappedPromiseThen,
|
|
389
|
+
);
|
|
377
390
|
return context.bind(execContext, wrappedPromise);
|
|
378
391
|
};
|
|
379
392
|
},
|
|
@@ -415,9 +428,7 @@ export class OpenAIInstrumentation extends InstrumentationBase<typeof openai> {
|
|
|
415
428
|
},
|
|
416
429
|
);
|
|
417
430
|
const execContext = getExecContext(span);
|
|
418
|
-
const execPromise = safeExecuteInTheMiddle
|
|
419
|
-
ReturnType<ResponsesCreateType>
|
|
420
|
-
>(
|
|
431
|
+
const execPromise = safeExecuteInTheMiddle(
|
|
421
432
|
() => {
|
|
422
433
|
return context.with(trace.setSpan(execContext, span), () => {
|
|
423
434
|
return original.apply(this, args);
|
|
@@ -435,7 +446,9 @@ export class OpenAIInstrumentation extends InstrumentationBase<typeof openai> {
|
|
|
435
446
|
}
|
|
436
447
|
},
|
|
437
448
|
);
|
|
438
|
-
const
|
|
449
|
+
const wrappedPromiseThen = (
|
|
450
|
+
result: Stream<ResponseStreamEvent> | ResponseType,
|
|
451
|
+
) => {
|
|
439
452
|
const recordSpan = (result?: ResponseType) => {
|
|
440
453
|
if (!result) {
|
|
441
454
|
span.setStatus({ code: SpanStatusCode.ERROR });
|
|
@@ -468,7 +481,11 @@ export class OpenAIInstrumentation extends InstrumentationBase<typeof openai> {
|
|
|
468
481
|
}
|
|
469
482
|
|
|
470
483
|
return result;
|
|
471
|
-
}
|
|
484
|
+
};
|
|
485
|
+
const wrappedPromise = invokeMaybeAPIPromise(
|
|
486
|
+
execPromise,
|
|
487
|
+
wrappedPromiseThen,
|
|
488
|
+
);
|
|
472
489
|
return context.bind(execContext, wrappedPromise);
|
|
473
490
|
};
|
|
474
491
|
},
|
|
@@ -925,3 +942,46 @@ function getToolAndFunctionCallAttributesFromStreamChunk(
|
|
|
925
942
|
}
|
|
926
943
|
return attributes;
|
|
927
944
|
}
|
|
945
|
+
|
|
946
|
+
/**
|
|
947
|
+
* Type-guard that checks if the promise is an APIPromise.
|
|
948
|
+
*
|
|
949
|
+
* APIPromise is a class from openai that wraps promises with special behavior.
|
|
950
|
+
*
|
|
951
|
+
* @param promise - The promise to check
|
|
952
|
+
* @returns True if the promise is an APIPromise, false otherwise
|
|
953
|
+
*/
|
|
954
|
+
function isAPIPromise<T>(promise: unknown): promise is APIPromise<T> {
|
|
955
|
+
return promise instanceof APIPromise;
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
/**
|
|
959
|
+
* Invokes the thennable of a promise or an APIPromise.
|
|
960
|
+
*
|
|
961
|
+
* This is necessary to safely invoke promises returned by openai sdk methods.
|
|
962
|
+
*
|
|
963
|
+
* Without this wrapper, instrumentation will "consume" returned APIPromise instances,
|
|
964
|
+
* Making them unusable by other openai sdk methods, such as when completions.parse internally
|
|
965
|
+
* calls completions.create, expecting an APIPromise which we would otherwise consume by calling `then` on it.
|
|
966
|
+
*
|
|
967
|
+
* @param promise - The promise to invoke the thennable of
|
|
968
|
+
* @param then - The thennable to invoke
|
|
969
|
+
* @returns The promise with the thennable invoked
|
|
970
|
+
*/
|
|
971
|
+
function invokeMaybeAPIPromise<T>(
|
|
972
|
+
promise: T,
|
|
973
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
974
|
+
then: (value: any) => unknown,
|
|
975
|
+
): T {
|
|
976
|
+
if (isAPIPromise<T>(promise)) {
|
|
977
|
+
return promise._thenUnwrap(then) as T;
|
|
978
|
+
} else if (promise instanceof Promise) {
|
|
979
|
+
return promise.then(then) as T;
|
|
980
|
+
} else {
|
|
981
|
+
// eslint-disable-next-line no-console
|
|
982
|
+
console.warn(
|
|
983
|
+
"Promise is not an APIPromise or a regular promise, cannot instrument.",
|
|
984
|
+
);
|
|
985
|
+
return promise;
|
|
986
|
+
}
|
|
987
|
+
}
|
|
@@ -220,7 +220,7 @@ export function getResponsesInputMessagesAttributes(
|
|
|
220
220
|
if (typeof body.input === "string") {
|
|
221
221
|
items.push({ content: body.input, role: "user" });
|
|
222
222
|
} else {
|
|
223
|
-
items.push(...body.input);
|
|
223
|
+
items.push(...(body.input ?? []));
|
|
224
224
|
}
|
|
225
225
|
items.forEach((item, index) => {
|
|
226
226
|
const indexPrefix = `${SemanticConventions.LLM_INPUT_MESSAGES}.${index}.`;
|
package/src/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// this is an auto-generated file. see js/scripts/version-update.js
|
|
2
|
-
export const VERSION = "
|
|
2
|
+
export const VERSION = "3.1.0";
|