posthoganalytics 6.3.2__tar.gz → 6.3.4__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 (57) hide show
  1. {posthoganalytics-6.3.2/posthoganalytics.egg-info → posthoganalytics-6.3.4}/PKG-INFO +1 -1
  2. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/posthoganalytics/__init__.py +74 -31
  3. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/posthoganalytics/ai/langchain/callbacks.py +5 -7
  4. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/posthoganalytics/ai/openai/openai.py +9 -36
  5. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/posthoganalytics/ai/openai/openai_async.py +9 -36
  6. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/posthoganalytics/ai/utils.py +136 -93
  7. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/posthoganalytics/client.py +53 -33
  8. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/posthoganalytics/test/test_client.py +113 -4
  9. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/posthoganalytics/types.py +8 -3
  10. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/posthoganalytics/version.py +1 -1
  11. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4/posthoganalytics.egg-info}/PKG-INFO +1 -1
  12. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/LICENSE +0 -0
  13. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/MANIFEST.in +0 -0
  14. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/README.md +0 -0
  15. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/posthoganalytics/ai/__init__.py +0 -0
  16. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/posthoganalytics/ai/anthropic/__init__.py +0 -0
  17. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/posthoganalytics/ai/anthropic/anthropic.py +0 -0
  18. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/posthoganalytics/ai/anthropic/anthropic_async.py +0 -0
  19. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/posthoganalytics/ai/anthropic/anthropic_providers.py +0 -0
  20. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/posthoganalytics/ai/gemini/__init__.py +0 -0
  21. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/posthoganalytics/ai/gemini/gemini.py +0 -0
  22. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/posthoganalytics/ai/langchain/__init__.py +0 -0
  23. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/posthoganalytics/ai/openai/__init__.py +0 -0
  24. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/posthoganalytics/ai/openai/openai_providers.py +0 -0
  25. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/posthoganalytics/args.py +0 -0
  26. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/posthoganalytics/consumer.py +0 -0
  27. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/posthoganalytics/contexts.py +0 -0
  28. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/posthoganalytics/exception_capture.py +0 -0
  29. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/posthoganalytics/exception_utils.py +0 -0
  30. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/posthoganalytics/feature_flags.py +0 -0
  31. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/posthoganalytics/integrations/__init__.py +0 -0
  32. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/posthoganalytics/integrations/django.py +0 -0
  33. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/posthoganalytics/poller.py +0 -0
  34. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/posthoganalytics/py.typed +0 -0
  35. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/posthoganalytics/request.py +0 -0
  36. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/posthoganalytics/test/__init__.py +0 -0
  37. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/posthoganalytics/test/test_before_send.py +0 -0
  38. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/posthoganalytics/test/test_consumer.py +0 -0
  39. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/posthoganalytics/test/test_contexts.py +0 -0
  40. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/posthoganalytics/test/test_exception_capture.py +0 -0
  41. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/posthoganalytics/test/test_feature_flag.py +0 -0
  42. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/posthoganalytics/test/test_feature_flag_result.py +0 -0
  43. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/posthoganalytics/test/test_feature_flags.py +0 -0
  44. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/posthoganalytics/test/test_module.py +0 -0
  45. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/posthoganalytics/test/test_request.py +0 -0
  46. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/posthoganalytics/test/test_size_limited_dict.py +0 -0
  47. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/posthoganalytics/test/test_types.py +0 -0
  48. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/posthoganalytics/test/test_utils.py +0 -0
  49. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/posthoganalytics/utils.py +0 -0
  50. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/posthoganalytics.egg-info/SOURCES.txt +0 -0
  51. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/posthoganalytics.egg-info/dependency_links.txt +0 -0
  52. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/posthoganalytics.egg-info/requires.txt +0 -0
  53. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/posthoganalytics.egg-info/top_level.txt +0 -0
  54. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/pyproject.toml +0 -0
  55. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/setup.cfg +0 -0
  56. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/setup.py +0 -0
  57. {posthoganalytics-6.3.2 → posthoganalytics-6.3.4}/setup_analytics.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: posthoganalytics
3
- Version: 6.3.2
3
+ Version: 6.3.4
4
4
  Summary: Integrate PostHog into any python application.
5
5
  Home-page: https://github.com/posthog/posthog-python
6
6
  Author: Posthog
@@ -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={}, # type: dict
392
- person_properties={}, # type: dict
393
- group_properties={}, # type: dict
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={}, # type: dict
443
- person_properties={}, # type: dict
444
- group_properties={}, # type: dict
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={}, # type: dict
492
- person_properties={}, # type: dict
493
- group_properties={}, # type: dict
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
  )
@@ -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"] = with_privacy_mode(
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
- _extract_raw_esponse(generation) for generation in generation_result
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 _extract_raw_esponse(last_response):
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
- tool_calls: Optional[List[Dict[str, Any]]] = None,
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 tool_calls:
216
- event_properties["$ai_tools"] = with_privacy_mode(
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
- tools,
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
- tool_calls: Optional[List[Dict[str, Any]]] = None,
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 tool_calls:
474
- event_properties["$ai_tools"] = with_privacy_mode(
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
@@ -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
- tool_calls: Optional[List[Dict[str, Any]]] = None,
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 tool_calls:
217
- event_properties["$ai_tools"] = with_privacy_mode(
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
- tools,
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
- tool_calls: Optional[List[Dict[str, Any]]] = None,
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 tool_calls:
478
- event_properties["$ai_tools"] = with_privacy_mode(
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