@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.
@@ -330,7 +330,7 @@ function addDefaults(params) {
330
330
  };
331
331
  }
332
332
 
333
- var version = "8.9.1";
333
+ var version = "8.9.2";
334
334
 
335
335
  const DEFAULT_MAX_DEPTH = 3;
336
336
  const MAX_STACK_LINES = 20;
@@ -487,15 +487,22 @@ const captureAiGeneration = async (client, options) => {
487
487
  };
488
488
  }
489
489
  httpStatus = httpStatus ?? 200;
490
- let costOverrideData = {};
490
+
491
+ // A configured price applies only to a count the provider reported, so a call with no
492
+ // reported usage sends no cost instead of asserting $0. $ai_total_cost_usd sums the sides
493
+ // that were priced, which makes it the cost of the known side alone when the other side
494
+ // went unreported: a lower bound on the true total, not an assertion of it.
495
+ const costOverrideData = {};
491
496
  if (options.costOverride) {
492
- const inputCostUSD = (options.costOverride.inputCost ?? 0) * (usage.inputTokens ?? 0);
493
- const outputCostUSD = (options.costOverride.outputCost ?? 0) * (usage.outputTokens ?? 0);
494
- costOverrideData = {
495
- $ai_input_cost_usd: inputCostUSD,
496
- $ai_output_cost_usd: outputCostUSD,
497
- $ai_total_cost_usd: inputCostUSD + outputCostUSD
498
- };
497
+ if (usage.inputTokens !== undefined) {
498
+ costOverrideData.$ai_input_cost_usd = (options.costOverride.inputCost ?? 0) * usage.inputTokens;
499
+ }
500
+ if (usage.outputTokens !== undefined) {
501
+ costOverrideData.$ai_output_cost_usd = (options.costOverride.outputCost ?? 0) * usage.outputTokens;
502
+ }
503
+ if (Object.keys(costOverrideData).length > 0) {
504
+ costOverrideData.$ai_total_cost_usd = (costOverrideData.$ai_input_cost_usd ?? 0) + (costOverrideData.$ai_output_cost_usd ?? 0);
505
+ }
499
506
  }
500
507
 
501
508
  // The caller's own token counts override the SDK-derived ones further down, via the
@@ -539,7 +546,9 @@ const captureAiGeneration = async (client, options) => {
539
546
  $ai_input: safeInput,
540
547
  $ai_output_choices: safeOutput,
541
548
  $ai_http_status: httpStatus,
542
- $ai_input_tokens: usage.inputTokens ?? 0,
549
+ ...(usage.inputTokens !== undefined ? {
550
+ $ai_input_tokens: usage.inputTokens
551
+ } : {}),
543
552
  ...(usage.outputTokens !== undefined ? {
544
553
  $ai_output_tokens: usage.outputTokens
545
554
  } : {}),
@@ -919,10 +928,6 @@ class WrappedMessages extends AnthropicOriginal.Messages {
919
928
  let firstTokenTime;
920
929
  let stopReason;
921
930
  const usage = {
922
- inputTokens: 0,
923
- outputTokens: 0,
924
- cacheCreationInputTokens: 0,
925
- cacheReadInputTokens: 0,
926
931
  webSearchCount: 0
927
932
  };
928
933
  let rawUsage = {};
@@ -1066,19 +1071,21 @@ class WrappedMessages extends AnthropicOriginal.Messages {
1066
1071
  tools: availableTools
1067
1072
  });
1068
1073
  } catch (error) {
1074
+ // The final usage delta may never arrive; whatever raw usage did
1075
+ // still belongs on the event.
1076
+ if (Object.keys(rawUsage).length > 0) {
1077
+ usage.rawUsage = rawUsage;
1078
+ }
1069
1079
  await captureAiGeneration(this.phClient, {
1070
1080
  ...posthogParams,
1071
1081
  model: anthropicParams.model,
1072
1082
  provider: 'anthropic',
1073
1083
  input: sanitizeAnthropic(mergeSystemPrompt(anthropicParams), this.phClient),
1074
1084
  output: [],
1075
- latency: 0,
1085
+ latency: (Date.now() - startTime) / 1000,
1076
1086
  baseURL: this.baseURL,
1077
1087
  modelParameters: getModelParams(body),
1078
- usage: {
1079
- inputTokens: 0,
1080
- outputTokens: 0
1081
- },
1088
+ usage,
1082
1089
  error: error
1083
1090
  });
1084
1091
  throw error;
@@ -1133,14 +1140,11 @@ class WrappedMessages extends AnthropicOriginal.Messages {
1133
1140
  provider: 'anthropic',
1134
1141
  input: sanitizeAnthropic(mergeSystemPrompt(anthropicParams), this.phClient),
1135
1142
  output: [],
1136
- latency: 0,
1143
+ latency: (Date.now() - startTime) / 1000,
1137
1144
  baseURL: this.baseURL,
1138
1145
  modelParameters: getModelParams(body),
1139
1146
  httpStatus: error?.status ? error.status : 500,
1140
- usage: {
1141
- inputTokens: 0,
1142
- outputTokens: 0
1143
- },
1147
+ usage: {},
1144
1148
  error: error
1145
1149
  });
1146
1150
  throw error;