@posthog/ai 8.3.0 → 8.3.1

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.
@@ -530,7 +530,7 @@ function formatOpenAIResponsesInput(input, instructions) {
530
530
  return messages;
531
531
  }
532
532
 
533
- var version = "8.3.0";
533
+ var version = "8.3.1";
534
534
 
535
535
  const DEFAULT_MAX_DEPTH = 3;
536
536
  const MAX_STACK_LINES = 20;
@@ -640,7 +640,7 @@ const warnIfPostHogAiGateway = baseURL => {
640
640
  * object, it is mutated in place to set `__posthog_previously_captured_error`
641
641
  * so callers can re-throw the original error reference safely.
642
642
  */
643
- const captureAiGeneration = async (client, options) => {
643
+ const captureAiGeneration$1 = async (client, options) => {
644
644
  if (!client.capture) {
645
645
  return;
646
646
  }
@@ -758,6 +758,43 @@ const captureAiGeneration = async (client, options) => {
758
758
  }
759
759
  };
760
760
 
761
+ /**
762
+ * The declared convention only describes the wrapper's own usage numbers, so
763
+ * when the caller passes any of these through posthogProperties the wrapper no
764
+ * longer knows the convention of the reported counts (callers working around
765
+ * the double-billing already pass exclusive ones) and must not declare it.
766
+ * Output/reasoning token overrides don't affect the input/cache relationship,
767
+ * so they don't suppress the declaration. Subset of the input/cache keys in
768
+ * `TOKEN_PROPERTY_KEYS` (../utils.ts) — keep in sync if that taxonomy grows.
769
+ */
770
+ const INPUT_OR_CACHE_TOKEN_KEYS = ['$ai_input_tokens', '$ai_cache_read_input_tokens', '$ai_cache_creation_input_tokens'];
771
+
772
+ /**
773
+ * OpenAI-compatible usage reports `prompt_tokens` INCLUSIVE of cached tokens
774
+ * (`prompt_tokens_details.cached_tokens` is a subset of it), unlike Anthropic's
775
+ * exclusive convention. Ingestion auto-classifies Claude-shaped models as
776
+ * exclusive regardless of provider, so events for Claude served through
777
+ * OpenAI-compatible hosts (e.g. OpenRouter) would get cache reads billed twice.
778
+ * Declaring the convention on every event from this wrapper lets ingestion
779
+ * normalize correctly (see PostHog/posthog#49252); for non-Claude models the
780
+ * flag is a no-op. Callers can still override it via posthogProperties, and
781
+ * when they pass through input or cache token counts themselves the flag stays
782
+ * unset unless they declare it explicitly.
783
+ */
784
+ const captureAiGeneration = (client, options) => {
785
+ const props = options.properties;
786
+ // Own-property check, matching how getTokensSource detects passthrough and
787
+ // how the properties spread actually copies values into the event.
788
+ const callerReportsTokens = props !== undefined && INPUT_OR_CACHE_TOKEN_KEYS.some(key => Object.prototype.hasOwnProperty.call(props, key));
789
+ return captureAiGeneration$1(client, {
790
+ ...options,
791
+ properties: callerReportsTokens ? props : {
792
+ $ai_cache_reporting_exclusive: false,
793
+ ...props
794
+ }
795
+ });
796
+ };
797
+
761
798
  /**
762
799
  * Checks if a ResponseStreamEvent chunk represents the first token/content from the model.
763
800
  * This includes various content types like text, reasoning, audio, and refusals.