[docs]defget_ordered_generation_requests(models_priority_list:List[GPTRouterModel],**kwargs:Any)->List:""" Return the body for the model router input. """fromgpt_router.modelsimportGenerationParams,ModelGenerationRequestreturn[ModelGenerationRequest(model_name=model.name,provider_name=model.provider_name,order=index+1,prompt_params=GenerationParams(**kwargs),)forindex,modelinenumerate(models_priority_list)]
[docs]defcompletion_with_retry(llm:GPTRouter,models_priority_list:List[GPTRouterModel],run_manager:Optional[CallbackManagerForLLMRun]=None,**kwargs:Any,)->Union[GenerationResponse,Generator[ChunkedGenerationResponse,None,None]]:"""Use tenacity to retry the completion call."""retry_decorator=_create_retry_decorator(llm,run_manager=run_manager)@retry_decoratordef_completion_with_retry(**kwargs:Any)->Any:ordered_generation_requests=get_ordered_generation_requests(models_priority_list,**kwargs)returnllm.client.generate(ordered_generation_requests=ordered_generation_requests,is_stream=kwargs.get("stream",False),)return_completion_with_retry(**kwargs)
[docs]asyncdefacompletion_with_retry(llm:GPTRouter,models_priority_list:List[GPTRouterModel],run_manager:Optional[AsyncCallbackManagerForLLMRun]=None,**kwargs:Any,)->Union[GenerationResponse,AsyncGenerator[ChunkedGenerationResponse,None]]:"""Use tenacity to retry the async completion call."""retry_decorator=_create_retry_decorator(llm,run_manager=run_manager)@retry_decoratorasyncdef_completion_with_retry(**kwargs:Any)->Any:ordered_generation_requests=get_ordered_generation_requests(models_priority_list,**kwargs)returnawaitllm.client.agenerate(ordered_generation_requests=ordered_generation_requests,is_stream=kwargs.get("stream",False),)returnawait_completion_with_retry(**kwargs)
[docs]classGPTRouter(BaseChatModel):"""GPTRouter by Writesonic Inc. For more information, see https://gpt-router.writesonic.com/docs """client:Any=Field(default=None,exclude=True)#: :meta private:models_priority_list:List[GPTRouterModel]=Field(min_items=1)gpt_router_api_base:str=Field(default=None)"""WriteSonic GPTRouter custom endpoint"""gpt_router_api_key:Optional[SecretStr]=None"""WriteSonic GPTRouter API Key"""temperature:float=0.7"""What sampling temperature to use."""model_kwargs:Dict[str,Any]=Field(default_factory=dict)"""Holds any model parameters valid for `create` call not explicitly specified."""max_retries:int=4"""Maximum number of retries to make when generating."""streaming:bool=False"""Whether to stream the results or not."""n:int=1"""Number of chat completions to generate for each prompt."""max_tokens:int=256@root_validator(pre=True)defvalidate_environment(cls,values:Dict)->Dict:values["gpt_router_api_base"]=get_from_dict_or_env(values,"gpt_router_api_base","GPT_ROUTER_API_BASE",DEFAULT_API_BASE_URL,)values["gpt_router_api_key"]=convert_to_secret_str(get_from_dict_or_env(values,"gpt_router_api_key","GPT_ROUTER_API_KEY",))returnvalues@root_validator(pre=True,skip_on_failure=True)defpost_init(cls,values:Dict)->Dict:try:fromgpt_router.clientimportGPTRouterClientexceptImportError:raiseGPTRouterException("Could not import GPTRouter python package. ""Please install it with `pip install GPTRouter`.")gpt_router_client=GPTRouterClient(values["gpt_router_api_base"],values["gpt_router_api_key"].get_secret_value(),)values["client"]=gpt_router_clientreturnvalues@propertydeflc_secrets(self)->Dict[str,str]:return{"gpt_router_api_key":"GPT_ROUTER_API_KEY"}@propertydeflc_serializable(self)->bool:returnTrue@propertydef_llm_type(self)->str:"""Return type of chat model."""return"gpt-router-chat"@propertydef_identifying_params(self)->Dict[str,Any]:"""Get the identifying parameters."""return{**{"models_priority_list":self.models_priority_list},**self._default_params,}@propertydef_default_params(self)->Dict[str,Any]:"""Get the default parameters for calling GPTRouter API."""return{"max_tokens":self.max_tokens,"stream":self.streaming,"n":self.n,"temperature":self.temperature,**self.model_kwargs,}def_generate(self,messages:List[BaseMessage],stop:Optional[List[str]]=None,run_manager:Optional[CallbackManagerForLLMRun]=None,stream:Optional[bool]=None,**kwargs:Any,)->ChatResult:should_stream=streamifstreamisnotNoneelseself.streamingifshould_stream:stream_iter=self._stream(messages,stop=stop,run_manager=run_manager,**kwargs)returngenerate_from_stream(stream_iter)message_dicts,params=self._create_message_dicts(messages,stop)params={**params,**kwargs,"stream":False}response=completion_with_retry(self,messages=message_dicts,models_priority_list=self.models_priority_list,run_manager=run_manager,**params,)returnself._create_chat_result(response)asyncdef_agenerate(self,messages:List[BaseMessage],stop:Optional[List[str]]=None,run_manager:Optional[AsyncCallbackManagerForLLMRun]=None,stream:Optional[bool]=None,**kwargs:Any,)->ChatResult:should_stream=streamifstreamisnotNoneelseself.streamingifshould_stream:stream_iter=self._astream(messages,stop=stop,run_manager=run_manager,**kwargs)returnawaitagenerate_from_stream(stream_iter)message_dicts,params=self._create_message_dicts(messages,stop)params={**params,**kwargs,"stream":False}response=awaitacompletion_with_retry(self,messages=message_dicts,models_priority_list=self.models_priority_list,run_manager=run_manager,**params,)returnself._create_chat_result(response)def_create_chat_generation_chunk(self,data:Mapping[str,Any],default_chunk_class:Type[BaseMessageChunk])->Tuple[ChatGenerationChunk,Type[BaseMessageChunk]]:chunk=_convert_delta_to_message_chunk({"content":data.get("text","")},default_chunk_class)finish_reason=data.get("finish_reason")generation_info=(dict(finish_reason=finish_reason)iffinish_reasonisnotNoneelseNone)default_chunk_class=chunk.__class__gen_chunk=ChatGenerationChunk(message=chunk,generation_info=generation_info)returngen_chunk,default_chunk_classdef_stream(self,messages:List[BaseMessage],stop:Optional[List[str]]=None,run_manager:Optional[CallbackManagerForLLMRun]=None,**kwargs:Any,)->Iterator[ChatGenerationChunk]:message_dicts,params=self._create_message_dicts(messages,stop)params={**params,**kwargs,"stream":True}default_chunk_class:Type[BaseMessageChunk]=AIMessageChunkgenerator_response=completion_with_retry(self,messages=message_dicts,models_priority_list=self.models_priority_list,run_manager=run_manager,**params,)forchunkingenerator_response:ifchunk.event!="update":continuechunk,default_chunk_class=self._create_chat_generation_chunk(chunk.data,default_chunk_class)ifrun_manager:run_manager.on_llm_new_token(token=chunk.message.content,chunk=chunk.message)yieldchunkasyncdef_astream(self,messages:List[BaseMessage],stop:Optional[List[str]]=None,run_manager:Optional[AsyncCallbackManagerForLLMRun]=None,**kwargs:Any,)->AsyncIterator[ChatGenerationChunk]:message_dicts,params=self._create_message_dicts(messages,stop)params={**params,**kwargs,"stream":True}default_chunk_class:Type[BaseMessageChunk]=AIMessageChunkgenerator_response=acompletion_with_retry(self,messages=message_dicts,models_priority_list=self.models_priority_list,run_manager=run_manager,**params,)asyncforchunkinawaitgenerator_response:ifchunk.event!="update":continuechunk,default_chunk_class=self._create_chat_generation_chunk(chunk.data,default_chunk_class)ifrun_manager:awaitrun_manager.on_llm_new_token(token=chunk.message.content,chunk=chunk.message)yieldchunkdef_create_message_dicts(self,messages:List[BaseMessage],stop:Optional[List[str]])->Tuple[List[Dict[str,Any]],Dict[str,Any]]:params=self._default_paramsifstopisnotNone:if"stop"inparams:raiseValueError("`stop` found in both the input and default params.")params["stop"]=stopmessage_dicts=[convert_message_to_dict(m)forminmessages]returnmessage_dicts,paramsdef_create_chat_result(self,response:GenerationResponse)->ChatResult:generations=[]forresinresponse.choices:message=convert_dict_to_message({"role":"assistant","content":res.text,})gen=ChatGeneration(message=message,generation_info=dict(finish_reason=res.finish_reason),)generations.append(gen)llm_output={"token_usage":response.meta,"model":response.model}returnChatResult(generations=generations,llm_output=llm_output)