o
    0i56                     @   s  U d dl mZ d dlmZmZmZmZ d dlmZ d dl	m
Z
 d dlmZmZ d dlmZ d dlmZmZmZ eeZi di d	i d
i di di di di di di di di di di di di di di di iZeeeee
f f ed< edeeef deeef fddZedee dee fddZdeeeef ee f deeeef ee f fd dZG d!d" d"ZG d#d$ d$eZG d%d& d&eZG d'd( d(eZ ed)d*d+eded, fd-d.Z!d/ed0edefd1d2Z"d)S )3    )	lru_cache)AnyOptionalUnionoverload)	constants)InferenceProviderMapping)	MimeBytesRequestParameters)ChatCompletionInputMessage)build_hf_headers	get_tokenloggingZcerebrasZcohereZclarifaizfal-aizfireworks-aiZgroqzhf-inferenceZ
hyperbolicZnebiusZnscaleZnvidiaZovhcloudZ	replicateZ	sambanovaZscalewayZtogetherZ	wavespeedzzai-org!HARDCODED_MODEL_INFERENCE_MAPPINGobjreturnc                 C      d S N r   r   r   f/home/kim/smarthome/.venv/lib/python3.10/site-packages/huggingface_hub/inference/_providers/_common.pyfilter_none.      r   c                 C   r   r   r   r   r   r   r   r   0   r   c                 C   sv   t | tr&i }|  D ]\}}|d u rqt |ttfrt|}|||< q|S t | tr2dd | D S tdt|  )Nc                 S   s&   g | ]}t |ttfrt|n|qS r   )
isinstancedictlistr   ).0vr   r   r   
<listcomp>@   s   & zfilter_none.<locals>.<listcomp>zExpected dict or list, got )r   r   itemsr   r   
ValueErrortype)r   cleanedkr   r   r   r   r   4   s   


c                   @   s  e Zd ZdZdedededdfddZdd	d
edeeef dedee dee deeeef  de	fddZ
	d,deeef dee	 defddZdee defddZdee defddZdeeef deeeef  dee deeef fddZdededeeef fddZded edefd!d"Zdedefd#d$Zd ededefd%d&Zd
eded'edee fd(d)Zd
eded'edee dee f
d*d+ZdS )-TaskProviderHelperz.Base class for task-specific provider helpers.providerbase_urltaskr   Nc                 C   s   || _ || _|| _d S r   )r%   r'   r&   )selfr%   r&   r'   r   r   r   __init__H   s   
zTaskProviderHelper.__init__)extra_payloadinputs
parametersheadersmodelapi_keyr*   c                C   s   |  |}| |}| ||}| ||j}| j|||d}	|	dur,t|	t|p)i }	| ||||}
|	dur@|
dur@t	d|	du rL|
du rLt	d| 
||	|
}t|| j|j|	|
|dS )z
        Prepare the request to be sent to the provider.

        Each step (api_key, model, headers, url, payload) can be customized in subclasses.
        )provider_mapping_infoNz8Both payload and data cannot be set in the same request.z2Either payload or data must be set in the request.)urlr'   r.   jsondatar-   )_prepare_api_key_prepare_mapping_info_prepare_headers_prepare_urlprovider_id_prepare_payload_as_dictrecursive_merger   _prepare_payload_as_bytesr    _normalize_headersr
   r'   )r(   r+   r,   r-   r.   r/   r*   r0   r1   payloadr3   normalized_headersr   r   r   prepare_requestM   s*   

