
    jKj
M                        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 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)AsyncStreamWrapper)
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_async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)AsyncClientaM  
    An async drop-in replacement for genai.Client that automatically sends LLM usage events to PostHog.

    Usage:
        client = AsyncClient(
            api_key="your_api_key",
            posthog_client=posthog_client,
            posthog_distinct_id="default_user",  # Optional defaults
            posthog_properties={"team": "ai"}    # Optional defaults
        )
        response = await 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AsyncModelsmodels)selfr   r   r   r   r   r    r!   r"   r#   r$   r%   r&   kwargss                 o/Users/ahmed/devFolder/Ultron/claude-voice/.venv/lib/python3.12/site-packages/posthog/ai/gemini/gemini_async.py__init__zAsyncClient.__init__7   sl    B )3EG??"NOO! 
#%%?? 31!5)
 
    NNNNNNNNNNFN)__name__
__module____qualname____doc__PostHogClient__annotations__r   strboolr   r   r0   r)   r1   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
r1   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+   z]
    Async Models interface that mimics genai.Client().aio.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/   r0   zAsyncModels.__init__u   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r1   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?   rA   rB   dictr@   updater9   uuiduuid4)
r-   rI   rJ   rK   rL   rM   distinct_idprivacy_modegroups
propertiess
             r/   _merge_posthog_paramsz!AsyncModels._merge_posthog_params   s      + ** 	 !, ++ 	
 !, 7T=Q=Q $223
o. 

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

        This method signature exactly matches genai.Client().aio.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
        rX   contentsgeminiN)rW   r   r   rG   rF   aior,   generate_content)r-   rX   r\   r#   rY   r$   r%   r&   r.   rS   trace_idrV   rT   rU   kwargs_with_contentss                  r/   r_   zAsyncModels.generate_content   s     < &&# "$ 	@Xz< */HOO3OONNLL##44
 #
 
 	
 
s   A6A?8A=9A?rS   r`   rV   rT   rU   c                 :   K   t        j                          t        dd      g d d}	  j                  j                  j                  j
                  di |	 d {    fd}
t         |
             S 7 (w)Nr   )input_tokensoutput_tokensr[   c                   K   	 2 3 d {   } t        |       }|rt        |d       t        |       }|j                  |       t	        |       }|||  W7 R6 	 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_contentr\   rS   rU   r.   rX   rT   rV   responser-   
start_timerh   r`   usage_statss         r/   async_generatorz@AsyncModels._generate_content_streaming.<locals>.async_generator8  s    
'#+  %"A%"HK")+{V %Fe$LM$0+22=A )Ne(T%(4&7K' 8,  99;"Z/-- ' + .   99;"Z/-- ' + . s=   CB A AA AB A  B "7C8CC)streamr)   )rj   r   rF   r^   r,   generate_content_streamr   )r-   rX   r\   rS   r`   rV   rT   rU   r.   kwargs_without_streamrv   rr   rs   rt   rh   ru   s   `````````  @@@@@r/   _generate_content_streamingz'AsyncModels._generate_content_streaming#  s      YY[
",!1"M %)*/X P PH))00HH 
#
 
,	 ,	 ,	\ "/"3HEEe
s   A B0B1)Bru   rq   outputrh   c                      | j                   |fi |}t        |      }t        d|| j                  ||t	        |      |	|
||||||      }t        | j                  |       y )Nr]   )providerrX   base_urlr.   formatted_inputformatted_outputru   rq   rS   r`   rV   rT   rU   rh   )_format_inputr   r   rG   r   r   r   )r-   rX   r\   rS   r`   rV   rT   rU   r.   ru   rq   r{   rh   r   sanitized_input
event_datas                   r/   rk   z$AsyncModels._capture_streaming_eventh  sr      -$,,X@@)/:'^^+;FC##!%#

$ 	 <r1   c                 &    d|i|}t        |d      S )z*Format input contents for PostHog trackingr\   r]   r	   )r-   r\   r.   input_kwargss       r/   r   zAsyncModels._format_input  s      #H77"<::r1   c           	         K   | j                  |||||      \  }	}
}}} | j                  |||	|
|||fi | d{   S 7 w)aI  
        Stream content from Gemini asynchronously 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 async ``generate_content_stream`` API.

        Returns:
            An async streaming iterator yielding Gemini chunks.
        N)rW   rz   )r-   rX   r\   r#   rY   r$   r%   r&   r.   rS   r`   rV   rT   rU   s                 r/   rx   z#AsyncModels.generate_content_stream  su     < &&# "$ 	@Xz< 6T55	
 	
 	
 		
 	
s   8A?Ac                   K   | j                  |||||      \  }	}
}}}t        j                         }d}d}d}	  | j                  j                  j                  j
                  d||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 7 # 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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   r[   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)rS   eventrV   rU   r)   )rW   rj   rF   r^   r,   embed_content	Exceptiongetattrr   r   r   rG   r9   capture)r-   rX   r\   r#   rY   r$   r%   r&   r.   rS   r`   rV   rT   rU   rt   rs   errorhttp_statusexcrp   rq   rc   event_propertiess                          r/   r   zAsyncModels.embed_content  s[    2 &&# "$ 	@Xz< YY[
'	BT\\--44BB h28 H yy{H+G CK4X>PQ 
 !)".thW#.$0& ( $
  #
  37 003E
 -">C !:;OO##'38%+	 $  KW  	9E!#}a8K	9 yy{H+G CK4X>PQ 
 !)".thW#.$0& ( $
  #
  37 003E
 -">C !:;OO##'38%+	 $ sN   6G6D /D0D 4BGD 	D5D0+D8 0D55D8 8BGGr2   )NNNNN)N)r3   r4   r5   r6   r7   r8   r   r9   r:   r   r   r0   rW   r_   rz   r   floatrk   r   rx   r   r)   r1   r/   r+   r+   n   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FCF c]	CF
 3-CF T#s(^,CF CF c3h(CF CFd &*%=%= 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r1   r+   )%rC   rj   rQ   typingr   r   r   posthog.ai.streamr   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   r7   r   r+   r)   r1   r/   <module>r      s    	   & & 0 ; 0  
  / 3 2H
 H
Vm mE  
^ s   A7 7B