@posthog/ai 7.16.1 → 7.16.3

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.
@@ -23,7 +23,7 @@ function _interopNamespace(e) {
23
23
 
24
24
  var uuid__namespace = /*#__PURE__*/_interopNamespace(uuid);
25
25
 
26
- var version = "7.16.1";
26
+ var version = "7.16.3";
27
27
 
28
28
  // Type guards for safer type checking
29
29
 
@@ -1,7 +1,7 @@
1
1
  import * as uuid from 'uuid';
2
2
  import '@posthog/core';
3
3
 
4
- var version = "7.16.1";
4
+ var version = "7.16.3";
5
5
 
6
6
  // Type guards for safer type checking
7
7
 
@@ -6,7 +6,7 @@ var openai = require('openai');
6
6
  var uuid = require('uuid');
7
7
  var core = require('@posthog/core');
8
8
 
9
- var version = "7.16.1";
9
+ var version = "7.16.3";
10
10
 
11
11
  // Type guards for safer type checking
12
12
 
@@ -2,7 +2,7 @@ import { OpenAI } from 'openai';
2
2
  import { v4 } from 'uuid';
3
3
  import { uuidv7 } from '@posthog/core';
4
4
 
5
- var version = "7.16.1";
5
+ var version = "7.16.3";
6
6
 
7
7
  // Type guards for safer type checking
8
8
 
@@ -3,7 +3,7 @@
3
3
  require('uuid');
4
4
  require('@posthog/core');
5
5
 
6
- var version = "7.16.1";
6
+ var version = "7.16.3";
7
7
 
8
8
  // limit large outputs by truncating to 200kb (approx 200k bytes)
9
9
  const MAX_OUTPUT_SIZE = 200000;
@@ -1,7 +1,7 @@
1
1
  import 'uuid';
2
2
  import '@posthog/core';
3
3
 
4
- var version = "7.16.1";
4
+ var version = "7.16.3";
5
5
 
6
6
  // limit large outputs by truncating to 200kb (approx 200k bytes)
7
7
  const MAX_OUTPUT_SIZE = 200000;
@@ -3,7 +3,7 @@
3
3
  var uuid = require('uuid');
4
4
  var core = require('@posthog/core');
5
5
 
6
- var version = "7.16.1";
6
+ var version = "7.16.3";
7
7
 
8
8
  // Type guards for safer type checking
9
9
 
@@ -566,12 +566,14 @@ const mapVercelOutput = result => {
566
566
  };
567
567
  }
568
568
  if (item.type === 'tool-call') {
569
+ const toolCall = item;
570
+ const rawArgs = toolCall.input ?? toolCall.args ?? toolCall.arguments ?? {};
569
571
  return {
570
572
  type: 'tool-call',
571
573
  id: item.toolCallId,
572
574
  function: {
573
575
  name: item.toolName,
574
- arguments: item.args || JSON.stringify(item.arguments || {})
576
+ arguments: typeof rawArgs === 'string' ? rawArgs : JSON.stringify(rawArgs)
575
577
  }
576
578
  };
577
579
  }
@@ -659,30 +661,6 @@ const extractWebSearchCount = (providerMetadata, usage) => {
659
661
  });
660
662
  };
661
663
 
662
- // Extract additional token values from provider metadata
663
- const extractAdditionalTokenValues = providerMetadata => {
664
- if (providerMetadata && typeof providerMetadata === 'object' && 'anthropic' in providerMetadata && providerMetadata.anthropic && typeof providerMetadata.anthropic === 'object' && 'cacheCreationInputTokens' in providerMetadata.anthropic) {
665
- return {
666
- cacheCreationInputTokens: providerMetadata.anthropic.cacheCreationInputTokens
667
- };
668
- }
669
- return {};
670
- };
671
-
672
- // For Anthropic providers in V3, inputTokens.total is the sum of all tokens (uncached + cache read + cache write).
673
- // Our cost calculation expects inputTokens to be only the uncached portion for Anthropic.
674
- // This helper subtracts cache tokens from inputTokens for Anthropic V3 models.
675
- const adjustAnthropicV3CacheTokens = (model, provider, usage) => {
676
- if (isV3Model(model) && provider.toLowerCase().includes('anthropic')) {
677
- const cacheReadTokens = usage.cacheReadInputTokens || 0;
678
- const cacheWriteTokens = usage.cacheCreationInputTokens || 0;
679
- const cacheTokens = cacheReadTokens + cacheWriteTokens;
680
- if (usage.inputTokens && cacheTokens > 0) {
681
- usage.inputTokens = Math.max(usage.inputTokens - cacheTokens, 0);
682
- }
683
- }
684
- };
685
-
686
664
  // Helper to extract numeric token value from V2 (number) or V3 (object with .total) usage formats
