@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.
@@ -217,7 +217,7 @@ function sanitizeValues(obj) {
217
217
  return jsonSafe;
218
218
  }
219
219
 
220
- var version = "8.6.3";
220
+ var version = "8.6.4";
221
221
 
222
222
  const DEFAULT_MAX_DEPTH = 3;
223
223
  const MAX_STACK_LINES = 20;
@@ -215,7 +215,7 @@ function sanitizeValues(obj) {
215
215
  return jsonSafe;
216
216
  }
217
217
 
218
- var version = "8.6.3";
218
+ var version = "8.6.4";
219
219
 
220
220
  const DEFAULT_MAX_DEPTH = 3;
221
221
  const MAX_STACK_LINES = 20;
@@ -538,7 +538,7 @@ function formatOpenAIResponsesInput(input, instructions) {
538
538
  return messages;
539
539
  }
540
540
 
541
- var version = "8.6.3";
541
+ var version = "8.6.4";
542
542
 
543
543
  const DEFAULT_MAX_DEPTH = 3;
544
544
  const MAX_STACK_LINES = 20;
@@ -671,6 +671,8 @@ const captureAiGeneration$1 = async (client, options) => {
671
671
  if (httpStatus === undefined) {
672
672
  if (typeof options.error === 'object' && 'status' in options.error && typeof options.error.status === 'number') {
673
673
  httpStatus = options.error.status;
674
+ } else if (typeof options.error === 'object' && 'statusCode' in options.error && typeof options.error.statusCode === 'number') {
675
+ httpStatus = options.error.statusCode;
674
676
  } else {
675
677
  httpStatus = 500;
676
678
  }
@@ -850,6 +852,98 @@ function buildProviderMetadata(fields) {
850
852
  return Object.keys(metadata).length > 0 ? metadata : undefined;
851
853
  }
852
854
 
855
+ function addRequestId(result, response, requestIdHeader) {
856
+ if (!result || typeof result !== 'object' || Array.isArray(result)) {
857
+ return result;
858
+ }
859
+ return Object.defineProperty(result, '_request_id', {
860
+ value: response.headers.get(requestIdHeader),
861
+ enumerable: false
862
+ });
863
+ }
864
+ function getResponsePropsPromise(parentPromise) {
865
+ const responsePromise = parentPromise.responsePromise;
866
+ if (!responsePromise || typeof responsePromise.then !== 'function') {
867
+ return undefined;
868
+ }
869
+ return responsePromise;
870
+ }
871
+ function decorateProviderPromise(wrappedPromise, responsePropsPromise, requestIdHeader, preserveThenUnwrap) {
872
+ const providerPromise = wrappedPromise;
873
+ if (responsePropsPromise) {
874
+ providerPromise.asResponse = async () => (await responsePropsPromise).response;
875
+ providerPromise.withResponse = async () => {
876
+ const [props, data] = await Promise.all([responsePropsPromise, wrappedPromise]);
877
+ return {
878
+ response: props.response,
879
+ data,
880
+ request_id: props.response.headers.get(requestIdHeader)
881
+ };
882
+ };
883
+ }
884
+ if (preserveThenUnwrap) {
885
+ providerPromise._thenUnwrap = transform => {
886
+ if (!responsePropsPromise) {
887
+ throw new Error('The provider promise response metadata is unavailable');
888
+ }
889
+ const transformedPromise = Promise.all([wrappedPromise, responsePropsPromise]).then(([data, props]) => addRequestId(transform(data, props), props.response, requestIdHeader));
890
+ return decorateProviderPromise(transformedPromise, responsePropsPromise, requestIdHeader, true);
891
+ };
892
+ }
893
+ return providerPromise;
894
+ }
895
+
896
+ /**
897
+ * Keep the provider SDK helpers on a promise whose resolved value is instrumented.
898
+ * OpenAI's parse helpers compose create calls through `_thenUnwrap`, while both
899
+ * OpenAI and Anthropic expose the raw response through `asResponse` and
900
+ * `withResponse`.
901
+ */
902
+
903
+ function preserveProviderPromise(parentPromise, wrappedPromise, options = {}) {
904
+ const responsePropsPromise = getResponsePropsPromise(parentPromise);
905
+ const preserveThenUnwrap = typeof parentPromise._thenUnwrap === 'function';
906
+ const providerPromise = decorateProviderPromise(wrappedPromise, responsePropsPromise, options.requestIdHeader ?? 'x-request-id', preserveThenUnwrap);
907
+ if (!responsePropsPromise) {
908
+ const asResponse = parentPromise.asResponse?.bind(parentPromise);
909
+ if (asResponse) {
910
+ providerPromise.asResponse = asResponse;
911
+ }
912
+ const withResponse = parentPromise.withResponse?.bind(parentPromise);
913
+ if (withResponse) {
914
+ providerPromise.withResponse = async () => {
915
+ const [response, data] = await Promise.all([withResponse(), wrappedPromise]);
916
+ return {
917
+ ...response,
918
+ data
919
+ };
920
+ };
921
+ }
922
+ }
923
+ return providerPromise;
924
+ }
925
+
926
+ /**
927
+ * OpenAI's `Responses.parse` dispatches through `this._client.responses.create`.
928
+ * Temporarily use the provider's original `create` implementation so parsing a
929
+ * wrapped response does not capture the same request twice.
930
+ */
931
+ function callWithOriginalCreate(resource, originalCreate, callback) {
932
+ const resourceRecord = resource;
933
+ const hadOwnCreate = Object.prototype.hasOwnProperty.call(resource, 'create');
934
+ const wrappedCreate = resourceRecord['create'];
935
+ resourceRecord['create'] = originalCreate;
936
+ try {
937
+ return callback();
938
+ } finally {
939
+ if (hadOwnCreate) {
940
+ resourceRecord['create'] = wrappedCreate;
941
+ } else {
942
+ delete resourceRecord['create'];
943
+ }
944
+ }
945
+ }
946
+
853
947
  /**
854
948
  * Splits an SDK stream into a monitoring branch and a caller branch without
855
949
  * allowing either branch to read ahead of the other. Unlike the SDKs' `tee()`
@@ -1105,7 +1199,7 @@ let WrappedCompletions$1 = class WrappedCompletions extends openai.AzureOpenAI.C
1105
1199
  const startTime = Date.now();
1106
1200
  const parentPromise = super.create(openAIParams, options);
1107
1201
  if (openAIParams.stream) {
1108
- return parentPromise.then(value => {
1202
+ const wrappedPromise = parentPromise.then(value => {
1109
1203
  if (Symbol.asyncIterator in value) {
1110
1204
  const [stream1, stream2] = monitoredStreamTee(value, (iterator, controller) => new streaming.Stream(iterator, controller));
1111
1205
  (async () => {
@@ -1283,6 +1377,7 @@ let WrappedCompletions$1 = class WrappedCompletions extends openai.AzureOpenAI.C
1283
1377
  }
1284
1378
  return value;
1285
1379
  });
1380
+ return preserveProviderPromise(parentPromise, wrappedPromise);
1286
1381
  } else {
1287
1382
  const wrappedPromise = parentPromise.then(async result => {
1288
1383
  if ('choices' in result) {
@@ -1331,7 +1426,7 @@ let WrappedCompletions$1 = class WrappedCompletions extends openai.AzureOpenAI.C
1331
1426
  });
1332
1427
  throw error;
1333
1428
  });
1334
- return wrappedPromise;
1429
+ return preserveProviderPromise(parentPromise, wrappedPromise);
1335
1430
  }
1336
1431
  }
1337
1432
  };
@@ -1357,7 +1452,7 @@ let WrappedResponses$1 = class WrappedResponses extends openai.AzureOpenAI.Respo
1357
1452
  const startTime = Date.now();
1358
1453
  const parentPromise = super.create(openAIParams, options);
1359
1454
  if (openAIParams.stream) {
1360
- return parentPromise.then(value => {
1455
+ const wrappedPromise = parentPromise.then(value => {
1361
1456
  if (Symbol.asyncIterator in value) {
1362
1457
  const [stream1, stream2] = monitoredStreamTee(value, (iterator, controller) => new streaming.Stream(iterator, controller));
1363
1458
  (async () => {
@@ -1447,6 +1542,7 @@ let WrappedResponses$1 = class WrappedResponses extends openai.AzureOpenAI.Respo
1447
1542
  }
1448
1543
  return value;
1449
1544
  });
1545
+ return preserveProviderPromise(parentPromise, wrappedPromise);
1450
1546
  } else {
1451
1547
  const wrappedPromise = parentPromise.then(async result => {
1452
1548
  if ('output' in result) {
@@ -1494,7 +1590,7 @@ let WrappedResponses$1 = class WrappedResponses extends openai.AzureOpenAI.Respo
1494
1590
  });
1495
1591
  throw error;
1496
1592
  });
1497
- return wrappedPromise;
1593
+ return preserveProviderPromise(parentPromise, wrappedPromise);
1498
1594
  }
1499
1595
  }
1500
1596
  parse(body, options) {
@@ -1503,7 +1599,7 @@ let WrappedResponses$1 = class WrappedResponses extends openai.AzureOpenAI.Respo
1503
1599
  posthogParams
1504
1600
  } = extractPosthogParams(body);
1505
1601
  const startTime = Date.now();
1506
- const parentPromise = super.parse(openAIParams, options);
1602
+ const parentPromise = callWithOriginalCreate(this, super.create.bind(this), () => super.parse(openAIParams, options));
1507
1603
  const wrappedPromise = parentPromise.then(async result => {
1508
1604
  const latency = (Date.now() - startTime) / 1000;
1509
1605
  await captureAiGeneration(this.phClient, {
@@ -1547,7 +1643,7 @@ let WrappedResponses$1 = class WrappedResponses extends openai.AzureOpenAI.Respo
1547
1643
  });
1548
1644
  throw error;
1549
1645
  });
1550
- return wrappedPromise;
1646
+ return preserveProviderPromise(parentPromise, wrappedPromise);
1551
1647
  }
1552
1648
  };
1553
1649
  let WrappedEmbeddings$1 = class WrappedEmbeddings extends openai.AzureOpenAI.Embeddings {
@@ -1602,7 +1698,7 @@ let WrappedEmbeddings$1 = class WrappedEmbeddings extends openai.AzureOpenAI.Emb
1602
1698
  });
1603
1699
  throw error;
1604
1700
  });
1605
- return wrappedPromise;
1701
+ return preserveProviderPromise(parentPromise, wrappedPromise);
1606
1702
  }
1607
1703
  };
1608
1704
 
@@ -1623,25 +1719,6 @@ async function captureAiGenerationAfterSuccess(...args) {
1623
1719
  captureAiGenerationInBackground(...args);
1624
1720
  }
1625
1721
  }
1626
- function preserveAPIPromiseHelpers(parentPromise, wrappedPromise) {
1627
- const apiPromise = wrappedPromise;
1628
- if (typeof parentPromise.asResponse === 'function') {
1629
- apiPromise.asResponse = () => parentPromise.asResponse();
1630
- }
1631
- if (typeof parentPromise.withResponse === 'function') {
1632
- apiPromise.withResponse = async () => {
1633
- const [response, data] = await Promise.all([parentPromise.withResponse(), wrappedPromise]);
1634
- // swaps the `data` payload inside the SDK's generic withResponse shape; the compiler
1635
- // cannot relate the Input- and Output-instantiated conditional types
1636
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
1637
- return {
1638
- ...response,
1639
- data
1640
- };
1641
- };
1642
- }
1643
- return apiPromise;
1644
- }
1645
1722
  const TERMINAL_RESPONSE_STATUSES = new Set(['completed', 'failed', 'cancelled', 'incomplete']);
1646
1723
  function isPendingBackgroundResponse(params, response) {
1647
1724
  return params.background === true && !response.usage && !!response.status && !TERMINAL_RESPONSE_STATUSES.has(response.status);
@@ -1888,7 +1965,7 @@ class WrappedCompletions extends Completions {
1888
1965
  }
1889
1966
  return value;
1890
1967
  });
1891
- return preserveAPIPromiseHelpers(parentPromise, wrappedPromise);
1968
+ return preserveProviderPromise(parentPromise, wrappedPromise);
1892
1969
  } else {
1893
1970
  const wrappedPromise = parentPromise.then(async result => {
1894
1971
  if ('choices' in result) {
@@ -1943,7 +2020,7 @@ class WrappedCompletions extends Completions {
1943
2020
  });
1944
2021
  throw error;
1945
2022
  });
1946
- return preserveAPIPromiseHelpers(parentPromise, wrappedPromise);
2023
+ return preserveProviderPromise(parentPromise, wrappedPromise);
1947
2024
  }
1948
2025
  }
1949
2026
  }
@@ -2081,7 +2158,7 @@ class WrappedResponses extends Responses {
2081
2158
  }
2082
2159
  return value;
2083
2160
  });
2084
- return preserveAPIPromiseHelpers(parentPromise, wrappedPromise);
2161
+ return preserveProviderPromise(parentPromise, wrappedPromise);
2085
2162
  } else {
2086
2163
  const wrappedPromise = parentPromise.then(async result => {
2087
2164
  if ('output' in result) {
@@ -2140,7 +2217,7 @@ class WrappedResponses extends Responses {
2140
2217
  });
2141
2218
  throw error;
2142
2219
  });
2143
- return preserveAPIPromiseHelpers(parentPromise, wrappedPromise);
2220
+ return preserveProviderPromise(parentPromise, wrappedPromise);
2144
2221
  }
2145
2222
  }
2146
2223
  parse(body, options) {
@@ -2149,64 +2226,55 @@ class WrappedResponses extends Responses {
2149
2226
  posthogParams
2150
2227
  } = extractPosthogParams(body);
2151
2228
  const startTime = Date.now();
2152
- const originalCreate = super.create.bind(this);
2153
- const originalSelfRecord = this;
2154
- const tempCreate = originalSelfRecord['create'];
2155
- originalSelfRecord['create'] = originalCreate;
2156
- try {
2157
- const parentPromise = super.parse(openAIParams, options);
2158
- const wrappedPromise = parentPromise.then(async result => {
2159
- if (isPendingBackgroundResponse(openAIParams, result)) {
2160
- return result;
2161
- }
2162
- const latency = (Date.now() - startTime) / 1000;
2163
- await captureAiGeneration(this.phClient, {
2164
- ...posthogParams,
2165
- model: openAIParams.model ?? result.model,
2166
- provider: 'openai',
2167
- input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
2168
- output: result.output,
2169
- latency,
2170
- baseURL: this.baseURL,
2171
- modelParameters: getModelParams(body, result.service_tier),
2172
- httpStatus: 200,
2173
- usage: {
2174
- inputTokens: result.usage?.input_tokens ?? 0,
2175
- outputTokens: result.usage?.output_tokens ?? 0,
2176
- reasoningTokens: result.usage?.output_tokens_details?.reasoning_tokens ?? 0,
2177
- cacheReadInputTokens: result.usage?.input_tokens_details?.cached_tokens ?? 0,
2178
- rawUsage: result.usage
2179
- },
2180
- stopReason: result.status ?? undefined,
2181
- completionId: result.id,
2182
- providerMetadata: buildProviderMetadata({
2183
- requestId: extractRequestId(result)
2184
- })
2185
- });
2229
+ const parentPromise = callWithOriginalCreate(this, super.create.bind(this), () => super.parse(openAIParams, options));
2230
+ const wrappedPromise = parentPromise.then(async result => {
2231
+ if (isPendingBackgroundResponse(openAIParams, result)) {
2186
2232
  return result;
2187
- }, async error => {
2188
- await captureAiGeneration(this.phClient, {
2189
- ...posthogParams,
2190
- model: openAIParams.model,
2191
- provider: 'openai',
2192
- input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
2193
- output: [],
2194
- latency: 0,
2195
- baseURL: this.baseURL,
2196
- modelParameters: getModelParams(body),
2197
- usage: {
2198
- inputTokens: 0,
2199
- outputTokens: 0
2200
- },
2201
- error
2202
- });
2203
- throw error;
2233
+ }
2234
+ const latency = (Date.now() - startTime) / 1000;
2235
+ await captureAiGeneration(this.phClient, {
2236
+ ...posthogParams,
2237
+ model: openAIParams.model ?? result.model,
2238
+ provider: 'openai',
2239
+ input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
2240
+ output: result.output,
2241
+ latency,
2242
+ baseURL: this.baseURL,
2243
+ modelParameters: getModelParams(body, result.service_tier),
2244
+ httpStatus: 200,
2245
+ usage: {
2246
+ inputTokens: result.usage?.input_tokens ?? 0,
2247
+ outputTokens: result.usage?.output_tokens ?? 0,
2248
+ reasoningTokens: result.usage?.output_tokens_details?.reasoning_tokens ?? 0,
2249
+ cacheReadInputTokens: result.usage?.input_tokens_details?.cached_tokens ?? 0,
2250
+ rawUsage: result.usage
2251
+ },
2252
+ stopReason: result.status ?? undefined,
2253
+ completionId: result.id,
2254
+ providerMetadata: buildProviderMetadata({
2255
+ requestId: extractRequestId(result)
2256
+ })
2204
2257
  });
2205
- return preserveAPIPromiseHelpers(parentPromise, wrappedPromise);
2206
- } finally {
2207
- // Restore our wrapped create method
2208
- originalSelfRecord['create'] = tempCreate;
2209
- }
2258
+ return result;
2259
+ }, async error => {
2260
+ await captureAiGeneration(this.phClient, {
2261
+ ...posthogParams,
2262
+ model: openAIParams.model,
2263
+ provider: 'openai',
2264
+ input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
2265
+ output: [],
2266
+ latency: 0,
2267
+ baseURL: this.baseURL,
2268
+ modelParameters: getModelParams(body),
2269
+ usage: {
2270
+ inputTokens: 0,
2271
+ outputTokens: 0
2272
+ },
2273
+ error
2274
+ });
2275
+ throw error;
2276
+ });
2277
+ return preserveProviderPromise(parentPromise, wrappedPromise);
2210
2278
  }
2211
2279
  }
2212
2280
  class WrappedEmbeddings extends Embeddings {
@@ -2263,7 +2331,7 @@ class WrappedEmbeddings extends Embeddings {
2263
2331
  });
2264
2332
  throw error;
2265
2333
  });
2266
- return preserveAPIPromiseHelpers(parentPromise, wrappedPromise);
2334
+ return preserveProviderPromise(parentPromise, wrappedPromise);
2267
2335
  }
2268
2336
  }
2269
2337
  class WrappedAudio extends Audio {
@@ -2373,7 +2441,7 @@ class WrappedTranscriptions extends Transcriptions {
2373
2441
  }
2374
2442
  return value;
2375
2443
  });
2376
- return preserveAPIPromiseHelpers(parentPromise, wrappedPromise);
2444
+ return preserveProviderPromise(parentPromise, wrappedPromise);
2377
2445
  } else {
2378
2446
  const wrappedPromise = parentPromise.then(async result => {
2379
2447
  if (result && typeof result === 'object' && 'text' in result) {
@@ -2414,7 +2482,7 @@ class WrappedTranscriptions extends Transcriptions {
2414
2482
  });
2415
2483
  throw error;
2416
2484
  });
2417
- return preserveAPIPromiseHelpers(parentPromise, wrappedPromise);
2485
+ return preserveProviderPromise(parentPromise, wrappedPromise);
2418
2486
  }
2419
2487
  }
2420
2488
  }