
    7|hH                    .   d Z ddlmZ ddlZddlZddlmZmZmZm	Z	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 dd	lmZmZmZmZmZ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.m/Z/ ddl0m1Z1 ddl2m3Z3m4Z4m5Z5m6Z6 erddl7m8Z8 ddl9m:Z:  ejv                  e<      Z=dZ>dZ?dZ@ G d deA      ZB	 	 	 	 	 	 d!dZC	 	 	 	 	 	 d"dZD	 	 	 	 	 	 d#dZE	 d$	 	 	 	 	 d%dZF G d dee3      ZGddd	 	 	 	 	 	 	 d&dZH	 	 d'	 	 	 	 	 	 	 	 	 	 	 	 	 d(d ZIy))zWrapper around Prem's Chat API.    )annotationsN)TYPE_CHECKINGAnyCallableDictIteratorListOptionalSequenceTupleTypeUnion)CallbackManagerForLLMRun)LanguageModelInput)BaseChatModel)create_base_retry_decorator)	AIMessageAIMessageChunkBaseMessageBaseMessageChunkChatMessageChatMessageChunkHumanMessageHumanMessageChunkSystemMessageSystemMessageChunkToolMessage)ChatGenerationChatGenerationChunk
ChatResult)Runnable)BaseTool)get_from_dict_or_envpre_init)convert_to_openai_tool)	BaseModel
ConfigDictField	SecretStr)ChatCompletionResponseStream)ChatCompletionResponsezM
Given the set of tools you used and the response, provide the final answer

z
{json}
z3
tool id: {tool_id}
tool_response: {tool_response}
c                      e Zd ZdZy)ChatPremAPIErrorzError with the `PremAI` API.N)__name__
__module____qualname____doc__     e/var/www/html/test/engine/venv/lib/python3.12/site-packages/langchain_community/chat_models/premai.pyr-   r-   J   s    &r3   r-   c                T    || S |D ]  }| j                  |      }|dk7  s| d| }   | S )z0Truncates text at the earliest stop token found.N)find)textstop
stop_tokenstop_token_idxs       r4   _truncate_at_stop_tokensr<   N   sF    
 | )
:.R(D) Kr3   c           
     2   | j                   st        d      g }| j                   D ]  }|j                  j                  }|t        d| d      t	        |j                  j
                  xs d|      }|t        d|       |dk(  r^|j                  d	   }|g }n"|D cg c]  }|d
   |d   d   |d   d   d }}|j                  t        |t        ||                   |dk(  r'|j                  t        |t        |                   |j                  t        |t        ||                    | j                  5t        |d| j                  D 	cg c]  }	|	j                          c}	i      S t        |ddi      S c c}w c c}	w )z4Converts a Prem API response into a LangChain resultz-ChatResponse must have at least one candidateNzChatResponse z must have a role. )r8   r9   z"ChatResponse must have a content: 	assistant
tool_callsidfunctionname	arguments)rA   rC   args)contentr@   )r8   messageuserrF   rolerF   document_chunks)generations
llm_output)choicesr-   rG   rK   r<   rF   appendr   r   r   r   rL   r    to_dict)
responser9   rM   choicerK   rF   r@   tools	tool_callchunks
             r4   _response_to_resultrW   ]   s    NOO(*K"" %~~""<"]6(:L#MNN +0F0F0L"SWX?"%Gy#QRR;5J! &0 "	 (o )* 5f = )* 5k B   )GPU*V
 V^G\'5RS  +4*QC%N +#!191I1I$(-EMMO$
 	
 k?PRV>WXXE8$s   #F Fc                   | j                   d   j                  }|j                  dd      }|j                  dd      }i }| j                   d   j                  }|dk(  s	|t        k(  rt	        |      |fS |dk(  s	|t
        k(  rt        ||      |fS |d	k(  s	|t        k(  rt        |      |fS |s	|t        k(  rt        ||
      |fS  ||      |fS )z(Converts delta response to message chunkr   rK   r>   rF   rH   rI   r?   )rF   additional_kwargssystem)rF   rK   )rO   deltagetfinish_reasonr   r   r   r   )rR   default_class_deltarK   rF   rY   finish_reasonss          r4   (_convert_delta_response_to_message_chunkra      s     a &&F::fb!DjjB'G $,$4$4Q$7$E$ENv~*;; 1>AA		 ?7>OP
 	
 
	].@@!'2NBB	"22d;^KKW-~==r3   c                D   d}g }| D ]  }t        |t              rt        |j                        }*t        |t              r|(|j                  dt        |j                        d       di }|j                  |j                  dk7  sJ t        dd             t        |j                        |t        |j                        <   |j                  d||d       t        |t              r|j                  t        |j                        dk(  r)|j                  d	t        |j                        d       0|j                  |j                  |j                  |j                  d
}|j                  d	t        j                  |      d       t        |t              rt        d       d}| D ]E  }t        |t              s|j                   }|j                  }	|t"        j                  ||	      z  }G |dk7  rt$        }
|
|z  }
|j                  d|
d       ||fS )zcConverts a list of LangChain Messages into a simple dict
    which is the message structure in PremNrH   rJ   r>   z9When using prompt template there should be id associated zwith each HumanMessage)rK   template_idparamsr   r?   )rA   rF   response_metadatar@   )jsonzNo such role explicitly exists)tool_idtool_response)
