posthog 6.9.1__py3-none-any.whl → 6.9.2__py3-none-any.whl

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.
posthog/__init__.py CHANGED
@@ -18,8 +18,15 @@ from posthog.exception_utils import (
18
18
  DEFAULT_CODE_VARIABLES_IGNORE_PATTERNS,
19
19
  DEFAULT_CODE_VARIABLES_MASK_PATTERNS,
20
20
  )
21
- from posthog.feature_flags import InconclusiveMatchError, RequiresServerEvaluation
22
- from posthog.types import FeatureFlag, FlagsAndPayloads, FeatureFlagResult
21
+ from posthog.feature_flags import (
22
+ InconclusiveMatchError as InconclusiveMatchError,
23
+ RequiresServerEvaluation as RequiresServerEvaluation,
24
+ )
25
+ from posthog.types import (
26
+ FeatureFlag,
27
+ FlagsAndPayloads,
28
+ FeatureFlagResult as FeatureFlagResult,
29
+ )
23
30
  from posthog.version import VERSION
24
31
 
25
32
  __version__ = VERSION
@@ -575,7 +575,7 @@ class CallbackHandler(BaseCallbackHandler):
575
575
  event_properties["$ai_is_error"] = True
576
576
  else:
577
577
  # Add usage
578
- usage = _parse_usage(output)
578
+ usage = _parse_usage(output, run.provider, run.model)
579
579
  event_properties["$ai_input_tokens"] = usage.input_tokens
580
580
  event_properties["$ai_output_tokens"] = usage.output_tokens
581
581
  event_properties["$ai_cache_creation_input_tokens"] = (
@@ -696,6 +696,8 @@ class ModelUsage:
696
696
 
697
697
  def _parse_usage_model(
698
698
  usage: Union[BaseModel, dict],
699
+ provider: Optional[str] = None,
700
+ model: Optional[str] = None,
699
701
  ) -> ModelUsage:
700
702
  if isinstance(usage, BaseModel):
701
703
  usage = usage.__dict__
@@ -764,16 +766,30 @@ def _parse_usage_model(
764
766
  for mapped_key, dataclass_key in field_mapping.items()
765
767
  },
766
768
  )
767
- # In LangChain, input_tokens is the sum of input and cache read tokens.
768
- # Our cost calculation expects them to be separate, for Anthropic.
769
- if normalized_usage.input_tokens and normalized_usage.cache_read_tokens:
769
+ # For Anthropic providers, LangChain reports input_tokens as the sum of input and cache read tokens.
770
+ # Our cost calculation expects them to be separate for Anthropic, so we subtract cache tokens.
771
+ # For other providers (OpenAI, etc.), input_tokens already includes cache tokens as expected.
772
+ # Match logic consistent with plugin-server: exact match on provider OR substring match on model
773
+ is_anthropic = False
774
+ if provider and provider.lower() == "anthropic":
775
+ is_anthropic = True
776
+ elif model and "anthropic" in model.lower():
777
+ is_anthropic = True
778
+
779
+ if (
780
+ is_anthropic
781
+ and normalized_usage.input_tokens
782
+ and normalized_usage.cache_read_tokens
783
+ ):
770
784
  normalized_usage.input_tokens = max(
771
785
  normalized_usage.input_tokens - normalized_usage.cache_read_tokens, 0
772
786
  )
773
787
  return normalized_usage
774
788
 
775
789
 
776
- def _parse_usage(response: LLMResult) -> ModelUsage:
790
+ def _parse_usage(
791
+ response: LLMResult, provider: Optional[str] = None, model: Optional[str] = None
792
+ ) -> ModelUsage:
777
793
  # langchain-anthropic uses the usage field
778
794
  llm_usage_keys = ["token_usage", "usage"]
779
795
  llm_usage: ModelUsage = ModelUsage(
@@ -787,13 +803,15 @@ def _parse_usage(response: LLMResult) -> ModelUsage:
787
803
  if response.llm_output is not None:
788
804
  for key in llm_usage_keys:
789
805
  if response.llm_output.get(key):
790
- llm_usage = _parse_usage_model(response.llm_output[key])
806
+ llm_usage = _parse_usage_model(
807
+ response.llm_output[key], provider, model
808
+ )
791
809
  break
792
810
 
793
811
  if hasattr(response, "generations"):
794
812
  for generation in response.generations:
795
813
  if "usage" in generation:
796
- llm_usage = _parse_usage_model(generation["usage"])
814
+ llm_usage = _parse_usage_model(generation["usage"], provider, model)
797
815
  break
798
816
 
799
817
  for generation_chunk in generation:
@@ -801,7 +819,9 @@ def _parse_usage(response: LLMResult) -> ModelUsage:
801
819
  "usage_metadata" in generation_chunk.generation_info
802
820
  ):
