from__future__importannotationsimportloggingfromtypingimportAny,Callable,Dict,List,Optional,Sequencefromlangchain_core.callbacksimport(AsyncCallbackManagerForLLMRun,CallbackManagerForLLMRun,)fromlangchain_core.language_models.llmsimportLLMfromlangchain_core.load.serializableimportSerializablefromlangchain_core.pydantic_v1importSecretStrfromlangchain_core.utilsimportconvert_to_secret_str,get_from_dict_or_env,pre_initfromtenacityimport(before_sleep_log,retry,retry_if_exception_type,stop_after_attempt,wait_exponential,)fromlangchain_community.llms.utilsimportenforce_stop_tokenslogger=logging.getLogger(__name__)class_BaseYandexGPT(Serializable):iam_token:SecretStr=""# type: ignore[assignment]"""Yandex Cloud IAM token for service or user account with the `ai.languageModels.user` role"""api_key:SecretStr=""# type: ignore[assignment]"""Yandex Cloud Api Key for service account with the `ai.languageModels.user` role"""folder_id:str="""""Yandex Cloud folder ID"""model_uri:str="""""Model uri to use."""model_name:str="yandexgpt-lite""""Model name to use."""model_version:str="latest""""Model version to use."""temperature:float=0.6"""What sampling temperature to use. Should be a double number between 0 (inclusive) and 1 (inclusive)."""max_tokens:int=7400"""Sets the maximum limit on the total number of tokens used for both the input prompt and the generated response. Must be greater than zero and not exceed 7400 tokens."""stop:Optional[List[str]]=None"""Sequences when completion generation will stop."""url:str="llm.api.cloud.yandex.net:443""""The url of the API."""max_retries:int=6"""Maximum number of retries to make when generating."""sleep_interval:float=1.0"""Delay between API requests"""disable_request_logging:bool=False"""YandexGPT API logs all request data by default. If you provide personal data, confidential information, disable logging."""grpc_metadata:Optional[Sequence]=None@propertydef_llm_type(self)->str:return"yandex_gpt"@propertydef_identifying_params(self)->Dict[str,Any]:"""Get the identifying parameters."""return{"model_uri":self.model_uri,"temperature":self.temperature,"max_tokens":self.max_tokens,"stop":self.stop,"max_retries":self.max_retries,}@pre_initdefvalidate_environment(cls,values:Dict)->Dict:"""Validate that iam token exists in environment."""iam_token=convert_to_secret_str(get_from_dict_or_env(values,"iam_token","YC_IAM_TOKEN",""))values["iam_token"]=iam_tokenapi_key=convert_to_secret_str(get_from_dict_or_env(values,"api_key","YC_API_KEY",""))values["api_key"]=api_keyfolder_id=get_from_dict_or_env(values,"folder_id","YC_FOLDER_ID","")values["folder_id"]=folder_idifapi_key.get_secret_value()==""andiam_token.get_secret_value()=="":raiseValueError("Either 'YC_API_KEY' or 'YC_IAM_TOKEN' must be provided.")ifvalues["iam_token"]:values["grpc_metadata"]=[("authorization",f"Bearer {values['iam_token'].get_secret_value()}")]ifvalues["folder_id"]:values["grpc_metadata"].append(("x-folder-id",values["folder_id"]))else:values["grpc_metadata"]=[("authorization",f"Api-Key {values['api_key'].get_secret_value()}"),]ifvalues["model_uri"]==""andvalues["folder_id"]=="":raiseValueError("Either 'model_uri' or 'folder_id' must be provided.")ifnotvalues["model_uri"]:values["model_uri"]=(f"gpt://{values['folder_id']}/{values['model_name']}/{values['model_version']}")ifvalues["disable_request_logging"]:values["grpc_metadata"].append(("x-data-logging-enabled","false",))returnvalues
[docs]classYandexGPT(_BaseYandexGPT,LLM):"""Yandex large language models. To use, you should have the ``yandexcloud`` python package installed. There are two authentication options for the service account with the ``ai.languageModels.user`` role: - You can specify the token in a constructor parameter `iam_token` or in an environment variable `YC_IAM_TOKEN`. - You can specify the key in a constructor parameter `api_key` or in an environment variable `YC_API_KEY`. To use the default model specify the folder ID in a parameter `folder_id` or in an environment variable `YC_FOLDER_ID`. Or specify the model URI in a constructor parameter `model_uri` Example: .. code-block:: python from langchain_community.llms import YandexGPT yandex_gpt = YandexGPT(iam_token="t1.9eu...", folder_id="b1g...") """def_call(self,prompt:str,stop:Optional[List[str]]=None,run_manager:Optional[CallbackManagerForLLMRun]=None,**kwargs:Any,)->str:"""Call the Yandex GPT model and return the output. Args: prompt: The prompt to pass into the model. stop: Optional list of stop words to use when generating. Returns: The string generated by the model. Example: .. code-block:: python response = YandexGPT("Tell me a joke.") """text=completion_with_retry(self,prompt=prompt)ifstopisnotNone:text=enforce_stop_tokens(text,stop)returntextasyncdef_acall(self,prompt:str,stop:Optional[List[str]]=None,run_manager:Optional[AsyncCallbackManagerForLLMRun]=None,**kwargs:Any,)->str:"""Async call the Yandex GPT model and return the output. Args: prompt: The prompt to pass into the model. stop: Optional list of stop words to use when generating. Returns: The string generated by the model. """text=awaitacompletion_with_retry(self,prompt=prompt)ifstopisnotNone:text=enforce_stop_tokens(text,stop)returntext
def_make_request(self:YandexGPT,prompt:str,)->str:try:importgrpcfromgoogle.protobuf.wrappers_pb2importDoubleValue,Int64Valuetry:fromyandex.cloud.ai.foundation_models.v1.text_common_pb2import(CompletionOptions,Message,)fromyandex.cloud.ai.foundation_models.v1.text_generation.text_generation_service_pb2import(# noqa: E501CompletionRequest,)fromyandex.cloud.ai.foundation_models.v1.text_generation.text_generation_service_pb2_grpcimport(# noqa: E501TextGenerationServiceStub,)exceptModuleNotFoundError:fromyandex.cloud.ai.foundation_models.v1.foundation_models_pb2import(CompletionOptions,Message,)fromyandex.cloud.ai.foundation_models.v1.foundation_models_service_pb2import(# noqa: E501CompletionRequest,)fromyandex.cloud.ai.foundation_models.v1.foundation_models_service_pb2_grpcimport(# noqa: E501TextGenerationServiceStub,)exceptImportErrorase:raiseImportError("Please install YandexCloud SDK with `pip install yandexcloud` \ or upgrade it to recent version.")fromechannel_credentials=grpc.ssl_channel_credentials()channel=grpc.secure_channel(self.url,channel_credentials)request=CompletionRequest(model_uri=self.model_uri,completion_options=CompletionOptions(temperature=DoubleValue(value=self.temperature),max_tokens=Int64Value(value=self.max_tokens),),messages=[Message(role="user",text=prompt)],)stub=TextGenerationServiceStub(channel)res=stub.Completion(request,metadata=self.grpc_metadata)# type: ignore[attr-defined]returnlist(res)[0].alternatives[0].message.textasyncdef_amake_request(self:YandexGPT,prompt:str)->str:try:importasyncioimportgrpcfromgoogle.protobuf.wrappers_pb2importDoubleValue,Int64Valuetry:fromyandex.cloud.ai.foundation_models.v1.text_common_pb2import(CompletionOptions,Message,)fromyandex.cloud.ai.foundation_models.v1.text_generation.text_generation_service_pb2import(# noqa: E501CompletionRequest,CompletionResponse,)fromyandex.cloud.ai.foundation_models.v1.text_generation.text_generation_service_pb2_grpcimport(# noqa: E501TextGenerationAsyncServiceStub,)exceptModuleNotFoundError:fromyandex.cloud.ai.foundation_models.v1.foundation_models_pb2import(CompletionOptions,Message,)fromyandex.cloud.ai.foundation_models.v1.foundation_models_service_pb2import(# noqa: E501CompletionRequest,CompletionResponse,)fromyandex.cloud.ai.foundation_models.v1.foundation_models_service_pb2_grpcimport(# noqa: E501TextGenerationAsyncServiceStub,)fromyandex.cloud.operation.operation_service_pb2importGetOperationRequestfromyandex.cloud.operation.operation_service_pb2_grpcimport(OperationServiceStub,)exceptImportErrorase:raiseImportError("Please install YandexCloud SDK with `pip install yandexcloud` \ or upgrade it to recent version.")fromeoperation_api_url="operation.api.cloud.yandex.net:443"channel_credentials=grpc.ssl_channel_credentials()asyncwithgrpc.aio.secure_channel(self.url,channel_credentials)aschannel:request=CompletionRequest(model_uri=self.model_uri,completion_options=CompletionOptions(temperature=DoubleValue(value=self.temperature),max_tokens=Int64Value(value=self.max_tokens),),messages=[Message(role="user",text=prompt)],)stub=TextGenerationAsyncServiceStub(channel)operation=awaitstub.Completion(request,metadata=self.grpc_metadata)# type: ignore[attr-defined]asyncwithgrpc.aio.secure_channel(operation_api_url,channel_credentials)asoperation_channel:operation_stub=OperationServiceStub(operation_channel)whilenotoperation.done:awaitasyncio.sleep(1)operation_request=GetOperationRequest(operation_id=operation.id)operation=awaitoperation_stub.Get(operation_request,metadata=self.grpc_metadata,# type: ignore[attr-defined])completion_response=CompletionResponse()operation.response.Unpack(completion_response)returncompletion_response.alternatives[0].message.textdef_create_retry_decorator(llm:YandexGPT)->Callable[[Any],Any]:fromgrpcimportRpcErrormin_seconds=llm.sleep_intervalmax_seconds=60returnretry(reraise=True,stop=stop_after_attempt(llm.max_retries),wait=wait_exponential(multiplier=1,min=min_seconds,max=max_seconds),retry=(retry_if_exception_type((RpcError))),before_sleep=before_sleep_log(logger,logging.WARNING),)
[docs]defcompletion_with_retry(llm:YandexGPT,**kwargs:Any)->Any:"""Use tenacity to retry the completion call."""retry_decorator=_create_retry_decorator(llm)@retry_decoratordef_completion_with_retry(**_kwargs:Any)->Any:return_make_request(llm,**_kwargs)return_completion_with_retry(**kwargs)
[docs]asyncdefacompletion_with_retry(llm:YandexGPT,**kwargs:Any)->Any:"""Use tenacity to retry the async completion call."""retry_decorator=_create_retry_decorator(llm)@retry_decoratorasyncdef_completion_with_retry(**_kwargs:Any)->Any:returnawait_amake_request(llm,**_kwargs)returnawait_completion_with_retry(**kwargs)