posthoganalytics 6.7.3__tar.gz → 6.7.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 (62) hide show
  1. {posthoganalytics-6.7.3/posthoganalytics.egg-info → posthoganalytics-6.7.4}/PKG-INFO +1 -1
  2. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics/ai/gemini/gemini.py +7 -7
  3. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics/ai/gemini/gemini_converter.py +56 -0
  4. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics/ai/openai/openai_converter.py +3 -4
  5. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics/ai/utils.py +18 -11
  6. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics/version.py +1 -1
  7. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4/posthoganalytics.egg-info}/PKG-INFO +1 -1
  8. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/LICENSE +0 -0
  9. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/MANIFEST.in +0 -0
  10. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/README.md +0 -0
  11. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics/__init__.py +0 -0
  12. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics/ai/__init__.py +0 -0
  13. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics/ai/anthropic/__init__.py +0 -0
  14. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics/ai/anthropic/anthropic.py +0 -0
  15. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics/ai/anthropic/anthropic_async.py +0 -0
  16. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics/ai/anthropic/anthropic_converter.py +0 -0
  17. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics/ai/anthropic/anthropic_providers.py +0 -0
  18. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics/ai/gemini/__init__.py +0 -0
  19. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics/ai/langchain/__init__.py +0 -0
  20. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics/ai/langchain/callbacks.py +0 -0
  21. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics/ai/openai/__init__.py +0 -0
  22. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics/ai/openai/openai.py +0 -0
  23. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics/ai/openai/openai_async.py +0 -0
  24. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics/ai/openai/openai_providers.py +0 -0
  25. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics/ai/sanitization.py +0 -0
  26. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics/ai/types.py +0 -0
  27. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics/args.py +0 -0
  28. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics/client.py +0 -0
  29. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics/consumer.py +0 -0
  30. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics/contexts.py +0 -0
  31. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics/exception_capture.py +0 -0
  32. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics/exception_utils.py +0 -0
  33. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics/feature_flags.py +0 -0
  34. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics/integrations/__init__.py +0 -0
  35. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics/integrations/django.py +0 -0
  36. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics/poller.py +0 -0
  37. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics/py.typed +0 -0
  38. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics/request.py +0 -0
  39. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics/test/__init__.py +0 -0
  40. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics/test/test_before_send.py +0 -0
  41. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics/test/test_client.py +0 -0
  42. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics/test/test_consumer.py +0 -0
  43. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics/test/test_contexts.py +0 -0
  44. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics/test/test_exception_capture.py +0 -0
  45. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics/test/test_feature_flag.py +0 -0
  46. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics/test/test_feature_flag_result.py +0 -0
  47. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics/test/test_feature_flags.py +0 -0
  48. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics/test/test_module.py +0 -0
  49. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics/test/test_request.py +0 -0
  50. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics/test/test_size_limited_dict.py +0 -0
  51. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics/test/test_types.py +0 -0
  52. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics/test/test_utils.py +0 -0
  53. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics/types.py +0 -0
  54. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics/utils.py +0 -0
  55. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics.egg-info/SOURCES.txt +0 -0
  56. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics.egg-info/dependency_links.txt +0 -0
  57. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics.egg-info/requires.txt +0 -0
  58. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/posthoganalytics.egg-info/top_level.txt +0 -0
  59. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/pyproject.toml +0 -0
  60. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/setup.cfg +0 -0
  61. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/setup.py +0 -0
  62. {posthoganalytics-6.7.3 → posthoganalytics-6.7.4}/setup_analytics.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: posthoganalytics
3
- Version: 6.7.3
3
+ Version: 6.7.4
4
4
  Summary: Integrate PostHog into any python application.
5
5
  Home-page: https://github.com/posthog/posthog-python
6
6
  Author: Posthog
@@ -3,7 +3,8 @@ import time
3
3
  import uuid
4
4
  from typing import Any, Dict, Optional
5
5
 
