@posthog/ai 8.6.3 → 8.6.4

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.
@@ -292,7 +292,7 @@ function addDefaults(params) {
292
292
  };
293
293
  }
294
294
 
295
- var version = "8.6.3";
295
+ var version = "8.6.4";
296
296
 
297
297
  const DEFAULT_MAX_DEPTH = 3;
298
298
  const MAX_STACK_LINES = 20;
@@ -425,6 +425,8 @@ const captureAiGeneration = async (client, options) => {
425
425
  if (httpStatus === undefined) {
426
426
  if (typeof options.error === 'object' && 'status' in options.error && typeof options.error.status === 'number') {
427
427
  httpStatus = options.error.status;
428
+ } else if (typeof options.error === 'object' && 'statusCode' in options.error && typeof options.error.statusCode === 'number') {
429
+ httpStatus = options.error.statusCode;
428
430
  } else {
429
431
  httpStatus = 500;
430
432
  }
@@ -531,6 +533,77 @@ const captureAiGeneration = async (client, options) => {
531
533
  }
532
534
  };
533
535
 
536
+ function addRequestId(result, response, requestIdHeader) {
537
+ if (!result || typeof result !== 'object' || Array.isArray(result)) {
538
+ return result;
539
+ }
540
+ return Object.defineProperty(result, '_request_id', {
541
+ value: response.headers.get(requestIdHeader),
542
+ enumerable: false
543
+ });
544
+ }
545
+ function getResponsePropsPromise(parentPromise) {
546
+ const responsePromise = parentPromise.responsePromise;
547
+ if (!responsePromise || typeof responsePromise.then !== 'function') {
548
+ return undefined;
549
+ }
550
+ return responsePromise;
551
+ }
552
+ function decorateProviderPromise(wrappedPromise, responsePropsPromise, requestIdHeader, preserveThenUnwrap) {
553
+ const providerPromise = wrappedPromise;
554
+ if (responsePropsPromise) {
555
+ providerPromise.asResponse = async () => (await responsePropsPromise).response;
556
+ providerPromise.withResponse = async () => {
557
+ const [props, data] = await Promise.all([responsePropsPromise, wrappedPromise]);
558
+ return {
559
+ response: props.response,
560
+ data,
561
+ request_id: props.response.headers.get(requestIdHeader)
562
+ };
563
+ };
564
+ }
565
+ if (preserveThenUnwrap) {
566
+ providerPromise._thenUnwrap = transform => {
567
+ if (!responsePropsPromise) {
568
+ throw new Error('The provider promise response metadata is unavailable');
569
+ }
570
+ const transformedPromise = Promise.all([wrappedPromise, responsePropsPromise]).then(([data, props]) => addRequestId(transform(data, props), props.response, requestIdHeader));
571
+ return decorateProviderPromise(transformedPromise, responsePropsPromise, requestIdHeader, true);
572
+ };
573
+ }
574
+ return providerPromise;
575
+ }
576
+
577
+ /**
578
+ * Keep the provider SDK helpers on a promise whose resolved value is instrumented.
579
+ * OpenAI's parse helpers compose create calls through `_thenUnwrap`, while both
580
+ * OpenAI and Anthropic expose the raw response through `asResponse` and
581
+ * `withResponse`.
582
+ */
583
+
584
+ function preserveProviderPromise(parentPromise, wrappedPromise, options = {}) {
585
+ const responsePropsPromise = getResponsePropsPromise(parentPromise);
586
+ const preserveThenUnwrap = typeof parentPromise._thenUnwrap === 'function';
587
+ const providerPromise = decorateProviderPromise(wrappedPromise, responsePropsPromise, options.requestIdHeader ?? 'x-request-id', preserveThenUnwrap);
588
+ if (!responsePropsPromise) {
589
+ const asResponse = parentPromise.asResponse?.bind(parentPromise);
590
+ if (asResponse) {
591
+ providerPromise.asResponse = asResponse;
592
+ }
593
+ const withResponse = parentPromise.withResponse?.bind(parentPromise);
594
+ if (withResponse) {
595
+ providerPromise.withResponse = async () => {
596
+ const [response, data] = await Promise.all([withResponse(), wrappedPromise]);
597
+ return {
598
+ ...response,
599
+ data
600
+ };
601
+ };
602
+ }
603
+ }
604
+ return providerPromise;
605
+ }
606
+
534
607
  /**
535
608
  * Splits an SDK stream into a monitoring branch and a caller branch without
536
609
  * allowing either branch to read ahead of the other. Unlike the SDKs' `tee()`
@@ -768,9 +841,9 @@ class WrappedMessages extends AnthropicOriginal.Messages {
768
841
  posthogParams
769
842
  } = extractPosthogParams(body);
770
843
  const startTime = Date.now();
771
- const parentPromise = super.create(anthropicParams, options);
772
844
  if (anthropicParams.stream) {
773
- return parentPromise.then(value => {
845
+ const parentPromise = super.create(anthropicParams, options);
846
+ const wrappedPromise = parentPromise.then(value => {
774
847
  let accumulatedContent = '';
775
848
  const contentBlocks = [];
776
849
  const toolsInProgress = new Map();
@@ -947,7 +1020,11 @@ class WrappedMessages extends AnthropicOriginal.Messages {
947
1020
  }
948
1021
  return value;
949
1022
  });
1023
+ return preserveProviderPromise(parentPromise, wrappedPromise, {
1024
+ requestIdHeader: 'request-id'
1025
+ });
950
1026
  } else {
1027
+ const parentPromise = super.create(anthropicParams, options);
951
1028
  const wrappedPromise = parentPromise.then(async result => {
952
1029
  if ('content' in result) {
953
1030
  const latency = (Date.now() - startTime) / 1000;
@@ -994,7 +1071,9 @@ class WrappedMessages extends AnthropicOriginal.Messages {
994
1071
  });
995
1072
  throw error;
996
1073
  });
997
- return wrappedPromise;
1074
+ return preserveProviderPromise(parentPromise, wrappedPromise, {
1075
+ requestIdHeader: 'request-id'
1076
+ });
998
1077
  }
999
1078
  }
1000
1079
  }