
    7|h8                       d Z ddlmZ ddlZddlZddlZddlmZmZ ddl	m
Z
mZmZmZmZmZmZmZ ddlmZ ddlZddlmZ ddlmZmZ dd	lmZmZ dd
l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*m+Z+m,Z, ddl-m.Z.m/Z/ e
rddl0m1Z1m2Z2m3Z3m4Z4 ddl5m6Z6  ejn                  e8      Z9e G d d             Z:ddZ;ddZ<	 	 	 	 	 	 d dZ=d!dZ>d"dZ? eddd       G d de*e             Z@y)#z1Wrapper around Google VertexAI chat-based models.    )annotationsN)	dataclassfield)TYPE_CHECKINGAnyDictIteratorListOptionalUnioncast)urlparse)
deprecated)AsyncCallbackManagerForLLMRunCallbackManagerForLLMRun)BaseChatModelgenerate_from_stream)	AIMessageAIMessageChunkBaseMessageHumanMessageSystemMessage)ChatGenerationChatGenerationChunk
ChatResult)pre_init)_VertexAICommonis_codey_modelis_gemini_model)load_image_from_gcsraise_vertex_import_error)ChatMessageChatSessionCodeChatSessionInputOutputTextPair)Contentc                  <    e Zd ZU dZ ee      Zded<   dZded<   y)_ChatHistoryz/Represents a context and a history of messages.)default_factoryzList['ChatMessage']historyNOptional[str]context)	__name__
__module____qualname____doc__r   listr*   __annotations__r,        g/var/www/html/test/engine/venv/lib/python3.12/site-packages/langchain_community/chat_models/vertexai.pyr(   r(   6   s    9#(#>G >!G]!r4   r(   c                   ddl m} g d}}t        |       D ]  \  }}t        t        |j
                        }|dk(  rt        |t              r|}8t        |t              r& ||j
                  d      }|j                  |       nt        |t              r& ||j
                  d      }|j                  |       t        dt        |       d| d	       t        ||
      }|S )a  Parse a sequence of messages into history.

    Args:
        history: The list of messages to re-create the history of the chat.
    Returns:
        A parsed chat history.
    Raises:
        ValueError: If a sequence of message has a SystemMessage not at the
        first place.
    r   )r"   Nbot)contentauthoruserUnexpected message with type  at the position .)r,   r*   )vertexai.language_modelsr"   	enumerater   strr8   
isinstancer   r   appendr   
ValueErrortyper(   )	r*   r"   vertex_messagesr,   imessager8   vertex_messagechat_historys	            r5   _parse_chat_historyrJ   >   s     5!4WO( 
7sGOO,6j-8G+(ON"">2.(PN"">2/W>OPQsRST   ILr4   c                    	 t        |       }t        |j                  |j                  g      S # t        $ r"}t
        j                  d|        Y d }~yd }~ww xY w)NzUnable to parse URL: F)r   allschemenetloc	Exceptionloggerdebug)sresultes      r5   _is_urlrU   ^   sO    !FMM6==122 ,QC01s   +. 	AAAc                   ddl m}mm dfd}g }t	        |       D ]  \  }}|dk(  rt        |t              rt        d      t        |t              rd}n.t        |t              rd}nt        dt        |       d| d	      |j                  }t        |t              r|g}|D 	cg c]
  }	 ||	       }
}	 |||

      }|j                  |        |S c c}	w )Nr   )r&   ImagePartc                   t        | t              rj                  |       S t        | t              st	        dt        |        d      | d   dk(  rj                  | d         S | d   dk(  r| d   d   }|j                  d      rt        |      }n|j                  d	      rZt        j                  d
