responsible-ai-moderationlayer / src /service /textTemplate_service.py
'''
Copyright 2024-2025 Infosys Ltd.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
'''
########################################### IMPORT LIBRARIES ############################################
from langchain_core.prompts import PromptTemplate
import openai
from openai import AzureOpenAI
from langchain_community.chat_models import AzureChatOpenAI
from config.logger import CustomLogger, request_id_var
import os
import json
from utilities.utility_methods import *
from utilities.lruCaching import *
import traceback
import re
import threading
from telemetry import telemetry
from dao.AdminDb import Results
import uuid
from datetime import datetime
import boto3
import requests
from langchain_aws import ChatBedrock
import Llama_auth
import copy
import google.generativeai as genai
from service.service import Geminicompletions,Llama3completions
######################################## Prompt Template ##########################################
BASELINE_PROMPT = """You are a detail-oriented and highly analytical LLM to detect {detection_type} in the provided prompt.
{evaluation_criteria}
{prompting_instructions}
{few_shot}
Given the below User Query , generate an output with following fields separated by comma as shown below:
{output_format}
Make sure, you don't include "[User Query]: [user prompt]" in the output, the output must only contain those parameters as
mentioned in {output_format}.
ONLY OUTPUT A JSON OBJECT WITH THE KEYS MENTIONED IN OUTPUT FORMAT. DO NOT GIVE ANY DESCRIPTION OR DETAILS OTHER THAN THE JSON OBJECT.
{task_data}
"""
BASELINE_PROMPT_DEEPSEEK = """You are a detail-oriented and highly analytical LLM to detect {detection_type} in the provided prompt.
{evaluation_criteria}
{prompting_instructions}
{few_shot_examples}
Given the below User Query , generate a json output with following fields separated by comma as shown below:
{output_format}
Make sure, you don't include "[User Query]: [user prompt]" or " Now, the user query is: "<user prompt>"\n\n</think>\n\n" or "\n</think>\n\n" in the output, the output must only contain those parameters as
mentioned in {output_format}.Don't cite any examples in the output generated by you,be strict to the user prompt provided and generate output based on that prompt only.Keep this in mind very seriously.
{task_data}
"""
NORMAL_OUTPUT = """
"analysis": "[keep it crisp and to the point, including all necessary details]",
"score": [Assign a decimal score between 0-1]
"""
FAIRNESS_OUTPUT = """
"analysis":"[give the analysis for the bias identified,crisp and to the point analysis including all necessary details]",
"Key Words": "[Highlight the words in the input which are crucial for the analysis]",
"Justification": "[Justify why the key words highlighted are crucial in the analysis made.]",
"bias_type":"[the bias type(s) which have been identified,comma separated bias type(s), state NA in case of no bias type]",
"Priviledged group(s)":"[the group(s) that are favored by the bias,comma separated group(s), state NA in case of no group]",
"Un-Priviledged group(s)":"[the group(s) that are ignored by the bias,comma separated group(s), state NA in case of no group]",
"score": "[give the score as a string which can be any of these values : High / Medium / Low / Neutral]"
"""
NAVI_OUTPUT = """
"analysis": "[keep it crisp and to the point, including all necessary details]",
"score": [Assign a decimal score between 0-1],
"role":"[role of LLM eg: expert,Advisory,Support]",
"Sentiment":"[this should show emotion state of user prompt eg: Positive - Upbeat]",
"Context":"[this will be coming context]"
"Domain":"[This should show Domain of topic]",
"outputBeforemoderation":"[This should show output before moderation]",
"outputAfterSentimentmoderation":"[This should show output before moderation]"
"""
TOXICITY_OUTPUT= """
"score":[
{
"metricName" : "Toxicity",
"metricScore" :[Assign a decimal score between 0-1]
},
{
"metricName" : "Severe Toxicity",
"metricScore" :[Assign a decimal score between 0-1]
},
{
"metricName" : "Insult",
"metricScore" :[Assign a decimal score between 0-1]
},
{
"metricName" : "Threat",
"metricScore" :[Assign a decimal score between 0-1]
},
{
"metricName" : "Obscene",
"metricScore" :[Assign a decimal score between 0-1]
},
{
"metricName" : "Hate speech",
"metricScore" :[Assign a decimal score between 0-1]
},
{
"metricName" : "Identity Attack",
"metricScore" :[Assign a decimal score between 0-1]
},
{
"metricName" : "Sexual Explicit",
"metricScore" :[Assign a decimal score between 0-1]
}
],
"category": "[mention the category of toxicity]",
"analysis": "[keep it crisp and to the point, including all necessary details]"
"""
RESTRICTED_TOPIC_OUTPUT = """
"analysis": "[keep it crisp and to the point, including all necessary details]",
"score": [Assign a decimal score between 0-1],
"category": "[mention the restricted topic being used]"
"""
TASK_DATA_FOR_REQ = """
Task Data.
[User Query]: {question}
[Output]:
"""
TASK_DATA_FOR_RESP = """
Task Data.
[User Query]: {question}
[Response]: {response}
[Output]:
"""
#######################################################################################################
log = CustomLogger()
log_dict={}
cache_ttl = int(os.getenv("CACHE_TTL"))
cache_size = int(os.getenv("CACHE_SIZE"))
cache_flag = os.getenv("CACHE_FLAG")
deep_seek_completion_url = os.getenv("DEEPSEEK_COMPLETION_URL")
deepseek_completion_model_name = os.getenv("DEEPSEEK_COMPLETION_MODEL_NAME")
contentType = os.getenv("CONTENTTYPE")
aicloud_access_token=None
token_expiration=0
verify_ssl = os.getenv("VERIFY_SSL")
sslv={"False":False,"True":True,"None":True}
############################### Template based Guardrails (LLM Evaluation) #######################
def get_response_from_llm(prompt,modelName):
global aicloud_access_token,contentType
if modelName != "AWS_CLAUDE_V3_5":
if modelName == "DeepSeek":
payload = {
"model":deepseek_completion_model_name,
"prompt":prompt,
"temperature": 0.01,
"top_p": 0.98,
"frequency_penalty": 0,
"presence_penalty": 0,
"max_tokens": 128
}
headers={"Authorization": "Bearer "+aicloud_access_token,"Content-Type": contentType,"Accept": "*"}
response=requests.post(url=deep_seek_completion_url,json=payload,headers=headers,verify=sslv[verify_ssl])
llm_resp = json.loads(response.text)['choices'][0]['text']
else:
MODEL_NAME,API_BASE,API_KEY,API_VERSION,API_TYPE = config(modelName)
client = AzureOpenAI(api_key=API_KEY,
azure_endpoint=API_BASE,
api_version=API_VERSION)
resp = client.chat.completions.create(
model=MODEL_NAME,
messages = [{"role": "user", "content": prompt}] ,
temperature=0,
max_tokens=500)
llm_resp = resp.choices[0].message.content if len(resp.choices[0].message.content)!=0 else resp.choices[0].finish_reason
else:
url = os.getenv("AWS_KEY_ADMIN_PATH")
response_admin = requests.get(url,verify=sslv[verify_ssl])
if response_admin.status_code == 200:
expiration_time = int(response_admin.json()['expirationTime'].split("hrs")[0])
creation_time = datetime.strptime(response_admin.json()['creationTime'], "%Y-%m-%dT%H:%M:%S.%f")
if is_time_difference_12_hours(creation_time, expiration_time):
aws_access_key_id=response_admin.json()['awsAccessKeyId']
aws_secret_access_key=response_admin.json()['awsSecretAccessKey']
aws_session_token=response_admin.json()['awsSessionToken']
log.info("AWS Creds retrieved !!!")
aws_service_name = os.getenv("AWS_SERVICE_NAME")
region_name=os.getenv("REGION_NAME")
model_id=os.getenv("AWS_MODEL_ID")
accept=os.getenv("ACCEPT")
contentType=os.getenv("CONTENTTYPE")
anthropic_version=os.getenv("ANTHROPIC_VERSION")
native_request = {
"anthropic_version": anthropic_version,
"max_tokens": 512,
"temperature": 0.1,
"messages": [
{
"role": "user",
"content": [{"type": "text", "text": prompt}],
}
],
}
request = json.dumps(native_request)
client = boto3.client(
service_name=aws_service_name,
aws_access_key_id=aws_access_key_id,
aws_secret_access_key=aws_secret_access_key,
aws_session_token=aws_session_token,
region_name=region_name,
verify=sslv[verify_ssl]
)
response = client.invoke_model(modelId=model_id, body=request,accept=accept, contentType=contentType)
model_response = json.loads(response["body"].read())
llm_resp = model_response["content"][0]["text"] if len(model_response["content"][0]["text"])!=0 else model_response["stop_reason"]
else:
log.info("session expired, please enter the credentials again")
llm_resp = "Response cannot be generated at this moment. Reason : (ExpiredTokenException) AWS Credentials included in the request is expired. Solution : Please update with new credentials and try again."
else:
log.info("Error getting data: ",{response.status_code})
return llm_resp
def get_output_format(template_name):
if template_name=="Toxicity Check" or template_name=="Image Toxicity Check":
return TOXICITY_OUTPUT
elif template_name == "Restricted Topic Check" or template_name=="Image Restricted Topic Check":
return RESTRICTED_TOPIC_OUTPUT
elif template_name == "Fairness and Bias Check":
return FAIRNESS_OUTPUT
elif template_name == "Navi Tone Correctness Check":
return NAVI_OUTPUT
else:
return NORMAL_OUTPUT
def set_result(response):
response['threshold']=0.6
if isinstance(response['score'],float):
response['result'] = "FAILED" if float(response['score'])>response['threshold'] else "PASSED"
else:
response['result'] = "FAILED" if response['score'] == "High" else "PASSED"
return response
@lru.lru_cache(ttl=cache_ttl,size=cache_size,flag=cache_flag)
def get_response(text,template_name,userId,modelName,temperature):
try:
llm_resp = ""
llm = dict()
if modelName not in ["AWS_CLAUDE_V3_5", "Llama3-70b", "Gemini-Pro", "Gemini-Flash"]:
MODEL_NAME,API_BASE,API_KEY,API_VERSION,API_TYPE = config(modelName)
llm = AzureChatOpenAI(deployment_name=MODEL_NAME,
openai_api_version=API_VERSION,
openai_api_key=API_KEY,
azure_endpoint=API_BASE,
openai_api_type = API_TYPE,
temperature = 0)
elif modelName == "Llama3-70b":
log.info("Using LLAMA model for template-based guardrails")
#retrieving auth token
token = Llama_auth.load_token()
url=os.getenv("LLAMA_ENDPOINT3_70b")
log.info(f"url accessed for llama {url}")
elif modelName == "Gemini-Pro":
api_key = os.getenv("GEMINI_PRO_API_KEY")
genai.configure(api_key=api_key)
model = genai.GenerativeModel(os.getenv("GEMINI_PRO_MODEL_NAME"))
elif modelName == "Gemini-Flash":
api_key = os.getenv("GEMINI_FLASH_API_KEY")
genai.configure(api_key=api_key)
model = genai.GenerativeModel(os.getenv("GEMINI_FLASH_MODEL_NAME"))
else:
url = os.getenv("AWS_KEY_ADMIN_PATH")
response_admin = requests.get(url,verify=sslv[verify_ssl])
if response_admin.status_code == 200:
expiration_time = int(response_admin.json()['expirationTime'].split("hrs")[0])
creation_time = datetime.strptime(response_admin.json()['creationTime'], "%Y-%m-%dT%H:%M:%S.%f")
if is_time_difference_12_hours(creation_time, expiration_time):
aws_access_key_id=response_admin.json()['awsAccessKeyId']
aws_secret_access_key=response_admin.json()['awsSecretAccessKey']
aws_session_token=response_admin.json()['awsSessionToken']
log.info("AWS Creds retrieved !!!")
aws_service_name = os.getenv("AWS_SERVICE_NAME")
region_name=os.getenv("REGION_NAME")
model_id=os.getenv("AWS_MODEL_ID")
bedrock_client = boto3.client(
region_name=region_name,
service_name=aws_service_name,
aws_access_key_id=aws_access_key_id,
aws_secret_access_key=aws_secret_access_key,
aws_session_token=aws_session_token,
verify=sslv[verify_ssl]
)
llm = ChatBedrock(
model_id=model_id,
model_kwargs={"max_tokens":512,"temperature":0.1},
client=bedrock_client
)
else:
log.info("session expired, please enter the credentials again")
else:
log.info("Error getting data: ",{response_admin.status_code})
if(text==""):
log.info("Prompt is Empty")
log_dict[request_id_var.get()].append("Prompt is Empty")
return "Error Occured due to empty prompt"
vars={}
if userId != "None":
vars = get_templates(template_name,userId)
else:
vars = get_templates_from_file(template_name)
if modelName=="Llama3-70b":
detection_type=template_name
#generating template using the retrieved template values
template_data=" + ".join(value for value in vars.values())
if template_name=='Fairness and Bias Check':
template = f"You are a detail-oriented and highly analytical LLM to detect {detection_type} in the provided prompt "+template_data+f" Make sure, you do not include '[User Query]: [user prompt]' in the output, the output must only contain those parameters and should always strictly be in the format as mentioned in {FAIRNESS_OUTPUT} and score in output should always be a float value."
else:
template = f"You are a detail-oriented and highly analytical LLM to detect {detection_type} in the provided prompt "+template_data+f"Make sure, you do not include '[User Query]: [user prompt]' in the output, the output must only contain those parameters and should always strictly be in the format as mentioned in {NORMAL_OUTPUT} and score in output should always be a float value."
#payload for llama model
llama_response_for_template = Llama3completions().textCompletion(text)
if template_name.startswith("Response"):
messages = [
{"role": "system", "content": template},
{"role": "user", "content": " 'User Query' : f{text}, 'Response': f{llama_response_for_template}"},
]
else:
messages = [
{"role": "system", "content": template},
{"role": "user", "content": text},
]
payload={
"model":"/models/Meta-Llama-3.3-70B-Instruct",
"messages": messages,
"temperature": temperature,
"top_p": 0.8,
"frequency_penalty": 0,
"presence_penalty": 0,
"max_tokens": 1000,
"stop": "null"
}
#headers for llama model request
headers={
"Authorization": "Bearer "+str(token),
"Content-Type": "application/json",
"Accept": "*",
"X-Cluster": "H100"
}
#request to the model
response=requests.post(url=url,json=payload,headers=headers,verify=sslv[verify_ssl])
content=response.json()['choices'][0]['message']['content']
#to check if llama model has refused to answer
refusal_patterns = [
r"i\s+can'?t\s+answer\s+that",
r"i'?m\s+sorry",
r"i\s+cannot\s+(help|comply|provide)",
r"not\s+able\s+to\s+(assist|comply|respond)",
r"against\s+(policy|guidelines)",
r"decline\s+to\s+answer",
r"refuse\s+to\s+comply",
r"not\s+permitted\s+to",
r"as\s+an\s+ai\s+language\s+model",
r"this\s+goes\s+against",
"i can't provide information or guidance on illegal or harmful activities. can i help you with something else?"
]
text = content.lower().strip()
text = text.replace("’", "'").replace("‘", "'")
text = text.replace("“", '"').replace("”", '"')
if any(re.search(pattern, text) for pattern in refusal_patterns):
response_dict = {}
if template_name=='Fairness and Bias Check':
response_dict['analysis']= "Llama model can't evaluate this prompt as it is inappropriate",
response_dict['Bias score']= "HIGH",
response_dict['bias_type']= "NA",
response_dict['Priviledged group(s)']= "NA",
response_dict['Un-Priviledged group(s)']= "NA"
else:
response_dict['analysis']= "Llama model can't evaluate this prompt as it is inappropriate",
response_dict['score']= 1.0
else:
json_pattern = r'\{.*?\}'
# Search for JSON in the content
json_match = re.search(json_pattern, content, re.DOTALL)
if json_match:
# extracting the JSON
json_part = json_match.group(0)
content=str(json_part)
else:
content = "{" + content.strip() + "}"
content = re.sub(r'([{,])\s*([A-Za-z0-9 _\(\)-]+)\s*:', r'\1 "\2":', content)
content = re.sub(r'(":)\s*([^"\[\]{},\d.\s][^,\]}]*)', r'\1 "\2"', content)
content = re.sub(r'"(None|NA|N/A)"', 'null', content, flags=re.IGNORECASE)
try:
response_dict = json.loads(content)
except Exception as e:
log.error("result not is proper format, try generating response again")
return e
response_dict['threshold']=0.6
if template_name=='Fairness and Bias Check':
if 'Bias score' in response_dict:
response_dict['score'] = response_dict.pop('Bias score')
response_dict['result']="FAILED" if response_dict['score'] == "High" else "PASSED"
else:
response_dict['result']="FAILED" if float(response_dict['score'])>response_dict['threshold'] else "PASSED"
elif modelName == "Gemini-Pro" or modelName == "Gemini-Flash":
final_prompt = BASELINE_PROMPT.format(
detection_type=template_name,
evaluation_criteria=vars["evaluation_criteria"],
prompting_instructions=vars["prompting_instructions"],
few_shot=vars["few_shot_examples"],
output_format=get_output_format(template_name),
task_data=TASK_DATA_FOR_RESP.format(question=text, response=Geminicompletions(modelName).textCompletion(text)[0]) if template_name.startswith("Response") else TASK_DATA_FOR_REQ.replace("{question}", text))
generation_config = genai.types.GenerationConfig(temperature=0)
response = model.generate_content(final_prompt,generation_config=generation_config)
content = response.text
for pattern in ("[Output]:\n", "[Output] :\n", "{{", "}}", "{", "}", "`","json"):
content = content.replace(pattern, "")
content = re.sub(r'(?<!")None(?!")','"None"', content)
content = "{\n" + content + "\n}"
log.info(f"Gemini response content: {content}")
response_dict = json.loads(content)
response_dict['threshold'] = 0.6
if isinstance(response_dict['score'], float):
response_dict['result'] = "FAILED" if float(response_dict['score']) > response_dict['threshold'] else "PASSED"
else:
response_dict['result'] = "FAILED" if response_dict['score'] == "High" else "PASSED"
else:
final_prompt = PromptTemplate.from_template(BASELINE_PROMPT)
final_chain = final_prompt | llm
response = final_chain.invoke({f"detection_type":template_name,
"evaluation_criteria":vars["evaluation_criteria"],
"prompting_instructions":vars["prompting_instructions"],
"few_shot":vars["few_shot_examples"],
"output_format":get_output_format(template_name),
"task_data":TASK_DATA_FOR_RESP.format(**{"question":text,"response":llm_resp}) if template_name.startswith("Response") else TASK_DATA_FOR_REQ.replace("{question}",text)})
if isinstance(response, dict):
if 'content' not in response.keys():
return "Session expired!"
content = response.dict()['content']
for pattern in ("[Output]:\n","[Output] :\n","{{","}}","{","}"):
content = content.replace(pattern,"")
content=re.sub(r'(?<!")None(?!")','"None"',content)
content = "{\n" + content + "\n}"
log.info(f"content : {content}")
response_dict = json.loads(content)
response_dict['threshold']=0.6
if isinstance(response_dict['score'],float):
response_dict['result']="FAILED" if float(response_dict['score'])>response_dict['threshold'] else "PASSED"
else:
response_dict['result'] = "FAILED" if response_dict['score'] == "High" else "PASSED"
if 'finish_reason' in response.dict().keys() and response.dict()['finish_reason']== "content_filter":
response_dict['analysis'] = "The response was filtered due to the prompt triggering Azure OpenAI's content management policy. Please modify your prompt and retry. To learn more about our content filtering policies please read our documentation: https://go.microsoft.com/fwlink/?linkid=2198766"
response_dict['score'] = "-1"
response_dict['result'] = "Can't be determined"
elif "stop_reason" in response.dict().keys() and response.dict()["stop_reason"]== "content_filter":
response_dict['analysis'] = "The response was filtered due to the prompt triggering Azure OpenAI's content management policy. Please modify your prompt and retry. To learn more about our content filtering policies please read our documentation: https://go.microsoft.com/fwlink/?linkid=2198766"
response_dict['score'] = "-1"
response_dict['result'] = "Can't be determined"
return response_dict
except Exception as e:
line_number = traceback.extract_tb(e.__traceback__)[0].lineno
log_dict[request_id_var.get()].append({"Line number":str(traceback.extract_tb(e.__traceback__)[0].lineno),"Error":str(e),
"Error Module":"Failed at Eval LLM model call"})
log.error(f"Error occured in Chain to generate initial answer: {line_number,e}")
return str(e)
@lru.lru_cache(ttl=cache_ttl,size=cache_size,flag=cache_flag)
def get_deepseek_response(prompt,template_name,userId,modelName):
try:
vars={}
global aicloud_access_token , token_expiration , contentType
if aicloud_access_token==None or time.time()>token_expiration:
aicloud_access_token,token_expiration=aicloud_auth_token_generate(aicloud_access_token,token_expiration)
if userId != "None":
vars = get_templates(template_name,userId)
else:
vars = get_templates_from_file(template_name)
vars["detection_type"]=template_name
vars["output_format"]=get_output_format(template_name)
if template_name.startswith("Response"):
llm_resp = ""
llm_resp = get_response_from_llm(prompt,modelName)
log.info(f"llm response : {llm_resp}")
vars["task_data"]=TASK_DATA_FOR_RESP.format(**{"question":prompt,"response":llm_resp})
else:
vars["task_data"]=TASK_DATA_FOR_REQ.replace("{question}",prompt)
payload = {
"model":deepseek_completion_model_name,
"prompt":BASELINE_PROMPT_DEEPSEEK.format(**vars),
"temperature": 0.01,
"top_p": 0.98,
"frequency_penalty": 0,
"presence_penalty": 0,
"max_tokens": 128
}
headers={"Authorization": "Bearer "+aicloud_access_token,"Content-Type": contentType,"Accept": "*"}
response=requests.post(url=deep_seek_completion_url,
json=payload,headers=headers,verify=False)
if response.status_code == 200:
response = json.loads(response.text)['choices'][0]['text']
response = response.split("{")[1] if response[0]!=" {\n\\" else response
for pattern in ("\n</think>\n\n","```json","```","{{","}}"):
response = response.replace(pattern,"")
response = "{"+response if response[0]!=" {\n\\" else response
response=response+"}" if "}" not in response else response
response= response.split("}")[0]+"}"
response_json = json.loads(response)
response_json['threshold']=set_result(response_json)['threshold']
response_json['result']=set_result(response_json)['result']
log.info(f"response : {response_json}")
return response_json
else:
log.info("Error getting response from Deepseek model: ",{response.status_code})
except Exception as e:
line_number = traceback.extract_tb(e.__traceback__)[0].lineno
log_dict[request_id_var.get()].append({"Line number":str(traceback.extract_tb(e.__traceback__)[0].lineno),"Error":str(e),
"Error Module":"Failed at Eval LLM model call"})
log.error(f"Error getting response from Deepseek model: {line_number,e}")
return str(e)
class TextTemplateService:
def generate_response(self,req,headers,telemetryFlag=False):
try:
id = uuid.uuid4().hex
request_id_var.set(id)
headers['id']=id
log_dict[request_id_var.get()]=[]
AccountName=req.AccountName if "AccountName" in req else "None"
PortfolioName=req.PortfolioName if "PortfolioName" in req else "None"
userid = req.userid if "userid" in req else "None"
lotNumber = str(req.lotNumber) if "lotNumber" in req else "None"
final_response = {}
if os.getenv("DBTYPE") != "False":# send request payload into DB #
thread=threading.Thread(target=Results.createRequestPayload,args=("evalLLM",req,id,
str(PortfolioName),
str(AccountName),userid,lotNumber))
thread.start()
try:
st = time.time()
response = {}
if req['model_name'] == "DeepSeek":
response = get_deepseek_response(req['Prompt'],req['template_name'],userid,req['model_name'])
else:
response = get_response(req['Prompt'],req['template_name'],userid,req['model_name'],req['temperature'])
if response == "Session expired!":
return """Response cannot be generated at this moment.\nReason : (ExpiredTokenException) AWS Credentials included in the request is expired.\nSolution : Please update with new credentials and try again."""
final_response = {'uniqueid':id,'userid': req.userid if "userid" in req else "None",
'lotNumber': str(req.lotNumber) if "lotNumber" in req else "None",
'created': str(datetime.now()),
'model': req.model_name,
'evaluation_check' : req['template_name'],
'moderationResults':{'analysis':response['analysis'],
'score':response['score'],
'threshold':response['threshold'],
'result':response['result']},
'timeTaken':str(round(time.time() - st, 3))+"s"}
if req['template_name'] == "Fairness and Bias Check":
final_response['moderationResults'].update({
'bias_type':response['bias_type'],
'Priviledged group(s)':response['Priviledged group(s)'],
'Un-Priviledged group(s)':response['Un-Priviledged group(s)']})
del final_response['moderationResults']['threshold']
final_resp=copy.deepcopy(final_response)
del final_resp['evaluation_check']
starttime = time.time()
if telemetryFlag==True: # sent response payload to Telemetry #
thread1 = threading.Thread(target=telemetry.send_evalLLM_telemetry_request, args=(final_response,id,lotNumber, PortfolioName, AccountName,userid))
thread1.start()
log.debug(f"Time taken in adding to telemetry {time.time()-starttime}")
if os.getenv("DBTYPE") != "False": # sent response payload to DB #
thread2=threading.Thread(target=Results.create,args=(final_response,id,str(PortfolioName), str(AccountName),userid,lotNumber))
thread2.start()
except Exception as e:
log_dict[request_id_var.get()].append({"Line number":str(traceback.extract_tb(e.__traceback__)[0].lineno),"Error":str(e),
"Error Module":"Failed at Completion Function"})
log.error(f"Error starting telemetry or DB thread: {str(traceback.extract_tb(e.__traceback__)[0].lineno),e}")
return str(e)
er=log_dict[request_id_var.get()]
logobj = {"_id":id,"error":er}
if len(er)!=0:
if os.getenv("DBTYPE") != "False":
Results.createlog(logobj)
err_desc = er
log.info(f"error---->>> {err_desc}")
token_info = {"unique_name":"None","X-Correlation-ID":"None","X-Span-ID":"None"}
thread_err = threading.Thread(target=telemetry.send_telemetry_error_request, args=(logobj,id,lotNumber,PortfolioName,AccountName,userid,err_desc,headers,token_info))
thread_err.start()
del log_dict[id]
return final_resp
except Exception as e:
line_number = traceback.extract_tb(e.__traceback__)[0].lineno
log_dict[request_id_var.get()].append({"Line number":str(traceback.extract_tb(e.__traceback__)[0].lineno),"Error":str(e),
"Error Module":"Failed at Eval LLM model call"})
log.error(f"Error occured in Chain to generate initial answer: {line_number,e}")