
    jKj
`                        d dl Z d dlZd dlmZmZmZmZ d dlmZ 	 d dl	Z	d dlmZmZmZmZ d dlmZ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  G d de	j@                        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# G d de      Z$ G d de      Z% G d de      Z& G d de      Z' G d de      Z( G d de      Z) G d  d!e      Z*y# e
$ r	  ed      w xY w)"    N)AnyDictListOptional)
TokenUsagezGPlease install the OpenAI SDK to use this feature: 'pip install openai')call_llm_and_track_usageextract_available_tool_callsmerge_usage_statswith_privacy_mode)extract_openai_usage_from_chunk!extract_openai_content_from_chunk$extract_openai_tool_calls_from_chunkaccumulate_openai_tool_calls)sanitize_openaisanitize_openai_response)Client)setup)_OpenAIWrapperResourcec                   <     e Zd ZU dZeed<   dde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        |   di | |xs
 t               | _        t	        | dd      | _        t	        | dd      | _        t	        | dd      | _        t	        | dd      | _        | j
                  t        | | j
                        | _
        | j                  t        | | j                        | _        | j                  t        | | j                        | _        | j                  t        | | j                        | _        yy)a  
        Args:
            posthog_client: If provided, events will be captured via this client
                instead of the global ``posthog`` client.
            **kwargs: Arguments passed to ``openai.OpenAI`` such as ``api_key``
                or ``organization``.
        chatN
embeddingsbeta	responses )super__init__r   r   getattr_original_chat_original_embeddings_original_beta_original_responsesWrappedChatr   WrappedEmbeddingsr   WrappedBetar   WrappedResponsesr   )selfr   kwargs	__class__s      i/Users/ahmed/devFolder/Ultron/claude-voice/.venv/lib/python3.12/site-packages/posthog/ai/openai/openai.pyr    zOpenAI.__init__'   s     	"6"(3EG &dFD9$+D,$E!%dFD9#*4d#C  *#D$*=*=>DI$$0/d6O6OPDO*#D$*=*=>DI##/-dD4L4LMDN 0    )N)	__name__
__module____qualname____doc__PostHogClient__annotations__r   r    __classcell__)r,   s   @r-   r   r       s)     Nx'> N Nr.   r   posthog_distinct_idposthog_trace_idposthog_propertiesposthog_privacy_modeposthog_groupsr+   c                     t        || j                  j                  d||||| j                  j                  | j                  j
                  f	i |S )Nopenai)r   _clientr   base_url	_originalparse)wrapperr6   r7   r8   r9   r:   r+   s          r-   _parse_and_trackrB   G   sV     $""    r.   c                      e Z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dededeeeeef         dee   de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fdZy)r)   z:Wrapper for OpenAI responses that tracks usage in PostHog.Nr6   r7   r8   r9   r:   r+   c                 2   |t        t        j                               }|j                  dd      r | j                  |||||fi |S t        || j                  j                  d||||| j                  j                  | j                  j                  f	i |S )a  
        Create an OpenAI Responses API response while tracking usage in PostHog.

        Args:
            posthog_distinct_id: Optional distinct ID to associate with the usage event.
            posthog_trace_id: Optional trace ID. Generated automatically when omitted.
            posthog_properties: Additional properties to include with the usage event.
            posthog_privacy_mode: Whether to redact captured input and output.
            posthog_groups: Optional PostHog groups to associate with the event.
            **kwargs: Arguments passed to OpenAI's ``responses.create`` API.

        Returns:
            The OpenAI response, or a streaming iterator when ``stream=True``.
        streamFr<   struuiduuid4get_create_streamingr   r=   r   r>   r?   creater*   r6   r7   r8   r9   r:   r+   s          r-   rL   zWrappedResponses.createa       . #"4::<0::h&)4))# "$   (LL## LL!!NN!!
 
 	
r.   c                     	
 t        j                          t               g d 	d   j                  j                  di 
	
 fd} |       S )Nc               3     K   	 D ]  } t        | d      r:| j                  r.	,t        | j                  d      r| j                  j                  	t        | d      }|rt	        |       t        | d      }|j                  |       t        | d      rB| j                  dk(  r3t        | d      r'| j                  rt        | j                  dd       }|||   	 t        j                         }|z
  }}j                  
||d 	       y # t        j                         }|z
  }}j                  
||d 	       w xY ww)Nresponsemodelr   typezresponse.completedstatusstop_reason)hasattrrQ   rR   r   r
   r   appendrS   r!   time_capture_streaming_event)chunkchunk_usagecontentchunk_statusend_timelatencyoutputfinal_contentr+   model_from_responser6   r:   r9   r8   r7   rQ   r*   
start_timerV   usage_statss          r-   	generatorz5WrappedResponses._create_streaming.<locals>.generator   s    3%Euj1enn.67!NNG< 38..2F2F/ #B%"UK")+{C @{SG*%,,W5  v.!JJ*>>#E:6!NN'.u~~x'N'3*6KK? &D  99;"Z/&--'$&("' + .   99;"Z/&--'$&("' + . s   ECD 9E:EEr   rY   r   r?   rL   )r*   r6   r7   r8   r9   r:   r+   rf   rb   rc   rQ   rd   rV   re   s   ``````` @@@@@@r-   rK   z"WrappedResponses._create_streaming   s[     YY[
",,-1%)(4>>((2629	 9	 9	v {r.   re   r`   ra   available_tool_callsrc   rV   c                 4   ddl m} ddlm}m} ddlm}  ||d      }t        |      }|j                  d      xs |xs d} |d|t        | j                  j                        || ||	d      ||||||||	      } || j                  j                  |       y )
Nr   StreamingEventDataformat_openai_streaming_inputformat_openai_streaming_outputcapture_streaming_eventr   rR   unknownr<   providerrR   r>   r+   formatted_inputformatted_outputre   r`   distinct_idtrace_id
propertiesprivacy_modegroupsrV   )posthog.ai.typesrk   "posthog.ai.openai.openai_converterrm   rn   posthog.ai.utilsrp   r   rJ   rG   r=   r>   r   )r*   r6   r7   r8   r9   r:   r+   re   r`   ra   rh   rc   rV   rk   rm   rn   rp   rt   sanitized_inputrR   
event_datas                        r-   rZ   z)WrappedResponses._capture_streaming_event   s     	8	
 	= 8L2?C 

