
    Zi\                     ^   d dl Z d dlZd dlmZmZmZmZ 	 d dlZn# e$ r  e	d          w xY wd dl
mZmZmZ d dlmZ  G d dej                  Z G d d	          Z G d
 d          Z G d d          Z G d d          Z G d d          Z G d d          Z G d d          ZdS )    N)AnyDictList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                     t                      j        di | || _        t          | dd          | _        t          | dd          | _        t          | dd          | _        t          | dd          | _        | j        t          | | j                  | _	        | j        t          | | j                  | _        | j        t          | | j                  | _        | j        t          | | j                  | _        dS dS )a-  
        Args:
            api_key: OpenAI API key.
            posthog_client: If provided, events will be captured via this client instead
                            of the global posthog.
            **openai_config: Any additional keyword args to set on openai (e.g. organization="xxx").
        chatN
embeddingsbeta	responses )super__init__r   getattr_original_chat_original_embeddings_original_beta_original_responsesWrappedChatr   WrappedEmbeddingsr   WrappedBetar   WrappedResponsesr   )selfr   kwargs	__class__s      Y/root/projects/butler/venv/lib/python3.11/site-packages/posthog/ai/openai/openai_async.pyr   zAsyncOpenAI.__init__   s     	""6"""( &dFD99$+D,$E$E!%dFD99#*4d#C#C  *#D$*=>>DI$0/d6OPPDO*#D$*=>>DI#/-dD4LMMDNNN 0/    )__name__
__module____qualname____doc__PostHogClient__annotations__r   __classcell__)r"   s   @r#   r   r      si           N} N N N N N N N N N Nr$   r   c                   X   e Zd ZdZdefdZ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dZ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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
deee	e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dZdS )r   z@Async wrapper for OpenAI responses that tracks usage in PostHog.clientc                 "    || _         || _        d S N_client	_original)r    r-   original_responsess      r#   r   zWrappedResponses.__init__=       +r$   c                 ,    t          | j        |          S )zQFallback to original responses object for any methods we don't explicitly handle.r   r2   r    names     r#   __getattr__zWrappedResponses.__getattr__A       t~t,,,r$   NFposthog_distinct_idposthog_trace_idposthog_propertiesposthog_privacy_modeposthog_groupsr!   c                   K   | t          t          j                              }|                    dd          r | j        |||||fi | d {V S t          || j        j        d||||| j        j        | j	        j
        f	i | d {V S NstreamFopenaistruuiduuid4get_create_streamingr   r1   r   base_urlr2   creater    r;   r<   r=   r>   r?   r!   s          r#   rK   zWrappedResponses.createE   s       #"4:<<00::h&& 	//# "$           4L# L!N!
 
 
 
 
 
 
 
 
 
 	
r$   c                     	
K   t          j                     
i g   j        j        di  d {V 		 
fd} |            S )Nc                 J  K   	 2 3 d {V t          d          rQj        dk    rFj        } | j        r8t	          | j                  dk    r                     | j        d                    t          d          rj        rfddD             t          j        d          r.t          j        j        d          rj        j        j        d<   t          j        d	          r.t          j        j	        d
          rj        j	        j
        d<   W V  6 	 t          j                    }|z
  }}                    
	||	  	         d {V  d S # t          j                    }|z
  }}                    
	||	  	         d {V  w xY w)Ntypezresponse.completedr   usagec                 >    i | ]}|t          j        |d           S r   r   rP   .0kchunks     r#   
<dictcomp>zOWrappedResponses._create_streaming.<locals>.async_generator.<locals>.<dictcomp>   9     ' ' ' ! wu{Aq99' ' 'r$   )input_tokensoutput_tokenstotal_tokensoutput_tokens_detailsreasoning_tokensinput_tokens_detailscached_tokenscache_read_input_tokens)hasattrrO   responseoutputlenappendrP   r]   r^   r_   r`   time_capture_streaming_event)resend_timelatencyrd   rW   final_contentr!   r;   r?   r>   r=   r<   rc   r    
start_timeusage_statss       @r#   async_generatorz;WrappedResponses._create_streaming.<locals>.async_generatorv   su     0#+              %uf-- @%*@T2T2T#n: @#cj//A*=*=)00A???ug.. 5; ' ' ' '&' ' ' #5;0GHH W!K=?QN N  !& A R ((:; #5;0FGG G!K<oM M  !& @ N ((AB  KKKKK? $,8D  9;;"Z/&33'$&("
 
 
 
 
 
 
 
 
 
 
  9;;"Z/&33'$&("
 
 
 
 
 
 
 
 
 
s   E# D"DE# #?F"r   rg   r2   rK   )r    r;   r<   r=   r>   r?   r!   ro   rl   rc   rm   rn   s   ``````` @@@@r#   rI   z"WrappedResponses._create_streamingh   s       Y[[
&(..88888888884	 4	 4	 4	 4	 4	 4	 4	 4	 4	 4	 4	 4	 4	 4	l    r$   rn   rk   rd   
tool_callsc                   K   | t          t          j                              }d|                    d          t	          |          t          | j        j        ||                    d                    t          | j        j        ||	          d|                    dd          |                    dd          |                    dd          |                    d	d          ||t          | j        j                  d
|pi }|
rt          | j        j        ||
          |d<   |d|d<   t          | j        j        d          r'| j        j        
                    |p|d||           d S d S )NrC   modelinput   rZ   r   r[   ra   r^   $ai_provider	$ai_modelz$ai_model_parameters	$ai_inputz$ai_output_choices$ai_http_status$ai_input_tokensz$ai_output_tokensz$ai_cache_read_input_tokensz$ai_reasoning_tokens$ai_latency$ai_trace_id$ai_base_url	$ai_toolsF$process_person_profilecapture$ai_generationdistinct_idevent
propertiesgroupsrE   rF   rG   rH   r   r	   r1   r   rJ   rb   r   r    r;   r<   r=   r>   r?   r!   rn   rk   rd   rq   event_propertiess               r#   rh   z)WrappedResponses._capture_streaming_event   s      #"4:<<00 %G,,$4V$<$<*')=vzz'?R?R  #4'$# #
  # + B B!,!!D!D+6??)1, , %0OO4F$J$J", 566+
 
, "'R-
2  	,='$- -[) &:?674<*I66 	L#++/C3C&+%	 ,     	 	r$   c                 x   K   t          || j        j        d||||| j        j        | j        j        f	i | d{V S )a  
        Parse structured output using OpenAI's 'responses.parse' 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 anonymize the input and output.
            posthog_groups: Optional dictionary of groups to associate with the event.
            **kwargs: Any additional parameters for the OpenAI Responses Parse API.

        Returns:
            The response from OpenAI's responses.parse call.
        rC   Nr   r1   r   rJ   r2   parserL   s          r#   r   zWrappedResponses.parse   sq      . 4L# L!N 
 
 
 
 
 
 
 
 
 
 	
r$   NNNFNr/   )r%   r&   r'   r(   r   r   r9   r   rE   r   r   boolrK   rI   intfloatr   rh   r   r   r$   r#   r   r   :   s       JJ,{ , , , ,- - - .2*.7;%*37!
 !
%c]!
 #3-!
 %T#s(^4	!

 #!
 !c3h0!
 !
 !
 !
 !
FD!%c]D! #3-D! %T#s(^4	D!
 #D! !c3h0D! D! D! D! D!b 6:9 9%c]9 #3-9 %T#s(^4	9
 #9 !c3h09 S#X9 #s(^9 9 9 T$sCx.129 9 9 9z .2*.7;%*37"
 "
%c]"
 #3-"
 %T#s(^4	"

 #"
 !c3h0"
 "
 "
 "
 "
 "
 "
r$   r   c                   :    e Zd ZdZdefdZd Zed             ZdS )r   z;Async wrapper for OpenAI chat that tracks usage in PostHog.r-   c                 "    || _         || _        d S r/   r0   )r    r-   original_chats      r#   r   zWrappedChat.__init__      &r$   c                 ,    t          | j        |          S )zLFallback to original chat object for any methods we don't explicitly handle.r6   r7   s     r#   r9   zWrappedChat.__getattr__  r:   r$   c                 @    t          | j        | j        j                  S r/   )WrappedCompletionsr1   r2   completionsr    s    r#   r   zWrappedChat.completions  s    !$,0JKKKr$   N	r%   r&   r'   r(   r   r   r9   propertyr   r   r$   r#   r   r     sd        EE'{ ' ' ' '- - - L L XL L Lr$   r   c                      e Zd ZdZdefdZ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dZ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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
deee	ee
f                           fdZdS )r   zGAsync wrapper for OpenAI chat completions that tracks usage in PostHog.r-   c                 "    || _         || _        d S r/   r0   )r    r-   original_completionss      r#   r   zWrappedCompletions.__init__!  s    -r$   c                 ,    t          | j        |          S )zSFallback to original completions object for any methods we don't explicitly handle.r6   r7   s     r#   r9   zWrappedCompletions.__getattr__%  r:   r$   NFr;   r<   r=   r>   r?   r!   c                   K   | t          t          j                              }|                    dd          r | j        |||||fi | d {V S t          || j        j        d||||| j        j        | j	        j
        f	i | d {V }|S rA   rD   )r    r;   r<   r=   r>   r?   r!   rc   s           r#   rK   zWrappedCompletions.create)  s       #"4:<<00 ::h&& 	//# "$           8L# L!N!
 
 
 
 
 
 
 
 
 
 r$   c                     	
K   t          j                     i g i 	dvri d<   dd         d<     j        j        di  d {V 
	
 fd} |            S )Nstream_optionsTinclude_usagec                 ~  K   	 2 3 d {V t          d          rj        rfddD             t          j        d          r.t          j        j        d          rj        j        j        d<   t          j        d          r.t          j        j        d          rj        j        j        d<   t          d	          rj        rt          j                  d
k    rډj        d
         j        rEj        d
         j        j	        r.j        d
         j        j	        } | r	
                    |            t          j        d
         j        dd           }|r`|D ]]}|j        }|
vr|
|<   t          |d          r:t          |j        d          r%
|         j        xj        |j        j        z  c_        ^W V  6 	 t          j                    }|z
  }d                    	          }
r!t#          
                                          nd }                    |||
  
         d {V  d S # t          j                    }|z
  }d                    	          }
r!t#          
                                          nd }                    |||
  
         d {V  w xY w)NrP   c                 >    i | ]}|t          j        |d           S rR   rS   rT   s     r#   rX   zQWrappedCompletions._create_streaming.<locals>.async_generator.<locals>.<dictcomp>i  rY   r$   )prompt_tokenscompletion_tokensr\   prompt_tokens_detailsr`   ra   r]   r^   choicesr   rq   function	arguments )rb   rP   r   r`   r]   r^   r   re   deltacontentrf   r   indexr   r   rg   joinlistvaluesrh   )r   rq   	tool_callr   rj   rk   rd   toolsrW   accumulated_contentaccumulated_toolsr!   r;   r?   r>   r=   r<   rc   r    rm   rn   s           @r#   ro   z=WrappedCompletions._create_streaming.<locals>.async_generatora  s     
I#+ 6  6  6  6  6  6  6 %ug.. 5; ' ' ' '&' ' ' #5;0GHH W!K=N N  !& A O ((AB #5;0GHH W!K=?QN N  !& A R ((:;
  y11*!M*  ..22 =+1 DemA6F6L6T D&+mA&6&<&DG& D 3 : :7 C C C &-U]1-=-C\SW%X%X
% *-7 * *	(1#(0A#A#A?H$5e$<$< (/y*'E'E %*'(1(:KK& K& %* ):,1)**2)=3<,5,>,H)*3<9  KKKKKm $,8r  9;;"Z/!455<MW.5577888SW33'$&("          	  9;;"Z/!455<MW.5577888SW33'$&("         s   I G
F=I A8J<r   rp   )r    r;   r<   r=   r>   r?   r!   ro   r   r   rc   rm   rn   s   ``````` @@@@@r#   rI   z$WrappedCompletions._create_streamingN  s       Y[[
&( 6))')F#$48 1..8888888888N	 N	 N	 N	 N	 N	 N	 N	 N	 N	 N	 N	 N	 N	 N	 N	`    r$   rn   rk   rd   rq   c                   K   | t          t          j                              }d|                    d          t	          |          t          | j        j        ||                    d                    t          | j        j        ||	ddg          d|                    dd          |                    d	d          |                    d
d          |                    dd          ||t          | j        j                  d|pi }|
rt          | j        j        ||
          |d<   |d|d<   t          | j        j        d          r'| j        j        
                    |p|d||           d S d S )NrC   rs   messages	assistant)r   roleru   r   r   r   ra   r^   rv   r   Fr   r   r   r   r   r   s               r#   rh   z+WrappedCompletions._capture_streaming_event  s      #"4:<<00 %G,,$4V$<$<*')=vzz*?U?U  #4'$#[99:# #
  # + C C!,1Da!H!H+6??)1, , %0OO4F$J$J", 566+
 
, "'R-
2  	,='$- -[) &:?674<*I66 	L#++/C3C&+%	 ,     	 	r$   r   r/   )r%   r&   r'   r(   r   r   r9   r   rE   r   r   r   rK   rI   r   r   r   rh   r   r$   r#   r   r     s
       QQ.{ . . . .- - - .2*.7;%*37# #%c]# #3-# %T#s(^4	#
 ## !c3h0# # # # #Jc!%c]c! #3-c! %T#s(^4	c!
 #c! !c3h0c! c! c! c! c!` 6:9 9%c]9 #3-9 %T#s(^4	9
 #9 !c3h09 S#X9 #s(^9 9 9 T$sCx.129 9 9 9 9 9r$   r   c                       e Zd ZdZdefdZ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dZdS )r   zAAsync wrapper for OpenAI embeddings that tracks usage in PostHog.r-   c                 "    || _         || _        d S r/   r0   )r    r-   original_embeddingss      r#   r   zWrappedEmbeddings.__init__  s    ,r$   c                 ,    t          | j        |          S )zRFallback to original embeddings object for any methods we don't explicitly handle.r6   r7   s     r#   r9   zWrappedEmbeddings.__getattr__  r:   r$   NFr;   r<   r=   r>   r?   r!   c           
        K   | t          t          j                              }t          j                    } | j        j        di | d{V }t          j                    }	i }
t          |d          r4|j        r-t          |j        dd          t          |j        dd          d}
|	|z
  }d|	                    d          t          | j        j        ||	                    d	                    d
|
	                    dd          ||t          | j        j                  d|pi }|d|d<   t          | j        j        d          r%| j        j                            |p|d||           |S )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 anonymize the input and output.
            posthog_groups: Optional dictionary of groups to associate with the event.
            **kwargs: Any additional parameters for the OpenAI Embeddings API.

        Returns:
            The response from OpenAI's embeddings.create call.
        NrP   r   r   r\   )r   r\   rC   rs   rt   ru   )rw   rx   ry   rz   r{   r|   r}   r~   Fr   r   z$ai_embeddingr   r   )rE   rF   rG   rg   r2   rK   rb   rP   r   rH   r	   r1   r   rJ   r   )r    r;   r<   r=   r>   r?   r!   rm   rc   rj   rn   rk   r   s                r#   rK   zWrappedEmbeddings.create  s     . #"4:<<00Y[[
..88888888889;; 8W%% 	(. 	!(!!L!L ' J J K
 Z' %G,,*')=vzz'?R?R   # + C C", 566
 
 "'R
 &:?67 4<*I66 	L#++/C3C%+%	 ,    r$   r   )r%   r&   r'   r(   r   r   r9   r   rE   r   r   r   rK   r   r$   r#   r   r     s        KK-{ - - - -- - - .2*.7;%*37C C%c]C #3-C %T#s(^4	C
 #C !c3h0C C C C C C Cr$   r   c                   :    e Zd ZdZdefdZd Zed             ZdS )r   zDAsync wrapper for OpenAI beta features that tracks usage in PostHog.r-   c                 "    || _         || _        d S r/   r0   )r    r-   original_betas      r#   r   zWrappedBeta.__init__C  r   r$   c                 ,    t          | j        |          S )zLFallback to original beta object for any methods we don't explicitly handle.r6   r7   s     r#   r9   zWrappedBeta.__getattr__G  r:   r$   c                 @    t          | j        | j        j                  S r/   )WrappedBetaChatr1   r2   r   r   s    r#   r   zWrappedBeta.chatK  s    t|T^-@AAAr$   N)	r%   r&   r'   r(   r   r   r9   r   r   r   r$   r#   r   r   @  sd        NN'{ ' ' ' '- - - B B XB B Br$   r   c                   :    e Zd ZdZdefdZd Zed             ZdS )r   z@Async wrapper for OpenAI beta chat that tracks usage in PostHog.r-   c                 "    || _         || _        d S r/   r0   )r    r-   original_beta_chats      r#   r   zWrappedBetaChat.__init__S  r4   r$   c                 ,    t          | j        |          S )zQFallback to original beta chat object for any methods we don't explicitly handle.r6   r7   s     r#   r9   zWrappedBetaChat.__getattr__W  r:   r$   c                 @    t          | j        | j        j                  S r/   )WrappedBetaCompletionsr1   r2   r   r   s    r#   r   zWrappedBetaChat.completions[  s    %dlDN4NOOOr$   Nr   r   r$   r#   r   r   P  sd        JJ,{ , , , ,- - - P P XP P Pr$   r   c                       e Zd ZdZdefdZ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dZdS )r   zLAsync wrapper for OpenAI beta chat completions that tracks usage in PostHog.r-   c                 "    || _         || _        d S r/   r0   )r    r-   original_beta_completionss      r#   r   zWrappedBetaCompletions.__init__c  s    2r$   c                 ,    t          | j        |          S )zXFallback to original beta completions object for any methods we don't explicitly handle.r6   r7   s     r#   r9   z"WrappedBetaCompletions.__getattr__g  r:   r$   NFr;   r<   r=   r>   r?   r!   c                 x   K   t          || j        j        d||||| j        j        | j        j        f	i | d {V S )NrC   r   rL   s          r#   r   zWrappedBetaCompletions.parsek  sq       4L# L!N 
 
 
 
 
 
 
 
 
 
 	
r$   r   )r%   r&   r'   r(   r   r   r9   r   rE   r   r   r   r   r   r$   r#   r   r   `  s        VV3{ 3 3 3 3- - - .2*.7;%*37
 
%c]
 #3-
 %T#s(^4	

 #
 !c3h0
 
 
 
 
 
 
r$   r   )rg   rF   typingr   r   r   r   rC   ImportErrorModuleNotFoundErrorposthog.ai.utilsr   r   r	   posthog.clientr
   r)   r   r   r   r   r   r   r   r   r   r$   r#   <module>r      sO     , , , , , , , , , , , ,MMMM   

Q  
         
 3 2 2 2 2 2#N #N #N #N #N&$ #N #N #NLQ
 Q
 Q
 Q
 Q
 Q
 Q
 Q
hL L L L L L L L N N N N N N N NbN N N N N N N NbB B B B B B B B P P P P P P P P 
 
 
 
 
 
 
 
 
 
s    ,