U
    hg*                     @   s^  d dl Z d dlmZ d dlmZ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mZmZmZ d dl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$ ee%dddZ&ee e%dddZ'e%edddZ(ee e	ee% ee f dddZ)G dd dZ*ddddddZ+edddd G d!d" d"ee!Z,dS )#    N)defaultdict)AnyDictIteratorListOptionalTupleUnion)
deprecated)CallbackManagerForLLMRun)BaseChatModel)	AIMessageAIMessageChunkBaseMessageChatMessageHumanMessageSystemMessage)ChatGenerationChatGenerationChunk
ChatResult)$convert_messages_to_prompt_anthropic) convert_messages_to_prompt_llama)BedrockBase)get_num_tokens_anthropicget_token_ids_anthropic)messagereturnc                 C   s~   t | tr$d| j  d| j }nVt | tr>d| j d}n<t | trR| j }n(t | trld| j d}ntd|  |S )Nz

z: z[INST] z [/INST]z<<SYS>> z	 <</SYS>>zGot unknown type )	
isinstancer   role
capitalizecontentr   r   r   
ValueError)r   Zmessage_text r"   K/tmp/pip-unpacked-wheel-9gdii04g/langchain_community/chat_models/bedrock.py$_convert_one_message_to_text_mistral   s    




r$   )messagesr   c                 C   s   d dd | D S )z3Convert a list of messages to a prompt for mistral.
c                 S   s   g | ]}t |qS r"   )r$   ).0r   r"   r"   r#   
<listcomp>0   s     z6convert_messages_to_prompt_mistral.<locals>.<listcomp>)joinr%   r"   r"   r#   "convert_messages_to_prompt_mistral-   s    r+   )	image_urlr   c                 C   s8   d}t || }|dkr tdd|d|ddS )a  
    Formats an image of format data:image/jpeg;base64,{b64_string}
    to a dict for anthropic api

    {
      "type": "base64",
      "media_type": "image/jpeg",
      "data": "/9j/4AAQSkZJRg...",
    }

    And throws an error if it's not a b64 image
    z3^data:(?P<media_type>image/.+);base64,(?P<data>.+)$NzgAnthropic only supports base64-encoded images currently. Example: data:image/png;base64,'/9j/4AAQSk'...base64
media_typedata)typer.   r/   )rematchr!   group)r,   regexr2   r"   r"   r#   _format_image4   s    r5   c           	      C   s>  d}g }t | D ]"\}}|jdkr\|dkr4tdt|jtsTtdt|j |j}qt|j }t|jtst|jtstdg }|jD ]}t|tr|	d|d qt|t
rd	|krtd
|d	 dkrt|d d }|	d|d n
|	| qtdt| qn|j}|	||d q||fS )zFormat messages for anthropic.Nsystemr   z4System message must be at beginning of message list.z.System message must be a string, instead was: z6Anthropic message content must be str or list of dictstext)r0   r7   r0   z&Dict content item must have a type keyr,   urlimage)r0   sourcez0Content items must be str or dict, instead was: )r   r    )	enumerater0   r!   r   r    str_message_type_lookupslistAssertionErrorappenddictr5   )	r%   r6   formatted_messagesir   r   r    itemr:   r"   r"   r#   _format_anthropic_messagesO   sb    

 

rE   c                   @   sT   e Zd ZdZeeee edddZeeee e	e
e ee f dddZdS )ChatPromptAdapterzeAdapter class to prepare the inputs from Langchain to prompt format
    that Chat model expects.
    )providerr%   r   c                 C   sh   |dkrt |d}nP|dkr(t|d}n<|dkr<t|d}n(|dkrTt |ddd}ntd	| d
|S )N	anthropicr*   metaZmistralZamazonz

User:z

Bot:)r%   Zhuman_promptZ	ai_prompt	Provider z model does not support chat.)r   r   r+   NotImplementedError)clsrG   r%   promptr"   r"   r#   convert_messages_to_prompt   s     
z,ChatPromptAdapter.convert_messages_to_promptc                 C   s$   |dkrt |S td| dd S )NrH   rJ   z" not supported for format_messages)rE   rK   )rL   rG   r%   r"   r"   r#   format_messages   s
    
