
    jKjK                        d dl Z d dlZd dlZd dlmZmZmZ d dlmZm	Z	 d dl
mZ 	 d dlmZ d dlmZ d dl
mZmZmZ d d	lmZmZmZmZmZ d d
l
mZ d dlmZ d dlmZ   G d d      Z G d d      Z!y# e$ r	  ed      w xY w)    N)AnyDictOptional)
TokenUsageStreamingEventDatamerge_system_prompt)genaizTPlease install the Google Gemini SDK to use this feature: 'pip install google-genai')setup)call_llm_and_track_usagecapture_streaming_eventmerge_usage_stats)$extract_gemini_embedding_token_countextract_gemini_usage_from_chunk!extract_gemini_content_from_chunk%extract_gemini_stop_reason_from_chunkformat_gemini_streaming_output)with_privacy_mode)sanitize_gemini)Clientc                       e Zd ZU dZeed<   	 	 	 	 	 	 	 	 	 	 	 	 ddee   dee   dee	   dee   dee   d	ee	   d
ee	   dee   dee   dee
ee	f      dedee
ee	f      fdZy)r   a;  
    A drop-in replacement for genai.Client that automatically sends LLM usage events to PostHog.

    Usage:
        client = Client(
            api_key="your_api_key",
            posthog_client=posthog_client,
            posthog_distinct_id="default_user",  # Optional defaults
            posthog_properties={"team": "ai"}    # Optional defaults
        )
        response = client.models.generate_content(
            model="gemini-2.0-flash",
            contents=["Hello world"],
            posthog_distinct_id="specific_user"  # Override default
        )
    
_ph_clientNapi_keyvertexaicredentialsprojectlocationdebug_confighttp_optionsposthog_clientposthog_distinct_idposthog_propertiesposthog_privacy_modeposthog_groupsc                     |xs
 t               | _        | j                  t        d      t        d|||||||| j                  |	|
||d|| _        y)a  
        Args:
            api_key: Google AI API key. If not provided, will use GOOGLE_API_KEY or API_KEY environment variable (not required for Vertex AI)
            vertexai: Whether to use Vertex AI authentication
            credentials: Vertex AI credentials object
            project: GCP project ID for Vertex AI
            location: GCP location for Vertex AI
            debug_config: Debug configuration for the client
            http_options: HTTP options for the client
            posthog_client: PostHog client for tracking usage
            posthog_distinct_id: Default distinct ID for all calls (can be overridden per call)
            posthog_properties: Default properties for all calls (can be overridden per call)
            posthog_privacy_mode: Default privacy mode for all calls (can be overridden per call)
            posthog_groups: Default groups for all calls (can be overridden per call)
            **kwargs: Additional arguments (for future compatibility)
        N/posthog_client is required for PostHog tracking)r   r   r   r   r   r   r   r    r!   r"   r#   r$    )r   r   
ValueErrorModelsmodels)selfr   r   r   r   r   r   r   r    r!   r"   r#   r$   kwargss                 i/Users/ahmed/devFolder/Ultron/claude-voice/.venv/lib/python3.12/site-packages/posthog/ai/gemini/gemini.py__init__zClient.__init__6   sl    B )3EG??"NOO 
#%%?? 31!5)
 
    NNNNNNNNNNFN)__name__
__module____qualname____doc__PostHogClient__annotations__r   strboolr   r   r.   r'   r/   r-   r   r   "   s    "  "&#'%)!%"&&*&*26-17;%*374
#4
 4.4
 c]	4

 #4
 3-4
 sm4
 sm4
 !/4
 &c]4
 %T#s(^44
 #4
 !c3h04