7#G':Gi'../+;FKP#+%)-!#

$ 	  7 7Dr.   c                 $    t        | |||||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.
        rB   rM   s          r-   r@   zWrappedResponses.parse  -    .   
 
 	
r.   NNNFN)NNN)r/   r0   r1   r2   r   rG   r   r   boolrL   rK   r   floatr   rZ   r@   r   r.   r-   r)   r)   ^   s-   D .2*.7;%*37/
%c]/
 #3-/
 %T#s(^4	/

 #/
 !c3h0/
 /
bK%c]K #3-K %T#s(^4	K
 #K !c3h0K Kp @D-1%)/E%c]/E #3-/E %T#s(^4	/E
 #/E !c3h0/E S#X/E  /E /E /E 'tDcN';</E &c]/E c]/Ef .2*.7;%*37
%c]
 #3-
 %T#s(^4	

 #
 !c3h0
 
r.   r)   c                        e Zd ZdZed        Zy)r&   z5Wrapper for OpenAI chat that tracks usage in PostHog.c                 V    t        | j                  | j                  j                        S )z4Access chat completions with PostHog usage tracking.)WrappedCompletionsr=   r?   completionsr*   s    r-   r   zWrappedChat.completions5  s     "$,,0J0JKKr.   Nr/   r0   r1   r2   propertyr   r   r.   r-   r&   r&   2  s    ?L Lr.   r&   c                      e Z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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dededeeeeef         deeeeef         dee   dee   fdZy)r   zAWrapper for OpenAI chat completions that tracks usage in PostHog.Nr6   r7   r8   r9   r:   r+   c                 $    t        | |||||fi |S )a  
        Parse an OpenAI chat completion while tracking usage in PostHog.

        Args:
            posthog_distinct_id: Optional distinct ID to associate with the usage event.
            posthog_trace_id: Optional trace ID. Generated automatically when omitted.
            posthog_properties: Additional properties to include with the usage event.
            posthog_privacy_mode: Whether to redact captured input and output.
            posthog_groups: Optional PostHog groups to associate with the event.
            **kwargs: Arguments passed to OpenAI's ``chat.completions.parse`` API.

        Returns:
            The parsed response from OpenAI.
        r   rM   s          r-   r@   zWrappedCompletions.parse>  r   r.   c                 2   |t        t        j                               }|j                  dd      r | j                  |||||fi |S t        || j                  j                  d||||| j                  j                  | j                  j                  f	i |S )a  
        Create an OpenAI chat completion while tracking usage in PostHog.

        Args:
            posthog_distinct_id: Optional distinct ID to associate with the usage event.
            posthog_trace_id: Optional trace ID. Generated automatically when omitted.
            posthog_properties: Additional properties to include with the usage event.
            posthog_privacy_mode: Whether to redact captured input and output.
            posthog_groups: Optional PostHog groups to associate with the event.
            **kwargs: Arguments passed to OpenAI's ``chat.completions.create`` API.

        Returns:
            The OpenAI chat completion, or a streaming iterator when ``stream=True``.
        rE   Fr<   rF   rM   s          r-   rL   zWrappedCompletions.create_  rN   r.   c                     	
 t        j                          t               g i 	d 