isinstancer   strrF   r   rP   rA   
ValueErrorr   r@   lenre   !INTERMEDIATE_TOOL_RESULT_TEMPLATEformatr   r-   tool_call_idSINGLE_TOOL_PROMPT_TEMPLATETOOL_PROMPT_HEADER)input_messagesrc   system_promptexamples_and_messages	input_msgrd   ai_msg_to_jsontool_promptrg   tool_resultprompts              r4   _messages_to_prompt_dictrz      s8    $(M24# 5E	i/	 1 12M	<0"%,, &#&y'8'8#9 *,!0y||r7I JO,M J -0	0A0A,Bs9<<()%,, &'2"( 	9-##+s93G3G/HA/M%,, +#&y'8'8#9 $,,(00)2)D)D"+"6"6	" &,, +#D#K#K!/ $L $ 	;/ ##CDDk5Ep K# 	i-,,G#++K6=={ >  K	 b#+$$f%HI///r3   c                      e Zd ZU dZded<   	  edd      Zded<   	  edd	      Zd
ed<   	 dZd
ed<   	  ed      Z	ded<   	 dZ
ded<   	  ed      Zded<   	  ed      Zded<   	 dZd
ed<   	 dZded<   	 dZded<   	 dZded<    eddd       Zed(d!       Zed)d"       Zed*d#       Zd+d$Z	 	 d,	 	 	 	 	 	 	 	 	 d-d%Z	 	 d,	 	 	 	 	 	 	 	 	 d.d&Z	 	 	 	 	 	 d/ fd'Z xZS )0
ChatPremAIzPremAI Chat models.

    To use, you will need to have an API key. You can find your existing API Key
    or generate a new one here: https://app.premai.io/api_keys/
    int
project_idNapi_key)defaultaliaszOptional[SecretStr]premai_api_key
model_nameOptional[str]model
session_id)r   zOptional[float]temperaturetop_pzOptional[int]
max_tokens   max_retriesr>   rs   zOptional[dict]repositoriesFOptional[bool]	streamingr   clientTforbid)populate_by_namearbitrary_types_allowedextrac                    	 ddl m} 	 t        |dd      } |t	        |t
              r|n|j                        |d<   |S # t        $ r}t        d      |d}~ww xY w# t        $ r}t        d	      |d}~ww xY w)