z!ChatPromptAdapter.format_messagesN)__name__
__module____qualname____doc__classmethodr<   r   r   rN   r   r   r   rO   r"   r"   r"   r#   rF      s     rF   userZ	assistant)ZhumanZair   ZHumanMessageChunkfunctionz0.0.34z1.0zlangchain_aws.ChatBedrock)ZsinceZremovalZalternative_importc                       s  e Zd ZdZeedddZeedddZ	ee
e dddZeeeef dd	d
ZG dd dZde
e ee
e  ee eee dddZde
e ee
e  ee eedddZe
ee  edddZeed fddZee
e d fddZ  ZS )BedrockChatz%Chat model that uses the Bedrock API.)r   c                 C   s   dS )zReturn type of chat model.Zamazon_bedrock_chatr"   )selfr"   r"   r#   	_llm_type   s    zBedrockChat._llm_typec                 C   s   dS )z9Return whether this model can be serialized by Langchain.Tr"   rL   r"   r"   r#   is_lc_serializable   s    zBedrockChat.is_lc_serializablec                 C   s
   dddgS )z*Get the namespace of the langchain object.Z	langchainZchat_modelsZbedrockr"   rZ   r"   r"   r#   get_lc_namespace   s    zBedrockChat.get_lc_namespacec                 C   s   i }| j r| j |d< |S )Nregion_name)r]   )rX   
attributesr"   r"   r#   lc_attributes   s    
zBedrockChat.lc_attributesc                   @   s   e Zd ZdZdS )zBedrockChat.ConfigZforbidN)rP   rQ   rR   extrar"   r"   r"   r#   Config   s   ra   N)r%   stoprun_managerkwargsr   c                 k   sx   |   }d\}}}|dkr,t||\}}ntj||d}| jf |||||d|D ]}	|	j}
tt|
ddV  qVd S )NNNNrH   rG   r%   )rM   r6   r%   rb   rc   r    r   )_get_providerrF   rO   rN   Z _prepare_input_and_invoke_streamr7   r   r   )rX   r%   rb   rc   rd   rG   rM   r6   rB   chunkdeltar"   r"   r#   _stream   s,    
 
 
zBedrockChat._streamc                 K   s   d}d| j i}| jr8| j|||f|D ]}||j7 }q&nt|  }d\}	}
}|}|dkrjt||\}
}ntj||d}	|r||d< | jf |	|||
|d|\}}||d< t	t
t|d	d
g|dS )N model_idre   rH   rf   Zstop_sequences)rM   rb   rc   r6   r%   usagerg   rh   )Zgenerations
llm_output)rn   Z	streamingrl   r7   ri   rF   rO   rN   Z_prepare_input_and_invoker   r   r   )rX   r%   rb   rc   rd   
completionrp   rj   rG   rM   r6   rB   paramsZ
usage_infor"   r"   r#   	_generate  sB    

 
 
	zBedrockChat._generate)llm_outputsr   c                 C   sb   t t}i }|D ]D}|pi }|di }| D ]\}}||  |7  < q0|| q||d< |S )Nro   )r   intgetitemsupdate)rX   rt   Zfinal_usageZfinal_outputoutputro   
token_typeZtoken_countr"   r"   r#   _combine_llm_outputs9  s    z BedrockChat._combine_llm_outputs)r7   r   c                    s   | j rt|S t |S d S N)_model_is_anthropicr   superget_num_tokensrX   r7   	__class__r"   r#   r   E  s    zBedrockChat.get_num_tokensc                    s   | j rt|S t |S d S r|   )r}   r   r~   get_token_idsr   r   r"   r#   r   K  s    zBedrockChat.get_token_ids)NN)NN)rP   rQ   rR   rS   propertyr<   rY   rT   boolr[   r   r\   r   r   r_   ra   r   r   r   r   r   rl   r   rs   rA   r{   ru   r   r   __classcell__r"   r"   r   r#   rW      s>     
!  
.rW   )-r1   collectionsr   typingr   r   r   r   r   r   r	   Zlangchain_core._api.deprecationr
   Zlangchain_core.callbacksr   Z*langchain_core.language_models.chat_modelsr   Zlangchain_core.messagesr   r   r   r   r   r   Zlangchain_core.outputsr   r   r   Z)langchain_community.chat_models.anthropicr   Z$langchain_community.chat_models.metar   Z langchain_community.llms.bedrockr   Z'langchain_community.utilities.anthropicr   r   r<   r$   r+   r5   rE   rF   r=   rW   r"   r"   r"   r#   <module>   s<   $ M(	  