o
    3Ih\                     @   s   d dl Z d dlZd dlmZmZmZmZ zd dlZW n ey%   e	dw d dl
mZmZmZ d dlmZ G dd dejZG dd	 d	ZG d
d dZG dd dZG dd dZG dd dZG dd dZG d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                       s0   e Zd ZU dZeed< def fddZ  ZS )AsyncOpenAIzf
    An async wrapper around the OpenAI SDK that automatically sends LLM usage events to PostHog.
    
_ph_clientposthog_clientc                    s   t  jdi | || _t| dd| _t| dd| _t| dd| _t| dd| _| jdur4t| | j| _	| jdur@t
| | j| _| jdurLt| | j| _| jdurZt| | 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__r   ^/home/air/sanwanet/gpt-api/venv/lib/python3.10/site-packages/posthog/ai/openai/openai_async.pyr      s   



zAsyncOpenAI.__init__)__name__
__module____qualname____doc__PostHogClient__annotations__r   __classcell__r   r   r   r!   r
      s   
 r
   c                   @   sz  e Zd ZdZdefddZd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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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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dZdS )r   z@Async wrapper for OpenAI responses that tracks usage in PostHog.clientc                 C      || _ || _d S N_client	_original)r   r)   original_responsesr   r   r!   r   =      
zWrappedResponses.__init__c                 C      t | j|S )zQFallback to original responses object for any methods we don't explicitly handle.r   r.   r   namer   r   r!   __getattr__A      zWrappedResponses.__getattr__NFposthog_distinct_idposthog_trace_idposthog_propertiesposthog_privacy_modeposthog_groupsr   c              
      st   |d u rt t }|ddr!| j|||||fi |I d H S t|| jjd||||| jj| j	j
f	i |I d H S NstreamFopenaistruuiduuid4get_create_streamingr   r-   r   base_urlr.   creater   r7   r8   r9   r:   r;   r   r   r   r!   rF   E   s4   		
zWrappedResponses.createc                    sP   t   	i 
g  jjdi I d H  	
fdd}| S )Nc                    s>  z2 za3 d H W  t  dr) jdkr) j} | jr)t| jdkr)| jd  t  drb jrb fdddD t  jdrNt  jjd	rN jjjd	< t  jd
rbt  jj	drb jj	j
d<  V  q6 W t }|
 }}	||	I d H  d S t }|
 }}	||	I d H  w )Ntypezresponse.completedr   usagec                       i | ]
}|t  j|d qS r   r   rI   .0kchunkr   r!   
<dictcomp>       zOWrappedResponses._create_streaming.<locals>.async_generator.<locals>.<dictcomp>)input_tokensoutput_tokenstotal_tokensoutput_tokens_detailsreasoning_tokensinput_tokens_detailscached_tokenscache_read_input_tokens)hasattrrH   responseoutputlenappendrI   rW   rX   rY   rZ   time_capture_streaming_event)resend_timelatencyr^   final_contentr   r7   r;   r:   r9   r8   r]   r   
start_timeusage_statsrP   r!   async_generatorv   sf   

"z;WrappedResponses._create_streaming.<locals>.async_generatorr   ra   r.   rF   r   r7   r8   r9   r:   r;   r   rj   r   rf   r!   rD   h   s   	 6z"WrappedResponses._create_streamingri   re   r^   
tool_callsc                    s   |d u rt t }d|dt|t| jj||dt| jj||	d|dd|dd|dd|d	d||t | jjd
|pEi }|
rSt| jj||
|d< |d u r[d|d< t	| jjdrq| jjj
|pi|d||d d S d S )Nr>   modelinput   rT   r   rU   r[   rX   $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r@   rA   rB   rC   r   r   r-   r   rE   r\   r|   r   r7   r8   r9   r:   r;   r   ri   re   r^   rm   event_propertiesr   r   r!   rb      sV   




z)WrappedResponses._capture_streaming_eventc              
      s4   t || jjd||||| jj| jjf	i |I dH 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.
        r>   Nr   r-   r   rE   r.   parserG   r   r   r!   r      s   