zFValidate that the package is installed and that the API token is validr   )PremzQCould not import Prem Python package.Please install it with: `pip install premai`Nr   PREMAI_API_KEY)r   r   z,Your API Key is incorrect. Please try again.)	premair   ImportErrorr#   ri   rj   _secret_value	Exceptionrk   )clsvaluesr   errorr   s        r4   validate_environmentsz ChatPremAI.validate_environmentsF  s    	#
	X4H(*:5N  $nc2 '#11 F8 #  	? 	  	XKLRWW	Xs.   A  5A  	A	AA	A7&A22A7c                     y)Nr   r2   selfs    r4   	_llm_typezChatPremAI._llm_type^  s    r3   c                v    | j                   | j                  | j                  | j                  | j                  dS )Nr   rs   r   r   r   r   r   s    r4   _default_paramszChatPremAI._default_paramsb  s7     ZZ!//++// --
 	
r3   c                   g d}g }|D ]1  }||v st        j                  d| d       |j                  |       3 |D ]  }|j                  |        i | j                  |}t        | j                  j                               D ]:  }|j                  |      |j                  |      dk(  s)|j                  |d        < |S )N)r   frequency_penaltypresence_penalty
logit_biasr9   seedzWARNING: Parameter z is not supported in kwargs.r>   )warningswarnrP   popr   listkeysr\   )r   kwargskwargs_to_ignorekeys_to_removekey
all_kwargss         r4   _get_all_kwargszChatPremAI._get_all_kwargsl  s    
  	+C&& 3C58TUV%%c*	+
 " 	CJJsO	 8,,77
,,1134 	*C~~c"*jnnS.AR.GsD)	* r3   c                    d|v rt        ||d         \  }}nt        |      \  }}|
|dk7  r||d<    | j                  di |}t        | f| j                  |d|d|}t	        ||      S )	Nrc   rc   r>   rs   Fr~   messagesstreamrun_manager)rR   r9   r2   )rz   r   chat_with_retryr~   rW   )	r   r   r9   r   r   rs   messages_to_passr   rR   s	            r4   	_generatezChatPremAI._generate  s     F".Ff]&;/+M+ /Gx.P+M+$")<&3F?#)T))3F3
"
%#
 
 #H4@@r3   c              +    K   d|v rt        ||d         \  }}nt        |      \  }}|t        j                  d       d|vr|
|dk7  r||d<    | j                  di |}t        }t        | f| j                  |d|d|D ]S  }		 t        |	|      \  }
}|t        |	      nd }t        |
|
      }|r|j                  |j                  |       | U y # t        $ r
}Y d }~ed }~ww xY ww)Nrc   r   z,stop is not supported in langchain streamingrs   r>   Tr   )rR   r^   )r]   )rG   generation_info)rV   r2   )rz   loggerwarningr   r   r   r~   ra   dictr   on_llm_new_tokenr8   r   )r   r   r9   r   r   rs   r   r   default_chunk_classstreamed_responserV   r]   r   cg_chunk_s                  r4   _streamzChatPremAI._stream  s;     F".Ff]&;/+M+ /Gx.P+M+NNIJ&((]b-@*7')T))3F3
,!0"
%#"
 "
 	'O.>Q($}
 %0 }5  
 /!? 00h0O-	.  s+   BC0ACC0	C-#C0(C--C0c                `    |D cg c]  }t        |       }}t        |   dd|i|S c c}w )NrT   r2   )r%   superbind)r   rT   r   toolformatted_tools	__class__s        r4   
bind_toolszChatPremAI.bind_tools  s=    
 EJJD1$7JJw|</<V<< Ks   +)r   r   returnr   )r   rj   )r   Dict[str, Any])r   r   r   r   )NN)
r   List[BaseMessage]r9   Optional[List[str]]r   "Optional[CallbackManagerForLLMRun]r   r   r   r    )
r   r   r9   r   r   r   r   r   r   zIterator[ChatGenerationChunk])rT   zDSequence[Union[Dict[str, Any], Type[BaseModel], Callable, BaseTool]]r   r   r   z)Runnable[LanguageModelInput, BaseMessage])r.   r/   r0   r1   __annotations__r(   r   r   r   r   r   r   r   rs   r   r   r   r'   model_configr$   r   propertyr   r   r   r   r   r   __classcell__)r   s   @r4   r|   r|     s    OL*/I*NN'NG \BE=B/
 !%J$K#(#6K6<!E?! !&d 3J32Q'K'/#%M=% $(L.' !&I~%1FC $L  .   
 
8 %):>	A#A "A 8	A
 A 