6
- from posthoganalytics.ai.types import TokenUsage
6
+ from posthoganalytics.ai.types import TokenUsage, StreamingEventData
7
+ from posthoganalytics.ai.utils import merge_system_prompt
7
8
 
8
9
  try:
9
10
  from google import genai
@@ -19,7 +20,6 @@ from posthoganalytics.ai.utils import (
19
20
  merge_usage_stats,
20
21
  )
21
22
  from posthoganalytics.ai.gemini.gemini_converter import (
22
- format_gemini_input,
23
23
  extract_gemini_usage_from_chunk,
24
24
  extract_gemini_content_from_chunk,
25
25
  format_gemini_streaming_output,
@@ -356,10 +356,8 @@ class Models:
356
356
  latency: float,
357
357
  output: Any,
358
358
  ):
359
- from posthoganalytics.ai.types import StreamingEventData
360
-
361
359
  # Prepare standardized event data
362
- formatted_input = self._format_input(contents)
360
+ formatted_input = self._format_input(contents, **kwargs)
363
361
  sanitized_input = sanitize_gemini(formatted_input)
364
362
 
365
363
  event_data = StreamingEventData(
@@ -381,10 +379,12 @@ class Models:
381
379
  # Use the common capture function
382
380
  capture_streaming_event(self._ph_client, event_data)
383
381
 
384
- def _format_input(self, contents):
382
+ def _format_input(self, contents, **kwargs):
385
383
  """Format input contents for PostHog tracking"""
386
384
 
387
- return format_gemini_input(contents)
385
+ # Create kwargs dict with contents for merge_system_prompt
386
+ input_kwargs = {"contents": contents, **kwargs}
387
+ return merge_system_prompt(input_kwargs, "gemini")
388
388
 
389
389
  def generate_content_stream(
390
390
  self,
@@ -220,6 +220,30 @@ def format_gemini_response(response: Any) -> List[FormattedMessage]:
220
220
  return output
221
221
 
222
222
 
223
+ def extract_gemini_system_instruction(config: Any) -> Optional[str]:
224
+ """
225
+ Extract system instruction from Gemini config parameter.
226
+
227
+ Args:
228
+ config: Config object or dict that may contain system instruction
229
+
230
+ Returns:
231
+ System instruction string if present, None otherwise
232
+ """
233
+ if config is None:
234
+ return None
235
+
236
+ # Handle different config formats
237
+ if hasattr(config, "system_instruction"):
238
+ return config.system_instruction
239
+ elif isinstance(config, dict) and "system_instruction" in config:
240
+ return config["system_instruction"]
241
+ elif isinstance(config, dict) and "systemInstruction" in config:
242
+ return config["systemInstruction"]
243
+
244
+ return None
245
+
246
+
223
247
  def extract_gemini_tools(kwargs: Dict[str, Any]) -> Optional[Any]:
224
248
  """
225
249
  Extract tool definitions from Gemini API kwargs.
@@ -237,6 +261,38 @@ def extract_gemini_tools(kwargs: Dict[str, Any]) -> Optional[Any]:
237
261
  return None
238
262
 
239
263
 
264
+ def format_gemini_input_with_system(
265
+ contents: Any, config: Any = None
266
+ ) -> List[FormattedMessage]:
267
+ """
268
+ Format Gemini input contents into standardized message format, including system instruction handling.
269
+
270
+ Args:
271
+ contents: Input contents in various possible formats
272
+ config: Config object or dict that may contain system instruction
273
+
274
+ Returns:
275
+ List of formatted messages with role and content fields, with system message prepended if needed
276
+ """
277
+ formatted_messages = format_gemini_input(contents)
278
+
279
+ # Check if system instruction is provided in config parameter
280
+ system_instruction = extract_gemini_system_instruction(config)
281
+
282
+ if system_instruction is not None:
283
+ has_system = any(msg.get("role") == "system" for msg in formatted_messages)
284
+ if not has_system:
285
+ from posthoganalytics.ai.types import FormattedMessage
286
+
287
+ system_message: FormattedMessage = {
288
+ "role": "system",
289
+ "content": system_instruction,
290
+ }
291
+ formatted_messages = [system_message] + list(formatted_messages)
292
+
293
+ return formatted_messages
294
+
295
+
240
296
  def format_gemini_input(contents: Any) -> List[FormattedMessage]:
241
297
  """
242
298
  Format Gemini input contents into standardized message format for PostHog tracking.
@@ -606,7 +606,6 @@ def format_openai_streaming_input(
606
606
  Returns:
607
607
  Formatted input ready for PostHog tracking
608
608
  """
609
- if api_type == "chat":
610
- return kwargs.get("messages")
611
- else: # responses API
612
- return kwargs.get("input")
609
+ from posthoganalytics.ai.utils import merge_system_prompt
610
+
611
+ return merge_system_prompt(kwargs, "openai")
@@ -1,9 +1,9 @@
1
1
  import time
2
2
  import uuid
3
- from typing import Any, Callable, Dict, Optional
3
+ from typing import Any, Callable, Dict, List, Optional, cast
4
4
 
5
5
  from posthoganalytics.client import Client as PostHogClient
6
- from posthoganalytics.ai.types import StreamingEventData, TokenUsage
6
+ from posthoganalytics.ai.types import FormattedMessage, StreamingEventData, TokenUsage
7
7
  from posthoganalytics.ai.sanitization import (
8
8
  sanitize_openai,
9
9
  sanitize_anthropic,
@@ -158,7 +158,9 @@ def extract_available_tool_calls(provider: str, kwargs: Dict[str, Any]):
158
158
  return None
159
159
 
160
160
 
161
- def merge_system_prompt(kwargs: Dict[str, Any], provider: str):
161
+ def merge_system_prompt(
162
+ kwargs: Dict[str, Any], provider: str
163
+ ) -> List[FormattedMessage]:
162
164
  """
163
165
  Merge system prompts and format messages for the given provider.
164
166
  """
@@ -169,10 +171,11 @@ def merge_system_prompt(kwargs: Dict[str, Any], provider: str):
169
171
  system = kwargs.get("system")
170
172
  return format_anthropic_input(messages, system)
171
173
  elif provider == "gemini":
172
- from posthoganalytics.ai.gemini.gemini_converter import format_gemini_input
174
+ from posthoganalytics.ai.gemini.gemini_converter import format_gemini_input_with_system
173
175
 
174
176
  contents = kwargs.get("contents", [])
175
- return format_gemini_input(contents)
177
+ config = kwargs.get("config")
178
+ return format_gemini_input_with_system(contents, config)
176
179
  elif provider == "openai":
177
180
  from posthoganalytics.ai.openai.openai_converter import format_openai_input
178
181
 
@@ -187,9 +190,11 @@ def merge_system_prompt(kwargs: Dict[str, Any], provider: str):
187
190
  if kwargs.get("system") is not None:
188
191
  has_system = any(msg.get("role") == "system" for msg in messages)
189
192
  if not has_system:
190
- messages = [
191
- {"role": "system", "content": kwargs.get("system")}
192
- ] + messages
193
+ system_msg = cast(
194
+ FormattedMessage,
195
+ {"role": "system", "content": kwargs.get("system")},
196
+ )
197
+ messages = [system_msg] + messages
193
198
 
194
199
  # For Responses API, add instructions to the system prompt if provided
195
200
  if kwargs.get("instructions") is not None:
@@ -207,9 +212,11 @@ def merge_system_prompt(kwargs: Dict[str, Any], provider: str):
207
212
  )
208
213
  else:
209
214
  # Create a new system message with instructions
210
- messages = [
211
- {"role": "system", "content": kwargs.get("instructions")}
212
- ] + messages
215
+ instruction_msg = cast(
216
+ FormattedMessage,
217
+ {"role": "system", "content": kwargs.get("instructions")},
218
+ )
219
+ messages = [instruction_msg] + messages
213
220
 
214
221
  return messages
215
222
 
@@ -1,4 +1,4 @@
1
- VERSION = "6.7.3"
1
+ VERSION = "6.7.4"
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.7.3
3
+ Version: 6.7.4
4
4
  Summary: Integrate PostHog into any python application.
5
5
  Home-page: https://github.com/posthog/posthog-python
6
6
  Author: Posthog