z"TaskProviderHelper.prepare_requestresponserequest_paramsc                 C   s   |S )z
        Return the response in the expected format.

        Override this method in subclasses for customized response handling.r   )r(   r@   rA   r   r   r   get_response   s   	zTaskProviderHelper.get_responsec                 C   s,   |du rt  }|du rtd| j d|S )zZReturn the API key to use for the request.

        Usually not overwritten in subclasses.Nz)You must provide an api_key to work with z$ API or log in with `hf auth login`.)r   r    r%   r(   r/   r   r   r   r4      s   z#TaskProviderHelper._prepare_api_keyc              
   C   s  |du rt d| j dt| ji |rt| j | S d}t|D ]}|j| jkr0|} nq$|du rAt d| d| j d|j| jkr[t d| d| j d| j d|j d	|jd	krmtd| d
| j d |jdkrtd| d| j d |S )zbReturn the mapped model ID to use for the request.

        Usually not overwritten in subclasses.Nz+Please provide an HF model ID supported by .zModel z is not supported by provider z is not supported for task z and provider z. Supported task: Zstagingz! is in staging mode for provider z. Meant for test purposes only.errorz,Our latest automated health check on model 'z' for provider 'z<' did not complete successfully.  Inference call might fail.)	r    r%   r   get!_fetch_inference_provider_mappingr'   statusloggerwarning)r(   r.   provider_mappingmappingr   r   r   r5      s6   

z(TaskProviderHelper._prepare_mapping_infor=   r3   c                 C   sT   dd |  D }|ddu r(|dur |jdur |j|d< |S |dur(d|d< |S )zzNormalize the headers to use for the request.

        Override this method in subclasses for customized headers.
        c                 S   s"   i | ]\}}|d ur|  |qS r   )lowerr   keyvaluer   r   r   
<dictcomp>   s   " z9TaskProviderHelper._normalize_headers.<locals>.<dictcomp>zcontent-typeNzapplication/json)r   rF   Z	mime_type)r(   r-   r=   r3   r>   r   r   r   r<      s   
z%TaskProviderHelper._normalize_headersc                 C   s   i t |d|S )zwReturn the headers to use for the request.

        Override this method in subclasses for customized headers.
        )token)r   )r(   r-   r/   r   r   r   r6      s   z#TaskProviderHelper._prepare_headersmapped_modelc                 C   s0   |  |}| ||}|d d|d S )zVReturn the URL to use for the request.

        Usually not overwritten in subclasses./)_prepare_base_url_prepare_routerstriplstrip)r(   r/   rS   r&   Zrouter   r   r   r7      s   
zTaskProviderHelper._prepare_urlc                 C   sH   | drtd| j d tjj| jdS td| j d | jS )[Return the base URL to use for the request.

        Usually not overwritten in subclasses.hf_z	Calling 'z'' provider through Hugging Face router.)r%   z' provider directly.)
startswithrI   infor%   r   ZINFERENCE_PROXY_TEMPLATEformatr&   rC   r   r   r   rU      s
   
z$TaskProviderHelper._prepare_base_urlc                 C      dS )ztReturn the route to use for the request.

        Override this method in subclasses for customized routes.
         r   r(   rS   r/   r   r   r   rV      s   z!TaskProviderHelper._prepare_router0   c                 C   r^   )zReturn the payload to use for the request, as a dict.

        Override this method in subclasses for customized payloads.
        Only one of `_prepare_payload_as_dict` and `_prepare_payload_as_bytes` should return a value.
        Nr   r(   r+   r,   r0   r   r   r   r9      s   z+TaskProviderHelper._prepare_payload_as_dictc                 C   r^   )zReturn the body to use for the request, as bytes.

        Override this method in subclasses for customized body data.
        Only one of `_prepare_payload_as_dict` and `_prepare_payload_as_bytes` should return a value.
        Nr   )r(   r+   r,   r0   r*   r   r   r   r;      s   z,TaskProviderHelper._prepare_payload_as_bytesr   )__name__
__module____qualname____doc__strr)   r   r   r   r
   r?   r   bytesrB   r4   r   r5   r	   r<   r6   r7   rU   rV   r9   r;   r   r   r   r   r$   E   s|    
	
8

%