A@ %):>	1#1 "1 8	1
 1 
'1f=S= = 
3	= =r3   r|   r   r   r   c                  ddl }|j                  j                  j                  |j                  j                  j
                  |j                  j                  j                  |j                  j                  j                  |j                  j                  j                  |j                  j                  j                  |j                  j                  j                  |j                  j                   j"                  |j                  j$                  j&                  |j                  j(                  j*                  |j                  j,                  j.                  |j                  j0                  j2                  g}t5        |||      }|S )z/Create a retry decorator for PremAI API errors.r   N)error_typesr   r   )premai.modelsmodelsapi_response_validation_errorAPIResponseValidationErrorconflict_errorConflictErrormodel_not_found_errorModelNotFoundErrorpermission_denied_errorPermissionDeniedErrorprovider_api_connection_errorProviderAPIConnectionErrorprovider_api_status_errorProviderAPIStatusErrorprovider_api_timeout_errorProviderAPITimeoutErrorprovider_internal_server_errorProviderInternalServerErrorprovider_not_found_errorProviderNotFoundErrorrate_limit_errorRateLimitErrorunprocessable_entity_errorUnprocessableEntityErrorvalidation_errorValidationErrorr   )llmr   r   r   errors	decorators         r4   create_prem_retry_decoratorr     s     	33NN$$22++>>--CC33NN//FF00HH44PP..DD&&5500II&&66F ,I r3   c                x     t          j                  |      }|	 d	 	 	 	 	 	 	 	 	 d fd       } |d|||d|S )z+Using tenacity for retry in completion callr   c                p     j                   j                  j                  j                  d| ||d|}|S )Nr~   r   r   r2   )r   chatcompletionscreate)r~   r   r   r   rR   r   s        r4   _completion_with_retryz/chat_with_retry.<locals>._completion_with_retry	  sD     63::??..55 
!
 	
 r3   r   )F)
r~   r}   r   
List[dict]r   r   r   r   r   r   r2   )r   r   )r   r~   r   r   r   r   retry_decoratorr  s   `       r4   r   r     s     2kO  "'  	
 
  "  	 r3   )r8   rj   r9   r   r   rj   )rR   r+   r9   r   r   r    )rR   r*   r^   zType[BaseMessageChunk]r   zdTuple[Union[BaseMessageChunk, HumanMessageChunk, AIMessageChunk, SystemMessageChunk], Optional[str]])N)rr   r   rc   r   r   z*Tuple[Optional[str], List[Dict[str, Any]]])r   r|   r   r}   r   z)Optional[Union[CallbackManagerForLLMRun]]r   zCallable[[Any], Any])FN)r   r|   r~   r}   r   r  r   boolr   r   r   r   r   r   )Jr1   
__future__r   loggingr   typingr   r   r   r   r   r	   r
   r   r   r   r   langchain_core.callbacksr   langchain_core.language_modelsr   *langchain_core.language_models.chat_modelsr   #langchain_core.language_models.llmsr   langchain_core.messagesr   r   r   r   r   r   r   r   r   r   r   langchain_core.outputsr   r   r    langchain_core.runnablesr!   langchain_core.toolsr"   langchain_core.utilsr#   r$   %langchain_core.utils.function_callingr%   pydanticr&   r'   r(   r)   6premai.api.chat_completions.v1_chat_completions_creater*   &premai.models.chat_completion_responser+   	getLoggerr.   r   rq   rm   rp   r   r-   r<   rW   ra   rz   r|   r   r   r2   r3   r4   <module>r     s   % "      > D K    S R - ) ? H   N			8	$ % ! 'y '

 	:Y$:Y
:Y :Yz>*>;Q>>< "&O0%O0O0 0O0dS=	 S=r =A		  ;	
 D 6:!	!! ! 	!
 4! ! 	!r3   