UI persistence (#7050)

This commit is contained in:
oobabooga 2025-06-07 22:46:52 -03:00 committed by GitHub
parent db847eed4c
commit 35ed55d18f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 112 additions and 16 deletions

View file

@ -1,4 +1,5 @@
import copy
import threading
from pathlib import Path
import gradio as gr
@ -7,6 +8,16 @@ import yaml
import extensions
from modules import shared
from modules.chat import load_history
from modules.utils import gradio
# Global state for auto-saving UI settings with debouncing
_auto_save_timer = None
_auto_save_lock = threading.Lock()
_last_interface_state = None
_last_preset = None
_last_extensions = None
_last_show_controls = None
_last_theme_state = None
with open(Path(__file__).resolve().parent / '../css/NotoSans/stylesheet.css', 'r') as f:
css = f.read()
@ -334,6 +345,101 @@ def save_settings(state, preset, extensions_list, show_controls, theme_state):
return yaml.dump(output, sort_keys=False, width=float("inf"), allow_unicode=True)
def store_current_state_and_debounce(interface_state, preset, extensions, show_controls, theme_state):
"""Store current state and trigger debounced save"""
global _auto_save_timer, _last_interface_state, _last_preset, _last_extensions, _last_show_controls, _last_theme_state
if shared.args.multi_user:
return
# Store the current state in global variables
_last_interface_state = interface_state
_last_preset = preset
_last_extensions = extensions
_last_show_controls = show_controls
_last_theme_state = theme_state
# Reset the debounce timer
with _auto_save_lock:
if _auto_save_timer is not None:
_auto_save_timer.cancel()
_auto_save_timer = threading.Timer(2.0, _perform_debounced_save)
_auto_save_timer.start()
def _perform_debounced_save():
"""Actually perform the save using the stored state"""
global _auto_save_timer
try:
if _last_interface_state is not None:
contents = save_settings(_last_interface_state, _last_preset, _last_extensions, _last_show_controls, _last_theme_state)
settings_path = Path('user_data') / 'settings.yaml'
settings_path.parent.mkdir(exist_ok=True)
with open(settings_path, 'w', encoding='utf-8') as f:
f.write(contents)
except Exception as e:
print(f"Auto-save failed: {e}")
finally:
with _auto_save_lock:
_auto_save_timer = None
def setup_auto_save():
"""Attach auto-save to key UI elements"""
if shared.args.multi_user:
return
change_elements = [
# Chat tab (ui_chat.py)
'start_with',
'enable_web_search',
'web_search_pages',
'mode',
'chat_style',
'chat-instruct_command',
'character_menu',
'name1',
'user_bio',
'custom_system_message',
'chat_template_str',
# Parameters tab (ui_parameters.py)
'preset_menu',
'max_new_tokens',
'prompt_lookup_num_tokens',
'max_tokens_second',
'auto_max_new_tokens',
'ban_eos_token',
'add_bos_token',
'enable_thinking',
'skip_special_tokens',
'stream',
'static_cache',
'seed',
'custom_stopping_strings',
'custom_token_bans',
'negative_prompt',
# Default tab (ui_default.py)
'prompt_menu-default',
# Notebook tab (ui_notebook.py)
'prompt_menu-notebook',
# Session tab (ui_session.py)
'show_controls',
'theme_state',
]
for element_name in change_elements:
if element_name in shared.gradio:
shared.gradio[element_name].change(
gather_interface_values, gradio(shared.input_elements), gradio('interface_state')).then(
store_current_state_and_debounce, gradio('interface_state', 'preset_menu', 'extensions_menu', 'show_controls', 'theme_state'), None, show_progress=False)
def create_refresh_button(refresh_component, refresh_method, refreshed_args, elem_class, interactive=True):
"""
Copied from https://github.com/AUTOMATIC1111/stable-diffusion-webui