zWrappedResponses.parseNNNFNr+   )r"   r#   r$   r%   r
   r   r5   r   r@   r   r   boolrF   rD   intfloatr   rb   r   r   r   r   r!   r   :   s    
#
Q

	

=r   c                   @   2   e Zd ZdZdefddZdd Zedd Zd	S )
r   z;Async wrapper for OpenAI chat that tracks usage in PostHog.r)   c                 C   r*   r+   r,   )r   r)   original_chatr   r   r!   r     r0   zWrappedChat.__init__c                 C   r1   )zLFallback to original chat object for any methods we don't explicitly handle.r2   r3   r   r   r!   r5     r6   zWrappedChat.__getattr__c                 C      t | j| jjS r+   )WrappedCompletionsr-   r.   completionsr   r   r   r!   r        zWrappedChat.completionsN	r"   r#   r$   r%   r
   r   r5   propertyr   r   r   r   r!   r         r   c                   @   s,  e Zd ZdZdefddZd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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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dZdS )r   zGAsync wrapper for OpenAI chat completions that tracks usage in PostHog.r)   c                 C   r*   r+   r,   )r   r)   original_completionsr   r   r!   r   !  r0   zWrappedCompletions.__init__c                 C   r1   )zSFallback to original completions object for any methods we don't explicitly handle.r2   r3   r   r   r!   r5   %  r6   zWrappedCompletions.__getattr__NFr7   r8   r9   r:   r;   r   c              
      sx   |d u rt t }|ddr!| j|||||fi |I d H S t|| jjd||||| jj| j	j
