
    ZiP[                     ^   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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 )OpenAIz_
    A 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      S/root/projects/butler/venv/lib/python3.11/site-packages/posthog/ai/openai/openai.pyr   zOpenAI.__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: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                     | t          t          j                              }|                    dd          r | j        |||||fi |S t          || j        j        d||||| j        j        | j	        j
        f	i |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        #"4:<<00::h&& 	)4)# "$     (L# L!N!
 
 
 
 	
r$   c                     	
 t          j                     
i g   j        j        di 		 
fd} |            S )Nc               3   &  K   	 D ]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<   V  	 t          j                    }|z
  }}                    
	||	  	         d S # t          j                    }|z
  }}                    
	||	  	         w xY w)Ntypezresponse.completedr   usagec                 >    i | ]}|t          j        |d           S r   r   rQ   .0kchunks     r#   
<dictcomp>zIWrappedResponses._create_streaming.<locals>.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)hasattrrP   responseoutputlenappendrQ   r^   r_   r`   ra   time_capture_streaming_event)resend_timelatencyre   rX   final_contentr!   r;   r?   r>   r=   r<   rd   r    
start_timeusage_statss       @r#   	generatorz5WrappedResponses._create_streaming.<locals>.generatorv   s     0%    E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  KKKK? D  9;;"Z/&--'$&("
 
 
 
 
  9;;"Z/&--'$&("
 
 
 
s   DE 9Fr   rh   r2   rK   )r    r;   r<   r=   r>   r?   r!   rp   rm   rd   rn   ro   s   ``````` @@@@r#   rI   z"WrappedResponses._create_streamingh   s     Y[[
&((4>(226224	 4	 4	 4	 4	 4	 4	 4	 4	 4	 4	 4	 4	 4	 4	l y{{r$   ro   rl   re   
tool_callsc                    | 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   r[   r   r\   rb   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   rc   r   r    r;   r<   r=   r>   r?   r!   ro   rl   re   rr   event_propertiess               r#   ri   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                 h    t          || j        j        d||||| j        j        | j        j        f	i |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   r   r1   r   rJ   r2   parserL   s          r#   r   zWrappedResponses.parse   sO    . (L# L!N 
 
 
 
 	
r$   NNNFNr/   )r%   r&   r'   r(   r   r   r9   r   rE   r   r   boolrK   rI   intfloatr   ri   r   r   r$   r#   r   r   :   s       DD,v , , , ,- - - .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   z5Wrapper 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        ??'v ' ' ' '- - - 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   zAWrapper 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                     | t          t          j                              }|                    dd          r | j        |||||fi |S t          || j        j        d||||| j        j        | j	        j
        f	i |S rA   rD   rL   s          r#   rK   zWrappedCompletions.create)  rM   r$   c                     	
 t          j                     i g i 	dvri d<   dd         d<     j        j        di 
	
 fd} |            S )Nstream_optionsTinclude_usagec               3   Z  K   	 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<   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_        ^V  	 t          j                    }|z
  }d                    	          }
r!t#          
                                          nd }                    |||
  
         d S # t          j                    }|z
  }d                    	          }
r!t#          
                                          nd }                    |||
  
         w xY w)NrQ   c                 >    i | ]}|t          j        |d           S rS   rT   rU   s     r#   rY   zKWrappedCompletions._create_streaming.<locals>.generator.<locals>.<dictcomp>f  rZ   r$   )prompt_tokenscompletion_tokensr]   prompt_tokens_detailsra   rb   r^   r_   choicesr   rr   function	arguments )rc   rQ   r   ra   r^   r_   r   rf   deltacontentrg   r   indexr   r   rh   joinlistvaluesri   )r   rr   	tool_callr   rk   rl   re   toolsrX   accumulated_contentaccumulated_toolsr!   r;   r?   r>   r=   r<   rd   r    rn   ro   s           @r#   rp   z7WrappedCompletions._create_streaming.<locals>.generator^  sg     
I% 6  6 E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  KKKKm6 r  9;;"Z/!455<MW.5577888SW--'$&("    	  9;;"Z/!455<MW.5577888SW--'$&("   s   F?H8 8A2J*r   rq   )r    r;   r<   r=   r>   r?   r!   rp   r   r   rd   rn   ro   s   ``````` @@@@@r#   rI   z$WrappedCompletions._create_streamingL  s     Y[[
&( 6))')F#$48 1(4>(22622N	 N	 N	 N	 N	 N	 N	 N	 N	 N	 N	 N	 N	 N	 N	 N	` y{{r$   ro   rl   re   rr   c                    | 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   rt   messages	assistant)r   rolerv   r   r   r   rb   r_   rw   r   Fr   r   r   r   r   r   s               r#   ri   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   ri   r   r$   r#   r   r     s
       KK.v . . . .- - - .2*.7;%*37!
 !
%c]!
 #3-!
 %T#s(^4	!

 #!
 !c3h0!
 !
 !
 !
 !
Fb%c]b #3-b %T#s(^4	b
 #b !c3h0b b b b 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 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   z;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           
         | t          t          j                              }t          j                    } | j        j        di |}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.
        NrQ   r   r   r]   )r   r]   rC   rt   ru   rv   )rx   ry   rz   r{   r|   r}   r~   r   Fr   r   z$ai_embeddingr   r   )rE   rF   rG   rh   r2   rK   rc   rQ   r   rH   r	   r1   r   rJ   r   )r    r;   r<   r=   r>   r?   r!   rn   rd   rk   ro   rl   r   s                r#   rK   zWrappedEmbeddings.create  s   . #"4:<<00Y[[
(4>(22622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        EE-v - - - -- - - .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   z>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__@  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__D  r:   r$   c                 @    t          | j        | j        j                  S r/   )WrappedBetaChatr1   r2   r   r   s    r#   r   zWrappedBeta.chatH  s    t|T^-@AAAr$   N)	r%   r&   r'   r(   r   r   r9   r   r   r   r$   r#   r   r   =  sd        HH'v ' ' ' '- - - 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: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__P  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__T  r:   r$   c                 @    t          | j        | j        j                  S r/   )WrappedBetaCompletionsr1   r2   r   r   s    r#   r   zWrappedBetaChat.completionsX  s    %dlDN4NOOOr$   Nr   r   r$   r#   r   r   M  sd        DD,v , , , ,- - - 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   zFWrapper 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__`  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__d  r:   r$   NFr;   r<   r=   r>   r?   r!   c                 h    t          || j        j        d||||| j        j        | j        j        f	i |S )NrC   r   rL   s          r#   r   zWrappedBetaCompletions.parseh  sO     (L# L!N 
 
 
 
 	
r$   r   )r%   r&   r'   r(   r   r   r9   r   rE   r   r   r   r   r   r$   r#   r   r   ]  s        PP3v 3 3 3 3- - - .2*.7;%*37
 
%c]
 #3-
 %T#s(^4	

 #
 !c3h0
 
 
 
 
 
 
r$   r   )rh   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      sN     , , , , , , , , , , , ,MMMM   

Q  
         
 3 2 2 2 2 2#N #N #N #N #NV] #N #N #NLQ
 Q
 Q
 Q
 Q
 Q
 Q
 Q
hL L L L L L L L K K K K K K K K\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    ,