posthoganalytics 7.6.0__tar.gz → 7.8.0__tar.gz

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.
Files changed (74) hide show
  1. {posthoganalytics-7.6.0/posthoganalytics.egg-info → posthoganalytics-7.8.0}/PKG-INFO +1 -1
  2. posthoganalytics-7.8.0/posthoganalytics/ai/__init__.py +3 -0
  3. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics/ai/anthropic/anthropic_converter.py +18 -0
  4. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics/ai/gemini/gemini_converter.py +7 -0
  5. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics/ai/openai/openai_converter.py +19 -0
  6. posthoganalytics-7.8.0/posthoganalytics/ai/openai_agents/__init__.py +76 -0
  7. posthoganalytics-7.8.0/posthoganalytics/ai/openai_agents/processor.py +863 -0
  8. posthoganalytics-7.8.0/posthoganalytics/ai/prompts.py +271 -0
  9. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics/ai/types.py +1 -0
  10. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics/ai/utils.py +78 -0
  11. posthoganalytics-7.8.0/posthoganalytics/test/ai/openai_agents/__init__.py +1 -0
  12. posthoganalytics-7.8.0/posthoganalytics/test/ai/openai_agents/test_processor.py +810 -0
  13. posthoganalytics-7.8.0/posthoganalytics/test/ai/test_prompts.py +577 -0
  14. posthoganalytics-7.8.0/posthoganalytics/test/ai/test_sanitization.py +522 -0
  15. posthoganalytics-7.8.0/posthoganalytics/test/ai/test_system_prompts.py +363 -0
  16. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics/version.py +1 -1
  17. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0/posthoganalytics.egg-info}/PKG-INFO +1 -1
  18. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics.egg-info/SOURCES.txt +10 -1
  19. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/pyproject.toml +3 -0
  20. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/LICENSE +0 -0
  21. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/MANIFEST.in +0 -0
  22. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/README.md +0 -0
  23. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics/__init__.py +0 -0
  24. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics/ai/anthropic/__init__.py +0 -0
  25. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics/ai/anthropic/anthropic.py +0 -0
  26. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics/ai/anthropic/anthropic_async.py +0 -0
  27. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics/ai/anthropic/anthropic_providers.py +0 -0
  28. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics/ai/gemini/__init__.py +0 -0
  29. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics/ai/gemini/gemini.py +0 -0
  30. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics/ai/gemini/gemini_async.py +0 -0
  31. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics/ai/langchain/__init__.py +0 -0
  32. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics/ai/langchain/callbacks.py +0 -0
  33. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics/ai/openai/__init__.py +0 -0
  34. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics/ai/openai/openai.py +0 -0
  35. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics/ai/openai/openai_async.py +0 -0
  36. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics/ai/openai/openai_providers.py +0 -0
  37. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics/ai/sanitization.py +0 -0
  38. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics/args.py +0 -0
  39. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics/client.py +0 -0
  40. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics/consumer.py +0 -0
  41. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics/contexts.py +0 -0
  42. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics/exception_capture.py +0 -0
  43. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics/exception_utils.py +0 -0
  44. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics/feature_flags.py +0 -0
  45. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics/flag_definition_cache.py +0 -0
  46. {posthoganalytics-7.6.0/posthoganalytics/ai → posthoganalytics-7.8.0/posthoganalytics/integrations}/__init__.py +0 -0
  47. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics/integrations/django.py +0 -0
  48. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics/poller.py +0 -0
  49. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics/py.typed +0 -0
  50. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics/request.py +0 -0
  51. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics/test/__init__.py +0 -0
  52. {posthoganalytics-7.6.0/posthoganalytics/integrations → posthoganalytics-7.8.0/posthoganalytics/test/ai}/__init__.py +0 -0
  53. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics/test/test_before_send.py +0 -0
  54. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics/test/test_client.py +0 -0
  55. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics/test/test_consumer.py +0 -0
  56. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics/test/test_contexts.py +0 -0
  57. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics/test/test_exception_capture.py +0 -0
  58. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics/test/test_feature_flag.py +0 -0
  59. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics/test/test_feature_flag_result.py +0 -0
  60. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics/test/test_feature_flags.py +0 -0
  61. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics/test/test_flag_definition_cache.py +0 -0
  62. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics/test/test_module.py +0 -0
  63. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics/test/test_request.py +0 -0
  64. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics/test/test_size_limited_dict.py +0 -0
  65. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics/test/test_types.py +0 -0
  66. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics/test/test_utils.py +0 -0
  67. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics/types.py +0 -0
  68. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics/utils.py +0 -0
  69. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics.egg-info/dependency_links.txt +0 -0
  70. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics.egg-info/requires.txt +0 -0
  71. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/posthoganalytics.egg-info/top_level.txt +0 -0
  72. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/setup.cfg +0 -0
  73. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/setup.py +0 -0
  74. {posthoganalytics-7.6.0 → posthoganalytics-7.8.0}/setup_analytics.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: posthoganalytics