r$   c                	       sj   e Zd ZdZdedef fddZdededefd	d
Zdeee	e
f  de	dedee	 fddZ  ZS )BaseConversationalTaskz
    Base class for conversational (chat completion) tasks.
    The schema follows the OpenAI API format defined here: https://platform.openai.com/docs/api-reference/chat
    r%   r&   c                       t  j||dd d S )Nconversationalr%   r&   r'   superr)   r(   r%   r&   	__class__r   r   r)        zBaseConversationalTask.__init__rS   r/   r   c                 C   r^   )Nz/v1/chat/completionsr   r`   r   r   r   rV     r   z%BaseConversationalTask._prepare_router+   r,   r0   c                 C      t d|i|d|jiS )Nmessagesr.   r   r8   ra   r   r   r   r9     s   z/BaseConversationalTask._prepare_payload_as_dict)rb   rc   rd   re   rf   r)   rV   r   r   r   r   r   r   r9   __classcell__r   r   ro   r   rh     s    rh   c                       sH   e Zd ZdZ fddZdedefddZdee defd	d
Z	  Z
S )AutoRouterConversationalTaska  
    Auto-router for conversational tasks.

    We let the Hugging Face router select the best provider for the model, based on availability and user preferences.
    This is a special case since the selection is done server-side (avoid 1 API call to fetch provider mapping).
    c                    s   t  jddd d S )Nautozhttps://router.huggingface.co)r%   r&   rl   )r(   ro   r   r   r)   %  s   z%AutoRouterConversationalTask.__init__r/   r   c                 C   s   | ds	td| jS )rY   rZ   z>Cannot select auto-router when using non-Hugging Face API key.)r[   r    r&   rC   r   r   r   rU   (  s   
z.AutoRouterConversationalTask._prepare_base_urlr.   c                 C   s"   |du rt dtd||dddS )z
        In auto-router, we don't need to fetch provider mapping info.
        We just return a dummy mapping info with provider_id set to the HF model ID.
        NzPlease provide an HF model ID.rw   liverj   )r%   Zhf_model_idZ
providerIdrH   r'   )r    r   )r(   r.   r   r   r   r5   2  s   z2AutoRouterConversationalTask._prepare_mapping_info)rb   rc   rd   re   r)   rf   rU   r   r   r5   ru   r   r   ro   r   rv     s
    
rv   c                	       s^   e Zd ZdZdedef fddZdededefd	d
Zdedede	de
e fddZ  ZS )BaseTextGenerationTaskz
    Base class for text-generation (completion) tasks.
    The schema follows the OpenAI API format defined here: https://platform.openai.com/docs/api-reference/completions
    r%   r&   c                    ri   )Nztext-generationrk   rl   rn   ro   r   r   r)   I  rq   zBaseTextGenerationTask.__init__rS   r/   r   c                 C   r^   )Nz/v1/completionsr   r`   r   r   r   rV   L  r   z%BaseTextGenerationTask._prepare_router+   r,   r0   c                 C   rr   )Npromptr.   rt   ra   r   r   r   r9   O  s   z/BaseTextGenerationTask._prepare_payload_as_dict)rb   rc   rd   re   rf   r)   rV   r   r   r   r   r9   ru   r   r   ro   r   ry   C  s    ry   N)maxsizer.   r   c                 C   s>   ddl m} | j| dgd}|j}|du rtd|  |S )z;
    Fetch provider mappings for a model from the Hub.
    r   )HfApiZinferenceProviderMapping)expandNz$No provider mapping found for model )huggingface_hub.hf_apir|   Z
model_infoZinference_provider_mappingr    )r.   r|   r\   rK   r   r   r   rG   U  s   rG   dict1dict2c                    s   i   fdd|  D S )Nc                    sD   i | ]\}}|| v rt  | trt |trt | |n|qS r   )r   r   r:   rN   r   r   r   rQ   f  s     z#recursive_merge.<locals>.<dictcomp>)r   )r   r   r   r   r   r:   c  s   
r:   )#	functoolsr   typingr   r   r   r   Zhuggingface_hubr   r~   r   Z!huggingface_hub.inference._commonr	   r
   Z:huggingface_hub.inference._generated.types.chat_completionr   Zhuggingface_hub.utilsr   r   r   Z
get_loggerrb   rI   r   r   rf   __annotations__r   r   r$   rh   rv   ry   rG   r:   r   r   r   r   <module>   st    
	
$: D&