687
665
  const extractTokenCount = value => {
688
666
  if (typeof value === 'number') {
@@ -720,6 +698,63 @@ const extractCacheReadTokens = usage => {
720
698
  return undefined;
721
699
  };
722
700
 
701
+ // Helper to extract cache write tokens from V3 (usage.inputTokens.cacheWrite). Providers like
702
+ // Amazon Bedrock populate this standardized field instead of providerMetadata.anthropic.
703
+ const extractCacheWriteTokens = usage => {
704
+ if ('inputTokens' in usage && usage.inputTokens && typeof usage.inputTokens === 'object' && 'cacheWrite' in usage.inputTokens) {
705
+ return usage.inputTokens.cacheWrite;
706
+ }
707
+ return undefined;
708
+ };
709
+
710
+ // Extract additional token values from provider metadata, with a V3 standardized fallback
711
+ // (e.g. Amazon Bedrock exposes cache write tokens via usage.inputTokens.cacheWrite rather
712
+ // than providerMetadata.anthropic.cacheCreationInputTokens). A cacheWrite of 0 is treated
713
+ // as absent so we preserve the pre-fallback event shape on providers that simply omit the
714
+ // field — consumers downstream saw `$ai_cache_creation_input_tokens` missing, not 0.
715
+ const extractAdditionalTokenValues = (providerMetadata, usage) => {
716
+ if (providerMetadata && typeof providerMetadata === 'object' && 'anthropic' in providerMetadata && providerMetadata.anthropic && typeof providerMetadata.anthropic === 'object' && 'cacheCreationInputTokens' in providerMetadata.anthropic) {
717
+ return {
718
+ cacheCreationInputTokens: providerMetadata.anthropic.cacheCreationInputTokens
719
+ };
720
+ }
721
+ if (usage && typeof usage === 'object') {
722
+ const cacheWrite = extractCacheWriteTokens(usage);
723
+ if (typeof cacheWrite === 'number' && cacheWrite > 0) {
724
+ return {
725
+ cacheCreationInputTokens: cacheWrite
726
+ };
727
+ }
728
+ }
729
+ return {};
730
+ };
731
+
732
+ // Detects Anthropic Claude regardless of host (direct Anthropic, Amazon Bedrock, Google Vertex, etc.).
733
+ // The server applies exclusive cache token accounting based on the model name, so any Claude model
734
+ // needs its V3 input tokens adjusted to exclude cache tokens — not just those routed through a
735
+ // provider whose name contains "anthropic". Accepts the resolved modelId string (not the raw model)
736
+ // so it sees the same id the server does after posthogModelOverride / response.modelId fallbacks.
737
+ const isAnthropicClaudeModel = (modelId, provider) => {
738
+ if (provider.toLowerCase().includes('anthropic')) {
739
+ return true;
740
+ }
741
+ return /claude|anthropic/i.test(modelId);
742
+ };
743
+
744
+ // For Anthropic providers in V3, inputTokens.total is the sum of all tokens (uncached + cache read + cache write).
745
+ // Our cost calculation expects inputTokens to be only the uncached portion for Anthropic.
746
+ // This helper subtracts cache tokens from inputTokens for Anthropic V3 models.
747
+ const adjustAnthropicV3CacheTokens = (model, modelId, provider, usage) => {
748
+ if (isV3Model(model) && isAnthropicClaudeModel(modelId, provider)) {
749
+ const cacheReadTokens = usage.cacheReadInputTokens || 0;
750
+ const cacheWriteTokens = usage.cacheCreationInputTokens || 0;
751
+ const cacheTokens = cacheReadTokens + cacheWriteTokens;
752
+ if (usage.inputTokens && cacheTokens > 0) {
753
+ usage.inputTokens = Math.max(usage.inputTokens - cacheTokens, 0);
754
+ }
755
+ }
756
+ };
757
+
723
758
  /**
724
759
  * Wraps a Vercel AI SDK language model (V2 or V3) with PostHog tracing.
725
760
  * Automatically detects the model version and applies appropriate instrumentation.
@@ -757,7 +792,7 @@ const wrapVercelLanguageModel = (model, phClient, options) => {
757
792
  const content = mapVercelOutput(result.content ?? []);
758
793
  const latency = (Date.now() - startTime) / 1000;
759
794
  const providerMetadata = result.providerMetadata;
760
- const additionalTokenValues = extractAdditionalTokenValues(providerMetadata);
795
+ const additionalTokenValues = extractAdditionalTokenValues(providerMetadata, result.usage);
761
796
  const webSearchCount = extractWebSearchCount(providerMetadata, result.usage);
762
797
 
763
798
  // V2 usage has simple numbers, V3 has objects with .total - normalize both
@@ -788,7 +823,7 @@ const wrapVercelLanguageModel = (model, phClient, options) => {
788
823
  ...additionalTokenValues,
789
824
  rawUsage: rawUsageData
790
825
  };
791
- adjustAnthropicV3CacheTokens(model, provider, usage);
826
+ adjustAnthropicV3CacheTokens(model, modelId, provider, usage);
792
827
 
793
828
  // Extract finish reason - V2 returns a string, V3 returns an object with .unified
794
829
  const rawFinishReason = result.finishReason;
@@ -915,8 +950,8 @@ const wrapVercelLanguageModel = (model, phClient, options) => {
915
950
  }
916
951
  if (chunk.type === 'finish') {
917
952
  providerMetadata = chunk.providerMetadata;
918
- const additionalTokenValues = extractAdditionalTokenValues(providerMetadata);
919
953
  const chunkUsage = chunk.usage || {};
954
+ const additionalTokenValues = extractAdditionalTokenValues(providerMetadata, chunkUsage);
920
955
  usage = {
921
956
  inputTokens: extractTokenCount(chunk.usage?.inputTokens),
922
957
  outputTokens: extractTokenCount(chunk.usage?.outputTokens),
@@ -983,7 +1018,7 @@ const wrapVercelLanguageModel = (model, phClient, options) => {
983
1018
  providerMetadata
984
1019
  }
985
1020
  };
986
- adjustAnthropicV3CacheTokens(model, provider, finalUsage);
1021
+ adjustAnthropicV3CacheTokens(model, modelId, provider, finalUsage);
987
1022
  await sendEventToPosthog({
988
1023
  client: phClient,
989
1024
  distinctId: mergedOptions.posthogDistinctId,