mirror of
https://github.com/oobabooga/text-generation-webui.git
synced 2024-12-25 22:08:53 +01:00
Add direct download for session/chat history JSONs
This commit is contained in:
parent
32a2bbee4a
commit
0e8f9354b5
@ -17,6 +17,7 @@ main_parent.addEventListener('click', function(e) {
|
||||
}
|
||||
});
|
||||
|
||||
// Add some scrollbars
|
||||
const textareaElements = document.querySelectorAll('.add_scrollbar textarea');
|
||||
for(i = 0; i < textareaElements.length; i++) {
|
||||
textareaElements[i].classList.remove('scroll-hide');
|
||||
|
40
css/save_files.js
Normal file
40
css/save_files.js
Normal file
@ -0,0 +1,40 @@
|
||||
// Functions for downloading JSON files
|
||||
function getCurrentTimestamp() {
|
||||
const now = new Date();
|
||||
const timezoneOffset = now.getTimezoneOffset() * 60000; // Convert to milliseconds
|
||||
const localTime = new Date(now.getTime() - timezoneOffset);
|
||||
const formattedTimestamp = localTime.toISOString().replace(/[-:]/g, '').slice(0, 15);
|
||||
return formattedTimestamp;
|
||||
}
|
||||
|
||||
function saveFile(contents, filename) {
|
||||
const element = document.createElement('a');
|
||||
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(contents));
|
||||
element.setAttribute('download', filename);
|
||||
element.style.display = 'none';
|
||||
document.body.appendChild(element);
|
||||
element.click();
|
||||
document.body.removeChild(element);
|
||||
}
|
||||
|
||||
function saveHistory(history, character, mode) {
|
||||
let path = null;
|
||||
|
||||
if (['chat', 'chat-instruct'].includes(mode) && character && character.trim() !== '') {
|
||||
path = `history_${character}_${getCurrentTimestamp()}.json`;
|
||||
} else {
|
||||
try {
|
||||
path = `history_${mode}_${getCurrentTimestamp()}.json`;
|
||||
} catch (error) {
|
||||
path = `history_${getCurrentTimestamp()}.json`;
|
||||
}
|
||||
}
|
||||
saveFile(history, path);
|
||||
}
|
||||
|
||||
function saveSession(session, mode) {
|
||||
let path = null;
|
||||
|
||||
path = `session_${mode}_${getCurrentTimestamp()}.json`;
|
||||
saveFile(session, path);
|
||||
}
|
@ -412,23 +412,6 @@ def load_history(file, history):
|
||||
return history
|
||||
|
||||
|
||||
def save_history_at_user_request(history, character, mode):
|
||||
def make_timestamp_path(character=None):
|
||||
return f"logs/{character or ''}{'_' if character else ''}{datetime.now().strftime('%Y%m%d-%H%M%S')}.json"
|
||||
|
||||
path = None
|
||||
if mode in ['chat', 'chat-instruct'] and character not in ['', 'None', None]:
|
||||
path = make_timestamp_path(character)
|
||||
else:
|
||||
# Try to use mode as the file name, otherwise just use the timestamp
|
||||
try:
|
||||
path = make_timestamp_path(mode.capitalize())
|
||||
except:
|
||||
path = make_timestamp_path()
|
||||
|
||||
return save_history(history, path)
|
||||
|
||||
|
||||
def save_persistent_history(history, character, mode):
|
||||
if mode in ['chat', 'chat-instruct'] and character not in ['', 'None', None] and not shared.args.multi_user:
|
||||
save_history(history, path=Path(f'logs/{character}_persistent.json'))
|
||||
|
@ -15,6 +15,8 @@ with open(Path(__file__).resolve().parent / '../css/main.js', 'r') as f:
|
||||
main_js = f.read()
|
||||
with open(Path(__file__).resolve().parent / '../css/chat.js', 'r') as f:
|
||||
chat_js = f.read()
|
||||
with open(Path(__file__).resolve().parent / '../css/save_files.js', 'r') as f:
|
||||
save_files_js = f.read()
|
||||
|
||||
refresh_symbol = '🔄'
|
||||
delete_symbol = '🗑️'
|
||||
@ -145,9 +147,6 @@ def gather_interface_values(*args):
|
||||
|
||||
if not shared.args.multi_user:
|
||||
shared.persistent_interface_state = output
|
||||
Path('logs').mkdir(exist_ok=True)
|
||||
with open(Path(f'logs/session_{shared.get_mode()}_autosave.json'), 'w') as f:
|
||||
f.write(json.dumps(output, indent=4))
|
||||
|
||||
return output
|
||||
|
||||
|
66
server.py
66
server.py
@ -508,44 +508,24 @@ def create_file_saving_event_handlers():
|
||||
|
||||
if not shared.args.multi_user:
|
||||
|
||||
def load_session(session, state):
|
||||
with open(Path(f'logs/{session}.json'), 'r') as f:
|
||||
state.update(json.loads(f.read()))
|
||||
def load_session(file, state):
|
||||
decoded_file = file if type(file) == str else file.decode('utf-8')
|
||||
data = json.loads(decoded_file)
|
||||
state.update(data)
|
||||
|
||||
if shared.is_chat():
|
||||
chat.save_persistent_history(state['history'], state['character_menu'], state['mode'])
|
||||
|
||||
return state
|
||||
|
||||
if shared.is_chat():
|
||||
shared.gradio['save_session'].click(
|
||||
ui.gather_interface_values, gradio(shared.input_elements), gradio('interface_state')).then(
|
||||
lambda x: json.dumps(x, indent=4), gradio('interface_state'), gradio('save_contents')).then(
|
||||
lambda: 'logs/', None, gradio('save_root')).then(
|
||||
lambda x: f'session_{shared.get_mode()}_{x + "_" if x not in ["None", None, ""] else ""}{utils.current_time()}.json', gradio('character_menu'), gradio('save_filename')).then(
|
||||
lambda: gr.update(visible=True), None, gradio('file_saver'))
|
||||
shared.gradio['save_session'].click(
|
||||
ui.gather_interface_values, gradio(shared.input_elements), gradio('interface_state')).then(
|
||||
lambda x: json.dumps(x, indent=4), gradio('interface_state'), gradio('temporary_text')).then(
|
||||
None, gradio('temporary_text'), None, _js=f"(contents) => {{{ui.save_files_js}; saveSession(contents, \"{shared.get_mode()}\")}}")
|
||||
|
||||
shared.gradio['session_menu'].change(
|
||||
load_session, gradio('session_menu', 'interface_state'), gradio('interface_state')).then(
|
||||
ui.apply_interface_values, gradio('interface_state'), gradio(ui.list_interface_input_elements()), show_progress=False).then(
|
||||
chat.redraw_html, shared.reload_inputs, gradio('display'))
|
||||
|
||||
else:
|
||||
shared.gradio['save_session'].click(
|
||||
ui.gather_interface_values, gradio(shared.input_elements), gradio('interface_state')).then(
|
||||
lambda x: json.dumps(x, indent=4), gradio('interface_state'), gradio('save_contents')).then(
|
||||
lambda: 'logs/', None, gradio('save_root')).then(
|
||||
lambda: f'session_{shared.get_mode()}_{utils.current_time()}.json', None, gradio('save_filename')).then(
|
||||
lambda: gr.update(visible=True), None, gradio('file_saver'))
|
||||
|
||||
shared.gradio['session_menu'].change(
|
||||
load_session, gradio('session_menu', 'interface_state'), gradio('interface_state')).then(
|
||||
ui.apply_interface_values, gradio('interface_state'), gradio(ui.list_interface_input_elements()), show_progress=False)
|
||||
|
||||
shared.gradio['delete_session'].click(
|
||||
lambda x: f'{x}.json', gradio('session_menu'), gradio('delete_filename')).then(
|
||||
lambda: 'logs/', None, gradio('delete_root')).then(
|
||||
lambda: gr.update(visible=True), None, gradio('file_deleter'))
|
||||
shared.gradio['load_session'].upload(
|
||||
load_session, gradio('load_session', 'interface_state'), gradio('interface_state')).then(
|
||||
ui.apply_interface_values, gradio('interface_state'), gradio(ui.list_interface_input_elements()), show_progress=False)
|
||||
|
||||
|
||||
def set_interface_arguments(interface_mode, extensions, bool_active):
|
||||
@ -558,7 +538,6 @@ def set_interface_arguments(interface_mode, extensions, bool_active):
|
||||
setattr(shared.args, k, False)
|
||||
if interface_mode != "default":
|
||||
setattr(shared.args, interface_mode, True)
|
||||
|
||||
for k in bool_list:
|
||||
setattr(shared.args, k, False)
|
||||
for k in bool_active:
|
||||
@ -622,6 +601,9 @@ def create_interface():
|
||||
# Floating menus for saving/deleting files
|
||||
create_file_saving_menus()
|
||||
|
||||
# Used for saving files using javascript
|
||||
shared.gradio['temporary_text'] = gr.Textbox(visible=False)
|
||||
|
||||
# Create chat mode interface
|
||||
if shared.is_chat():
|
||||
shared.input_elements = ui.list_interface_input_elements()
|
||||
@ -702,11 +684,10 @@ def create_interface():
|
||||
with gr.Tab('Chat history'):
|
||||
with gr.Row():
|
||||
with gr.Column():
|
||||
shared.gradio['download'] = gr.File(label="Download")
|
||||
shared.gradio['download_button'] = gr.Button(value='Refresh')
|
||||
shared.gradio['save_chat_history'] = gr.Button(value='Save history')
|
||||
|
||||
with gr.Column():
|
||||
shared.gradio['upload_chat_history'] = gr.File(type='binary', file_types=['.json', '.txt'], label="Upload")
|
||||
shared.gradio['load_chat_history'] = gr.File(type='binary', file_types=['.json', '.txt'], label="Upload History JSON")
|
||||
|
||||
with gr.Tab('Upload character'):
|
||||
with gr.Tab('YAML or JSON'):
|
||||
@ -845,11 +826,8 @@ def create_interface():
|
||||
|
||||
with gr.Column():
|
||||
if not shared.args.multi_user:
|
||||
with gr.Row():
|
||||
shared.gradio['session_menu'] = gr.Dropdown(choices=utils.get_available_sessions(), value='None', label='Session', elem_classes='slim-dropdown', info='When saving a session, make sure to keep the initial part of the filename (session_chat, session_notebook, or session_default), otherwise it will not appear on this list afterwards.')
|
||||
ui.create_refresh_button(shared.gradio['session_menu'], lambda: None, lambda: {'choices': utils.get_available_sessions()}, ['refresh-button'])
|
||||
shared.gradio['save_session'] = gr.Button('💾', elem_classes=['refresh-button'])
|
||||
shared.gradio['delete_session'] = gr.Button('🗑️', elem_classes=['refresh-button'])
|
||||
shared.gradio['save_session'] = gr.Button('Save session')
|
||||
shared.gradio['load_session'] = gr.File(type='binary', file_types=['.json'], label="Upload Session JSON")
|
||||
|
||||
extension_name = gr.Textbox(lines=1, label='Install or update an extension', info='Enter the GitHub URL below and press Enter. For a list of extensions, see: https://github.com/oobabooga/text-generation-webui-extensions ⚠️ WARNING ⚠️ : extensions can execute arbitrary code. Make sure to inspect their source code before activating them.')
|
||||
extension_status = gr.Markdown()
|
||||
@ -967,8 +945,8 @@ def create_interface():
|
||||
shared.gradio['instruction_template'].change(
|
||||
partial(chat.load_character, instruct=True), gradio('instruction_template', 'name1_instruct', 'name2_instruct'), gradio('name1_instruct', 'name2_instruct', 'dummy', 'dummy', 'context_instruct', 'turn_template'))
|
||||
|
||||
shared.gradio['upload_chat_history'].upload(
|
||||
chat.load_history, gradio('upload_chat_history', 'history'), gradio('history')).then(
|
||||
shared.gradio['load_chat_history'].upload(
|
||||
chat.load_history, gradio('load_chat_history', 'history'), gradio('history')).then(
|
||||
chat.redraw_html, shared.reload_inputs, gradio('display'))
|
||||
|
||||
shared.gradio['Copy last reply'].click(chat.send_last_reply_to_input, gradio('history'), gradio('textbox'), show_progress=False)
|
||||
@ -991,7 +969,9 @@ def create_interface():
|
||||
lambda: 'characters/instruction-following/', None, gradio('delete_root')).then(
|
||||
lambda: gr.update(visible=True), None, gradio('file_deleter'))
|
||||
|
||||
shared.gradio['download_button'].click(chat.save_history_at_user_request, gradio('history', 'character_menu', 'mode'), gradio('download'))
|
||||
shared.gradio['save_chat_history'].click(lambda x: json.dumps(x, indent=4), gradio('history'), gradio('temporary_text')).then(
|
||||
None, gradio('temporary_text', 'character_menu', 'mode'), None, _js=f"(hist, char, mode) => {{{ui.save_files_js}; saveHistory(hist, char, mode)}}")
|
||||
|
||||
shared.gradio['Submit character'].click(chat.upload_character, gradio('upload_json', 'upload_img_bot'), gradio('character_menu'))
|
||||
shared.gradio['upload_json'].upload(lambda: gr.update(interactive=True), None, gradio('Submit character'))
|
||||
shared.gradio['upload_json'].clear(lambda: gr.update(interactive=False), None, gradio('Submit character'))
|
||||
|
Loading…
Reference in New Issue
Block a user