@arizeai/openinference-instrumentation-openai 4.4.0 → 4.4.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arizeai/openinference-instrumentation-openai",
3
- "version": "4.4.0",
3
+ "version": "4.4.2",
4
4
  "private": false,
5
5
  "description": "OpenInference instrumentation for OpenAI",
6
6
  "keywords": [],
@@ -28,8 +28,8 @@
28
28
  "@opentelemetry/api": "^1.9.0",
29
29
  "@opentelemetry/core": "^2.8.0",
30
30
  "@opentelemetry/instrumentation": "^0.46.0",
31
- "@arizeai/openinference-core": "2.8.0",
32
- "@arizeai/openinference-semantic-conventions": "2.14.0"
31
+ "@arizeai/openinference-core": "2.8.1",
32
+ "@arizeai/openinference-semantic-conventions": "2.15.0"
33
33
  },
34
34
  "devDependencies": {
35
35
  "@opentelemetry/exporter-trace-otlp-proto": "^0.50.0",
@@ -327,6 +327,7 @@ export class OpenAIInstrumentation extends InstrumentationBase<typeof openai> {
327
327
  },
328
328
  });
329
329
  const execContext = getExecContext(span);
330
+ const recordError = (error: unknown) => endSpanWithError(span, error);
330
331
  const execPromise = safeExecuteInTheMiddle(
331
332
  () => {
332
333
  return context.with(trace.setSpan(execContext, span), () => {
@@ -336,12 +337,7 @@ export class OpenAIInstrumentation extends InstrumentationBase<typeof openai> {
336
337
  (error) => {
337
338
  // Push the error to the span
338
339
  if (error) {
339
- span.recordException(error);
340
- span.setStatus({
341
- code: SpanStatusCode.ERROR,
342
- message: error.message,
343
- });
344
- span.end();
340
+ recordError(error);
345
341
  }
346
342
  },
347
343
  );
@@ -375,6 +371,7 @@ export class OpenAIInstrumentation extends InstrumentationBase<typeof openai> {
375
371
 
376
372
  return result;
377
373
  };
374
+ observeRejection(execPromise, recordError);
378
375
  const wrappedPromise = invokeMaybeAPIPromise(execPromise, wrappedPromiseThen);
379
376
  return context.bind(execContext, wrappedPromise);
380
377
  };
@@ -404,7 +401,7 @@ export class OpenAIInstrumentation extends InstrumentationBase<typeof openai> {
404
401
  },
405
402
  });
406
403
  const execContext = getExecContext(span);
407
-
404
+ const recordError = (error: unknown) => endSpanWithError(span, error);
408
405
  const execPromise = safeExecuteInTheMiddle(
409
406
  () => {
410
407
  return context.with(trace.setSpan(execContext, span), () => {
@@ -414,12 +411,7 @@ export class OpenAIInstrumentation extends InstrumentationBase<typeof openai> {
414
411
  (error) => {
415
412
  // Push the error to the span
416
413
  if (error) {
417
- span.recordException(error);
418
- span.setStatus({
419
- code: SpanStatusCode.ERROR,
420
- message: error.message,
421
- });
422
- span.end();
414
+ recordError(error);
423
415
  }
424
416
  },
425
417
  );
@@ -439,6 +431,7 @@ export class OpenAIInstrumentation extends InstrumentationBase<typeof openai> {
439
431
  }
440
432
  return result;
441
433
  };
434
+ observeRejection(execPromise, recordError);
442
435
  const wrappedPromise = invokeMaybeAPIPromise(execPromise, wrappedPromiseThen);
443
436
  return context.bind(execContext, wrappedPromise);
444
437
  };
@@ -472,6 +465,7 @@ export class OpenAIInstrumentation extends InstrumentationBase<typeof openai> {
472
465
  },
473
466
  });
474
467
  const execContext = getExecContext(span);
468
+ const recordError = (error: unknown) => endSpanWithError(span, error);
475
469
  const execPromise = safeExecuteInTheMiddle(
476
470
  () => {
477
471
  return context.with(trace.setSpan(execContext, span), () => {
@@ -481,12 +475,7 @@ export class OpenAIInstrumentation extends InstrumentationBase<typeof openai> {
481
475
  (error) => {
482
476
  // Push the error to the span
483
477
  if (error) {
484
- span.recordException(error);
485
- span.setStatus({
486
- code: SpanStatusCode.ERROR,
487
- message: error.message,
488
- });
489
- span.end();
478
+ recordError(error);
490
479
  }
491
480
  },
492
481
  );
@@ -496,12 +485,14 @@ export class OpenAIInstrumentation extends InstrumentationBase<typeof openai> {
496
485
  span.setAttributes({
497
486
  // Do not record the output data as it can be large
498
487
  ...getEmbeddingEmbeddingsAttributes(result),
488
+ ...getEmbeddingUsageAttributes(result),
499
489
  });
500
490
  }
501
491
  span.setStatus({ code: SpanStatusCode.OK });
502
492
  span.end();
503
493
  return result;
504
494
  };
495
+ observeRejection(execPromise, recordError);
505
496
  const wrappedPromise = invokeMaybeAPIPromise(execPromise, wrappedPromiseThen);
506
497
  return context.bind(execContext, wrappedPromise);
507
498
  };
@@ -536,6 +527,7 @@ export class OpenAIInstrumentation extends InstrumentationBase<typeof openai> {
536
527
  },
537
528
  });
538
529
  const execContext = getExecContext(span);
530
+ const recordError = (error: unknown) => endSpanWithError(span, error);
539
531
  const execPromise = safeExecuteInTheMiddle(
540
532
  () => {
541
533
  return context.with(trace.setSpan(execContext, span), () => {
@@ -545,12 +537,7 @@ export class OpenAIInstrumentation extends InstrumentationBase<typeof openai> {
545
537
  (error) => {
546
538
  // Push the error to the span
547
539
  if (error) {
548
- span.recordException(error);
549
- span.setStatus({
550
- code: SpanStatusCode.ERROR,
551
- message: error.message,
552
- });
553
- span.end();
540
+ recordError(error);
554
541
  }
555
542
  },
556
543
  );
@@ -588,6 +575,7 @@ export class OpenAIInstrumentation extends InstrumentationBase<typeof openai> {
588
575
 
589
576
  return result;
590
577
  };
578
+ observeRejection(execPromise, recordError);
591
579
  const wrappedPromise = invokeMaybeAPIPromise(execPromise, wrappedPromiseThen);
592
580
  return context.bind(execContext, wrappedPromise);
593
581
  };
@@ -616,14 +604,7 @@ export class OpenAIInstrumentation extends InstrumentationBase<typeof openai> {
616
604
  },
617
605
  });
618
606
  const execContext = getExecContext(span);
619
- const recordError = (error: unknown) => {
620
- span.recordException(error instanceof Error ? error : String(error));
621
- span.setStatus({
622
- code: SpanStatusCode.ERROR,
623
- message: error instanceof Error ? error.message : String(error),
624
- });
625
- span.end();
626
- };
607
+ const recordError = (error: unknown) => endSpanWithError(span, error);
627
608
  const execPromise = safeExecuteInTheMiddle(
628
609
  () => {
629
610
  return context.with(trace.setSpan(execContext, span), () => {
@@ -1001,6 +982,19 @@ function getEmbeddingEmbeddingsAttributes(response: CreateEmbeddingResponse): At
1001
982
  }, {});
1002
983
  }
1003
984
 
985
+ /**
986
+ * Get the token usage of an embedding response
987
+ */
988
+ function getEmbeddingUsageAttributes(response: CreateEmbeddingResponse): Attributes {
989
+ if (!response.usage) {
990
+ return {};
991
+ }
992
+ return {
993
+ [SemanticConventions.LLM_TOKEN_COUNT_PROMPT]: response.usage.prompt_tokens,
994
+ [SemanticConventions.LLM_TOKEN_COUNT_TOTAL]: response.usage.total_tokens,
995
+ };
996
+ }
997
+
1004
998
  /**
1005
999
  * Consumes the stream chunks and adds them to the span
1006
1000
  */
@@ -1114,7 +1108,8 @@ function isAPIPromise<T>(promise: unknown): promise is APIPromise<T> {
1114
1108
  * failed request would leave its span open. For an APIPromise the rejection is
1115
1109
  * observed through `asResponse()`, which settles with the underlying HTTP
1116
1110
  * promise and never parses the body: parsing it here as well would consume the
1117
- * body before the caller reads it.
1111
+ * body before the caller reads it. So only a failed request is observed, not a
1112
+ * response body that fails to parse.
1118
1113
  *
1119
1114
  * @param promise - The value returned by the original SDK method
1120
1115
  * @param onRejected - Called with the rejection reason
@@ -1127,6 +1122,24 @@ function observeRejection(promise: unknown, onRejected: (error: unknown) => void
1127
1122
  }
1128
1123
  }
1129
1124
 
1125
+ /**
1126
+ * Records the error on the span, sets its status to ERROR, and ends it.
1127
+ *
1128
+ * Used both when the SDK method throws synchronously and, through
1129
+ * {@link observeRejection}, when its promise rejects (#3845).
1130
+ *
1131
+ * @param span - The span to end
1132
+ * @param error - The thrown or rejected value, which need not be an Error
1133
+ */
1134
+ function endSpanWithError(span: Span, error: unknown): void {
1135
+ span.recordException(error instanceof Error ? error : String(error));
1136
+ span.setStatus({
1137
+ code: SpanStatusCode.ERROR,
1138
+ message: error instanceof Error ? error.message : String(error),
1139
+ });
1140
+ span.end();
1141
+ }
1142
+
1130
1143
  /**
1131
1144
  * Invokes the thennable of a promise or an APIPromise.
1132
1145
  *
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 = "4.4.0";
2
+ export const VERSION = "4.4.2";