3
- Version: 7.6.0
3
+ Version: 7.8.0
4
4
  Summary: Integrate PostHog into any python application.
5
5
  Home-page: https://github.com/posthog/posthog-python
6
6
  Author: Posthog
@@ -0,0 +1,3 @@
1
+ from posthoganalytics.ai.prompts import Prompts
2
+
3
+ __all__ = ["Prompts"]
@@ -17,6 +17,7 @@ from posthoganalytics.ai.types import (
17
17
  TokenUsage,
18
18
  ToolInProgress,
19
19
  )
20
+ from posthoganalytics.ai.utils import serialize_raw_usage
20
21
 
21
22
 
22
23
  def format_anthropic_response(response: Any) -> List[FormattedMessage]:
@@ -221,6 +222,12 @@ def extract_anthropic_usage_from_response(response: Any) -> TokenUsage:
221
222
  if web_search_count > 0:
222
223
  result["web_search_count"] = web_search_count
223
224
 
225
+ # Capture raw usage metadata for backend processing
226
+ # Serialize to dict here in the converter (not in utils)
227
+ serialized = serialize_raw_usage(response.usage)
228
+ if serialized:
229
+ result["raw_usage"] = serialized
230
+
224
231
  return result
225
232
 
226
233
 
@@ -247,6 +254,11 @@ def extract_anthropic_usage_from_event(event: Any) -> TokenUsage:
247
254
  usage["cache_read_input_tokens"] = getattr(
248
255
  event.message.usage, "cache_read_input_tokens", 0
249
256
  )
257
+ # Capture raw usage metadata for backend processing
258
+ # Serialize to dict here in the converter (not in utils)
259
+ serialized = serialize_raw_usage(event.message.usage)
260
+ if serialized:
261
+ usage["raw_usage"] = serialized
250
262
 
251
263
  # Handle usage stats from message_delta event
252
264
  if hasattr(event, "usage") and event.usage:
@@ -262,6 +274,12 @@ def extract_anthropic_usage_from_event(event: Any) -> TokenUsage:
262
274
  if web_search_count > 0:
263
275
  usage["web_search_count"] = web_search_count
264
276
 
277
+ # Capture raw usage metadata for backend processing
278
+ # Serialize to dict here in the converter (not in utils)
279
+ serialized = serialize_raw_usage(event.usage)
280
+ if serialized:
281
+ usage["raw_usage"] = serialized
282
+
265
283
  return usage
266
284
 
267
285
 
@@ -12,6 +12,7 @@ from posthoganalytics.ai.types import (
12
12
  FormattedMessage,
13
13
  TokenUsage,
14
14
  )
15
+ from posthoganalytics.ai.utils import serialize_raw_usage
15
16
 
16
17
 
17
18
  class GeminiPart(TypedDict, total=False):
@@ -487,6 +488,12 @@ def _extract_usage_from_metadata(metadata: Any) -> TokenUsage:
487
488
  if reasoning_tokens and reasoning_tokens > 0:
488
489
  usage["reasoning_tokens"] = reasoning_tokens
489
490
 
491
+ # Capture raw usage metadata for backend processing
492
+ # Serialize to dict here in the converter (not in utils)
493
+ serialized = serialize_raw_usage(metadata)
494
+ if serialized:
495
+ usage["raw_usage"] = serialized
496
+
490
497
  return usage
491
498
 
492
499
 
@@ -16,6 +16,7 @@ from posthoganalytics.ai.types import (
16
16
  FormattedTextContent,
17
17
  TokenUsage,
18
18
  )
19
+ from posthoganalytics.ai.utils import serialize_raw_usage
19
20
 
20
21
 
21
22
  def format_openai_response(response: Any) -> List[FormattedMessage]:
@@ -429,6 +430,12 @@ def extract_openai_usage_from_response(response: Any) -> TokenUsage:
429
430
  if web_search_count > 0:
430
431
  result["web_search_count"] = web_search_count
431
432
 
433
+ # Capture raw usage metadata for backend processing
434
+ # Serialize to dict here in the converter (not in utils)
435
+ serialized = serialize_raw_usage(response.usage)
436
+ if serialized:
437
+ result["raw_usage"] = serialized
438
+
432
439
  return result
433
440
 
434
441
 
@@ -482,6 +489,12 @@ def extract_openai_usage_from_chunk(
482
489
  chunk.usage.completion_tokens_details.reasoning_tokens
483
490
  )
484
491
 
492
+ # Capture raw usage metadata for backend processing
493
+ # Serialize to dict here in the converter (not in utils)
494
+ serialized = serialize_raw_usage(chunk.usage)
495
+ if serialized:
496
+ usage["raw_usage"] = serialized
497
+
485
498
  elif provider_type == "responses":
486
499
  # For Responses API, usage is only in chunk.response.usage for completed events
487
500
  if hasattr(chunk, "type") and chunk.type == "response.completed":
@@ -516,6 +529,12 @@ def extract_openai_usage_from_chunk(
516
529
  if web_search_count > 0:
517
530
  usage["web_search_count"] = web_search_count
518
531
 
532
+ # Capture raw usage metadata for backend processing
533
+ # Serialize to dict here in the converter (not in utils)
534
+ serialized = serialize_raw_usage(response_usage)
535
+ if serialized:
536
+ usage["raw_usage"] = serialized
537
+
519
538
  return usage
520
539
 
521
540
 
@@ -0,0 +1,76 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING, Any, Callable, Dict, Optional, Union
4
+
5
+ if TYPE_CHECKING:
6
+ from agents.tracing import Trace
7
+
8
+ from posthoganalytics.client import Client
9
+
10
+ try:
11
+ import agents # noqa: F401
12
+ except ImportError:
13
+ raise ModuleNotFoundError(
14
+ "Please install the OpenAI Agents SDK to use this feature: 'pip install openai-agents'"
15
+ )
16
+
17
+ from posthoganalytics.ai.openai_agents.processor import PostHogTracingProcessor
18
+
19
+ __all__ = ["PostHogTracingProcessor", "instrument"]
20
+
21
+
22
+ def instrument(
23
+ client: Optional[Client] = None,
24
+ distinct_id: Optional[Union[str, Callable[[Trace], Optional[str]]]] = None,
25
+ privacy_mode: bool = False,
26
+ groups: Optional[Dict[str, Any]] = None,
27
+ properties: Optional[Dict[str, Any]] = None,
28
+ ) -> PostHogTracingProcessor:
29
+ """
30
+ One-liner to instrument OpenAI Agents SDK with PostHog tracing.
31
+
32
+ This registers a PostHogTracingProcessor with the OpenAI Agents SDK,
33
+ automatically capturing traces, spans, and LLM generations.
34
+
35
+ Args:
36
+ client: Optional PostHog client instance. If not provided, uses the default client.
37
+ distinct_id: Optional distinct ID to associate with all traces.
38
+ Can also be a callable that takes a trace and returns a distinct ID.
39
+ privacy_mode: If True, redacts input/output content from events.
40
+ groups: Optional PostHog groups to associate with events.
41
+ properties: Optional additional properties to include with all events.
42
+
43
+ Returns:
44
+ PostHogTracingProcessor: The registered processor instance.
45
+
46
+ Example:
47
+ ```python
48
+ from posthoganalytics.ai.openai_agents import instrument
49
+
50
+ # Simple setup
51
+ instrument(distinct_id="user@example.com")
52
+
53
+ # With custom properties
54
+ instrument(
55
+ distinct_id="user@example.com",
56
+ privacy_mode=True,
57
+ properties={"environment": "production"}
58
+ )
59
+
60
+ # Now run agents as normal - traces automatically sent to PostHog
61
+ from agents import Agent, Runner
62
+ agent = Agent(name="Assistant", instructions="You are helpful.")
63
+ result = Runner.run_sync(agent, "Hello!")
64
+ ```
65
+ """
66
+ from agents.tracing import add_trace_processor
67
+
68
+ processor = PostHogTracingProcessor(
69
+ client=client,
70
+ distinct_id=distinct_id,
71
+ privacy_mode=privacy_mode,
72
+ groups=groups,
73
+ properties=properties,
74
+ )
75
+ add_trace_processor(processor)
76
+ return processor