posthoganalytics 6.3.0__py3-none-any.whl → 6.3.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.
@@ -5,6 +5,7 @@ except ImportError:
5
5
  "Please install LangChain to use this feature: 'pip install langchain'"
6
6
  )
7
7
 
8
+ import json
8
9
  import logging
9
10
  import time
10
11
  from dataclasses import dataclass
@@ -29,6 +30,7 @@ from langchain_core.messages import (
29
30
  HumanMessage,
30
31
  SystemMessage,
31
32
  ToolMessage,
33
+ ToolCall,
32
34
  )
33
35
  from langchain_core.outputs import ChatGeneration, LLMResult
34
36
  from pydantic import BaseModel
@@ -629,12 +631,35 @@ def _extract_raw_esponse(last_response):
629
631
  return ""
630
632
 
631
633
 
632
- def _convert_message_to_dict(message: BaseMessage) -> Dict[str, Any]:
634
+ def _convert_lc_tool_calls_to_oai(
635
+ tool_calls: list[ToolCall],
636
+ ) -> list[dict[str, Any]]:
637
+ try:
638
+ return [
639
+ {
640
+ "type": "function",
641
+ "id": tool_call["id"],
642
+ "function": {
643
+ "name": tool_call["name"],
644
+ "arguments": json.dumps(tool_call["args"]),
645
+ },
646
+ }
647
+ for tool_call in tool_calls
648
+ ]
649
+ except KeyError:
650
+ return tool_calls
651
+
652
+
653
+ def _convert_message_to_dict(message: BaseMessage) -> dict[str, Any]:
633
654
  # assistant message
634
655
  if isinstance(message, HumanMessage):
635
656
  message_dict = {"role": "user", "content": message.content}
636
657
  elif isinstance(message, AIMessage):
637
658
  message_dict = {"role": "assistant", "content": message.content}
659
+ if message.tool_calls:
660
+ message_dict["tool_calls"] = _convert_lc_tool_calls_to_oai(
661
+ message.tool_calls
662
+ )
638
663
  elif isinstance(message, SystemMessage):
639
664
  message_dict = {"role": "system", "content": message.content}
640
665
  elif isinstance(message, ToolMessage):
@@ -647,6 +672,9 @@ def _convert_message_to_dict(message: BaseMessage) -> Dict[str, Any]:
647
672
  if message.additional_kwargs:
648
673
  message_dict.update(message.additional_kwargs)
649
674
 
675
+ if "content" in message_dict and not message_dict["content"]:
676
+ message_dict["content"] = ""
677
+
650
678
  return message_dict
651
679
 
652
680
 
@@ -118,7 +118,12 @@ def format_response(response, provider: str):
118
118
  def format_response_anthropic(response):
119
119
  output = []
120
120
  for choice in response.content:
121
- if choice.text:
121
+ if (
122
+ hasattr(choice, "type")
123
+ and choice.type == "text"
124
+ and hasattr(choice, "text")
125
+ and choice.text
126
+ ):
122
127
  output.append(
123
128
  {
124
129
  "role": "assistant",
@@ -225,8 +230,21 @@ def format_response_gemini(response):
225
230
 
226
231
  def format_tool_calls(response, provider: str):
227
232
  if provider == "anthropic":
228
- if hasattr(response, "tools") and response.tools and len(response.tools) > 0:
229
- return response.tools
233
+ if hasattr(response, "content") and response.content:
234
+ tool_calls = []
235
+
236
+ for content_item in response.content:
237
+ if hasattr(content_item, "type") and content_item.type == "tool_use":
238
+ tool_calls.append(
239
+ {
240
+ "type": content_item.type,
241
+ "id": content_item.id,
242
+ "name": content_item.name,
243
+ "input": content_item.input,
244
+ }
245
+ )
246
+
247
+ return tool_calls if tool_calls else None
230
248
  elif provider == "openai":
231
249
  # Handle both Chat Completions and Responses API
232
250
  if hasattr(response, "choices") and response.choices:
@@ -378,6 +396,7 @@ def call_llm_and_track_usage(
378
396
  }
379
397
 
380
398
  tool_calls = format_tool_calls(response, provider)
399
+
381
400
  if tool_calls:
382
401
  event_properties["$ai_tools"] = with_privacy_mode(
383
402
  ph_client, posthog_privacy_mode, tool_calls
@@ -1,4 +1,4 @@
1
- VERSION = "6.3.0"
1
+ VERSION = "6.3.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: posthoganalytics
3
- Version: 6.3.0
3
+ Version: 6.3.2
4
4
  Summary: Integrate PostHog into any python application.
5
5
  Home-page: https://github.com/posthog/posthog-python
6
6
  Author: Posthog
@@ -11,9 +11,9 @@ posthoganalytics/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
11
  posthoganalytics/request.py,sha256=TaeySYpcvHMf5Ftf5KqqlO0VPJpirKBCRrThlS04Kew,6124
12
12
  posthoganalytics/types.py,sha256=2rwhiZd9lvs37MiXEBADVdMKvcCvFXfAMgIUJ8KNTBs,10005
13
13
  posthoganalytics/utils.py,sha256=-0w-OLcCaoldkbBebPzQyBzLJSo9G9yBOg8NDVz7La8,16088
14
- posthoganalytics/version.py,sha256=kh3XbIm02A3duSxLSxM9UICZfLJm0YJYGYgmKSdH210,87
14
+ posthoganalytics/version.py,sha256=kOxUrR3O_Y01B2UchA6DsMVI7kcK9QuMPXjeIi0yXRs,87
15
15
  posthoganalytics/ai/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
- posthoganalytics/ai/utils.py,sha256=5-2XfmetCs0v9otBoux7-IEG933wAnKLSGS6oYLqCkw,19529
16
+ posthoganalytics/ai/utils.py,sha256=-iT0gOf_5Q3E6X20jKGOyJgyarwkml73vaf60bUzRtM,20165
17
17
  posthoganalytics/ai/anthropic/__init__.py,sha256=fFhDOiRzTXzGQlgnrRDL-4yKC8EYIl8NW4a2QNR6xRU,368
18
18
  posthoganalytics/ai/anthropic/anthropic.py,sha256=P8o-pZ2rbJXDiHO73OWjO7OgboGiEm_wVY4pbvHnUEs,7397
19
19
  posthoganalytics/ai/anthropic/anthropic_async.py,sha256=iAwVlAY6VeW0dGZdMkdfniBTBFUdZZrDMZi-O9vdiuo,7511
@@ -21,7 +21,7 @@ posthoganalytics/ai/anthropic/anthropic_providers.py,sha256=y1_qc8Lbip-YDmpimPGg
21
21
  posthoganalytics/ai/gemini/__init__.py,sha256=bMNBnJ6NO_PCQCwmxKIiw4adFuEQ06hFFBALt-aDW-0,174
22
22
  posthoganalytics/ai/gemini/gemini.py,sha256=oi7VIPJLMEHPqRQwvAGwLjkaF0RZhvloCqOJgsQrmJ8,13285
23
23
  posthoganalytics/ai/langchain/__init__.py,sha256=9CqAwLynTGj3ASAR80C3PmdTdrYGmu99tz0JL-HPFgI,70
24
- posthoganalytics/ai/langchain/callbacks.py,sha256=nfLRbAOajQ6DVSCedUUnemY3uS_icTeILEhfnSAUJ4U,28755
24
+ posthoganalytics/ai/langchain/callbacks.py,sha256=9WP09msvuq1dWFVsIlDINn1QL_QdX7yJ8foI7uU7FmQ,29519
25
25
  posthoganalytics/ai/openai/__init__.py,sha256=_flZxkyaDZme9hxJsY31sMlq4nP1dtc75HmNgj-21Kg,197
26
26
  posthoganalytics/ai/openai/openai.py,sha256=6bC3OxH9TP7EFkCGQRfxfcormVTAwLP4Wfj3ID3RwEc,23431
27
27
  posthoganalytics/ai/openai/openai_async.py,sha256=0gEhTr-ePiOhS8h1WznQDSz_lJm1aferk5K1ZAMo-K0,23838
@@ -42,8 +42,8 @@ posthoganalytics/test/test_request.py,sha256=Zc0VbkjpVmj8mKokQm9rzdgTr0b1U44vvMY
42
42
  posthoganalytics/test/test_size_limited_dict.py,sha256=-5IQjIEr_-Dql24M0HusdR_XroOMrtgiT0v6ZQCRvzo,774
43
43
  posthoganalytics/test/test_types.py,sha256=bRPHdwVpP7hu7emsplU8UVyzSQptv6PaG5lAoOD_BtM,7595
44
44
  posthoganalytics/test/test_utils.py,sha256=sqUTbfweVcxxFRd3WDMFXqPMyU6DvzOBeAOc68Py9aw,9620
45
- posthoganalytics-6.3.0.dist-info/licenses/LICENSE,sha256=wGf9JBotDkSygFj43m49oiKlFnpMnn97keiZKF-40vE,2450
46
- posthoganalytics-6.3.0.dist-info/METADATA,sha256=TyFn8t0pOnWbsC11Y3J-iJM50uiDgdQwsmmz9gKmvCw,6024
47
- posthoganalytics-6.3.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
48
- posthoganalytics-6.3.0.dist-info/top_level.txt,sha256=8QsNIqIkBh1p2TXvKp0Em9ZLZKwe3uIqCETyW4s1GOE,17
49
- posthoganalytics-6.3.0.dist-info/RECORD,,
45
+ posthoganalytics-6.3.2.dist-info/licenses/LICENSE,sha256=wGf9JBotDkSygFj43m49oiKlFnpMnn97keiZKF-40vE,2450
46
+ posthoganalytics-6.3.2.dist-info/METADATA,sha256=RJnl7mgjcZisjrCF3titIoWaXpxvzy5uqojHxqActWM,6024
47
+ posthoganalytics-6.3.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
48
+ posthoganalytics-6.3.2.dist-info/top_level.txt,sha256=8QsNIqIkBh1p2TXvKp0Em9ZLZKwe3uIqCETyW4s1GOE,17
49
+ posthoganalytics-6.3.2.dist-info/RECORD,,