o
    3IhP[                     @   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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 )OpenAIz_
    A 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   X/home/air/sanwanet/gpt-api/venv/lib/python3.10/site-packages/posthog/ai/openai/openai.pyr      s   



zOpenAI.__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: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              
   K   f   |d u r
t t }|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   r-   r   base_urlr.   creater   r7   r8   r9   r:   r;   r   r   r   r!   rG   E   2   		
zWrappedResponses.createc                    sH   t   	i 
g  jjdi  	
fdd}| S )Nc                  3   s(   zzD ]] t  dr% jdkr% j} | jr%t| jdkr%| jd  t  dr^ jr^ fdddD t  jdrJt  jjd	rJ jjjd	< t  jd
r^t  jj	dr^ jj	j
d<  V  qW t }|
 }}	||	 d S t }|
 }}	||	 w )Ntypezresponse.completedr   usagec                       i | ]
}|t  j|d qS r   r   rK   .0kchunkr   r!   
<dictcomp>       zIWrappedResponses._create_streaming.<locals>.generator.<locals>.<dictcomp>)input_tokensoutput_tokenstotal_tokensoutput_tokens_detailsreasoning_tokensinput_tokens_detailscached_tokenscache_read_input_tokens)hasattrrJ   responseoutputlenappendrK   rY   rZ   r[   r\   time_capture_streaming_event)resend_timelatencyr`   final_contentr   r7   r;   r:   r9   r8   r_   r   
start_timeusage_statsrR   r!   	generatorv   sf   

"z5WrappedResponses._create_streaming.<locals>.generatorr   rc   r.   rG   r   r7   r8   r9   r:   r;   r   rl   r   rh   r!   rE   h   s   	 6z"WrappedResponses._create_streamingrk   rg   r`   
tool_callsc                 C   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
|pDi }|
rRt| jj||
|d< |d u rZd|d< t	| jjdrp| jjj
|ph|d||d d S d S )Nr?   modelinput   rV   r   rW   r]   rZ   $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rA   rB   rC   rD   r   r   r-   r   rF   r^   r~   r   r7   r8   r9   r:   r;   r   rk   rg   r`   ro   event_propertiesr   r   r!   rd      sT   




z)WrappedResponses._capture_streaming_eventc              
   K   ,   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.
        r?   r   r-   r   rF   r.   parserH   r   r   r!   r      s   
zWrappedResponses.parseNNNFNr+   )r"   r#   r$   r%   r
   r   r5   r   rA   r   r   boolrG   rE   intfloatr   rd   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   z5Wrapper 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   zAWrapper 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              
   K   r<   r=   r@   rH   r   r   r!   rG   )  rI   zWrappedCompletions.createc                    sj   t   
i g  i dvri d< dd d< 	jjdi  	
fdd}| S )Nstream_optionsTinclude_usagec                  3   s   zǈ	D ] t  dr? jr? fd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ri jd jj	ri jd jj	} | ri
|  t jd jdd }|r|D ]%}|j}|vr||< qwt |drt |jdr| j j|jj7  _qw V  qW t }| }d}rt nd }
|||
 d S t }| }d}rt nd }
|||
 w )NrK   c                    rL   rM   rN   rO   rR   r   r!   rT   f  rU   zKWrappedCompletions._create_streaming.<locals>.generator.<locals>.<dictcomp>)prompt_tokenscompletion_tokensrX   prompt_tokens_detailsr\   r]   rY   rZ   choicesr   ro   function	arguments )r^   rK   r   r\   rY   rZ   r   ra   deltacontentrb   r   indexr   r   rc   joinlistvaluesrd   )r   ro   	tool_callr   rf   rg   r`   toolsaccumulated_contentaccumulated_toolsr   r7   r;   r:   r9   r8   r_   r   rj   rk   rR   r!   rl   ^  s   



9

z7WrappedCompletions._create_streaming.<locals>.generatorr   rm   rn   r   r   r!   rE   L  s   	"Pz$WrappedCompletions._create_streamingrk   rg   r`   ro   c                 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|pHi }|
rVt| jj||
|d< |d u r^d|d< t	| jjdrt| jjj
|pl|d||d d S d S )Nr?   rp   messages	assistant)r   rolerr   r   r   r   r]   rZ   rs   r|   Fr}   r~   r   r   r   r   r   r   r!   rd     sT   





z+WrappedCompletions._capture_streaming_eventr   r+   )r"   r#   r$   r%   r
   r   r5   r   rA   r   r   r   rG   rE   r   r   r   rd   r   r   r   r!   r     sr    
#
o

	
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   z;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              	   K   s   |du r
t t }t }| jjdi |}t }	i }
t|dr4|jr4t|jddt|jddd}
|	| }d|	dt
| jj||	d	d
|
	dd||t | jjd|pYi }|du rcd|d< t| jjdrw| jjj|pq|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.
        NrK   r   r   rX   )r   rX   r?   rp   rq   rr   )rt   ru   rv   rw   rx   ry   rz   r{   Fr}   r~   z$ai_embeddingr   r   )rA   rB   rC   rc   r.   rG   r^   rK   r   rD   r   r-   r   rF   r~   )r   r7   r8   r9   r:   r;   r   rj   r_   rf   rk   rg   r   r   r   r!   rG     sD   

zWrappedEmbeddings.creater   )r"   r#   r$   r%   r
   r   r5   r   rA   r   r   r   rG   r   r   r   r!   r     ,    r   c                   @   r   )
r   z>Wrapper for OpenAI beta features that tracks usage in PostHog.r)   c                 C   r*   r+   r,   )r   r)   original_betar   r   r!   r   @  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   D  r6   zWrappedBeta.__getattr__c                 C   r   r+   )WrappedBetaChatr-   r.   r   r   r   r   r!   r   H  r   zWrappedBeta.chatN)	r"   r#   r$   r%   r
   r   r5   r   r   r   r   r   r!   r   =  r   r   c                   @   r   )
r   z:Wrapper for OpenAI beta chat that tracks usage in PostHog.r)   c                 C   r*   r+   r,   )r   r)   original_beta_chatr   r   r!   r   P  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   T  r6   zWrappedBetaChat.__getattr__c                 C   r   r+   )WrappedBetaCompletionsr-   r.   r   r   r   r   r!   r   X  r   zWrappedBetaChat.completionsNr   r   r   r   r!   r   M  r   r   c                   @   r   )r   zFWrapper for OpenAI beta chat completions that tracks usage in PostHog.r)   c                 C   r*   r+   r,   )r   r)   original_beta_completionsr   r   r!   r   `  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   d  r6   z"WrappedBetaCompletions.__getattr__NFr7   r8   r9   r:   r;   r   c              
   K   r   )Nr?   r   rH   r   r   r!   r   h  s   	
zWrappedBetaCompletions.parser   )r"   r#   r$   r%   r
   r   r5   r   rA   r   r   r   r   r   r   r   r!   r   ]  r   r   )rc   rB   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 OQ