@posthog/ai 8.9.1 → 8.9.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.
@@ -577,7 +577,7 @@ function formatOpenAIResponsesInput(input, instructions) {
577
577
  return messages;
578
578
  }
579
579
 
580
- var version = "8.9.1";
580
+ var version = "8.9.2";
581
581
 
582
582
  const DEFAULT_MAX_DEPTH = 3;
583
583
  const MAX_STACK_LINES = 20;
@@ -734,15 +734,22 @@ const captureAiGeneration$1 = async (client, options) => {
734
734
  };
735
735
  }
736
736
  httpStatus = httpStatus ?? 200;
737
- let costOverrideData = {};
737
+
738
+ // A configured price applies only to a count the provider reported, so a call with no
739
+ // reported usage sends no cost instead of asserting $0. $ai_total_cost_usd sums the sides
740
+ // that were priced, which makes it the cost of the known side alone when the other side
741
+ // went unreported: a lower bound on the true total, not an assertion of it.
742
+ const costOverrideData = {};
738
743
  if (options.costOverride) {
739
- const inputCostUSD = (options.costOverride.inputCost ?? 0) * (usage.inputTokens ?? 0);
740
- const outputCostUSD = (options.costOverride.outputCost ?? 0) * (usage.outputTokens ?? 0);
741
- costOverrideData = {
742
- $ai_input_cost_usd: inputCostUSD,
743
- $ai_output_cost_usd: outputCostUSD,
744
- $ai_total_cost_usd: inputCostUSD + outputCostUSD
745
- };
744
+ if (usage.inputTokens !== undefined) {
745
+ costOverrideData.$ai_input_cost_usd = (options.costOverride.inputCost ?? 0) * usage.inputTokens;
746
+ }
747
+ if (usage.outputTokens !== undefined) {
748
+ costOverrideData.$ai_output_cost_usd = (options.costOverride.outputCost ?? 0) * usage.outputTokens;
749
+ }
750
+ if (Object.keys(costOverrideData).length > 0) {
751
+ costOverrideData.$ai_total_cost_usd = (costOverrideData.$ai_input_cost_usd ?? 0) + (costOverrideData.$ai_output_cost_usd ?? 0);
752
+ }
746
753
  }
747
754
 
748
755
  // The caller's own token counts override the SDK-derived ones further down, via the
