@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.
@@ -300,7 +300,7 @@ function addDefaults(params) {
300
300
  };
301
301
  }
302
302
 
303
- var version = "8.6.3";
303
+ var version = "8.6.4";
304
304
 
305
305
  const DEFAULT_MAX_DEPTH = 3;
306
306
  const MAX_STACK_LINES = 20;
@@ -433,6 +433,8 @@ const captureAiGeneration = async (client, options) => {
433
433
  if (httpStatus === undefined) {
434
434
  if (typeof options.error === 'object' && 'status' in options.error && typeof options.error.status === 'number') {
435
435
  httpStatus = options.error.status;
436
+ } else if (typeof options.error === 'object' && 'statusCode' in options.error && typeof options.error.statusCode === 'number') {
437
+ httpStatus = options.error.statusCode;
436
438
  } else {
437
439
  httpStatus = 500;
438
440
  }
@@ -539,6 +541,77 @@ const captureAiGeneration = async (client, options) => {
539
541
  }
540
542
  };
541
543
 
544
+ function addRequestId(result, response, requestIdHeader) {
545
+ if (!result || typeof result !== 'object' || Array.isArray(result)) {
546
+ return result;
547
+ }
548
+ return Object.defineProperty(result, '_request_id', {
549
+ value: response.headers.get(requestIdHeader),
550
+ enumerable: false
551
+ });
552
+ }
553
+ function getResponsePropsPromise(parentPromise) {
554
+ const responsePromise = parentPromise.responsePromise;
555
+ if (!responsePromise || typeof responsePromise.then !== 'function') {
556
+ return undefined;
557
+ }
558
+ return responsePromise;
559
+ }
560
+ function decorateProviderPromise(wrappedPromise, responsePropsPromise, requestIdHeader, preserveThenUnwrap) {
561
+ const providerPromise = wrappedPromise;
562
+ if (responsePropsPromise) {
563
+ providerPromise.asResponse = async () => (await responsePropsPromise).response;
564
+ providerPromise.withResponse = async () => {
565
+ const [props, data] = await Promise.all([responsePropsPromise, wrappedPromise]);
566
+ return {
567
+ response: props.response,
568
+ data,
569
+ request_id: props.response.headers.get(requestIdHeader)
570
+ };
571
+ };
572
+ }
573
+ if (preserveThenUnwrap) {
574
+ providerPromise._thenUnwrap = transform => {
575
+ if (!responsePropsPromise) {
576
+ throw new Error('The provider promise response metadata is unavailable');
577
+ }
578
+ const transformedPromise = Promise.all([wrappedPromise, responsePropsPromise]).then(([data, props]) => addRequestId(transform(data, props), props.response, requestIdHeader));
579
+ return decorateProviderPromise(transformedPromise, responsePropsPromise, requestIdHeader, true);
580
+ };
581
+ }
582
+ return providerPromise;
583
+ }
584
+
585
+ /**
586
+ * Keep the provider SDK helpers on a promise whose resolved value is instrumented.
587
+ * OpenAI's parse helpers compose create calls through `_thenUnwrap`, while both
588
+ * OpenAI and Anthropic expose the raw response through `asResponse` and
589
+ * `withResponse`.
590
+ */
591
+
592
+ function preserveProviderPromise(parentPromise, wrappedPromise, options = {}) {
593
+ const responsePropsPromise = getResponsePropsPromise(parentPromise);
594
+ const preserveThenUnwrap = typeof parentPromise._thenUnwrap === 'function';
595
+ const providerPromise = decorateProviderPromise(wrappedPromise, responsePropsPromise, options.requestIdHeader ?? 'x-request-id', preserveThenUnwrap);
596
+ if (!responsePropsPromise) {
597
+ const asResponse = parentPromise.asResponse?.bind(parentPromise);
598
+ if (asResponse) {
599
+ providerPromise.asResponse = asResponse;
600
+ }
601
+ const withResponse = parentPromise.withResponse?.bind(parentPromise);
602
+ if (withResponse) {
603
+ providerPromise.withResponse = async () => {
604
+ const [response, data] = await Promise.all([withResponse(), wrappedPromise]);
605
+ return {
606
+ ...response,
607
+ data
608
+ };
609
+ };
610
+ }
611
+ }
612
+ return providerPromise;
613
+ }
614
+
542
615
  /**
543
616
  * Splits an SDK stream into a monitoring branch and a caller branch without
544
617
  * allowing either branch to read ahead of the other. Unlike the SDKs' `tee()`
@@ -776,9 +849,9 @@ class WrappedMessages extends AnthropicOriginal__default.default.Messages {
776
849
  posthogParams
777
850
  } = extractPosthogParams(body);
778
851
  const startTime = Date.now();
779
- const parentPromise = super.create(anthropicParams, options);
780
852
  if (anthropicParams.stream) {
781
- return parentPromise.then(value => {
853
+ const parentPromise = super.create(anthropicParams, options);
854
+ const wrappedPromise = parentPromise.then(value => {
782
855
  let accumulatedContent = '';
783
856
  const contentBlocks = [];
784
857
  const toolsInProgress = new Map();
@@ -955,7 +1028,11 @@ class WrappedMessages extends AnthropicOriginal__default.default.Messages {
955
1028
  }
956
1029
  return value;
957
1030
  });
1031
+ return preserveProviderPromise(parentPromise, wrappedPromise, {
1032
+ requestIdHeader: 'request-id'
1033
+ });
958
1034
  } else {
1035
+ const parentPromise = super.create(anthropicParams, options);
959
1036
  const wrappedPromise = parentPromise.then(async result => {
960
1037
  if ('content' in result) {
961
1038
  const latency = (Date.now() - startTime) / 1000;
@@ -1002,7 +1079,9 @@ class WrappedMessages extends AnthropicOriginal__default.default.Messages {
1002
1079
  });
1003
1080
  throw error;
1004
1081
  });
1005
- return wrappedPromise;
1082
+ return preserveProviderPromise(parentPromise, wrappedPromise, {
1083
+ requestIdHeader: 'request-id'
1084
+ });
1006
1085
  }
1007
1086
  }
1008
1087
  }