|      }|r|j                  d      }nt	        d      j                  t        j                  |            }nit        |      rAt        j                   |      }|j#                          j                  |j$                        }nj'                  |      }nt	        d      j)                  |      S )Nz0Message's content is expected to be a dict, got !rD   text	image_urlurlzgs://)pathprojectzdata:image/zdata:image/\w{2,4};base64,(.*)   zdInvalid image uri. It should be in the format data:image/<image_type>;base64,<base64_encoded_image>.z,Only text and image_url types are supported!)rA   r@   	from_textr   rC   rD   
startswithr    researchgroup
from_bytesbase64	b64decoderU   requestsgetraise_for_statusr8   load_from_file
from_image)partr^   imageencodedresponserW   rX   r_   s        r5   _convert_to_promptz6_parse_chat_history_gemini.<locals>._convert_to_promptl   sW   dC >>$''$%B4:,aP  <6!>>$v,//&\[($U+Dw'+wG/!yy)JDQ%mmA.G$Q  (()9)9')BC#<<-))+(()9)9:,,T2KLLu%%r4   z%SystemMessages are not yet supported!modelr:   r;   r<   r=   )roleparts)rn   zUnion[str, Dict]returnrX   )"vertexai.preview.generative_modelsr&   rW   rX   r?   rA   r   rC   r   r   rD   r8   r@   rB   )r*   r_   r&   rr   rE   rF   rG   rt   raw_contentrn   ru   rH   rW   rX   s    `          @@r5   _parse_chat_history_geminiry   g   s     HG!&F O( /
76j-8DEE+D.D/W>OPQsRST  ook3'&-K6ABd#D)BB d%8~.#/$  Cs   -Cc                   ddl m} t        |       dz  dk7  rt        dt        |        d      g }d }t	        |       D ]  \  }}|dz  dk(  r7t        |t              st        dt        |       d| d      |j                  }|dz  d	k(  sNt        |t              st        d
t        |       d| d       |||j                        }|j                  |        |S )Nr   )r%      z8Expect examples to have an even amount of messages, got r=   z;Expected the first message in a part to be from human, got z	 for the zth message.r`   z9Expected the second message in a part to be from AI, got )
input_textoutput_text)r>   r%   lenrC   r?   rA   r   rD   r8   r   rB   )examplesr%   example_pairsr|   rF   examplepairs          r5   _parse_examplesr      s   <
8}qAFs8}oUVW
 	
 MJ) '
7q5A:g|4 QG}oYqc>  !Jq5A:gy1 OG}oYqc>  '%7??D   &#'$ r4   c                |    | st        d      | d   }t        |t              st        d|j                   d      |S )zMGet the human message at the end of a list of input messages to a chat model.z:You should provide at least one message to start the chat!z3Last message in the list should be from human, got r=   )rC   rA   r   rD   )messagesquestions     r5   _get_questionr      sI    UVV|Hh-A(--PQR
 	
 Or4   z0.0.12z1.0z&langchain_google_vertexai.ChatVertexAI)sinceremovalalternative_importc                      e Zd ZU dZdZded<   	 dZded<   edd       Zedd	       Z	e
dd
       Z	 	 	 d	 	 	 	 	 	 	 	 	 	 	 ddZ	 	 d	 	 	 	 	 	 	 	 	 ddZ	 	 d	 	 	 	 	 	 	 	 	 ddZ	 	 	 	 	 	 ddZy)ChatVertexAIz+`Vertex AI` Chat large language models API.z
chat-bisonr@   
model_nameNzOptional[List[BaseMessage]]r   c                     y)NTr3   )selfs    r5   is_lc_serializablezChatVertexAI.is_lc_serializable   s    r4   c                
    g dS )z*Get the namespace of the langchain object.)	langchainchat_modelsvertexair3   )clss    r5   get_lc_namespacezChatVertexAI.get_lc_namespace   s
     87r4   c                   t        |d         }| j                  |       	 ddlm}m} |rddlm} |r |d         |d<   |S t        |d         r}n}|j                  |d         |d<   |S # t        $ r t                Y Tw xY w)z7Validate that the python package exists in environment.r   r   )	ChatModelCodeChatModel)GenerativeModel)r   client)r   _try_init_vertexair>   r   r   rw   r   ImportErrorr!   r   from_pretrained)r   values	is_geminir   r   r   	model_clss          r5   validate_environmentz!ChatVertexAI.validate_environment   s     $F<$89	v&	(I
 .&:NOF8  f\23)	%	(889MNF8  	(%'	(s   A0 0BBc                   ||n| j                   }|r! | j                  |f||d|}t        |      S t        |      } | j                  d|dd|}	i }
d|	v r|	j                  d      |
d<   | j                  rWt        || j                        }|j                         }| j                  j                  |      }|j                  ||	      }nmt        |dd	       }|j                  d
      xs | j                  }|rt        |      |	d
<    | j                   |fi |	} |j                  |j"                  fi |
}|j$                  D cg c]"  }t'        t)        |j*                              $ }}t-        |      S c c}w )a>  Generate next turn in the conversation.

        Args:
            messages: The history of the conversation as a list of messages. Code chat
                does not support context.
            stop: The list of stop words (optional).
            run_manager: The CallbackManager for LLM run, it's not used at the moment.
            stream: Whether to use the streaming endpoint.

        Returns:
            The ChatResult that contains outputs generated by the model.

        Raises:
            ValueError: if the last message in the list is not from human.
        N)stoprun_managerFr   streamcandidate_countr_   r*   generation_configr   r   r8   rG   generationsr3   )	streaming_streamr   r   _prepare_paramspop_is_gemini_modelry   r_   r   
start_chatsend_messagerJ   rj   r   r   _start_chatr8   
candidatesr   r   r[   r   )r   r   r   r   r   kwargsshould_streamstream_iterr   params
msg_paramshistory_geminirG   chatrq   r*   r   rr   s                      r5   	_generatezChatVertexAI._generate   s   . #)"4$..&$,,#@FK (44 *%%%H4HH
&,2JJ7H,IJ()  7$,,WN$((*G;;)).)AD((F(KH)(3B-8Gzz*->H%4X%>z"#4##G6v6D(t(()9)9HZHH ((
 9QVV#<=
 
 k22	
s   'Fc                  K   d|v r&|j                  d       t        j                  d        | j                  dd|i|}i }d|v r|j                  d      |d<   | j                  r_t        || j                        }|j                         }| j                  j                  |      }	|	j                  ||       d{   }
nst        |      }t        |dd	       }|j                  d
d      }|rt        |      |d
<    | j                  |fi |}	 |	j                  |j                  fi | d{   }
|
j                   D cg c]"  }t#        t%        |j&                              $ }}t)        |      S 7 7 Ic c}w w)a  Asynchronously generate next turn in the conversation.

        Args:
            messages: The history of the conversation as a list of messages. Code chat
                does not support context.
            stop: The list of stop words (optional).
            run_manager: The CallbackManager for LLM run, it's not used at the moment.

        Returns:
            The ChatResult that contains outputs generated by the model.

        Raises:
            ValueError: if the last message in the list is not from human.
        r   z8ChatVertexAI does not currently support async streaming.r   r   r   r   r   Nr   r   r   r   r   r3   )r   rP   warningr   r   ry   r_   r   r   send_message_asyncr   rJ   rj   r   r   r8   r   r   r   r[   r   )r   r   r   r   r   r   r   r   rG   r   rq   r   r*   r   r   r   s                   r5   
_ageneratezChatVertexAI._agenerate2  s    * vJJx NNUV%%%:4:6:
&,2JJ7H,IJ()  7$,,WN$((*G;;)).)AD!44WPV4WWH$X.H)(3B-8Gzz*d3H%4X%>z"#4##G6v6D4T44X5E5ETTTH ((
 9QVV#<=
 
 k22 X U
s7   B>F E<A3F4E>5F'F .F>F Fc              +  h  K    | j                   d|dd|}| j                  rXt        || j                        }|j	                         }| j
                  j                  |      }|j                  |d|      }	nkt        |      }
t        |d d       }|j                  dd       }|rt        |      |d<    | j                  |fi |} |j                  |
j                  fi |}	|	D ]E  }t        t!        |j"                        	      }|r|j%                  |j"                  |
       | G y w)NTr   r   r   )r   r   r   r   r   r   )chunkr3   )r   r   ry   r_   r   r   r   r   r   rJ   rj   r   r   send_message_streamingr8   r   r   r[   on_llm_new_token)r   r   r   r   r   r   r   rG   r   	responsesr   r*   r   rq   r   s                  r5   r   zChatVertexAI._streamd  s1     &%%G4GG  7$,,WN$((*G;;)).)AD)) * I %X.H)(3B-8Gzz*d3H%4X%>z"#4##G6v6D333H4D4DOOI! 	H'x}}0UVE,,X]]%,HK		s   D0D2c                    | j                   s3 | j                  j                  d|j                  |j                  d|S  | j                  j                  dd|j                  i|S )N)r,   message_historyr   r3   )r   r   r   r,   r*   )r   r*   r   s      r5   r   zChatVertexAI._start_chat  se     "")4;;)) LR  *4;;))T'//TVTTr4   )rv   bool)rv   z	List[str])r   r   rv   r   )NNN)r   List[BaseMessage]r   Optional[List[str]]r   "Optional[CallbackManagerForLLMRun]r   zOptional[bool]r   r   rv   r   )NN)
r   r   r   r   r   z'Optional[AsyncCallbackManagerForLLMRun]r   r   rv   r   )
r   r   r   r   r   r   r   r   rv   zIterator[ChatGenerationChunk])r*   r(   r   r   rv   z#Union[ChatSession, CodeChatSession])r-   r.   r/   r0   r   r2   r   classmethodr   r   r   r   r   r   r   r   r3   r4   r5   r   r      s@    6"J",0H)0  8 8  4 %):>!%43#43 "43 8	43
 43 43 
43r %)?C	03#03 "03 =	03
 03 
03j %):>	# " 8	
  
':U#U/2U	,Ur4   r   )r*   r   rv   r(   )rR   r@   rv   r   )r*   r   r_   r+   rv   zList['Content'])r   r   rv   zList['InputOutputTextPair'])r   r   rv   r   )Ar0   
__future__r   rg   loggingrc   dataclassesr   r   typingr   r   r   r	   r
   r   r   r   urllib.parser   ri   langchain_core._api.deprecationr   langchain_core.callbacksr   r   *langchain_core.language_models.chat_modelsr   r   langchain_core.messagesr   r   r   r   r   langchain_core.outputsr   r   r   langchain_core.utilsr   !langchain_community.llms.vertexair   r   r   &langchain_community.utilities.vertexair    r!   r>   r"   r#   r$   r%   rw   r&   	getLoggerr-   rP   r(   rJ   rU   ry   r   r   r   r3   r4   r5   <module>r      s    7 "   	 ( R R R !  6  S R ) 

   ;			8	$ " " "@;;)6;;|<	 
?
uU?M uU
uUr4   