| | import re |
| | from datetime import datetime |
| | from g4f import ChatCompletion |
| | from flask import request, Response, stream_with_context |
| | from requests import get |
| | from server.config import special_instructions |
| |
|
| |
|
| | class Backend_Api: |
| | def __init__(self, bp, config: dict) -> None: |
| | """ |
| | Initialize the Backend_Api class. |
| | :param app: Flask application instance |
| | :param config: Configuration dictionary |
| | """ |
| | self.bp = bp |
| | self.routes = { |
| | '/backend-api/v2/conversation': { |
| | 'function': self._conversation, |
| | 'methods': ['POST'] |
| | } |
| | } |
| |
|
| | def _conversation(self): |
| | """ |
| | Handles the conversation route. |
| | |
| | :return: Response object containing the generated conversation stream |
| | """ |
| | conversation_id = request.json['conversation_id'] |
| |
|
| | try: |
| | jailbreak = request.json['jailbreak'] |
| | model = request.json['model'] |
| | messages = build_messages(jailbreak) |
| |
|
| | |
| | response = ChatCompletion.create( |
| | model=model, |
| | chatId=conversation_id, |
| | messages=messages |
| | ) |
| |
|
| | return Response(stream_with_context(generate_stream(response, jailbreak)), 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(jailbreak): |
| | """ |
| | Build the messages for the conversation. |
| | |
| | :param jailbreak: Jailbreak instruction string |
| | :return: List of messages for the conversation |
| | """ |
| | _conversation = request.json['meta']['content']['conversation'] |
| | internet_access = request.json['meta']['content']['internet_access'] |
| | prompt = request.json['meta']['content']['parts'][0] |
| |
|
| | |
| | conversation = _conversation |
| |
|
| | |
| | if internet_access: |
| | current_date = datetime.now().strftime("%Y-%m-%d") |
| | query = f'Current date: {current_date}. ' + prompt["content"] |
| | search_results = fetch_search_results(query) |
| | conversation.extend(search_results) |
| |
|
| | |
| | if jailbreak_instructions := getJailbreak(jailbreak): |
| | conversation.extend(jailbreak_instructions) |
| |
|
| | |
| | conversation.append(prompt) |
| |
|
| | |
| | if len(conversation) > 3: |
| | conversation = conversation[-4:] |
| |
|
| | return conversation |
| |
|
| |
|
| | def fetch_search_results(query): |
| | """ |
| | Fetch search results for a given query. |
| | |
| | :param query: Search query string |
| | :return: List of search results |
| | """ |
| | 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_stream(response, jailbreak): |
| | """ |
| | Generate the conversation stream. |
| | |
| | :param response: Response object from ChatCompletion.create |
| | :param jailbreak: Jailbreak instruction string |
| | :return: Generator object yielding messages in the conversation |
| | """ |
| | if getJailbreak(jailbreak): |
| | response_jailbreak = '' |
| | jailbroken_checked = False |
| | for message in response: |
| | response_jailbreak += message |
| | if jailbroken_checked: |
| | yield message |
| | else: |
| | if response_jailbroken_success(response_jailbreak): |
| | jailbroken_checked = True |
| | if response_jailbroken_failed(response_jailbreak): |
| | yield response_jailbreak |
| | jailbroken_checked = True |
| | else: |
| | yield from response |
| |
|
| |
|
| | def response_jailbroken_success(response: str) -> bool: |
| | """Check if the response has been jailbroken. |
| | |
| | :param response: Response string |
| | :return: Boolean indicating if the response has been jailbroken |
| | """ |
| | act_match = re.search(r'ACT:', response, flags=re.DOTALL) |
| | return bool(act_match) |
| |
|
| |
|
| | def response_jailbroken_failed(response): |
| | """ |
| | Check if the response has not been jailbroken. |
| | |
| | :param response: Response string |
| | :return: Boolean indicating if the response has not been jailbroken |
| | """ |
| | return False if len(response) < 4 else not (response.startswith("GPT:") or response.startswith("ACT:")) |
| |
|
| |
|
| | def getJailbreak(jailbreak): |
| | """ |
| | Check if jailbreak instructions are provided. |
| | |
| | :param jailbreak: Jailbreak instruction string |
| | :return: Jailbreak instructions if provided, otherwise None |
| | """ |
| | 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 |
| |
|