803
821
  llm_usage = _parse_usage_model(
804
- generation_chunk.generation_info["usage_metadata"]
822
+ generation_chunk.generation_info["usage_metadata"],
823
+ provider,
824
+ model,
805
825
  )
806
826
  break
807
827
 
@@ -828,7 +848,7 @@ def _parse_usage(response: LLMResult) -> ModelUsage:
828
848
  bedrock_anthropic_usage or bedrock_titan_usage or ollama_usage
829
849
  )
830
850
  if chunk_usage:
831
- llm_usage = _parse_usage_model(chunk_usage)
851
+ llm_usage = _parse_usage_model(chunk_usage, provider, model)
832
852
  break
833
853
 
834
854
  return llm_usage
@@ -929,7 +929,7 @@ def _compile_patterns(patterns):
929
929
  for pattern in patterns:
930
930
  try:
931
931
  compiled.append(re.compile(pattern))
932
- except:
932
+ except Exception:
933
933
  pass
934
934
  return compiled
935
935
 
posthog/version.py CHANGED
@@ -1,4 +1,4 @@
1
- VERSION = "6.9.1"
1
+ VERSION = "6.9.2"
2
2
 
3
3
  if __name__ == "__main__":
4
4
  print(VERSION, end="") # noqa: T201
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: posthog
3
- Version: 6.9.1
3
+ Version: 6.9.2
4
4
  Summary: Integrate PostHog into any python application.
5
5
  Home-page: https://github.com/posthog/posthog-python
6
6
  Author: Posthog
@@ -1,17 +1,17 @@
1
- posthog/__init__.py,sha256=nu76iBqww-8EDideLMh1oY--6zjLRCUlRorHfYlj-rM,27555
1
+ posthog/__init__.py,sha256=3nTRvobcwGbU55ltU3tK1JjrzjO-l8NOG1JA3ceh9k8,27660
2
2
  posthog/args.py,sha256=JUt0vbtF33IzLt3ARgsxMEYYnZo3RNS_LcK4-CjWaco,3298
3
3
  posthog/client.py,sha256=FPCykXYOJ1jtiqxxmoe_dbvw5HKJH14wDHFJQyXSLjU,74076
4
4
  posthog/consumer.py,sha256=fdteMZ-deJGMpaQmHyznw_cwQG2Vvld1tmN9LUkZPrY,4608
5
5
  posthog/contexts.py,sha256=22z4KySFCTwPbz4OYsd_8EJpoc2H91NiLq9cscSvFfw,12600
6
6
  posthog/exception_capture.py,sha256=pmKtjQ6QY6zs4u_-ZA4H1gCyR3iI4sfqCQG_jwe_bKo,1774
7
- posthog/exception_utils.py,sha256=nn2ue5Xmj1Rv5a6WWK1toScjv4Y2PxPRbVD41tbfKXA,31848
7
+ posthog/exception_utils.py,sha256=-pvsDuDlsTORFLLYAEhiii5VBKie3jbFgadMFSaix-g,31858
8
8
  posthog/feature_flags.py,sha256=4xAcYEpa97b5Lv9bIo5JHbCO6lhYBnH5EmJ2MrjbU3k,22517
9
9
  posthog/poller.py,sha256=jBz5rfH_kn_bBz7wCB46Fpvso4ttx4uzqIZWvXBCFmQ,595
10
10
  posthog/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
11
  posthog/request.py,sha256=CaONBN7a5RD8xiSShVMgHEd9XxKWM6ZQTLZypiqABhA,6168
12
12
  posthog/types.py,sha256=Dl3aFGX9XUR0wMmK12r2s5Hjan9jL4HpQ9GHpVcEq5U,10207
13
13
  posthog/utils.py,sha256=-0w-OLcCaoldkbBebPzQyBzLJSo9G9yBOg8NDVz7La8,16088