r/   r   c                      e Zd ZU dZeed<   	 	 	 	 	 	 	 	 	 	 	 	 d)dee   dee   dee	   dee   dee   d	ee	   d
ee	   dee   dee   dee
ee	f      dedee
ee	f      fdZdee   dee   dee
ee	f      dee   dee
ee	f      f
dZ	 	 	 	 	 d*dedee   dee   dee
ee	f      dee   dee
ee	f      de	fdZdedee   dee   dee
ee	f      dedee
ee	f      de	fd Z	 d+dedee   dee   dee
ee	f      dedee
ee	f      de
ee	f   d!ed"ed#e	d$ee   fd%Zd& Z	 	 	 	 	 d*dedee   dee   dee
ee	f      dee   dee
ee	f      de	fd'Z	 	 	 	 	 d*dedee   dee   dee
ee	f      dee   dee
ee	f      de	fd(Zy),r)   zS
    Models interface that mimics genai.Client().models with PostHog tracking.
    r   Nr   r   r   r   r   r   r   r    r!   r"   r#   r$   c                    |xs
 t               | _        | j                  t        d      |	| _        |
xs i | _        || _        || _        i }|||d<   |||d<   |||d<   |||d<   |||d<   |||d<   |r|Z||d	<   nT|@t        j                  j                  d
      xs t        j                  j                  d      }|t        d      ||d	<   t        j                  di || _        d| _        y)au  
        Args:
            api_key: Google AI API key. If not provided, will use GOOGLE_API_KEY or API_KEY environment variable (not required for Vertex AI)
            vertexai: Whether to use Vertex AI authentication
            credentials: Vertex AI credentials object
            project: GCP project ID for Vertex AI
            location: GCP location for Vertex AI
            debug_config: Debug configuration for the client
            http_options: HTTP options for the client
            posthog_client: PostHog client for tracking usage
            posthog_distinct_id: Default distinct ID for all calls
            posthog_properties: Default properties for all calls
            posthog_privacy_mode: Default privacy mode for all calls
            posthog_groups: Default groups for all calls
            **kwargs: Additional arguments (for future compatibility)
        Nr&   r   r   r   r   r   r   r   GOOGLE_API_KEYAPI_KEYz_API key must be provided either as parameter or via GOOGLE_API_KEY/API_KEY environment variablez)https://generativelanguage.googleapis.comr'   )r   r   r(   _default_distinct_id_default_properties_default_privacy_mode_default_groupsosenvirongetr
   r   _client	_base_url)r+   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r,   client_argss                  r-   r.   zModels.__init__t   s5   B )3EG??"NOO %8!#5#; %9"- ') &.K
#")4K&%,K	"&.K
##*6K'#*6K' ")0I& **..)9:WbjjnnY>W u  &-K	"||2k2Dr/   call_distinct_idcall_trace_idcall_propertiescall_privacy_modecall_groupsc                     ||n| j                   }||n| j                  }||n| j                  }t        | j                        }	|r|	j                  |       |t        t        j                               }|||	||fS )z9Merge call-level PostHog parameters with client defaults.)	r=   r?   r@   dictr>   updater7   uuiduuid4)
r+   rG   rH   rI   rJ   rK   distinct_idprivacy_modegroups
propertiess
             r-   _merge_posthog_paramszModels._merge_posthog_params   s      + ** 	 !, ++ 	
 !, 7T=Q=Q $223
o. 

-MM:|VKKr/   modelposthog_trace_idr,   c                     | j                  |||||      \  }	}
}}}||d|}t        |	| j                  d|
|||| j                  | j                  j
                  j                  f	i |S )a  
        Generate content using Gemini's API while tracking usage in PostHog.

        This method signature exactly matches genai.Client().models.generate_content()
        with additional PostHog tracking parameters.

        Args:
            model: The model to use (e.g., 'gemini-2.0-flash')
            contents: The input content for generation
            posthog_distinct_id: ID to associate with the usage event (overrides client default)
            posthog_trace_id: Trace UUID for linking events (auto-generated if not provided)
            posthog_properties: Extra properties to include in the event (merged with client defaults)
            posthog_privacy_mode: Whether to redact sensitive information (overrides client default)
            posthog_groups: Group analytics properties (overrides client default)
            **kwargs: Arguments passed to Gemini's generate_content
        rV   contentsgemini)rU   r   r   rE   rD   r*   generate_content)r+   rV   rZ   r!   rW   r"   r#   r$   r,   rQ   trace_idrT   rR   rS   kwargs_with_contentss                  r-   r\   zModels.generate_content   s    < &&# "$ 	@Xz< */HOO'OONNLL00
 #
 	
