posthoganalytics 6.3.3__tar.gz → 6.4.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.
- {posthoganalytics-6.3.3/posthoganalytics.egg-info → posthoganalytics-6.4.0}/PKG-INFO +1 -1
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/posthoganalytics/__init__.py +74 -31
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/posthoganalytics/ai/gemini/gemini.py +64 -10
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/posthoganalytics/ai/langchain/callbacks.py +5 -7
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/posthoganalytics/ai/openai/openai.py +9 -36
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/posthoganalytics/ai/openai/openai_async.py +9 -36
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/posthoganalytics/ai/utils.py +136 -93
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/posthoganalytics/client.py +50 -30
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/posthoganalytics/test/test_client.py +4 -4
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/posthoganalytics/version.py +1 -1
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0/posthoganalytics.egg-info}/PKG-INFO +1 -1
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/LICENSE +0 -0
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/MANIFEST.in +0 -0
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/README.md +0 -0
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/posthoganalytics/ai/__init__.py +0 -0
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/posthoganalytics/ai/anthropic/__init__.py +0 -0
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/posthoganalytics/ai/anthropic/anthropic.py +0 -0
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/posthoganalytics/ai/anthropic/anthropic_async.py +0 -0
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/posthoganalytics/ai/anthropic/anthropic_providers.py +0 -0
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/posthoganalytics/ai/gemini/__init__.py +0 -0
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/posthoganalytics/ai/langchain/__init__.py +0 -0
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/posthoganalytics/ai/openai/__init__.py +0 -0
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/posthoganalytics/ai/openai/openai_providers.py +0 -0
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/posthoganalytics/args.py +0 -0
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/posthoganalytics/consumer.py +0 -0
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/posthoganalytics/contexts.py +0 -0
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/posthoganalytics/exception_capture.py +0 -0
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/posthoganalytics/exception_utils.py +0 -0
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/posthoganalytics/feature_flags.py +0 -0
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/posthoganalytics/integrations/__init__.py +0 -0
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/posthoganalytics/integrations/django.py +0 -0
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/posthoganalytics/poller.py +0 -0
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/posthoganalytics/py.typed +0 -0
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/posthoganalytics/request.py +0 -0
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/posthoganalytics/test/__init__.py +0 -0
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/posthoganalytics/test/test_before_send.py +0 -0
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/posthoganalytics/test/test_consumer.py +0 -0
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/posthoganalytics/test/test_contexts.py +0 -0
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/posthoganalytics/test/test_exception_capture.py +0 -0
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/posthoganalytics/test/test_feature_flag.py +0 -0
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/posthoganalytics/test/test_feature_flag_result.py +0 -0
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/posthoganalytics/test/test_feature_flags.py +0 -0
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/posthoganalytics/test/test_module.py +0 -0
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/posthoganalytics/test/test_request.py +0 -0
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/posthoganalytics/test/test_size_limited_dict.py +0 -0
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/posthoganalytics/test/test_types.py +0 -0
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/posthoganalytics/test/test_utils.py +0 -0
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/posthoganalytics/types.py +0 -0
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/posthoganalytics/utils.py +0 -0
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/posthoganalytics.egg-info/SOURCES.txt +0 -0
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/posthoganalytics.egg-info/dependency_links.txt +0 -0
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/posthoganalytics.egg-info/requires.txt +0 -0
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/posthoganalytics.egg-info/top_level.txt +0 -0
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/pyproject.toml +0 -0
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/setup.cfg +0 -0
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/setup.py +0 -0
- {posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/setup_analytics.py +0 -0
|
@@ -11,7 +11,7 @@ from posthoganalytics.contexts import (
|
|
|
11
11
|
set_context_session as inner_set_context_session,
|
|
12
12
|
identify_context as inner_identify_context,
|
|
13
13
|
)
|
|
14
|
-
from posthoganalytics.types import FeatureFlag, FlagsAndPayloads
|
|
14
|
+
from posthoganalytics.types import FeatureFlag, FlagsAndPayloads, FeatureFlagResult
|
|
15
15
|
from posthoganalytics.version import VERSION
|
|
16
16
|
|
|
17
17
|
__version__ = VERSION
|
|
@@ -388,9 +388,9 @@ def capture_exception(
|
|
|
388
388
|
def feature_enabled(
|
|
389
389
|
key, # type: str
|
|
390
390
|
distinct_id, # type: str
|
|
391
|
-
groups=
|
|
392
|
-
person_properties=
|
|
393
|
-
group_properties=
|
|
391
|
+
groups=None, # type: Optional[dict]
|
|
392
|
+
person_properties=None, # type: Optional[dict]
|
|
393
|
+
group_properties=None, # type: Optional[dict]
|
|
394
394
|
only_evaluate_locally=False, # type: bool
|
|
395
395
|
send_feature_flag_events=True, # type: bool
|
|
396
396
|
disable_geoip=None, # type: Optional[bool]
|
|
@@ -427,9 +427,9 @@ def feature_enabled(
|
|
|
427
427
|
"feature_enabled",
|
|
428
428
|
key=key,
|
|
429
429
|
distinct_id=distinct_id,
|
|
430
|
-
groups=groups,
|
|
431
|
-
person_properties=person_properties,
|
|
432
|
-
group_properties=group_properties,
|
|
430
|
+
groups=groups or {},
|
|
431
|
+
person_properties=person_properties or {},
|
|
432
|
+
group_properties=group_properties or {},
|
|
433
433
|
only_evaluate_locally=only_evaluate_locally,
|
|
434
434
|
send_feature_flag_events=send_feature_flag_events,
|
|
435
435
|
disable_geoip=disable_geoip,
|
|
@@ -439,9 +439,9 @@ def feature_enabled(
|
|
|
439
439
|
def get_feature_flag(
|
|
440
440
|
key, # type: str
|
|
441
441
|
distinct_id, # type: str
|
|
442
|
-
groups=
|
|
443
|
-
person_properties=
|
|
444
|
-
group_properties=
|
|
442
|
+
groups=None, # type: Optional[dict]
|
|
443
|
+
person_properties=None, # type: Optional[dict]
|
|
444
|
+
group_properties=None, # type: Optional[dict]
|
|
445
445
|
only_evaluate_locally=False, # type: bool
|
|
446
446
|
send_feature_flag_events=True, # type: bool
|
|
447
447
|
disable_geoip=None, # type: Optional[bool]
|
|
@@ -477,9 +477,9 @@ def get_feature_flag(
|
|
|
477
477
|
"get_feature_flag",
|
|
478
478
|
key=key,
|
|
479
479
|
distinct_id=distinct_id,
|
|
480
|
-
groups=groups,
|
|
481
|
-
person_properties=person_properties,
|
|
482
|
-
group_properties=group_properties,
|
|
480
|
+
groups=groups or {},
|
|
481
|
+
person_properties=person_properties or {},
|
|
482
|
+
group_properties=group_properties or {},
|
|
483
483
|
only_evaluate_locally=only_evaluate_locally,
|
|
484
484
|
send_feature_flag_events=send_feature_flag_events,
|
|
485
485
|
disable_geoip=disable_geoip,
|
|
@@ -488,9 +488,9 @@ def get_feature_flag(
|
|
|
488
488
|
|
|
489
489
|
def get_all_flags(
|
|
490
490
|
distinct_id, # type: str
|
|
491
|
-
groups=
|
|
492
|
-
person_properties=
|
|
493
|
-
group_properties=
|
|
491
|
+
groups=None, # type: Optional[dict]
|
|
492
|
+
person_properties=None, # type: Optional[dict]
|
|
493
|
+
group_properties=None, # type: Optional[dict]
|
|
494
494
|
only_evaluate_locally=False, # type: bool
|
|
495
495
|
disable_geoip=None, # type: Optional[bool]
|
|
496
496
|
) -> Optional[dict[str, FeatureFlag]]:
|
|
@@ -520,21 +520,64 @@ def get_all_flags(
|
|
|
520
520
|
return _proxy(
|
|
521
521
|
"get_all_flags",
|
|
522
522
|
distinct_id=distinct_id,
|
|
523
|
-
groups=groups,
|
|
524
|
-
person_properties=person_properties,
|
|
525
|
-
group_properties=group_properties,
|
|
523
|
+
groups=groups or {},
|
|
524
|
+
person_properties=person_properties or {},
|
|
525
|
+
group_properties=group_properties or {},
|
|
526
526
|
only_evaluate_locally=only_evaluate_locally,
|
|
527
527
|
disable_geoip=disable_geoip,
|
|
528
528
|
)
|
|
529
529
|
|
|
530
530
|
|
|
531
|
+
def get_feature_flag_result(
|
|
532
|
+
key,
|
|
533
|
+
distinct_id,
|
|
534
|
+
groups=None, # type: Optional[dict]
|
|
535
|
+
person_properties=None, # type: Optional[dict]
|
|
536
|
+
group_properties=None, # type: Optional[dict]
|
|
537
|
+
only_evaluate_locally=False,
|
|
538
|
+
send_feature_flag_events=True,
|
|
539
|
+
disable_geoip=None, # type: Optional[bool]
|
|
540
|
+
):
|
|
541
|
+
# type: (...) -> Optional[FeatureFlagResult]
|
|
542
|
+
"""
|
|
543
|
+
Get a FeatureFlagResult object which contains the flag result and payload.
|
|
544
|
+
|
|
545
|
+
This method evaluates a feature flag and returns a FeatureFlagResult object containing:
|
|
546
|
+
- enabled: Whether the flag is enabled
|
|
547
|
+
- variant: The variant value if the flag has variants
|
|
548
|
+
- payload: The payload associated with the flag (automatically deserialized from JSON)
|
|
549
|
+
- key: The flag key
|
|
550
|
+
- reason: Why the flag was enabled/disabled
|
|
551
|
+
|
|
552
|
+
Example:
|
|
553
|
+
```python
|
|
554
|
+
result = posthog.get_feature_flag_result('beta-feature', 'distinct_id')
|
|
555
|
+
if result and result.enabled:
|
|
556
|
+
# Use the variant and payload
|
|
557
|
+
print(f"Variant: {result.variant}")
|
|
558
|
+
print(f"Payload: {result.payload}")
|
|
559
|
+
```
|
|
560
|
+
"""
|
|
561
|
+
return _proxy(
|
|
562
|
+
"get_feature_flag_result",
|
|
563
|
+
key=key,
|
|
564
|
+
distinct_id=distinct_id,
|
|
565
|
+
groups=groups or {},
|
|
566
|
+
person_properties=person_properties or {},
|
|
567
|
+
group_properties=group_properties or {},
|
|
568
|
+
only_evaluate_locally=only_evaluate_locally,
|
|
569
|
+
send_feature_flag_events=send_feature_flag_events,
|
|
570
|
+
disable_geoip=disable_geoip,
|
|
571
|
+
)
|
|
572
|
+
|
|
573
|
+
|
|
531
574
|
def get_feature_flag_payload(
|
|
532
575
|
key,
|
|
533
576
|
distinct_id,
|
|
534
577
|
match_value=None,
|
|
535
|
-
groups=
|
|
536
|
-
person_properties=
|
|
537
|
-
group_properties=
|
|
578
|
+
groups=None, # type: Optional[dict]
|
|
579
|
+
person_properties=None, # type: Optional[dict]
|
|
580
|
+
group_properties=None, # type: Optional[dict]
|
|
538
581
|
only_evaluate_locally=False,
|
|
539
582
|
send_feature_flag_events=True,
|
|
540
583
|
disable_geoip=None, # type: Optional[bool]
|
|
@@ -544,9 +587,9 @@ def get_feature_flag_payload(
|
|
|
544
587
|
key=key,
|
|
545
588
|
distinct_id=distinct_id,
|
|
546
589
|
match_value=match_value,
|
|
547
|
-
groups=groups,
|
|
548
|
-
person_properties=person_properties,
|
|
549
|
-
group_properties=group_properties,
|
|
590
|
+
groups=groups or {},
|
|
591
|
+
person_properties=person_properties or {},
|
|
592
|
+
group_properties=group_properties or {},
|
|
550
593
|
only_evaluate_locally=only_evaluate_locally,
|
|
551
594
|
send_feature_flag_events=send_feature_flag_events,
|
|
552
595
|
disable_geoip=disable_geoip,
|
|
@@ -575,18 +618,18 @@ def get_remote_config_payload(
|
|
|
575
618
|
|
|
576
619
|
def get_all_flags_and_payloads(
|
|
577
620
|
distinct_id,
|
|
578
|
-
groups=
|
|
579
|
-
person_properties=
|
|
580
|
-
group_properties=
|
|
621
|
+
groups=None, # type: Optional[dict]
|
|
622
|
+
person_properties=None, # type: Optional[dict]
|
|
623
|
+
group_properties=None, # type: Optional[dict]
|
|
581
624
|
only_evaluate_locally=False,
|
|
582
625
|
disable_geoip=None, # type: Optional[bool]
|
|
583
626
|
) -> FlagsAndPayloads:
|
|
584
627
|
return _proxy(
|
|
585
628
|
"get_all_flags_and_payloads",
|
|
586
629
|
distinct_id=distinct_id,
|
|
587
|
-
groups=groups,
|
|
588
|
-
person_properties=person_properties,
|
|
589
|
-
group_properties=group_properties,
|
|
630
|
+
groups=groups or {},
|
|
631
|
+
person_properties=person_properties or {},
|
|
632
|
+
group_properties=group_properties or {},
|
|
590
633
|
only_evaluate_locally=only_evaluate_locally,
|
|
591
634
|
disable_geoip=disable_geoip,
|
|
592
635
|
)
|
|
@@ -42,6 +42,12 @@ class Client:
|
|
|
42
42
|
def __init__(
|
|
43
43
|
self,
|
|
44
44
|
api_key: Optional[str] = None,
|
|
45
|
+
vertexai: Optional[bool] = None,
|
|
46
|
+
credentials: Optional[Any] = None,
|
|
47
|
+
project: Optional[str] = None,
|
|
48
|
+
location: Optional[str] = None,
|
|
49
|
+
debug_config: Optional[Any] = None,
|
|
50
|
+
http_options: Optional[Any] = None,
|
|
45
51
|
posthog_client: Optional[PostHogClient] = None,
|
|
46
52
|
posthog_distinct_id: Optional[str] = None,
|
|
47
53
|
posthog_properties: Optional[Dict[str, Any]] = None,
|
|
@@ -51,7 +57,13 @@ class Client:
|
|
|
51
57
|
):
|
|
52
58
|
"""
|
|
53
59
|
Args:
|
|
54
|
-
api_key: Google AI API key. If not provided, will use GOOGLE_API_KEY or API_KEY environment variable
|
|
60
|
+
api_key: Google AI API key. If not provided, will use GOOGLE_API_KEY or API_KEY environment variable (not required for Vertex AI)
|
|
61
|
+
vertexai: Whether to use Vertex AI authentication
|
|
62
|
+
credentials: Vertex AI credentials object
|
|
63
|
+
project: GCP project ID for Vertex AI
|
|
64
|
+
location: GCP location for Vertex AI
|
|
65
|
+
debug_config: Debug configuration for the client
|
|
66
|
+
http_options: HTTP options for the client
|
|
55
67
|
posthog_client: PostHog client for tracking usage
|
|
56
68
|
posthog_distinct_id: Default distinct ID for all calls (can be overridden per call)
|
|
57
69
|
posthog_properties: Default properties for all calls (can be overridden per call)
|
|
@@ -66,6 +78,12 @@ class Client:
|
|
|
66
78
|
|
|
67
79
|
self.models = Models(
|
|
68
80
|
api_key=api_key,
|
|
81
|
+
vertexai=vertexai,
|
|
82
|
+
credentials=credentials,
|
|
83
|
+
project=project,
|
|
84
|
+
location=location,
|
|
85
|
+
debug_config=debug_config,
|
|
86
|
+
http_options=http_options,
|
|
69
87
|
posthog_client=self._ph_client,
|
|
70
88
|
posthog_distinct_id=posthog_distinct_id,
|
|
71
89
|
posthog_properties=posthog_properties,
|
|
@@ -85,6 +103,12 @@ class Models:
|
|
|
85
103
|
def __init__(
|
|
86
104
|
self,
|
|
87
105
|
api_key: Optional[str] = None,
|
|
106
|
+
vertexai: Optional[bool] = None,
|
|
107
|
+
credentials: Optional[Any] = None,
|
|
108
|
+
project: Optional[str] = None,
|
|
109
|
+
location: Optional[str] = None,
|
|
110
|
+
debug_config: Optional[Any] = None,
|
|
111
|
+
http_options: Optional[Any] = None,
|
|
88
112
|
posthog_client: Optional[PostHogClient] = None,
|
|
89
113
|
posthog_distinct_id: Optional[str] = None,
|
|
90
114
|
posthog_properties: Optional[Dict[str, Any]] = None,
|
|
@@ -94,7 +118,13 @@ class Models:
|
|
|
94
118
|
):
|
|
95
119
|
"""
|
|
96
120
|
Args:
|
|
97
|
-
api_key: Google AI API key. If not provided, will use GOOGLE_API_KEY or API_KEY environment variable
|
|
121
|
+
api_key: Google AI API key. If not provided, will use GOOGLE_API_KEY or API_KEY environment variable (not required for Vertex AI)
|
|
122
|
+
vertexai: Whether to use Vertex AI authentication
|
|
123
|
+
credentials: Vertex AI credentials object
|
|
124
|
+
project: GCP project ID for Vertex AI
|
|
125
|
+
location: GCP location for Vertex AI
|
|
126
|
+
debug_config: Debug configuration for the client
|
|
127
|
+
http_options: HTTP options for the client
|
|
98
128
|
posthog_client: PostHog client for tracking usage
|
|
99
129
|
posthog_distinct_id: Default distinct ID for all calls
|
|
100
130
|
posthog_properties: Default properties for all calls
|
|
@@ -113,16 +143,40 @@ class Models:
|
|
|
113
143
|
self._default_privacy_mode = posthog_privacy_mode
|
|
114
144
|
self._default_groups = posthog_groups
|
|
115
145
|
|
|
116
|
-
#
|
|
117
|
-
|
|
118
|
-
|
|
146
|
+
# Build genai.Client arguments
|
|
147
|
+
client_args: Dict[str, Any] = {}
|
|
148
|
+
|
|
149
|
+
# Add Vertex AI parameters if provided
|
|
150
|
+
if vertexai is not None:
|
|
151
|
+
client_args["vertexai"] = vertexai
|
|
152
|
+
if credentials is not None:
|
|
153
|
+
client_args["credentials"] = credentials
|
|
154
|
+
if project is not None:
|
|
155
|
+
client_args["project"] = project
|
|
156
|
+
if location is not None:
|
|
157
|
+
client_args["location"] = location
|
|
158
|
+
if debug_config is not None:
|
|
159
|
+
client_args["debug_config"] = debug_config
|
|
160
|
+
if http_options is not None:
|
|
161
|
+
client_args["http_options"] = http_options
|
|
162
|
+
|
|
163
|
+
# Handle API key authentication
|
|
164
|
+
if vertexai:
|
|
165
|
+
# For Vertex AI, api_key is optional
|
|
166
|
+
if api_key is not None:
|
|
167
|
+
client_args["api_key"] = api_key
|
|
168
|
+
else:
|
|
169
|
+
# For non-Vertex AI mode, api_key is required (backwards compatibility)
|
|
170
|
+
if api_key is None:
|
|
171
|
+
api_key = os.environ.get("GOOGLE_API_KEY") or os.environ.get("API_KEY")
|
|
119
172
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
173
|
+
if api_key is None:
|
|
174
|
+
raise ValueError(
|
|
175
|
+
"API key must be provided either as parameter or via GOOGLE_API_KEY/API_KEY environment variable"
|
|
176
|
+
)
|
|
177
|
+
client_args["api_key"] = api_key
|
|
124
178
|
|
|
125
|
-
self._client = genai.Client(
|
|
179
|
+
self._client = genai.Client(**client_args)
|
|
126
180
|
self._base_url = "https://generativelanguage.googleapis.com"
|
|
127
181
|
|
|
128
182
|
def _merge_posthog_params(
|
{posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/posthoganalytics/ai/langchain/callbacks.py
RENAMED
|
@@ -556,12 +556,9 @@ class CallbackHandler(BaseCallbackHandler):
|
|
|
556
556
|
"$ai_latency": run.latency,
|
|
557
557
|
"$ai_base_url": run.base_url,
|
|
558
558
|
}
|
|
559
|
+
|
|
559
560
|
if run.tools:
|
|
560
|
-
event_properties["$ai_tools"] =
|
|
561
|
-
self._ph_client,
|
|
562
|
-
self._privacy_mode,
|
|
563
|
-
run.tools,
|
|
564
|
-
)
|
|
561
|
+
event_properties["$ai_tools"] = run.tools
|
|
565
562
|
|
|
566
563
|
if isinstance(output, BaseException):
|
|
567
564
|
event_properties["$ai_http_status"] = _get_http_status(output)
|
|
@@ -587,7 +584,8 @@ class CallbackHandler(BaseCallbackHandler):
|
|
|
587
584
|
]
|
|
588
585
|
else:
|
|
589
586
|
completions = [
|
|
590
|
-
|
|
587
|
+
_extract_raw_response(generation)
|
|
588
|
+
for generation in generation_result
|
|
591
589
|
]
|
|
592
590
|
event_properties["$ai_output_choices"] = with_privacy_mode(
|
|
593
591
|
self._ph_client, self._privacy_mode, completions
|
|
@@ -618,7 +616,7 @@ class CallbackHandler(BaseCallbackHandler):
|
|
|
618
616
|
)
|
|
619
617
|
|
|
620
618
|
|
|
621
|
-
def
|
|
619
|
+
def _extract_raw_response(last_response):
|
|
622
620
|
"""Extract the response from the last response of the LLM call."""
|
|
623
621
|
# We return the text of the response if not empty
|
|
624
622
|
if last_response.text is not None and last_response.text.strip() != "":
|
|
@@ -11,6 +11,7 @@ except ImportError:
|
|
|
11
11
|
|
|
12
12
|
from posthoganalytics.ai.utils import (
|
|
13
13
|
call_llm_and_track_usage,
|
|
14
|
+
extract_available_tool_calls,
|
|
14
15
|
get_model_params,
|
|
15
16
|
with_privacy_mode,
|
|
16
17
|
)
|
|
@@ -167,6 +168,7 @@ class WrappedResponses:
|
|
|
167
168
|
usage_stats,
|
|
168
169
|
latency,
|
|
169
170
|
output,
|
|
171
|
+
extract_available_tool_calls("openai", kwargs),
|
|
170
172
|
)
|
|
171
173
|
|
|
172
174
|
return generator()
|
|
@@ -182,7 +184,7 @@ class WrappedResponses:
|
|
|
182
184
|
usage_stats: Dict[str, int],
|
|
183
185
|
latency: float,
|
|
184
186
|
output: Any,
|
|
185
|
-
|
|
187
|
+
available_tool_calls: Optional[List[Dict[str, Any]]] = None,
|
|
186
188
|
):
|
|
187
189
|
if posthog_trace_id is None:
|
|
188
190
|
posthog_trace_id = str(uuid.uuid4())
|
|
@@ -212,12 +214,8 @@ class WrappedResponses:
|
|
|
212
214
|
**(posthog_properties or {}),
|
|
213
215
|
}
|
|
214
216
|
|
|
215
|
-
if
|
|
216
|
-
event_properties["$ai_tools"] =
|
|
217
|
-
self._client._ph_client,
|
|
218
|
-
posthog_privacy_mode,
|
|
219
|
-
tool_calls,
|
|
220
|
-
)
|
|
217
|
+
if available_tool_calls:
|
|
218
|
+
event_properties["$ai_tools"] = available_tool_calls
|
|
221
219
|
|
|
222
220
|
if posthog_distinct_id is None:
|
|
223
221
|
event_properties["$process_person_profile"] = False
|
|
@@ -341,7 +339,6 @@ class WrappedCompletions:
|
|
|
341
339
|
start_time = time.time()
|
|
342
340
|
usage_stats: Dict[str, int] = {}
|
|
343
341
|
accumulated_content = []
|
|
344
|
-
accumulated_tools = {}
|
|
345
342
|
if "stream_options" not in kwargs:
|
|
346
343
|
kwargs["stream_options"] = {}
|
|
347
344
|
kwargs["stream_options"]["include_usage"] = True
|
|
@@ -350,7 +347,6 @@ class WrappedCompletions:
|
|
|
350
347
|
def generator():
|
|
351
348
|
nonlocal usage_stats
|
|
352
349
|
nonlocal accumulated_content # noqa: F824
|
|
353
|
-
nonlocal accumulated_tools # noqa: F824
|
|
354
350
|
|
|
355
351
|
try:
|
|
356
352
|
for chunk in response:
|
|
@@ -389,31 +385,12 @@ class WrappedCompletions:
|
|
|
389
385
|
if content:
|
|
390
386
|
accumulated_content.append(content)
|
|
391
387
|
|
|
392
|
-
# Process tool calls
|
|
393
|
-
tool_calls = getattr(chunk.choices[0].delta, "tool_calls", None)
|
|
394
|
-
if tool_calls:
|
|
395
|
-
for tool_call in tool_calls:
|
|
396
|
-
index = tool_call.index
|
|
397
|
-
if index not in accumulated_tools:
|
|
398
|
-
accumulated_tools[index] = tool_call
|
|
399
|
-
else:
|
|
400
|
-
# Append arguments for existing tool calls
|
|
401
|
-
if hasattr(tool_call, "function") and hasattr(
|
|
402
|
-
tool_call.function, "arguments"
|
|
403
|
-
):
|
|
404
|
-
accumulated_tools[
|
|
405
|
-
index
|
|
406
|
-
].function.arguments += (
|
|
407
|
-
tool_call.function.arguments
|
|
408
|
-
)
|
|
409
|
-
|
|
410
388
|
yield chunk
|
|
411
389
|
|
|
412
390
|
finally:
|
|
413
391
|
end_time = time.time()
|
|
414
392
|
latency = end_time - start_time
|
|
415
393
|
output = "".join(accumulated_content)
|
|
416
|
-
tools = list(accumulated_tools.values()) if accumulated_tools else None
|
|
417
394
|
self._capture_streaming_event(
|
|
418
395
|
posthog_distinct_id,
|
|
419
396
|
posthog_trace_id,
|
|
@@ -424,7 +401,7 @@ class WrappedCompletions:
|
|
|
424
401
|
usage_stats,
|
|
425
402
|
latency,
|
|
426
403
|
output,
|
|
427
|
-
|
|
404
|
+
extract_available_tool_calls("openai", kwargs),
|
|
428
405
|
)
|
|
429
406
|
|
|
430
407
|
return generator()
|
|
@@ -440,7 +417,7 @@ class WrappedCompletions:
|
|
|
440
417
|
usage_stats: Dict[str, int],
|
|
441
418
|
latency: float,
|
|
442
419
|
output: Any,
|
|
443
|
-
|
|
420
|
+
available_tool_calls: Optional[List[Dict[str, Any]]] = None,
|
|
444
421
|
):
|
|
445
422
|
if posthog_trace_id is None:
|
|
446
423
|
posthog_trace_id = str(uuid.uuid4())
|
|
@@ -470,12 +447,8 @@ class WrappedCompletions:
|
|
|
470
447
|
**(posthog_properties or {}),
|
|
471
448
|
}
|
|
472
449
|
|
|
473
|
-
if
|
|
474
|
-
event_properties["$ai_tools"] =
|
|
475
|
-
self._client._ph_client,
|
|
476
|
-
posthog_privacy_mode,
|
|
477
|
-
tool_calls,
|
|
478
|
-
)
|
|
450
|
+
if available_tool_calls:
|
|
451
|
+
event_properties["$ai_tools"] = available_tool_calls
|
|
479
452
|
|
|
480
453
|
if posthog_distinct_id is None:
|
|
481
454
|
event_properties["$process_person_profile"] = False
|
{posthoganalytics-6.3.3 → posthoganalytics-6.4.0}/posthoganalytics/ai/openai/openai_async.py
RENAMED
|
@@ -12,6 +12,7 @@ except ImportError:
|
|
|
12
12
|
from posthoganalytics import setup
|
|
13
13
|
from posthoganalytics.ai.utils import (
|
|
14
14
|
call_llm_and_track_usage_async,
|
|
15
|
+
extract_available_tool_calls,
|
|
15
16
|
get_model_params,
|
|
16
17
|
with_privacy_mode,
|
|
17
18
|
)
|
|
@@ -168,6 +169,7 @@ class WrappedResponses:
|
|
|
168
169
|
usage_stats,
|
|
169
170
|
latency,
|
|
170
171
|
output,
|
|
172
|
+
extract_available_tool_calls("openai", kwargs),
|
|
171
173
|
)
|
|
172
174
|
|
|
173
175
|
return async_generator()
|
|
@@ -183,7 +185,7 @@ class WrappedResponses:
|
|
|
183
185
|
usage_stats: Dict[str, int],
|
|
184
186
|
latency: float,
|
|
185
187
|
output: Any,
|
|
186
|
-
|
|
188
|
+
available_tool_calls: Optional[List[Dict[str, Any]]] = None,
|
|
187
189
|
):
|
|
188
190
|
if posthog_trace_id is None:
|
|
189
191
|
posthog_trace_id = str(uuid.uuid4())
|
|
@@ -213,12 +215,8 @@ class WrappedResponses:
|
|
|
213
215
|
**(posthog_properties or {}),
|
|
214
216
|
}
|
|
215
217
|
|
|
216
|
-
if
|
|
217
|
-
event_properties["$ai_tools"] =
|
|
218
|
-
self._client._ph_client,
|
|
219
|
-
posthog_privacy_mode,
|
|
220
|
-
tool_calls,
|
|
221
|
-
)
|
|
218
|
+
if available_tool_calls:
|
|
219
|
+
event_properties["$ai_tools"] = available_tool_calls
|
|
222
220
|
|
|
223
221
|
if posthog_distinct_id is None:
|
|
224
222
|
event_properties["$process_person_profile"] = False
|
|
@@ -344,7 +342,6 @@ class WrappedCompletions:
|
|
|
344
342
|
start_time = time.time()
|
|
345
343
|
usage_stats: Dict[str, int] = {}
|
|
346
344
|
accumulated_content = []
|
|
347
|
-
accumulated_tools = {}
|
|
348
345
|
|
|
349
346
|
if "stream_options" not in kwargs:
|
|
350
347
|
kwargs["stream_options"] = {}
|
|
@@ -354,7 +351,6 @@ class WrappedCompletions:
|
|
|
354
351
|
async def async_generator():
|
|
355
352
|
nonlocal usage_stats
|
|
356
353
|
nonlocal accumulated_content # noqa: F824
|
|
357
|
-
nonlocal accumulated_tools # noqa: F824
|
|
358
354
|
|
|
359
355
|
try:
|
|
360
356
|
async for chunk in response:
|
|
@@ -393,31 +389,12 @@ class WrappedCompletions:
|
|
|
393
389
|
if content:
|
|
394
390
|
accumulated_content.append(content)
|
|
395
391
|
|
|
396
|
-
# Process tool calls
|
|
397
|
-
tool_calls = getattr(chunk.choices[0].delta, "tool_calls", None)
|
|
398
|
-
if tool_calls:
|
|
399
|
-
for tool_call in tool_calls:
|
|
400
|
-
index = tool_call.index
|
|
401
|
-
if index not in accumulated_tools:
|
|
402
|
-
accumulated_tools[index] = tool_call
|
|
403
|
-
else:
|
|
404
|
-
# Append arguments for existing tool calls
|
|
405
|
-
if hasattr(tool_call, "function") and hasattr(
|
|
406
|
-
tool_call.function, "arguments"
|
|
407
|
-
):
|
|
408
|
-
accumulated_tools[
|
|
409
|
-
index
|
|
410
|
-
].function.arguments += (
|
|
411
|
-
tool_call.function.arguments
|
|
412
|
-
)
|
|
413
|
-
|
|
414
392
|
yield chunk
|
|
415
393
|
|
|
416
394
|
finally:
|
|
417
395
|
end_time = time.time()
|
|
418
396
|
latency = end_time - start_time
|
|
419
397
|
output = "".join(accumulated_content)
|
|
420
|
-
tools = list(accumulated_tools.values()) if accumulated_tools else None
|
|
421
398
|
await self._capture_streaming_event(
|
|
422
399
|
posthog_distinct_id,
|
|
423
400
|
posthog_trace_id,
|
|
@@ -428,7 +405,7 @@ class WrappedCompletions:
|
|
|
428
405
|
usage_stats,
|
|
429
406
|
latency,
|
|
430
407
|
output,
|
|
431
|
-
|
|
408
|
+
extract_available_tool_calls("openai", kwargs),
|
|
432
409
|
)
|
|
433
410
|
|
|
434
411
|
return async_generator()
|
|
@@ -444,7 +421,7 @@ class WrappedCompletions:
|
|
|
444
421
|
usage_stats: Dict[str, int],
|
|
445
422
|
latency: float,
|
|
446
423
|
output: Any,
|
|
447
|
-
|
|
424
|
+
available_tool_calls: Optional[List[Dict[str, Any]]] = None,
|
|
448
425
|
):
|
|
449
426
|
if posthog_trace_id is None:
|
|
450
427
|
posthog_trace_id = str(uuid.uuid4())
|
|
@@ -474,12 +451,8 @@ class WrappedCompletions:
|
|
|
474
451
|
**(posthog_properties or {}),
|
|
475
452
|
}
|
|
476
453
|
|
|
477
|
-
if
|
|
478
|
-
event_properties["$ai_tools"] =
|
|
479
|
-
self._client._ph_client,
|
|
480
|
-
posthog_privacy_mode,
|
|
481
|
-
tool_calls,
|
|
482
|
-
)
|
|
454
|
+
if available_tool_calls:
|
|
455
|
+
event_properties["$ai_tools"] = available_tool_calls
|
|
483
456
|
|
|
484
457
|
if posthog_distinct_id is None:
|
|
485
458
|
event_properties["$process_person_profile"] = False
|