o
    Zh=                     @  s  d dl mZ d dlZd dlZd dlmZ d dlmZ d dlm	Z	m
Z
mZmZmZmZ d dlmZ d dlmZ d dlmZ d d	lmZmZmZ e	rfd d
lmZmZ d dlmZmZmZ d dl m!Z! d dl"m#Z# ededde
f dZ$e%e&Z'ej(dRddZ)dSddZ*dTddZ+dUd!d"Z,dVd%d&Z-dWd(d)Z.dXd,d-Z/dYd0d1Z0			dZd[d;d<Z1		d\d]d>d?Z2d^dBdCZ3G dDdE dEedFdGZ4ddHddId_dMdNZ5d`dPdQZ6dS )a    )annotationsN)defaultdict)Mapping)TYPE_CHECKINGAnyCallableOptionalTypeVarUnion)	TypedDict)client)run_helpers)InputTokenDetailsOutputTokenDetailsUsageMetadata)AsyncOpenAIOpenAI)ChatCompletionChunkChoiceChoiceDeltaToolCall)
Completion)ResponseStreamEventCr   r   )boundreturnOptional[type]c                  C  s(   z	ddl m}  | W S  ty   Y d S w )Nr   NotGiven)Zopenai._typesr   ImportErrorr    r   Q/var/www/html/lang_env/lib/python3.10/site-packages/langsmith/wrappers/_openai.py_get_not_given%   s   r!   ddictc              
     sf   zt    d u r| W S  fdd|  D W S  ty2 } ztd|  | W  Y d }~S d }~ww )Nc                   s2   i | ]\}}t | s|d r|du s||qS )Zextra_N)
isinstance
startswith.0kvZ	not_givenr   r    
<dictcomp>4   s    z$_strip_not_given.<locals>.<dictcomp>zError stripping NotGiven: )r!   items	Exceptionloggererror)r"   er   r*   r    _strip_not_given/   s   
r1   
model_typestrkwargsc                 C  s^   t |}|d}|rt|tr|g}d| |d|d|dp+|dp+|d|dS )	NstopopenaimodelZtemperatureZ
max_tokensZmax_completion_tokensZmax_output_tokens)Zls_providerZls_model_typeZls_model_nameZls_temperatureZls_max_tokensZls_stop)r1   getr$   r3   )r2   r4   strippedr5   r   r   r    _infer_invocation_params>   s   

r:   choiceslist[Choice]c                 C  sR  t t| }ddd}|D ]}t|dr#t|jdd r#|jj|d<  nqtt }| D ]o}t|drt|jdd rB|d  |jj7  < t|jdd r}|dsUddd|d< t|jj	d	d }|ri|d d	  |7  < t|jj	d
d }|r}|d d
  |7  < t|jdd r|jj
}|d ur|D ]
}||j | qq*|rdd tt| d D |d< | D ]]\}	}
|	tdd |
D d tdd |
D d dddd|d |	< |
D ]8}t|dd rt|jd	d }|r|d |	 d d	  |7  < t|jd
d }|r|d |	 d d
  |7  < qq| rt| d ddndtdd |D d |dS )N	assistant rolecontentdeltar@   rA   function_call)name	argumentsrD   rE   
tool_callsc                 S  s   g | ]}d qS Nr   )r'   _r   r   r    
<listcomp>o   s    z#_reduce_choices.<locals>.<listcomp>   c                 s      | ]	}|j r|j V  qd S rG   )idr'   cr   r   r    	<genexpr>s       z"_reduce_choices.<locals>.<genexpr>c                 s  rK   rG   )typerM   r   r   r    rO   t   rP   )indexrL   rQ   functionrS   r   rR   c                 s  s"    | ]}t |d dr|jV  qdS )finish_reasonN)getattrrT   rM   r   r   r    rO      s    

)rR   rT   message)listreversedhasattrrU   rB   r@   r   rA   r8   rC   rF   rR   appendrangemaxkeysr,   nextrS   )r;   Zreversed_choicesrV   rN   rF   Zname_Z
arguments_Ztool_calls_listZ	tool_callrR   Ztool_call_chunkschunkr   r   r    _reduce_choicesQ   sx   

