[docs]defcompletion_with_retry(llm:GooglePalm,prompt:LanguageModelInput,is_gemini:bool=False,stream:bool=False,run_manager:Optional[CallbackManagerForLLMRun]=None,**kwargs:Any,)->Any:"""Use tenacity to retry the completion call."""retry_decorator=create_retry_decorator(llm,max_retries=llm.max_retries,run_manager=run_manager)@retry_decoratordef_completion_with_retry(prompt:LanguageModelInput,is_gemini:bool,stream:bool,**kwargs:Any)->Any:generation_config=kwargs.get("generation_config",{})ifis_gemini:returnllm.client.generate_content(contents=prompt,stream=stream,generation_config=generation_config)returnllm.client.generate_text(prompt=prompt,**kwargs)return_completion_with_retry(prompt=prompt,is_gemini=is_gemini,stream=stream,**kwargs)
def_is_gemini_model(model_name:str)->bool:return"gemini"inmodel_namedef_strip_erroneous_leading_spaces(text:str)->str:"""Strip erroneous leading spaces from text. The PaLM API will sometimes erroneously return a single leading space in all lines > 1. This function strips that space. """has_leading_space=all(notlineorline[0]==" "forlineintext.split("\n")[1:])ifhas_leading_space:returntext.replace("\n ","\n")else:returntext
[docs]@deprecated("0.0.12",alternative_import="langchain_google_genai.GoogleGenerativeAI")classGooglePalm(BaseLLM,BaseModel):""" DEPRECATED: Use `langchain_google_genai.GoogleGenerativeAI` instead. Google PaLM models. """client:Any#: :meta private:google_api_key:Optional[SecretStr]model_name:str="models/text-bison-001""""Model name to use."""temperature:float=0.7"""Run inference with this temperature. Must be in the closed interval [0.0, 1.0]."""top_p:Optional[float]=None"""Decode using nucleus sampling: consider the smallest set of tokens whose probability sum is at least top_p. Must be in the closed interval [0.0, 1.0]."""top_k:Optional[int]=None"""Decode using top-k sampling: consider the set of top_k most probable tokens. Must be positive."""max_output_tokens:Optional[int]=None"""Maximum number of tokens to include in a candidate. Must be greater than zero. If unset, will default to 64."""n:int=1"""Number of chat completions to generate for each prompt. Note that the API may not return the full n completions if duplicates are generated."""max_retries:int=6"""The maximum number of retries to make when generating."""@propertydefis_gemini(self)->bool:"""Returns whether a model is belongs to a Gemini family or not."""return_is_gemini_model(self.model_name)@propertydeflc_secrets(self)->Dict[str,str]:return{"google_api_key":"GOOGLE_API_KEY"}@classmethoddefis_lc_serializable(self)->bool:returnTrue@classmethoddefget_lc_namespace(cls)->List[str]:"""Get the namespace of the langchain object."""return["langchain","llms","google_palm"]
[docs]@pre_initdefvalidate_environment(cls,values:Dict)->Dict:"""Validate api key, python package exists."""google_api_key=get_from_dict_or_env(values,"google_api_key","GOOGLE_API_KEY")model_name=values["model_name"]try:importgoogle.generativeaiasgenaiifisinstance(google_api_key,SecretStr):google_api_key=google_api_key.get_secret_value()genai.configure(api_key=google_api_key)if_is_gemini_model(model_name):values["client"]=genai.GenerativeModel(model_name=model_name)else:values["client"]=genaiexceptImportError:raiseImportError("Could not import google-generativeai python package. ""Please install it with `pip install google-generativeai`.")ifvalues["temperature"]isnotNoneandnot0<=values["temperature"]<=1:raiseValueError("temperature must be in the range [0.0, 1.0]")ifvalues["top_p"]isnotNoneandnot0<=values["top_p"]<=1:raiseValueError("top_p must be in the range [0.0, 1.0]")ifvalues["top_k"]isnotNoneandvalues["top_k"]<=0:raiseValueError("top_k must be positive")ifvalues["max_output_tokens"]isnotNoneandvalues["max_output_tokens"]<=0:raiseValueError("max_output_tokens must be greater than zero")returnvalues
def_generate(self,prompts:List[str],stop:Optional[List[str]]=None,run_manager:Optional[CallbackManagerForLLMRun]=None,**kwargs:Any,)->LLMResult:generations:List[List[Generation]]=[]generation_config={"stop_sequences":stop,"temperature":self.temperature,"top_p":self.top_p,"top_k":self.top_k,"max_output_tokens":self.max_output_tokens,"candidate_count":self.n,}forpromptinprompts:ifself.is_gemini:res=completion_with_retry(self,prompt=prompt,stream=False,is_gemini=True,run_manager=run_manager,generation_config=generation_config,)candidates=["".join([p.textforpinc.content.parts])forcinres.candidates]generations.append([Generation(text=c)forcincandidates])else:res=completion_with_retry(self,model=self.model_name,prompt=prompt,stream=False,is_gemini=False,run_manager=run_manager,**generation_config,)prompt_generations=[]forcandidateinres.candidates:raw_text=candidate["output"]stripped_text=_strip_erroneous_leading_spaces(raw_text)prompt_generations.append(Generation(text=stripped_text))generations.append(prompt_generations)returnLLMResult(generations=generations)def_stream(self,prompt:str,stop:Optional[List[str]]=None,run_manager:Optional[CallbackManagerForLLMRun]=None,**kwargs:Any,)->Iterator[GenerationChunk]:generation_config=kwargs.get("generation_config",{})ifstop:generation_config["stop_sequences"]=stopforstream_respincompletion_with_retry(self,prompt,stream=True,is_gemini=True,run_manager=run_manager,generation_config=generation_config,**kwargs,):chunk=GenerationChunk(text=stream_resp.text)ifrun_manager:run_manager.on_llm_new_token(stream_resp.text,chunk=chunk,verbose=self.verbose,)yieldchunk@propertydef_llm_type(self)->str:"""Return type of llm."""return"google_palm"
[docs]defget_num_tokens(self,text:str)->int:"""Get the number of tokens present in the text. Useful for checking if an input will fit in a model's context window. Args: text: The string input to tokenize. Returns: The integer number of tokens in the text. """ifself.is_gemini:raiseValueError("Counting tokens is not yet supported!")result=self.client.count_text_tokens(model=self.model_name,prompt=text)returnresult["token_count"]