@@ -786,7 +793,9 @@ const captureAiGeneration$1 = async (client, options) => {
786
793
  $ai_input: safeInput,
787
794
  $ai_output_choices: safeOutput,
788
795
  $ai_http_status: httpStatus,
789
- $ai_input_tokens: usage.inputTokens ?? 0,
796
+ ...(usage.inputTokens !== undefined ? {
797
+ $ai_input_tokens: usage.inputTokens
798
+ } : {}),
790
799
  ...(usage.outputTokens !== undefined ? {
791
800
  $ai_output_tokens: usage.outputTokens
792
801
  } : {}),
@@ -1339,8 +1348,6 @@ function monitoredStreamTee(source, createStream) {
1339
1348
  class OpenAIChatStreamAccumulator {
1340
1349
  accumulatedContent = '';
1341
1350
  usage = {
1342
- inputTokens: 0,
1343
- outputTokens: 0,
1344
1351
  webSearchCount: 0
1345
1352
  };
1346
1353
  toolCalls = new Map();
@@ -1442,8 +1449,6 @@ class OpenAIChatStreamAccumulator {
1442
1449
  class OpenAIResponsesStreamAccumulator {
1443
1450
  output = [];
1444
1451
  usage = {
1445
- inputTokens: 0,
1446
- outputTokens: 0,
1447
1452
  webSearchCount: 0
1448
1453
  };
1449
1454
  consume(event, receivedAt = Date.now()) {
@@ -1552,20 +1557,17 @@ function buildChatSuccessOptions(context, result) {
1552
1557
  })
1553
1558
  };
1554
1559
  }
1555
- function buildChatErrorOptions(context, error, metadata = {}) {
1560
+ function buildChatErrorOptions(context, error, metadata) {
1556
1561
  return {
1557
1562
  ...context.monitoring,
1558
1563
  model: context.params.model,
1559
1564
  provider: context.provider,
1560
1565
  input: sanitizeOpenAI(context.params.messages, context.client),
1561
1566
  output: [],
1562
- latency: 0,
1567
+ latency: metadata.latency,
1563
1568
  baseURL: context.baseURL,
1564
1569
  modelParameters: getModelParams(context.modelParametersSource),
1565
- usage: {
1566
- inputTokens: 0,
1567
- outputTokens: 0
1568
- },
1570
+ usage: metadata.usage ?? {},
1569
1571
  completionId: metadata.completionId,
1570
1572
  providerMetadata: buildProviderMetadata({
1571
1573
  systemFingerprint: metadata.systemFingerprint
@@ -1615,21 +1617,18 @@ function buildBackgroundResponseOptions(context, response) {
1615
1617
  includeRequestId: true
1616
1618
  });
1617
1619
  }
1618
- function buildResponsesErrorOptions(context, error, completionId) {
1620
+ function buildResponsesErrorOptions(context, error, metadata) {
1619
1621
  return {
1620
1622
  ...context.monitoring,
1621
1623
  model: context.params.model,
1622
1624
  provider: context.provider,
1623
1625
  input: buildSanitizedResponsesInput(context),
1624
1626
  output: [],
1625
- latency: 0,
1627
+ latency: metadata.latency,
1626
1628
  baseURL: context.baseURL,
1627
1629
  modelParameters: getModelParams(context.modelParametersSource),
1628
- usage: {
1629
- inputTokens: 0,
1630
- outputTokens: 0
1631
- },
1632
- completionId,
1630
+ usage: metadata.usage ?? {},
1631
+ completionId: metadata.completionId,
1633
1632
  error
1634
1633
  };
1635
1634
  }
@@ -1651,7 +1650,7 @@ function buildEmbeddingSuccessOptions(context, usage, latency) {
1651
1650
  }
1652
1651
  };
1653
1652
  }
1654
- function buildEmbeddingErrorOptions(context, error) {
1653
+ function buildEmbeddingErrorOptions(context, error, latency) {
1655
1654
  return {
1656
1655
  eventType: AIEvent.Embedding,
1657
1656
  ...context.monitoring,
@@ -1659,12 +1658,10 @@ function buildEmbeddingErrorOptions(context, error) {
1659
1658
  provider: context.provider,
1660
1659
  input: withPrivacyMode(context.client, context.monitoring.privacyMode, context.params.input),
1661
1660
  output: null,
1662
- latency: 0,
1661
+ latency,
1663
1662
  baseURL: context.baseURL,
1664
1663
  modelParameters: getModelParams(context.modelParametersSource),
1665
- usage: {
1666
- inputTokens: 0
1667
- },
1664
+ usage: {},
1668
1665
  error
1669
1666
  };
1670
1667
  }
@@ -1743,7 +1740,9 @@ let WrappedCompletions$1 = class WrappedCompletions extends AzureOpenAI.Chat.Com
1743
1740
  modelParametersSource: body
1744
1741
  }, error, {
1745
1742
  completionId: accumulated.completionId,
1746
- systemFingerprint: accumulated.systemFingerprint
1743
+ systemFingerprint: accumulated.systemFingerprint,
1744
+ usage: accumulated.usage,
1745
+ latency: (Date.now() - startTime) / 1000
1747
1746
  }));
1748
1747
  throw error;
1749
1748
  }
@@ -1789,7 +1788,9 @@ let WrappedCompletions$1 = class WrappedCompletions extends AzureOpenAI.Chat.Com
1789
1788
  params: openAIParams,
1790
1789
  monitoring: posthogParams,
1791
1790
  modelParametersSource: body
1792
- }, error));
1791
+ }, error, {
1792
+ latency: (Date.now() - startTime) / 1000
1793
+ }));
1793
1794
  throw error;
1794
1795
  });
1795
1796
  return preserveProviderPromise(parentPromise, wrappedPromise);
@@ -1891,7 +1892,11 @@ let WrappedResponses$1 = class WrappedResponses extends AzureOpenAI.Responses {
1891
1892
  params: openAIParams,
1892
1893
  monitoring: posthogParams,
1893
1894
  modelParametersSource: body
1894
- }, error, accumulated.completionId));
1895
+ }, error, {
1896
+ completionId: accumulated.completionId,
1897
+ usage: accumulated.usage,
1898
+ latency: (Date.now() - startTime) / 1000
1899
+ }));
1895
1900
  throw error;
1896
1901
  }
1897
1902
  })().catch(() => {
@@ -1939,7 +1944,9 @@ let WrappedResponses$1 = class WrappedResponses extends AzureOpenAI.Responses {
1939
1944
  params: openAIParams,
1940
1945
  monitoring: posthogParams,
1941
1946
  modelParametersSource: body
1942
- }, error));
1947
+ }, error, {
1948
+ latency: (Date.now() - startTime) / 1000
1949
+ }));
1943
1950
  throw error;
1944
1951
  });
1945
1952
  return preserveProviderPromise(parentPromise, wrappedPromise);
@@ -2031,7 +2038,9 @@ let WrappedResponses$1 = class WrappedResponses extends AzureOpenAI.Responses {
2031
2038
  params: openAIParams,
2032
2039
  monitoring: posthogParams,
2033
2040
  modelParametersSource: body
2034
- }, error));
2041
+ }, error, {
2042
+ latency: (Date.now() - startTime) / 1000
2043
+ }));
2035
2044
  throw error;
2036
2045
  });
2037
2046
  return preserveProviderPromise(parentPromise, wrappedPromise);
@@ -2068,7 +2077,7 @@ let WrappedEmbeddings$1 = class WrappedEmbeddings extends AzureOpenAI.Embeddings
2068
2077
  params: openAIParams,
2069
2078
  monitoring: posthogParams,
2070
2079
  modelParametersSource: body
2071
- }, error));
2080
+ }, error, (Date.now() - startTime) / 1000));
2072
2081
  throw error;
