SixOpen's picture
MoA
50efed6
raw
history blame
5.58 kB
import re
from datetime import datetime
from flask import request, Response, stream_with_context
from requests import get
from server.config import special_instructions
from server.utils import generate_with_references, inject_references_to_messages, check_model, make_prompt
from config import MODEL_REFERENCE_1, MODEL_REFERENCE_2, MODEL_REFERENCE_3
class Backend_Api:
def __init__(self, bp, config: dict) -> None:
self.bp = bp
self.routes = {
'/backend-api/v2/conversation': {
'function': self._conversation,
'methods': ['POST']
}
}
def _conversation(self):
conversation_id = request.json['conversation_id']
try:
api_key = request.json['api_key']
jailbreak = request.json['jailbreak']
model = request.json['model']
check_model(model)
messages = self.build_messages(jailbreak)
# Generate response
response = self.generate_response(model, messages, jailbreak)
return Response(stream_with_context(response), mimetype='text/event-stream')
except Exception as e:
print(e)
print(e.__traceback__.tb_next)
return {
'_action': '_ask',
'success': False,
"error": f"an error occurred {str(e)}"
}, 400
def build_messages(self, jailbreak):
_conversation = request.json['meta']['content']['conversation']
internet_access = request.json['meta']['content']['internet_access']
prompt = request.json['meta']['content']['parts'][0]
# Add the existing conversation
conversation = _conversation
# Add web results if enabled
if internet_access:
current_date = datetime.now().strftime("%Y-%m-%d")
query = f'Current date: {current_date}. ' + prompt["content"]
search_results = self.fetch_search_results(query)
conversation.extend(search_results)
# Add jailbreak instructions if enabled
if jailbreak_instructions := self.getJailbreak(jailbreak):
conversation.extend(jailbreak_instructions)
# Add the prompt
conversation.append(prompt)
# Reduce conversation size to avoid API Token quantity error
if len(conversation) > 3:
conversation = conversation[-4:]
return conversation
def fetch_search_results(self, query):
search = get('https://ddg-api.herokuapp.com/search',
params={
'query': query,
'limit': 3,
})
snippets = ""
for index, result in enumerate(search.json()):
snippet = f'[{index + 1}] "{result["snippet"]}" URL:{result["link"]}.'
snippets += snippet
response = "Here are some updated web searches. Use this to improve user response:"
response += snippets
return [{'role': 'system', 'content': response}]
def generate_response(self, model, messages, jailbreak):
reference_models = [MODEL_REFERENCE_1, MODEL_REFERENCE_2, MODEL_REFERENCE_3]
data = {
"instruction": [[] for _ in range(len(reference_models))],
"references": [""] * len(reference_models),
"model": [m for m in reference_models],
}
num_proc = len(reference_models)
rounds = 1
for i in range(len(reference_models)):
data["instruction"][i].append({"role": "user", "content": messages[-1]['content']})
for i_round in range(rounds):
for i in range(num_proc):
reference_model = data["model"][i]
prompt = make_prompt(data["instruction"][i][-1]['content'], data["instruction"][i], reference_model)
data["references"][i] = generate_with_references(reference_model, prompt)
output = generate_with_references(
model=model,
messages=data["instruction"][0],
references=data["references"],
)
all_output = ""
for chunk in output:
all_output += chunk
if jailbreak:
response_jailbreak = ''
jailbroken_checked = False
for message in all_output:
response_jailbreak += message
if jailbroken_checked:
yield message
else:
if self.response_jailbroken_success(response_jailbreak):
jailbroken_checked = True
if self.response_jailbroken_failed(response_jailbreak):
yield response_jailbreak
jailbroken_checked = True
else:
yield all_output
def response_jailbroken_success(self, response: str) -> bool:
act_match = re.search(r'ACT:', response, flags=re.DOTALL)
return bool(act_match)
def response_jailbroken_failed(self, response):
return False if len(response) < 4 else not (response.startswith("GPT:") or response.startswith("ACT:"))
def getJailbreak(self, jailbreak):
if jailbreak != "default":
special_instructions[jailbreak][0]['content'] += special_instructions['two_responses_instruction']
if jailbreak in special_instructions:
special_instructions[jailbreak]
return special_instructions[jailbreak]
else:
return None
else:
return None