d dvri d<   dd   d<     j                  j                  di 	
 fd} |       S )Nstream_optionsTinclude_usagec               3     K   	 D ]  } 
t        | d      r| j                  
t        | d      }|rt        |       t	        | d      }|j                  |       t        |       }|rt        |       t        | d      r?| j                  r3t        | j                  d   dd       | j                  d   j                  |   	 t        j                         }|z
  }rt        j                               nd }j                  	||t        d	      
       y # t        j                         }|z
  }rt        j                               nd }j                  	||t        d	      
       w xY ww)NrR   r   choicesr   finish_reasonr<   rU   )rW   rR   r   r
   r   rX   r   r   r   r!   r   rY   listvaluesrZ   r	   )r[   r\   r]   chunk_tool_callsr_   r`   tool_calls_listaccumulated_contentaccumulated_tool_callsr+   rc   r6   r:   r9   r8   r7   rQ   r*   rd   rV   re   s          r-   rf   z7WrappedCompletions._create_streaming.<locals>.generator  s    <%E*2wug7N.3kk+ #B%"PK")+{C @vNG*+227; (LE'R$'424D  y1!MM#EMM!$4otLX&+mmA&6&D&DKA &F  99;"Z/
 . /6689   --'$&("'#06B' + .   99;"Z/
 . /6689   --'$&("'#06B' + . s   F
CD' AF
'A FF
r   rg   )r*   r6   r7   r8   r9   r:   r+   rf   r   r   rc   rQ   rd   rV   re   s   ``````` @@@@@@@r-   rK   z$WrappedCompletions._create_streaming  s     YY[
",, <>-1%)6)')F#$48 1(4>>((262C	 C	 C	J {r.   re   r`   ra   
tool_callsrh   rc   rV   c                 6   ddl m} ddlm}m} ddlm}  ||d      }t        |      }|j                  d      xs |xs d} |d|t        | j                  j                        || ||	d|
      ||||||||	      } || j                  j                  |       y )
Nr   rj   rl   ro   r   rR   rq   r<   rr   )r{   rk   r|   rm   rn   r}   rp   r   rJ   rG   r=   r>   r   )r*   r6   r7   r8   r9   r:   r+   re   r`   ra   r   rh   rc   rV   rk   rm   rn   rp   rt   r~   rR   r   s                         r-   rZ   z+WrappedCompletions._capture_streaming_event  s      	8	
 	= 8G)/: 

7#G':Gi'../+;FFJW#+%)-!#

$ 	  7 7Dr.   r   )NNNN)r/   r0   r1   r2   r   rG   r   r   r   r@   rL   rK   r   r   r   rZ   r   r.   r-   r   r   ;  sK   K .2*.7;%*37
%c]
 #3-
 %T#s(^4	

 #
 !c3h0
 
F .2*.7;%*37/
%c]/
 #3-/
 %T#s(^4	/

 #/
 !c3h0/
 /
bY%c]Y #3-Y %T#s(^4	Y
 #Y !c3h0Y YL 6:?C-1%)0E%c]0E #3-0E %T#s(^4	0E
 #0E !c3h00E S#X0E  0E 0E 0E T$sCx.120E 'tDcN';<0E &c]0E c]0Er.   r   c                   h    e Z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	y)r'   z;Wrapper for OpenAI embeddings that tracks usage in PostHog.Nr6   r7   r8   r9   r:   r+   c                    |t        t        j                               }t        j                         } | j                  j
                  di |}t        j                         }	i }
t        |d      r;|j                  r/t        |j                  dd      t        |j                  dd      d}
|	|z
  }d|j                  d      t        | j                  j                  |t        |j                  d                  d	|
j                  dd      ||t        | j                  j                        d
|xs i }|d|d<   t        | j                  j                  d      r-| j                  j                  j                  |xs |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.
        usageprompt_tokensr   total_tokens)r   r   r<   rR   input   )z$ai_providerz	$ai_modelz	$ai_inputz$ai_http_statusz$ai_input_tokensz$ai_latencyz$ai_trace_idz$ai_base_urlFz$process_person_profilecapturez$ai_embedding)rv   eventrx   rz   r   )rG   rH   rI   rY   r?   rL   rW   r   r!   rJ   r   r=   r   r   r>   r   )r*   r6   r7   r8   r9   r:   r+   rd   rQ   r_   re   r`   event_propertiess                r-   rL   zWrappedEmbeddings.create!  sp   0 #"4::<0YY[