14
- posthog/version.py,sha256=OMdDT60Qk45GJfzp5Rdz7eHHZuu4MYT9YrnOl-Mr1yY,87
14
+ posthog/version.py,sha256=zvqnhz0fFaGVjl6Hb6DGlJacDLQ1AwGr9KdJwg82zOA,87
15
15
  posthog/ai/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
16
  posthog/ai/sanitization.py,sha256=owipZ4eJYtd4JTI-CM_klatclXaeaIec3XJBOUfsOnQ,5770
17
17
  posthog/ai/types.py,sha256=arX98hR1PIPeJ3vFikxTlACIh1xPp6aEUw1gBLcKoB0,3273
@@ -25,7 +25,7 @@ posthog/ai/gemini/__init__.py,sha256=JV_9-gBR87leHgZW4XAYZP7LSl4YaXeuhqDUpA8HygA
25
25
  posthog/ai/gemini/gemini.py,sha256=-c2MnBeask6SrAbFZ7XXZ_OMcuglTBRdnFe_ROVgXWQ,14972
26
26
  posthog/ai/gemini/gemini_converter.py,sha256=WFF1gzLGk1DId-1yrA9nDYMd9PXgbVsyhU3wgKjAJTE,18731
27
27
  posthog/ai/langchain/__init__.py,sha256=9CqAwLynTGj3ASAR80C3PmdTdrYGmu99tz0JL-HPFgI,70
28
- posthog/ai/langchain/callbacks.py,sha256=5cjBFTNmHYhWxDWSAjIRfHvTebO8M6D5D37CR9vvoAg,30261
28
+ posthog/ai/langchain/callbacks.py,sha256=yTlg-kA4Sc0ZA2pSyPrhRpZjB_gMfeVrMhAJlXWipV0,31066
29
29
  posthog/ai/openai/__init__.py,sha256=u4OuUT7k1NgFj0TrxjuyegOg7a_UA8nAU6a-Hszr0OM,490
30
30
  posthog/ai/openai/openai.py,sha256=ts95vdvWH7h0TX4FpLLK_wU_7H0MP3eZBEg0S-lsCKw,20127
31
31
  posthog/ai/openai/openai_async.py,sha256=Ebd6_H3Zf3wGPycVJd_vOd3ZVoO3Mf3ZV339BExQd6Q,22436
@@ -47,8 +47,8 @@ posthog/test/test_request.py,sha256=l19WVyZQc4Iqmh_bpnAFOj4nGRpDK1iO-o5aJDQfFdo,
47
47
  posthog/test/test_size_limited_dict.py,sha256=Wom7BkzpHmusHilZy0SV3PNzhw7ucuQgqrx86jf8euo,765
48
48
  posthog/test/test_types.py,sha256=csLuBiz6RMV36cpg9LVIor4Khq6MfjjGxYXodx5VttY,7586
49
49
  posthog/test/test_utils.py,sha256=NUs2bgqrVuMdnKRq52syizgglt5_7wxxZl3dDMun-Tg,9602
50
- posthog-6.9.1.dist-info/licenses/LICENSE,sha256=wGf9JBotDkSygFj43m49oiKlFnpMnn97keiZKF-40vE,2450
51
- posthog-6.9.1.dist-info/METADATA,sha256=xAiCicB2ng9wcjNnHY3SAfPy90f96Wwfcbonxhg0qMA,6015
52
- posthog-6.9.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
53
- posthog-6.9.1.dist-info/top_level.txt,sha256=7FBLsRjIUHVKQsXIhozuI3k-mun1tapp8iZO9EmUPEw,8
54
- posthog-6.9.1.dist-info/RECORD,,
50
+ posthog-6.9.2.dist-info/licenses/LICENSE,sha256=wGf9JBotDkSygFj43m49oiKlFnpMnn97keiZKF-40vE,2450
51
+ posthog-6.9.2.dist-info/METADATA,sha256=WbGyiRzHgyL5ErzlwlfxAzZUPrdMDxSbRDaU0cwd9mo,6015
52
+ posthog-6.9.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
53
+ posthog-6.9.2.dist-info/top_level.txt,sha256=7FBLsRjIUHVKQsXIhozuI3k-mun1tapp8iZO9EmUPEw,8
54
+ posthog-6.9.2.dist-info/RECORD,,