
    g	#                        d dl Z d dlZd dlmZmZmZ 	 d dlZd dlZd dl
mZmZmZ d dlmZ  G d dej"                        Z G d d	ej$                  j&                  j(                        Z G d
 dej$                  j&                  j,                  j.                        Z G d dej$                  j2                  j4                        Zy# e$ r	  e	d      w xY w)    N)AnyDictOptionalzGPlease install the OpenAI SDK to use this feature: 'pip install openai')call_llm_and_track_usage_asyncget_model_paramswith_privacy_mode)Clientc                   4     e Zd ZU dZeed<   def fdZ xZS )AsyncOpenAIzf
    An async wrapper around the OpenAI SDK that automatically sends LLM usage events to PostHog.
    
_ph_clientposthog_clientc                 r    t        |   di | || _        t        |       | _        t        |       | _        y)z
        Args:
            api_key: OpenAI API key.
            posthog_client: If provided, events will be captured via this client instance.
            **openai_config: Additional keyword args (e.g. organization="xxx").
        N )super__init__r   WrappedChatchatWrappedEmbeddings
embeddings)selfr   kwargs	__class__s      S/var/www/openai/venv/lib/python3.12/site-packages/posthog/ai/openai/openai_async.pyr   zAsyncOpenAI.__init__   s4     	"6"(%	+D1    )__name__
__module____qualname____doc__PostHogClient__annotations__r   __classcell__r   s   @r   r   r      s!     
2} 
2 
2r   r   c                   (    e Zd ZU eed<   ed        Zy)r   _clientc                 ,    t        | j                        S )N)WrappedCompletionsr$   )r   s    r   completionszWrappedChat.completions&   s    !$,,//r   N)r   r   r   r   r    propertyr'   r   r   r   r   r   #   s    0 0r   r   c                   >    e Zd ZU eed<   	 	 	 	 	 ddee   dee   deeeef      de	deeeef      def fdZ
	 	 ddee   dee   deeeef      de	deeeef      def fd	Z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eef   dedefdZ xZS )r&   r$   posthog_distinct_idposthog_trace_idposthog_propertiesposthog_privacy_modeposthog_groupsr   c                 :  K   |t        j                         }|j                  dd      r | j                  |||||fi | d {   S t	        || j
                  j                  d||| j
                  j                  t        | $  fi | d {   }|S 7 P7 w)NstreamFopenai)
uuiduuid4get_create_streamingr   r$   r   base_urlr   create)	r   r*   r+   r,   r-   r.   r   responser   s	           r   r7   zWrappedCompletions.create.   s      ##zz| ::h&///# "$    8LL##LL!!GN	
 	
 	
 '	
s%   ABBA	BBBBc                     	
K   t        j                          
i g dvri d<   dd   d<   t           di  d {   		 
fd} |       S 7 w)Nstream_optionsTinclude_usagec                   K   	 2 3 d {   } t        | d      r2| j                  r&dD ci c]  }|t        | j                  |d       c}t        | d      rZ| j                  rNt	        | j                        dkD  r6| j                  d   j
                  j                  }|rj                  |       |  7 c c}w 6 	 t        j                         }|z
  }dj                        }j                  
	||	       d {  7   y # t        j                         }|z
  }dj                        }j                  
	||	       d {  7   w xY ww)Nusage)prompt_tokenscompletion_tokenstotal_tokensr   choices )hasattrr=   getattrrA   lendeltacontentappendtimejoin_capture_streaming_event)chunkkrG   end_timelatencyoutputaccumulated_contentr   r*   r.   r-   r,   r+   r8   r   
start_timeusage_statss         r   async_generatorz=WrappedCompletions._create_streaming.<locals>.async_generatorb   sp     #+  %ug.5;;&'& wu{{Aq99&' ui0U]]s5==GY\]G]"'--"2"8"8"@"@"/66w?K ' $,$  99;"Z/!4533'$&("
 
 
  99;"Z/!4533'$&("
 
 