f	i |I d H }|S r<   r?   )r   r7   r8   r9   r:   r;   r   r]   r   r   r!   rF   )  s6   		
zWrappedCompletions.createc                    sr   t   
i g  i dvri d< dd d< 	jjdi I d H  	
fdd}| S )Nstream_optionsTinclude_usagec                    s  zψ	2 z3 d H W  t  drC jrC fdddD t  jdr/t  jjdr/ jjjd< t  jdrCt  jjd	rC jjjd	< t  d
r jrt jdkr jd jrm jd jj	rm jd jj	} | rm
|  t jd jdd }|r|D ]%}|j}|vr||< q{t |drt |jdr| j j|jj7  _q{ V  q6 W t }| }d}rt nd }
|||
I d H  d S t }| }d}rt nd }
|||
I d H  w )NrI   c                    rJ   rK   rL   rM   rP   r   r!   rR   i  rS   zQWrappedCompletions._create_streaming.<locals>.async_generator.<locals>.<dictcomp>)prompt_tokenscompletion_tokensrV   prompt_tokens_detailsrZ   r[   rW   rX   choicesr   rm   function	arguments )r\   rI   r   rZ   rW   rX   r   r_   deltacontentr`   r   indexr   r   ra   joinlistvaluesrb   )r   rm   	tool_callr   rd   re   r^   toolsaccumulated_contentaccumulated_toolsr   r7   r;   r:   r9   r8   r]   r   rh   ri   rP   r!   rj   a  s   



9

z=WrappedCompletions._create_streaming.<locals>.async_generatorr   rk   rl   r   r   r!   rD   N  s   	"Pz$WrappedCompletions._create_streamingri   re   r^   rm   c                    s   |d u rt t }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|pIi }|
rWt| jj||
|d< |d u r_d|d< t	| jjdru| jjj
|pm|d||d d S d S )Nr>   rn   messages	assistant)r   rolerp   r   r   r   r[   rX   rq   rz   Fr{   r|   r}   r~   r   r   r   r   r!   rb     sV   





z+WrappedCompletions._capture_streaming_eventr   r+   )r"   r#   r$   r%   r
   r   r5   r   r@   r   r   r   rF   rD   r   r   r   rb   r   r   r   r!   r     sr    
%
p

	
r   c                   @   t   e Zd ZdZdefddZd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dZdS )r   zAAsync wrapper for OpenAI embeddings that tracks usage in PostHog.r)   c                 C   r*   r+   r,   )r   r)   original_embeddingsr   r   r!   r     r0   zWrappedEmbeddings.__init__c                 C   r1   )zRFallback to original embeddings object for any methods we don't explicitly handle.r2   r3   r   r   r!   r5     r6   zWrappedEmbeddings.__getattr__NFr7   r8   r9   r:   r;   r   c              	      s   |du rt t }t }| jjdi |I dH }t }	i }
t|dr8|jr8t|jddt|jddd}
|	| }d|	dt
| jj||	d	d
|
	dd||t | jjd|p]i }|du rgd|d< t| jjdr{| jjj|pu|d||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.
        NrI   r   r   rV   )r   rV   r>   rn   ro   rp   )rr   rs   rt   ru   rv   rw   rx   ry   Fr{   r|   z$ai_embeddingr~   r   )r@   rA   rB   ra   r.   rF   r\   rI   r   rC   r   r-   r   rE   r|   )r   r7   r8   r9   r:   r;   r   rh   r]   rd   ri   re   r   r   r   r!   rF     sF   

zWrappedEmbeddings.creater   )r"   r#   r$   r%   r
   r   r5   r   r@   r   r   r   rF   r   r   r   r!   r     ,    r   c                   @   r   )
r   zDAsync wrapper for OpenAI beta features that tracks usage in PostHog.r)   c                 C   r*   r+   r,   )r   r)   original_betar   r   r!   r   C  r0   zWrappedBeta.__init__c                 C   r1   )zLFallback to original beta object for any methods we don't explicitly handle.r2   r3   r   r   r!   r5   G  r6   zWrappedBeta.__getattr__c                 C   r   r+   )WrappedBetaChatr-   r.   r   r   r   r   r!   r   K  r   zWrappedBeta.chatN)	r"   r#   r$   r%   r
   r   r5   r   r   r   r   r   r!   r   @  r   r   c                   @   r   )
r   z@Async wrapper for OpenAI beta chat that tracks usage in PostHog.r)   c                 C   r*   r+   r,   )r   r)   original_beta_chatr   r   r!   r   S  r0   zWrappedBetaChat.__init__c                 C   r1   )zQFallback to original beta chat object for any methods we don't explicitly handle.r2   r3   r   r   r!   r5   W  r6   zWrappedBetaChat.__getattr__c                 C   r   r+   )WrappedBetaCompletionsr-   r.   r   r   r   r   r!   r   [  r   zWrappedBetaChat.completionsNr   r   r   r   r!   r   P  r   r   c                   @   r   )r   zLAsync wrapper for OpenAI beta chat completions that tracks usage in PostHog.r)   c                 C   r*   r+   r,   )r   r)   original_beta_completionsr   r   r!   r   c  r0   zWrappedBetaCompletions.__init__c                 C   r1   )zXFallback to original beta completions object for any methods we don't explicitly handle.r2   r3   r   r   r!   r5   g  r6   z"WrappedBetaCompletions.__getattr__NFr7   r8   r9   r:   r;   r   c              
      s4   t || jjd||||| jj| jjf	i |I d H S )Nr>   r   rG   r   r   r!   r   k  s   	
zWrappedBetaCompletions.parser   )r"   r#   r$   r%   r
   r   r5   r   r@   r   r   r   r   r   r   r   r!   r   `  r   r   )ra   rA   typingr   r   r   r   r>   ImportErrorModuleNotFoundErrorposthog.ai.utilsr   r   r   posthog.clientr	   r&   r
   r   r   r   r   r   r   r   r   r   r   r!   <module>   s,    & U RQ