(4>>((26299; 8W%(..!(!!L ' JK
 Z' %G,*''$(G)<=
  # + C", 5 56
 "'R
  &:?67 4<<**I6LL##++/C3C%+%	 ,  r.   r   )
r/   r0   r1   r2   r   rG   r   r   r   rL   r   r.   r-   r'   r'     s~    E .2*.7;%*37F%c]F #3-F %T#s(^4	F
 #F !c3h0F Fr.   r'   c                        e Zd ZdZed        Zy)r(   z>Wrapper for OpenAI beta features that tracks usage in PostHog.c                 V    t        | j                  | j                  j                        S )z2Access beta chat APIs with PostHog usage tracking.)WrappedBetaChatr=   r?   r   r   s    r-   r   zWrappedBeta.chatm  s     t||T^^-@-@AAr.   N)r/   r0   r1   r2   r   r   r   r.   r-   r(   r(   j  s    HB Br.   r(   c                        e Zd ZdZed        Zy)r   z:Wrapper for OpenAI beta chat that tracks usage in PostHog.c                 V    t        | j                  | j                  j                        S )z9Access beta chat completions with PostHog usage tracking.)WrappedBetaCompletionsr=   r?   r   r   s    r-   r   zWrappedBetaChat.completionsv  s     &dllDNN4N4NOOr.   Nr   r   r.   r-   r   r   s  s    DP Pr.   r   c                   h    e Z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	y)r   zFWrapper for OpenAI beta chat completions that tracks usage in PostHog.Nr6   r7   r8   r9   r:   r+   c                 $    t        | |||||fi |S )a  
        Parse an OpenAI beta chat completion while tracking usage in PostHog.

        Args:
            posthog_distinct_id: Optional distinct ID to associate with the usage event.
            posthog_trace_id: Optional trace ID. Generated automatically when omitted.
            posthog_properties: Additional properties to include with the usage event.
            posthog_privacy_mode: Whether to redact captured input and output.
            posthog_groups: Optional PostHog groups to associate with the event.
            **kwargs: Arguments passed to OpenAI's beta ``chat.completions.parse`` API.

        Returns:
            The parsed response from OpenAI.
        r   rM   s          r-   r@   zWrappedBetaCompletions.parse  r   r.   r   )
r/   r0   r1   r2   r   rG   r   r   r   r@   r   r.   r-   r   r   |  sw    P .2*.7;%*37
%c]
 #3-
 %T#s(^4	

 #
 !c3h0
 
r.   r   )+rY   rH   typingr   r   r   r   r{   r   r<   ImportErrorModuleNotFoundErrorr}   r   r	   r
   r   r|   r   r   r   r   posthog.ai.sanitizationr   r   posthog.clientr   r3   posthogr   posthog.ai.openai.wrapper_utilsr   r   rG   r   rB   r)   r&   r   r'   r(   r   r   r   r.   r-   <module>r      sA     , , '   N 2  B$NV]] $NN!# sm !c3h0	
  T#s(^, .Q
- Q
hL( L`E/ `EFI. IXB( BP, P"
3 "
g  
Q s   C C)