Add menus for saving presets/characters/instruction templates/prompts (#2621)

This commit is contained in:
oobabooga 2023-06-11 12:19:18 -03:00 committed by GitHub
parent ea0eabd266
commit 6133675e0f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 220 additions and 98 deletions

View File

@ -82,7 +82,7 @@ div.svelte-15lo0d8 > *, div.svelte-15lo0d8 > .form > * {
} }
.textbox_default textarea { .textbox_default textarea {
height: calc(100vh - 381px); height: calc(100vh - 416px);
} }
.textbox_default_output textarea { .textbox_default_output textarea {
@ -113,4 +113,19 @@ button {
.small-button { .small-button {
max-width: 171px; max-width: 171px;
}
.file-saver {
position: fixed !important;
top: 50%;
left: 50%;
transform: translate(-50%, -50%); /* center horizontally */
max-width: 500px;
background-color: var(--input-background-fill);
border: 2px solid black !important;
z-index: 1000;
}
.dark .file-saver {
border: 2px solid white !important;
} }

View File

@ -17,7 +17,7 @@ from modules.html_generator import chat_html_wrapper, make_thumbnail
from modules.logging_colors import logger from modules.logging_colors import logger
from modules.text_generation import (generate_reply, get_encoded_length, from modules.text_generation import (generate_reply, get_encoded_length,
get_max_prompt_length) get_max_prompt_length)
from modules.utils import replace_all from modules.utils import delete_file, replace_all, save_file
def get_turn_substrings(state, instruct=False): def get_turn_substrings(state, instruct=False):
@ -320,8 +320,8 @@ def generate_chat_reply(text, history, state, regenerate=False, _continue=False,
# Same as above but returns HTML for the UI # Same as above but returns HTML for the UI
def generate_chat_reply_wrapper(text, start_with, state, regenerate=False, _continue=False): def generate_chat_reply_wrapper(text, start_with, state, regenerate=False, _continue=False):
if start_with != '' and _continue == False: if start_with != '' and not _continue:
if regenerate == True: if regenerate:
text = remove_last_message() text = remove_last_message()
regenerate = False regenerate = False
@ -628,18 +628,7 @@ def upload_your_profile_picture(img):
logger.info('Profile picture saved to "cache/pfp_me.png"') logger.info('Profile picture saved to "cache/pfp_me.png"')
def delete_file(path): def generate_character_yaml(name, greeting, context):
if path.exists():
logger.warning(f'Deleting {path}')
path.unlink(missing_ok=True)
def save_character(name, greeting, context, picture, filename, instruct=False):
if filename == "":
logger.error("The filename is empty, so the character will not be saved.")
return
folder = 'characters' if not instruct else 'characters/instruction-following'
data = { data = {
'name': name, 'name': name,
'greeting': greeting, 'greeting': greeting,
@ -647,22 +636,37 @@ def save_character(name, greeting, context, picture, filename, instruct=False):
} }
data = {k: v for k, v in data.items() if v} # Strip falsy data = {k: v for k, v in data.items() if v} # Strip falsy
filepath = Path(f'{folder}/{filename}.yaml') return yaml.dump(data, sort_keys=False)
with filepath.open('w') as f:
yaml.dump(data, f, sort_keys=False)
logger.info(f'Wrote {filepath}')
path_to_img = Path(f'{folder}/{filename}.png') def generate_instruction_template_yaml(user, bot, context, turn_template):
if picture and not instruct: data = {
'user': user,
'bot': bot,
'turn_template': turn_template,
'context': context,
}
data = {k: v for k, v in data.items() if v} # Strip falsy
return yaml.dump(data, sort_keys=False)
def save_character(name, greeting, context, picture, filename):
if filename == "":
logger.error("The filename is empty, so the character will not be saved.")
return
data = generate_character_yaml(name, greeting, context)
filepath = Path(f'characters/{filename}.yaml')
save_file(filepath, data)
path_to_img = Path(f'characters/{filename}.png')
if picture is not None:
picture.save(path_to_img) picture.save(path_to_img)
logger.info(f'Wrote {path_to_img}') logger.info(f'Saved {path_to_img}.')
elif path_to_img.exists():
delete_file(path_to_img)
def delete_character(name, instruct=False): def delete_character(name, instruct=False):
folder = 'characters' if not instruct else 'characters/instruction-following'
for extension in ["yml", "yaml", "json"]: for extension in ["yml", "yaml", "json"]:
delete_file(Path(f'{folder}/{name}.{extension}')) delete_file(Path(f'characters/{name}.{extension}'))
delete_file(Path(f'{folder}/{name}.png')) delete_file(Path(f'characters/{name}.png'))

View File

@ -3,7 +3,10 @@
import logging import logging
import platform import platform
logging.basicConfig(format='%(levelname)s:%(message)s') logging.basicConfig(
format='%(asctime)s %(levelname)s:%(message)s',
datefmt='%Y-%m-%d %H:%M:%S',
)
def add_coloring_to_emit_windows(fn): def add_coloring_to_emit_windows(fn):

View File

@ -3,6 +3,42 @@ import re
from pathlib import Path from pathlib import Path
from modules import shared from modules import shared
from modules.logging_colors import logger
def save_file(fname, contents):
if fname == '':
logger.error('File name is empty!')
return
root_folder = Path(__file__).resolve().parent.parent
abs_path = Path(fname).resolve()
rel_path = abs_path.relative_to(root_folder)
if rel_path.parts[0] == '..':
logger.error(f'Invalid file path: {fname}')
return
with open(abs_path, 'w', encoding='utf-8') as f:
f.write(contents)
logger.info(f'Saved {abs_path}.')
def delete_file(fname):
if fname == '':
logger.error('File name is empty!')
return
root_folder = Path(__file__).resolve().parent.parent
abs_path = Path(fname).resolve()
rel_path = abs_path.relative_to(root_folder)
if rel_path.parts[0] == '..':
logger.error(f'Invalid file path: {fname}')
return
if abs_path.exists():
abs_path.unlink()
logger.info(f'Deleted {fname}.')
def atoi(text): def atoi(text):

202
server.py
View File

@ -117,21 +117,13 @@ def load_preset_values(preset_menu, state, return_dict=False):
return state, *[generate_params[k] for k in ['do_sample', 'temperature', 'top_p', 'typical_p', 'epsilon_cutoff', 'eta_cutoff', 'repetition_penalty', 'encoder_repetition_penalty', 'top_k', 'min_length', 'no_repeat_ngram_size', 'num_beams', 'penalty_alpha', 'length_penalty', 'early_stopping', 'mirostat_mode', 'mirostat_tau', 'mirostat_eta', 'tfs', 'top_a']] return state, *[generate_params[k] for k in ['do_sample', 'temperature', 'top_p', 'typical_p', 'epsilon_cutoff', 'eta_cutoff', 'repetition_penalty', 'encoder_repetition_penalty', 'top_k', 'min_length', 'no_repeat_ngram_size', 'num_beams', 'penalty_alpha', 'length_penalty', 'early_stopping', 'mirostat_mode', 'mirostat_tau', 'mirostat_eta', 'tfs', 'top_a']]
def open_save_prompt(): def generate_preset_yaml(state):
fname = f"{datetime.now().strftime('%Y-%m-%d-%H%M%S')}" data = {k: state[k] for k in ['do_sample', 'temperature', 'top_p', 'typical_p', 'epsilon_cutoff', 'eta_cutoff', 'repetition_penalty', 'encoder_repetition_penalty', 'top_k', 'min_length', 'no_repeat_ngram_size', 'num_beams', 'penalty_alpha', 'length_penalty', 'early_stopping', 'mirostat_mode', 'mirostat_tau', 'mirostat_eta', 'tfs', 'top_a']}
return gr.update(value=fname, visible=True), gr.update(visible=False), gr.update(visible=True) return yaml.dump(data, sort_keys=False)
def save_prompt(text, fname): def current_time():
if fname != "": return f"{datetime.now().strftime('%Y-%m-%d-%H%M%S')}"
with open(Path(f'prompts/{fname}.txt'), 'w', encoding='utf-8') as f:
f.write(text)
message = f"Saved to prompts/{fname}.txt"
else:
message = "Error: No prompt name given."
return message, gr.update(visible=False), gr.update(visible=True), gr.update(visible=False)
def load_prompt(fname): def load_prompt(fname):
@ -163,8 +155,11 @@ def load_prompt(fname):
def count_tokens(text): def count_tokens(text):
tokens = get_encoded_length(text) try:
return f'{tokens} tokens in the input.' tokens = get_encoded_length(text)
return f'{tokens} tokens in the input.'
except:
return 'Couldn\'t count the number of tokens. Is a tokenizer loaded?'
def download_model_wrapper(repo_id): def download_model_wrapper(repo_id):
@ -462,19 +457,17 @@ def create_settings_menus(default_preset):
with gr.Row(): with gr.Row():
with gr.Column(): with gr.Column():
with gr.Row(): with gr.Row():
with gr.Column(): shared.gradio['preset_menu'] = gr.Dropdown(choices=utils.get_available_presets(), value=default_preset if not shared.args.flexgen else 'Naive', label='Generation parameters preset')
with gr.Row(): ui.create_refresh_button(shared.gradio['preset_menu'], lambda: None, lambda: {'choices': utils.get_available_presets()}, 'refresh-button')
shared.gradio['preset_menu'] = gr.Dropdown(choices=utils.get_available_presets(), value=default_preset if not shared.args.flexgen else 'Naive', label='Generation parameters preset') with gr.Column(scale=0):
ui.create_refresh_button(shared.gradio['preset_menu'], lambda: None, lambda: {'choices': utils.get_available_presets()}, 'refresh-button') shared.gradio['save_preset'] = gr.Button('Save preset')
shared.gradio['delete_preset'] = gr.Button('Delete preset')
with gr.Column():
shared.gradio['seed'] = gr.Number(value=shared.settings['seed'], label='Seed (-1 for random)')
shared.gradio['seed'] = gr.Number(value=shared.settings['seed'], label='Seed (-1 for random)')
with gr.Box(): with gr.Box():
gr.Markdown('Main parameters') gr.Markdown('Main parameters')
with gr.Row(): with gr.Row():
with gr.Column(): with gr.Column():
shared.gradio['do_sample'] = gr.Checkbox(value=generate_params['do_sample'], label='do_sample')
shared.gradio['temperature'] = gr.Slider(0.01, 1.99, value=generate_params['temperature'], step=0.01, label='temperature', info='Primary factor to control randomness of outputs. 0 = deterministic (only the most likely token is used). Higher value = more randomness.') shared.gradio['temperature'] = gr.Slider(0.01, 1.99, value=generate_params['temperature'], step=0.01, label='temperature', info='Primary factor to control randomness of outputs. 0 = deterministic (only the most likely token is used). Higher value = more randomness.')
shared.gradio['top_p'] = gr.Slider(0.0, 1.0, value=generate_params['top_p'], step=0.01, label='top_p', info='If not set to 1, select tokens with probabilities adding up to less than this number. Higher value = higher range of possible random results.') shared.gradio['top_p'] = gr.Slider(0.0, 1.0, value=generate_params['top_p'], step=0.01, label='top_p', info='If not set to 1, select tokens with probabilities adding up to less than this number. Higher value = higher range of possible random results.')
shared.gradio['top_k'] = gr.Slider(0, 200, value=generate_params['top_k'], step=1, label='top_k', info='Similar to top_p, but select instead only the top_k most likely tokens. Higher value = higher range of possible random results.') shared.gradio['top_k'] = gr.Slider(0, 200, value=generate_params['top_k'], step=1, label='top_k', info='Similar to top_p, but select instead only the top_k most likely tokens. Higher value = higher range of possible random results.')
@ -489,6 +482,9 @@ def create_settings_menus(default_preset):
shared.gradio['min_length'] = gr.Slider(0, 2000, step=1, value=generate_params['min_length'], label='min_length', info='Minimum generation length in tokens.') shared.gradio['min_length'] = gr.Slider(0, 2000, step=1, value=generate_params['min_length'], label='min_length', info='Minimum generation length in tokens.')
shared.gradio['tfs'] = gr.Slider(0.0, 1.0, value=generate_params['tfs'], step=0.01, label='tfs') shared.gradio['tfs'] = gr.Slider(0.0, 1.0, value=generate_params['tfs'], step=0.01, label='tfs')
shared.gradio['top_a'] = gr.Slider(0.0, 1.0, value=generate_params['top_a'], step=0.01, label='top_a') shared.gradio['top_a'] = gr.Slider(0.0, 1.0, value=generate_params['top_a'], step=0.01, label='top_a')
shared.gradio['do_sample'] = gr.Checkbox(value=generate_params['do_sample'], label='do_sample')
gr.Markdown('[Click here for more information.](https://github.com/oobabooga/text-generation-webui/blob/main/docs/Generation-parameters.md)')
with gr.Column(): with gr.Column():
create_chat_settings_menus() create_chat_settings_menus()
@ -521,11 +517,66 @@ def create_settings_menus(default_preset):
shared.gradio['skip_special_tokens'] = gr.Checkbox(value=shared.settings['skip_special_tokens'], label='Skip special tokens', info='Some specific models need this unset.') shared.gradio['skip_special_tokens'] = gr.Checkbox(value=shared.settings['skip_special_tokens'], label='Skip special tokens', info='Some specific models need this unset.')
shared.gradio['stream'] = gr.Checkbox(value=not shared.args.no_stream, label='Activate text streaming') shared.gradio['stream'] = gr.Checkbox(value=not shared.args.no_stream, label='Activate text streaming')
gr.Markdown('[Click here for more information.](https://github.com/oobabooga/text-generation-webui/blob/main/docs/Generation-parameters.md)')
shared.gradio['preset_menu'].change(load_preset_values, [shared.gradio[k] for k in ['preset_menu', 'interface_state']], [shared.gradio[k] for k in ['interface_state', 'do_sample', 'temperature', 'top_p', 'typical_p', 'epsilon_cutoff', 'eta_cutoff', 'repetition_penalty', 'encoder_repetition_penalty', 'top_k', 'min_length', 'no_repeat_ngram_size', 'num_beams', 'penalty_alpha', 'length_penalty', 'early_stopping', 'mirostat_mode', 'mirostat_tau', 'mirostat_eta', 'tfs', 'top_a']]) shared.gradio['preset_menu'].change(load_preset_values, [shared.gradio[k] for k in ['preset_menu', 'interface_state']], [shared.gradio[k] for k in ['interface_state', 'do_sample', 'temperature', 'top_p', 'typical_p', 'epsilon_cutoff', 'eta_cutoff', 'repetition_penalty', 'encoder_repetition_penalty', 'top_k', 'min_length', 'no_repeat_ngram_size', 'num_beams', 'penalty_alpha', 'length_penalty', 'early_stopping', 'mirostat_mode', 'mirostat_tau', 'mirostat_eta', 'tfs', 'top_a']])
def create_file_saving_menus():
# Text file saver
with gr.Box(visible=False, elem_classes='file-saver') as shared.gradio['file_saver']:
shared.gradio['save_filename'] = gr.Textbox(lines=1, label='File name')
shared.gradio['save_root'] = gr.Textbox(lines=1, label='File folder', info='For reference. Unchangeable.', interactive=False)
shared.gradio['save_contents'] = gr.Textbox(lines=10, label='File contents')
with gr.Row():
shared.gradio['save_confirm'] = gr.Button('Save', elem_classes="small-button")
shared.gradio['save_cancel'] = gr.Button('Cancel', elem_classes="small-button")
# Text file deleter
with gr.Box(visible=False, elem_classes='file-saver') as shared.gradio['file_deleter']:
shared.gradio['delete_filename'] = gr.Textbox(lines=1, label='File name')
shared.gradio['delete_root'] = gr.Textbox(lines=1, label='File folder', info='For reference. Unchangeable.', interactive=False)
with gr.Row():
shared.gradio['delete_confirm'] = gr.Button('Delete', elem_classes="small-button", variant='stop')
shared.gradio['delete_cancel'] = gr.Button('Cancel', elem_classes="small-button")
shared.gradio['save_confirm'].click(
lambda x, y, z: utils.save_file(x + y, z), [shared.gradio[k] for k in ['save_root', 'save_filename', 'save_contents']], None).then(
lambda: gr.update(visible=False), None, shared.gradio['file_saver'])
shared.gradio['delete_confirm'].click(
lambda x, y: utils.delete_file(x + y), [shared.gradio[k] for k in ['delete_root', 'delete_filename']], None).then(
lambda: gr.update(visible=False), None, shared.gradio['file_deleter'])
shared.gradio['delete_cancel'].click(lambda: gr.update(visible=False), None, shared.gradio['file_deleter'])
shared.gradio['save_cancel'].click(lambda: gr.update(visible=False), None, shared.gradio['file_saver'])
# Character saver/deleter
if shared.is_chat():
with gr.Box(visible=False, elem_classes='file-saver') as shared.gradio['character_saver']:
shared.gradio['save_character_filename'] = gr.Textbox(lines=1, label='File name', info='The character will be saved to your characters/ folder with this base filename.')
with gr.Row():
shared.gradio['save_character_confirm'] = gr.Button('Save', elem_classes="small-button")
shared.gradio['save_character_cancel'] = gr.Button('Cancel', elem_classes="small-button")
with gr.Box(visible=False, elem_classes='file-saver') as shared.gradio['character_deleter']:
gr.Markdown('Confirm the character deletion?')
with gr.Row():
shared.gradio['delete_character_confirm'] = gr.Button('Delete', elem_classes="small-button", variant='stop')
shared.gradio['delete_character_cancel'] = gr.Button('Cancel', elem_classes="small-button")
shared.gradio['save_character_confirm'].click(
chat.save_character, [shared.gradio[k] for k in ['name2', 'greeting', 'context', 'character_picture', 'save_character_filename']], None).then(
lambda: gr.update(visible=False), None, shared.gradio['character_saver'])
shared.gradio['delete_character_confirm'].click(
chat.delete_character, shared.gradio['character_menu'], None).then(
lambda: gr.update(visible=False), None, shared.gradio['character_deleter']).then(
lambda: gr.update(choices=utils.get_available_characters()), outputs=shared.gradio['character_menu'])
shared.gradio['save_character_cancel'].click(lambda: gr.update(visible=False), None, shared.gradio['character_saver'])
shared.gradio['delete_character_cancel'].click(lambda: gr.update(visible=False), None, shared.gradio['character_deleter'])
def set_interface_arguments(interface_mode, extensions, bool_active): def set_interface_arguments(interface_mode, extensions, bool_active):
modes = ["default", "notebook", "chat", "cai_chat"] modes = ["default", "notebook", "chat", "cai_chat"]
cmd_list = vars(shared.args) cmd_list = vars(shared.args)
@ -626,14 +677,9 @@ def create_interface():
with gr.Row(): with gr.Row():
shared.gradio['character_menu'] = gr.Dropdown(choices=utils.get_available_characters(), label='Character', elem_id='character-menu', info='Used in chat and chat-instruct modes.') shared.gradio['character_menu'] = gr.Dropdown(choices=utils.get_available_characters(), label='Character', elem_id='character-menu', info='Used in chat and chat-instruct modes.')
ui.create_refresh_button(shared.gradio['character_menu'], lambda: None, lambda: {'choices': utils.get_available_characters()}, 'refresh-button') ui.create_refresh_button(shared.gradio['character_menu'], lambda: None, lambda: {'choices': utils.get_available_characters()}, 'refresh-button')
shared.gradio['save_character'] = ui.create_save_button(elem_id='refresh-button') with gr.Column(scale=0):
shared.gradio['delete_character'] = ui.create_delete_button(elem_id='refresh-button') shared.gradio['save_character'] = gr.Button('Save character')
shared.gradio['delete_character'] = gr.Button('Delete character')
shared.gradio['save_character-filename'] = gr.Textbox(lines=1, label='File name:', interactive=True, visible=False)
shared.gradio['save_character-confirm'] = gr.Button('Confirm save character', elem_classes="small-button", variant='primary', visible=False)
shared.gradio['save_character-cancel'] = gr.Button('Cancel', elem_classes="small-button", visible=False)
shared.gradio['delete_character-confirm'] = gr.Button('Confirm delete character', elem_classes="small-button", variant='stop', visible=False)
shared.gradio['delete_character-cancel'] = gr.Button('Cancel', elem_classes="small-button", visible=False)
shared.gradio['name1'] = gr.Textbox(value=shared.settings['name1'], lines=1, label='Your name') shared.gradio['name1'] = gr.Textbox(value=shared.settings['name1'], lines=1, label='Your name')
shared.gradio['name2'] = gr.Textbox(value=shared.settings['name2'], lines=1, label='Character\'s name') shared.gradio['name2'] = gr.Textbox(value=shared.settings['name2'], lines=1, label='Character\'s name')
@ -647,6 +693,9 @@ def create_interface():
with gr.Row(): with gr.Row():
shared.gradio['instruction_template'] = gr.Dropdown(choices=utils.get_available_instruction_templates(), label='Instruction template', value='None', info='Change this according to the model/LoRA that you are using. Used in instruct and chat-instruct modes.') shared.gradio['instruction_template'] = gr.Dropdown(choices=utils.get_available_instruction_templates(), label='Instruction template', value='None', info='Change this according to the model/LoRA that you are using. Used in instruct and chat-instruct modes.')
ui.create_refresh_button(shared.gradio['instruction_template'], lambda: None, lambda: {'choices': utils.get_available_instruction_templates()}, 'refresh-button') ui.create_refresh_button(shared.gradio['instruction_template'], lambda: None, lambda: {'choices': utils.get_available_instruction_templates()}, 'refresh-button')
with gr.Column(scale=0):
shared.gradio['save_template'] = gr.Button('Save template')
shared.gradio['delete_template'] = gr.Button('Delete template')
shared.gradio['name1_instruct'] = gr.Textbox(value='', lines=2, label='User string') shared.gradio['name1_instruct'] = gr.Textbox(value='', lines=2, label='User string')
shared.gradio['name2_instruct'] = gr.Textbox(value='', lines=1, label='Bot string') shared.gradio['name2_instruct'] = gr.Textbox(value='', lines=1, label='Bot string')
@ -716,9 +765,10 @@ def create_interface():
shared.gradio['prompt_menu'] = gr.Dropdown(choices=utils.get_available_prompts(), value='None', label='Prompt') shared.gradio['prompt_menu'] = gr.Dropdown(choices=utils.get_available_prompts(), value='None', label='Prompt')
ui.create_refresh_button(shared.gradio['prompt_menu'], lambda: None, lambda: {'choices': utils.get_available_prompts()}, 'refresh-button') ui.create_refresh_button(shared.gradio['prompt_menu'], lambda: None, lambda: {'choices': utils.get_available_prompts()}, 'refresh-button')
shared.gradio['open_save_prompt'] = gr.Button('Save prompt') with gr.Row():
shared.gradio['save_prompt'] = gr.Button('Confirm save prompt', visible=False) shared.gradio['save_prompt'] = gr.Button('Save prompt')
shared.gradio['prompt_to_save'] = gr.Textbox(elem_classes="textbox_default", lines=1, label='Prompt name:', interactive=True, visible=False) shared.gradio['delete_prompt'] = gr.Button('Delete prompt')
shared.gradio['count_tokens'] = gr.Button('Count tokens') shared.gradio['count_tokens'] = gr.Button('Count tokens')
shared.gradio['status'] = gr.Markdown('') shared.gradio['status'] = gr.Markdown('')
@ -736,22 +786,19 @@ def create_interface():
shared.gradio['textbox'] = gr.Textbox(value=default_text, elem_classes="textbox_default", lines=27, label='Input') shared.gradio['textbox'] = gr.Textbox(value=default_text, elem_classes="textbox_default", lines=27, label='Input')
shared.gradio['max_new_tokens'] = gr.Slider(minimum=shared.settings['max_new_tokens_min'], maximum=shared.settings['max_new_tokens_max'], step=1, label='max_new_tokens', value=shared.settings['max_new_tokens']) shared.gradio['max_new_tokens'] = gr.Slider(minimum=shared.settings['max_new_tokens_min'], maximum=shared.settings['max_new_tokens_max'], step=1, label='max_new_tokens', value=shared.settings['max_new_tokens'])
with gr.Row(): with gr.Row():
shared.gradio['Generate'] = gr.Button('Generate', variant='primary', elem_classes="small-button") shared.gradio['Generate'] = gr.Button('Generate', variant='primary')
shared.gradio['Stop'] = gr.Button('Stop', elem_classes="small-button") shared.gradio['Stop'] = gr.Button('Stop')
shared.gradio['Continue'] = gr.Button('Continue', elem_classes="small-button") shared.gradio['Continue'] = gr.Button('Continue')
shared.gradio['open_save_prompt'] = gr.Button('Save prompt', elem_classes="small-button") shared.gradio['count_tokens'] = gr.Button('Count tokens')
shared.gradio['save_prompt'] = gr.Button('Confirm save prompt', visible=False, elem_classes="small-button")
shared.gradio['count_tokens'] = gr.Button('Count tokens', elem_classes="small-button")
with gr.Row(): with gr.Row():
shared.gradio['prompt_menu'] = gr.Dropdown(choices=utils.get_available_prompts(), value='None', label='Prompt')
ui.create_refresh_button(shared.gradio['prompt_menu'], lambda: None, lambda: {'choices': utils.get_available_prompts()}, 'refresh-button')
with gr.Column(): with gr.Column():
with gr.Row(): shared.gradio['save_prompt'] = gr.Button('Save prompt')
shared.gradio['prompt_menu'] = gr.Dropdown(choices=utils.get_available_prompts(), value='None', label='Prompt') shared.gradio['delete_prompt'] = gr.Button('Delete prompt')
ui.create_refresh_button(shared.gradio['prompt_menu'], lambda: None, lambda: {'choices': utils.get_available_prompts()}, 'refresh-button')
with gr.Column(): shared.gradio['status'] = gr.Markdown('')
shared.gradio['prompt_to_save'] = gr.Textbox(elem_classes="textbox_default", lines=1, label='Prompt name:', interactive=True, visible=False)
shared.gradio['status'] = gr.Markdown('')
with gr.Column(): with gr.Column():
with gr.Tab('Raw'): with gr.Tab('Raw'):
@ -803,6 +850,9 @@ def create_interface():
shared.gradio['toggle_dark_mode'].click(lambda: None, None, None, _js='() => {document.getElementsByTagName("body")[0].classList.toggle("dark")}') shared.gradio['toggle_dark_mode'].click(lambda: None, None, None, _js='() => {document.getElementsByTagName("body")[0].classList.toggle("dark")}')
# Floating menus for saving/deleting files
create_file_saving_menus()
# chat mode event handlers # chat mode event handlers
if shared.is_chat(): if shared.is_chat():
shared.input_params = [shared.gradio[k] for k in ['Chat input', 'start_with', 'interface_state']] shared.input_params = [shared.gradio[k] for k in ['Chat input', 'start_with', 'interface_state']]
@ -896,28 +946,21 @@ def create_interface():
# Save/delete a character # Save/delete a character
shared.gradio['save_character'].click( shared.gradio['save_character'].click(
lambda x: x, shared.gradio['name2'], shared.gradio['save_character-filename'], show_progress=True).then( lambda x: x, shared.gradio['name2'], shared.gradio['save_character_filename']).then(
lambda: [gr.update(visible=True)] * 3, None, [shared.gradio[k] for k in ['save_character-filename', 'save_character-confirm', 'save_character-cancel']], show_progress=False) lambda: gr.update(visible=True), None, shared.gradio['character_saver'])
shared.gradio['save_character-cancel'].click( shared.gradio['delete_character'].click(lambda: gr.update(visible=True), None, shared.gradio['character_deleter'])
lambda: [gr.update(visible=False)] * 3, None, [shared.gradio[k] for k in ['save_character-filename', 'save_character-confirm', 'save_character-cancel']], show_progress=False)
shared.gradio['save_character-confirm'].click( shared.gradio['save_template'].click(
partial(chat.save_character, instruct=False), [shared.gradio[k] for k in ['name2', 'greeting', 'context', 'character_picture', 'save_character-filename']], None).then( lambda: 'My Template.yaml', None, shared.gradio['save_filename']).then(
lambda: [gr.update(visible=False)] * 3, None, [shared.gradio[k] for k in ['save_character-filename', 'save_character-confirm', 'save_character-cancel']], show_progress=False).then( lambda: 'characters/instruction-following/', None, shared.gradio['save_root']).then(
lambda x: x, shared.gradio['save_character-filename'], shared.gradio['character_menu']) chat.generate_instruction_template_yaml, [shared.gradio[k] for k in ['name1_instruct', 'name2_instruct', 'context_instruct', 'turn_template']], shared.gradio['save_contents']).then(
lambda: gr.update(visible=True), None, shared.gradio['file_saver'])
shared.gradio['delete_character'].click( shared.gradio['delete_template'].click(
lambda: [gr.update(visible=True)] * 2, None, [shared.gradio[k] for k in ['delete_character-confirm', 'delete_character-cancel']], show_progress=False) lambda x: f'{x}.yaml', shared.gradio['instruction_template'], shared.gradio['delete_filename']).then(
lambda: 'characters/instruction-following/', None, shared.gradio['delete_root']).then(
shared.gradio['delete_character-cancel'].click( lambda: gr.update(visible=True), None, shared.gradio['file_deleter'])
lambda: [gr.update(visible=False)] * 2, None, [shared.gradio[k] for k in ['delete_character-confirm', 'delete_character-cancel']], show_progress=False)
shared.gradio['delete_character-confirm'].click(
partial(chat.delete_character, instruct=False), shared.gradio['character_menu'], None).then(
lambda: gr.update(choices=utils.get_available_characters()), outputs=shared.gradio['character_menu']).then(
lambda: 'None', None, shared.gradio['character_menu']).then(
lambda: [gr.update(visible=False)] * 2, None, [shared.gradio[k] for k in ['delete_character-confirm', 'delete_character-cancel']], show_progress=False)
shared.gradio['download_button'].click(lambda x: chat.save_history(x, timestamp=True), shared.gradio['mode'], shared.gradio['download']) shared.gradio['download_button'].click(lambda x: chat.save_history(x, timestamp=True), shared.gradio['mode'], shared.gradio['download'])
shared.gradio['Upload character'].click(chat.upload_character, [shared.gradio['upload_json'], shared.gradio['upload_img_bot']], [shared.gradio['character_menu']]) shared.gradio['Upload character'].click(chat.upload_character, [shared.gradio['upload_json'], shared.gradio['upload_img_bot']], [shared.gradio['character_menu']])
@ -975,10 +1018,31 @@ def create_interface():
shared.gradio['Stop'].click(stop_everything_event, None, None, queue=False, cancels=gen_events if shared.args.no_stream else None) shared.gradio['Stop'].click(stop_everything_event, None, None, queue=False, cancels=gen_events if shared.args.no_stream else None)
shared.gradio['prompt_menu'].change(load_prompt, shared.gradio['prompt_menu'], shared.gradio['textbox'], show_progress=False) shared.gradio['prompt_menu'].change(load_prompt, shared.gradio['prompt_menu'], shared.gradio['textbox'], show_progress=False)
shared.gradio['open_save_prompt'].click(open_save_prompt, None, [shared.gradio[k] for k in ['prompt_to_save', 'open_save_prompt', 'save_prompt']], show_progress=False) shared.gradio['save_prompt'].click(
shared.gradio['save_prompt'].click(save_prompt, [shared.gradio[k] for k in ['textbox', 'prompt_to_save']], [shared.gradio[k] for k in ['status', 'prompt_to_save', 'open_save_prompt', 'save_prompt']], show_progress=False) lambda x: x, shared.gradio['textbox'], shared.gradio['save_contents']).then(
lambda: 'prompts/', None, shared.gradio['save_root']).then(
lambda: current_time() + '.txt', None, shared.gradio['save_filename']).then(
lambda: gr.update(visible=True), None, shared.gradio['file_saver'])
shared.gradio['delete_prompt'].click(
lambda: 'prompts/', None, shared.gradio['delete_root']).then(
lambda x: x + '.txt', shared.gradio['prompt_menu'], shared.gradio['delete_filename']).then(
lambda: gr.update(visible=True), None, shared.gradio['file_deleter'])
shared.gradio['count_tokens'].click(count_tokens, shared.gradio['textbox'], shared.gradio['status'], show_progress=False) shared.gradio['count_tokens'].click(count_tokens, shared.gradio['textbox'], shared.gradio['status'], show_progress=False)
shared.gradio['save_preset'].click(
ui.gather_interface_values, [shared.gradio[k] for k in shared.input_elements], shared.gradio['interface_state']).then(
generate_preset_yaml, shared.gradio['interface_state'], shared.gradio['save_contents']).then(
lambda: 'presets/', None, shared.gradio['save_root']).then(
lambda: 'My Preset.yaml', None, shared.gradio['save_filename']).then(
lambda: gr.update(visible=True), None, shared.gradio['file_saver'])
shared.gradio['delete_preset'].click(
lambda x: f'{x}.yaml', shared.gradio['preset_menu'], shared.gradio['delete_filename']).then(
lambda: 'presets/', None, shared.gradio['delete_root']).then(
lambda: gr.update(visible=True), None, shared.gradio['file_deleter'])
shared.gradio['interface'].load(lambda: None, None, None, _js=f"() => {{{js}}}") shared.gradio['interface'].load(lambda: None, None, None, _js=f"() => {{{js}}}")
if shared.settings['dark_theme']: if shared.settings['dark_theme']:
shared.gradio['interface'].load(lambda: None, None, None, _js="() => document.getElementsByTagName('body')[0].classList.add('dark')") shared.gradio['interface'].load(lambda: None, None, None, _js="() => document.getElementsByTagName('body')[0].classList.add('dark')")