def_convert_prompt_to_text(self,prompt:Any)->str:input_text=str()ifisinstance(prompt,StringPromptValue):input_text=prompt.textelifisinstance(prompt,str):input_text=promptelifisinstance(prompt,ChatPromptValue):""" We will just check the last message in the message Chain of a ChatPromptTemplate. The typical chronology is SystemMessage > HumanMessage > AIMessage and so on. However assuming that with every chat the chain is invoked we will only check the last message. This is assuming that all previous messages have been checked already. Only HumanMessage and AIMessage will be checked. We can perhaps loop through and take advantage of the additional_kwargs property in the HumanMessage and AIMessage schema to mark messages that have been moderated. However that means that this class could generate multiple text chunks and moderate() logics would need to be updated. This also means some complexity in re-constructing the prompt while keeping the messages in sequence. """message=prompt.messages[-1]self.chat_message_index=len(prompt.messages)-1ifisinstance(message,HumanMessage):input_text=cast(str,message.content)ifisinstance(message,AIMessage):input_text=cast(str,message.content)else:raiseValueError(f"Invalid input type {type(input_text)}. ""Must be a PromptValue, str, or list of BaseMessages.")returninput_textdef_convert_text_to_prompt(self,prompt:Any,text:str)->Any:ifisinstance(prompt,StringPromptValue):returnStringPromptValue(text=text)elifisinstance(prompt,str):returntextelifisinstance(prompt,ChatPromptValue):# Copy the messages because we may need to mutate them.# We don't want to mutate data we don't own.messages=list(prompt.messages)message=messages[self.chat_message_index]ifisinstance(message,HumanMessage):messages[self.chat_message_index]=HumanMessage(content=text,example=message.example,additional_kwargs=message.additional_kwargs,)ifisinstance(message,AIMessage):messages[self.chat_message_index]=AIMessage(content=text,example=message.example,additional_kwargs=message.additional_kwargs,)returnChatPromptValue(messages=messages)else:raiseValueError(f"Invalid input type {type(input)}. ""Must be a PromptValue, str, or list of BaseMessages.")def_moderation_class(self,moderation_class:Any)->Callable:returnmoderation_class(client=self.client,callback=self.moderation_callback,unique_id=self.unique_id,chain_id=self.chain_id,).validatedef_log_message_for_verbose(self,message:str)->None:ifself.run_manager:self.run_manager.on_text(message)
[docs]defmoderate(self,prompt:Any)->str:"""Moderate the input prompt."""fromlangchain_experimental.comprehend_moderation.base_moderation_configimport(# noqa: E501ModerationPiiConfig,ModerationPromptSafetyConfig,ModerationToxicityConfig,)fromlangchain_experimental.comprehend_moderation.base_moderation_exceptionsimport(# noqa: E501ModerationPiiError,ModerationPromptSafetyError,ModerationToxicityError,)try:# convert prompt to textinput_text=self._convert_prompt_to_text(prompt=prompt)output_text=str()# perform moderationfilter_functions={"pii":ComprehendPII,"toxicity":ComprehendToxicity,"prompt_safety":ComprehendPromptSafety,}filters=self.config.filters# type: ignorefor_filterinfilters:filter_name=("pii"ifisinstance(_filter,ModerationPiiConfig)else("toxicity"ifisinstance(_filter,ModerationToxicityConfig)else("prompt_safety"ifisinstance(_filter,ModerationPromptSafetyConfig)elseNone)))iffilter_nameinfilter_functions:self._log_message_for_verbose(f"Running {filter_name} Validation...\n")validation_fn=self._moderation_class(moderation_class=filter_functions[filter_name])input_text=input_textifnotoutput_textelseoutput_textoutput_text=validation_fn(prompt_value=input_text,config=_filter.dict(),)# convert text to prompt and returnreturnself._convert_text_to_prompt(prompt=prompt,text=output_text)exceptModerationPiiErrorase:self._log_message_for_verbose(f"Found PII content..stopping..\n{str(e)}\n")raiseeexceptModerationToxicityErrorase:self._log_message_for_verbose(f"Found Toxic content..stopping..\n{str(e)}\n")raiseeexceptModerationPromptSafetyErrorase:self._log_message_for_verbose(f"Found Harmful intention..stopping..\n{str(e)}\n")raiseeexceptExceptionase:raisee