2073
2082
  });
2074
2083
  return preserveProviderPromise(parentPromise, wrappedPromise);
@@ -2156,7 +2165,9 @@ class WrappedCompletions extends Completions {
2156
2165
  modelParametersSource: body
2157
2166
  }, error, {
2158
2167
  completionId: accumulated.completionId,
2159
- systemFingerprint: accumulated.systemFingerprint
2168
+ systemFingerprint: accumulated.systemFingerprint,
2169
+ usage: accumulated.usage,
2170
+ latency: (Date.now() - startTime) / 1000
2160
2171
  }));
2161
2172
  throw error;
2162
2173
  }
@@ -2202,7 +2213,9 @@ class WrappedCompletions extends Completions {
2202
2213
  params: openAIParams,
2203
2214
  monitoring: posthogParams,
2204
2215
  modelParametersSource: body
2205
- }, error));
2216
+ }, error, {
2217
+ latency: (Date.now() - startTime) / 1000
2218
+ }));
2206
2219
  throw error;
2207
2220
  });
2208
2221
  return preserveProviderPromise(parentPromise, wrappedPromise);
@@ -2304,7 +2317,11 @@ class WrappedResponses extends Responses {
2304
2317
  params: openAIParams,
2305
2318
  monitoring: posthogParams,
2306
2319
  modelParametersSource: body
2307
- }, error, accumulated.completionId));
2320
+ }, error, {
2321
+ completionId: accumulated.completionId,
2322
+ usage: accumulated.usage,
2323
+ latency: (Date.now() - startTime) / 1000
2324
+ }));
2308
2325
  throw error;
2309
2326
  }
2310
2327
  })().catch(() => {
@@ -2352,7 +2369,9 @@ class WrappedResponses extends Responses {
2352
2369
  params: openAIParams,
2353
2370
  monitoring: posthogParams,
2354
2371
  modelParametersSource: body
2355
- }, error));
2372
+ }, error, {
2373
+ latency: (Date.now() - startTime) / 1000
2374
+ }));
2356
2375
  throw error;
2357
2376
  });
2358
2377
  return preserveProviderPromise(parentPromise, wrappedPromise);
@@ -2444,7 +2463,9 @@ class WrappedResponses extends Responses {
2444
2463
  params: openAIParams,
2445
2464
  monitoring: posthogParams,
2446
2465
  modelParametersSource: body
2447
- }, error));
2466
+ }, error, {
2467
+ latency: (Date.now() - startTime) / 1000
2468
+ }));
2448
2469
  throw error;
2449
2470
  });
2450
2471
  return preserveProviderPromise(parentPromise, wrappedPromise);
@@ -2481,7 +2502,7 @@ class WrappedEmbeddings extends Embeddings {
2481
2502
  params: openAIParams,
2482
2503
  monitoring: posthogParams,
2483
2504
  modelParametersSource: body
2484
- }, error));
2505
+ }, error, (Date.now() - startTime) / 1000));
2485
2506
  throw error;
2486
2507
  });
2487
2508
  return preserveProviderPromise(parentPromise, wrappedPromise);
@@ -2527,13 +2548,10 @@ class WrappedTranscriptions extends Transcriptions {
2527
2548
  if (Symbol.asyncIterator in value) {
2528
2549
  const [stream1, stream2] = monitoredStreamTee(value, (iterator, controller) => new Stream(iterator, controller));
2529
2550
  (async () => {
2551
+ let usage = {};
2530
2552
  try {
2531
2553
  let finalContent = '';
2532
2554
  let firstTokenTime;
2533
- let usage = {
2534
- inputTokens: 0,
2535
- outputTokens: 0
2536
- };
2537
2555
  const doneEvent = 'transcript.text.done';
2538
2556
  for await (const chunk of stream1) {
2539
2557
  // Track first token on text delta events
@@ -2575,13 +2593,10 @@ class WrappedTranscriptions extends Transcriptions {
2575
2593
  provider: 'openai',
2576
2594
  input: openAIParams.prompt,
2577
2595
  output: [],
2578
- latency: 0,
2596
+ latency: (Date.now() - startTime) / 1000,
2579
2597
  baseURL: this.baseURL,
2580
2598
  modelParameters: getModelParams(body),
2581
- usage: {
2582
- inputTokens: 0,
2583
- outputTokens: 0
2584
- },
2599
+ usage,
2585
2600
  error
2586
2601
  });
2587
2602
  throw error;
@@ -2624,13 +2639,10 @@ class WrappedTranscriptions extends Transcriptions {
2624
2639
  provider: 'openai',
2625
2640
  input: openAIParams.prompt,
2626
2641
  output: [],
2627
- latency: 0,
2642
+ latency: (Date.now() - startTime) / 1000,
2628
2643
  baseURL: this.baseURL,
2629
2644
  modelParameters: getModelParams(body),
2630
- usage: {
2631
- inputTokens: 0,
2632
- outputTokens: 0
2633
- },
2645
+ usage: {},
2634
2646
  error
2635
2647
  });
2636
2648
  throw error;