sb   E!D CB:CD B<A/D :C<D AE!	D
E!AEEEE!r   )rI   r   r7   )r   r*   r+   r,   r-   r.   r   rT   rQ   r8   rR   rS   r   s   ``````` @@@@r   r5   z$WrappedCompletions._create_streamingQ   ss      YY[
&( 6)')F#$48 11&11"	 "	H   M 2s   <A'
A%A'rS   rO   rP   c
                 N  K   |t        j                         }d|j                  d      t        |      t	        | j
                  j                  ||j                  d            t	        | j
                  j                  ||	ddg      d|j                  dd      |j                  d	d      ||t        | j
                  j                        d
|}
|d|
d<   t        | j
                  j                  d      r.| j
                  j                  j                  |xs |d|
|       y y w)Nr1   modelmessages	assistant)rG   role   r>   r   r?   )$ai_provider	$ai_modelz$ai_model_parameters	$ai_inputz$ai_output_choices$ai_http_status$ai_input_tokensz$ai_output_tokens$ai_latency$ai_trace_id$ai_base_urlF$process_person_profilecapturez$ai_generationdistinct_idevent
propertiesgroups)r2   r3   r4   r   r   r$   r   strr6   rC   rd   )r   r*   r+   r,   r-   r.   r   rS   rO   rP   event_propertiess              r   rK   z+WrappedCompletions._capture_streaming_event   s"     ##zz| %G,$4V$<*4<<+B+BDXZ`ZdZdeoZpq"3''$#[9:#
  # + C!,1Da!H", 5 56
  !!
& &:?674<<**I6LL##++/C3C&+%	 ,  7s   D#D%NNNFN)FN)r   r   r   r   r    r   rj   r   r   boolr7   r5   intfloatrK   r!   r"   s   @r   r&   r&   +   su    .2*.7;%*37!%c]! #3-! %T#s(^4	!
 #! !c3h0! !P &+375!%c]5! #3-5! %T#s(^4	5!
 #5! !c3h05! 5!n+%c]+ #3-+ %T#s(^4	+
 #+ !c3h0+ S#X+ #s(^+ + +r   r&   c                   |     e Zd ZU eed<   	 	 	 	 	 d	dee   dee   deeeef      de	deeeef      def fdZ
 xZS )
r   r$   r*   r+   r,   r-   r.   r   c           
        K   |t        j                         }t        j                         }t        |   di | d{   }t        j                         }	i }
t        |d      r;|j                  r/t        |j                  dd      t        |j                  dd      d}
|	|z
  }d|j                  d      t        | j                  j                  ||j                  d	            d
|
j                  dd      ||t        | j                  j                        d|}|d|d<   t        | j                  j                  d      r-| j                  j                  j                  |xs |d||       |S 7 4w)a  
        Create an embedding using OpenAI's 'embeddings.create' method, but also track usage in PostHog.

        Args:
            posthog_distinct_id: Optional ID to associate with the usage event.
            posthog_trace_id: Optional trace UUID for linking events.
            posthog_properties: Optional dictionary of extra properties to include in the event.
            posthog_privacy_mode: Whether to store input and output in PostHog.
            posthog_groups: Optional dictionary of groups to include in the event.
            **kwargs: Any additional parameters for the OpenAI Embeddings API.

        Returns:
            The response from OpenAI's embeddings.create call.
        Nr=   r>   r   r@   )r>   r@   r1   rV   inputrZ   )r[   r\   r]   r^   r_   r`   ra   rb   Frc   rd   z$ai_embeddingre   r   )r2   r3   rI   r   r7   rC   r=   rD   r4   r   r$   r   rj   r6   rd   )r   r*   r+   r,   r-   r.   r   rR   r8   rN   rS   rO   rk   r   s                r   r7   zWrappedEmbeddings.create   se    . ##zz|YY[
1&1199; 8W%(..!(!!L ' JK
 Z' %G,*4<<+B+BDXZ`ZdZdelZmn" + C", 5 56

 !

 &:?67 4<<**I6LL##++/C3C%+%	 ,  M 2s   =E7 E4D4E7rl   )r   r   r   r   r    r   rj   r   r   rm   r7   r!   r"   s   @r   r   r      s     .2*.7;%*37A%c]A #3-A %T#s(^4	A
 #A !c3h0A A Ar   r   )rI   r2   typingr   r   r   r1   openai.resourcesImportErrorModuleNotFoundErrorposthog.ai.utilsr   r   r   posthog.clientr	   r   r   	resourcesr   	AsyncChatr   r'   AsyncCompletionsr&   r   AsyncEmbeddingsr   r   r   r   <module>r}      s      & &i a ` 22&$$ 2(0&""''11 0H))..::KK HVD((33CC D]  i
g
hhis   C C