"r`   
all_chunkslist[ChatCompletionChunk]c                 C  s   t t}| D ]}|jD ]
}||j | qq| r+| d  }dd | D |d< n
dddddigi}|d	d }|rAt|nd |d
< |S )Nc                 S  s   g | ]}t |qS r   )r`   )r'   r;   r   r   r    rI      s    z _reduce_chat.<locals>.<listcomp>r;   rV   r=   r>   r?   usageusage_metadata)	r   rW   r;   rR   rZ   
model_dumpvaluespop_create_usage_metadata)ra   Zchoices_by_indexr_   choicer"   oai_token_usager   r   r    _reduce_chat   s   
rl   list[Completion]c                 C  sj   g }| D ]}|j d j}|d ur|| qd|}| r,| d  }d|ig|d< |S dd|igi}|S )Nr   r>   rc   textr;   )r;   rn   rZ   joinrf   )ra   Zall_contentr_   rA   r"   r   r   r    _reduce_completions   s   

rp   rk   r   c                 C  s   |  dp|  dpd}|  dp|  dpd}|  dp || }|  dp,|  dp,i  d	|  dp:|  dp:i  d
d}|  dpK|  dpKi  d	|  dpY|  dpYi  dd}t|||tdi dd | D tdi dd | D dS )NZprompt_tokensinput_tokensr   Zcompletion_tokensoutput_tokenstotal_tokensZprompt_tokens_detailsZinput_tokens_detailsZaudio_tokensZcached_tokens)audioZ
cache_readZcompletion_tokens_detailsZoutput_tokens_detailsZreasoning_tokens)rt   Z	reasoningc                 S     i | ]\}}|d ur||qS rG   r   r&   r   r   r    r+          z*_create_usage_metadata.<locals>.<dictcomp>c                 S  ru   rG   r   r&   r   r   r    r+      rv   )rq   rr   rs   input_token_detailsoutput_token_detailsr   )r8   r   r   r,   r   )rk   rq   rr   rs   rw   rx   r   r   r    ri      sR   




ri   outputsr   c              
   C  sl   z|   }|dd }|rt|nd |d< |W S  ty5 } ztd|  d| iW  Y d }~S d }~ww )Nrd   re   z"Error processing chat completion: output)rf   rh   ri   BaseExceptionr.   debug)ry   Zrdictrk   r0   r   r   r    _process_chat_completion   s   r}   original_creater   rD   	reduce_fntracing_extraOptional[TracingExtra]invocation_params_fnOptional[Callable]process_outputsc                   sZ   |pi t  fdd}t  fdd}tr+|S |S )Nc               	     sB   t jdd|ddu rnd t d}|| i |S NllmstreamTrD   Zrun_typer   Zprocess_inputsZ_invocation_params_fnr   r   )r   	traceabler8   r1   argsr4   	decoratorr   rD   r~   r   r   textrar   r    create   s   
z_get_wrapper.<locals>.createc               	     sR   t |}tjdd|ddu rnd t  d}|| i |I d H S r   )r1   r   r   r8   r   r   r   r    acreate  s   	z_get_wrapper.<locals>.acreate	functoolswrapsr   is_async)r~   rD   r   r   r   r   r   r   r   r   r    _get_wrapper   s   r   original_parsec                   sV   |pi t  fdd}t  fdd}tr)|S |S )Nc               	     s0   t jddd t d}|| i |S Nr   r   r   )r   r   r1   r   r   rD   r   r   r   r   r    parse"  s   	z!_get_parse_wrapper.<locals>.parsec               	     s@   t |}tjddd t  d}|| i |I d H S r   )r1   r   r   r   r   r   r    aparse/  s   	z"_get_parse_wrapper.<locals>.aparser   )r   rD   r   r   r   r   r   r   r   r    _get_parse_wrapper  s   r   eventslist[ResponseStreamEvent]c                 C  s&   | D ]}|j dkrt|j  S qi S )Nzresponse.completed)rQ   _process_responses_api_outputresponse)r   eventr   r   r    _reduce_response_events@  s
   
r   c                   @  s&   e Zd ZU ded< ded< ded< dS )TracingExtrazOptional[Mapping[str, Any]]metadatazOptional[list[str]]tagszOptional[ls_client.Client]r   N)__name__
__module____qualname____annotations__r   r   r   r    r   G  s   
 r   F)totalZ
ChatOpenAI)r   	chat_namecompletions_namer   r   r   c             
   C  s  |pi }t | jjj|t|ttdtd| jj_t | jj|t	|ttdd| j_t
| drXt
| jdrXt
| jjdrXt
| jjjdrXt| jjjj|t|ttdd| jjj_t
| drt
| jd	rut | jj|tt|ttdd
| j_t
| jdrt| jj|t|ttdd| j_| S )a  Patch the OpenAI client to make it traceable.

    Supports:
        - Chat and Responses API's
        - Sync and async OpenAI clients
        - create() and parse() methods
        - with and without streaming

    Args:
        client (Union[OpenAI, AsyncOpenAI]): The client to patch.
        tracing_extra (Optional[TracingExtra], optional): Extra tracing information.
            Defaults to None.
        chat_name (str, optional): The run name for the chat completions endpoint.
            Defaults to "ChatOpenAI".
        completions_name (str, optional): The run name for the completions endpoint.
            Defaults to "OpenAI".

    Returns:
        Union[OpenAI, AsyncOpenAI]: The patched client.

    Example:

        .. code-block:: python

            import openai
            from langsmith import wrappers

            # Use OpenAI client same as you normally would.
            client = wrappers.wrap_openai(openai.OpenAI())

            # Chat API:
            messages = [
                {"role": "system", "content": "You are a helpful assistant."},
                {
                    "role": "user",
                    "content": "What physics breakthroughs do you predict will happen by 2300?",
                },
            ]
            completion = client.chat.completions.create(
                model="gpt-4o-mini", messages=messages
            )
            print(completion.choices[0].message.content)

            # Responses API:
            response = client.responses.create(
                model="gpt-4o-mini",
                messages=messages,
            )
            print(response.output_text)

    .. versionchanged:: 0.3.16

        Support for Responses API added.
    chat)r   r   r   r   )r   r   betacompletionsr   	responsesr   )r   r   r   )r   r   r   r   rl   r   partialr:   r}   rp   rY   r   r   r   r   r   r   )r   r   r   r   r   r   r    wrap_openaiM  sl   =
	






	



r   r   c                 C  sT   | r(z| j ddd}|dd  }rt||d< |W S  ty'   d| i Y S w i S )NTjson)Zexclude_nonemoderd   re   rz   )rf   rh   ri   r-   )r   rz   rd   r   r   r    r     s   r   )r   r   )r"   r#   r   r#   )r2   r3   r4   r#   )r;   r<   r   r#   )ra   rb   r   r#   )ra   rm   r   r#   )rk   r#   r   r   )ry   r   )NNN)r~   r   rD   r3   r   r   r   r   r   r   r   r   r   r   )NN)r   r   rD   r3   r   r   r   r   r   r   r   r   )r   r   r   r#   )
r   r   r   r   r   r3   r   r3   r   r   )r   r   r   r#   )7
__future__r   r   loggingcollectionsr   collections.abcr   typingr   r   r   r   r	   r
   typing_extensionsr   Z	langsmithr   Z	ls_clientr   Zlangsmith.schemasr   r   r   r6   r   r   Z'openai.types.chat.chat_completion_chunkr   r   r   Zopenai.types.completionr   Zopenai.types.responsesr   r   	getLoggerr   r.   	lru_cacher!   r1   r:   r`   rl   rp   ri   r}   r   r   r   r   r   r   r   r   r   r    <module>   sP     	

	


>


/-
'	{