import re import asyncio import subprocess import json import modules.shared as shared import gradio as gr from EdgeGPT.EdgeGPT import Chatbot, ConversationStyle from modules.chat import replace_all, get_turn_substrings, replace_character_names from modules.text_generation import (get_max_prompt_length, get_encoded_length) from modules.extensions import apply_extensions #------------------------------------------------------------ # Get current acheong08 EdgeGPT version installed #------------------------------------------------------------ # Run "conda list EdgeGPT" and get output command = "conda list EdgeGPT" conda_version = subprocess.check_output(command, shell=True) # Decode output into string conda_version_output = conda_version.decode("utf-8") # Find version pattern = r"edgegpt\s+(\S+)" match = re.search(pattern, conda_version_output) if match: version = match.group(1) print("acheong08 EdgeGPT core script: ", version) else: print("Version not found.") #------------------------------------------------------------ # Normal oobaboga webui #------------------------------------------------------------ BingOutput=None RawBingString=None BingString=None ShowBingString=False OverwriteWord=False PrintUserInput=False PrintWholePrompt=False PrintRawBingString=False PrintBingString=False UseCookies=False BingConversationStyle="creative" ChosenWord="Hey Bing" BingContext1="Important informations: " BingContext2="Now answer the following question based on the given informations. If I say \"Hey Bing\" I am referring to you anyway. Do not say you are Bing.\n" print("\nThanks for using the EdgeGPT extension! If you encounter any bug or you have some nice idea to add, write it on the issue page here: https://github.com/GiusTex/EdgeGPT/issues") params = { 'ShowBingString': False, 'OverwriteWord': False, 'PrintUserInput': False, 'PrintWholePrompt': False, 'PrintRawBingString': False, 'PrintBingString': False, 'UseCookies': False, } def input_modifier(string): global UserInput global BingOutput global RawBingString global ChosenWord # Reset Bing output shown in the webui RawBingString=None UserInput=string # Find out if the chosen word appears in the sentence. BingOutput = re.search(ChosenWord, UserInput) if params['ShowBingString']: global ShowBingString ShowBingString=True else: ShowBingString=False if params['OverwriteWord']: global OverwriteWord OverwriteWord=True else: OverwriteWord=False if params['PrintUserInput']: global PrintUserInput PrintUserInput=True print("User input:\n", UserInput) else: PrintUserInput=False if params['PrintWholePrompt']: global PrintWholePrompt PrintWholePrompt=True else: PrintWholePrompt=False if params['PrintRawBingString']: global PrintRawBingString PrintRawBingString=True else: PrintRawBingString=False if params['PrintBingString']: global PrintBingString PrintBingString=True else: PrintBingString=False if params['UseCookies']: global UseCookies UseCookies=True else: UseCookies=False if(BingOutput!=None) and not OverwriteWord: shared.processing_message = "*Is searching...*" elif OverwriteWord: shared.processing_message = "*Is searching...*" else: shared.processing_message = "*Is typing...*" return string # Prompt + BingString (if requested) def custom_generate_chat_prompt(user_input, state, **kwargs): impersonate = kwargs.get('impersonate', False) _continue = kwargs.get('_continue', False) also_return_rows = kwargs.get('also_return_rows', False) history = kwargs.get('history', state['history'])['internal'] is_instruct = state['mode'] == 'instruct' # Finding the maximum prompt size max_length = get_max_prompt_length(state) all_substrings = { 'chat': get_turn_substrings(state, instruct=False), 'instruct': get_turn_substrings(state, instruct=True) } substrings = all_substrings['instruct' if is_instruct else 'chat'] # Create the template for "chat-instruct" mode if state['mode'] == 'chat-instruct': wrapper = '' command = state['chat-instruct_command'].replace('<|character|>', state['name2'] if not impersonate else state['name1']) wrapper += state['context_instruct'] wrapper += all_substrings['instruct']['user_turn'].replace('<|user-message|>', command) wrapper += all_substrings['instruct']['bot_turn_stripped'] if impersonate: wrapper += substrings['user_turn_stripped'].rstrip(' ') elif _continue: wrapper += apply_extensions('bot_prefix', substrings['bot_turn_stripped'], state) wrapper += history[-1][1] else: wrapper += apply_extensions('bot_prefix', substrings['bot_turn_stripped'].rstrip(' '), state) else: wrapper = '<|prompt|>' if is_instruct: context = state['context_instruct'] else: context = replace_character_names( f"{state['context'].strip()}\n", state['name1'], state['name2'] ) # Build the prompt rows = [context] min_rows = 3 i = len(history) - 1 while i >= 0 and get_encoded_length(wrapper.replace('<|prompt|>', ''.join(rows))) < max_length: if _continue and i == len(history) - 1: if state['mode'] != 'chat-instruct': rows.insert(1, substrings['bot_turn_stripped'] + history[i][1].strip()) else: rows.insert(1, substrings['bot_turn'].replace('<|bot-message|>', history[i][1].strip())) string = history[i][0] if string not in ['', '<|BEGIN-VISIBLE-CHAT|>']: rows.insert(1, replace_all(substrings['user_turn'], {'<|user-message|>': string.strip(), '<|round|>': str(i)})) i -= 1 if impersonate: if state['mode'] == 'chat-instruct': min_rows = 1 else: min_rows = 2 rows.append(substrings['user_turn_stripped'].rstrip(' ')) elif not _continue: #------------------------------------------------------------ # Add Bing output #------------------------------------------------------------ async def EdgeGPT(): global UserInput global RawBingString global PrintRawBingString global UseCookies if BingConversationStyle=="creative": style = ConversationStyle.creative elif BingConversationStyle=="balanced": style = ConversationStyle.balanced elif BingConversationStyle=="precise": style = ConversationStyle.precise # Define and create one time the bot bot_created=False if (bot_created==False): if UseCookies: cookies = json.loads(open("./extensions/EdgeGPT/cookies.json", encoding="utf-8").read()) bot = await Chatbot.create(cookies=cookies) else: bot = await Chatbot.create() bot_created=True response = await bot.ask(prompt=UserInput, conversation_style=style, simplify_response=True) # If required, end bot and create a new one if response["messages_left"] < 2: print("WARNING: You are almost out of Bing messages! Recreating bot...") await bot.close() if UseCookies: bot = await Chatbot.create(cookies=cookies) return bot else: bot = await Chatbot.create() return bot # Select only the bot response from the response dictionary bot_response = response["text"] # You can also get citations via ["sources_text"] # Remove [^#^] citations in response bot_response_fixed = re.sub(r"\*", "", bot_response) RawBingString = re.sub('\[\^\d+\^\]', '', str(bot_response_fixed)) await bot.close() return RawBingString # Different ways to run the same EdgeGPT function: # From chosen word if(BingOutput!=None) and not OverwriteWord: asyncio.run(EdgeGPT()) # of from OverwriteWord button elif OverwriteWord: asyncio.run(EdgeGPT()) # When Bing has given his answer we print (if requested) and save # the output if RawBingString != None and not "" or OverwriteWord==True: BingString=BingContext1 + RawBingString + "\n" + BingContext2 if PrintUserInput: print("\nUser input:\n", UserInput) if PrintRawBingString: print("\nBing output:\n", RawBingString) if PrintBingString: print("\nBing context + Bing output:\n", BingString) # Add Bing output to character memory rows.append(BingString) # Add the user message if len(user_input) > 0: rows.append(replace_all(substrings['user_turn'], {'<|user-message|>': user_input.strip(), '<|round|>': str(len(history))})) # Add the character prefix if state['mode'] != 'chat-instruct': rows.append(apply_extensions('bot_prefix', substrings['bot_turn_stripped'].rstrip(' '), state)) while len(rows) > min_rows and get_encoded_length(wrapper.replace('<|prompt|>', ''.join(rows))) >= max_length: rows.pop(1) prompt = wrapper.replace('<|prompt|>', ''.join(rows)) if RawBingString != None and not "" or OverwriteWord==True: if PrintWholePrompt: print("\nWhole prompt:\n", prompt + "\n") if also_return_rows: return prompt, rows else: return prompt def output_modifier(string): """ This function is applied to the model outputs. """ global BingOutput global RawBingString global ShowBingString if ShowBingString: string = "Bing:" + str(RawBingString) + "\n\n\n" + string return string else: return string def bot_prefix_modifier(string): """ This function is only applied in chat mode. It modifies the prefix text for the Bot and can be used to bias its behavior. """ return string def FunChooseWord(CustomWordRaw): global ChosenWord ChosenWord = CustomWordRaw return CustomWordRaw def Context1Func(Context1Raw): global BingContext1 BingContext1 = Context1Raw return Context1Raw def Context2Func(Context2Raw): global BingContext2 BingContext2 = Context2Raw return Context2Raw def ConversationStyleFunc(ConversationStyleRaw): global BingConversationStyle BingConversationStyle = ConversationStyleRaw return ConversationStyleRaw def ui(): with gr.Accordion("Instructions", open=False): with gr.Box(): gr.Markdown( """ To use it, just start the prompt with Hey Bing; it doesn't start if you don't use uppercase and lowercase as in the example. You can change the activation word from EdgeGPT options. If the output is strange turn on Show Bing Output to see the result of Bing, maybe you need to correct your question. """) with gr.Accordion("EdgeGPT options", open=True): with gr.Row(): ShowBingString = gr.Checkbox(value=params['ShowBingString'], label='Show Bing Output') with gr.Row(): WordOption = gr.Textbox(label='Choose and use a word to activate Bing', placeholder="Choose your word. Empty = Hey Bing") OverwriteWord = gr.Checkbox(value=params['OverwriteWord'], label='Overwrite Activation Word. Bing will always search, ignoring the activation word.') with gr.Row(): UseCookies = gr.Checkbox(value=params['UseCookies'], label='Use cookies. If you have login problems turn this on to use cookies (you need cookies.json). Instructions here: https://github.com/GiusTex/EdgeGPT/blob/main/how-to-use-cookies.md') with gr.Row(): ConversationStyleOption = gr.Textbox(label='Choose Bing Conversation Style', placeholder="Supported Conversation Styles: creative, balanced, precise. Empty = default creative") with gr.Accordion("EdgeGPT context", open=False): with gr.Row(): Context1Option = gr.Textbox(label='Choose Bing context-1', placeholder="First context, is injected before the Bing output. Empty = default context-1") with gr.Row(): Context2Option = gr.Textbox(label='Choose Bing context-2', placeholder="Second context, is injected after the Bing output. Empty = default context-2") with gr.Row(): gr.Markdown( """ You can see the default context (with Bing output in the middle) by turning on the fourth option in "Print in console options": "Print Bing string in command console". """) with gr.Accordion("Print in console options", open=False): with gr.Row(): PrintUserInput = gr.Checkbox(value=params['PrintUserInput'], label='Print User input in command console. The user input will be fed first to Bing, and then to the default bot.') with gr.Row(): PrintWholePrompt = gr.Checkbox(value=params['PrintWholePrompt'], label='Print whole prompt in command console. Prompt has: context, Bing search output, and user input.') with gr.Row(): PrintRawBingString = gr.Checkbox(value=params['PrintRawBingString'], label='Print Bing output in command console.') with gr.Row(): PrintBingString = gr.Checkbox(value=params['PrintBingString'], label='Print Bing output + Bing context in command console.') ShowBingString.change(lambda x: params.update({"ShowBingString": x}), ShowBingString, None) WordOption.change(fn=FunChooseWord, inputs=WordOption) OverwriteWord.change(lambda x: params.update({"OverwriteWord": x}), OverwriteWord, None) UseCookies.change(lambda x: params.update({"UseCookies": x}), UseCookies, None) ConversationStyleOption.change(fn=ConversationStyleFunc, inputs=ConversationStyleOption) Context1Option.change(fn=Context1Func, inputs=Context1Option) Context2Option.change(fn=Context2Func, inputs=Context2Option) PrintUserInput.change(lambda x: params.update({"PrintUserInput": x}), PrintUserInput, None) PrintWholePrompt.change(lambda x: params.update({"PrintWholePrompt": x}), PrintWholePrompt, None) PrintRawBingString.change(lambda x: params.update({"PrintRawBingString": x}), PrintRawBingString, None) PrintBingString.change(lambda x: params.update({"PrintBingString": x}), PrintBingString, None)