r/   rQ   r]   rT   rR   rS   c                      t        j                          t        dd      g d d}	  j                  j                  j                  di |	 fd}
 |
       S )Nr   )input_tokensoutput_tokensrY   c               3     K   	 D ]N  } t        |       }|rt        |d       t        |       }|j                  |       t	        |       }|||  P 	 t        j
                         }|z
  }j                  	
|       y # t        j
                         }|z
  }j                  	
|       w xY ww)N
cumulative)mode)stop_reason)r   r   r   appendr   time_capture_streaming_event)chunkchunk_usagecontent_blockchunk_stop_reasonend_timelatencyaccumulated_contentrZ   rQ   rS   r,   rV   rR   rT   responser+   
start_timere   r]   usage_statss         r-   	generatorz5Models._generate_content_streaming.<locals>.generator5  s    '%E"A%"HK")+{V %Fe$LM$0+22=A )Ne(T%(4&7K' &,  99;"Z/-- ' + .   99;"Z/-- ' + . s   CAB 7C8CCr'   )rg   r   rD   r*   generate_content_stream)r+   rV   rZ   rQ   r]   rT   rR   rS   r,   kwargs_without_streamrs   ro   rp   rq   re   rr   s   `````````  @@@@@r-   _generate_content_streamingz"Models._generate_content_streaming"  sr     YY[
",!1"M %)*/X P P>4<<&&>>WAVW+	 +	 +	Z {r/   rr   rn   outputre   c                      | j                   |fi |}t        |      }t        d|| j                  ||t	        |      |	|
||||||      }t        | j                  |       y )Nr[   )providerrV   base_urlr,   formatted_inputformatted_outputrr   rn   rQ   r]   rT   rR   rS   re   )_format_inputr   r   rE   r   r   r   )r+   rV   rZ   rQ   r]   rT   rR   rS   r,   rr   rn   rw   re   r{   sanitized_input
event_datas                   r-   rh   zModels._capture_streaming_eventd  sr      -$,,X@@)/:'^^+;FC##!%#

$ 	 <r/   c                 &    d|i|}t        |d      S )z*Format input contents for PostHog trackingrZ   r[   r   )r+   rZ   r,   input_kwargss       r-   r}   zModels._format_input  s      #H77"<::r/   c           	      j    | j                  |||||      \  }	}
}}} | j                  |||	|
|||fi |S )a-  
        Stream content from Gemini while tracking usage in PostHog.

        Args:
            model: The Gemini model to use.
            contents: Input content for generation.
            posthog_distinct_id: Optional distinct ID, overriding the client default.
            posthog_trace_id: Optional trace ID. Generated automatically when omitted.
            posthog_properties: Additional properties merged with client defaults.
            posthog_privacy_mode: Whether to redact captured input and output,
                overriding the client default.
            posthog_groups: Optional PostHog groups, overriding the client default.
            **kwargs: Arguments passed to Gemini's ``generate_content_stream`` API.

        Returns:
            A streaming iterator yielding Gemini chunks.
        )rU   rv   )r+   rV   rZ   r!   rW   r"   r#   r$   r,   rQ   r]   rT   rR   rS   s                 r-   rt   zModels.generate_content_stream  sg    < &&# "$ 	@Xz< 0t//	
 	
 		
r/   c                 |   | j                  |||||      \  }	}
}}}t        j                         }d}d}d}	  | j                  j                  j                  d||d|}t        j                         }||z
  }|rt        |      nd}d|t        | j                  ||      ||||
| j                  d|xs i }|rd|d	<   t        |      |d
<   |	d|d<   | j                  j                  |	xs |
d||       |r||S # t
        $ r}|}t        |dd      }Y d}~d}~ww xY w# t        j                         }||z
  }|rt        |      nd}d|t        | j                  ||      ||||
| j                  d|xs i }|rd|d	<   t        |      |d
<   |	d|d<   | j                  j                  |	xs |
d||       w xY w)a  
        Create embeddings using Gemini's API while tracking usage in PostHog.

        Args:
            model: The model to use (e.g., 'gemini-embedding-001')
            contents: The input content for embedding
            posthog_distinct_id: ID to associate with the usage event (overrides client default)
            posthog_trace_id: Trace UUID for linking events (auto-generated if not provided)
            posthog_properties: Extra properties to include in the event (merged with client defaults)
            posthog_privacy_mode: Whether to redact sensitive information (overrides client default)
            posthog_groups: Group analytics properties (overrides client default)
            **kwargs: Arguments passed to Gemini's embed_content (e.g., config)
        N   rY   status_coder   r[   )z$ai_providerz	$ai_modelz	$ai_inputz$ai_http_statusz$ai_input_tokensz$ai_latencyz$ai_trace_idz$ai_base_urlTz$ai_is_errorz	$ai_errorFz$process_person_profilez$ai_embedding)rQ   eventrT   rS   r'   )rU   rg   rD   r*   embed_content	Exceptiongetattrr   r   r   rE   r7   capture)r+   rV   rZ   r!   rW   r"   r#   r$   r,   rQ   r]   rT   rR   rS   rq   rp   errorhttp_statusexcrm   rn   r`   event_propertiess                          r-   r   zModels.embed_content  sH   2 &&# "$ 	@Xz< YY[
