o
    +iCJ                     @  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(dWddZ)dXddZ*dXddZ+dYd d!Z,dZd$d%Z-d[d(d)Z.d\d+d,Z/	d]d^d1d2Z0d_d5d6Z1			d`dad@dAZ2		dbdcdCdDZ3dddGdHZ4G dIdJ dJedKdLZ5ddMddNdedRdSZ6dfdUdVZ7dS )g    )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tuple[type, ...]c                  C  sL   g } zddl m}m} | | | | W t| S  ty%   Y t| S w )z4Get NotGiven/Omit sentinel types used by OpenAI SDK.r   )NotGivenOmit)openai._typesr   r   appendImportErrortuple)typesr   r    r#   W/var/www/html/psymed-ai/venv/lib/python3.10/site-packages/langsmith/wrappers/_openai.py_get_omit_types%   s   
r%   ddictc              
     sb   zt    s	| W S  fdd|  D W S  ty0 } ztd|  | W  Y d }~S d }~ww )Nc                   s2   i | ]\}}t | s|d r|du s||qS )extra_N)
isinstance
startswith.0kv
omit_typesr#   r$   
<dictcomp>9   s    z$_strip_not_given.<locals>.<dictcomp>zError stripping NotGiven: )r%   items	Exceptionloggererror)r&   er#   r/   r$   _strip_not_given4   s   
r7   c                 C  sR   t | } d| v r'| d }t|dr'zi | d| iW S  ty&   Y | S w | S )zCStrip `NotGiven` values and serialize `text_format` to JSON schema.text_formatmodel_json_schema)r7   hasattrr9   r3   )r&   r8   r#   r#   r$   _process_inputsC   s   
r;   
model_typestrproviderkwargsc                   s~   t |}|d}|rt|tr|g}h d  fdd| D }|| |d|d|dp:|dp:|d	||d
S )Nstop>   nseedusertop_plogprobs	reasoning	verbosity
logit_bias
modalities
prediction
truncationservice_tiertop_logprobsstream_optionsresponse_formatpresence_penaltyprompt_cache_keyreasoning_effortfrequency_penaltyweb_search_optionsparallel_tool_callsc                   s   i | ]\}}| v r||qS r#   r#   r+   allowed_invocation_keysr#   r$   r1   w   s    z,_infer_invocation_params.<locals>.<dictcomp>modeltemperature
max_tokensmax_completion_tokensmax_output_tokens)ls_providerls_model_typels_model_namels_temperaturels_max_tokensls_stopls_invocation_params)r7   getr)   r=   r2   )r<   r>   r?   strippedr@   invocation_paramsr#   rV   r$   _infer_invocation_paramsU   s&   


rg   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deltarm   rn   function_call)name	argumentsrq   rr   
tool_callsc                 S  s   g | ]}d qS Nr#   )r,   _r#   r#   r$   
<listcomp>   s    z#_reduce_choices.<locals>.<listcomp>   c                 s      | ]	}|j r|j V  qd S rt   )idr,   cr#   r#   r$   	<genexpr>       z"_reduce_choices.<locals>.<genexpr>c                 s  rx   rt   )typerz   r#   r#   r$   r|      r}   )indexry   r~   functionr   r   r   c                 s  s"    | ]}t |d dr|jV  qdS )finish_reasonN)getattrr   rz   r#   r#   r$   r|      s    

)r   r   message)listreversedr:   r   ro   rm   r   rn   rd   rp   rs   r   r   rangemaxkeysr2   nextr   )rh   reversed_choicesr   r{   rs   name_
arguments_tool_calls_list	tool_callr   tool_call_chunkschunkr#   r#   r$   _reduce_choices   st   

"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,   rh   r#   r#   r$   rv      s    z _reduce_chat.<locals>.<listcomp>rh   r   rj   rk   rl   usageusage_metadata)	r   r   rh   r   r   
model_dumpvaluespop_create_usage_metadata)r   choices_by_indexr   choicer&   oai_token_usager#   r#   r$   _reduce_chat   s   
r   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   rk   r   textrh   )rh   r   r   joinr   )r   all_contentr   rn   r&   r#   r#   r$   _reduce_completions   s   

r   r   rL   Optional[str]r   c           	      C  sn  |dv r|nd }|r| dnd}|  dp|  dpd}|  dp(|  dp(d}|  d	p1|| }d
|  dp>|  dp>i  d| d|  dpP|  dpPi  di}d
|  dpa|  dpai  d| d|  dps|  dpsi  di}|r|| | dpd ||< || | dpd ||< t|||tdi dd | D tdi dd | D dS )N)priorityflexru   rk   prompt_tokensinput_tokensr   completion_tokensoutput_tokenstotal_tokensaudioprompt_tokens_detailsinput_tokens_detailsaudio_tokens
cache_readcached_tokenscompletion_tokens_detailsoutput_tokens_detailsrF   reasoning_tokensc                 S     i | ]\}}|d ur||qS rt   r#   r+   r#   r#   r$   r1   '      z*_create_usage_metadata.<locals>.<dictcomp>c                 S  r   rt   r#   r+   r#   r#   r$   r1   *  r   )r   r   r   input_token_detailsoutput_token_detailsr#   )rd   r   r   r2   r   )	r   rL   recognized_service_tierservice_tier_prefixr   r   r   r   r   r#   r#   r$   r      sp   




r   outputsr   c              
   C  st   z|   }|dd }|rt||dnd |d< |W S  ty9 } ztd|  d| iW  Y d }~S d }~ww )Nr   rL   r   z"Error processing chat completion: output)r   r   r   rd   BaseExceptionr4   debug)r   rdictr   r6   r#   r#   r$   _process_chat_completion/  s   r   original_creater   rq   	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rq   run_typer   process_inputs_invocation_params_fnr   r#   r   	traceablerd   r;   argsr?   	decoratorr   rq   r   r   r   textrar#   r$   createH  s   
z_get_wrapper.<locals>.createc               	     sJ   t jdd|ddu rnd t d}|| i |I d H S r   r   r   r   r#   r$   acreateV  s   	z_get_wrapper.<locals>.acreate	functoolswrapsr   is_async)r   rq   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   r;   r   r   rq   r   r   r   r#   r$   parseo  s   	z!_get_parse_wrapper.<locals>.parsec               	     s8   t jddd t d}|| i |I d H S r   r   r   r   r#   r$   aparse|  s   	z"_get_parse_wrapper.<locals>.aparser   )r   rq   r   r   r   r   r   r#   r   r$   _get_parse_wrapperf  s   r   eventslist[ResponseStreamEvent]c                 C  s&   | D ]}|j dkrt|j  S qi S )Nzresponse.completed)r~   _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     s   
 r   F)total
ChatOpenAI)r   	chat_namecompletions_namer   r   r   c                C  s  |pi }d}zddl m}m} t| |st| |rd}d}d}W n	 ty)   Y nw t| jjj|t	|t
td|td| jj_t| jj|t|t
td	|d
| j_t| drt| jdrt| jjdrt| jjjdrt| jjjj|t|t
td|d
| jjj_t| drt| jdrt| jjdrt| jjj|t|t
td|d
| jj_t| drt| jdrt| 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: The client to patch.
        tracing_extra: Extra tracing information.
        chat_name: The run name for the chat completions endpoint.
        completions_name: The run name for the completions endpoint.

    Returns:
        The patched client.

    Example:
        ```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)
        ```

    !!! warning "Behavior changed in `langsmith` 0.3.16"

        Support for Responses API added.
    openair   )AsyncAzureOpenAIAzureOpenAIazureAzureChatOpenAIr   chat)r   r   r   r   )r   r   betacompletionsr   	responsesr   )r   r   r   )r   r   r   r)   r    r   r   r   r   r   r   partialrg   r   r   r:   r   r   r   r   r   r   )r   r   r   r   r]   r   r   r#   r#   r$   wrap_openai  s   9








r   r   c                 C  s\   | r,z| j ddd}|dd  }rt||d|d< |W S  ty+   d| i Y S w i S )NTjson)exclude_nonemoder   rL   r   r   )r   r   r   rd   r3   )r   r   r   r#   r#   r$   r   1  s   
r   )r   r   )r&   r'   r   r'   )r<   r=   r>   r=   r?   r'   )rh   ri   r   r'   )r   r   r   r'   )r   r   r   r'   rt   )r   r'   rL   r   r   r   )r   r   )NNN)r   r   rq   r=   r   r   r   r   r   r   r   r   r   r   )NN)r   r   rq   r=   r   r   r   r   r   r   r   r   )r   r   r   r'   )
r   r   r   r   r   r=   r   r=   r   r   )r   r   r   r'   )8
__future__r   r   loggingcollectionsr   collections.abcr   typingr   r   r   r   r	   r
   typing_extensionsr   	langsmithr   	ls_clientr   langsmith.schemasr   r   r   r   r   r   'openai.types.chat.chat_completion_chunkr   r   r   openai.types.completionr   openai.types.responsesr   r   	getLoggerr   r4   	lru_cacher%   r7   r;   rg   r   r   r   r   r   r   r   r   r   r   r   r#   r#   r#   r$   <module>   sV     	




3
>

D,
&	 