'	8t||**88 h28H yy{H+G CK4X>PQ 
 !)".thW#.$0& ( $
  #
  37 003E
 -">C !:;OO##'38%+	 $  KQ  	9E!#}a8K	9 yy{H+G CK4X>PQ 
 !)".thW#.$0& ( $
  #
  37 003E
 -">C !:;OO##'38%+	 $ s*   )C= =	DDD" DD" "BF;r0   )NNNNN)N)r1   r2   r3   r4   r5   r6   r   r7   r8   r   r   r.   rU   r\   rv   r   floatrh   r}   rt   r   r'   r/   r-   r)   r)   m   s     "&#'%)!%"&&*&*26-17;%*37TE#TE 4.TE c]	TE
 #TE 3-TE smTE smTE !/TE &c]TE %T#s(^4TE #TE !c3h0TEl L"3- L  } L "$sCx.1	 L
 $D> L d38n- LL .2*.7;/3374
4
 &c]	4

 #3-4
 %T#s(^44
 'tn4
 !c3h04
 4
l@@ c]	@
 3-@ T#s(^,@ @ c3h(@ @^ &*%=%= c]	%=
 3-%= T#s(^,%= %= c3h(%= S#X%=  %= %= %= c]%=N; .2*.7;/3370
0
 &c]	0

 #3-0
 %T#s(^40
 'tn0
 !c3h00
 0
l .2*.7;/337SS &c]	S
 #3-S %T#s(^4S 'tnS !c3h0S Sr/   r)   )"rA   rg   rO   typingr   r   r   posthog.ai.typesr   r   posthog.ai.utilsr	   googler
   ImportErrorModuleNotFoundErrorposthogr   r   r   r   "posthog.ai.gemini.gemini_converterr   r   r   r   r   r   posthog.ai.sanitizationr   posthog.clientr   r5   r)   r'   r/   r-   <module>r      s    	   & & ; 0  
  / 3 2H
 H
Vj jE  
^ s   A1 1A?